Esempio n. 1
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;
	}
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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);
}
Esempio n. 5
0
File: ril.c Progetto: 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;
		}
	}
}
Esempio n. 6
0
struct unsol_ussd *g_ril_unsol_parse_ussd(GRil *gril, struct ril_msg *message)
{
	struct parcel rilp;
	struct unsol_ussd *ussd;
	char *typestr = NULL;
	int numstr;

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

	g_ril_init_parcel(message, &rilp);

	numstr = parcel_r_int32(&rilp);
	if (numstr < 1) {
		ofono_error("%s malformed parcel", __func__);
		goto error;
	}

	typestr = parcel_r_string(&rilp);
	if (typestr == NULL || *typestr == '\0') {
		ofono_error("%s wrong type", __func__);
		goto error;
	}

	ussd->type = *typestr - '0';

	g_free(typestr);

	if (numstr > 1)
		ussd->message = parcel_r_string(&rilp);

	g_ril_append_print_buf(gril, "{%d,%s}", ussd->type, ussd->message);

	g_ril_print_unsol(gril, message);

	return ussd;

error:
	g_free(typestr);
	g_free(ussd);

	return NULL;
}
Esempio n. 7
0
struct unsol_sms_data *g_ril_unsol_parse_new_sms(GRil *gril,
						const struct ril_msg *message)
{
	struct parcel rilp;
	char *ril_pdu;
	size_t ril_pdu_len;
	struct unsol_sms_data *sms_data;

	sms_data = g_new0(struct unsol_sms_data, 1);
	if (sms_data == NULL) {
		ofono_error("%s out of memory", __func__);
		goto error;
	}

	g_ril_init_parcel(message, &rilp);

	ril_pdu = parcel_r_string(&rilp);
	if (ril_pdu == NULL) {
		ofono_error("%s Unable to parse notification", __func__);
		goto error;
	}

	ril_pdu_len = strlen(ril_pdu);

	sms_data->data = decode_hex(ril_pdu, ril_pdu_len,
					&sms_data->length, -1);
	if (sms_data->data == NULL) {
		ofono_error("%s Unable to decode notification", __func__);
		goto error_dec;
	}

	g_ril_append_print_buf(gril, "{%s}", ril_pdu);
	g_ril_print_unsol(gril, message);

	g_free(ril_pdu);

	return sms_data;

error_dec:
	g_free(ril_pdu);
error:
	g_ril_unsol_free_sms_data(sms_data);
	return NULL;
}
Esempio n. 8
0
static void ril_nitz_notify(struct ril_msg *message, gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *nd = ofono_netreg_get_data(netreg);
	struct parcel rilp;
	int year, mon, mday, hour, min, sec, dst, tzi;
	char tzs, tz[4];
	gchar *nitz;

	if (message->req != RIL_UNSOL_NITZ_TIME_RECEIVED)
		goto error;


	ril_util_init_parcel(message, &rilp);

	nitz = parcel_r_string(&rilp);

	g_ril_append_print_buf(nd->ril, "(%s)", nitz);
	g_ril_print_unsol(nd->ril, message);

	sscanf(nitz, "%u/%u/%u,%u:%u:%u%c%u,%u", &year, &mon, &mday,
			&hour, &min, &sec, &tzs, &tzi, &dst);
	sprintf(tz, "%c%d", tzs, tzi);

	nd->time.utcoff = atoi(tz) * 15 * 60;
	nd->time.dst = dst;
	nd->time.sec = sec;
	nd->time.min = min;
	nd->time.hour = hour;
	nd->time.mday = mday;
	nd->time.mon = mon;
	nd->time.year = 2000 + year;

	ofono_netreg_time_notify(netreg, &nd->time);

	g_free(nitz);

	return;

error:
	ofono_error("Unable to notify ofono about nitz");
}
Esempio n. 9
0
int g_ril_unsol_parse_radio_state_changed(GRil *gril, const struct ril_msg *message)
{
	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__);
		radio_state = -1;
	}

	g_ril_append_print_buf(gril, "(state: %s)",
				ril_radio_state_to_string(radio_state));

	g_ril_print_unsol(gril, message);

	return radio_state;
}
Esempio n. 10
0
char *g_ril_unsol_parse_nitz(GRil *gril, const struct ril_msg *message)
{
	struct parcel rilp;
	gchar *nitz = NULL;

	DBG("");

	if (message->buf_len < MIN_NITZ_SIZE) {
		ofono_error("%s: NITZ too small: %d",
				__func__,
				(int) message->buf_len);
		goto error;
	}

	g_ril_init_parcel(message, &rilp);

	nitz = parcel_r_string(&rilp);

	g_ril_append_print_buf(gril, "(%s)", nitz);
	g_ril_print_unsol(gril, message);

error:
	return nitz;
}
Esempio n. 11
0
File: sms.c Progetto: leinomii/ofono
static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
{
	struct ofono_sms *sms = user_data;
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct parcel rilp;
	char *ril_pdu;
	int ril_pdu_len;
	unsigned int smsc_len;
	long ril_buf_len;
	guchar *ril_data;

	DBG("req: %d; data_len: %d", message->req, message->buf_len);

	switch (message->req) {
	case RIL_UNSOL_RESPONSE_NEW_SMS:
	case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
		break;
	default:
		goto error;
	}

	ril_util_init_parcel(message, &rilp);

	ril_pdu = parcel_r_string(&rilp);
	if (ril_pdu == NULL)
		goto error;

	ril_pdu_len = strlen(ril_pdu);

	DBG("ril_pdu_len is %d", ril_pdu_len);
	ril_data = decode_hex(ril_pdu, ril_pdu_len, &ril_buf_len, -1);
	if (ril_data == NULL)
		goto error;

	/* The first octect in the pdu contains the SMSC address length
	 * which is the X following octects it reads. We add 1 octet to
	 * the read length to take into account this read octet in order
	 * to calculate the proper tpdu length.
	 */
	smsc_len = ril_data[0] + 1;
	DBG("smsc_len is %d", smsc_len);

	g_ril_append_print_buf(sd->ril, "(%s)", ril_pdu);
	g_ril_print_unsol(sd->ril, message);

	if (message->req == RIL_UNSOL_RESPONSE_NEW_SMS) {
		/* Last parameter is 'tpdu_len' ( substract SMSC length ) */
		ofono_sms_deliver_notify(sms, ril_data,
				ril_buf_len,
				ril_buf_len - smsc_len);
	} else if (message->req == RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT) {
		ofono_sms_status_notify(sms, ril_data, ril_buf_len,
						ril_buf_len - smsc_len);
	}

	ril_ack_delivery(sms);

	return;

error:
	ofono_error("Unable to parse NEW_SMS notification");
}
Esempio n. 12
0
int g_ril_unsol_parse_signal_strength(GRil *gril, const struct ril_msg *message,
					int ril_tech)
{
	struct parcel rilp;
	int gw_sigstr, gw_signal, cdma_dbm, evdo_dbm;
	int lte_sigstr = -1, lte_rsrp = -1, lte_rssnr = -1;
	int lte_signal;
	int signal;

	g_ril_init_parcel(message, &rilp);

	/* RIL_SignalStrength_v5 */
	/* GW_SignalStrength */
	gw_sigstr = parcel_r_int32(&rilp);
	gw_signal = get_gsm_strength(gw_sigstr);
	parcel_r_int32(&rilp); /* bitErrorRate */

	/*
	 * CDMA/EVDO values are not processed as CDMA is not supported
	 */

	/* CDMA_SignalStrength */
	cdma_dbm = parcel_r_int32(&rilp);
	parcel_r_int32(&rilp); /* ecio */

	/* EVDO_SignalStrength */
	evdo_dbm = parcel_r_int32(&rilp);
	parcel_r_int32(&rilp); /* ecio */
	parcel_r_int32(&rilp); /* signalNoiseRatio */

	/* Present only for RIL_SignalStrength_v6 or newer */
	if (parcel_data_avail(&rilp) > 0) {
		/* LTE_SignalStrength */
		lte_sigstr = parcel_r_int32(&rilp);
		lte_rsrp = parcel_r_int32(&rilp);
		parcel_r_int32(&rilp); /* rsrq */
		lte_rssnr = parcel_r_int32(&rilp);
		parcel_r_int32(&rilp); /* cqi */
		lte_signal = get_lte_strength(lte_sigstr, lte_rsrp, lte_rssnr);
	} else {
		lte_signal = -1;
	}

	g_ril_append_print_buf(gril,
				"{gw: %d, cdma: %d, evdo: %d, lte: %d %d %d}",
				gw_sigstr, cdma_dbm, evdo_dbm, lte_sigstr,
				lte_rsrp, lte_rssnr);

	if (message->unsolicited)
		g_ril_print_unsol(gril, message);
	else
		g_ril_print_response(gril, message);

	/* Return the first valid one */
	if (gw_signal != -1 && lte_signal != -1)
		if (ril_tech == RADIO_TECH_LTE)
			signal = lte_signal;
		else
			signal = gw_signal;
	else if (gw_signal != -1)
		signal = gw_signal;
	else if (lte_signal != -1)
		signal = lte_signal;
	else
		signal = -1;

	return signal;
}
Esempio n. 13
0
/*
 * This function handles RIL_UNSOL_DATA_CALL_LIST_CHANGED messages,
 * as well as RIL_REQUEST_DATA_CALL_LIST/SETUP_DATA_CALL replies, as
 * all have the same payload.
 */
struct ril_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
						const struct ril_msg *message)
{
	struct ril_data_call *call;
	struct parcel rilp;
	struct ril_data_call_list *reply = NULL;
	unsigned int active, cid, i, num_calls, retry, status;
	char *type = NULL, *ifname = NULL, *raw_addrs = NULL;
	char *raw_dns = NULL, *raw_gws = NULL;

	DBG("");

	/* Can happen for RIL_REQUEST_DATA_CALL_LIST replies */
	if (message->buf_len < MIN_DATA_CALL_LIST_SIZE) {
		if (message->req == RIL_REQUEST_SETUP_DATA_CALL) {
			ofono_error("%s: message too small: %d",
					__func__,
					(int) message->buf_len);
			goto error;
		} else {
			g_ril_append_print_buf(gril, "{");
			goto done;
		}
	}

	reply = g_try_new0(struct ril_data_call_list, 1);
	if (reply == NULL) {
		ofono_error("%s: out of memory", __func__);
		goto error;
	}

	g_ril_init_parcel(message, &rilp);

	/*
	 * ril.h documents the reply to a RIL_REQUEST_DATA_CALL_LIST
	 * as being an array of  RIL_Data_Call_Response_v6 structs,
	 * however in reality, the response also includes a version
	 * to start.
	 */
	reply->version = parcel_r_int32(&rilp);
	num_calls = parcel_r_int32(&rilp);

	g_ril_append_print_buf(gril,
				"{version=%d,num=%d",
				reply->version,
				num_calls);

	for (i = 0; i < num_calls; i++) {
		status = parcel_r_int32(&rilp);
		retry = parcel_r_int32(&rilp);          /* ignore */
		cid = parcel_r_int32(&rilp);
		active = parcel_r_int32(&rilp);
		type = parcel_r_string(&rilp);
		ifname = parcel_r_string(&rilp);
		raw_addrs = parcel_r_string(&rilp);
		raw_dns = parcel_r_string(&rilp);
		raw_gws = parcel_r_string(&rilp);

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

		g_ril_append_print_buf(gril,
					"%s [status=%d,retry=%d,cid=%d,"
					"active=%d,type=%s,ifname=%s,"
					"address=%s,dns=%s,gateways=%s]",
					print_buf,
					status,
					retry,
					cid,
					active,
					type,
					ifname,
					raw_addrs,
					raw_dns,
					raw_gws);

		call = g_try_new0(struct ril_data_call, 1);
		if (call == NULL) {
			ofono_error("%s: out of memory", __func__);
			goto error;
		}

		call->status = status;
		call->cid = cid;
		call->active = active;

		if (message->req == RIL_REQUEST_SETUP_DATA_CALL &&
			status == PDP_FAIL_NONE &&
			handle_settings(call, type, ifname, raw_addrs,
					raw_dns, raw_gws) == FALSE)
			goto error;

		g_free(type);
		g_free(ifname);
		g_free(raw_addrs);
		g_free(raw_dns);
		g_free(raw_gws);

		reply->calls =
			g_slist_insert_sorted(reply->calls, call,
						data_call_compare);
	}

done:
	g_ril_append_print_buf(gril, "%s}", print_buf);

	if (message->unsolicited)
		g_ril_print_unsol(gril, message);
	else
		g_ril_print_response(gril, message);

	return reply;

error:
	g_free(type);
	g_free(ifname);
	g_free(raw_addrs);
	g_free(raw_dns);
	g_free(raw_gws);
	g_ril_unsol_free_data_call_list(reply);

	return NULL;
}
Esempio n. 14
0
File: sms.c Progetto: miksa/ofono
static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
{
	struct ofono_sms *sms = user_data;
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct parcel rilp;
	char *ril_pdu;
	int ril_pdu_len;
	unsigned int smsc_len;
	long ril_buf_len;
	guchar *ril_data;
	int request = RIL_REQUEST_SMS_ACKNOWLEDGE;
	int ret;

	DBG("req: %d; data_len: %d", message->req, (int) message->buf_len);

	if (message->req != RIL_UNSOL_RESPONSE_NEW_SMS)
		goto error;


	ril_util_init_parcel(message, &rilp);

	ril_pdu = parcel_r_string(&rilp);
	if (ril_pdu == NULL)
		goto error;

	ril_pdu_len = strlen(ril_pdu);

	DBG("ril_pdu_len is %d", ril_pdu_len);
	ril_data = decode_hex(ril_pdu, ril_pdu_len, &ril_buf_len, -1);
	if (ril_data == NULL)
		goto error;

	/* The first octect in the pdu contains the SMSC address length
	 * which is the X following octects it reads. We add 1 octet to
	 * the read length to take into account this read octet in order
	 * to calculate the proper tpdu length.
	 */
	smsc_len = ril_data[0] + 1;
	DBG("smsc_len is %d", smsc_len);

	g_ril_append_print_buf(sd->ril, "(%s)", ril_pdu);
	g_ril_print_unsol(sd->ril, message);

	/* Last parameter is 'tpdu_len' ( substract SMSC length ) */
	ofono_sms_deliver_notify(sms, ril_data,
			ril_buf_len,
			ril_buf_len - smsc_len);

	/* Re-use rilp, so initilize */
	parcel_init(&rilp);
	parcel_w_int32(&rilp, 2); /* Number of int32 values in array */
	parcel_w_int32(&rilp, 1); /* Successful receipt */
	parcel_w_int32(&rilp, 0); /* error code */

	/* TODO: should ACK be sent for either of the error cases? */

	/* ACK the incoming NEW_SMS; ignore response so no cb needed */
	ret = g_ril_send(sd->ril, request,
			rilp.data,
			rilp.size,
			NULL, NULL, NULL);

	g_ril_append_print_buf(sd->ril, "(1,0)");
	g_ril_print_request(sd->ril, ret, request);

	parcel_free(&rilp);
	return;

error:
	ofono_error("Unable to parse NEW_SMS notification");
}