Fix some compilation warnings
[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 Paul Kocialkowski <contact@oaulk.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  * SMS global vars
30  */
31
32 struct ril_request_sms ril_request_sms[10];
33 int ril_request_sms_lock = 0;
34
35 unsigned char ipc_sms_tpid_queue[10];
36
37 /**
38  * Format conversion utils
39  */
40
41 unsigned short ril2ipc_sms_ack_error(int success, int failcause)
42 {
43         if(success) {
44                 return IPC_SMS_ACK_NO_ERROR;
45         } else {
46                 switch(failcause) {
47                         case 0xD3:
48                                 return IPC_SMS_ACK_PDA_FULL_ERROR;
49                         default:
50                                 return IPC_SMS_ACK_UNSPEC_ERROR;
51                 }
52         }
53 }
54
55 RIL_Errno ipc2ril_sms_ack_error(unsigned short error, int *error_code)
56 {
57         /* error_code is defined in See 3GPP 27.005, 3.2.5 for GSM/UMTS */
58
59         switch(error) {
60                 case IPC_SMS_ACK_NO_ERROR:
61                         *error_code = -1;
62                         return RIL_E_SUCCESS;
63                 default:
64                         // unknown error
65                         *error_code = 500;
66                         return RIL_E_GENERIC_FAILURE;
67         }
68 }
69
70 /**
71  * RIL request SMS (queue) functions
72  */
73
74 void ril_request_sms_init(void)
75 {
76         memset(ril_request_sms, 0, sizeof(struct ril_request_sms) * 10);
77         ril_request_sms_lock = 0;
78 }
79
80 void ril_request_sms_del(int id)
81 {
82         if(id < 0 || id > 9) {
83                 LOGD("Invalid id (%d) for the SMS queue", id);
84                 return;
85         }
86
87         ril_request_sms[id].aseq = 0;
88         ril_request_sms[id].pdu_len = 0;
89         ril_request_sms[id].smsc_len = 0;
90
91         if(ril_request_sms[id].pdu != NULL)
92                 free(ril_request_sms[id].pdu);
93         if(ril_request_sms[id].smsc != NULL)
94                 free(ril_request_sms[id].smsc);
95 }
96
97 void ril_request_sms_clear(int id)
98 {
99         if(id < 0 || id > 9) {
100                 LOGD("Invalid id (%d) for the SMS queue", id);
101                 return;
102         }
103
104         ril_request_sms[id].aseq = 0;
105         ril_request_sms[id].pdu = NULL;
106         ril_request_sms[id].pdu_len = 0;
107         ril_request_sms[id].smsc = NULL;
108         ril_request_sms[id].smsc_len = 0;
109 }
110
111 int ril_request_sms_new(void)
112 {
113         int id = -1;
114         int i;
115
116         /* Find the highest place in the queue */
117         for(i=10 ; i > 0 ; i--) {
118                 if(ril_request_sms[i-1].aseq && ril_request_sms[i-1].pdu) {
119                         break;
120                 }
121
122                 id = i-1;
123         }
124
125         if(id < 0) {
126                 LOGE("The SMS queue is full, removing the oldest req");
127         
128                 /* Free the request at index 0 (oldest) */
129                 ril_request_sms_del(0);
130
131                 /* Increase all the requests id to have the last one free */
132                 for(i=1 ; i < 10 ; i++) {
133                         LOGD("SMS queue: moving %d -> %d", i, i-1);
134                         memcpy(&ril_request_sms[i-1], &ril_request_sms[i], sizeof(struct ril_request_sms));
135                 }
136
137                 /* We must not free the pointers here as we copied these at index 8 */
138
139                 ril_request_sms_clear(9);
140
141                 return 9;
142         }
143
144         return id;
145 }
146
147 int ril_request_sms_add(unsigned char aseq,
148                         char *pdu, int pdu_len, 
149                         char *smsc, int smsc_len)
150 {
151         int id = ril_request_sms_new();
152
153         LOGD("Storing new SMS request in the queue at index %d\n", id);
154
155         ril_request_sms[id].aseq = aseq;
156         ril_request_sms[id].smsc_len = smsc_len;
157         ril_request_sms[id].pdu_len = pdu_len;
158
159         if(pdu != NULL) {
160                 ril_request_sms[id].pdu = malloc(pdu_len);
161                 memcpy(ril_request_sms[id].pdu, pdu, pdu_len);
162         }
163
164         if(smsc != NULL) {
165                 ril_request_sms[id].smsc = malloc(smsc_len);
166                 memcpy(ril_request_sms[id].smsc, smsc, smsc_len);
167         }
168
169         return id;
170 }
171
172 int ril_request_sms_get_id(unsigned char aseq)
173 {
174         int i;
175
176         for(i=0 ; i < 10 ; i++) {
177                 if(ril_request_sms[i].aseq == aseq) {
178                         return i;
179                 }
180         }
181
182         return -1;
183 }
184
185 int ril_request_sms_get_next(void)
186 {
187         int id = -1;
188         int i;
189
190         for(i=0 ; i < 10 ; i++) {
191                 if(ril_request_sms[i].aseq && ril_request_sms[i].pdu) {
192                         id = i;
193                 }
194         }
195
196         if(id < 0)
197                 LOGD("Nothing left on the queue!");
198         else
199                 LOGD("Next queued request is at id #%d\n", id);
200
201         return id;
202 }
203
204 int ril_request_sms_lock_acquire(void)
205 {
206         if(ril_request_sms_lock > 0) {
207                 return 0;
208         } else
209         {
210                 ril_request_sms_lock = 1;
211                 return 1;
212         }
213 }
214
215 void ril_request_sms_lock_release(void)
216 {
217         ril_request_sms_lock = 0;
218 }
219
220 /**
221  * Outgoing SMS functions
222  */
223
224 /**
225  * In: RIL_REQUEST_SEND_SMS
226  *   Send an SMS message.
227  *
228  * Out: IPC_SMS_SEND_MSG
229  */
230 void ril_request_send_sms(RIL_Token t, void *data, size_t datalen)
231 {
232         char **request = (char **) data;
233         char *pdu = request[1];
234         int pdu_len = pdu != NULL ? strlen(pdu) : 0;
235         char *smsc = request[0];
236         int smsc_len = smsc != NULL ? strlen(smsc) : 0;
237
238         if(!ril_request_sms_lock_acquire()) {
239                 LOGD("The SMS lock is already taken, adding req to the SMS queue");
240
241                 ril_request_sms_add(reqGetId(t), pdu, pdu_len, smsc, smsc_len);
242                 return;
243         }
244
245         /* We first need to get SMS SVC before sending the message */
246         if(smsc == NULL) {
247                 LOGD("We have no SMSC, let's ask one");
248
249                 /* Enqueue the request */
250                 ril_request_sms_add(reqGetId(t), pdu, pdu_len, NULL, 0);
251
252                 ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, reqGetId(t));
253                 
254         } else {
255                 ril_request_send_sms_complete(t, pdu, smsc);
256         }
257 }
258
259 /**
260  * In: RIL_REQUEST_SEND_SMS_EXPECT_MORE
261  *   Send an SMS message. Identical to RIL_REQUEST_SEND_SMS,
262  *   except that more messages are expected to be sent soon. If possible,
263  *   keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command)
264  *
265  * Out: IPC_SMS_SEND_MSG
266  */
267 void ril_request_send_sms_expect_more(RIL_Token t, void *data, size_t datalen)
268 {
269         /* No particular treatment here, we already have a queue */
270         ril_request_send_sms(t, data, datalen);
271 }
272
273 /**
274  * Send the next SMS in the queue
275  */
276 int ril_request_send_sms_next(void)
277 {
278         int id = ril_request_sms_get_next();
279
280         char *request[2] = { NULL };
281         unsigned char aseq;
282         char *pdu;
283         char *smsc;
284
285         /* When calling this function, you assume you're done with the previous sms req */
286         ril_request_sms_lock_release();
287
288         if(id < 0) 
289                 return -1;
290
291         LOGD("Sending queued SMS!");
292
293         aseq = ril_request_sms[id].aseq;
294         pdu = ril_request_sms[id].pdu;
295         smsc = ril_request_sms[id].smsc;
296
297         request[0] = smsc;
298         request[1] = pdu;
299
300         /* We need to clear here to prevent infinite loop, but we can't free mem yet */
301         ril_request_sms_clear(id);
302
303         ril_request_send_sms(reqGetToken(aseq), (void *) request, sizeof(request));
304
305         if(pdu != NULL)
306                 free(pdu);
307
308         if(smsc != NULL)
309                 free(smsc);
310
311         return id;
312 }
313
314 /**
315  * Complete (continue) the send_sms request (do the real sending)
316  */
317 void ril_request_send_sms_complete(RIL_Token t, char *pdu, char *smsc)
318 {
319         struct ipc_sms_send_msg send_msg;
320         unsigned char send_msg_type = IPC_SMS_MSG_SINGLE;
321         int send_msg_len;
322
323         char *data;
324         int data_len;
325
326         char *pdu_dec;
327         unsigned char pdu_dec_len;
328
329         int pdu_len;
330         unsigned char smsc_len;
331
332         char *p;
333
334         if(pdu == NULL || smsc == NULL) {
335                 LOGE("Provided PDU or SMSC is NULL! Aborting");
336
337                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
338
339                 /* Release the lock so we can accept new requests */
340                 ril_request_sms_lock_release();
341                 /* Now send the next message in the queue if any */
342                 ril_request_send_sms_next();
343
344                 return;
345         }
346
347         /* Setting various len vars */
348         pdu_len = strlen(pdu);
349
350         if(pdu_len / 2 > 0xff) {
351                 LOGE("PDU is too large, aborting");
352
353                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
354
355                 /* Release the lock so we can accept new requests */
356                 ril_request_sms_lock_release();
357                 /* Now send the next message in the queue if any */
358                 ril_request_send_sms_next();
359
360                 return;
361         }
362
363         pdu_dec_len = pdu_len / 2;
364         smsc_len = smsc[0];
365         send_msg_len = sizeof(struct ipc_sms_send_msg);
366
367         /* Length of the final message */
368         data_len = pdu_dec_len + smsc_len + send_msg_len;
369
370         LOGD("Sending SMS message!");
371
372         LOGD("data_len is 0x%x + 0x%x + 0x%x = 0x%x\n", pdu_dec_len, smsc_len, send_msg_len, data_len);
373
374         pdu_dec = malloc(pdu_dec_len);
375         hex2bin(pdu, pdu_len, (unsigned char*)pdu_dec);
376
377         /* PDU operations */
378         int pdu_tp_da_index = 2;
379         unsigned char pdu_tp_da_len = pdu_dec[pdu_tp_da_index];
380
381         if(pdu_tp_da_len > 0xff / 2) {
382                 LOGE("PDU TP-DA Len failed (0x%x)\n", pdu_tp_da_len);
383                 goto pdu_end;
384         }
385
386         LOGD("PDU TP-DA Len is 0x%x\n", pdu_tp_da_len);
387
388         int pdu_tp_udh_index = pdu_tp_da_index + pdu_tp_da_len;
389         unsigned char pdu_tp_udh_len = pdu_dec[pdu_tp_udh_index];
390         
391         if(pdu_tp_udh_len > 0xff / 2 || pdu_tp_udh_len < 5) {
392                 LOGE("PDU TP-UDH Len failed (0x%x)\n", pdu_tp_udh_len);
393                 goto pdu_end;
394         }
395
396         LOGD("PDU TP-UDH Len is 0x%x\n", pdu_tp_udh_len);
397
398         int pdu_tp_udh_num_index = pdu_tp_udh_index + 4;
399         unsigned char pdu_tp_udh_num = pdu_dec[pdu_tp_udh_num_index];
400
401         if(pdu_tp_udh_num > 0xf) {
402                 LOGE("PDU TP-UDH Num failed (0x%x)\n", pdu_tp_udh_num);
403                 goto pdu_end;
404         }
405
406         int pdu_tp_udh_seq_index = pdu_tp_udh_index + 5;
407         unsigned char pdu_tp_udh_seq = pdu_dec[pdu_tp_udh_seq_index];
408
409         if(pdu_tp_udh_seq > 0xf || pdu_tp_udh_seq > pdu_tp_udh_num) {
410                 LOGE("PDU TP-UDH Seq failed (0x%x)\n", pdu_tp_udh_seq);
411                 goto pdu_end;
412         }
413
414         LOGD("We are sending message %d on %d\n", pdu_tp_udh_seq, pdu_tp_udh_num);
415
416         if(pdu_tp_udh_num > 1) {
417                 LOGD("We are sending a multi-part message!");
418                 send_msg_type = IPC_SMS_MSG_MULTIPLE;
419         }
420
421 pdu_end:
422         /* Alloc and clean memory for the final message */
423         data = malloc(data_len);
424         memset(&send_msg, 0, sizeof(struct ipc_sms_send_msg));
425
426         /* Fill the IPC structure part of the message */
427         send_msg.type = IPC_SMS_TYPE_OUTGOING;
428         send_msg.msg_type = send_msg_type;
429         send_msg.length = (unsigned char) (pdu_dec_len + smsc_len + 1);
430         send_msg.smsc_len = smsc_len;
431
432         /* Copy the other parts of the message */
433         p = data;
434         memcpy(p, &send_msg, send_msg_len);
435         p +=  send_msg_len;
436         memcpy(p, (char *) (smsc + 1), smsc_len); // First SMSC bytes is length
437         p += smsc_len;
438         memcpy(p, pdu_dec, pdu_dec_len);
439
440         ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_SMS_SEND_MSG, ipc_sms_send_msg_complete);
441
442         ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, data_len, reqGetId(t));
443
444         free(pdu_dec);
445         free(data);
446 }
447
448 void ipc_sms_send_msg_complete(struct ipc_message_info *info)
449 {
450         struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
451
452         if(ipc_gen_phone_res_check(phone_res) < 0) {
453                 LOGE("IPC_GEN_PHONE_RES indicates error, abort request to RILJ");
454
455                 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
456
457                 /* Release the lock so we can accept new requests */
458                 ril_request_sms_lock_release();
459                 /* Now send the next message in the queue if any */
460                 ril_request_send_sms_next();
461         }
462 }
463
464 /**
465  * In: IPC_SMS_SVC_CENTER_ADDR
466  *   SMSC: Service Center Address, needed to send an SMS
467  *
468  * Out: IPC_SMS_SEND_MSG
469  */
470 void ipc_sms_svc_center_addr(struct ipc_message_info *info)
471 {
472         int id = ril_request_sms_get_id(info->aseq);
473
474         char *pdu;
475         int pdu_len;
476
477         if(id < 0) {
478                 LOGE("The request wasn't queued, reporting generic error!");
479
480                 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
481
482                 /* Release the lock so we can accept new requests */
483                 ril_request_sms_lock_release();
484                 /* Now send the next message in the queue if any */
485                 ril_request_send_sms_next();
486
487                 return;
488         }
489
490         LOGD("Completing the request");
491
492         pdu = ril_request_sms[id].pdu;
493         pdu_len = ril_request_sms[id].pdu_len;
494
495         /* We need to clear here to prevent infinite loop, but we can't free mem yet */
496         ril_request_sms_clear(id);
497
498         ril_request_send_sms_complete(reqGetToken(info->aseq), pdu, (char *) info->data);
499
500         /* Now it is safe to free mem */
501         if(pdu != NULL)
502                 free(pdu);
503 }
504
505 /**
506  * In: IPC_SMS_SEND_MSG
507  *   This comes to ACK the latest sent SMS message
508  */
509 void ipc_sms_send_msg(struct ipc_message_info *info)
510 {
511         struct ipc_sms_deliv_report_msg *report_msg = (struct ipc_sms_deliv_report_msg *) info->data;
512         RIL_SMS_Response response;
513         
514         RIL_Errno ril_ack_err;
515
516         LOGD("Got ACK for msg_tpid #%d\n", report_msg->msg_tpid);
517
518         response.messageRef = report_msg->msg_tpid;
519         response.ackPDU = NULL;
520         ril_ack_err = ipc2ril_sms_ack_error(report_msg->error, &(response.errorCode));
521
522         RIL_onRequestComplete(reqGetToken(info->aseq), ril_ack_err, &response, sizeof(response));
523
524         /* Release the lock so we can accept new requests */
525         ril_request_sms_lock_release();
526         /* Now send the next message in the queue if any */
527         ril_request_send_sms_next();
528 }
529
530 /**
531  * IPC incoming SMS queue functions
532  */
533
534 void ipc_sms_tpid_queue_init(void)
535 {
536         memset(ipc_sms_tpid_queue, 0, sizeof(unsigned char) * 10);
537 }
538
539 void ipc_sms_tpid_queue_del(int id)
540 {
541         if(id < 0 || id > 9) {
542                 LOGD("Invalid id (%d) for the SMS tpid queue", id);
543                 return;
544         }
545
546         ipc_sms_tpid_queue[id] = 0;
547 }
548
549 int ipc_sms_tpid_queue_new(void)
550 {
551         int id = -1;
552         int i;
553
554         /* Find the highest place in the queue */
555         for(i=10 ; i > 0 ; i--) {
556                 if(ipc_sms_tpid_queue[i-1]) {
557                         break;
558                 }
559
560                 id = i-1;
561         }
562
563         if(id < 0) {
564                 LOGE("The SMS tpid queue is full, removing the oldest tpid");
565
566                 ipc_sms_tpid_queue_del(0);
567
568                 for(i=1 ; i < 10 ; i++) {
569                         LOGD("SMS tpid queue: moving %d -> %d", i, i-1);
570                         ipc_sms_tpid_queue[i-1] = ipc_sms_tpid_queue[i];
571                 }
572
573                 ipc_sms_tpid_queue_del(9);
574
575                 return 9;
576         }
577
578         return id;
579 }
580
581 int ipc_sms_tpid_queue_add(unsigned char sms_tpid)
582 {
583         int id = ipc_sms_tpid_queue_new();
584
585         LOGD("Storing new SMS tpid in the queue at index %d\n", id);
586
587         ipc_sms_tpid_queue[id] = sms_tpid;
588
589         return id;
590 }
591
592 int ipc_sms_tpid_queue_get_next(void)
593 {
594         int id = -1;
595         int i;
596
597         for(i=0 ; i < 10 ; i++) {
598                 if(ipc_sms_tpid_queue[i]) {
599                         id = i;
600                 }
601         }
602
603         if(id < 0)
604                 LOGD("Nothing left on the queue!");
605         else
606                 LOGD("Next queued tpid is at id #%d\n", id);
607
608         return id;
609 }
610
611 /**
612  * Incoming SMS functions
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
623 void ipc_sms_incoming_msg(struct ipc_message_info *info)
624 {
625         struct ipc_sms_incoming_msg *msg = (struct ipc_sms_incoming_msg *) info->data;
626         char *pdu = ((char *) info->data + sizeof(struct ipc_sms_incoming_msg));
627
628         int resp_length = msg->length * 2 + 1;
629         char *resp = (char *) malloc(resp_length);
630
631         bin2hex(pdu, msg->length, resp);
632
633         ipc_sms_tpid_queue_add(msg->msg_tpid);
634
635         if(msg->type == IPC_SMS_TYPE_POINT_TO_POINT) {
636                 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NEW_SMS, resp, resp_length);
637         } else if(msg->type == IPC_SMS_TYPE_STATUS_REPORT) {
638                 // FIXME: do we need to enqueue for this?
639
640                 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, resp, resp_length);
641         } else {
642                 LOGE("%s: Unknown message type", __FUNCTION__);
643         }
644
645 exit:
646         free(resp);
647 }
648
649 /**
650  * In: RIL_REQUEST_SMS_ACKNOWLEDGE
651  *   Acknowledge successful or failed receipt of SMS previously indicated
652  *   via RIL_UNSOL_RESPONSE_NEW_SMS
653  *
654  * Out: IPC_SMS_DELIVER_REPORT
655  *   Sends a SMS delivery report
656  */
657 void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t datalen)
658 {
659         struct ipc_sms_deliv_report_msg report_msg;
660         int success = ((int *)data)[0];
661         int failcause = ((int *)data)[1];
662         int id = ipc_sms_tpid_queue_get_next();
663
664         if(id < 0) {
665                 LOGE("There is no SMS message to ACK!");
666                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
667
668                 return;
669         }
670
671         report_msg.type = IPC_SMS_TYPE_STATUS_REPORT;
672         report_msg.error = ril2ipc_sms_ack_error(success, failcause);
673         report_msg.msg_tpid = ipc_sms_tpid_queue[id];
674         report_msg.unk = 0;
675
676         ipc_gen_phone_res_expect_to_abort(reqGetId(t), IPC_SMS_DELIVER_REPORT);
677
678         ipc_fmt_send(IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(struct ipc_sms_deliv_report_msg), reqGetId(t));
679
680         ipc_sms_tpid_queue_del(id);
681 }
682
683 /**
684  * In: IPC_SMS_DELIVER_REPORT
685  *   Attest that the modem successfully sent our SMS recv ACK 
686  */
687 void ipc_sms_deliver_report(struct ipc_message_info *info)
688 {
689         // TODO: check error code to eventually resend ACK
690
691         RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, NULL, 0);
692 }
693
694 /**
695  * Apparently non-SMS-messages-related function
696  */
697
698 void ipc_sms_device_ready(struct ipc_message_info *info)
699 {
700         if(ril_state.radio_state == RADIO_STATE_SIM_READY) {
701                 ipc_fmt_send(IPC_SMS_DEVICE_READY, IPC_TYPE_SET, NULL, 0, info->aseq);
702         }
703
704         ril_tokens_check();
705 }