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 Paul Kocialkowski <contact@oaulk.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"
32 struct ril_request_sms ril_request_sms[10];
33 int ril_request_sms_lock = 0;
36 * Format conversion utils
39 unsigned short ril2ipc_sms_ack_error(int success, int failcause)
42 return IPC_SMS_ACK_NO_ERROR;
46 return IPC_SMS_ACK_PDA_FULL_ERROR;
48 return IPC_SMS_ACK_UNSPEC_ERROR;
53 RIL_Errno ipc2ril_sms_ack_error(unsigned short error, int *error_code)
55 /* error_code is defined in See 3GPP 27.005, 3.2.5 for GSM/UMTS */
58 case IPC_SMS_ACK_NO_ERROR:
64 return RIL_E_GENERIC_FAILURE;
69 * RIL request SMS (queue) functions
72 void ril_request_sms_init(void)
74 memset(ril_request_sms, 0, sizeof(struct ril_request_sms) * 10);
75 ril_request_sms_lock = 0;
78 void ril_request_sms_del(int id)
80 if(id < 0 || id > 9) {
81 LOGD("Invalid id (%d) for the SMS queue", id);
85 ril_request_sms[id].aseq = 0;
86 ril_request_sms[id].pdu_len = 0;
87 ril_request_sms[id].smsc_len = 0;
89 if(ril_request_sms[id].pdu != NULL)
90 free(ril_request_sms[id].pdu);
91 if(ril_request_sms[id].smsc != NULL)
92 free(ril_request_sms[id].smsc);
95 void ril_request_sms_clear(int id)
97 if(id < 0 || id > 9) {
98 LOGD("Invalid id (%d) for the SMS queue", id);
102 ril_request_sms[id].aseq = 0;
103 ril_request_sms[id].pdu = NULL;
104 ril_request_sms[id].pdu_len = 0;
105 ril_request_sms[id].smsc = NULL;
106 ril_request_sms[id].smsc_len = 0;
109 int ril_request_sms_new(void)
114 /* Find the highest place in the queue */
115 for(i=10 ; i > 0 ; i--) {
116 if(ril_request_sms[i-1].aseq && ril_request_sms[i-1].pdu) {
124 LOGE("The SMS queue is full, removing the oldest req");
126 /* Free the request at index 0 (oldest) */
127 ril_request_sms_del(0);
129 /* Increase all the requests id to have the last one free */
130 for(i=1 ; i < 10 ; i++) {
131 LOGD("SMS queue: moving %d -> %d", i, i-1);
132 memcpy(&ril_request_sms[i-1], &ril_request_sms[i], sizeof(struct ril_request_sms));
135 /* We must not free the pointers here as we copied these at index 8 */
137 ril_request_sms_clear(9);
145 int ril_request_sms_add(unsigned char aseq,
146 char *pdu, int pdu_len,
147 char *smsc, int smsc_len)
149 int id = ril_request_sms_new();
151 LOGD("Storing new SMS request in the queue at index %d\n", id);
153 ril_request_sms[id].aseq = aseq;
154 ril_request_sms[id].smsc_len = smsc_len;
155 ril_request_sms[id].pdu_len = pdu_len;
158 ril_request_sms[id].pdu = malloc(pdu_len);
159 memcpy(ril_request_sms[id].pdu, pdu, pdu_len);
163 ril_request_sms[id].smsc = malloc(smsc_len);
164 memcpy(ril_request_sms[id].smsc, smsc, smsc_len);
170 int ril_request_sms_get_id(unsigned char aseq)
174 for(i=0 ; i < 10 ; i++) {
175 if(ril_request_sms[i].aseq == aseq) {
183 int ril_request_sms_get_next(void)
188 for(i=0 ; i < 10 ; i++) {
189 if(ril_request_sms[i].aseq && ril_request_sms[i].pdu) {
195 LOGD("Nothing left on the queue!");
197 LOGD("Next queued request is at id #%d\n", id);
202 int ril_request_sms_lock_acquire(void)
204 if(ril_request_sms_lock > 0) {
208 ril_request_sms_lock = 1;
213 void ril_request_sms_lock_release(void)
215 ril_request_sms_lock = 0;
219 * Outgoing SMS functions
223 * In: RIL_REQUEST_SEND_SMS
224 * Send an SMS message.
226 * Out: IPC_SMS_SEND_MSG
228 void ril_request_send_sms(RIL_Token t, void *data, size_t datalen)
230 char **request = (char **) data;
231 char *pdu = request[1];
232 int pdu_len = pdu != NULL ? strlen(pdu) : 0;
233 char *smsc = request[0];
234 int smsc_len = smsc != NULL ? strlen(smsc) : 0;
236 if(!ril_request_sms_lock_acquire()) {
237 LOGD("The SMS lock is already taken, adding req to the SMS queue");
239 ril_request_sms_add(ril_request_get_id(t), pdu, pdu_len, smsc, smsc_len);
243 /* We first need to get SMS SVC before sending the message */
245 LOGD("We have no SMSC, let's ask one");
247 /* Enqueue the request */
248 ril_request_sms_add(ril_request_get_id(t), pdu, pdu_len, NULL, 0);
250 ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t));
253 ril_request_send_sms_complete(t, pdu, smsc);
258 * In: RIL_REQUEST_SEND_SMS_EXPECT_MORE
259 * Send an SMS message. Identical to RIL_REQUEST_SEND_SMS,
260 * except that more messages are expected to be sent soon. If possible,
261 * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command)
263 * Out: IPC_SMS_SEND_MSG
265 void ril_request_send_sms_expect_more(RIL_Token t, void *data, size_t datalen)
267 /* No particular treatment here, we already have a queue */
268 ril_request_send_sms(t, data, datalen);
272 * Send the next SMS in the queue
274 int ril_request_send_sms_next(void)
276 int id = ril_request_sms_get_next();
278 char *request[2] = { NULL };
283 /* When calling this function, you assume you're done with the previous sms req */
284 ril_request_sms_lock_release();
289 LOGD("Sending queued SMS!");
291 aseq = ril_request_sms[id].aseq;
292 pdu = ril_request_sms[id].pdu;
293 smsc = ril_request_sms[id].smsc;
298 /* We need to clear here to prevent infinite loop, but we can't free mem yet */
299 ril_request_sms_clear(id);
301 ril_request_send_sms(ril_request_get_token(aseq), (void *) request, sizeof(request));
313 * Complete (continue) the send_sms request (do the real sending)
315 void ril_request_send_sms_complete(RIL_Token t, char *pdu, char *smsc)
317 struct ipc_sms_send_msg_request send_msg;
318 unsigned char send_msg_type = IPC_SMS_MSG_SINGLE;
325 unsigned char pdu_dec_len;
328 unsigned char smsc_len;
332 if(pdu == NULL || smsc == NULL) {
333 LOGE("Provided PDU or SMSC is NULL! Aborting");
335 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
337 /* Release the lock so we can accept new requests */
338 ril_request_sms_lock_release();
339 /* Now send the next message in the queue if any */
340 ril_request_send_sms_next();
345 /* Setting various len vars */
346 pdu_len = strlen(pdu);
348 if(pdu_len / 2 > 0xff) {
349 LOGE("PDU is too large, aborting");
351 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
353 /* Release the lock so we can accept new requests */
354 ril_request_sms_lock_release();
355 /* Now send the next message in the queue if any */
356 ril_request_send_sms_next();
361 pdu_dec_len = pdu_len / 2;
363 send_msg_len = sizeof(struct ipc_sms_send_msg_request);
365 /* Length of the final message */
366 data_len = pdu_dec_len + smsc_len + send_msg_len;
368 LOGD("Sending SMS message!");
370 LOGD("data_len is 0x%x + 0x%x + 0x%x = 0x%x\n", pdu_dec_len, smsc_len, send_msg_len, data_len);
372 pdu_dec = malloc(pdu_dec_len);
373 hex2bin(pdu, pdu_len, (unsigned char*)pdu_dec);
376 int pdu_tp_da_index = 2;
377 unsigned char pdu_tp_da_len = pdu_dec[pdu_tp_da_index];
379 if(pdu_tp_da_len > 0xff / 2) {
380 LOGE("PDU TP-DA Len failed (0x%x)\n", pdu_tp_da_len);
384 LOGD("PDU TP-DA Len is 0x%x\n", pdu_tp_da_len);
386 int pdu_tp_udh_index = pdu_tp_da_index + pdu_tp_da_len;
387 unsigned char pdu_tp_udh_len = pdu_dec[pdu_tp_udh_index];
389 if(pdu_tp_udh_len > 0xff / 2 || pdu_tp_udh_len < 5) {
390 LOGE("PDU TP-UDH Len failed (0x%x)\n", pdu_tp_udh_len);
394 LOGD("PDU TP-UDH Len is 0x%x\n", pdu_tp_udh_len);
396 int pdu_tp_udh_num_index = pdu_tp_udh_index + 4;
397 unsigned char pdu_tp_udh_num = pdu_dec[pdu_tp_udh_num_index];
399 if(pdu_tp_udh_num > 0xf) {
400 LOGE("PDU TP-UDH Num failed (0x%x)\n", pdu_tp_udh_num);
404 int pdu_tp_udh_seq_index = pdu_tp_udh_index + 5;
405 unsigned char pdu_tp_udh_seq = pdu_dec[pdu_tp_udh_seq_index];
407 if(pdu_tp_udh_seq > 0xf || pdu_tp_udh_seq > pdu_tp_udh_num) {
408 LOGE("PDU TP-UDH Seq failed (0x%x)\n", pdu_tp_udh_seq);
412 LOGD("We are sending message %d on %d\n", pdu_tp_udh_seq, pdu_tp_udh_num);
414 if(pdu_tp_udh_num > 1) {
415 LOGD("We are sending a multi-part message!");
416 send_msg_type = IPC_SMS_MSG_MULTIPLE;
420 /* Alloc and clean memory for the final message */
421 data = malloc(data_len);
422 memset(&send_msg, 0, sizeof(struct ipc_sms_send_msg_request));
424 /* Fill the IPC structure part of the message */
425 send_msg.type = IPC_SMS_TYPE_OUTGOING;
426 send_msg.msg_type = send_msg_type;
427 send_msg.length = (unsigned char) (pdu_dec_len + smsc_len + 1);
428 send_msg.smsc_len = smsc_len;
430 /* Copy the other parts of the message */
432 memcpy(p, &send_msg, send_msg_len);
434 memcpy(p, (char *) (smsc + 1), smsc_len); // First SMSC bytes is length
436 memcpy(p, pdu_dec, pdu_dec_len);
438 ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SMS_SEND_MSG, ipc_sms_send_msg_complete);
440 ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, (void *) data, data_len, ril_request_get_id(t));
446 void ipc_sms_send_msg_complete(struct ipc_message_info *info)
448 struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
450 if(ipc_gen_phone_res_check(phone_res) < 0) {
451 LOGE("IPC_GEN_PHONE_RES indicates error, abort request to RILJ");
453 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
455 /* Release the lock so we can accept new requests */
456 ril_request_sms_lock_release();
457 /* Now send the next message in the queue if any */
458 ril_request_send_sms_next();
463 * In: IPC_SMS_SVC_CENTER_ADDR
464 * SMSC: Service Center Address, needed to send an SMS
466 * Out: IPC_SMS_SEND_MSG
468 void ipc_sms_svc_center_addr(struct ipc_message_info *info)
470 int id = ril_request_sms_get_id(info->aseq);
476 LOGE("The request wasn't queued, reporting generic error!");
478 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
480 /* Release the lock so we can accept new requests */
481 ril_request_sms_lock_release();
482 /* Now send the next message in the queue if any */
483 ril_request_send_sms_next();
488 LOGD("Completing the request");
490 pdu = ril_request_sms[id].pdu;
491 pdu_len = ril_request_sms[id].pdu_len;
493 /* We need to clear here to prevent infinite loop, but we can't free mem yet */
494 ril_request_sms_clear(id);
496 ril_request_send_sms_complete(ril_request_get_token(info->aseq), pdu, (char *) info->data);
498 /* Now it is safe to free mem */
504 * In: IPC_SMS_SEND_MSG
505 * This comes to ACK the latest sent SMS message
507 void ipc_sms_send_msg(struct ipc_message_info *info)
509 struct ipc_sms_send_msg_response *report_msg = (struct ipc_sms_send_msg_response *) info->data;
510 RIL_SMS_Response response;
512 RIL_Errno ril_ack_err;
514 LOGD("Got ACK for msg_tpid #%d\n", report_msg->msg_tpid);
516 response.messageRef = report_msg->msg_tpid;
517 response.ackPDU = NULL;
518 ril_ack_err = ipc2ril_sms_ack_error(report_msg->error, &(response.errorCode));
520 ril_request_complete(ril_request_get_token(info->aseq), ril_ack_err, &response, sizeof(response));
522 /* Release the lock so we can accept new requests */
523 ril_request_sms_lock_release();
524 /* Now send the next message in the queue if any */
525 ril_request_send_sms_next();
529 * Incoming SMS functions
532 int ipc_sms_incoming_msg_register(char *pdu, int length, unsigned char type, unsigned char tpid)
534 struct ipc_sms_incoming_msg_info *incoming_msg;
535 struct list_head *list_end;
536 struct list_head *list;
538 incoming_msg = calloc(1, sizeof(struct ipc_sms_incoming_msg_info));
539 if(incoming_msg == NULL)
542 incoming_msg->pdu = pdu;
543 incoming_msg->length = length;
544 incoming_msg->type = type;
545 incoming_msg->tpid = tpid;
547 list_end = ril_data.incoming_sms;
548 while(list_end != NULL && list_end->next != NULL)
549 list_end = list_end->next;
551 list = list_head_alloc((void *) incoming_msg, list_end, NULL);
553 if(ril_data.incoming_sms == NULL)
554 ril_data.incoming_sms = list;
559 void ipc_sms_incoming_msg_unregister(struct ipc_sms_incoming_msg_info *incoming_msg)
561 struct list_head *list;
563 if(incoming_msg == NULL)
566 list = ril_data.incoming_sms;
567 while(list != NULL) {
568 if(list->data == (void *) incoming_msg) {
569 memset(incoming_msg, 0, sizeof(struct ipc_sms_incoming_msg_info));
572 if(list == ril_data.incoming_sms)
573 ril_data.incoming_sms = list->next;
575 list_head_free(list);
584 struct ipc_sms_incoming_msg_info *ipc_sms_incoming_msg_info_find(void)
586 struct ipc_sms_incoming_msg_info *incoming_msg;
587 struct list_head *list;
589 list = ril_data.incoming_sms;
590 while(list != NULL) {
591 incoming_msg = (struct ipc_sms_incoming_msg_info *) list->data;
592 if(incoming_msg == NULL)
605 * In: IPC_SMS_INCOMING_MSG
606 * Message to notify an incoming message, with PDU
608 * Out: RIL_UNSOL_RESPONSE_NEW_SMS or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT
609 * Notify RILJ about the incoming message
612 void ipc_sms_incoming_msg_next(void)
614 struct ipc_sms_incoming_msg_info *incoming_msg;
616 ril_data.state.sms_incoming_msg_tpid = 0;
618 incoming_msg = ipc_sms_incoming_msg_info_find();
619 if(incoming_msg == NULL)
622 ipc_sms_incoming_msg_complete(incoming_msg->pdu, incoming_msg->length, incoming_msg->type, incoming_msg->tpid);
623 ipc_sms_incoming_msg_unregister(incoming_msg);
626 void ipc_sms_incoming_msg_complete(char *pdu, int length, unsigned char type, unsigned char tpid)
628 if(pdu == NULL || length <= 0)
631 ril_data.state.sms_incoming_msg_tpid = tpid;
633 if(type == IPC_SMS_TYPE_POINT_TO_POINT) {
634 ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS, pdu, length);
635 } else if(type == IPC_SMS_TYPE_STATUS_REPORT) {
636 ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, pdu, length);
638 LOGE("Unhandled message type: %x", type);
644 void ipc_sms_incoming_msg(struct ipc_message_info *info)
646 struct ipc_sms_incoming_msg *msg;
647 unsigned char *pdu_hex;
652 if(info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_incoming_msg))
655 msg = (struct ipc_sms_incoming_msg *) info->data;
656 pdu_hex = ((unsigned char *) info->data + sizeof(struct ipc_sms_incoming_msg));
658 length = msg->length * 2 + 1;
659 pdu = (char *) calloc(1, length);
661 bin2hex(pdu_hex, msg->length, pdu);
663 if(ril_data.state.sms_incoming_msg_tpid != 0) {
664 LOGD("Another message is waiting ACK, queuing");
665 rc = ipc_sms_incoming_msg_register(pdu, length, msg->type, msg->msg_tpid);
667 LOGE("Unable to register incoming msg");
672 ipc_sms_incoming_msg_complete(pdu, length, msg->type, msg->msg_tpid);
676 * In: RIL_REQUEST_SMS_ACKNOWLEDGE
677 * Acknowledge successful or failed receipt of SMS previously indicated
678 * via RIL_UNSOL_RESPONSE_NEW_SMS
680 * Out: IPC_SMS_DELIVER_REPORT
681 * Sends a SMS delivery report
683 void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t length)
685 struct ipc_sms_deliver_report_request report_msg;
686 int success, fail_cause;
688 if(data == NULL || length < 2 * sizeof(int))
691 success = ((int *) data)[0];
692 fail_cause = ((int *) data)[1];
694 if(ril_data.state.sms_incoming_msg_tpid == 0) {
695 LOGE("There is no SMS message to ACK!");
696 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
697 ipc_sms_incoming_msg_next();
701 report_msg.type = IPC_SMS_TYPE_STATUS_REPORT;
702 report_msg.error = ril2ipc_sms_ack_error(success, fail_cause);
703 report_msg.msg_tpid = ril_data.state.sms_incoming_msg_tpid;
706 ipc_gen_phone_res_expect_to_abort(ril_request_get_id(t), IPC_SMS_DELIVER_REPORT);
708 ipc_fmt_send(IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(report_msg), ril_request_get_id(t));
710 ipc_sms_incoming_msg_next();
714 * In: IPC_SMS_DELIVER_REPORT
715 * Attest that the modem successfully sent our SMS recv ACK
717 void ipc_sms_deliver_report(struct ipc_message_info *info)
719 struct ipc_sms_deliver_report_response *report_msg;
723 if(info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_deliver_report_response))
726 report_msg = (struct ipc_sms_deliver_report_response *) info->data;
727 e = ipc2ril_sms_ack_error(report_msg->error, &error_code);
729 ril_request_complete(ril_request_get_token(info->aseq), e, NULL, 0);
733 * Apparently non-SMS-messages-related function
736 void ipc_sms_device_ready(struct ipc_message_info *info)
739 if(ril_data.state.radio_state == RADIO_STATE_ON) {
741 if(ril_data.state.radio_state == RADIO_STATE_SIM_READY) {
743 ipc_fmt_send(IPC_SMS_DEVICE_READY, IPC_TYPE_SET, NULL, 0, info->aseq);