static void event_notify(struct qmi_result *result, void *user_data) { struct ofono_netreg *netreg = user_data; struct netreg_data *data = ofono_netreg_get_data(netreg); const struct qmi_nas_signal_strength *ss; const struct qmi_nas_rf_info *rf; uint16_t len; DBG(""); ss = qmi_result_get(result, QMI_NAS_NOTIFY_SIGNAL_STRENGTH, &len); if (ss) { int strength; DBG("signal with %d dBm on %d", ss->dbm, ss->rat); strength = dbm_to_strength(ss->dbm); ofono_netreg_strength_notify(netreg, strength); } rf = qmi_result_get(result, QMI_NAS_NOTIFY_RF_INFO, &len); if (rf) { uint8_t i; for (i = 0; i < rf->count; i++) { DBG("rat %d band %d channel %d", rf->info[i].rat, rf->info[i].band, rf->info[i].channel); } data->current_rat = rf->info[i].rat; } }
static void get_pin_status_cb(struct qmi_result *result, void *user_data) { struct cb_data *cbd = user_data; ofono_sim_passwd_cb_t cb = cbd->cb; struct sim_data *data = cbd->user; const struct qmi_dms_pin_status *pin; uint16_t len; int pin_type; DBG(""); if (qmi_result_set_error(result, NULL)) { CALLBACK_WITH_FAILURE(cb, -1, cbd->data); return; } pin = qmi_result_get(result, QMI_DMS_RESULT_PIN1_STATUS, &len); if (!pin) { CALLBACK_WITH_FAILURE(cb, -1, cbd->data); return; } DBG("PIN 1 status %d", pin->status); switch (pin->status) { case QMI_DMS_PIN_ENABLED_UNVERIFIED: pin_type = OFONO_SIM_PASSWORD_SIM_PIN; break; case QMI_DMS_PIN_ENABLED_VERIFIED: case QMI_DMS_PIN_DISABLED: pin_type = OFONO_SIM_PASSWORD_NONE; break; default: pin_type = OFONO_SIM_PASSWORD_INVALID; break; } data->retries[OFONO_SIM_PASSWORD_SIM_PIN] = pin->verify_retries; data->retries[OFONO_SIM_PASSWORD_SIM_PUK] = pin->unblock_retries; pin = qmi_result_get(result, QMI_DMS_RESULT_PIN2_STATUS, &len); if (!pin) goto done; DBG("PIN 2 status %d", pin->status); data->retries[OFONO_SIM_PASSWORD_SIM_PIN2] = pin->verify_retries; data->retries[OFONO_SIM_PASSWORD_SIM_PUK2] = pin->unblock_retries; done: CALLBACK_WITH_SUCCESS(cb, pin_type, cbd->data); }
static void get_rssi_cb(struct qmi_result *result, void *user_data) { struct cb_data *cbd = user_data; ofono_netreg_strength_cb_t cb = cbd->cb; const struct qmi_nas_signal_strength *ss; uint16_t len; int strength; DBG(""); if (qmi_result_set_error(result, NULL)) { CALLBACK_WITH_FAILURE(cb, -1, cbd->data); return; } ss = qmi_result_get(result, QMI_NAS_RESULT_SIGNAL_STRENGTH, &len); if (!ss) { CALLBACK_WITH_FAILURE(cb, -1, cbd->data); return; } DBG("signal with %d dBm on %d", ss->dbm, ss->rat); strength = dbm_to_strength(ss->dbm); CALLBACK_WITH_SUCCESS(cb, strength, cbd->data); }
static bool extract_ss_info(struct qmi_result *result, int *status, int *lac, int *cellid, int *tech, struct ofono_network_operator *operator) { const struct qmi_nas_serving_system *ss; const struct qmi_nas_current_plmn *plmn; uint8_t i, roaming; uint16_t value16, len, opname_len; uint32_t value32; DBG(""); ss = qmi_result_get(result, QMI_NAS_RESULT_SERVING_SYSTEM, &len); if (!ss) return false; *status = ss->status; DBG("serving system status %d", ss->status); *tech = -1; for (i = 0; i < ss->radio_if_count; i++) { DBG("radio in use %d", ss->radio_if[i]); *tech = qmi_nas_rat_to_tech(ss->radio_if[i]); } if (qmi_result_get_uint8(result, QMI_NAS_RESULT_ROAMING_STATUS, &roaming)) { if (ss->status == 1 && roaming == 0) *status = NETWORK_REGISTRATION_STATUS_ROAMING; } if (!operator) return true; plmn = qmi_result_get(result, QMI_NAS_RESULT_CURRENT_PLMN, &len); if (plmn) { snprintf(operator->mcc, OFONO_MAX_MCC_LENGTH + 1, "%03d", GUINT16_FROM_LE(plmn->mcc)); snprintf(operator->mnc, OFONO_MAX_MNC_LENGTH + 1, "%02d", GUINT16_FROM_LE(plmn->mnc)); opname_len = plmn->desc_len; if (opname_len > OFONO_MAX_OPERATOR_NAME_LENGTH) opname_len = OFONO_MAX_OPERATOR_NAME_LENGTH; /* * Telit QMI modems can return non-utf-8 characters in * plmn-desc. When that happens, libdbus will abort ofono. * If non-utf-8 characters are detected, use mccmnc string. */ if (g_utf8_validate(plmn->desc, opname_len, NULL)) { strncpy(operator->name, plmn->desc, opname_len); operator->name[opname_len] = '\0'; } else snprintf(operator->name, OFONO_MAX_OPERATOR_NAME_LENGTH, "%s%s", operator->mcc, operator->mnc); DBG("%s (%s:%s)", operator->name, operator->mcc, operator->mnc); } if (qmi_result_get_uint16(result, QMI_NAS_RESULT_LOCATION_AREA_CODE, &value16)) *lac = value16; else *lac = -1; if (qmi_result_get_uint32(result, QMI_NAS_RESULT_CELL_ID, &value32)) *cellid = value32; else *cellid = -1; DBG("lac %d cellid %d tech %d", *lac, *cellid, *tech); return true; }
static void scan_nets_cb(struct qmi_result *result, void *user_data) { struct cb_data *cbd = user_data; ofono_netreg_operator_list_cb_t cb = cbd->cb; struct ofono_network_operator *list; const struct qmi_nas_network_list *netlist; const struct qmi_nas_network_rat *netrat; const void *ptr; uint16_t len, num, offset, i; DBG(""); if (qmi_result_set_error(result, NULL)) { CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data); return; } ptr = qmi_result_get(result, QMI_NAS_RESULT_NETWORK_LIST, &len); if (!ptr) { CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data); return; } netlist = ptr; num = GUINT16_FROM_LE(netlist->count); DBG("found %d operators", num); list = g_try_new0(struct ofono_network_operator, num); if (!list) { CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data); return; } offset = 2; for (i = 0; i < num; i++) { const struct qmi_nas_network_info *netinfo = ptr + offset; snprintf(list[i].mcc, OFONO_MAX_MCC_LENGTH + 1, "%03d", GUINT16_FROM_LE(netinfo->mcc)); snprintf(list[i].mnc, OFONO_MAX_MNC_LENGTH + 1, "%02d", GUINT16_FROM_LE(netinfo->mnc)); strncpy(list[i].name, netinfo->desc, netinfo->desc_len); list[i].name[netinfo->desc_len] = '\0'; if (netinfo->status & 0x10) list[i].status = 3; else if (netinfo->status & 0x01) list[i].status = 2; else if (netinfo->status & 0x02) list[i].status = 1; else list[i].status = 0; list[i].tech = -1; DBG("%s (%s:%s) status %d", list[i].name, list[i].mcc, list[i].mnc, list[i].status); offset += sizeof(struct qmi_nas_network_info) + netinfo->desc_len; } netrat = qmi_result_get(result, QMI_NAS_RESULT_NETWORK_RAT, &len); if (!netrat) goto done; if (GUINT16_FROM_LE(netrat->count) != num) goto done; for (i = 0; i < num; i++) { DBG("%03d:%02d %d", netrat->info[i].mcc, netrat->info[i].mnc, netrat->info[i].rat); list[i].tech = qmi_nas_rat_to_tech(netrat->info[i].rat); } done: CALLBACK_WITH_SUCCESS(cb, num, list, cbd->data); g_free(list); }