static gboolean hfp_netreg_register(gpointer user_data) { struct ofono_netreg *netreg = user_data; ofono_netreg_register(netreg); return FALSE; }
static void set_event_cb(struct qmi_result *result, void *user_data) { struct ofono_netreg *netreg = user_data; DBG(""); ofono_netreg_register(netreg); }
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; }
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; }
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); }
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); }
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); }