SMS: Use lists stored in ril_data instead of global tpid table
authorPaul Kocialkowski <contact@paulk.fr>
Thu, 1 Nov 2012 18:23:49 +0000 (19:23 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Thu, 1 Nov 2012 18:23:49 +0000 (19:23 +0100)
Some strutures were also renamed to Stick to libsamsung-ipc changes

Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
samsung-ril.c
samsung-ril.h
sms.c

index cf4f380..94f935a 100644 (file)
@@ -648,7 +648,6 @@ void ril_data_init(void)
 void ril_globals_init(void)
 {
        ril_request_sms_init();
-       ipc_sms_tpid_queue_init();
 }
 
 /**
index 9219a2b..c67dd63 100644 (file)
@@ -160,6 +160,8 @@ struct ril_state {
 
        unsigned char dtmf_tone;
        unsigned char ussd_state;
+
+       unsigned char sms_incoming_msg_tpid;
 };
 
 void ril_state_lpm(void);
@@ -174,6 +176,8 @@ struct ril_data {
        struct ril_state state;
        struct ril_tokens tokens;
        struct list_head *gprs_connections;
+       struct list_head *incoming_sms;
+       struct list_head *outgoing_sms;
        struct list_head *generic_responses;
        struct list_head *requests;
        int request_id;
@@ -290,6 +294,14 @@ void ril_request_set_network_selection_manual(RIL_Token t, void *data, size_t da
 
 /* SMS */
 
+struct ipc_sms_incoming_msg_info {
+       char *pdu;
+       int length;
+
+       unsigned char type;
+       unsigned char tpid;
+};
+
 struct ril_request_sms {
        char *pdu;
        int pdu_len;
@@ -318,13 +330,13 @@ void ipc_sms_send_msg_complete(struct ipc_message_info *info);
 void ipc_sms_svc_center_addr(struct ipc_message_info *info);
 void ipc_sms_send_msg(struct ipc_message_info *info);
 
-void ipc_sms_tpid_queue_init(void);
-void ipc_sms_tpid_queue_del(int id);
-int ipc_sms_tpid_queue_add(unsigned char sms_tpid);
-int ipc_sms_tpid_queue_get_next(void);
+int ipc_sms_incoming_msg_register(char *pdu, int length, unsigned char type, unsigned char tpid);
+void ipc_sms_incoming_msg_unregister(struct ipc_sms_incoming_msg_info *incoming_msg);
+struct ipc_sms_incoming_msg_info *ipc_sms_incoming_msg_info_find(void);
 
+void ipc_sms_incoming_msg_complete(char *pdu, int length, unsigned char type, unsigned char tpid);
 void ipc_sms_incoming_msg(struct ipc_message_info *info);
-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);
 void ipc_sms_deliver_report(struct ipc_message_info *info);
 
 void ipc_sms_device_ready(struct ipc_message_info *info);
diff --git a/sms.c b/sms.c
index 5a45d58..39da237 100644 (file)
--- 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);
 }
 
 /**