예제 #1
0
파일: sms.c 프로젝트: Conjuror/ofono
static void at_cmt_notify(GAtResult *result, gpointer user_data)
{
	struct ofono_sms *sms = user_data;
	const char *hexpdu;
	long pdu_len;
	int tpdu_len;
	unsigned char pdu[176];

	if (!at_parse_pdu_common(result, "+CMT:", &hexpdu, &tpdu_len)) {
		ofono_error("Unable to parse CMT notification");
		return;
	}

	if (strlen(hexpdu) > sizeof(pdu) * 2) {
		ofono_error("Bad PDU length in CMT notification");
		return;
	}

	DBG("Got new SMS Deliver PDU via CMT: %s, %d", hexpdu, tpdu_len);

	decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu);
	ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len);

	at_ack_delivery(sms);
}
예제 #2
0
static void ril_sms_on_sim_cb(int ok, int total_length, int record,
		const unsigned char *sdata, int length, void *userdata)
{
	struct ril_sms_on_sim_req *cbd = userdata;
	struct ril_sms *sd = cbd->sd;

	/*
	 * It seems when reading EFsms RIL returns the whole record including
	 * the first status byte therefore we ignore that as we are only
	 * interested of the following pdu
	 */
	/* 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.
	 */
	if (ok) {
		unsigned int smsc_len = sdata[1] + 1;
		ofono_sms_deliver_notify(sd->sms, sdata + 1, length - 1,
						length - smsc_len - 1);
		ril_request_delete_sms_om_sim(sd, cbd->record);
	} else {
		ofono_error("cannot read sms from sim");
	}

	ril_sms_on_sim_req_free(cbd);
}
예제 #3
0
static void ril_sms_notify(GRilIoChannel *io, guint ril_event,
				const void *data, guint len, void *user_data)
{
	struct ril_sms *sd = user_data;
	GRilIoParser rilp;
	char *ril_pdu;
	int ril_pdu_len;
	unsigned int smsc_len;
	long ril_buf_len;
	guchar *ril_data;

	ril_pdu = NULL;
	ril_data = NULL;

	DBG("event: %d; data_len: %d", ril_event, len);

	grilio_parser_init(&rilp, data, len);
	ril_pdu = grilio_parser_get_utf8(&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;
	ofono_info("sms received, smsc_len is %d", smsc_len);
	DBG("(%s)", ril_pdu);

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

	g_free(ril_pdu);
	g_free(ril_data);
	ril_ack_delivery(sd, TRUE);
	return;

error:
	g_free(ril_pdu);
	g_free(ril_data);
	ril_ack_delivery(sd, FALSE);
	ofono_error("Unable to parse NEW_SMS notification");
}
예제 #4
0
파일: sms.c 프로젝트: Conjuror/ofono
static void received_msg_ind_cb(const GIsiMessage *msg, void *data)
{
	struct ofono_sms *sms = data;
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct sms_common tpdu;
	struct sms_addr addr;
	GIsiSubBlockIter iter;

	uint8_t pdu[176];
	uint8_t sbcount;

	DBG("");

	if (g_isi_msg_id(msg) != SMS_RECEIVED_MSG_IND)
		return;

	if (!g_isi_msg_data_get_byte(msg, 1, &sbcount))
		return;

	for (g_isi_sb_iter_init_full(&iter, msg, 2, TRUE, sbcount);
			g_isi_sb_iter_is_valid(&iter);
			g_isi_sb_iter_next(&iter)) {

		switch (g_isi_sb_iter_get_id(&iter)) {
		case SMS_ADDRESS:

			if (!parse_sms_address(&iter, 4, &addr))
				return;

			if (addr.type != SMS_SMSC_ADDRESS)
				return;

			break;

		case SMS_SB_TPDU:

			if (!parse_sms_tpdu(&iter, 4, &tpdu))
				return;

			break;
		}
	}

	if (tpdu.data == NULL || addr.data == NULL ||
			tpdu.len + addr.len > sizeof(pdu))
		return;

	memcpy(pdu, addr.data, addr.len);
	memcpy(pdu + addr.len, tpdu.data, tpdu.len);

	/* 23.040 9.2.3.1 */
	if ((tpdu.data[0] & 0x03) == 0x02)
		ofono_sms_status_notify(sms, pdu, tpdu.len + addr.len, tpdu.len);
	else
		ofono_sms_deliver_notify(sms, pdu, tpdu.len + addr.len, tpdu.len);

	send_deliver_report(sd->client, TRUE, NULL, NULL);
}
예제 #5
0
파일: sms.c 프로젝트: Conjuror/ofono
static void at_cmgl_notify(GAtResult *result, gpointer user_data)
{
	struct ofono_sms *sms = user_data;
	struct sms_data *data = ofono_sms_get_data(sms);
	GAtResultIter iter;
	const char *hexpdu;
	unsigned char pdu[176];
	long pdu_len;
	int tpdu_len;
	int index;
	int status;
	char buf[16];

	DBG("");

	g_at_result_iter_init(&iter, result);

	while (g_at_result_iter_next(&iter, "+CMGL:")) {
		if (!g_at_result_iter_next_number(&iter, &index))
			goto err;

		if (!g_at_result_iter_next_number(&iter, &status))
			goto err;

		if (!g_at_result_iter_skip_next(&iter))
			goto err;

		if (!g_at_result_iter_next_number(&iter, &tpdu_len))
			goto err;

		/* Only MT messages */
		if (status != 0 && status != 1)
			continue;

		hexpdu = g_at_result_pdu(result);

		DBG("Found an old SMS PDU: %s, with len: %d",
				hexpdu, tpdu_len);

		if (strlen(hexpdu) > sizeof(pdu) * 2)
			continue;

		decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu);
		ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len);

		/* We don't buffer SMS on the SIM/ME, send along a CMGD */
		snprintf(buf, sizeof(buf), "AT+CMGD=%d", index);
		g_at_chat_send(data->chat, buf, none_prefix,
				at_cmgd_cb, NULL, NULL);
	}
	return;

err:
	ofono_error("Unable to parse CMGL response");
}
예제 #6
0
파일: sms.c 프로젝트: Conjuror/ofono
static void at_cmgr_notify(GAtResult *result, gpointer user_data)
{
	struct ofono_sms *sms = user_data;
	struct sms_data *data = ofono_sms_get_data(sms);
	GAtResultIter iter;
	const char *hexpdu;
	unsigned char pdu[176];
	long pdu_len;
	int tpdu_len;

	DBG("");

	g_at_result_iter_init(&iter, result);

	if (!g_at_result_iter_next(&iter, "+CMGR:"))
		goto err;

	if (!g_at_result_iter_skip_next(&iter))
		goto err;

	if (!g_at_result_iter_skip_next(&iter))
		goto err;

	if (!g_at_result_iter_next_number(&iter, &tpdu_len))
		goto err;

	hexpdu = g_at_result_pdu(result);

	if (strlen(hexpdu) > sizeof(pdu) * 2)
		goto err;

	DBG("Got PDU: %s, with len: %d", hexpdu, tpdu_len);

	decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu);

	if (data->expect_sr)
		ofono_sms_status_notify(sms, pdu, pdu_len, tpdu_len);
	else
		ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len);
	return;

err:
	ofono_error("Unable to parse CMGR response");
}
예제 #7
0
파일: sms.c 프로젝트: Conjuror/ofono
static void routing_ntf_cb(const GIsiMessage *msg, void *data)
{
	struct ofono_sms *sms = data;
	struct sms_data *sd = ofono_sms_get_data(sms);
	struct sms_common tpdu;
	struct sms_addr addr;
	GIsiSubBlockIter iter;

	uint8_t pdu[176];

	if (g_isi_msg_id(msg) != SMS_PP_ROUTING_NTF)
		return;

	for (g_isi_sb_iter_init(&iter, msg, 2);
			g_isi_sb_iter_is_valid(&iter);
			g_isi_sb_iter_next(&iter)) {

		if (g_isi_sb_iter_get_id(&iter) != SMS_GSM_TPDU)
			continue;

		if (!parse_gsm_tpdu(&iter, &addr, &tpdu))
			return;
	}

	if (tpdu.data == NULL || addr.data == NULL ||
			tpdu.len + addr.len > sizeof(pdu))
		return;

	memcpy(pdu, addr.data, addr.len);
	memcpy(pdu + addr.len, tpdu.data, tpdu.len);

	/* 23.040 9.2.3.1 */
	if ((tpdu.data[0] & 0x03) == 0x02)
		ofono_sms_status_notify(sms, pdu, tpdu.len + addr.len, tpdu.len);
	else
		ofono_sms_deliver_notify(sms, pdu, tpdu.len + addr.len, tpdu.len);

	send_gsm_deliver_report(sd->client, TRUE, NULL, NULL);
}
예제 #8
0
파일: sms.c 프로젝트: 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");
}
예제 #9
0
파일: sms.c 프로젝트: 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");
}