예제 #1
0
static gboolean hfp_netreg_register(gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;

	ofono_netreg_register(netreg);

	return FALSE;
}
예제 #2
0
static void set_event_cb(struct qmi_result *result, void *user_data)
{
	struct ofono_netreg *netreg = user_data;

	DBG("");

	ofono_netreg_register(netreg);
}
예제 #3
0
static gboolean hfp_netreg_register(gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *nd = ofono_netreg_get_data(netreg);

	nd->register_source = 0;

	g_at_chat_register(nd->chat, "+CIEV:", ciev_notify, FALSE,
							netreg, NULL);

	ofono_netreg_register(netreg);

	return FALSE;
}
예제 #4
0
static gboolean ril_delayed_register(gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *nd = ofono_netreg_get_data(netreg);
	ofono_netreg_register(netreg);

	/* Register for network state changes */
	g_ril_register(nd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
			ril_network_state_change, netreg);

	/* Register for network time update reports */
	g_ril_register(nd->ril, RIL_UNSOL_NITZ_TIME_RECEIVED,
			ril_nitz_notify, netreg);

	/* Register for signal strength changes */
	g_ril_register(nd->ril, RIL_UNSOL_SIGNAL_STRENGTH,
			ril_strength_notify, netreg);

	/* This makes the timeout a single-shot */
	return FALSE;
}
예제 #5
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);
}
예제 #6
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);
}
예제 #7
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);
}