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);
}
Пример #2
0
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;
}