2 * This file is part of Samsung-RIL.
4 * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
5 * Copyright (C) 2011-2012 Paul Kocialkowski <contact@paulk.fr>
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.
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.
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/>.
22 #define LOG_TAG "RIL-SMS"
23 #include <utils/Log.h>
25 #include "samsung-ril.h"
29 * Format conversion utils
32 unsigned short ril2ipc_sms_ack_error(int success, int failcause)
35 return IPC_SMS_ACK_NO_ERROR;
39 return IPC_SMS_ACK_PDA_FULL_ERROR;
41 return IPC_SMS_ACK_UNSPEC_ERROR;
46 RIL_Errno ipc2ril_sms_ack_error(unsigned short error, int *error_code)
48 /* error_code is defined in See 3GPP 27.005, 3.2.5 for GSM/UMTS */
51 case IPC_SMS_ACK_NO_ERROR:
57 return RIL_E_GENERIC_FAILURE;
62 * Outgoing SMS functions
65 int ril_request_send_sms_register(char *pdu, int pdu_length, unsigned char *smsc, int smsc_length, RIL_Token t)
67 struct ril_request_send_sms_info *send_sms;
68 struct list_head *list_end;
69 struct list_head *list;
71 send_sms = calloc(1, sizeof(struct ril_request_send_sms_info));
76 send_sms->pdu_length = pdu_length;
77 send_sms->smsc = smsc;
78 send_sms->smsc_length = smsc_length;
81 list_end = ril_data.outgoing_sms;
82 while (list_end != NULL && list_end->next != NULL)
83 list_end = list_end->next;
85 list = list_head_alloc((void *) send_sms, list_end, NULL);
87 if (ril_data.outgoing_sms == NULL)
88 ril_data.outgoing_sms = list;
93 void ril_request_send_sms_unregister(struct ril_request_send_sms_info *send_sms)
95 struct list_head *list;
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));
106 if (list == ril_data.outgoing_sms)
107 ril_data.outgoing_sms = list->next;
109 list_head_free(list);
118 struct ril_request_send_sms_info *ril_request_send_sms_info_find(void)
120 struct ril_request_send_sms_info *send_sms;
121 struct list_head *list;
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)
138 struct ril_request_send_sms_info *ril_request_send_sms_info_find_token(RIL_Token t)
140 struct ril_request_send_sms_info *send_sms;
141 struct list_head *list;
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)
149 if (send_sms->token == t)
159 void ril_request_send_sms_info_clear(struct ril_request_send_sms_info *send_sms)
161 if (send_sms == NULL)
164 if (send_sms->pdu != NULL)
167 if (send_sms->smsc != NULL)
168 free(send_sms->smsc);
171 void ril_request_send_sms_next(void)
173 struct ril_request_send_sms_info *send_sms;
181 ril_data.tokens.outgoing_sms = (RIL_Token) 0x00;
183 send_sms = ril_request_send_sms_info_find();
184 if (send_sms == NULL)
189 pdu_length = send_sms->pdu_length;
190 smsc = send_sms->smsc;
191 smsc_length = send_sms->smsc_length;
193 ril_request_send_sms_unregister(send_sms);
196 LOGE("SMS send request has no valid PDU");
202 ril_data.tokens.outgoing_sms = t;
204 // We first need to get SMS SVC before sending the message
205 LOGD("We have no SMSC, let's ask one");
207 rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t);
209 LOGE("Unable to add the request to the list");
211 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
214 // Send the next SMS in the list
215 ril_request_send_sms_next();
218 ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t));
220 ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length);
229 * In: RIL_REQUEST_SEND_SMS
230 * Send an SMS message.
232 * Out: IPC_SMS_SEND_MSG
234 void ril_request_send_sms_complete(RIL_Token t, char *pdu, int pdu_length, unsigned char *smsc, int smsc_length)
236 struct ipc_sms_send_msg_request send_msg;
237 unsigned char send_msg_type;
239 unsigned char *pdu_hex;
247 if (pdu == NULL || pdu_length <= 0 || smsc == NULL || smsc_length <= 0) {
248 LOGE("Provided PDU or SMSC is invalid! Aborting");
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();
256 if ((pdu_length / 2 + smsc_length) > 0xfe) {
257 LOGE("PDU or SMSC too large, aborting");
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();
266 pdu_hex_length = pdu_length % 2 == 0 ? pdu_length / 2 :
267 (pdu_length ^ 1) / 2;
269 // Length of the final message
270 length = sizeof(send_msg) + pdu_hex_length + smsc_length;
272 LOGD("Sending SMS message (length: 0x%x)!", length);
274 pdu_hex = calloc(1, pdu_hex_length);
275 hex2bin(pdu, pdu_length, pdu_hex);
276 send_msg_type = IPC_SMS_MSG_SINGLE;
279 int pdu_tp_da_index = 2;
280 unsigned char pdu_tp_da_len = pdu_hex[pdu_tp_da_index];
282 if (pdu_tp_da_len > 0xff / 2) {
283 LOGE("PDU TP-DA Len failed (0x%x)\n", pdu_tp_da_len);
287 LOGD("PDU TP-DA Len is 0x%x\n", pdu_tp_da_len);
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];
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);
297 LOGD("PDU TP-UDH Len is 0x%x\n", pdu_tp_udh_len);
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];
302 if (pdu_tp_udh_num > 0xf) {
303 LOGE("PDU TP-UDH Num failed (0x%x)\n", pdu_tp_udh_num);
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];
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);
315 LOGD("We are sending message %d on %d\n", pdu_tp_udh_seq, pdu_tp_udh_num);
317 if (pdu_tp_udh_num > 1) {
318 LOGD("We are sending a multi-part message!");
319 send_msg_type = IPC_SMS_MSG_MULTIPLE;
323 // Alloc memory for the final message
324 data = calloc(1, length);
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;
333 // Copy the parts of the message
335 memcpy(p, &send_msg, sizeof(send_msg));
336 p += sizeof(send_msg);
337 memcpy(p, smsc, smsc_length);
339 memcpy(p, pdu_hex, pdu_hex_length);
341 ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SMS_SEND_MSG, ipc_sms_send_msg_complete);
343 ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, length, ril_request_get_id(t));
349 void ril_request_send_sms(RIL_Token t, void *data, size_t length)
357 if (data == NULL || length < 2 * sizeof(char *))
360 pdu = ((char **) data)[1];
361 smsc = ((unsigned char **) data)[0];
366 pdu_length = strlen(pdu) + 1;
370 smsc_length = strlen((char *) smsc);
371 smsc = (unsigned char *) strdup((char *) smsc);
374 if (ril_data.tokens.outgoing_sms != (RIL_Token) 0x00) {
375 LOGD("Another outgoing SMS is being processed, adding to the list");
377 rc = ril_request_send_sms_register(pdu, pdu_length, smsc, smsc_length, t);
379 LOGE("Unable to add the request to the list");
381 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
386 // Send the next SMS in the list
387 ril_request_send_sms_next();
393 ril_data.tokens.outgoing_sms = t;
395 // We first need to get SMS SVC before sending the message
396 LOGD("We have no SMSC, let's ask one");
398 rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t);
400 LOGE("Unable to add the request to the list");
402 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
405 // Send the next SMS in the list
406 ril_request_send_sms_next();
409 ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t));
411 ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length);
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)
425 * Out: IPC_SMS_SEND_MSG
427 void ril_request_send_sms_expect_more(RIL_Token t, void *data, size_t length)
429 /* No particular treatment here, we already have a queue */
430 ril_request_send_sms(t, data, length);
434 * In: IPC_SMS_SVC_CENTER_ADDR
435 * SMSC: Service Center Address, needed to send an SMS
437 * Out: IPC_SMS_SEND_MSG
439 void ipc_sms_svc_center_addr(struct ipc_message_info *info)
441 struct ril_request_send_sms_info *send_sms;
449 if (info == NULL || info->data == NULL)
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!");
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();
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];
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);
478 void ipc_sms_send_msg_complete(struct ipc_message_info *info)
480 struct ril_request_send_sms_info *send_sms;
481 struct ipc_gen_phone_res *phone_res;
483 if (info->data == NULL || info->length < sizeof(struct ipc_gen_phone_res))
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");
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();
497 * In: IPC_SMS_SEND_MSG
498 * This comes to ACK the latest sent SMS message
500 void ipc_sms_send_msg(struct ipc_message_info *info)
502 struct ipc_sms_send_msg_response *report_msg;
503 RIL_SMS_Response response;
506 if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_send_msg_response))
509 report_msg = (struct ipc_sms_send_msg_response *) info->data;
511 LOGD("Got ACK for msg_tpid #%d\n", report_msg->msg_tpid);
513 memset(&response, 0, sizeof(response));
514 response.messageRef = report_msg->msg_tpid;
515 response.ackPDU = NULL;
517 e = ipc2ril_sms_ack_error(report_msg->error, &response.errorCode);
519 ril_request_complete(ril_request_get_token(info->aseq), e, (void *) &response, sizeof(response));
521 // Send the next SMS in the list
522 ril_request_send_sms_next();
526 * Incoming SMS functions
529 int ipc_sms_incoming_msg_register(char *pdu, int length, unsigned char type, unsigned char tpid)
531 struct ipc_sms_incoming_msg_info *incoming_msg;
532 struct list_head *list_end;
533 struct list_head *list;
535 incoming_msg = calloc(1, sizeof(struct ipc_sms_incoming_msg_info));
536 if (incoming_msg == NULL)
539 incoming_msg->pdu = pdu;
540 incoming_msg->length = length;
541 incoming_msg->type = type;
542 incoming_msg->tpid = tpid;
544 list_end = ril_data.incoming_sms;
545 while (list_end != NULL && list_end->next != NULL)
546 list_end = list_end->next;
548 list = list_head_alloc((void *) incoming_msg, list_end, NULL);
550 if (ril_data.incoming_sms == NULL)
551 ril_data.incoming_sms = list;
556 void ipc_sms_incoming_msg_unregister(struct ipc_sms_incoming_msg_info *incoming_msg)
558 struct list_head *list;
560 if (incoming_msg == NULL)
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));
569 if (list == ril_data.incoming_sms)
570 ril_data.incoming_sms = list->next;
572 list_head_free(list);
581 struct ipc_sms_incoming_msg_info *ipc_sms_incoming_msg_info_find(void)
583 struct ipc_sms_incoming_msg_info *incoming_msg;
584 struct list_head *list;
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)
601 void ipc_sms_incoming_msg_next(void)
603 struct ipc_sms_incoming_msg_info *incoming_msg;
605 ril_data.state.sms_incoming_msg_tpid = 0;
607 incoming_msg = ipc_sms_incoming_msg_info_find();
608 if (incoming_msg == NULL)
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);
616 * In: IPC_SMS_INCOMING_MSG
617 * Message to notify an incoming message, with PDU
619 * Out: RIL_UNSOL_RESPONSE_NEW_SMS or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT
620 * Notify RILJ about the incoming message
622 void ipc_sms_incoming_msg_complete(char *pdu, int length, unsigned char type, unsigned char tpid)
624 if (pdu == NULL || length <= 0)
627 ril_data.state.sms_incoming_msg_tpid = tpid;
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);
634 LOGE("Unhandled message type: %x", type);
640 void ipc_sms_incoming_msg(struct ipc_message_info *info)
642 struct ipc_sms_incoming_msg *msg;
643 unsigned char *pdu_hex;
648 if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_incoming_msg))
651 msg = (struct ipc_sms_incoming_msg *) info->data;
652 pdu_hex = ((unsigned char *) info->data + sizeof(struct ipc_sms_incoming_msg));
654 length = msg->length * 2 + 1;
655 pdu = (char *) calloc(1, length);
657 bin2hex(pdu_hex, msg->length, pdu);
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);
663 LOGE("Unable to register incoming msg");
668 ipc_sms_incoming_msg_complete(pdu, length, msg->type, msg->msg_tpid);
672 * In: RIL_REQUEST_SMS_ACKNOWLEDGE
673 * Acknowledge successful or failed receipt of SMS previously indicated
674 * via RIL_UNSOL_RESPONSE_NEW_SMS
676 * Out: IPC_SMS_DELIVER_REPORT
677 * Sends a SMS delivery report
679 void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t length)
681 struct ipc_sms_deliver_report_request report_msg;
682 int success, fail_cause;
684 if (data == NULL || length < 2 * sizeof(int))
687 success = ((int *) data)[0];
688 fail_cause = ((int *) data)[1];
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();
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;
702 ipc_gen_phone_res_expect_to_abort(ril_request_get_id(t), IPC_SMS_DELIVER_REPORT);
704 ipc_fmt_send(IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(report_msg), ril_request_get_id(t));
706 ipc_sms_incoming_msg_next();
710 * In: IPC_SMS_DELIVER_REPORT
711 * Attest that the modem successfully sent our SMS recv ACK
713 void ipc_sms_deliver_report(struct ipc_message_info *info)
715 struct ipc_sms_deliver_report_response *report_msg;
719 if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_deliver_report_response))
722 report_msg = (struct ipc_sms_deliver_report_response *) info->data;
723 e = ipc2ril_sms_ack_error(report_msg->error, &error_code);
725 ril_request_complete(ril_request_get_token(info->aseq), e, NULL, 0);
729 * Apparently non-SMS-messages-related function
732 void ipc_sms_device_ready(struct ipc_message_info *info)
735 if (ril_data.state.radio_state == RADIO_STATE_ON) {
737 if (ril_data.state.radio_state == RADIO_STATE_SIM_READY) {
739 ipc_fmt_send(IPC_SMS_DEVICE_READY, IPC_TYPE_SET, NULL, 0, info->aseq);