Exemple #1
0
static void ril_sim_update_binary(struct ofono_sim *sim, int fileid,
					int start, int length,
					const unsigned char *value,
					const unsigned char *path,
					unsigned int path_len,
					ofono_sim_write_cb_t cb, void *data)
{
	struct sim_data *sd = ofono_sim_get_data(sim);
	struct cb_data *cbd = cb_data_new(cb, data, sd);
	char *hex_path;
	struct parcel rilp;
	char *hex_data;
	int p1, p2;

	DBG("file 0x%04x", fileid);

	hex_path = get_path(g_ril_vendor(sd->ril),
					sd->app_type, fileid, path, path_len);
	if (hex_path == NULL) {
		ofono_error("Couldn't build SIM read info request - NULL path");
		goto error;
	}

	p1 = start >> 8;
	p2 = start & 0xff;
	hex_data = encode_hex(value, length, 0);

	parcel_init(&rilp);
	parcel_w_int32(&rilp, CMD_UPDATE_BINARY);
	parcel_w_int32(&rilp, fileid);
	parcel_w_string(&rilp, hex_path);
	parcel_w_int32(&rilp, p1);		/* P1 */
	parcel_w_int32(&rilp, p2);		/* P2 */
	parcel_w_int32(&rilp, length);		/* P3 (Lc) */
	parcel_w_string(&rilp, hex_data);	/* data */
	parcel_w_string(&rilp, NULL);		/* pin2; only for FDN/BDN */
	parcel_w_string(&rilp, sd->aid_str);	/* AID (Application ID) */

	/* sessionId, specific to latest MTK modems (harmless for older ones) */
	if (g_ril_vendor(sd->ril) == OFONO_RIL_VENDOR_MTK)
		parcel_w_int32(&rilp, 0);

	g_ril_append_print_buf(sd->ril, "(cmd=0x%02X,efid=0x%04X,path=%s,"
					"%d,%d,%d,%s,pin2=(null),aid=%s),",
					CMD_UPDATE_BINARY, fileid, hex_path,
					p1, p2, length, hex_data, sd->aid_str);
	g_free(hex_path);
	g_free(hex_data);

	if (g_ril_send(sd->ril, RIL_REQUEST_SIM_IO, &rilp,
				ril_file_write_cb, cbd, g_free) > 0)
		return;

error:
	g_free(cbd);
	CALLBACK_WITH_FAILURE(cb, data);
}
Exemple #2
0
static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
				int start, int length,
				const unsigned char *path,
				unsigned int path_len,
				ofono_sim_read_cb_t cb, void *data)
{
	struct sim_data *sd = ofono_sim_get_data(sim);
	struct cb_data *cbd = cb_data_new(cb, data, sd);
	char *hex_path;
	struct parcel rilp;

	DBG("file %04x", fileid);

	hex_path = get_path(g_ril_vendor(sd->ril),
					sd->app_type, fileid, path, path_len);
	if (hex_path == NULL) {
		ofono_error("Couldn't build SIM read info request - NULL path");
		goto error;
	}

	parcel_init(&rilp);
	parcel_w_int32(&rilp, CMD_READ_BINARY);
	parcel_w_int32(&rilp, fileid);
	parcel_w_string(&rilp, hex_path);
	parcel_w_int32(&rilp, start >> 8);   /* P1 */
	parcel_w_int32(&rilp, start & 0xff); /* P2 */
	parcel_w_int32(&rilp, length);         /* P3 */
	parcel_w_string(&rilp, NULL);          /* data; only req'd for writes */
	parcel_w_string(&rilp, NULL);          /* pin2; only req'd for writes */
	parcel_w_string(&rilp, sd->aid_str);

	/* sessionId, specific to latest MTK modems (harmless for older ones) */
	if (g_ril_vendor(sd->ril) == OFONO_RIL_VENDOR_MTK)
		parcel_w_int32(&rilp, 0);

	g_ril_append_print_buf(sd->ril, "(cmd=0x%.2X,efid=0x%.4X,path=%s,"
					"%d,%d,%d,(null),pin2=(null),aid=%s)",
					CMD_READ_BINARY, fileid, hex_path,
					start >> 8, start & 0xff,
					length, sd->aid_str);
	g_free(hex_path);

	if (g_ril_send(sd->ril, RIL_REQUEST_SIM_IO, &rilp,
				ril_file_io_cb, cbd, g_free) > 0)
		return;

error:
	g_free(cbd);
	CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
}
Exemple #3
0
static void set_data_reg_state(GRil *gril, struct reply_data_reg_state *reply,
				int i, const char *str)
{
	unsigned val;
	char *endp;

	if (str == NULL || *str == '\0')
		goto no_val;

	val = (unsigned) strtoul(str, &endp, 10);
	if (*endp != '\0')
		goto no_val;

	switch (i) {
	case RDST_IX_MAXDC:
		/*
		 * MTK modem does not return max_cids, string for this index
		 * actually contains the maximum data bearer capability.
		 */
		if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK)
			reply->max_cids = MTK_MODEM_MAX_CIDS;
		else
			reply->max_cids = val;
		g_ril_append_print_buf(gril, "%s%u", print_buf, val);
		break;
	default:
		goto no_val;
	}

	return;

no_val:
	g_ril_append_print_buf(gril, "%s%s", print_buf, str ? str : "(null)");
}
int g_ril_unsol_parse_connected(GRil *gril, const struct ril_msg *message)
{
	struct parcel rilp;
	int size;
	int version;

	DBG("");

	g_ril_init_parcel(message, &rilp);

	size = parcel_r_int32(&rilp);
	version = parcel_r_int32(&rilp);

	/*
	 * For something that looks like a bug we get an extra int in mtk2
	 * modems. RIL version is the second integer in this case. This
	 * happens when we get duplicated connected events, which should
	 * not happen either. In these cases the first event has the right
	 * size, but not those appearing after.
	 */
	if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK2 && size > 1)
		version = parcel_r_int32(&rilp);

	if (rilp.malformed) {
		ofono_error("%s: malformed parcel", __func__);
		version = RIL_VERSION_UNSPECIFIED;
	}

	g_ril_append_print_buf(gril, "{size: %d, [%d]}", size, version);
	g_ril_print_unsol(gril, message);

	return version;
}
Exemple #5
0
void g_ril_request_set_initial_attach_apn(GRil *gril, const char *apn,
						int proto,
						const char *user,
						const char *passwd,
						const char *mccmnc,
						struct parcel *rilp)
{
	const char *proto_str;
	const int auth_type = RIL_AUTH_ANY;

	parcel_init(rilp);

	parcel_w_string(rilp, apn);

	proto_str = ril_ofono_protocol_to_ril_string(proto);
	parcel_w_string(rilp, proto_str);

	parcel_w_int32(rilp, auth_type);
	parcel_w_string(rilp, user);
	parcel_w_string(rilp, passwd);

	g_ril_append_print_buf(gril, "(%s,%s,%s,%s,%s", apn, proto_str,
				ril_authtype_to_string(auth_type),
				user, passwd);

	if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) {
		parcel_w_string(rilp, mccmnc);
		g_ril_append_print_buf(gril, "%s,%s)", print_buf, mccmnc);
	} else {
		g_ril_append_print_buf(gril, "%s)", print_buf);
	}
}
Exemple #6
0
gboolean g_ril_request_sim_read_record(GRil *gril,
					const struct req_sim_read_record *req,
					struct parcel *rilp)
{
	parcel_init(rilp);
	parcel_w_int32(rilp, CMD_READ_RECORD);
	parcel_w_int32(rilp, req->fileid);

	g_ril_append_print_buf(gril,
				"(cmd=0x%.2X,efid=0x%.4X,",
				CMD_READ_RECORD,
				req->fileid);

	if (set_path(gril, req->app_type, rilp, req->fileid,
			req->path, req->path_len) == FALSE)
		goto error;

	parcel_w_int32(rilp, req->record);      /* P1 */
	parcel_w_int32(rilp, 4);           /* P2 */
	parcel_w_int32(rilp, req->length);      /* P3 */
	parcel_w_string(rilp, NULL);       /* data; only req'd for writes */
	parcel_w_string(rilp, NULL);       /* pin2; only req'd for writes */
	parcel_w_string(rilp, req->aid_str); /* AID (Application ID) */

	/* sessionId, specific to latest MTK modems (harmless for older ones) */
	if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK)
		parcel_w_int32(rilp, 0);

	return TRUE;

error:
	return FALSE;
}
Exemple #7
0
static void ril_ussd_notify(struct ril_msg *message, gpointer user_data)
{
	struct ofono_ussd *ussd = user_data;
	struct ussd_data *ud = ofono_ussd_get_data(ussd);
	struct parcel rilp;
	int numstr;
	char *typestr;
	int type;
	char *str = NULL;
	gsize written;
	char *ucs2;

	g_ril_init_parcel(message, &rilp);

	numstr = parcel_r_int32(&rilp);
	if (numstr < 1)
		return;

	typestr = parcel_r_string(&rilp);
	if (typestr == NULL || *typestr == '\0')
		return;

	type = *typestr - '0';
	g_free(typestr);

	if (numstr > 1)
		str = parcel_r_string(&rilp);

	g_ril_append_print_buf(ud->ril, "{%d,%s}", type, str);

	g_ril_print_unsol(ud->ril, message);

	/* To fix bug in MTK: USSD-Notify arrive with type 2 instead of 0 */
	if (g_ril_vendor(ud->ril) == OFONO_RIL_VENDOR_MTK &&
			str != NULL && type == 2)
		type = 0;

	if (str == NULL) {
		ofono_ussd_notify(ussd, type, 0, NULL, 0);
		return;
	}

	/*
	 * With data coding scheme 0x48, we are saying that the ussd string is a
	 * UCS-2 string, uncompressed, and with unspecified message class. For
	 * the DCS coding, see 3gpp 23.038, sect. 5.
	 */
	ucs2 = g_convert(str, -1, "UCS-2BE//TRANSLIT",
					"UTF-8", NULL, &written, NULL);
	g_free(str);

	if (ucs2 == NULL) {
		ofono_error("%s: Error transcoding", __func__);
		return;
	}

	ofono_ussd_notify(ussd, type, 0x48, (unsigned char *) ucs2, written);
	g_free(ucs2);
}
Exemple #8
0
int g_ril_reply_parse_get_preferred_network_type(GRil *gril,
						const struct ril_msg *message)
{
	struct parcel rilp;
	int numint, parcel_net_type, net_type;

	g_ril_init_parcel(message, &rilp);

	numint = parcel_r_int32(&rilp);
	if (numint != 1) {
		ofono_error("%s: Wrong format", __func__);
		goto error;
	}

	parcel_net_type = parcel_r_int32(&rilp);
	net_type = parcel_net_type;

	/* Try to translate special MTK settings */
	if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) {
		switch (net_type) {
		/* 4G preferred */
		case MTK_PREF_NET_TYPE_LTE_GSM_WCDMA:
		case MTK_PREF_NET_TYPE_LTE_GSM_WCDMA_MMDC:
		case MTK_PREF_NET_TYPE_LTE_GSM_TYPE:
		case MTK_PREF_NET_TYPE_LTE_GSM_MMDC_TYPE:
			net_type = PREF_NET_TYPE_LTE_GSM_WCDMA;
			break;
		/* 3G or 2G preferred over LTE */
		case MTK_PREF_NET_TYPE_GSM_WCDMA_LTE:
		case MTK_PREF_NET_TYPE_GSM_WCDMA_LTE_MMDC:
			net_type = PREF_NET_TYPE_GSM_WCDMA;
			break;
		}
	}

	if (net_type < 0 || net_type > PREF_NET_TYPE_LTE_ONLY) {
		ofono_error("%s: unknown network type", __func__);
		goto error;
	}

	if (rilp.malformed) {
		ofono_error("%s: malformed parcel", __func__);
		goto error;
	}

	g_ril_append_print_buf(gril, "{%d}", parcel_net_type);
	g_ril_print_response(gril, message);

	return net_type;

error:
	return -1;
}
Exemple #9
0
gboolean g_ril_request_sim_write_binary(GRil *gril,
					const struct req_sim_write_binary *req,
					struct parcel *rilp)
{
	char *hex_data;
	int p1, p2;

	parcel_init(rilp);
	parcel_w_int32(rilp, CMD_UPDATE_BINARY);
	parcel_w_int32(rilp, req->fileid);

	g_ril_append_print_buf(gril, "(cmd=0x%02X,efid=0x%04X,",
				CMD_UPDATE_BINARY, req->fileid);

	if (set_path(gril, req->app_type, rilp, req->fileid,
			req->path, req->path_len) == FALSE)
		goto error;

	p1 = req->start >> 8;
	p2 = req->start & 0xff;
	hex_data = encode_hex(req->data, req->length, 0);

	parcel_w_int32(rilp, p1);		/* P1 */
	parcel_w_int32(rilp, p2);		/* P2 */
	parcel_w_int32(rilp, req->length);	/* P3 (Lc) */
	parcel_w_string(rilp, hex_data);	/* data */
	parcel_w_string(rilp, NULL);		/* pin2; only for FDN/BDN */
	parcel_w_string(rilp, req->aid_str);	/* AID (Application ID) */

	/* sessionId, specific to latest MTK modems (harmless for older ones) */
	if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK)
		parcel_w_int32(rilp, 0);

	g_ril_append_print_buf(gril,
				"%s%d,%d,%d,%s,pin2=(null),aid=%s)",
				print_buf,
				p1,
				p2,
				req->length,
				hex_data,
				req->aid_str);

	g_free(hex_data);

	return TRUE;

error:
	return FALSE;
}
Exemple #10
0
gboolean g_ril_request_sim_read_info(GRil *gril,
					const struct req_sim_read_info *req,
					struct parcel *rilp)
{
	parcel_init(rilp);

	parcel_w_int32(rilp, CMD_GET_RESPONSE);
	parcel_w_int32(rilp, req->fileid);

	g_ril_append_print_buf(gril,
				"(cmd=0x%.2X,efid=0x%.4X,",
				CMD_GET_RESPONSE,
				req->fileid);

	if (set_path(gril, req->app_type, rilp, req->fileid,
			req->path, req->path_len) == FALSE)
		goto error;

	parcel_w_int32(rilp, 0);           /* P1 */
	parcel_w_int32(rilp, 0);           /* P2 */

	/*
	 * TODO: review parameters values used by Android.
	 * The values of P1-P3 in this code were based on
	 * values used by the atmodem driver impl.
	 *
	 * NOTE:
	 * GET_RESPONSE_EF_SIZE_BYTES == 15; !255
	 */
	parcel_w_int32(rilp, 15);         /* P3 - max length */
	parcel_w_string(rilp, NULL);       /* data; only req'd for writes */
	parcel_w_string(rilp, NULL);       /* pin2; only req'd for writes */
	parcel_w_string(rilp, req->aid_str); /* AID (Application ID) */

	/*
	 * sessionId, specific to latest MTK modems (harmless for older ones).
	 * It looks like this field selects one or another SIM application, but
	 * we use only one at a time so using zero here seems safe.
	 */
	if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK)
		parcel_w_int32(rilp, 0);

	return TRUE;

error:
	return FALSE;
}
Exemple #11
0
static void ril_ussd_notify(struct ril_msg *message, gpointer user_data)
{
	struct ofono_ussd *ussd = user_data;
	struct ussd_data *ud = ofono_ussd_get_data(ussd);
	struct unsol_ussd *unsol;
	enum ofono_ril_vendor vendor;

	unsol = g_ril_unsol_parse_ussd(ud->ril, message);
	if (unsol == NULL) {
		ofono_error("%s: Parsing error", __func__);
		return;
	}

	/* To fix bug in MTK: USSD-Notify arrive with type 2 instead of 0 */
	vendor = g_ril_vendor(ud->ril);
	if ((vendor == OFONO_RIL_VENDOR_MTK ||
				vendor == OFONO_RIL_VENDOR_MTK2)
			&& unsol->message != NULL && unsol->type == 2)
		unsol->type = 0;

	/*
	 * With data coding scheme 0x48, we are saying that the ussd string is a
	 * UCS-2 string, uncompressed, and with unspecified message class. For
	 * the DCS coding, see 3gpp 23.038, sect. 5.
	 */
	if (unsol->message != NULL) {
		gsize written;
		char *ucs2;

		ucs2 = g_convert(unsol->message, -1, "UCS-2BE//TRANSLIT",
					"UTF-8", NULL, &written, NULL);
		if (ucs2 != NULL) {
			ofono_ussd_notify(ussd, unsol->type, 0x48,
					(unsigned char *) ucs2, written);
			g_free(ucs2);
		} else {
			ofono_error("%s: Error transcoding", __func__);
		}
	} else {
		ofono_ussd_notify(ussd, unsol->type, 0, NULL, 0);
	}

	g_ril_unsol_free_ussd(unsol);
}
Exemple #12
0
static void set_reg_state(GRil *gril, struct reply_reg_state *reply,
				int i, const char *str)
{
	int val;
	char *endp;
	int base;
	const char *strstate;

	if (str == NULL || *str == '\0')
		goto no_val;

	if (i == RST_IX_LAC || i == RST_IX_CID)
		base = 16;
	else
		base = 10;

	val = (int) strtol(str, &endp, base);
	if (*endp != '\0')
		goto no_val;

	switch (i) {
	case RST_IX_STATE:
		switch (val) {
		case RIL_REG_STATE_NOT_REGISTERED:
		case RIL_REG_STATE_REGISTERED:
		case RIL_REG_STATE_SEARCHING:
		case RIL_REG_STATE_DENIED:
		case RIL_REG_STATE_UNKNOWN:
		case RIL_REG_STATE_ROAMING:
			/* Only valid values for ofono */
			strstate = registration_status_to_string(val);
			break;
		case RIL_REG_STATE_EMERGENCY_NOT_REGISTERED:
		case RIL_REG_STATE_EMERGENCY_SEARCHING:
		case RIL_REG_STATE_EMERGENCY_DENIED:
		case RIL_REG_STATE_EMERGENCY_UNKNOWN:
			/* Map to states valid for ofono core */
			val -= RIL_REG_STATE_EMERGENCY_NOT_REGISTERED;
			strstate = str;
			break;
		default:
			val = NETWORK_REGISTRATION_STATUS_UNKNOWN;
			strstate = str;
		}
		reply->status = val;
		g_ril_append_print_buf(gril, "%s%s", print_buf, strstate);
		break;
	case RST_IX_LAC:
		reply->lac = val;
		g_ril_append_print_buf(gril, "%s0x%x", print_buf, val);
		break;
	case RST_IX_CID:
		reply->ci = val;
		g_ril_append_print_buf(gril, "%s0x%x", print_buf, val);
		break;
	case RST_IX_RAT:
		g_ril_append_print_buf(gril, "%s%s", print_buf,
					ril_radio_tech_to_string(val));

		if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) {
			switch (val) {
			case MTK_RADIO_TECH_HSDPAP:
			case MTK_RADIO_TECH_HSDPAP_UPA:
			case MTK_RADIO_TECH_HSUPAP:
			case MTK_RADIO_TECH_HSUPAP_DPA:
				val = RADIO_TECH_HSPAP;
				break;
			case MTK_RADIO_TECH_DC_DPA:
				val = RADIO_TECH_HSDPA;
				break;
			case MTK_RADIO_TECH_DC_UPA:
				val = RADIO_TECH_HSUPA;
				break;
			case MTK_RADIO_TECH_DC_HSDPAP:
			case MTK_RADIO_TECH_DC_HSDPAP_UPA:
			case MTK_RADIO_TECH_DC_HSDPAP_DPA:
			case MTK_RADIO_TECH_DC_HSPAP:
				val = RADIO_TECH_HSPAP;
				break;
			}
		}

		reply->tech = val;
		break;
	default:
		goto no_val;
	}

	return;

no_val:
	g_ril_append_print_buf(gril, "%s%s", print_buf, str ? str : "(null)");
}
Exemple #13
0
int *g_ril_reply_parse_retries(GRil *gril, const struct ril_msg *message,
				enum ofono_sim_password_type passwd_type)
{
	struct parcel rilp;
	int i, numint;
	int *retries = g_try_malloc0(sizeof(int) * OFONO_SIM_PASSWORD_INVALID);

	if (retries == NULL) {
		ofono_error("%s: out of memory", __func__);
		goto no_data;
	}

	for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; ++i)
		retries[i] = -1;

	g_ril_init_parcel(message, &rilp);

	/* maguro/infineon: no data is returned */
	if (parcel_data_avail(&rilp) == 0)
		goto no_data;

	numint = parcel_r_int32(&rilp);

	switch (g_ril_vendor(gril)) {
	case OFONO_RIL_VENDOR_AOSP:
	case OFONO_RIL_VENDOR_QCOM_MSIM:
		/*
		 * The number of retries is valid only when a wrong password has
		 * been introduced in Nexus 4. TODO: check Nexus 5 behaviour.
		 */
		if (message->error == RIL_E_PASSWORD_INCORRECT)
			retries[passwd_type] = parcel_r_int32(&rilp);

		g_ril_append_print_buf(gril, "{%d}", retries[passwd_type]);
		break;
	case OFONO_RIL_VENDOR_MTK:
		/*
		 * Some versions of MTK modem return just the retries for the
		 * password just entered while others return the retries for all
		 * passwords.
		 */
		if (numint == 1) {
			retries[passwd_type] = parcel_r_int32(&rilp);

			g_ril_append_print_buf(gril, "{%d}",
							retries[passwd_type]);
		} else if (numint == 4) {
			retries[OFONO_SIM_PASSWORD_SIM_PIN] =
							parcel_r_int32(&rilp);
			retries[OFONO_SIM_PASSWORD_SIM_PIN2] =
							parcel_r_int32(&rilp);
			retries[OFONO_SIM_PASSWORD_SIM_PUK] =
							parcel_r_int32(&rilp);
			retries[OFONO_SIM_PASSWORD_SIM_PUK2] =
							parcel_r_int32(&rilp);

			g_ril_append_print_buf(gril,
					"{pin %d, pin2 %d, puk %d, puk2 %d}",
					retries[OFONO_SIM_PASSWORD_SIM_PIN],
					retries[OFONO_SIM_PASSWORD_SIM_PIN2],
					retries[OFONO_SIM_PASSWORD_SIM_PUK],
					retries[OFONO_SIM_PASSWORD_SIM_PUK2]);
		} else {
			ofono_error("%s: wrong format", __func__);
			goto no_data;
		}
		break;
	case OFONO_RIL_VENDOR_INFINEON:
		ofono_error("%s: infineon type should not arrive here",
				__func__);
		g_assert(FALSE);
		break;
	}

	if (rilp.malformed) {
		ofono_error("%s: malformed parcel", __func__);
		goto no_data;
	}

	g_ril_print_response(gril, message);

	return retries;

no_data:
	g_free(retries);

	return NULL;
}
Exemple #14
0
gboolean g_ril_request_setup_data_call(GRil *gril,
					const struct req_setup_data_call *req,
					struct parcel *rilp,
					struct ofono_error *error)
{
	const gchar *protocol_str;
	gchar *tech_str;
	gchar *auth_str;
	gchar *profile_str;
	int num_param = SETUP_DATA_CALL_PARAMS;

	DBG("");

	if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK)
		num_param = SETUP_DATA_CALL_PARAMS + 1;

	/*
	 * Radio technology to use: 0-CDMA, 1-GSM/UMTS, 2...
	 * values > 2 are (RADIO_TECH + 2)
	 */
	if (req->tech < 1 || req->tech > (RADIO_TECH_GSM + 2)) {
		ofono_error("%s: Invalid tech value: %d",
				__func__,
				req->tech);
		goto error;
	}

	/*
	 * TODO(OEM): This code doesn't currently support
	 * OEM data profiles.  If a use case exist, then
	 * this code will need to be modified.
	 */
	switch (req->data_profile) {
	case RIL_DATA_PROFILE_DEFAULT:
		profile_str = DATA_PROFILE_DEFAULT_STR;
		break;
	case RIL_DATA_PROFILE_TETHERED:
		profile_str = DATA_PROFILE_TETHERED_STR;
		break;
	case RIL_DATA_PROFILE_IMS:
		profile_str = DATA_PROFILE_IMS_STR;
		break;
	case RIL_DATA_PROFILE_FOTA:
		profile_str = DATA_PROFILE_FOTA_STR;
		break;
	case RIL_DATA_PROFILE_CBS:
		profile_str = DATA_PROFILE_CBS_STR;
		break;
	case RIL_DATA_PROFILE_MTK_MMS:
		if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) {
			profile_str = DATA_PROFILE_MTK_MMS_STR;
			break;
		}
	default:
		ofono_error("%s, invalid data_profile value: %d",
				__func__,
				req->data_profile);
		goto error;
	}

	if (req->apn == NULL)
		goto error;

	if (req->auth_type > RIL_AUTH_BOTH) {
		ofono_error("%s: Invalid auth type: %d",
				__func__,
				req->auth_type);
		goto error;
	}

	protocol_str = ril_ofono_protocol_to_ril_string(req->protocol);
	if (protocol_str == NULL) {
		ofono_error("%s: Invalid protocol: %d",
				__func__,
				req->protocol);
		goto error;
	}

	parcel_init(rilp);

	parcel_w_int32(rilp, num_param);

	tech_str = g_strdup_printf("%d", req->tech);
	parcel_w_string(rilp, tech_str);
	parcel_w_string(rilp, profile_str);
	parcel_w_string(rilp, req->apn);
	parcel_w_string(rilp, req->username);
	parcel_w_string(rilp, req->password);

	auth_str = g_strdup_printf("%d", req->auth_type);
	parcel_w_string(rilp, auth_str);
	parcel_w_string(rilp, protocol_str);

	g_ril_append_print_buf(gril,
				"(%s,%s,%s,%s,%s,%s,%s",
				tech_str,
				profile_str,
				req->apn,
				req->username,
				req->password,
				auth_str,
				protocol_str);

	if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) {
		/* MTK request_cid parameter */
		char cid_str[MAX_CID_DIGITS + 1];

		snprintf(cid_str, sizeof(cid_str), "%u", req->req_cid);
		parcel_w_string(rilp, cid_str);
		g_ril_append_print_buf(gril, "%s,%s", print_buf, cid_str);
	}

	g_ril_append_print_buf(gril, "%s)", print_buf);

	g_free(tech_str);
	g_free(auth_str);

	OFONO_NO_ERROR(error);
	return TRUE;

error:
        OFONO_EINVAL(error);
	return FALSE;
}
Exemple #15
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;
}
Exemple #16
0
static void ril_sim_read_info(struct ofono_sim *sim, int fileid,
				const unsigned char *path,
				unsigned int path_len,
				ofono_sim_file_info_cb_t cb, void *data)
{
	struct sim_data *sd = ofono_sim_get_data(sim);
	struct cb_data *cbd = cb_data_new(cb, data, sd);
	struct parcel rilp;
	char *hex_path;

	DBG("file %04x", fileid);

	hex_path = get_path(g_ril_vendor(sd->ril),
					sd->app_type, fileid, path, path_len);
	if (hex_path == NULL) {
		ofono_error("Couldn't build SIM read info request - NULL path");
		goto error;
	}

	parcel_init(&rilp);

	parcel_w_int32(&rilp, CMD_GET_RESPONSE);
	parcel_w_int32(&rilp, fileid);
	parcel_w_string(&rilp, hex_path);
	parcel_w_int32(&rilp, 0);           /* P1 */
	parcel_w_int32(&rilp, 0);           /* P2 */

	/*
	 * TODO: review parameters values used by Android.
	 * The values of P1-P3 in this code were based on
	 * values used by the atmodem driver impl.
	 *
	 * NOTE:
	 * GET_RESPONSE_EF_SIZE_BYTES == 15; !255
	 */
	parcel_w_int32(&rilp, 15);         /* P3 - max length */
	parcel_w_string(&rilp, NULL);       /* data; only req'd for writes */
	parcel_w_string(&rilp, NULL);       /* pin2; only req'd for writes */
	parcel_w_string(&rilp, sd->aid_str); /* AID (Application ID) */

	/*
	 * sessionId, specific to latest MTK modems (harmless for older ones).
	 * It looks like this field selects one or another SIM application, but
	 * we use only one at a time so using zero here seems safe.
	 */
	if (g_ril_vendor(sd->ril) == OFONO_RIL_VENDOR_MTK)
		parcel_w_int32(&rilp, 0);

	g_ril_append_print_buf(sd->ril, "(cmd=0x%.2X,efid=0x%.4X,path=%s,"
					"0,0,15,(null),pin2=(null),aid=%s)",
					CMD_GET_RESPONSE, fileid, hex_path,
					sd->aid_str);
	g_free(hex_path);

	if (g_ril_send(sd->ril, RIL_REQUEST_SIM_IO, &rilp,
				ril_file_info_cb, cbd, g_free) > 0)
		return;

error:
	g_free(cbd);
	CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL,
				EF_STATUS_INVALIDATED, data);
}
Exemple #17
0
static gboolean set_path(GRil *ril, guint app_type,
				struct parcel *rilp,
				const int fileid, const guchar *path,
				const guint path_len)
{
	unsigned char db_path[6] = { 0x00 };
	unsigned char *comm_path = db_path;
	char *hex_path = NULL;
	int len = 0;

	if (path_len > 0 && path_len < 7) {
		memcpy(db_path, path, path_len);
		len = path_len;
	} else if (app_type == RIL_APPTYPE_USIM) {
		len = sim_ef_db_get_path_3g(fileid, db_path);
	} else if (app_type == RIL_APPTYPE_SIM) {
		len = sim_ef_db_get_path_2g(fileid, db_path);
	} else {
		ofono_error("Unsupported app_type: 0%x", app_type);
		return FALSE;
	}

	/*
	 * db_path contains the ID of the MF, but MediaTek modems return an
	 * error if we do not remove it. Other devices work the other way
	 * around: they need the MF in the path. In fact MTK behaviour seem to
	 * be the right one: to have the MF in the file is forbidden following
	 * ETSI TS 102 221, section 8.4.2 (we are accessing the card in mode
	 * "select by path from MF", see 3gpp 27.007, +CRSM).
	 */
	if (g_ril_vendor(ril) == OFONO_RIL_VENDOR_MTK && len >= (int) ROOTMF_SZ
			&& memcmp(db_path, ROOTMF, ROOTMF_SZ) == 0) {
		comm_path = db_path + ROOTMF_SZ;
		len -= ROOTMF_SZ;
	}

	if (len > 0) {
		hex_path = encode_hex(comm_path, len, 0);
		parcel_w_string(rilp, hex_path);

		g_ril_append_print_buf(ril,
					"%spath=%s,",
					print_buf,
					hex_path);

		g_free(hex_path);
	} else {
		/*
		 * The only known case of this is EFPHASE_FILED (0x6FAE).
		 * The ef_db table ( see /src/simutil.c ) entry for
		 * EFPHASE contains a value of 0x0000 for it's
		 * 'parent3g' member.  This causes a NULL path to
		 * be returned.
		 * (EF_PHASE does not exist for USIM)
		 */
		parcel_w_string(rilp, NULL);

		g_ril_append_print_buf(ril,
					"%spath=(null),",
					print_buf);
	}

	return TRUE;
}