static void ril_cops_list_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_netreg_operator_list_cb_t cb = cbd->cb; struct netreg_data *nd = cbd->user; struct reply_avail_ops *reply = NULL; struct ofono_network_operator *ops; struct reply_operator *operator; GSList *l; unsigned int i = 0; if (message->error != RIL_E_SUCCESS) { ofono_error("%s: failed to retrive the list of operators", __func__); goto error; } reply = g_ril_reply_parse_avail_ops(nd->ril, message); if (reply == NULL) goto error; ops = g_try_new0(struct ofono_network_operator, reply->num_ops); if (ops == NULL) { ofono_error("%s: can't allocate ofono_network_operator", __func__); goto error; } for (l = reply->list; l; l = l->next) { operator = l->data; set_oper_name(operator, &ops[i]); extract_mcc_mnc(operator->numeric, ops[i].mcc, ops[i].mnc); ops[i].tech = ril_tech_to_access_tech(operator->tech); /* Set the proper status */ if (!strcmp(operator->status, "unknown")) ops[i].status = OPERATOR_STATUS_UNKNOWN; else if (!strcmp(operator->status, "available")) ops[i].status = OPERATOR_STATUS_AVAILABLE; else if (!strcmp(operator->status, "current")) ops[i].status = OPERATOR_STATUS_CURRENT; else if (!strcmp(operator->status, "forbidden")) ops[i].status = OPERATOR_STATUS_FORBIDDEN; i++; } CALLBACK_WITH_SUCCESS(cb, reply->num_ops, ops, cbd->data); g_ril_reply_free_avail_ops(reply); return; error: CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data); g_ril_reply_free_avail_ops(reply); }
struct reply_avail_ops *g_ril_reply_parse_avail_ops(GRil *gril, const struct ril_msg *message) { struct parcel rilp; struct reply_operator *operator; struct reply_avail_ops *reply = NULL; unsigned int num_ops, num_strings; unsigned int i; int strings_per_opt; if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) strings_per_opt = 5; else strings_per_opt = 4; /* * Minimum message length is 4: * - array size */ if (message->buf_len < 4) { ofono_error("%s: invalid QUERY_AVAIL_NETWORKS reply: " "size too small (< 4): %d ", __func__, (int) message->buf_len); goto error; } g_ril_init_parcel(message, &rilp); g_ril_append_print_buf(gril, "{"); /* Number of operators at the list */ num_strings = (unsigned int) parcel_r_int32(&rilp); if (num_strings % strings_per_opt) { ofono_error("%s: invalid QUERY_AVAIL_NETWORKS reply: " "num_strings (%d) MOD %d != 0", __func__, num_strings, strings_per_opt); goto error; } num_ops = num_strings / strings_per_opt; DBG("noperators = %d", num_ops); reply = g_try_new0(struct reply_avail_ops, 1); if (reply == NULL) { ofono_error("%s: can't allocate reply struct", __func__); goto error; } reply->num_ops = num_ops; for (i = 0; i < num_ops; i++) { operator = g_try_new0(struct reply_operator, 1); if (operator == NULL) { ofono_error("%s: can't allocate reply struct", __func__); goto error; } operator->lalpha = parcel_r_string(&rilp); operator->salpha = parcel_r_string(&rilp); operator->numeric = parcel_r_string(&rilp); operator->status = parcel_r_string(&rilp); /* * MTK: additional string with technology: 2G/3G are the only * valid values currently. */ if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) { char *tech = parcel_r_string(&rilp); if (strcmp(tech, "3G") == 0) operator->tech = RADIO_TECH_UMTS; else operator->tech = RADIO_TECH_GSM; g_free(tech); } else { operator->tech = RADIO_TECH_GSM; } if (operator->lalpha == NULL && operator->salpha == NULL) { ofono_error("%s: operator (%s) doesn't specify names", operator->numeric, __func__); g_ril_reply_free_operator(operator); continue; } if (operator->numeric == NULL) { ofono_error("%s: operator (%s/%s) " "doesn't specify numeric", operator->lalpha, operator->salpha, __func__); g_ril_reply_free_operator(operator); continue; } if (operator->status == NULL) { ofono_error("%s: operator (%s/%s) " "doesn't specify status", operator->lalpha, operator->salpha, __func__); g_ril_reply_free_operator(operator); continue; } reply->list = g_slist_append(reply->list, operator); g_ril_append_print_buf(gril, "%s [lalpha=%s, salpha=%s, " " numeric=%s status=%s tech=%s]", print_buf, operator->lalpha, operator->salpha, operator->numeric, operator->status, ril_radio_tech_to_string(operator->tech)); } g_ril_append_print_buf(gril, "%s}", print_buf); g_ril_print_response(gril, message); return reply; error: if (reply) g_ril_reply_free_avail_ops(reply); return NULL; }