549713f61181456fdb674d8723c00940d9c2566e
[samsung-ril.git] / sms.c
1 /*
2  * This file is part of Samsung-RIL.
3  *
4  * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
5  * Copyright (C) 2011-2012 Paul Kocialkowski <contact@paulk.fr>
6  *
7  * Samsung-RIL is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Samsung-RIL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Samsung-RIL.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #define LOG_TAG "RIL-SMS"
23 #include <utils/Log.h>
24
25 #include "samsung-ril.h"
26 #include "util.h"
27
28 /*
29  * Format conversion utils
30  */
31
32 unsigned short ril2ipc_sms_ack_error(int success, int failcause)
33 {
34         if (success) {
35                 return IPC_SMS_ACK_NO_ERROR;
36         } else {
37                 switch(failcause) {
38                         case 0xD3:
39                                 return IPC_SMS_ACK_PDA_FULL_ERROR;
40                         default:
41                                 return IPC_SMS_ACK_UNSPEC_ERROR;
42                 }
43         }
44 }
45
46 RIL_Errno ipc2ril_sms_ack_error(unsigned short error, int *error_code)
47 {
48         /* error_code is defined in See 3GPP 27.005, 3.2.5 for GSM/UMTS */
49
50         switch(error) {
51                 case IPC_SMS_ACK_NO_ERROR:
52                         *error_code = -1;
53                         return RIL_E_SUCCESS;
54                 default:
55                         // unknown error
56                         *error_code = 500;
57                         return RIL_E_GENERIC_FAILURE;
58         }
59 }
60
61 /*
62  * Outgoing SMS functions
63  */
64
65 int ril_request_send_sms_register(char *pdu, int pdu_length, unsigned char *smsc, int smsc_length, RIL_Token t)
66 {
67         struct ril_request_send_sms_info *send_sms;
68         struct list_head *list_end;
69         struct list_head *list;
70
71         send_sms = calloc(1, sizeof(struct ril_request_send_sms_info));
72         if (send_sms == NULL)
73                 return -1;
74
75         send_sms->pdu = pdu;
76         send_sms->pdu_length = pdu_length;
77         send_sms->smsc = smsc;
78         send_sms->smsc_length = smsc_length;
79         send_sms->token = t;
80
81         list_end = ril_data.outgoing_sms;
82         while (list_end != NULL && list_end->next != NULL)
83                 list_end = list_end->next;
84
85         list = list_head_alloc((void *) send_sms, list_end, NULL);
86
87         if (ril_data.outgoing_sms == NULL)
88                 ril_data.outgoing_sms = list;
89
90         return 0;
91 }
92
93 void ril_request_send_sms_unregister(struct ril_request_send_sms_info *send_sms)
94 {
95         struct list_head *list;
96
97         if (send_sms == NULL)
98                 return;
99
100         list = ril_data.outgoing_sms;
101         while (list != NULL) {
102                 if (list->data == (void *) send_sms) {
103                         memset(send_sms, 0, sizeof(struct ril_request_send_sms_info));
104                         free(send_sms);
105
106                         if (list == ril_data.outgoing_sms)
107                                 ril_data.outgoing_sms = list->next;
108
109                         list_head_free(list);
110
111                         break;
112                 }
113 list_continue:
114                 list = list->next;
115         }
116 }
117
118 struct ril_request_send_sms_info *ril_request_send_sms_info_find(void)
119 {
120         struct ril_request_send_sms_info *send_sms;
121         struct list_head *list;
122
123         list = ril_data.outgoing_sms;
124         while (list != NULL) {
125                 send_sms = (struct ril_request_send_sms_info *) list->data;
126                 if (send_sms == NULL)
127                         goto list_continue;
128
129                 return send_sms;
130
131 list_continue:
132                 list = list->next;
133         }
134
135         return NULL;
136 }
137
138 struct ril_request_send_sms_info *ril_request_send_sms_info_find_token(RIL_Token t)
139 {
140         struct ril_request_send_sms_info *send_sms;
141         struct list_head *list;
142
143         list = ril_data.outgoing_sms;
144         while (list != NULL) {
145                 send_sms = (struct ril_request_send_sms_info *) list->data;
146                 if (send_sms == NULL)
147                         goto list_continue;
148
149                 if (send_sms->token == t)
150                         return send_sms;
151
152 list_continue:
153                 list = list->next;
154         }
155
156         return NULL;
157 }
158
159 void ril_request_send_sms_info_clear(struct ril_request_send_sms_info *send_sms)
160 {
161         if (send_sms == NULL)
162                 return;
163
164         if (send_sms->pdu != NULL)
165                 free(send_sms->pdu);
166
167         if (send_sms->smsc != NULL)
168                 free(send_sms->smsc);
169 }
170
171 void ril_request_send_sms_next(void)
172 {
173         struct ril_request_send_sms_info *send_sms;
174         RIL_Token t;
175         char *pdu;
176         int pdu_length;
177         unsigned char *smsc;
178         int smsc_length;
179         int rc;
180
181         ril_data.tokens.outgoing_sms = (RIL_Token) 0x00;
182
183         send_sms = ril_request_send_sms_info_find();
184         if (send_sms == NULL)
185                 return;
186
187         t = send_sms->token;
188         pdu = send_sms->pdu;
189         pdu_length = send_sms->pdu_length;
190         smsc = send_sms->smsc;
191         smsc_length = send_sms->smsc_length;
192
193         ril_request_send_sms_unregister(send_sms);
194
195         if (pdu == NULL) {
196                 LOGE("SMS send request has no valid PDU");
197                 if (smsc != NULL)
198                         free(smsc);
199                 return;
200         }
201
202         ril_data.tokens.outgoing_sms = t;
203         if (smsc == NULL) {
204                 // We first need to get SMS SVC before sending the message
205                 LOGD("We have no SMSC, let's ask one");
206
207                 rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t);
208                 if (rc < 0) {
209                         LOGE("Unable to add the request to the list");
210
211                         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
212                         if (pdu != NULL)
213                                 free(pdu);
214                         // Send the next SMS in the list
215                         ril_request_send_sms_next();
216                 }
217
218                 ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t));
219         } else {
220                 ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length);
221                 if (pdu != NULL)
222                         free(pdu);
223                 if (smsc != NULL)
224                         free(smsc);
225         }
226 }
227
228 /*
229  * In: RIL_REQUEST_SEND_SMS
230  *   Send an SMS message.
231  *
232  * Out: IPC_SMS_SEND_MSG
233  */
234 void ril_request_send_sms_complete(RIL_Token t, char *pdu, int pdu_length, unsigned char *smsc, int smsc_length)
235 {
236         struct ipc_sms_send_msg_request send_msg;
237         unsigned char send_msg_type;
238
239         unsigned char *pdu_hex;
240         int pdu_hex_length;
241
242         void *data;
243         int length;
244
245         unsigned char *p;
246
247         if (pdu == NULL || pdu_length <= 0 || smsc == NULL || smsc_length <= 0) {
248                 LOGE("Provided PDU or SMSC is invalid! Aborting");
249
250                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
251                 // Send the next SMS in the list
252                 ril_request_send_sms_next();
253
254                 return;
255         }
256         if ((pdu_length / 2 + smsc_length) > 0xfe) {
257                 LOGE("PDU or SMSC too large, aborting");
258
259                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
260                 // Send the next SMS in the list
261                 ril_request_send_sms_next();
262
263                 return;
264         }
265
266         pdu_hex_length = pdu_length % 2 == 0 ? pdu_length / 2 :
267                 (pdu_length ^ 1) / 2;
268
269         // Length of the final message
270         length = sizeof(send_msg) + pdu_hex_length + smsc_length;
271
272         LOGD("Sending SMS message (length: 0x%x)!", length);
273
274         pdu_hex = calloc(1, pdu_hex_length);
275         hex2bin(pdu, pdu_length, pdu_hex);
276         send_msg_type = IPC_SMS_MSG_SINGLE;
277
278         /* PDU operations */
279         int pdu_tp_da_index = 2;
280         unsigned char pdu_tp_da_len = pdu_hex[pdu_tp_da_index];
281
282         if (pdu_tp_da_len > 0xff / 2) {
283                 LOGE("PDU TP-DA Len failed (0x%x)\n", pdu_tp_da_len);
284                 goto pdu_end;
285         }
286
287         LOGD("PDU TP-DA Len is 0x%x\n", pdu_tp_da_len);
288
289         int pdu_tp_udh_index = pdu_tp_da_index + pdu_tp_da_len;
290         unsigned char pdu_tp_udh_len = pdu_hex[pdu_tp_udh_index];
291
292         if (pdu_tp_udh_len > 0xff / 2 || pdu_tp_udh_len < 5) {
293                 LOGE("PDU TP-UDH Len failed (0x%x)\n", pdu_tp_udh_len);
294                 goto pdu_end;
295         }
296
297         LOGD("PDU TP-UDH Len is 0x%x\n", pdu_tp_udh_len);
298
299         int pdu_tp_udh_num_index = pdu_tp_udh_index + 4;
300         unsigned char pdu_tp_udh_num = pdu_hex[pdu_tp_udh_num_index];
301
302         if (pdu_tp_udh_num > 0xf) {
303                 LOGE("PDU TP-UDH Num failed (0x%x)\n", pdu_tp_udh_num);
304                 goto pdu_end;
305         }
306
307         int pdu_tp_udh_seq_index = pdu_tp_udh_index + 5;
308         unsigned char pdu_tp_udh_seq = pdu_hex[pdu_tp_udh_seq_index];
309
310         if (pdu_tp_udh_seq > 0xf || pdu_tp_udh_seq > pdu_tp_udh_num) {
311                 LOGE("PDU TP-UDH Seq failed (0x%x)\n", pdu_tp_udh_seq);
312                 goto pdu_end;
313         }
314
315         LOGD("We are sending message %d on %d\n", pdu_tp_udh_seq, pdu_tp_udh_num);
316
317         if (pdu_tp_udh_num > 1) {
318                 LOGD("We are sending a multi-part message!");
319                 send_msg_type = IPC_SMS_MSG_MULTIPLE;
320         }
321
322 pdu_end:
323         // Alloc memory for the final message
324         data = calloc(1, length);
325
326         // Clear and fill the IPC structure part of the message
327         memset(&send_msg, 0, sizeof(struct ipc_sms_send_msg_request));
328         send_msg.type = IPC_SMS_TYPE_OUTGOING;
329         send_msg.msg_type = send_msg_type;
330         send_msg.length = (unsigned char) (pdu_hex_length + smsc_length + 1);
331         send_msg.smsc_len = smsc_length;
332
333         // Copy the parts of the message
334         p = data;
335         memcpy(p, &send_msg, sizeof(send_msg));
336         p += sizeof(send_msg);
337         memcpy(p, smsc, smsc_length);
338         p += smsc_length;
339         memcpy(p, pdu_hex, pdu_hex_length);
340
341         ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SMS_SEND_MSG, ipc_sms_send_msg_complete);
342
343         ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, length, ril_request_get_id(t));
344
345         free(pdu_hex);
346         free(data);
347 }
348
349 void ril_request_send_sms(RIL_Token t, void *data, size_t length)
350 {
351         char *pdu;
352         int pdu_length;
353         unsigned char *smsc;
354         int smsc_length;
355         int rc;
356
357         if (data == NULL || length < 2 * sizeof(char *))
358                 return;
359
360         pdu = ((char **) data)[1];
361         smsc = ((unsigned char **) data)[0];
362         pdu_length = 0;
363         smsc_length = 0;
364
365         if (pdu != NULL) {
366                 pdu_length = strlen(pdu) + 1;
367                 pdu = strdup(pdu);
368         }
369         if (smsc != NULL) {
370                 smsc_length = strlen((char *) smsc);
371                 smsc = (unsigned char *) strdup((char *) smsc);
372         }
373
374         if (ril_data.tokens.outgoing_sms != (RIL_Token) 0x00) {
375                 LOGD("Another outgoing SMS is being processed, adding to the list");
376
377                 rc = ril_request_send_sms_register(pdu, pdu_length, smsc, smsc_length, t);
378                 if (rc < 0) {
379                         LOGE("Unable to add the request to the list");
380
381                         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
382                         if (pdu != NULL)
383                                 free(pdu);
384                         if (smsc != NULL)
385                                 free(smsc);
386                         // Send the next SMS in the list
387                         ril_request_send_sms_next();
388                 }
389
390                 return;
391         }
392
393         ril_data.tokens.outgoing_sms = t;
394         if (smsc == NULL) {
395                 // We first need to get SMS SVC before sending the message
396                 LOGD("We have no SMSC, let's ask one");
397
398                 rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t);
399                 if (rc < 0) {
400                         LOGE("Unable to add the request to the list");
401
402                         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
403                         if (pdu != NULL)
404                                 free(pdu);
405                         // Send the next SMS in the list
406                         ril_request_send_sms_next();
407                 }
408
409                 ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t));
410         } else {
411                 ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length);
412                 if (pdu != NULL)
413                         free(pdu);
414                 if (smsc != NULL)
415                         free(smsc);
416         }
417 }
418
419 /*
420  * In: RIL_REQUEST_SEND_SMS_EXPECT_MORE
421  *   Send an SMS message. Identical to RIL_REQUEST_SEND_SMS,
422  *   except that more messages are expected to be sent soon. If possible,
423  *   keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command)
424  *
425  * Out: IPC_SMS_SEND_MSG
426  */
427 void ril_request_send_sms_expect_more(RIL_Token t, void *data, size_t length)
428 {
429         /* No particular treatment here, we already have a queue */
430         ril_request_send_sms(t, data, length);
431 }
432
433 /*
434  * In: IPC_SMS_SVC_CENTER_ADDR
435  *   SMSC: Service Center Address, needed to send an SMS
436  *
437  * Out: IPC_SMS_SEND_MSG
438  */
439 void ipc_sms_svc_center_addr(struct ipc_message_info *info)
440 {
441         struct ril_request_send_sms_info *send_sms;
442         RIL_Token t;
443         char *pdu;
444         int pdu_length;
445         unsigned char *smsc;
446         int smsc_length;
447         int rc;
448
449         if (info == NULL || info->data == NULL)
450                 return;
451
452         send_sms = ril_request_send_sms_info_find_token(ril_request_get_token(info->aseq));
453         if (send_sms == NULL || send_sms->pdu == NULL || send_sms->pdu_length <= 0) {
454                 LOGE("The request wasn't queued, reporting generic error!");
455
456                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
457                 ril_request_send_sms_info_clear(send_sms);
458                 ril_request_send_sms_unregister(send_sms);
459                 // Send the next SMS in the list
460                 ril_request_send_sms_next();
461
462                 return;
463         }
464
465         t = send_sms->token;
466         pdu = send_sms->pdu;
467         pdu_length = send_sms->pdu_length;
468         smsc = (unsigned char *) info->data + sizeof(unsigned char);
469         smsc_length = (int) ((unsigned char *) info->data)[0];
470
471         LOGD("Got SMSC, completing the request");
472         ril_request_send_sms_unregister(send_sms);
473         ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length);
474         if (pdu != NULL)
475                 free(pdu);
476 }
477
478 void ipc_sms_send_msg_complete(struct ipc_message_info *info)
479 {
480         struct ril_request_send_sms_info *send_sms;
481         struct ipc_gen_phone_res *phone_res;
482
483         if (info->data == NULL || info->length < sizeof(struct ipc_gen_phone_res))
484                 return;
485
486         phone_res = (struct ipc_gen_phone_res *) info->data;
487         if (ipc_gen_phone_res_check(phone_res) < 0) {
488                 LOGE("IPC_GEN_PHONE_RES indicates error, abort request to RILJ");
489
490                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
491                 // Send the next SMS in the list
492                 ril_request_send_sms_next();
493         }
494 }
495
496 /*
497  * In: IPC_SMS_SEND_MSG
498  *   This comes to ACK the latest sent SMS message
499  */
500 void ipc_sms_send_msg(struct ipc_message_info *info)
501 {
502         struct ipc_sms_send_msg_response *report_msg;
503         RIL_SMS_Response response;
504         RIL_Errno e;
505
506         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_send_msg_response))
507                 return;
508
509         report_msg = (struct ipc_sms_send_msg_response *) info->data;
510
511         LOGD("Got ACK for msg_tpid #%d\n", report_msg->msg_tpid);
512
513         memset(&response, 0, sizeof(response));
514         response.messageRef = report_msg->msg_tpid;
515         response.ackPDU = NULL;
516
517         e = ipc2ril_sms_ack_error(report_msg->error, &response.errorCode);
518
519         ril_request_complete(ril_request_get_token(info->aseq), e, (void *) &response, sizeof(response));
520
521         // Send the next SMS in the list
522         ril_request_send_sms_next();
523 }
524
525 /*
526  * Incoming SMS functions
527  */
528
529 int ipc_sms_incoming_msg_register(char *pdu, int length, unsigned char type, unsigned char tpid)
530 {
531         struct ipc_sms_incoming_msg_info *incoming_msg;
532         struct list_head *list_end;
533         struct list_head *list;
534
535         incoming_msg = calloc(1, sizeof(struct ipc_sms_incoming_msg_info));
536         if (incoming_msg == NULL)
537                 return -1;
538
539         incoming_msg->pdu = pdu;
540         incoming_msg->length = length;
541         incoming_msg->type = type;
542         incoming_msg->tpid = tpid;
543
544         list_end = ril_data.incoming_sms;
545         while (list_end != NULL && list_end->next != NULL)
546                 list_end = list_end->next;
547
548         list = list_head_alloc((void *) incoming_msg, list_end, NULL);
549
550         if (ril_data.incoming_sms == NULL)
551                 ril_data.incoming_sms = list;
552
553         return 0;
554 }
555
556 void ipc_sms_incoming_msg_unregister(struct ipc_sms_incoming_msg_info *incoming_msg)
557 {
558         struct list_head *list;
559
560         if (incoming_msg == NULL)
561                 return;
562
563         list = ril_data.incoming_sms;
564         while (list != NULL) {
565                 if (list->data == (void *) incoming_msg) {
566                         memset(incoming_msg, 0, sizeof(struct ipc_sms_incoming_msg_info));
567                         free(incoming_msg);
568
569                         if (list == ril_data.incoming_sms)
570                                 ril_data.incoming_sms = list->next;
571
572                         list_head_free(list);
573
574                         break;
575                 }
576 list_continue:
577                 list = list->next;
578         }
579 }
580
581 struct ipc_sms_incoming_msg_info *ipc_sms_incoming_msg_info_find(void)
582 {
583         struct ipc_sms_incoming_msg_info *incoming_msg;
584         struct list_head *list;
585
586         list = ril_data.incoming_sms;
587         while (list != NULL) {
588                 incoming_msg = (struct ipc_sms_incoming_msg_info *) list->data;
589                 if (incoming_msg == NULL)
590                         goto list_continue;
591
592                 return incoming_msg;
593
594 list_continue:
595                 list = list->next;
596         }
597
598         return NULL;
599 }
600
601 void ipc_sms_incoming_msg_next(void)
602 {
603         struct ipc_sms_incoming_msg_info *incoming_msg;
604
605         ril_data.state.sms_incoming_msg_tpid = 0;
606
607         incoming_msg = ipc_sms_incoming_msg_info_find();
608         if (incoming_msg == NULL)
609                 return;
610
611         ipc_sms_incoming_msg_complete(incoming_msg->pdu, incoming_msg->length, incoming_msg->type, incoming_msg->tpid);
612         ipc_sms_incoming_msg_unregister(incoming_msg);
613 }
614
615 /*
616  * In: IPC_SMS_INCOMING_MSG
617  *   Message to notify an incoming message, with PDU
618  *
619  * Out: RIL_UNSOL_RESPONSE_NEW_SMS or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT
620  *   Notify RILJ about the incoming message
621  */
622 void ipc_sms_incoming_msg_complete(char *pdu, int length, unsigned char type, unsigned char tpid)
623 {
624         if (pdu == NULL || length <= 0)
625                 return;
626
627         ril_data.state.sms_incoming_msg_tpid = tpid;
628
629         if (type == IPC_SMS_TYPE_POINT_TO_POINT) {
630                 ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS, pdu, length);
631         } else if (type == IPC_SMS_TYPE_STATUS_REPORT) {
632                 ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, pdu, length);
633         } else {
634                 LOGE("Unhandled message type: %x", type);
635         }
636
637         free(pdu);
638 }
639
640 void ipc_sms_incoming_msg(struct ipc_message_info *info)
641 {
642         struct ipc_sms_incoming_msg *msg;
643         unsigned char *pdu_hex;
644         char *pdu;
645         int length;
646         int rc;
647
648         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_incoming_msg))
649                 return;
650
651         msg = (struct ipc_sms_incoming_msg *) info->data;
652         pdu_hex = ((unsigned char *) info->data + sizeof(struct ipc_sms_incoming_msg));
653
654         length = msg->length * 2 + 1;
655         pdu = (char *) calloc(1, length);
656
657         bin2hex(pdu_hex, msg->length, pdu);
658
659         if (ril_data.state.sms_incoming_msg_tpid != 0) {
660                 LOGD("Another message is waiting ACK, queuing");
661                 rc = ipc_sms_incoming_msg_register(pdu, length, msg->type, msg->msg_tpid);
662                 if (rc < 0)
663                         LOGE("Unable to register incoming msg");
664
665                 return;
666         }
667
668         ipc_sms_incoming_msg_complete(pdu, length, msg->type, msg->msg_tpid);
669 }
670
671 /*
672  * In: RIL_REQUEST_SMS_ACKNOWLEDGE
673  *   Acknowledge successful or failed receipt of SMS previously indicated
674  *   via RIL_UNSOL_RESPONSE_NEW_SMS
675  *
676  * Out: IPC_SMS_DELIVER_REPORT
677  *   Sends a SMS delivery report
678  */
679 void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t length)
680 {
681         struct ipc_sms_deliver_report_request report_msg;
682         int success, fail_cause;
683
684         if (data == NULL || length < 2 * sizeof(int))
685                 return;
686
687         success = ((int *) data)[0];
688         fail_cause = ((int *) data)[1];
689
690         if (ril_data.state.sms_incoming_msg_tpid == 0) {
691                 LOGE("There is no SMS message to ACK!");
692                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
693                 ipc_sms_incoming_msg_next();
694                 return;
695         }
696
697         report_msg.type = IPC_SMS_TYPE_STATUS_REPORT;
698         report_msg.error = ril2ipc_sms_ack_error(success, fail_cause);
699         report_msg.msg_tpid = ril_data.state.sms_incoming_msg_tpid;
700         report_msg.unk = 0;
701
702         ipc_gen_phone_res_expect_to_abort(ril_request_get_id(t), IPC_SMS_DELIVER_REPORT);
703
704         ipc_fmt_send(IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(report_msg), ril_request_get_id(t));
705
706         ipc_sms_incoming_msg_next();
707 }
708
709 /*
710  * In: IPC_SMS_DELIVER_REPORT
711  *   Attest that the modem successfully sent our SMS recv ACK 
712  */
713 void ipc_sms_deliver_report(struct ipc_message_info *info)
714 {
715         struct ipc_sms_deliver_report_response *report_msg;
716         RIL_Errno e;
717         int error_code;
718
719         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_deliver_report_response))
720                 return;
721
722         report_msg = (struct ipc_sms_deliver_report_response *) info->data;
723         e = ipc2ril_sms_ack_error(report_msg->error, &error_code);
724
725         ril_request_complete(ril_request_get_token(info->aseq), e, NULL, 0);
726 }
727
728 /*
729  * Apparently non-SMS-messages-related function
730  */
731
732 void ipc_sms_device_ready(struct ipc_message_info *info)
733 {
734 #if RIL_VERSION >= 7
735         if (ril_data.state.radio_state == RADIO_STATE_ON) {
736 #else
737         if (ril_data.state.radio_state == RADIO_STATE_SIM_READY) {
738 #endif
739                 ipc_fmt_send(IPC_SMS_DEVICE_READY, IPC_TYPE_SET, NULL, 0, info->aseq);
740         }
741
742         ril_tokens_check();
743 }