Example #1
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 #2
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 #3
0
static void ril_imsi_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_sim_imsi_cb_t cb = cbd->cb;
	struct sim_data *sd = cbd->user;
	struct ofono_error error;
	struct parcel rilp;
	gchar *imsi;

	if (message->error == RIL_E_SUCCESS) {
		DBG("GET IMSI reply - OK");
		decode_ril_error(&error, "OK");
	} else {
		ofono_error("Reply failure: %s",
			    ril_error_to_string(message->error));
		decode_ril_error(&error, "FAIL");
		cb(&error, NULL, cbd->data);
		return;
	}

	ril_util_init_parcel(message, &rilp);

	/* 15 is the max length of IMSI
	 * add 4 bytes for string length */
	/* FIXME: g_assert(message->buf_len <= 19); */
	imsi = parcel_r_string(&rilp);

	g_ril_append_print_buf(sd->ril, "{%s}", imsi);
	g_ril_print_response(sd->ril, message);

	cb(&error, imsi, cbd->data);
	g_free(imsi);
}
Example #4
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 #5
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 #6
0
static void ril_query_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_call_forwarding_query_cb_t cb = cbd->cb;
	struct ofono_call_forwarding_condition *list = NULL;
	struct parcel rilp;
	int nmbr_of_resps = 0;
	int i;

	if (message->error == RIL_E_SUCCESS) {

		ril_util_init_parcel(message, &rilp);

		nmbr_of_resps = parcel_r_int32(&rilp);

		list = g_new0(
				struct ofono_call_forwarding_condition,
				nmbr_of_resps);

		for (i = 0; i < nmbr_of_resps; i++) {
			const char *str;

			list[i].status =  parcel_r_int32(&rilp);

			parcel_r_int32(&rilp);

			list[i].cls = parcel_r_int32(&rilp);

			list[i].phone_number.type = parcel_r_int32(&rilp);

			str = parcel_r_string(&rilp);

			if (str) {

				strncpy(list[i].phone_number.number,
					str,
					OFONO_MAX_PHONE_NUMBER_LENGTH);

				list[i].phone_number.number[
					OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';

				list[i].time = parcel_r_int32(&rilp);
			}

		}

		CALLBACK_WITH_SUCCESS(cb, 1, list, cbd->data);

		g_free(list);
	} else
Example #7
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 #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");
}
Example #9
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 #10
0
File: sms.c Project: leinomii/ofono
static void ril_csca_query_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_sms_sca_query_cb_t cb = cbd->cb;
	struct ofono_error error;
	struct ofono_phone_number sca;
	struct parcel rilp;
	gchar *number, *temp_buf;

	if (message->error == RIL_E_SUCCESS) {
		decode_ril_error(&error, "OK");
	} else {
		decode_ril_error(&error, "FAIL");
		cb(&error, NULL, cbd->data);
		return;
	}

	ril_util_init_parcel(message, &rilp);
	temp_buf = parcel_r_string(&rilp);

	if (temp_buf != NULL) {
		/* RIL gives address in quotes */
		number = strtok(temp_buf, "\"");

		if (number[0] == '+') {
			number = number + 1;
			sca.type = 145;
		} else {
			sca.type = 129;
		}
		strncpy(sca.number, number, OFONO_MAX_PHONE_NUMBER_LENGTH);
		sca.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';

		DBG("csca_query_cb: %s, %d", sca.number, sca.type);

		cb(&error, &sca, cbd->data);
	} else {
		CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
	}
}
Example #11
0
static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb;
	struct parcel rilp;
	int mode = OFONO_RADIO_BAND_GSM_ANY;
	int pref;

	if (message->error == RIL_E_SUCCESS) {
		ril_util_init_parcel(message, &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:
			mode = OFONO_RADIO_ACCESS_MODE_UMTS;
			break;
		case PREF_NET_TYPE_GSM_WCDMA:
		case PREF_NET_TYPE_GSM_WCDMA_AUTO:
		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:
		case PREF_NET_TYPE_LTE_CDMA_EVDO:
		case PREF_NET_TYPE_LTE_GSM_WCDMA:
		case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
		default:
			break;
		}
		CALLBACK_WITH_SUCCESS(cb, mode, cbd->data);
	} else {
		CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
	}
}
Example #12
0
File: stk.c Project: CODeRUS/ofono
static void ril_stk_pcmd_notify(struct ril_msg *message, gpointer user_data)
{
	struct ofono_stk *stk = user_data;
	struct parcel rilp;
	char *pcmd = NULL;
	guchar *pdu = NULL;
	long len;

	DBG("");

	ril_util_init_parcel(message, &rilp);
	pcmd = parcel_r_string(&rilp);
	DBG("pcmd: %s", pcmd);

	pdu = decode_hex((const char *) pcmd,
			strlen(pcmd),
			&len, -1);

	g_free(pcmd);
	ofono_stk_proactive_command_notify(stk, len, (const guchar *)pdu);
	g_free(pdu);
}
Example #13
0
File: ril.c Project: CODeRUS/ofono
static void ril_connected(struct ril_msg *message, gpointer user_data)
{
	DBG("");

	struct ofono_modem *modem = (struct ofono_modem *) user_data;
	struct ril_data *ril = ofono_modem_get_data(modem);
	int ril_version = 0;
	struct parcel rilp;

	ril_util_init_parcel(message, &rilp);
	ril_version = parcel_r_int32(&rilp);
	ofono_debug("%s: [UNSOL]< %s, RIL_VERSION %d",
			__func__, ril_unsol_request_to_string(message->req),
			ril_version);

	ril->connected = TRUE;

	send_get_sim_status(modem);

	connection = ofono_dbus_get_connection();
	mce_daemon_watch = g_dbus_add_service_watch(connection, MCE_SERVICE,
				mce_connect, mce_disconnect, modem, NULL);
}
Example #14
0
static void ril_ussd_notify(struct ril_msg *message, gpointer user_data)
{
	struct ofono_ussd *ussd = user_data;
	struct parcel rilp;
	gchar *ussd_from_network;
	gchar *type;
	gint ussdtype;

	ril_util_init_parcel(message, &rilp);
	parcel_r_int32(&rilp);
	type = parcel_r_string(&rilp);
	ussdtype = g_ascii_xdigit_value(*type);
	ussd_from_network = parcel_r_string(&rilp);

	if (ussd_from_network)
		ofono_ussd_notify(ussd, ussdtype, 0xFF,
			(const unsigned char *)ussd_from_network,
			strlen(ussd_from_network));
	else
		ofono_ussd_notify(ussd, ussdtype, 0, NULL, 0);

	return;
}
Example #15
0
static void ril_cbs_notify(struct ril_msg *message, gpointer user_data)
{
	struct ofono_cbs *cbs = user_data;

	/*
	 * Ofono does not support UMTS CB - see
	 * src/smsutil.c method cbs_decode.
	 * But let's let the core to make
	 * the rejection reserve memory here
	 * for maximum UMTS CB length
	 */

	unsigned char pdu[1252];
	char *resp;
	struct parcel rilp;

	ril_util_init_parcel(message, &rilp);

	resp = parcel_r_string(&rilp);

	memcpy(resp, pdu, strlen((char *)resp));

	ofono_cbs_notify(cbs, pdu, strlen((char *)resp));
}
Example #16
0
File: sms.c Project: 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");
}
Example #17
0
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 ofono_network_operator *list;
	struct ofono_error error;
	struct parcel rilp;
	int noperators, i;
	gchar *lalpha, *salpha, *numeric, *status;

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

	ril_util_init_parcel(message, &rilp);

	g_ril_append_print_buf(nd->ril, "{");

	/* Number of operators at the list (4 strings for every operator) */
	noperators = parcel_r_int32(&rilp) / 4;
	DBG("noperators = %d", noperators);

	list = g_try_new0(struct ofono_network_operator, noperators);
	if (list == NULL)
		goto error;

	for (i = 0; i < noperators; i++) {
		lalpha = parcel_r_string(&rilp);
		salpha = parcel_r_string(&rilp);
		numeric = parcel_r_string(&rilp);
		status = parcel_r_string(&rilp);

		/* Try to use long by default */
		if (lalpha) {
			strncpy(list[i].name, lalpha,
					OFONO_MAX_OPERATOR_NAME_LENGTH);
		} else {
			strncpy(list[i].name, salpha,
					OFONO_MAX_OPERATOR_NAME_LENGTH);
		}

		extract_mcc_mnc(numeric, list[i].mcc, list[i].mnc);

		/* FIXME: need to fix this for CDMA */
		/* Use GSM as default, as RIL doesn't pass that info to us */
		list[i].tech = ACCESS_TECHNOLOGY_GSM;

		/* Set the proper status  */
		if (!strcmp(status, "unknown"))
			list[i].status = OPERATOR_STATUS_UNKNOWN;
		else if (!strcmp(status, "available"))
			list[i].status = OPERATOR_STATUS_AVAILABLE;
		else if (!strcmp(status, "current"))
			list[i].status = OPERATOR_STATUS_CURRENT;
		else if (!strcmp(status, "forbidden"))
			list[i].status = OPERATOR_STATUS_FORBIDDEN;

		g_ril_append_print_buf(nd->ril,
					"%s [operator=%s, %s, %s, status: %s]",
					print_buf,
					list[i].name, list[i].mcc,
					list[i].mnc, status);

		g_free(lalpha);
		g_free(salpha);
		g_free(numeric);
		g_free(status);
	}

	g_ril_append_print_buf(nd->ril, "%s}", print_buf);
	g_ril_print_response(nd->ril, message);

	cb(&error, noperators, list, cbd->data);

	return;

error:
	CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data);
}
Example #18
0
File: sms.c Project: 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");
}