4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
28 #include <core_object.h>
38 #include "imc_common.h"
43 #define AT_MT_UNREAD 0 /* Received and Unread */
44 #define AT_MT_READ 1 /* Received and Read */
45 #define AT_MO_UNSENT 2 /* Unsent */
46 #define AT_MO_SENT 3 /* Sent */
47 #define AT_ALL 4 /* Unknown */
49 #define IMC_NUM_PLAN_ID(sca) (gchar)(sca & 0x0F)
50 #define IMC_TYPE_OF_NUM(sca) (gchar)((sca & 0x70) >> 4)
52 /* SCA 12 bytes long and TDPU is 164 bytes long */
53 #define PDU_LEN_MAX 176
54 #define HEX_PDU_LEN_MAX ((PDU_LEN_MAX * 2) + 1)
56 #define IMC_SIM_TON_INTERNATIONAL 1
57 #define IMC_SIM_TON_NATIONAL 2
59 #define IMC_AT_EF_SMS_RECORD_LEN 176
62 guint total_param_count;
65 TelSmsParamsInfo *params;
69 * Notification - SMS-DELIVER
70 * +CMT = [<alpha>],<length><CR><LF><pdu> (PDU mode enabled)
74 * <length> length of the PDU
75 * <pdu> Incomming SMS PDU
77 * Notification - SMS-STATUS-REPORT
78 * +CDS: <length><CR><LF><pdu> (PDU mode enabled)
81 * <length> length of the PDU
82 * <pdu> Incomming SMS PDU
85 static gboolean on_notification_imc_sms_incoming_msg(CoreObject *co,
86 const void *event_info, void *user_data)
88 GSList *tokens = NULL;
91 int pdu_len = 0, no_of_tokens = 0;
93 TelSmsDatapackageInfo incoming_msg = {{0}, };
99 lines = (GSList *)event_info;
100 if (2 != g_slist_length(lines)) {
101 err("Invalid number of lines for +CMT. Must be 2");
105 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
107 err("Line 1 is invalid");
110 dbg("Line 1: [%s]", line);
112 /* Split Line 1 into tokens */
113 tokens = tcore_at_tok_new(line);
114 no_of_tokens = g_slist_length(tokens);
118 * Number of tokens: 2
120 * Incoming SMS-STATUS-REPORT: +CDS
121 * Number of tokens: 1
123 if (2 == no_of_tokens) {
124 /* Token 0: Alpha ID */
125 dbg("Alpha ID: [0x%x]", g_slist_nth_data(tokens, 0));
127 /* Token 1: PDU Length */
128 pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
129 dbg("pdu_len: [%d]", pdu_len);
130 } else if (1 == no_of_tokens) {
131 /* Token 0: PDU Length */
132 pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
133 dbg("pdu_len: [%d]", pdu_len);
135 tcore_at_tok_free(tokens);
138 line = (char *)g_slist_nth_data(lines, 1);
140 err("Line 2 is invalid");
143 dbg("Line 2: [%s]", line);
145 /* Convert to Bytes */
146 tcore_util_hexstring_to_bytes(line, &byte_pdu, &byte_pdu_len);
148 sca_length = byte_pdu[0];
149 dbg("SCA length = %d", sca_length);
152 guint encoded_sca_len;
154 * byte_pdu[1] - sca_address_type
155 * Excluding sca_address_type and copy SCA
157 encoded_sca_len = sca_length - 1;
159 tcore_util_convert_bcd_to_ascii(&byte_pdu[2], encoded_sca_len, encoded_sca_len*2);
160 dbg("Decoded SCA: [%s]", decoded_sca);
161 g_strlcpy(incoming_msg.sca.number, decoded_sca, strlen(decoded_sca)+1);
162 tcore_free(decoded_sca);
164 /*SCA Conversion for Address type*/
165 incoming_msg.sca.ton = IMC_TYPE_OF_NUM(byte_pdu[1]);
166 incoming_msg.sca.npi = IMC_NUM_PLAN_ID(byte_pdu[1]);
167 dbg("TON: [%d] NPI: [%d] SCA: [%s]",
168 incoming_msg.sca.ton, incoming_msg.sca.npi,
169 incoming_msg.sca.number);
172 dbg("NO SCA Present");
176 incoming_msg.tpdu_length = pdu_len;
177 memcpy(incoming_msg.tpdu,
178 &byte_pdu[sca_length+1], incoming_msg.tpdu_length);
180 tcore_util_hex_dump(" ",incoming_msg.tpdu_length, &byte_pdu[sca_length+1]);
182 /* Send notification */
183 tcore_object_send_notification(co,
184 TCORE_NOTIFICATION_SMS_INCOM_MSG,
185 sizeof(TelSmsDatapackageInfo), &incoming_msg);
193 * +CBM: <length><CR><LF><pdu> (PDU mode enabled);
196 * <length> length of the PDU
197 * <pdu> Incomming SMS CB PDU
200 static gboolean on_notification_imc_sms_cb_incom_msg(CoreObject *co,
201 const void *event_info, void *user_data)
203 char * line = NULL, *pdu = NULL, *line_token = NULL;
204 GSList *tokens = NULL;
205 unsigned char *byte_pdu = NULL;
206 guint byte_pdu_len = 0;
207 GSList *lines = NULL;
209 TelSmsCbMsgInfo cb_noti = { 0, };
212 lines = (GSList *)event_info;
214 line = (char *)(lines->data);/*Fetch Line 1*/
216 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
217 line_token = g_slist_nth_data(tokens, 0);
219 cb_noti.length = atoi(line_token);
221 dbg("token 0 is NULL");
222 tcore_at_tok_free(tokens);
225 pdu = g_slist_nth_data(lines, 1);
227 cb_noti.cb_type = TEL_SMS_CB_MSG_GSM;
229 dbg("CB Msg LENGTH [%d]", cb_noti.length);
231 if ((cb_noti.length > 0) && (TEL_SMS_CB_DATA_SIZE_MAX >= cb_noti.length)) {
232 tcore_util_hexstring_to_bytes(pdu, (gchar **)&byte_pdu, &byte_pdu_len);
234 memcpy(cb_noti.cb_data, (char*)byte_pdu, cb_noti.length);
236 err("Invalid Message Length");
237 tcore_at_tok_free(tokens);
241 err("NULL PDU Recieved ");
242 tcore_at_tok_free(tokens);
245 tcore_object_send_notification(co,
246 TCORE_NOTIFICATION_SMS_CB_INCOM_MSG, sizeof(TelSmsCbMsgInfo), &cb_noti);
252 tcore_at_tok_free(tokens);
258 * TODO - AT Command Description Not available
261 static gboolean on_notification_imc_sms_memory_status(CoreObject *co,
262 const void *event_info, void *user_data)
264 gboolean memory_status = TRUE;
266 GSList *tokens = NULL;
267 GSList *lines = NULL;
268 char *line = NULL , *line_token = NULL;
271 lines = (GSList *)event_info;
272 if (1 != g_slist_length(lines)) {
273 dbg("Unsolicited msg but multiple line");
277 line = (char*)(lines->data);
279 tokens = tcore_at_tok_new(line);
280 line_token = g_slist_nth_data(tokens, 0);
282 /* SIM Full condition */
283 if (0 == atoi(line_token))
284 memory_status = FALSE;
286 /* Send notification */
287 tcore_object_send_notification(co,
288 TCORE_NOTIFICATION_SMS_MEMORY_STATUS,
289 sizeof(gboolean), &memory_status);
291 tcore_at_tok_free(tokens);
299 static void on_response_imc_class2_sms_incom_msg(TcorePending *p,
300 guint data_len, const void *data, void *user_data)
302 const TcoreAtResponse *at_resp = data;
303 CoreObject *co = tcore_pending_ref_core_object(p);
305 TelSmsDatapackageInfo incoming_msg = { { 0 }, };
308 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
310 guint byte_pdu_len = 0;
313 if (at_resp && at_resp->success) {
315 if (at_resp->lines) {
320 * Fetching First Line
322 gslist_line = (char *)at_resp->lines->data;
323 dbg("gslist_line: [%s]", gslist_line);
326 tokens = tcore_at_tok_new(gslist_line);
327 dbg("Number of tokens: [%d]", g_slist_length(tokens));
329 /* First Token : status
330 * Second Token: Alpha ID - not needed
332 line_token = g_slist_nth_data(tokens, 2); /* Third Token: PDU Length */
333 if (line_token != NULL) {
334 incoming_msg.tpdu_length = atoi(line_token);
335 dbg("Length: [%d]", incoming_msg.tpdu_length);
338 err("Line Token for PDU Length is NULL");
342 /* Fetching line: Second line is PDU */
343 hex_pdu = (char *) at_resp->lines->next->data;
344 dbg("EF-SMS PDU: [%s]", hex_pdu);
346 tcore_at_tok_free(tokens); /* free the consumed token */
347 if (NULL != hex_pdu) {
348 tcore_util_hexstring_to_bytes(hex_pdu, &byte_pdu, &byte_pdu_len);
350 sca_length = (int)byte_pdu[0];
352 dbg("SCA Length [%d], msgLength: [%d]", sca_length, incoming_msg.tpdu_length);
354 if (ZERO == sca_length) {
355 memcpy(incoming_msg.tpdu, &byte_pdu[1], incoming_msg.tpdu_length);
361 * byte_pdu[1] - sca_address_type
362 * Excluding sca_address_type and copy SCA
364 memcpy(incoming_msg.sca.number, &byte_pdu[2], (sca_length-1));
367 * SCA Conversion: Address Type
368 * 3GPP TS 23.040 V6.5.0 Section: 9.1.2.5
370 sca_toa = byte_pdu[1];
371 incoming_msg.sca.npi = IMC_NUM_PLAN_ID(sca_toa);
372 incoming_msg.sca.ton = IMC_TYPE_OF_NUM(sca_toa);
374 memcpy(incoming_msg.tpdu,
375 &byte_pdu[sca_length+1],
376 incoming_msg.tpdu_length);
380 tcore_object_send_notification(co,
381 TCORE_NOTIFICATION_SMS_INCOM_MSG,
382 sizeof(TelSmsDatapackageInfo), &incoming_msg);
383 tcore_at_tok_free(tokens);
387 err("Invalid Response Received");
397 * +CMTI: <mem>,<index>
400 * <mem> memory location
401 * <index> index where msg is stored
403 static gboolean on_notification_imc_sms_class2_incoming_msg(CoreObject *co, const void *event_info, void *user_data)
408 GSList *tokens = NULL , *lines = NULL;
410 gint index, mem_type = 0;
413 lines = (GSList *)event_info;
414 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
416 err("Line 1 is invalid");
419 dbg("Line 1: [%s]", line);
421 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
422 mem_type = atoi(g_slist_nth_data(tokens, 0));/* Type of Memory stored */
423 dbg("mem_type=[%d]", mem_type);
424 index = atoi((char *) g_slist_nth_data(tokens, 1));
425 dbg("index: [%d]", index);
428 * Operation - read_sms_in_sim
431 * AT-Command: At+CMGR=<index>
433 * <index> index of the message to be read.
436 * Success: (PDU: Multi-line output)
437 * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
440 * +CMS ERROR: <error>
443 at_cmd = g_strdup_printf("AT+CMGR=%d", index);
445 /* Send Request to modem */
446 ret = tcore_at_prepare_and_send_request(co,
448 TCORE_AT_COMMAND_TYPE_PDU,
449 TCORE_PENDING_PRIORITY_DEFAULT,
451 on_response_imc_class2_sms_incom_msg, NULL,
452 on_send_imc_request, NULL,
454 if (ret != TEL_RETURN_SUCCESS) {
455 err("Failed to Read Class2 Incomming Message");
461 static void on_response_imc_sms_send_more_msg(TcorePending *p,
462 guint data_len, const void *data, void *user_data)
464 const TcoreAtResponse *at_resp = data;
468 if (at_resp && at_resp->success)
469 dbg("Response OK for AT+CMMS: More msgs to send!!");
471 err("Response NOK for AT+CMMS: More msgs to send");
473 /* Need not send any response */
476 static void on_response_imc_sms_send_sms(TcorePending *p,
477 guint data_len, const void *data, void *user_data)
479 const TcoreAtResponse *at_resp = data;
480 CoreObject *co = tcore_pending_ref_core_object(p);
481 ImcRespCbData *resp_cb_data = user_data;
483 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CMS error mapping required */
486 tcore_check_return_assert(co != NULL);
487 tcore_check_return_assert(resp_cb_data != NULL);
489 if (at_resp && at_resp->success) {
491 if (at_resp->lines) {
494 GSList *tokens = NULL;
497 line = (const gchar *)at_resp->lines->data;
498 tokens = tcore_at_tok_new(line);
499 line_token = g_slist_nth_data(tokens, 0);
500 if (line_token != NULL) {
501 /*Response from MODEM for send SMS: +CMGS: <mr>[,<ackpdu>]*/
502 /*Message Reference is not used by MSG_SERVER and application.So Filling only result*/
503 msg_ref = atoi(line_token);
505 dbg("Message Reference: [%d]", msg_ref);
507 result = TEL_SMS_RESULT_SUCCESS;
510 dbg("No Message Reference received");
512 tcore_at_tok_free(tokens);
519 /* Invoke callback */
520 if (resp_cb_data->cb)
521 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
523 /* Free callback data */
524 imc_destroy_resp_cb_data(resp_cb_data);
527 static void on_response_imc_sms_write_sms_in_sim(TcorePending *p,
528 guint data_len, const void *data, void *user_data)
530 const TcoreAtResponse *at_resp = data;
531 CoreObject *co = tcore_pending_ref_core_object(p);
532 ImcRespCbData *resp_cb_data = user_data;
534 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
536 GSList *tokens = NULL;
537 char *line = NULL, *line_token = NULL;
542 if (at_resp && at_resp->success) {
544 if (at_resp->lines) {
545 line = (char *)at_resp->lines->data;
546 tokens = tcore_at_tok_new(line);
547 line_token = g_slist_nth_data(tokens, 0);
549 index = (atoi(line_token));
550 dbg("SMS written to '%d' index", index);
551 result = TEL_SMS_RESULT_SUCCESS;
555 result = TEL_SMS_RESULT_FAILURE;
559 err("Lines NOT present");
566 /* Invoke callback */
567 if (resp_cb_data->cb)
568 resp_cb_data->cb(co, (gint)result, &index, resp_cb_data->cb_data);
570 /* Free callback data */
571 imc_destroy_resp_cb_data(resp_cb_data);
574 static void on_response_imc_sms_read_sms_in_sim(TcorePending *p,
575 guint data_len, const void *data, void *user_data)
577 const TcoreAtResponse *at_resp = data;
578 CoreObject *co = tcore_pending_ref_core_object(p);
579 ImcRespCbData *resp_cb_data = user_data;
580 TelSmsSimDataInfo read_resp;
581 GSList *tokens = NULL;
583 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/* CMS error mapping required */
586 memset(&read_resp, 0x0, sizeof(TelSmsSimDataInfo));
588 if (at_resp && at_resp->success) {
590 if (at_resp->lines) {
591 char *gslist_line = NULL,*line_token = NULL,*byte_pdu = NULL,*hex_pdu = NULL;
592 gint msg_status = 0, pdu_len = 0, alpha_id = 0;
598 * Fetching First Line
600 gslist_line = (char *)at_resp->lines->data;
601 dbg("gslist_line: [%s]", gslist_line);
604 tokens = tcore_at_tok_new(gslist_line);
605 dbg("Number of tokens: [%d]", g_slist_length(tokens));
607 /*+CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>*/
608 line_token = g_slist_nth_data(tokens, 0); /*First Token: Message status*/
609 if (line_token == NULL) {
614 msg_status = atoi(line_token);
615 dbg("msg_status is %d",msg_status);
617 switch (msg_status) {
619 read_resp.status = TEL_SMS_STATUS_MT_UNREAD;
622 read_resp.status = TEL_SMS_STATUS_MT_READ;
625 read_resp.status = TEL_SMS_STATUS_MO_NOT_SENT;
628 read_resp.status = TEL_SMS_STATUS_MO_SENT;
632 read_resp.status = TEL_SMS_STATUS_REPLACED;
636 /*Second Token: Alpha ID*/
637 line_token = g_slist_nth_data(tokens, 1);
638 if (line_token != NULL) {
639 alpha_id = atoi(line_token);
640 dbg("alpha_id: [%d]", alpha_id);
643 /*Third Token: Length*/
644 line_token = g_slist_nth_data(tokens, 2);
645 if (line_token == NULL) {
646 err("Invalid PDU length");
649 pdu_len = atoi(line_token);
650 dbg("PDU length: [%d]", pdu_len);
652 /*Fetching line: Second line is PDU*/
653 hex_pdu = (char *) at_resp->lines->next->data;
654 dbg("EF-SMS PDU: [%s]", hex_pdu);
656 if (NULL != hex_pdu) {
658 guint byte_pdu_len = 0;
660 tcore_util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
662 tcore_util_hexstring_to_bytes(hex_pdu, &byte_pdu, &byte_pdu_len);
664 sca_length = byte_pdu[0];
665 dbg("SCA length = %d", sca_length);
668 guint encoded_sca_len;
671 * byte_pdu[1] - sca_address_type
672 * Excluding sca_address_type and copy SCA
674 encoded_sca_len = sca_length - 1;
676 tcore_util_convert_bcd_to_ascii(&byte_pdu[2],
677 encoded_sca_len, encoded_sca_len*2);
679 dbg("Decoded SCA: [%s]", decoded_sca);
680 memcpy(read_resp.data.sca.number, decoded_sca, TEL_SMS_SCA_LEN_MAX);
681 tcore_free(decoded_sca);
683 /*SCA Conversion for Address type*/
684 read_resp.data.sca.ton = IMC_TYPE_OF_NUM(byte_pdu[1]);
685 read_resp.data.sca.npi = IMC_NUM_PLAN_ID(byte_pdu[1]);
686 dbg("TON: [%d] NPI: [%d] SCA: [%s]",
687 read_resp.data.sca.ton, read_resp.data.sca.npi,
688 read_resp.data.sca.number);
690 err("NO SCA Present");
694 read_resp.data.tpdu_length = pdu_len;
695 if ((read_resp.data.tpdu_length > 0)
696 && (read_resp.data.tpdu_length <= TEL_SMS_SMDATA_SIZE_MAX)) {
697 memcpy(read_resp.data.tpdu, &byte_pdu[sca_length+1],
698 read_resp.data.tpdu_length);
700 warn("Invalid TPDU length: [%d]", read_resp.data.tpdu_length);
703 result = TEL_SMS_RESULT_SUCCESS;
707 err("Invalid Response Received");
714 /* Invoke callback */
715 if (resp_cb_data->cb)
716 resp_cb_data->cb(co, (gint)result, &read_resp, resp_cb_data->cb_data);
718 /* Free callback data */
719 imc_destroy_resp_cb_data(resp_cb_data);
721 /*free the consumed token*/
722 tcore_at_tok_free(tokens);
725 static void on_response_imc_sms_delete_sms_in_sim(TcorePending *p,
726 guint data_len, const void *data, void *user_data)
728 const TcoreAtResponse *at_resp = data;
729 CoreObject *co = tcore_pending_ref_core_object(p);
730 ImcRespCbData *resp_cb_data = user_data;
732 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
735 tcore_check_return_assert(co != NULL);
737 if (at_resp && at_resp->success) {
739 result = TEL_SMS_RESULT_SUCCESS;
745 /* Invoke callback */
746 if (resp_cb_data->cb)
747 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
749 /* Free callback data */
750 imc_destroy_resp_cb_data(resp_cb_data);
753 static void on_response_imc_sms_get_msg_indices(TcorePending *p,
754 guint data_len, const void *data, void *user_data)
756 TelSmsStoredMsgCountInfo *count_info;/*Response from get_count Request*/
757 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CMS error mapping required */
759 const TcoreAtResponse *at_resp = data;
760 CoreObject *co = tcore_pending_ref_core_object(p);
761 ImcRespCbData *resp_cb_data = user_data;
764 count_info = (TelSmsStoredMsgCountInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
766 if (at_resp && at_resp->success) {
768 if (at_resp->lines) {
769 char *gslist_line = NULL;
770 gint gslist_line_count = 0, ctr_loop = 0;
772 gslist_line_count = g_slist_length(at_resp->lines);
774 if (gslist_line_count > TEL_SMS_GSM_MSG_NUM_MAX)
775 gslist_line_count = TEL_SMS_GSM_MSG_NUM_MAX;
776 dbg("Number of lines: [%d]", gslist_line_count);
778 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
779 /* Fetch Line 'ctr_loop' */
780 gslist_line = (char *)g_slist_nth_data(at_resp->lines, ctr_loop);
781 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
783 if (NULL != gslist_line) {
784 GSList *tokens = NULL;
785 char *line_token = NULL;
787 tokens = tcore_at_tok_new(gslist_line);
789 line_token = g_slist_nth_data(tokens, 0);
790 if (NULL != line_token) {
791 count_info->index_list[ctr_loop] = atoi(line_token);
794 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
797 tcore_at_tok_free(tokens);
800 err("gslist_line is NULL");
805 result = TEL_SMS_RESULT_SUCCESS;
808 err("Invalid Response received. No Lines present in Response");
810 /* Check if used count is zero*/
811 if (count_info->used_count == 0)
812 result = TEL_SMS_RESULT_SUCCESS;
820 /* Invoke callback */
821 if (resp_cb_data->cb)
822 resp_cb_data->cb(co, (gint)result, count_info, resp_cb_data->cb_data);
824 /* Free callback data */
825 imc_destroy_resp_cb_data(resp_cb_data);
828 static void on_response_imc_sms_get_sms_count(TcorePending *p,
829 guint data_len, const void *data, void *user_data)
834 TelSmsStoredMsgCountInfo count_info = {0, };
835 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
836 int used_count = 0, total_count = 0;
838 const TcoreAtResponse *at_resp = data;
839 CoreObject *co = tcore_pending_ref_core_object(p);
840 ImcRespCbData *resp_cb_data = user_data;
841 ImcRespCbData *getcnt_resp_cb_data;
844 if (at_resp && at_resp->success) {
846 if (at_resp->lines) {
847 GSList *tokens = NULL;
848 char *line = NULL, *line_token = NULL;
850 line = (char *)at_resp->lines->data;
851 dbg("line: [%s]",line);
856 * +CPMS: <used1>, <total1>, <used2>, <total2>, <used3>, <total3>
858 tokens = tcore_at_tok_new(line);
861 line_token = g_slist_nth_data(tokens, 0);
863 used_count =atoi(line_token);
864 dbg("used cnt is %d",used_count);
867 err("Line Token for used count is NULL");
868 tcore_at_tok_free(tokens);
873 line_token = g_slist_nth_data(tokens, 1);
875 total_count = atoi(line_token);
877 count_info.total_count = total_count;
878 count_info.used_count = used_count;
879 dbg("Count - used: [%d] total: [%d]", used_count, total_count);
882 * Operation - get_msg_indices_in_sim
885 * AT-Command: AT+CMGL
886 * +CPMS=<mem1>[, <mem2>[,<mem3>]]
888 * <mem1> memory storage to read.
891 * Success: (Multi-line output)
894 * <stat> status of the message.
896 * +CMS ERROR: <error>
899 /* Sending the Second AT Request to fetch msg indices */
900 at_cmd = g_strdup_printf("AT+CMGL=4");
902 /* Response callback data */
903 getcnt_resp_cb_data = imc_create_resp_cb_data(resp_cb_data->cb,
904 resp_cb_data->cb_data,
905 &count_info, sizeof(TelSmsStoredMsgCountInfo));
907 /* Free previous request callback data */
908 imc_destroy_resp_cb_data(resp_cb_data);
910 /* Send Request to modem */
911 ret = tcore_at_prepare_and_send_request(co,
913 TCORE_AT_COMMAND_TYPE_MULTILINE,
914 TCORE_PENDING_PRIORITY_DEFAULT,
916 on_response_imc_sms_get_msg_indices, getcnt_resp_cb_data,
917 on_send_imc_request, NULL,
920 /* free the consumed token */
921 tcore_at_tok_free(tokens);
924 IMC_CHECK_REQUEST_RET(ret, getcnt_resp_cb_data, "Get Indices in SIM");
925 if (ret != TEL_RETURN_SUCCESS) {
926 err("Failed to Process Get Msg Indices Request");
934 err("Line Token for Total count is NULL");
936 /* free the consumed token */
937 tcore_at_tok_free(tokens);
942 err("Invalid Response Received: NO Lines Present");
950 /* Invoke callback in case of error*/
951 if (resp_cb_data->cb)
952 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
954 /* Free callback data */
955 imc_destroy_resp_cb_data(resp_cb_data);
958 static void on_response_imc_sms_set_sca(TcorePending *p,
959 guint data_len, const void *data, void *user_data)
961 const TcoreAtResponse *at_resp = data;
962 CoreObject *co = tcore_pending_ref_core_object(p);
963 ImcRespCbData *resp_cb_data = user_data;
965 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
968 if (at_resp && at_resp->success) {
970 result = TEL_SMS_RESULT_SUCCESS;
976 /* Invoke callback */
977 if (resp_cb_data->cb)
978 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
980 /* Free callback data */
981 imc_destroy_resp_cb_data(resp_cb_data);
984 static void on_response_imc_sms_get_sca(TcorePending *p,
985 guint data_len, const void *data, void *user_data)
987 const TcoreAtResponse *at_resp = data;
988 CoreObject *co = tcore_pending_ref_core_object(p);
989 ImcRespCbData *resp_cb_data = user_data;
991 TelSmsSca sca_resp = { 0, };
992 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
995 if (at_resp && at_resp->success) {
997 if (at_resp->lines) {
998 GSList *tokens = NULL;
999 const char *sca_tok_addr;
1000 gchar *line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1002 line = (char *)at_resp->lines->data;
1003 tokens = tcore_at_tok_new(line);
1004 sca_tok_addr = g_slist_nth_data(tokens, 0);
1005 sca_toa = g_slist_nth_data(tokens, 1);
1007 sca_addr = tcore_at_tok_extract(sca_tok_addr);
1008 dbg("SCA: [%s] SCA-TOA: [%s]", sca_addr, sca_toa);
1009 if ((NULL != sca_addr) && (NULL != sca_toa)) {
1010 memcpy(sca_resp.number, sca_addr, strlen(sca_addr));
1012 /* Type-of-Address */
1013 if (145 == atoi(sca_toa)) {
1014 sca_resp.ton = IMC_SIM_TON_INTERNATIONAL;
1017 sca_resp.ton = IMC_SIM_TON_NATIONAL;
1019 sca_resp.npi = 0;/* TODO */
1020 result = TEL_SMS_RESULT_SUCCESS;
1025 tcore_at_tok_free(tokens);
1029 err("Invalid Response.No Lines Received");
1033 err("Response NOK");
1036 /* Invoke callback */
1037 if (resp_cb_data->cb)
1038 resp_cb_data->cb(co, (gint)result, &sca_resp, resp_cb_data->cb_data);
1040 /* Free callback data */
1041 imc_destroy_resp_cb_data(resp_cb_data);
1044 static void on_response_imc_sms_set_cb_config(TcorePending *p,
1045 guint data_len, const void *data, void *user_data)
1047 const TcoreAtResponse *at_resp = data;
1048 CoreObject *co = tcore_pending_ref_core_object(p);
1049 ImcRespCbData *resp_cb_data = user_data;
1051 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CME error mapping required */
1054 if (at_resp && at_resp->success) {
1056 result = TEL_SMS_RESULT_SUCCESS;
1059 err("Response NOK");
1062 /* Invoke callback */
1063 if (resp_cb_data->cb)
1064 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1066 /* Free callback data */
1067 imc_destroy_resp_cb_data(resp_cb_data);
1070 static void on_response_imc_sms_get_cb_config(TcorePending *p,
1071 guint data_len, const void *data, void *user_data)
1073 const TcoreAtResponse *at_resp = data;
1074 CoreObject *co = tcore_pending_ref_core_object(p);
1075 ImcRespCbData *resp_cb_data = user_data;
1077 GSList *cb_tokens = NULL;
1078 char *cb_str_token = NULL;
1079 int num_cb_tokens = 0;
1080 char *mid_tok = NULL;
1081 char *first_tok = NULL, *second_tok = NULL;
1082 gint i = 0, mode = 0;
1085 TelSmsCbConfigInfo get_cb_conf = {0, };
1086 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1089 if (at_resp && at_resp->success) {
1091 if (at_resp->lines) {
1092 GSList *tokens = NULL;
1093 char *line_token = NULL, *line = NULL;
1094 line = (char*)at_resp->lines->data;
1096 tokens = tcore_at_tok_new(line);
1099 * +CSCB: <mode>,<mids>,<dcss>
1101 line_token = g_slist_nth_data(tokens, 0);
1103 mode = atoi(line_token);
1104 dbg("mode:[%d]", mode);
1105 get_cb_conf.cb_enabled = mode;
1108 err("Line Token for Mode is NULL");
1109 tcore_at_tok_free(tokens);
1112 line_token = g_slist_nth_data(tokens, 1);
1114 cb_str_token = tcore_at_tok_extract(line_token);
1115 cb_tokens = tcore_at_tok_new((const char *)cb_str_token);
1117 num_cb_tokens = g_slist_length(cb_tokens);
1118 dbg("num_cb_tokens = %d", num_cb_tokens);
1119 if (num_cb_tokens == 0) {
1120 if (mode == 1) { /* All CBS Enabled */
1121 get_cb_conf.msg_id_range_cnt = 1;
1122 get_cb_conf.msg_ids[0].from_msg_id = 0x0000;
1123 get_cb_conf.msg_ids[0].to_msg_id = TEL_SMS_GSM_CBMI_LIST_SIZE_MAX + 1;
1124 get_cb_conf.msg_ids[0].selected = TRUE;
1126 else { /* All CBS Disabled */
1127 get_cb_conf.msg_id_range_cnt = 0;
1128 get_cb_conf.msg_ids[0].selected = FALSE;
1132 for(i = 0; i < num_cb_tokens; i++) {
1133 get_cb_conf.msg_ids[i].selected = TRUE;
1134 dbg("msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
1135 get_cb_conf.msg_id_range_cnt++;
1136 dbg("Incremented msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
1138 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1139 first_tok = strtok(mid_tok, delim);
1140 second_tok = strtok(NULL, delim);
1142 if ((first_tok != NULL) && (second_tok != NULL)) {/* mids in range (320-478) */
1143 get_cb_conf.msg_ids[i].from_msg_id = atoi(first_tok);
1144 get_cb_conf.msg_ids[i].to_msg_id = atoi(second_tok);
1146 else {/* single mid value (0,1,5, 922)*/
1147 get_cb_conf.msg_ids[i].from_msg_id = atoi(mid_tok);
1148 get_cb_conf.msg_ids[i].to_msg_id = atoi(mid_tok);
1153 err("Line Token for MID is NULL");
1154 tcore_at_tok_free(tokens);
1159 err("Line is NULL");
1161 result = TEL_SMS_RESULT_SUCCESS;
1162 tcore_at_tok_free(tokens);
1163 tcore_at_tok_free(cb_tokens);
1164 g_free(cb_str_token);
1167 err("Invalid Response.No Lines Received");
1171 err("Response NOK");
1175 /* Invoke callback */
1176 if (resp_cb_data->cb)
1177 resp_cb_data->cb(co, (gint)result, &get_cb_conf, resp_cb_data->cb_data);
1179 /* Free callback data */
1180 imc_destroy_resp_cb_data(resp_cb_data);
1183 static void on_response_imc_sms_set_memory_status(TcorePending *p,
1184 guint data_len, const void *data, void *user_data)
1186 const TcoreAtResponse *at_resp = data;
1187 CoreObject *co = tcore_pending_ref_core_object(p);
1188 ImcRespCbData *resp_cb_data = user_data;
1190 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1193 if (at_resp && at_resp->success) {
1195 result = TEL_SMS_RESULT_SUCCESS;
1198 err("Response NOK");
1201 /* Invoke callback */
1202 if (resp_cb_data->cb)
1203 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1205 /* Free callback data */
1206 imc_destroy_resp_cb_data(resp_cb_data);
1209 static void on_response_imc_sms_set_message_status(TcorePending *p,
1210 guint data_len, const void *data, void *user_data)
1212 const TcoreAtResponse *at_resp = data;
1213 CoreObject *co = tcore_pending_ref_core_object(p);
1214 ImcRespCbData *resp_cb_data = user_data;
1216 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1217 int response = 0, sw1 = 0, sw2 = 0;
1218 const char *line = NULL;
1219 char *line_token = NULL;
1220 GSList *tokens = NULL;
1223 if (at_resp && at_resp->success) {
1225 if (at_resp->lines) {
1226 line = (const char *) at_resp->lines->data;
1227 tokens = tcore_at_tok_new(line);
1228 line_token = g_slist_nth_data(tokens, 0);
1229 if (line_token != NULL) {
1230 sw1 = atoi(line_token);
1235 line_token = g_slist_nth_data(tokens, 1);
1236 if (line_token != NULL) {
1237 sw2 = atoi(line_token);
1238 if ((sw1 == 0x90) && (sw2 == 0)) {
1239 result = TEL_SMS_RESULT_SUCCESS;
1245 line_token = g_slist_nth_data(tokens, 3);
1247 if (line_token != NULL) {
1248 response = atoi(line_token);
1249 dbg("response is %s", response);
1251 tcore_at_tok_free(tokens);
1258 err("RESPONSE NOK");
1261 /* Invoke callback */
1262 if (resp_cb_data->cb)
1263 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1265 /* Free callback data */
1266 imc_destroy_resp_cb_data(resp_cb_data);
1269 static void _response_get_efsms_data(TcorePending *p,
1270 guint data_len, const void *data, void *user_data)
1273 const TcoreAtResponse *at_resp = data;
1274 CoreObject *co = tcore_pending_ref_core_object(p);
1275 ImcRespCbData *resp_cb_data = user_data;
1277 TelSmsStatusInfo *status_info;
1278 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1281 char *encoded_data = NULL;
1282 int encoded_len = 0;
1283 char msg_status = 0;
1284 char *line_token = NULL;
1285 GSList *tokens=NULL;
1286 const char *line = NULL;
1291 status_info = (TelSmsStatusInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1292 if (at_resp && at_resp->success) {
1294 if (at_resp->lines) {
1295 dbg("Entry:lines Ok");
1296 line = (const char *) at_resp->lines->data;
1297 tokens = tcore_at_tok_new(line);
1299 sw1 = atoi(g_slist_nth_data(tokens, 0));
1300 sw2 = atoi(g_slist_nth_data(tokens, 1));
1301 line_token = g_slist_nth_data(tokens, 2);
1303 dbg("line_token:[%s], Length of line token:[%d]", line_token, strlen(line_token));
1305 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1306 switch (status_info->status) {
1307 case TEL_SMS_STATUS_MT_READ:
1311 case TEL_SMS_STATUS_MT_UNREAD:
1315 case TEL_SMS_STATUS_MO_NOT_SENT:
1319 case TEL_SMS_STATUS_MO_SENT:
1323 case TEL_SMS_STATUS_MO_DELIVERED:
1327 case TEL_SMS_STATUS_MO_DELIVERY_NOT_CONFIRMED:
1331 case TEL_SMS_STATUS_REPLACED:/*Fall Through*/
1337 encoded_len = strlen(line_token);
1338 dbg("Encoded data length:[%d]", encoded_len);
1340 encoded_data = tcore_malloc0(2*encoded_len + 1);
1342 memcpy(encoded_data, line_token, encoded_len);
1343 dbg("encoded_data: [%s]", encoded_data);
1345 /* overwrite Status byte information */
1346 tcore_util_byte_to_hex((const char *)&msg_status, encoded_data, 1);
1349 * Updating EF-SMS File with status byte
1350 * Rest 175 bytes are same as received in Read Record
1353 at_cmd = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"",
1354 (status_info->index), IMC_AT_EF_SMS_RECORD_LEN, encoded_data);
1356 /* Send Request to modem */
1357 ret = tcore_at_prepare_and_send_request(co,
1359 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1360 TCORE_PENDING_PRIORITY_DEFAULT,
1362 on_response_imc_sms_set_message_status, resp_cb_data,
1363 on_send_imc_request, NULL,
1365 IMC_CHECK_REQUEST_RET(ret, resp_cb_data,
1366 "Set Message Status-Updating status in Record");
1368 g_free(encoded_data);
1369 g_free(status_info);
1370 tcore_at_tok_free(tokens);
1374 err("Invalid Response Received");
1378 err("Response NOK");
1381 /* Invoke callback */
1382 if (resp_cb_data->cb)
1383 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1385 /* Free callback data */
1386 imc_destroy_resp_cb_data(resp_cb_data);
1389 static void on_response_imc_sms_get_sms_params(TcorePending *p,
1390 guint data_len, const void *data, void *user_data)
1392 const TcoreAtResponse *at_resp = data;
1393 CoreObject *co = tcore_pending_ref_core_object(p);
1394 ImcRespCbData *resp_cb_data = user_data;
1395 ImcSmsParamsCbData *params_req_data;
1396 gint sw1 = 0, sw2 = 0, decoding_length = 0;
1397 const char *line = NULL;
1398 char *hex_data = NULL, *record_data = NULL;
1399 GSList *tokens = NULL;
1401 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1404 params_req_data = (ImcSmsParamsCbData *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1406 if (at_resp && at_resp->success) {
1408 if (at_resp->lines) {
1409 line = (const char *) at_resp->lines->data;
1410 tokens = tcore_at_tok_new(line);
1412 sw1 = atoi(g_slist_nth_data(tokens, 0));
1413 sw2 = atoi(g_slist_nth_data(tokens, 1));
1414 dbg("sw1 [0x%x], sw2[0x%x]", sw1, sw2);
1416 if (!(sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1417 err("invalid response received");
1421 hex_data = g_slist_nth_data(tokens, 2);
1422 if (hex_data == NULL) {
1423 err("invalid response received");
1427 tcore_util_hexstring_to_bytes(hex_data, &record_data, (guint*)&decoding_length);
1429 * Decrementing the Record Count and Filling the ParamsInfo List
1430 * Final Response will be posted when Record count is ZERO
1432 params_req_data->params[params_req_data->index].index = params_req_data->index;
1434 tcore_util_decode_sms_parameters((unsigned char *)record_data,
1436 ¶ms_req_data->params[params_req_data->index]);
1438 params_req_data->total_param_count -= 1;
1440 if (params_req_data->total_param_count == 0) {
1441 dbg("Reading all Records - Complete");
1442 result = TEL_SMS_RESULT_SUCCESS;
1445 dbg("Reading all records incomplete [%d - Pending]",
1446 params_req_data->total_param_count);
1447 tcore_at_tok_free(tokens);
1451 err("Invalid Response Received");
1454 err("RESPONSE NOK");
1459 TelSmsParamsInfoList param_info_list = {0, };
1461 if (result == TEL_SMS_RESULT_SUCCESS) {
1462 param_info_list.params = params_req_data->params;
1463 param_info_list.count = params_req_data->count;
1466 /* Invoke callback */
1467 if (resp_cb_data->cb)
1468 resp_cb_data->cb(co, (gint)result, (void *)¶m_info_list, resp_cb_data->cb_data);
1472 tcore_at_tok_free(tokens);
1474 tcore_free(params_req_data->params);
1475 g_free(record_data);
1477 /* Free callback data */
1478 imc_destroy_resp_cb_data(resp_cb_data);
1481 static void on_response_imc_sms_set_sms_params(TcorePending *p,
1482 guint data_len, const void *data, void *user_data)
1484 const TcoreAtResponse *at_resp = data;
1485 CoreObject *co = tcore_pending_ref_core_object(p);
1486 ImcRespCbData *resp_cb_data = user_data;
1488 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1489 gint sw1 = 0 , sw2 = 0;
1490 const char *line = NULL;
1491 GSList *tokens=NULL;
1494 if (at_resp && at_resp->success) {
1496 if (at_resp->lines) {
1497 line = (const char *) at_resp->lines->data;
1498 tokens = tcore_at_tok_new(line);
1500 sw1 = atoi(g_slist_nth_data(tokens, 0));
1501 sw2 = atoi(g_slist_nth_data(tokens, 1));
1503 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1504 result = TEL_SMS_RESULT_SUCCESS;
1507 result = TEL_SMS_RESULT_FAILURE;
1510 tcore_at_tok_free(tokens);
1512 err("Response NOK");
1515 /* Invoke callback */
1516 if (resp_cb_data->cb)
1517 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1519 /* Free callback data */
1520 imc_destroy_resp_cb_data(resp_cb_data);
1523 static gboolean async_callback(gpointer data)
1525 ImcRespCbData *resp_cb_data = data;
1527 TelSmsResult result = TEL_SMS_RESULT_SUCCESS;
1529 co = ((CoreObject **)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data));
1531 /* Invoke callback */
1532 if (resp_cb_data->cb)
1533 resp_cb_data->cb(*co, (gint)result, NULL, resp_cb_data->cb_data);
1535 /* Free callback data */
1536 imc_destroy_resp_cb_data(resp_cb_data);
1541 /* SMS Operations */
1543 * Operation - send_sms
1546 * AT-Command: AT+CMGS
1547 * For PDU mode (+CMGF=0):
1548 * +CMGS=<length><CR>
1549 * PDU is given<ctrl-Z/ESC>
1551 * <length> Length of the pdu.
1552 * <PDU> PDU to send.
1555 *+CMGS: <mr>[,<ackpdu>]
1558 * +CMS ERROR: <error>
1560 static TelReturn imc_sms_send_sms(CoreObject *co,
1561 const TelSmsSendInfo *send_info, TcoreObjectResponseCallback cb, void *cb_data)
1565 ImcRespCbData *resp_cb_data;
1568 const unsigned char *tpdu_byte_data;
1569 gint tpdu_byte_len, pdu_byte_len;
1570 char buf[HEX_PDU_LEN_MAX];
1571 char pdu[PDU_LEN_MAX];
1574 tpdu_byte_data = send_info->send_data.tpdu;
1576 /* TPDU length is in byte */
1577 tpdu_byte_len = send_info->send_data.tpdu_length;
1579 /* Use same Radio Resource Channel :More Messages to send*/
1580 dbg("More messages: [%d]", send_info->more_msgs);
1582 /* Prepare PDU for hex encoding */
1583 pdu_byte_len = tcore_util_encode_pdu(&(send_info->send_data.sca),
1584 tpdu_byte_data, tpdu_byte_len, pdu);
1585 tcore_util_hex_dump(" ", pdu_byte_len, pdu);
1587 tcore_util_encode_hex((unsigned char *)pdu, pdu_byte_len, buf);
1589 /* Response callback data */
1590 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1592 if (send_info->more_msgs == TRUE) {
1593 /* AT Command: More Msgs to Send */
1594 ret = tcore_at_prepare_and_send_request(co,
1595 "AT+CMMS=1", "+CMMS:",
1596 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1597 TCORE_PENDING_PRIORITY_DEFAULT,
1599 on_response_imc_sms_send_more_msg, NULL,
1600 on_send_imc_request, NULL,
1602 IMC_CHECK_REQUEST_RET(ret, NULL, "More Msgs to Send");
1605 /* AT-Command : Send SMS*/
1606 at_cmd = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
1608 /* Send Request to modem */
1609 ret = tcore_at_prepare_and_send_request(co,
1611 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1612 TCORE_PENDING_PRIORITY_DEFAULT,
1614 on_response_imc_sms_send_sms, resp_cb_data,
1615 on_send_imc_request, NULL,
1617 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send SMS");
1619 /* Free resources */
1626 * Operation - write_sms_in_sim
1629 * AT-Command: AT+CMGW
1630 * AT+CMGW = <length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
1632 * <length> length of the tpdu
1633 * <stat> status of the message
1634 * <PDU> PDu of the message
1638 * Success: (Single line)
1641 * +CMS ERROR: <error>
1643 static TelReturn imc_sms_write_sms_in_sim(CoreObject *co,
1644 const TelSmsSimDataInfo *wdata, TcoreObjectResponseCallback cb, void *cb_data)
1648 ImcRespCbData *resp_cb_data;
1651 const unsigned char *tpdu_byte_data;
1652 int tpdu_byte_len, pdu_byte_len;
1653 char buf[HEX_PDU_LEN_MAX];
1654 char hex_pdu[PDU_LEN_MAX];
1658 switch (wdata->status) {
1659 case TEL_SMS_STATUS_MT_UNREAD:
1660 status = AT_MT_UNREAD;
1663 case TEL_SMS_STATUS_MT_READ:
1664 status = AT_MT_READ;
1667 case TEL_SMS_STATUS_MO_NOT_SENT:
1668 status = AT_MO_UNSENT;
1671 case TEL_SMS_STATUS_MO_SENT:
1672 status = AT_MO_SENT;
1676 err("Invalid Message Status");
1677 return TEL_RETURN_INVALID_PARAMETER;
1679 tpdu_byte_data = wdata->data.tpdu;
1681 tpdu_byte_len = wdata->data.tpdu_length;
1682 dbg("TDPU length: [%d]", tpdu_byte_len);
1684 /* Prepare PDU for hex encoding */
1685 pdu_byte_len = tcore_util_encode_pdu(&(wdata->data.sca),
1686 tpdu_byte_data, tpdu_byte_len, hex_pdu);
1687 tcore_util_hex_dump(" ", pdu_byte_len, hex_pdu);
1689 tcore_util_encode_hex((unsigned char *)hex_pdu, pdu_byte_len, buf);
1692 at_cmd = g_strdup_printf("AT+CMGW=%d,%d%c%s%c",
1693 tpdu_byte_len, status, CR, buf, CTRL_Z);
1695 /* Response callback data */
1696 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1698 /* Send Request to modem */
1699 ret = tcore_at_prepare_and_send_request(co,
1701 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1702 TCORE_PENDING_PRIORITY_DEFAULT,
1704 on_response_imc_sms_write_sms_in_sim, resp_cb_data,
1705 on_send_imc_request, NULL,
1707 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Write SMS in SIM");
1709 /* Free resources */
1716 * Operation - read_sms_in_sim
1719 * AT-Command: At+CMGR=<index>
1721 * <index> index of the message to be read.
1724 * Success: (PDU: Multi-line output)
1725 * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
1728 * +CMS ERROR: <error>
1730 static TelReturn imc_sms_read_sms_in_sim(CoreObject *co,
1731 unsigned int index, TcoreObjectResponseCallback cb, void *cb_data)
1735 ImcRespCbData *resp_cb_data;
1740 at_cmd = g_strdup_printf("AT+CMGR=%d", index);
1742 /* Response callback data */
1743 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, ZERO);
1745 /* Send Request to modem */
1746 ret = tcore_at_prepare_and_send_request(co,
1748 TCORE_AT_COMMAND_TYPE_PDU,
1749 TCORE_PENDING_PRIORITY_DEFAULT,
1751 on_response_imc_sms_read_sms_in_sim, resp_cb_data,
1752 on_send_imc_request, NULL,
1754 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read SMS in SIM");
1756 /* Free resources */
1763 * Operation - delete_sms_in_sim
1766 * AT-Command: AT+CGMD
1767 * +CMGD=<index>[,<delflag>]
1770 * Success: (NO RESULT) -
1773 * +CMS ERROR: <error>
1775 static TelReturn imc_sms_delete_sms_in_sim(CoreObject *co,
1777 TcoreObjectResponseCallback cb, void *cb_data)
1781 ImcRespCbData *resp_cb_data;
1785 /* Response callback data */
1786 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1788 * TODO: Delete All Messages
1790 * at_cmd = g_strdup_printf("AT+CMGD=0,4");
1791 * Need to convey MSG_SERVICE to pass an index of
1792 * guint value to delete all Messages.probably as 0.
1796 at_cmd = g_strdup_printf("AT+CMGD=%d,0", index); /*Delete specified index*/
1798 /* Send Request to modem */
1799 ret = tcore_at_prepare_and_send_request(co,
1801 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1802 TCORE_PENDING_PRIORITY_DEFAULT,
1804 on_response_imc_sms_delete_sms_in_sim, resp_cb_data,
1805 on_send_imc_request, NULL,
1807 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete SMS in SIM");
1809 /* Free resources */
1816 * Operation - get_sms_count_in_sim
1819 * AT-Command: AT+CPMS
1820 * +CPMS=<mem1>[, <mem2>[,<mem3>]]
1822 * <mem1> memory storage to read.
1825 * Success: (Single-line output)
1826 * +CPMS: <mem1>,<used1>,<total1>,<mem2>,<used2>,<total2>,
1827 * <mem3>,<used3>,<total3>
1831 * +CMS ERROR: <error>
1833 static TelReturn imc_sms_get_msg_count_in_sim(CoreObject *co,
1834 TcoreObjectResponseCallback cb, void *cb_data)
1838 ImcRespCbData *resp_cb_data;
1843 at_cmd = g_strdup_printf("AT+CPMS=\"SM\"");
1845 /* Response callback data */
1846 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1848 /* Send Request to modem */
1849 ret = tcore_at_prepare_and_send_request(co,
1851 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1852 TCORE_PENDING_PRIORITY_DEFAULT,
1854 on_response_imc_sms_get_sms_count, resp_cb_data,
1855 on_send_imc_request, NULL,
1857 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Count");
1859 /* Free resources */
1866 * Operation - set SCA
1869 * AT-Command: AT+CSCA
1870 * AT+CSCA=<sca>[,<tosca>]
1872 * <sca> Service center number
1873 * <tosca> address type of SCA
1876 * Success: No result
1880 * +CMS ERROR: <error>
1882 static TelReturn imc_sms_set_sca(CoreObject *co,
1883 const TelSmsSca *sca, TcoreObjectResponseCallback cb, void *cb_data)
1887 ImcRespCbData *resp_cb_data;
1891 address_type = ((sca->ton << 4) | sca->npi ) | 0x80;
1894 at_cmd = g_strdup_printf("AT+CSCA=\"%s\",%d", sca->number, address_type);
1896 /* Response callback data */
1897 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1899 /* Send Request to modem */
1900 ret = tcore_at_prepare_and_send_request(co,
1902 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1903 TCORE_PENDING_PRIORITY_DEFAULT,
1905 on_response_imc_sms_set_sca, resp_cb_data,
1906 on_send_imc_request, NULL,
1908 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SCA");
1910 /* Free resources */
1917 * Operation - get SCA
1920 * AT-Command: AT+CSCA?
1923 * Success: Single-Line
1924 * +CSCA: <sca>,<tosca>
1927 * <sca> Service center number
1928 * <tosca> address type of SCA
1931 static TelReturn imc_sms_get_sca(CoreObject *co,
1932 TcoreObjectResponseCallback cb, void *cb_data)
1936 ImcRespCbData *resp_cb_data;
1941 at_cmd = g_strdup_printf("AT+CSCA?");
1943 /* Response callback data */
1944 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1946 /* Send Request to modem */
1947 ret = tcore_at_prepare_and_send_request(co,
1949 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1950 TCORE_PENDING_PRIORITY_DEFAULT,
1952 on_response_imc_sms_get_sca, resp_cb_data,
1953 on_send_imc_request, NULL,
1955 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SCA");
1957 /* Free resources */
1964 * Operation - set_cb_config
1967 * AT-Command: AT+CSCB
1968 * +CSCB=[<mode>[,<mids>[,<dcss>]]]
1975 * +CME ERROR: <error>
1977 static TelReturn imc_sms_set_cb_config(CoreObject *co,
1978 const TelSmsCbConfigInfo *cb_conf,
1979 TcoreObjectResponseCallback cb, void *cb_data)
1983 ImcRespCbData *resp_cb_data;
1986 unsigned short ctr1 = 0, ctr2 = 0, msg_id_range = 0;
1987 unsigned short append_msg_id = 0;
1990 if (cb_conf->msg_id_range_cnt != 0) { /* Enable Specific Msgid's */
1991 gchar *mids_str = NULL;
1992 GString *mid_string = NULL;
1995 mid_string = g_string_new("AT+CSCB=0,\"");
1996 for(ctr1 = 0; ctr1 < cb_conf->msg_id_range_cnt; ctr1++) {
1997 if (cb_conf->msg_ids[ctr1].selected == FALSE)
1999 msg_id_range = ((cb_conf->msg_ids[ctr1].to_msg_id) - (cb_conf->msg_ids[ctr1].from_msg_id));
2001 if (TEL_SMS_GSM_CBMI_LIST_SIZE_MAX <= msg_id_range) {
2002 mid_string = g_string_new("AT+CSCB=1"); /* Enable All CBS */
2005 append_msg_id = cb_conf->msg_ids[ctr1].from_msg_id;
2006 dbg( "%x", append_msg_id);
2008 for(ctr2 = 0; ctr2 <= msg_id_range; ctr2++) {
2009 mid_string = g_string_append(mid_string, g_strdup_printf("%d", append_msg_id));
2010 if (ctr2 == msg_id_range) {
2011 mid_string = g_string_append(mid_string, "\""); /*Mids string termination*/
2014 mid_string = g_string_append(mid_string, ",");
2019 mids_str = g_string_free(mid_string, FALSE);
2020 at_cmd = g_strdup_printf("%s", mids_str);
2024 at_cmd = g_strdup_printf("AT+CSCB=%d", cb_conf->cb_enabled); /* Enable or Disable MsgId's */
2027 /* Response callback data */
2028 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2030 /* Send Request to modem */
2031 ret = tcore_at_prepare_and_send_request(co,
2033 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2034 TCORE_PENDING_PRIORITY_DEFAULT,
2036 on_response_imc_sms_set_cb_config, resp_cb_data,
2037 on_send_imc_request, NULL,
2039 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Cb Config");
2041 /* Free resources */
2048 * Operation - get_cb_config
2051 * AT-Command: AT+CSCB
2055 * Success - (Single line)
2056 * +CSCB : <mode>,<mids>,<dcss>
2060 static TelReturn imc_sms_get_cb_config(CoreObject *co,
2061 TcoreObjectResponseCallback cb, void *cb_data)
2065 ImcRespCbData *resp_cb_data;
2070 at_cmd = g_strdup_printf("AT+CSCB?");
2072 /* Response callback data */
2073 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2075 /* Send Request to modem */
2076 ret = tcore_at_prepare_and_send_request(co,
2078 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2079 TCORE_PENDING_PRIORITY_DEFAULT,
2081 on_response_imc_sms_get_cb_config, resp_cb_data,
2082 on_send_imc_request, NULL,
2084 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Cb Config");
2086 /* Free resources */
2093 * Operation - send_deliver_report
2096 * Modem Takes care of sending the ACK to the network
2099 * Success: Default response always SUCCESS posted
2102 static TelReturn imc_sms_send_deliver_report(CoreObject *co,
2103 const TelSmsDeliverReportInfo *dr_info,
2104 TcoreObjectResponseCallback cb, void *cb_data)
2106 ImcRespCbData *resp_cb_data;
2107 TelReturn ret = TEL_RETURN_FAILURE;
2109 dbg("CP takes care of sending SMS ack to network for all "
2110 "classes of SMS. Sending default success.!!!");
2111 ret = TEL_RETURN_SUCCESS;
2113 /* Response callback data */
2114 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2115 (void *)&co, sizeof(CoreObject*));
2117 g_idle_add(async_callback, (gpointer)resp_cb_data);
2123 /* Operation - set memory status
2126 * AT-Command: AT+XTESM=<mem_capacity>
2127 * <mem_capacity> status of the external SMS storage which may be:
2128 * 0: memory capacity free
2129 * 1: memory capacity full
2131 * Response -No Result
2136 * +CME ERROR: <error>
2138 static TelReturn imc_sms_set_memory_status(CoreObject *co,
2139 gboolean available, TcoreObjectResponseCallback cb, void *cb_data)
2143 ImcRespCbData *resp_cb_data;
2147 at_cmd = g_strdup_printf("AT+XTESM=%d", available? 0: 1);
2149 /* Response callback data */
2150 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2152 /* Send Request to modem */
2153 ret = tcore_at_prepare_and_send_request(co,
2155 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2156 TCORE_PENDING_PRIORITY_DEFAULT,
2158 on_response_imc_sms_set_memory_status, resp_cb_data,
2159 on_send_imc_request, NULL,
2161 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Memory Status");
2163 /* Free resources */
2169 /* Operation - set Message status
2172 * AT-Command: AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2174 * p3 SMSP record length
2177 * Response -Single Line
2182 * +CME ERROR: <error>
2184 static TelReturn imc_sms_set_message_status(CoreObject *co,
2185 const TelSmsStatusInfo *status_info,
2186 TcoreObjectResponseCallback cb, void *cb_data)
2190 ImcRespCbData *resp_cb_data;
2194 at_cmd = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d",
2195 (status_info->index), IMC_AT_EF_SMS_RECORD_LEN);
2197 /* Response callback data */
2198 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2199 (void *)status_info, sizeof(TelSmsStatusInfo));
2201 /* Send Request to modem */
2202 ret = tcore_at_prepare_and_send_request(co,
2204 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2205 TCORE_PENDING_PRIORITY_DEFAULT,
2207 _response_get_efsms_data, resp_cb_data,
2208 on_send_imc_request, NULL,
2210 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Message Status");
2212 /* Free resources */
2219 * Operation - get_sms_parameters
2222 * AT-Command: AT+CRSM
2223 * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2226 * Success: (Single-line output)
2228 * <sw1>,<sw2>[,<response>]
2232 * +CME ERROR: <error>
2234 static TelReturn imc_sms_get_sms_params(CoreObject *co,
2235 TcoreObjectResponseCallback cb, void *cb_data)
2237 TcorePlugin *plugin;
2238 ImcRespCbData *resp_cb_data;
2239 ImcSmsParamsCbData params_req_data = {0, };
2240 gint loop_count, record_count = 0, smsp_record_len = 0;
2241 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
2245 plugin = tcore_object_ref_plugin(co);
2247 /* Get Record count and SMSP record length*/
2248 if (FALSE == (imc_sim_get_smsp_info(plugin, &record_count,
2249 &smsp_record_len))) {
2250 err("Failed to get SMSP record Count and Record length");
2254 dbg("Record Count: [%d] SMSP Record Length: [%d]",
2255 record_count, smsp_record_len);
2257 /* Allocate Memory for params list data */
2258 params_req_data.params = tcore_malloc0(sizeof(TelSmsParamsInfo) * record_count);
2260 params_req_data.total_param_count = record_count;
2261 /* Saving actual count to be returned */
2262 params_req_data.count = record_count;
2263 /* Response callback data */
2264 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2265 (void *)¶ms_req_data,
2266 sizeof(ImcSmsParamsCbData));
2268 for (loop_count = 1; loop_count <= record_count; loop_count++) {
2271 /* Updating the Index */
2272 params_req_data.index = loop_count;
2274 at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
2275 params_req_data.index, smsp_record_len);
2277 /* Send Request to modem */
2278 ret = tcore_at_prepare_and_send_request(co,
2280 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2281 TCORE_PENDING_PRIORITY_DEFAULT,
2283 on_response_imc_sms_get_sms_params, resp_cb_data,
2284 on_send_imc_request, NULL,
2287 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Parameters");
2289 /* Free resources */
2290 if (ret != TEL_RETURN_SUCCESS)
2291 tcore_free(params_req_data.params);
2299 * Operation - set_sms_params
2302 * AT-Command: AT+CRSM
2303 * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2306 * Success: (Single-line output)
2308 * <sw1>,<sw2>[,<response>]
2312 * +CME ERROR: <error>
2314 static TelReturn imc_sms_set_sms_params(CoreObject *co,
2315 const TelSmsParamsInfo *params,
2316 TcoreObjectResponseCallback cb, void *cb_data)
2319 ImcRespCbData *resp_cb_data;
2322 TcorePlugin *plugin;
2323 gint smsp_record_len = 0;
2324 gchar *set_params_data = NULL;
2325 gchar *encoded_data = NULL;
2329 plugin = tcore_object_ref_plugin(co);
2331 if (FALSE == imc_sim_get_smsp_info(plugin, &record_count, &smsp_record_len)) {
2332 err("Failed to get SMSP record Count and Record length");
2333 return TEL_RETURN_INVALID_PARAMETER;
2336 dbg("SMSP Record Length: [%d]", smsp_record_len);
2338 /* Allocate memory for set_params_data */
2339 set_params_data = tcore_malloc0(sizeof(smsp_record_len));
2341 /* Allocate memory for encoded data*/
2342 encoded_data = tcore_malloc0((2 * sizeof(smsp_record_len)+1));
2344 tcore_util_encode_sms_parameters((TelSmsParamsInfo *)params,
2345 set_params_data, smsp_record_len);
2347 tcore_util_byte_to_hex((const char *)set_params_data,
2348 (char *)encoded_data, smsp_record_len);
2350 /* Response callback data */
2351 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, sizeof(gint));
2354 at_cmd = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",
2355 params->index, smsp_record_len, encoded_data);
2356 dbg("at_cmd - %s", at_cmd);
2357 /* Send Request to modem */
2358 ret = tcore_at_prepare_and_send_request(co,
2360 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2361 TCORE_PENDING_PRIORITY_DEFAULT,
2363 on_response_imc_sms_set_sms_params, resp_cb_data,
2364 on_send_imc_request, NULL,
2366 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SMS Parameters");
2368 /* Free resources */
2370 g_free(set_params_data);
2371 g_free(encoded_data);
2376 /* SMS Operations */
2377 static TcoreSmsOps imc_sms_ops = {
2378 .send_sms = imc_sms_send_sms,
2379 .read_in_sim = imc_sms_read_sms_in_sim,
2380 .write_in_sim = imc_sms_write_sms_in_sim,
2381 .delete_in_sim = imc_sms_delete_sms_in_sim,
2382 .get_count = imc_sms_get_msg_count_in_sim,
2383 .set_cb_config = imc_sms_set_cb_config,
2384 .get_cb_config = imc_sms_get_cb_config,
2385 .get_parameters = imc_sms_get_sms_params,
2386 .set_parameters = imc_sms_set_sms_params,
2387 .send_deliver_report = imc_sms_send_deliver_report,
2388 .set_sca = imc_sms_set_sca,
2389 .get_sca = imc_sms_get_sca,
2390 .set_memory_status = imc_sms_set_memory_status,
2391 .set_message_status = imc_sms_set_message_status
2394 gboolean imc_sms_init(TcorePlugin *p, CoreObject *co)
2398 /* Set operations */
2399 tcore_sms_set_ops(co, &imc_sms_ops);
2402 tcore_object_add_callback(co, "\e+CMT:",
2403 on_notification_imc_sms_incoming_msg, NULL);
2404 tcore_object_add_callback(co, "\e+CDS",
2405 on_notification_imc_sms_incoming_msg, NULL);
2407 tcore_object_add_callback(co, "\e+CBM",
2408 on_notification_imc_sms_cb_incom_msg, NULL);
2409 tcore_object_add_callback(co, "+CMTI",
2410 on_notification_imc_sms_class2_incoming_msg, NULL);
2414 * TODO - AT Command Description Not available
2416 tcore_object_add_callback(co, "+XSMSMMSTAT",
2417 on_notification_imc_sms_memory_status, NULL);
2423 void imc_sms_exit(TcorePlugin *p, CoreObject *co)