summaryrefslogtreecommitdiffstats
path: root/sms.c
diff options
context:
space:
mode:
Diffstat (limited to 'sms.c')
-rw-r--r--sms.c218
1 files changed, 125 insertions, 93 deletions
diff --git a/sms.c b/sms.c
index 5a45d58..39da237 100644
--- a/sms.c
+++ b/sms.c
@@ -32,8 +32,6 @@
struct ril_request_sms ril_request_sms[10];
int ril_request_sms_lock = 0;
-unsigned char ipc_sms_tpid_queue[10];
-
/**
* Format conversion utils
*/
@@ -316,7 +314,7 @@ int ril_request_send_sms_next(void)
*/
void ril_request_send_sms_complete(RIL_Token t, char *pdu, char *smsc)
{
- struct ipc_sms_send_msg send_msg;
+ struct ipc_sms_send_msg_request send_msg;
unsigned char send_msg_type = IPC_SMS_MSG_SINGLE;
int send_msg_len;
@@ -362,7 +360,7 @@ void ril_request_send_sms_complete(RIL_Token t, char *pdu, char *smsc)
pdu_dec_len = pdu_len / 2;
smsc_len = smsc[0];
- send_msg_len = sizeof(struct ipc_sms_send_msg);
+ send_msg_len = sizeof(struct ipc_sms_send_msg_request);
/* Length of the final message */
data_len = pdu_dec_len + smsc_len + send_msg_len;
@@ -421,7 +419,7 @@ void ril_request_send_sms_complete(RIL_Token t, char *pdu, char *smsc)
pdu_end:
/* Alloc and clean memory for the final message */
data = malloc(data_len);
- memset(&send_msg, 0, sizeof(struct ipc_sms_send_msg));
+ memset(&send_msg, 0, sizeof(struct ipc_sms_send_msg_request));
/* Fill the IPC structure part of the message */
send_msg.type = IPC_SMS_TYPE_OUTGOING;
@@ -439,7 +437,7 @@ pdu_end:
ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SMS_SEND_MSG, ipc_sms_send_msg_complete);
- ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, data_len, ril_request_get_id(t));
+ ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, (void *) data, data_len, ril_request_get_id(t));
free(pdu_dec);
free(data);
@@ -508,7 +506,7 @@ void ipc_sms_svc_center_addr(struct ipc_message_info *info)
*/
void ipc_sms_send_msg(struct ipc_message_info *info)
{
- struct ipc_sms_deliv_report_msg *report_msg = (struct ipc_sms_deliv_report_msg *) info->data;
+ struct ipc_sms_send_msg_response *report_msg = (struct ipc_sms_send_msg_response *) info->data;
RIL_SMS_Response response;
RIL_Errno ril_ack_err;
@@ -528,91 +526,82 @@ void ipc_sms_send_msg(struct ipc_message_info *info)
}
/**
- * IPC incoming SMS queue functions
+ * Incoming SMS functions
*/
-void ipc_sms_tpid_queue_init(void)
+int ipc_sms_incoming_msg_register(char *pdu, int length, unsigned char type, unsigned char tpid)
{
- memset(ipc_sms_tpid_queue, 0, sizeof(unsigned char) * 10);
-}
+ struct ipc_sms_incoming_msg_info *incoming_msg;
+ struct list_head *list_end;
+ struct list_head *list;
-void ipc_sms_tpid_queue_del(int id)
-{
- if(id < 0 || id > 9) {
- LOGD("Invalid id (%d) for the SMS tpid queue", id);
- return;
- }
+ incoming_msg = calloc(1, sizeof(struct ipc_sms_incoming_msg_info));
+ if(incoming_msg == NULL)
+ return -1;
+
+ incoming_msg->pdu = pdu;
+ incoming_msg->length = length;
+ incoming_msg->type = type;
+ incoming_msg->tpid = tpid;
- ipc_sms_tpid_queue[id] = 0;
+ list_end = ril_data.incoming_sms;
+ while(list_end != NULL && list_end->next != NULL)
+ list_end = list_end->next;
+
+ list = list_head_alloc((void *) incoming_msg, list_end, NULL);
+
+ if(ril_data.incoming_sms == NULL)
+ ril_data.incoming_sms = list;
+
+ return 0;
}
-int ipc_sms_tpid_queue_new(void)
+void ipc_sms_incoming_msg_unregister(struct ipc_sms_incoming_msg_info *incoming_msg)
{
- int id = -1;
- int i;
+ struct list_head *list;
- /* Find the highest place in the queue */
- for(i=10 ; i > 0 ; i--) {
- if(ipc_sms_tpid_queue[i-1]) {
- break;
- }
+ if(incoming_msg == NULL)
+ return;
- id = i-1;
- }
+ list = ril_data.incoming_sms;
+ while(list != NULL) {
+ if(list->data == (void *) incoming_msg) {
+ memset(incoming_msg, 0, sizeof(struct ipc_sms_incoming_msg_info));
+ free(incoming_msg);
- if(id < 0) {
- LOGE("The SMS tpid queue is full, removing the oldest tpid");
+ if(list == ril_data.incoming_sms)
+ ril_data.incoming_sms = list->next;
- ipc_sms_tpid_queue_del(0);
+ list_head_free(list);
- for(i=1 ; i < 10 ; i++) {
- LOGD("SMS tpid queue: moving %d -> %d", i, i-1);
- ipc_sms_tpid_queue[i-1] = ipc_sms_tpid_queue[i];
+ break;
}
-
- ipc_sms_tpid_queue_del(9);
-
- return 9;
+list_continue:
+ list = list->next;
}
-
- return id;
}
-int ipc_sms_tpid_queue_add(unsigned char sms_tpid)
+struct ipc_sms_incoming_msg_info *ipc_sms_incoming_msg_info_find(void)
{
- int id = ipc_sms_tpid_queue_new();
-
- LOGD("Storing new SMS tpid in the queue at index %d\n", id);
+ struct ipc_sms_incoming_msg_info *incoming_msg;
+ struct list_head *list;
- ipc_sms_tpid_queue[id] = sms_tpid;
+ list = ril_data.incoming_sms;
+ while(list != NULL) {
+ incoming_msg = (struct ipc_sms_incoming_msg_info *) list->data;
+ if(incoming_msg == NULL)
+ goto list_continue;
- return id;
-}
-
-int ipc_sms_tpid_queue_get_next(void)
-{
- int id = -1;
- int i;
+ return incoming_msg;
- for(i=0 ; i < 10 ; i++) {
- if(ipc_sms_tpid_queue[i]) {
- id = i;
- }
+list_continue:
+ list = list->next;
}
- if(id < 0)
- LOGD("Nothing left on the queue!");
- else
- LOGD("Next queued tpid is at id #%d\n", id);
-
- return id;
+ return NULL;
}
/**
- * Incoming SMS functions
- */
-
-/**
* In: IPC_SMS_INCOMING_MSG
* Message to notify an incoming message, with PDU
*
@@ -620,30 +609,53 @@ int ipc_sms_tpid_queue_get_next(void)
* Notify RILJ about the incoming message
*/
+void ipc_sms_incoming_msg_complete(char *pdu, int length, unsigned char type, unsigned char tpid)
+{
+ if(pdu == NULL || length <= 0)
+ return;
+
+ ril_data.state.sms_incoming_msg_tpid = tpid;
+
+ if(type == IPC_SMS_TYPE_POINT_TO_POINT) {
+ ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS, pdu, length);
+ } else if(type == IPC_SMS_TYPE_STATUS_REPORT) {
+ ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, pdu, length);
+ } else {
+ LOGE("Unhandled message type: %x", type);
+ }
+
+ free(pdu);
+}
+
void ipc_sms_incoming_msg(struct ipc_message_info *info)
{
- struct ipc_sms_incoming_msg *msg = (struct ipc_sms_incoming_msg *) info->data;
- char *pdu = ((char *) info->data + sizeof(struct ipc_sms_incoming_msg));
+ struct ipc_sms_incoming_msg *msg;
+ unsigned char *pdu_hex;
+ char *pdu;
+ int length;
+ int rc;
- int resp_length = msg->length * 2 + 1;
- char *resp = (char *) malloc(resp_length);
+ if(info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_incoming_msg))
+ return;
- bin2hex(pdu, msg->length, resp);
+ msg = (struct ipc_sms_incoming_msg *) info->data;
+ pdu_hex = ((unsigned char *) info->data + sizeof(struct ipc_sms_incoming_msg));
- ipc_sms_tpid_queue_add(msg->msg_tpid);
+ length = msg->length * 2 + 1;
+ pdu = (char *) calloc(1, length);
- if(msg->type == IPC_SMS_TYPE_POINT_TO_POINT) {
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS, resp, resp_length);
- } else if(msg->type == IPC_SMS_TYPE_STATUS_REPORT) {
- // FIXME: do we need to enqueue for this?
+ bin2hex(pdu_hex, msg->length, pdu);
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, resp, resp_length);
- } else {
- LOGE("%s: Unknown message type", __FUNCTION__);
+ if(ril_data.state.sms_incoming_msg_tpid != 0) {
+ LOGD("Another message is waiting ACK, queuing");
+ rc = ipc_sms_incoming_msg_register(pdu, length, msg->type, msg->msg_tpid);
+ if(rc < 0)
+ LOGE("Unable to register incoming msg");
+
+ return;
}
-exit:
- free(resp);
+ ipc_sms_incoming_msg_complete(pdu, length, msg->type, msg->msg_tpid);
}
/**
@@ -654,14 +666,19 @@ exit:
* Out: IPC_SMS_DELIVER_REPORT
* Sends a SMS delivery report
*/
-void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t datalen)
+void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t length)
{
- struct ipc_sms_deliv_report_msg report_msg;
- int success = ((int *)data)[0];
- int failcause = ((int *)data)[1];
- int id = ipc_sms_tpid_queue_get_next();
+ struct ipc_sms_incoming_msg_info *incoming_msg;
+ struct ipc_sms_deliver_report_request report_msg;
+ int success, fail_cause;
- if(id < 0) {
+ if(data == NULL || length < 2 * sizeof(int))
+ return;
+
+ success = ((int *) data)[0];
+ fail_cause = ((int *) data)[1];
+
+ if(ril_data.state.sms_incoming_msg_tpid == 0) {
LOGE("There is no SMS message to ACK!");
ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
@@ -669,15 +686,22 @@ void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t datalen)
}
report_msg.type = IPC_SMS_TYPE_STATUS_REPORT;
- report_msg.error = ril2ipc_sms_ack_error(success, failcause);
- report_msg.msg_tpid = ipc_sms_tpid_queue[id];
+ report_msg.error = ril2ipc_sms_ack_error(success, fail_cause);
+ report_msg.msg_tpid = ril_data.state.sms_incoming_msg_tpid;
report_msg.unk = 0;
ipc_gen_phone_res_expect_to_abort(ril_request_get_id(t), IPC_SMS_DELIVER_REPORT);
- ipc_fmt_send(IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(struct ipc_sms_deliv_report_msg), ril_request_get_id(t));
+ ipc_fmt_send(IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(report_msg), ril_request_get_id(t));
- ipc_sms_tpid_queue_del(id);
+ ril_data.state.sms_incoming_msg_tpid = 0;
+
+ incoming_msg = ipc_sms_incoming_msg_info_find();
+ if(incoming_msg == NULL)
+ return;
+
+ ipc_sms_incoming_msg_complete(incoming_msg->pdu, incoming_msg->length, incoming_msg->type, incoming_msg->tpid);
+ ipc_sms_incoming_msg_unregister(incoming_msg);
}
/**
@@ -686,9 +710,17 @@ void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t datalen)
*/
void ipc_sms_deliver_report(struct ipc_message_info *info)
{
- // TODO: check error code to eventually resend ACK
+ struct ipc_sms_deliver_report_response *report_msg;
+ RIL_Errno e;
+ int error_code;
+
+ if(info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_deliver_report_response))
+ return;
+
+ report_msg = (struct ipc_sms_deliver_report_response *) info->data;
+ e = ipc2ril_sms_ack_error(report_msg->error, &error_code);
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, NULL, 0);
+ ril_request_complete(ril_request_get_token(info->aseq), e, NULL, 0);
}
/**