Ejemplo n.º 1
0
static void at_creg_test_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *nd = ofono_netreg_get_data(netreg);
	gint range[2];
	GAtResultIter iter;
	int creg1 = 0;
	int creg2 = 0;

	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);

	if (!g_at_result_iter_next(&iter, "+CREG:"))
		goto error;

	if (!g_at_result_iter_open_list(&iter))
		goto error;

	while (g_at_result_iter_next_range(&iter, &range[0], &range[1])) {
		if (1 >= range[0] && 1 <= range[1])
			creg1 = 1;
		if (2 >= range[0] && 2 <= range[1])
			creg2 = 1;
	}

	g_at_result_iter_close_list(&iter);

	if (creg2) {
		g_at_chat_send(nd->chat, "AT+CREG=2", none_prefix,
				at_creg_set_cb, netreg, NULL);
		return;
	}

	if (creg1) {
		g_at_chat_send(nd->chat, "AT+CREG=1", none_prefix,
				at_creg_set_cb, netreg, NULL);
		return;
	}

error:
	ofono_error("Unable to initialize Network Registration");
	ofono_netreg_remove(netreg);
}
Ejemplo n.º 2
0
static void create_nas_cb(struct qmi_service *service, void *user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *data = ofono_netreg_get_data(netreg);
	struct qmi_param *param;
	struct qmi_nas_param_event_signal_strength ss = { .report = 0x01,
				.count = 5, .dbm[0] = -55, .dbm[1] = -65,
				.dbm[2] = -75, .dbm[3] = -85, .dbm[4] = -95 };

	DBG("");

	if (!service) {
		ofono_error("Failed to request NAS service");
		ofono_netreg_remove(netreg);
		return;
	}

	data->nas = qmi_service_ref(service);

	qmi_service_register(data->nas, QMI_NAS_EVENT,
					event_notify, netreg, NULL);

	qmi_service_register(data->nas, QMI_NAS_SS_INFO_IND,
					ss_info_notify, netreg, NULL);

	param = qmi_param_new();
	if (!param)
		goto done;

	qmi_param_append(param, QMI_NAS_PARAM_REPORT_SIGNAL_STRENGTH,
							sizeof(ss), &ss);
	qmi_param_append_uint8(param, QMI_NAS_PARAM_REPORT_RF_INFO, 0x01);

	if (qmi_service_send(data->nas, QMI_NAS_SET_EVENT, param,
					set_event_cb, netreg, NULL) > 0)
		return;

	qmi_param_free(param);

done:
	ofono_netreg_register(netreg);
}

static int qmi_netreg_probe(struct ofono_netreg *netreg,
				unsigned int vendor, void *user_data)
{
	struct qmi_device *device = user_data;
	struct netreg_data *data;

	DBG("");

	data = g_new0(struct netreg_data, 1);

	data->operator.name[0] = '\0';
	data->operator.mcc[0] = '\0';
	data->operator.mnc[0] = '\0';
	data->operator.status = -1;
	data->operator.tech = -1;

	data->current_rat = QMI_NAS_NETWORK_RAT_NO_CHANGE;

	ofono_netreg_set_data(netreg, data);

	qmi_service_create_shared(device, QMI_SERVICE_NAS,
					create_nas_cb, netreg, NULL);

	return 0;
}

static void qmi_netreg_remove(struct ofono_netreg *netreg)
{
	struct netreg_data *data = ofono_netreg_get_data(netreg);

	DBG("");

	ofono_netreg_set_data(netreg, NULL);

	qmi_service_unregister_all(data->nas);

	qmi_service_unref(data->nas);

	g_free(data);
}

static struct ofono_netreg_driver driver = {
	.name			= "qmimodem",
	.probe			= qmi_netreg_probe,
	.remove			= qmi_netreg_remove,
	.registration_status	= qmi_registration_status,
	.current_operator	= qmi_current_operator,
	.list_operators		= qmi_list_operators,
	.register_auto		= qmi_register_auto,
	.register_manual	= qmi_register_manual,
	.strength		= qmi_signal_strength,
};

void qmi_netreg_init(void)
{
	ofono_netreg_driver_register(&driver);
}

void qmi_netreg_exit(void)
{
	ofono_netreg_driver_unregister(&driver);
}
Ejemplo n.º 3
0
Archivo: mtk.c Proyecto: semafor/ofono
/*
 * sim_state_watch listens to SIM state changes and creates/removes atoms
 * accordingly. This is needed because we cannot rely on the modem core code,
 * which handles modem state transitions, to do this due to the SIM not being
 * accessible in the offline state for mtk modems. This causes a mismatch
 * between what the core thinks it can do in some states and what the mtk modem
 * can really do in those. This is a workaround to solve that.
 */
static void sim_state_watch(enum ofono_sim_state new_state, void *data)
{
	struct ofono_modem *modem = data;
	struct mtk_data *md = ofono_modem_get_data(modem);

	if (new_state == OFONO_SIM_STATE_READY) {
		struct ofono_gprs_context *gc;
		struct ril_gprs_driver_data gprs_data = { md->ril, modem };
		struct ril_gprs_context_data inet_ctx =
			{ md->ril, OFONO_GPRS_CONTEXT_TYPE_INTERNET };
		struct ril_gprs_context_data mms_ctx =
			{ md->ril, OFONO_GPRS_CONTEXT_TYPE_MMS };

		DBG("SIM ready, creating more atoms");

		/*
		 * TODO: this function should setup:
		 *  - stk ( SIM toolkit )
		 */
		md->sms = ofono_sms_create(modem, OFONO_RIL_VENDOR_MTK,
						RILMODEM, md->ril);

		/* netreg needs access to the SIM (SPN, SPDI) */
		md->netreg = ofono_netreg_create(modem, OFONO_RIL_VENDOR_MTK,
							RILMODEM, md->ril);
		md->ussd = ofono_ussd_create(modem, OFONO_RIL_VENDOR_MTK,
						RILMODEM, md->ril);
		md->call_settings =
			ofono_call_settings_create(modem, OFONO_RIL_VENDOR_MTK,
							RILMODEM, md->ril);
		md->call_forwarding =
			ofono_call_forwarding_create(modem,
							OFONO_RIL_VENDOR_MTK,
							RILMODEM, md->ril);
		md->call_barring =
			ofono_call_barring_create(modem, OFONO_RIL_VENDOR_MTK,
							RILMODEM, md->ril);
		md->phonebook =
			ofono_phonebook_create(modem, OFONO_RIL_VENDOR_MTK,
						RILMODEM, modem);
		md->gprs = ofono_gprs_create(modem, OFONO_RIL_VENDOR_MTK,
						MTKMODEM, &gprs_data);

		gc = ofono_gprs_context_create(modem, OFONO_RIL_VENDOR_MTK,
						RILMODEM, &inet_ctx);
		if (gc) {
			ofono_gprs_context_set_type(gc,
					OFONO_GPRS_CONTEXT_TYPE_INTERNET);
			ofono_gprs_add_context(md->gprs, gc);
		}

		gc = ofono_gprs_context_create(modem, OFONO_RIL_VENDOR_MTK,
						RILMODEM, &mms_ctx);
		if (gc) {
			ofono_gprs_context_set_type(gc,
					OFONO_GPRS_CONTEXT_TYPE_MMS);
			ofono_gprs_add_context(md->gprs, gc);
		}

		md->message_waiting = ofono_message_waiting_create(modem);
		if (md->message_waiting)
			ofono_message_waiting_register(md->message_waiting);

		/*
		 * Now that we can access IMSI, see if a FW change is needed.
		 */

	 	md->sim_plmn_type = get_plmn_type(ofono_sim_get_imsi(md->sim));

		check_modem_fw(modem);

	} else if (new_state == OFONO_SIM_STATE_LOCKED_OUT) {

		DBG("SIM locked, removing atoms");

		if (md->message_waiting) {
			ofono_message_waiting_remove(md->message_waiting);
			md->message_waiting = NULL;
		}
		if (md->gprs) {
			ofono_gprs_remove(md->gprs);
			md->gprs = NULL;
		}
		if (md->phonebook) {
			ofono_phonebook_remove(md->phonebook);
			md->phonebook = NULL;
		}
		if (md->call_barring) {
			ofono_call_barring_remove(md->call_barring);
			md->call_barring = NULL;
		}
		if (md->call_forwarding) {
			ofono_call_forwarding_remove(md->call_forwarding);
			md->call_forwarding = NULL;
		}
		if (md->call_settings) {
			ofono_call_settings_remove(md->call_settings);
			md->call_settings = NULL;
		}
		if (md->ussd) {
			ofono_ussd_remove(md->ussd);
			md->ussd = NULL;
		}
		if (md->netreg) {
			ofono_netreg_remove(md->netreg);
			md->netreg = NULL;
		}
		if (md->sms) {
			ofono_sms_remove(md->sms);
			md->sms = NULL;
		}
	}
}
Ejemplo n.º 4
0
static void at_creg_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *nd = ofono_netreg_get_data(netreg);

	if (!ok) {
		ofono_error("Unable to initialize Network Registration");
		ofono_netreg_remove(netreg);
		return;
	}

	switch (nd->vendor) {
	case OFONO_VENDOR_PHONESIM:
		g_at_chat_register(nd->chat, "+CSQ:",
					csq_notify, FALSE, netreg, NULL);
		break;
	case OFONO_VENDOR_CALYPSO:
		g_at_chat_send(nd->chat, "AT%CSQ=1", none_prefix,
				NULL, NULL, NULL);
		g_at_chat_register(nd->chat, "%CSQ:", calypso_csq_notify,
					FALSE, netreg, NULL);
		break;
	case OFONO_VENDOR_OPTION_HSO:
		g_at_chat_send(nd->chat, "AT_OSSYS=1", none_prefix,
				NULL, NULL, NULL);
		g_at_chat_send(nd->chat, "AT_OSQI=1", none_prefix,
				NULL, NULL, NULL);
		g_at_chat_register(nd->chat, "_OSIGQ:", option_osigq_notify,
					FALSE, netreg, NULL);

		g_at_chat_send(nd->chat, "AT_OSSYS?", none_prefix,
				NULL, NULL, NULL);
		g_at_chat_send(nd->chat, "AT_OSQI?", none_prefix,
				NULL, NULL, NULL);

		/* Register for network time update reports */
		g_at_chat_register(nd->chat, "+CTZV:", ctzv_notify,
						FALSE, netreg, NULL);
		g_at_chat_send(nd->chat, "AT+CTZR=1", none_prefix,
						NULL, NULL, NULL);
		break;
	case OFONO_VENDOR_MBM:
		/* Enable network registration updates */
		g_at_chat_send(nd->chat, "AT*E2REG=1", none_prefix,
						NULL, NULL, NULL);
		g_at_chat_send(nd->chat, "AT*EREG=2", none_prefix,
						NULL, NULL, NULL);
		g_at_chat_send(nd->chat, "AT*EPSB=1", none_prefix,
						NULL, NULL, NULL);

		/* Register for network technology updates */
		g_at_chat_send(nd->chat, "AT*ERINFO=1", none_prefix,
						NULL, NULL, NULL);
		g_at_chat_register(nd->chat, "*ERINFO:", mbm_erinfo_notify,
						FALSE, netreg, NULL);

		/* Register for network time update reports */
		g_at_chat_register(nd->chat, "*ETZV:", mbm_etzv_notify,
						FALSE, netreg, NULL);
		g_at_chat_send(nd->chat, "AT*ETZR=2", none_prefix,
						NULL, NULL, NULL);

		g_at_chat_send(nd->chat, "AT+CIND=?", cind_prefix,
					cind_support_cb, netreg, NULL);
		return;
	case OFONO_VENDOR_GOBI:
		/*
		 * Gobi devices don't support unsolicited notifications
		 * of technology changes, but register a handle for
		 * CNTI so we get notified by any query.
		 */
		g_at_chat_register(nd->chat, "*CNTI:", gobi_cnti_notify,
					FALSE, netreg, NULL);
		break;
	case OFONO_VENDOR_NOVATEL:
		/*
		 * Novatel doesn't support unsolicited notifications
		 * of technology changes, but register a handle for
		 * CNTI so we get notified by any query.
		 */
		g_at_chat_register(nd->chat, "$CNTI:", nw_cnti_notify,
					FALSE, netreg, NULL);
		break;
	case OFONO_VENDOR_HUAWEI:
		g_at_chat_register(nd->chat, "^RSSI:", huawei_rssi_notify,
					FALSE, netreg, NULL);
		break;
	case OFONO_VENDOR_IFX:
		/* Register for specific signal strength reports */
		g_at_chat_register(nd->chat, "+XCIEV:", ifx_xciev_notify,
						FALSE, netreg, NULL);
		g_at_chat_send(nd->chat, "AT+XMER=1", none_prefix,
						NULL, NULL, NULL);

		/* Register for home zone reports */
		g_at_chat_register(nd->chat, "+XHOMEZR:", ifx_xhomezr_notify,
						FALSE, netreg, NULL);
		g_at_chat_send(nd->chat, "AT+XHOMEZR=1", none_prefix,
						NULL, NULL, NULL);

		/* Register for network time update reports */
		g_at_chat_register(nd->chat, "+CTZV:", ifx_ctzv_notify,
						FALSE, netreg, NULL);
		g_at_chat_register(nd->chat, "+CTZDST:", ifx_ctzdst_notify,
						FALSE, netreg, NULL);
		g_at_chat_send(nd->chat, "AT+CTZR=1", none_prefix,
						NULL, NULL, NULL);
		break;
	case OFONO_VENDOR_ZTE:
	case OFONO_VENDOR_NOKIA:
		/* Signal strength reporting via CIND is not supported */
		break;
	default:
		g_at_chat_send(nd->chat, "AT+CIND=?", cind_prefix,
				cind_support_cb, netreg, NULL);
		return;
	}

	g_at_chat_register(nd->chat, "+CREG:",
				creg_notify, FALSE, netreg, NULL);
	ofono_netreg_register(netreg);
}
Ejemplo n.º 5
0
static void cind_support_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *nd = ofono_netreg_get_data(netreg);
	GAtResultIter iter;
	const char *str;
	int index;
	int min = 0;
	int max = 0;
	int tmp_min, tmp_max, invalid;

	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);
	if (!g_at_result_iter_next(&iter, "+CIND:"))
		goto error;

	index = 1;

	/*
	 * Telit encapsulates the CIND=? tokens with braces
	 * so we need to skip them
	 */
	if (nd->vendor == OFONO_VENDOR_TELIT)
		g_at_result_iter_open_list(&iter);

	while (g_at_result_iter_open_list(&iter)) {
		/* Reset invalid default value for every token */
		invalid = 99;

		if (!g_at_result_iter_next_string(&iter, &str))
			goto error;

		if (!g_at_result_iter_open_list(&iter))
			goto error;

		while (g_at_result_iter_next_range(&iter, &tmp_min, &tmp_max)) {
			if (tmp_min != tmp_max) {
				min = tmp_min;
				max = tmp_max;
			} else
				invalid = tmp_min;
		}

		if (!g_at_result_iter_close_list(&iter))
			goto error;

		if (!g_at_result_iter_close_list(&iter))
			goto error;

		if (g_str_equal("signal", str) == TRUE) {
			nd->signal_index = index;
			nd->signal_min = min;
			nd->signal_max = max;
			nd->signal_invalid = invalid;
		}

		index += 1;
	}

	if (nd->vendor == OFONO_VENDOR_TELIT)
		g_at_result_iter_close_list(&iter);

	if (nd->signal_index == 0)
		goto error;

	g_at_chat_send(nd->chat, "AT+CMER=3,0,0,1", NULL,
			NULL, NULL, NULL);
	g_at_chat_register(nd->chat, "+CIEV:",
				ciev_notify, FALSE, netreg, NULL);
	g_at_chat_register(nd->chat, "+CREG:",
				creg_notify, FALSE, netreg, NULL);

	ofono_netreg_register(netreg);
	return;

error:
	ofono_error("This driver is not setup with Signal Strength reporting"
			" via CIND indications, please write proper netreg"
			" handling for this device");

	ofono_netreg_remove(netreg);
}