Example #1
0
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;
}
Example #2
0
File: sim.c Project: endocode/ofono
static gboolean parse_sim_io(GRil *ril, struct ril_msg *message,
				int *sw1, int *sw2, char **hex_response)
{
	struct parcel rilp;

	/*
	 * Minimum length of SIM_IO_Response is 12:
	 * sw1 (int32)
	 * sw2 (int32)
	 * simResponse (string)
	 */
	if (message->buf_len < 12) {
		ofono_error("Invalid SIM IO reply: size too small (< 12): %u",
				message->buf_len);
		return FALSE;
	}

	g_ril_init_parcel(message, &rilp);
	*sw1 = parcel_r_int32(&rilp);
	*sw2 = parcel_r_int32(&rilp);

	*hex_response = parcel_r_string(&rilp);

	g_ril_append_print_buf(ril, "(sw1=0x%.2X,sw2=0x%.2X,%s)",
				*sw1, *sw2, *hex_response);
	g_ril_print_response(ril, message);

	if (rilp.malformed) {
		g_free(*hex_response);
		return FALSE;
	}

	return TRUE;
}
Example #3
0
struct unsol_supp_svc_notif *g_ril_unsol_parse_supp_svc_notif(GRil *gril,
						struct ril_msg *message)
{
	struct parcel rilp;
	char *tmp_number;
	int type;
	struct unsol_supp_svc_notif *unsol =
		g_new0(struct unsol_supp_svc_notif, 1);

	g_ril_init_parcel(message, &rilp);

	unsol->notif_type = parcel_r_int32(&rilp);
	unsol->code = parcel_r_int32(&rilp);
	unsol->index = parcel_r_int32(&rilp);
	type = parcel_r_int32(&rilp);
	tmp_number = parcel_r_string(&rilp);

	if (tmp_number != NULL) {
		strncpy(unsol->number.number, tmp_number,
			OFONO_MAX_PHONE_NUMBER_LENGTH);
		unsol->number.type = type;
		g_free(tmp_number);
	}

	g_ril_append_print_buf(gril, "{%d,%d,%d,%d,%s}",
				unsol->notif_type, unsol->code, unsol->index,
				type, tmp_number);
	g_ril_print_unsol(gril, message);

	return unsol;
}
Example #4
0
static void ril_call_barring_set_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_call_barring_set_cb_t cb = cbd->cb;
	struct barring_data *bd = cbd->user;
	struct parcel rilp;
	int retries = -1;

	if (message->error != RIL_E_SUCCESS)
		goto error;

	g_ril_init_parcel(message, &rilp);

	/* mako reply has no payload for call barring */
	if (parcel_data_avail(&rilp) == 0)
		goto done;

	if (parcel_r_int32(&rilp) != 1)
		goto error;

	retries = parcel_r_int32(&rilp);

	if (rilp.malformed)
		goto error;

done:
	g_ril_append_print_buf(bd->ril, "{%d}", retries);
	g_ril_print_response(bd->ril, message);

	CALLBACK_WITH_SUCCESS(cb, cbd->data);
	return;

error:
	CALLBACK_WITH_FAILURE(cb, cbd->data);
}
Example #5
0
int g_ril_reply_parse_query_facility_lock(GRil *gril,
						const struct ril_msg *message)
{
	struct parcel rilp;
	int status, numint;

	g_ril_init_parcel(message, &rilp);

	/* infineon returns two integers */
	numint = parcel_r_int32(&rilp);
	if (numint < 1) {
		ofono_error("%s: wrong format", __func__);
		goto error;
	}

	status = parcel_r_int32(&rilp);

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

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

	return status;

error:
	return -1;
}
Example #6
0
File: sim.c Project: endocode/ofono
static void ril_query_facility_lock_cb(struct ril_msg *message,
							gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_query_facility_lock_cb_t cb = cbd->cb;
	struct sim_data *sd = cbd->user;
	struct parcel rilp;
	ofono_bool_t status;
	int numparams;

	if (message->error != RIL_E_SUCCESS)
		goto error;

	g_ril_init_parcel(message, &rilp);

	numparams = parcel_r_int32(&rilp);
	if (numparams < 1)
		goto error;

	status = (ofono_bool_t) parcel_r_int32(&rilp);

	g_ril_append_print_buf(sd->ril, "{%d}", status);
	g_ril_print_response(sd->ril, message);

	CALLBACK_WITH_SUCCESS(cb, status, cbd->data);
	return;

error:
	CALLBACK_WITH_FAILURE(cb, 0, cbd->data);
}
Example #7
0
File: sim.c Project: endocode/ofono
static void ril_enter_sim_puk_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
	struct ofono_sim *sim = cbd->user;
	struct sim_data *sd = ofono_sim_get_data(sim);
	struct parcel rilp;

	g_ril_init_parcel(message, &rilp);

	parcel_r_int32(&rilp);

	if (message->error != RIL_E_SUCCESS) {
		sd->retries[OFONO_SIM_PASSWORD_SIM_PUK] = parcel_r_int32(&rilp);
	} else {
		sd->retries[OFONO_SIM_PASSWORD_SIM_PIN] = -1;
		sd->retries[OFONO_SIM_PASSWORD_SIM_PUK] = -1;
	}

	g_ril_append_print_buf(sd->ril, "{%d}",
				sd->retries[OFONO_SIM_PASSWORD_SIM_PUK]);
	g_ril_print_response(sd->ril, message);

	if (message->error == RIL_E_SUCCESS) {
		CALLBACK_WITH_SUCCESS(cb, cbd->data);
		return;
	}

	CALLBACK_WITH_FAILURE(cb, cbd->data);
}
Example #8
0
int g_ril_reply_parse_set_facility_lock(GRil *gril,
					const struct ril_msg *message)
{
	struct parcel rilp;
	int retries = -1, numint;

	g_ril_init_parcel(message, &rilp);

	/* mako reply has no payload for call barring */
	if (parcel_data_avail(&rilp) == 0)
		goto end;

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

	retries = parcel_r_int32(&rilp);

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

end:
	g_ril_append_print_buf(gril, "{%d}", retries);
	g_ril_print_response(gril, message);

	return retries;
}
Example #9
0
static void ril_call_barring_query_cb(struct ril_msg *message,
					gpointer user_data)
{
	struct cb_data *cbd = user_data;
	struct parcel rilp;
	struct ofono_error error;
	ofono_call_barring_query_cb_t cb = cbd->cb;
	int bearer_class = 0;

	if (message->error != RIL_E_SUCCESS) {
		ofono_error("Call Barring query failed, err: %i",
			message->error);
		decode_ril_error(&error, "FAIL");
		goto out;
	}

	ril_util_init_parcel(message, &rilp);

	/*
	 * Services for which the specified barring facility is active.
	 * "0" means "disabled for all, -1 if unknown"
	 */
	parcel_r_int32(&rilp); /* count - we know there is only 1 */
	bearer_class = parcel_r_int32(&rilp);
	DBG("Active services: %i", bearer_class);

	decode_ril_error(&error, "OK");

out:
	cb(&error, bearer_class, cbd->data);
}
Example #10
0
int g_ril_reply_parse_sms_response(GRil *gril, const struct ril_msg *message)
{
	struct parcel rilp;
	int error, mr;
	char *ack_pdu;

	/* Set up Parcel struct for proper parsing */
	g_ril_init_parcel(message, &rilp);

	/*
	 * TP-Message-Reference for GSM/
	 * BearerData MessageId for CDMA
	 */
	mr = parcel_r_int32(&rilp);
	ack_pdu = parcel_r_string(&rilp);
	error = parcel_r_int32(&rilp);

	g_ril_append_print_buf(gril, "{%d,%s,%d}",
				mr, ack_pdu, error);
	g_ril_print_response(gril, message);

	g_free(ack_pdu);

	return mr;
}
Example #11
0
int g_ril_reply_parse_query_call_waiting(GRil *gril,
						const struct ril_msg *message)
{
	struct parcel rilp;
	int numint, enabled, cls;

	g_ril_init_parcel(message, &rilp);

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

	enabled = parcel_r_int32(&rilp);

	if (enabled > 0)
		cls = parcel_r_int32(&rilp);
	else
		cls = 0;

	g_ril_append_print_buf(gril, "{%d,0x%x}", enabled, cls);
	g_ril_print_response(gril, message);

	return cls;

error:
	return -1;
}
Example #12
0
static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
	struct sim_data *sd = cbd->user;
	struct parcel rilp;
	int retry_count;
	int retries[OFONO_SIM_PASSWORD_INVALID];
	int passwd_type;
	/* There is no reason to ask SIM status until
	 * unsolicited sim status change indication
	 * Looks like state does not change before that.
	 */

	passwd_type = sd->passwd_type;
	ril_util_init_parcel(message, &rilp);
	parcel_r_int32(&rilp);
	retry_count = parcel_r_int32(&rilp);
	retries[passwd_type] = retry_count;
	sd->retries[passwd_type] = retries[passwd_type];

	DBG("result=%d passwd_type=%d retry_count=%d",
		message->error, passwd_type, retry_count);
	if (message->error == RIL_E_SUCCESS) {
		CALLBACK_WITH_SUCCESS(cb, cbd->data);
		g_ril_print_response_no_args(sd->ril, message);

	} else {
		if (current_passwd)
			g_stpcpy(current_passwd, defaultpasswd);
		CALLBACK_WITH_FAILURE(cb, cbd->data);
	}

}
Example #13
0
static void ril_call_barring_query_cb(struct ril_msg *message,
					gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_call_barring_query_cb_t cb = cbd->cb;
	struct barring_data *bd = cbd->user;
	struct parcel rilp;
	int bearer_class;

	if (message->error != RIL_E_SUCCESS)
		goto error;

	g_ril_init_parcel(message, &rilp);

	/* TODO: infineon returns two integers, use a quirk here */
	if (parcel_r_int32(&rilp) < 1)
		goto error;

	bearer_class = parcel_r_int32(&rilp);

	if (bearer_class < 0 || rilp.malformed)
		goto error;

	g_ril_append_print_buf(bd->ril, "{%d}", bearer_class);
	g_ril_print_response(bd->ril, message);

	CALLBACK_WITH_SUCCESS(cb, bearer_class, cbd->data);
	return;

error:
	CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
}
Example #14
0
static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data)
{
	DBG("");
	struct cb_data *cbd = user_data;
	ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb;
	struct parcel rilp, rilp_out;
	int mode = OFONO_RADIO_ACCESS_MODE_ANY;
	int pref;
	struct radio_data *rd = NULL;

	if (message->error == RIL_E_SUCCESS) {
		ril_util_init_parcel(message, &rilp);
		/*first item in int[] is len so let's skip that*/
		parcel_r_int32(&rilp);
		pref = parcel_r_int32(&rilp);

		switch (pref) {
		case PREF_NET_TYPE_LTE_ONLY:
			mode = OFONO_RADIO_ACCESS_MODE_LTE;
		case PREF_NET_TYPE_GSM_ONLY:
			mode = OFONO_RADIO_ACCESS_MODE_GSM;
			break;
		case PREF_NET_TYPE_WCDMA:
		case PREF_NET_TYPE_GSM_WCDMA: /* according to UI design */
		case PREF_NET_TYPE_GSM_WCDMA_AUTO:/* according to UI design */
			mode = OFONO_RADIO_ACCESS_MODE_UMTS;
			break;
		case PREF_NET_TYPE_LTE_CDMA_EVDO:
		case PREF_NET_TYPE_LTE_GSM_WCDMA:
		case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
			if (!cb) {
				rd = cbd->user;
				parcel_init(&rilp_out);
				parcel_w_int32(&rilp_out, 1);
				parcel_w_int32(&rilp_out, rd->ratmode);
				g_ril_send(rd->ril,
					RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE,
					rilp_out.data, rilp_out.size, NULL,
					NULL, g_free);
				parcel_free(&rilp_out);
			}
			break;
		case PREF_NET_TYPE_CDMA_EVDO_AUTO:
		case PREF_NET_TYPE_CDMA_ONLY:
		case PREF_NET_TYPE_EVDO_ONLY:
		case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO:
		default:
			break;
		}
		if (cb)
			CALLBACK_WITH_SUCCESS(cb, mode, cbd->data);
	} else {
		if (cb)
			CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
	}
}
Example #15
0
struct reply_sim_io *g_ril_reply_parse_sim_io(GRil *gril,
						const struct ril_msg *message)
{
	struct parcel rilp;
	char *response = NULL;
	struct reply_sim_io *reply;

	/*
	 * Minimum length of SIM_IO_Response is 12:
	 * sw1 (int32)
	 * sw2 (int32)
	 * simResponse (string)
	 */
	if (message->buf_len < 12) {
		ofono_error("Invalid SIM IO reply: size too small (< 12): %d ",
			    (int) message->buf_len);
		return NULL;
	}

	reply =	g_new0(struct reply_sim_io, 1);

	g_ril_init_parcel(message, &rilp);
	reply->sw1 = parcel_r_int32(&rilp);
	reply->sw2 = parcel_r_int32(&rilp);

	response = parcel_r_string(&rilp);

	g_ril_append_print_buf(gril,
				"(sw1=0x%.2X,sw2=0x%.2X,%s)",
				reply->sw1,
				reply->sw2,
				response);
	g_ril_print_response(gril, message);

	if (rilp.malformed)
		goto error;

	if (response != NULL) {
		reply->hex_response =
			decode_hex(response, strlen(response),
					(long *) &reply->hex_len, -1);
		g_free(response);

		if (reply->hex_response == NULL)
			goto error;
	}

	return reply;

error:
	g_free(reply);

	return NULL;
}
Example #16
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;
}
Example #17
0
static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data)
{
	DBG("");
	struct cb_data *cbd = user_data;
	ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb;
	struct parcel rilp;
	int mode = OFONO_RADIO_ACCESS_MODE_ANY;
	int pref;

	if (message->error == RIL_E_SUCCESS) {
		ril_util_init_parcel(message, &rilp);
		/* first item in int[] is len so let's skip that */
		parcel_r_int32(&rilp);
		pref = parcel_r_int32(&rilp);

		switch (pref) {
		case PREF_NET_TYPE_LTE_ONLY:
			mode = OFONO_RADIO_ACCESS_MODE_LTE;
		case PREF_NET_TYPE_GSM_ONLY:
			mode = OFONO_RADIO_ACCESS_MODE_GSM;
			break;
		case PREF_NET_TYPE_GSM_WCDMA_AUTO:/* according to UI design */
			if (!cb)
				ril_force_rat_mode(cbd->user, pref);
		case PREF_NET_TYPE_WCDMA:
		case PREF_NET_TYPE_GSM_WCDMA: /* according to UI design */
			mode = OFONO_RADIO_ACCESS_MODE_UMTS;
			break;
		case PREF_NET_TYPE_LTE_CDMA_EVDO:
		case PREF_NET_TYPE_LTE_GSM_WCDMA:
		case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
			if (!cb)
				ril_force_rat_mode(cbd->user, pref);
			break;
		case PREF_NET_TYPE_CDMA_EVDO_AUTO:
		case PREF_NET_TYPE_CDMA_ONLY:
		case PREF_NET_TYPE_EVDO_ONLY:
		case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO:
		default:
			break;
		}
		ofono_info("rat mode %d (ril %d)", mode, pref);
		if (cb)
			CALLBACK_WITH_SUCCESS(cb, mode, cbd->data);
	} else {
		if (cb)
			CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
		ofono_error("rat mode query failed");
	}
}
Example #18
0
static void ril_radio_state_changed(struct ril_msg *message,
							gpointer user_data)
{
	struct ofono_modem *modem = user_data;
	struct ril_data *rd = ofono_modem_get_data(modem);
	struct parcel rilp;
	int radio_state;

	g_ril_init_parcel(message, &rilp);
	radio_state = parcel_r_int32(&rilp);

	if (rilp.malformed) {
		ofono_error("%s: malformed parcel received", __func__);
		ofono_modem_set_powered(modem, FALSE);
		return;
	}

	g_ril_append_print_buf(rd->ril, "(state: %s)",
				ril_radio_state_to_string(radio_state));
	g_ril_print_unsol(rd->ril, message);

	switch (radio_state) {
	case RADIO_STATE_ON:
		break;
	case RADIO_STATE_UNAVAILABLE:
		ofono_modem_set_powered(modem, FALSE);
		break;
	case RADIO_STATE_OFF:
		break;
	}
}
Example #19
0
void *parcel_r_raw(struct parcel *p, int *len)
{
	char *ret;

	*len = parcel_r_int32(p);

	if (p->malformed || *len <= 0)
		return NULL;

	if (p->offset + *len > p->size) {
		ofono_error("%s: parcel is too small", __func__);
		p->malformed = 1;
		return NULL;
	}

	ret = g_try_malloc0(*len);
	if (ret == NULL) {
		ofono_error("%s: out of memory (%d bytes)", __func__, *len);
		return NULL;
	}

	memcpy(ret, p->data + p->offset, *len);
	p->offset += *len;

	return ret;
}
Example #20
0
char *parcel_r_string(struct parcel *p)
{
	char *ret;
	int len16 = parcel_r_int32(p);
	int strbytes;

	if (p->malformed)
		return NULL;

	/* This is how a null string is sent */
	if (len16 < 0)
		return NULL;

	strbytes = PAD_SIZE((len16 + 1) * sizeof(char16_t));
	if (p->offset + strbytes > p->size) {
		ofono_error("%s: parcel is too small", __func__);
		p->malformed = 1;
		return NULL;
	}

	ret = g_utf16_to_utf8((gunichar2 *) (void *) (p->data + p->offset),
				len16, NULL, NULL, NULL);
	if (ret == NULL) {
		ofono_error("%s: wrong UTF16 coding", __func__);
		p->malformed = 1;
		return NULL;
	}

	p->offset += strbytes;

	return ret;
}
Example #21
0
static void ril_cops_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_netreg_operator_cb_t cb = cbd->cb;
	struct netreg_data *nd = cbd->user;
	struct ofono_error error;
	struct parcel rilp;
	struct ofono_network_operator op;
	gchar *lalpha, *salpha, *numeric;

	if (message->error == RIL_E_SUCCESS) {
		decode_ril_error(&error, "OK");
	} else {
		ofono_error("Failed to retrive the current operator");
		goto error;
	}

	ril_util_init_parcel(message, &rilp);

	/* Size of char ** */
	if (parcel_r_int32(&rilp) == 0)
		goto error;

	lalpha = parcel_r_string(&rilp);
	salpha = parcel_r_string(&rilp);
	numeric = parcel_r_string(&rilp);

	/* Try to use long by default */
	if (lalpha)
		strncpy(op.name, lalpha, OFONO_MAX_OPERATOR_NAME_LENGTH);
	else if (salpha)
		strncpy(op.name, salpha, OFONO_MAX_OPERATOR_NAME_LENGTH);
	else
		goto error;

	extract_mcc_mnc(numeric, op.mcc, op.mnc);

	/* Set to current */
	op.status = OPERATOR_STATUS_CURRENT;
	op.tech = nd->tech;

	g_ril_append_print_buf(nd->ril,
				"(lalpha=%s, salpha=%s, numeric=%s, %s, mcc=%s, mnc=%s, %s)",
				lalpha, salpha, numeric,
				op.name, op.mcc, op.mnc,
				registration_tech_to_string(op.tech));
	g_ril_print_response(nd->ril, message);

	g_free(lalpha);
	g_free(salpha);
	g_free(numeric);

	cb(&error, &op, cbd->data);

	return;

error:
	CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
}
Example #22
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);
}
Example #23
0
int g_ril_reply_parse_get_mute(GRil *gril, const struct ril_msg *message)
{
	struct parcel rilp;
	int muted;

	g_ril_init_parcel(message, &rilp);

	/* skip length of int[] */
	parcel_r_int32(&rilp);
	muted = parcel_r_int32(&rilp);

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

	return muted;

}
Example #24
0
File: ril.c Project: endocode/ofono
static void ril_radio_state_changed(struct ril_msg *message, gpointer user_data)
{
	struct ofono_modem *modem = user_data;
	struct ril_data *rd = ofono_modem_get_data(modem);
	struct parcel rilp;
	int radio_state;

	g_ril_init_parcel(message, &rilp);

	radio_state = parcel_r_int32(&rilp);

	if (rilp.malformed) {
		ofono_error("%s: malformed parcel received", __func__);
		ofono_modem_set_powered(modem, FALSE);
		return;
	}

	g_ril_append_print_buf(rd->ril, "(state: %s)",
				ril_radio_state_to_string(radio_state));
	g_ril_print_unsol(rd->ril, message);

	if (radio_state != rd->radio_state) {
		ofono_info("%s: state: %s rd->ofono_online: %d",
				__func__,
				ril_radio_state_to_string(radio_state),
				rd->ofono_online);

		rd->radio_state = radio_state;

		switch (radio_state) {
		case RADIO_STATE_ON:
			if (rd->radio_settings == NULL)
				rd->radio_settings =
					ofono_radio_settings_create(modem,
							rd->vendor, RILMODEM,
							rd->ril);

			break;

		case RADIO_STATE_UNAVAILABLE:
		case RADIO_STATE_OFF:
			/*
			 * Unexpected radio state change, as we are supposed to
			 * be online. UNAVAILABLE has been seen occassionally
			 * when powering off the phone. We wait 5 secs to avoid
			 * too fast re-spawns, then exit with error to make
			 * upstart re-start ofono.
			 */
			if (rd->ofono_online)
				ofono_error("%s: radio self-powered off!",
						__func__);

			break;
		}
	}
}
Example #25
0
static void lastcause_cb(struct ril_msg *message, gpointer user_data)
{
	struct lastcause_req *reqdata = user_data;
	struct ofono_voicecall *vc = reqdata->vc;
	int id = reqdata->id;

	enum ofono_disconnect_reason reason = OFONO_DISCONNECT_REASON_ERROR;
	int last_cause = CALL_FAIL_ERROR_UNSPECIFIED;
	struct parcel rilp;
	ril_util_init_parcel(message, &rilp);
	if (parcel_r_int32(&rilp) > 0)
		last_cause = parcel_r_int32(&rilp);

	DBG("Call %d ended with RIL cause %d", id, last_cause);
	if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY) {
		reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
	}

	ofono_voicecall_disconnected(vc, id, reason, NULL);
}
Example #26
0
File: sim.c Project: endocode/ofono
static void ril_enter_sim_pin_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
	struct ofono_sim *sim = cbd->user;
	struct sim_data *sd = ofono_sim_get_data(sim);
	struct parcel rilp;

	/*
	 * There is no reason to ask SIM status until
	 * unsolicited sim status change indication
	 * Looks like state does not change before that.
	 */
	DBG("Enter password: type %d, result %d",
				sd->passwd_type, message->error);

	g_ril_init_parcel(message, &rilp);

	parcel_r_int32(&rilp);

	if (message->error == RIL_E_SUCCESS)
		sd->retries[sd->passwd_type] = -1;
	else
		sd->retries[sd->passwd_type] = parcel_r_int32(&rilp);

	g_ril_append_print_buf(sd->ril, "{%d}",
				sd->retries[sd->passwd_type]);
	g_ril_print_response(sd->ril, message);

	if (message->error == RIL_E_SUCCESS) {
		CALLBACK_WITH_SUCCESS(cb, cbd->data);
		return;
	}

	CALLBACK_WITH_FAILURE(cb, cbd->data);
	/*
	 * Refresh passwd_state (not needed if the unlock is
	 * successful, as an event will refresh the state in that case)
	 */
	send_get_sim_status(sim);
}
Example #27
0
static void probe_mute_cb(struct ril_msg *message, gpointer user_data)
{
	struct ofono_call_volume *cv = user_data;
	struct cv_data *cvd = ofono_call_volume_get_data(cv);
	struct parcel rilp;
	int muted;

	if (message->error != RIL_E_SUCCESS)
		return;

	g_ril_init_parcel(message, &rilp);

	/* skip length of int[] */
	parcel_r_int32(&rilp);
	muted = parcel_r_int32(&rilp);

	g_ril_append_print_buf(cvd->ril, "{%d}", muted);
	g_ril_print_response(cvd->ril, message);

	ofono_call_volume_set_muted(cv, muted);
}
Example #28
0
enum ofono_disconnect_reason g_ril_reply_parse_call_fail_cause(
				GRil *gril, const struct ril_msg *message)
{
	enum ofono_disconnect_reason reason = OFONO_DISCONNECT_REASON_ERROR;
	int last_cause = CALL_FAIL_ERROR_UNSPECIFIED;
	struct parcel rilp;

	g_ril_init_parcel(message, &rilp);

	if (rilp.size < sizeof(int32_t))
		ofono_error("%s: Parcel is too small", __func__);
	else if (parcel_r_int32(&rilp) > 0)
		last_cause = parcel_r_int32(&rilp);

	if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY)
		reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;

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

	return reason;
}
Example #29
0
struct reply_clir *g_ril_reply_parse_get_clir(GRil *gril,
						const struct ril_msg *message)
{
	struct parcel rilp;
	struct reply_clir *rclir;
	int numint;

	rclir = g_try_malloc0(sizeof(*rclir));
	if (rclir == NULL) {
		ofono_error("%s Out of memory", __func__);
		goto error;
	}

	g_ril_init_parcel(message, &rilp);

	/* Length */
	numint = parcel_r_int32(&rilp);
	if (numint != 2) {
		ofono_error("%s Wrong format", __func__);
		goto error;
	}

	/* Set HideCallerId property from network */
	rclir->status = parcel_r_int32(&rilp);

	/* State of the CLIR supplementary service in the network */
	rclir->provisioned = parcel_r_int32(&rilp);

	g_ril_append_print_buf(gril, "{%d,%d}",
				rclir->status, rclir->provisioned);
	g_ril_print_response(gril, message);

	return rclir;

error:
	g_free(rclir);
	return NULL;
}
Example #30
0
File: parcel.c Project: 8l/inferno
char*
parcel_r_string(struct parcel *p)
{
	char *ret;
	int len16 = parcel_r_int32(p);
	size_t len8;
	if(len16 < 0) return NULL; // this is how a null string is sent
	len8 = strnlen16to8((char16_t *) (p->data + p->offset), len16);
	ret = malloc(len8 + 1);
	if(ret == NULL) return NULL;
	strncpy16to8(ret, (char16_t *) (p->data + p->offset), len16);
	p->offset += PAD_SIZE((len16 + 1) * sizeof(char16_t));
	return ret;
}