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;
66 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,
450 on_response_imc_class2_sms_incom_msg, NULL,
451 on_send_imc_request, NULL);
452 if (ret != TEL_RETURN_SUCCESS) {
453 err("Failed to Read Class2 Incomming Message");
459 static void on_response_imc_sms_send_more_msg(TcorePending *p,
460 guint data_len, const void *data, void *user_data)
462 const TcoreAtResponse *at_resp = data;
466 if (at_resp && at_resp->success)
467 dbg("Response OK for AT+CMMS: More msgs to send!!");
469 err("Response NOK for AT+CMMS: More msgs to send");
471 /* Need not send any response */
474 static void on_response_imc_sms_send_sms(TcorePending *p,
475 guint data_len, const void *data, void *user_data)
477 const TcoreAtResponse *at_resp = data;
478 CoreObject *co = tcore_pending_ref_core_object(p);
479 ImcRespCbData *resp_cb_data = user_data;
481 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CMS error mapping required */
484 tcore_check_return_assert(co != NULL);
485 tcore_check_return_assert(resp_cb_data != NULL);
487 if (at_resp && at_resp->success) {
489 if (at_resp->lines) {
492 GSList *tokens = NULL;
495 line = (const gchar *)at_resp->lines->data;
496 tokens = tcore_at_tok_new(line);
497 line_token = g_slist_nth_data(tokens, 0);
498 if (line_token != NULL) {
499 /*Response from MODEM for send SMS: +CMGS: <mr>[,<ackpdu>]*/
500 /*Message Reference is not used by MSG_SERVER and application.So Filling only result*/
501 msg_ref = atoi(line_token);
503 dbg("Message Reference: [%d]", msg_ref);
505 result = TEL_SMS_RESULT_SUCCESS;
508 dbg("No Message Reference received");
510 tcore_at_tok_free(tokens);
517 /* Invoke callback */
518 if (resp_cb_data->cb)
519 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
521 /* Free callback data */
522 imc_destroy_resp_cb_data(resp_cb_data);
525 static void on_response_imc_sms_write_sms_in_sim(TcorePending *p,
526 guint data_len, const void *data, void *user_data)
528 const TcoreAtResponse *at_resp = data;
529 CoreObject *co = tcore_pending_ref_core_object(p);
530 ImcRespCbData *resp_cb_data = user_data;
532 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
534 GSList *tokens = NULL;
535 char *line = NULL, *line_token = NULL;
540 if (at_resp && at_resp->success) {
542 if (at_resp->lines) {
543 line = (char *)at_resp->lines->data;
544 tokens = tcore_at_tok_new(line);
545 line_token = g_slist_nth_data(tokens, 0);
547 index = (atoi(line_token));
548 dbg("SMS written to '%d' index", index);
549 result = TEL_SMS_RESULT_SUCCESS;
553 result = TEL_SMS_RESULT_FAILURE;
557 err("Lines NOT present");
564 /* Invoke callback */
565 if (resp_cb_data->cb)
566 resp_cb_data->cb(co, (gint)result, &index, resp_cb_data->cb_data);
568 /* Free callback data */
569 imc_destroy_resp_cb_data(resp_cb_data);
572 static void on_response_imc_sms_read_sms_in_sim(TcorePending *p,
573 guint data_len, const void *data, void *user_data)
575 const TcoreAtResponse *at_resp = data;
576 CoreObject *co = tcore_pending_ref_core_object(p);
577 ImcRespCbData *resp_cb_data = user_data;
578 TelSmsSimDataInfo read_resp;
579 GSList *tokens = NULL;
581 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/* CMS error mapping required */
584 memset(&read_resp, 0x0, sizeof(TelSmsSimDataInfo));
586 if (at_resp && at_resp->success) {
588 if (at_resp->lines) {
589 char *gslist_line = NULL,*line_token = NULL,*byte_pdu = NULL,*hex_pdu = NULL;
590 gint msg_status = 0, pdu_len = 0, alpha_id = 0;
596 * Fetching First Line
598 gslist_line = (char *)at_resp->lines->data;
599 dbg("gslist_line: [%s]", gslist_line);
602 tokens = tcore_at_tok_new(gslist_line);
603 dbg("Number of tokens: [%d]", g_slist_length(tokens));
605 /*+CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>*/
606 line_token = g_slist_nth_data(tokens, 0); /*First Token: Message status*/
607 if (line_token == NULL) {
612 msg_status = atoi(line_token);
613 dbg("msg_status is %d",msg_status);
615 switch (msg_status) {
617 read_resp.status = TEL_SMS_STATUS_MT_UNREAD;
620 read_resp.status = TEL_SMS_STATUS_MT_READ;
623 read_resp.status = TEL_SMS_STATUS_MO_NOT_SENT;
626 read_resp.status = TEL_SMS_STATUS_MO_SENT;
630 read_resp.status = TEL_SMS_STATUS_REPLACED;
634 /*Second Token: Alpha ID*/
635 line_token = g_slist_nth_data(tokens, 1);
636 if (line_token != NULL) {
637 alpha_id = atoi(line_token);
638 dbg("alpha_id: [%d]", alpha_id);
641 /*Third Token: Length*/
642 line_token = g_slist_nth_data(tokens, 2);
643 if (line_token == NULL) {
644 err("Invalid PDU length");
647 pdu_len = atoi(line_token);
648 dbg("PDU length: [%d]", pdu_len);
650 /*Fetching line: Second line is PDU*/
651 hex_pdu = (char *) at_resp->lines->next->data;
652 dbg("EF-SMS PDU: [%s]", hex_pdu);
654 if (NULL != hex_pdu) {
656 guint byte_pdu_len = 0;
658 tcore_util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
660 tcore_util_hexstring_to_bytes(hex_pdu, &byte_pdu, &byte_pdu_len);
662 sca_length = byte_pdu[0];
663 dbg("SCA length = %d", sca_length);
666 guint encoded_sca_len;
669 * byte_pdu[1] - sca_address_type
670 * Excluding sca_address_type and copy SCA
672 encoded_sca_len = sca_length - 1;
674 tcore_util_convert_bcd_to_ascii(&byte_pdu[2],
675 encoded_sca_len, encoded_sca_len*2);
677 dbg("Decoded SCA: [%s]", decoded_sca);
678 memcpy(read_resp.data.sca.number, decoded_sca, TEL_SMS_SCA_LEN_MAX);
679 tcore_free(decoded_sca);
681 /*SCA Conversion for Address type*/
682 read_resp.data.sca.ton = IMC_TYPE_OF_NUM(byte_pdu[1]);
683 read_resp.data.sca.npi = IMC_NUM_PLAN_ID(byte_pdu[1]);
684 dbg("TON: [%d] NPI: [%d] SCA: [%s]",
685 read_resp.data.sca.ton, read_resp.data.sca.npi,
686 read_resp.data.sca.number);
688 err("NO SCA Present");
692 read_resp.data.tpdu_length = pdu_len;
693 if ((read_resp.data.tpdu_length > 0)
694 && (read_resp.data.tpdu_length <= TEL_SMS_SMDATA_SIZE_MAX)) {
695 memcpy(read_resp.data.tpdu, &byte_pdu[sca_length+1],
696 read_resp.data.tpdu_length);
698 warn("Invalid TPDU length: [%d]", read_resp.data.tpdu_length);
701 result = TEL_SMS_RESULT_SUCCESS;
705 err("Invalid Response Received");
712 /* Invoke callback */
713 if (resp_cb_data->cb)
714 resp_cb_data->cb(co, (gint)result, &read_resp, resp_cb_data->cb_data);
716 /* Free callback data */
717 imc_destroy_resp_cb_data(resp_cb_data);
719 /*free the consumed token*/
720 tcore_at_tok_free(tokens);
723 static void on_response_imc_sms_delete_sms_in_sim(TcorePending *p,
724 guint data_len, const void *data, void *user_data)
726 const TcoreAtResponse *at_resp = data;
727 CoreObject *co = tcore_pending_ref_core_object(p);
728 ImcRespCbData *resp_cb_data = user_data;
730 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
733 tcore_check_return_assert(co != NULL);
735 if (at_resp && at_resp->success) {
737 result = TEL_SMS_RESULT_SUCCESS;
743 /* Invoke callback */
744 if (resp_cb_data->cb)
745 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
747 /* Free callback data */
748 imc_destroy_resp_cb_data(resp_cb_data);
751 static void on_response_imc_sms_get_msg_indices(TcorePending *p,
752 guint data_len, const void *data, void *user_data)
754 TelSmsStoredMsgCountInfo *count_info;/*Response from get_count Request*/
755 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CMS error mapping required */
757 const TcoreAtResponse *at_resp = data;
758 CoreObject *co = tcore_pending_ref_core_object(p);
759 ImcRespCbData *resp_cb_data = user_data;
762 count_info = (TelSmsStoredMsgCountInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
764 if (at_resp && at_resp->success) {
766 if (at_resp->lines) {
767 char *gslist_line = NULL;
768 gint gslist_line_count = 0, ctr_loop = 0;
770 gslist_line_count = g_slist_length(at_resp->lines);
772 if (gslist_line_count > TEL_SMS_GSM_MSG_NUM_MAX)
773 gslist_line_count = TEL_SMS_GSM_MSG_NUM_MAX;
774 dbg("Number of lines: [%d]", gslist_line_count);
776 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
777 /* Fetch Line 'ctr_loop' */
778 gslist_line = (char *)g_slist_nth_data(at_resp->lines, ctr_loop);
779 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
781 if (NULL != gslist_line) {
782 GSList *tokens = NULL;
783 char *line_token = NULL;
785 tokens = tcore_at_tok_new(gslist_line);
787 line_token = g_slist_nth_data(tokens, 0);
788 if (NULL != line_token) {
789 count_info->index_list[ctr_loop] = atoi(line_token);
792 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
795 tcore_at_tok_free(tokens);
798 err("gslist_line is NULL");
803 result = TEL_SMS_RESULT_SUCCESS;
806 err("Invalid Response received. No Lines present in Response");
808 /* Check if used count is zero*/
809 if (count_info->used_count == 0)
810 result = TEL_SMS_RESULT_SUCCESS;
818 /* Invoke callback */
819 if (resp_cb_data->cb)
820 resp_cb_data->cb(co, (gint)result, count_info, resp_cb_data->cb_data);
822 /* Free callback data */
823 imc_destroy_resp_cb_data(resp_cb_data);
826 static void on_response_imc_sms_get_sms_count(TcorePending *p,
827 guint data_len, const void *data, void *user_data)
832 TelSmsStoredMsgCountInfo count_info = {0, };
833 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
834 int used_count = 0, total_count = 0;
836 const TcoreAtResponse *at_resp = data;
837 CoreObject *co = tcore_pending_ref_core_object(p);
838 ImcRespCbData *resp_cb_data = user_data;
839 ImcRespCbData *getcnt_resp_cb_data;
842 if (at_resp && at_resp->success) {
844 if (at_resp->lines) {
845 GSList *tokens = NULL;
846 char *line = NULL, *line_token = NULL;
848 line = (char *)at_resp->lines->data;
849 dbg("line: [%s]",line);
854 * +CPMS: <used1>, <total1>, <used2>, <total2>, <used3>, <total3>
856 tokens = tcore_at_tok_new(line);
859 line_token = g_slist_nth_data(tokens, 0);
861 used_count =atoi(line_token);
862 dbg("used cnt is %d",used_count);
865 err("Line Token for used count is NULL");
866 tcore_at_tok_free(tokens);
871 line_token = g_slist_nth_data(tokens, 1);
873 total_count = atoi(line_token);
875 count_info.total_count = total_count;
876 count_info.used_count = used_count;
877 dbg("Count - used: [%d] total: [%d]", used_count, total_count);
880 * Operation - get_msg_indices_in_sim
883 * AT-Command: AT+CMGL
884 * +CPMS=<mem1>[, <mem2>[,<mem3>]]
886 * <mem1> memory storage to read.
889 * Success: (Multi-line output)
892 * <stat> status of the message.
894 * +CMS ERROR: <error>
897 /* Sending the Second AT Request to fetch msg indices */
898 at_cmd = g_strdup_printf("AT+CMGL=4");
900 /* Response callback data */
901 getcnt_resp_cb_data = imc_create_resp_cb_data(resp_cb_data->cb,
902 resp_cb_data->cb_data,
903 &count_info, sizeof(TelSmsStoredMsgCountInfo));
905 /* Free previous request callback data */
906 imc_destroy_resp_cb_data(resp_cb_data);
908 /* Send Request to modem */
909 ret = tcore_at_prepare_and_send_request(co,
911 TCORE_AT_COMMAND_TYPE_MULTILINE,
913 on_response_imc_sms_get_msg_indices, getcnt_resp_cb_data,
914 on_send_imc_request, NULL);
916 /* free the consumed token */
917 tcore_at_tok_free(tokens);
920 IMC_CHECK_REQUEST_RET(ret, getcnt_resp_cb_data, "Get Indices in SIM");
921 if (ret != TEL_RETURN_SUCCESS) {
922 err("Failed to Process Get Msg Indices Request");
930 err("Line Token for Total count is NULL");
932 /* free the consumed token */
933 tcore_at_tok_free(tokens);
938 err("Invalid Response Received: NO Lines Present");
946 /* Invoke callback in case of error*/
947 if (resp_cb_data->cb)
948 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
950 /* Free callback data */
951 imc_destroy_resp_cb_data(resp_cb_data);
954 static void on_response_imc_sms_set_sca(TcorePending *p,
955 guint data_len, const void *data, void *user_data)
957 const TcoreAtResponse *at_resp = data;
958 CoreObject *co = tcore_pending_ref_core_object(p);
959 ImcRespCbData *resp_cb_data = user_data;
961 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
964 if (at_resp && at_resp->success) {
966 result = TEL_SMS_RESULT_SUCCESS;
972 /* Invoke callback */
973 if (resp_cb_data->cb)
974 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
976 /* Free callback data */
977 imc_destroy_resp_cb_data(resp_cb_data);
980 static void on_response_imc_sms_get_sca(TcorePending *p,
981 guint data_len, const void *data, void *user_data)
983 const TcoreAtResponse *at_resp = data;
984 CoreObject *co = tcore_pending_ref_core_object(p);
985 ImcRespCbData *resp_cb_data = user_data;
987 TelSmsSca sca_resp = { 0, };
988 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
991 if (at_resp && at_resp->success) {
993 if (at_resp->lines) {
994 GSList *tokens = NULL;
995 const char *sca_tok_addr;
996 gchar *line = NULL, *sca_addr = NULL, *sca_toa = NULL;
998 line = (char *)at_resp->lines->data;
999 tokens = tcore_at_tok_new(line);
1000 sca_tok_addr = g_slist_nth_data(tokens, 0);
1001 sca_toa = g_slist_nth_data(tokens, 1);
1003 sca_addr = tcore_at_tok_extract(sca_tok_addr);
1004 dbg("SCA: [%s] SCA-TOA: [%s]", sca_addr, sca_toa);
1005 if ((NULL != sca_addr) && (NULL != sca_toa)) {
1006 memcpy(sca_resp.number, sca_addr, strlen(sca_addr));
1008 /* Type-of-Address */
1009 if (145 == atoi(sca_toa)) {
1010 sca_resp.ton = IMC_SIM_TON_INTERNATIONAL;
1013 sca_resp.ton = IMC_SIM_TON_NATIONAL;
1015 sca_resp.npi = 0;/* TODO */
1016 result = TEL_SMS_RESULT_SUCCESS;
1021 tcore_at_tok_free(tokens);
1025 err("Invalid Response.No Lines Received");
1029 err("Response NOK");
1032 /* Invoke callback */
1033 if (resp_cb_data->cb)
1034 resp_cb_data->cb(co, (gint)result, &sca_resp, resp_cb_data->cb_data);
1036 /* Free callback data */
1037 imc_destroy_resp_cb_data(resp_cb_data);
1040 static void on_response_imc_sms_set_cb_config(TcorePending *p,
1041 guint data_len, const void *data, void *user_data)
1043 const TcoreAtResponse *at_resp = data;
1044 CoreObject *co = tcore_pending_ref_core_object(p);
1045 ImcRespCbData *resp_cb_data = user_data;
1047 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CME error mapping required */
1050 if (at_resp && at_resp->success) {
1052 result = TEL_SMS_RESULT_SUCCESS;
1055 err("Response NOK");
1058 /* Invoke callback */
1059 if (resp_cb_data->cb)
1060 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1062 /* Free callback data */
1063 imc_destroy_resp_cb_data(resp_cb_data);
1066 static void on_response_imc_sms_get_cb_config(TcorePending *p,
1067 guint data_len, const void *data, void *user_data)
1069 const TcoreAtResponse *at_resp = data;
1070 CoreObject *co = tcore_pending_ref_core_object(p);
1071 ImcRespCbData *resp_cb_data = user_data;
1073 GSList *cb_tokens = NULL;
1074 char *cb_str_token = NULL;
1075 int num_cb_tokens = 0;
1076 char *mid_tok = NULL;
1077 char *first_tok = NULL, *second_tok = NULL;
1078 gint i = 0, mode = 0;
1081 TelSmsCbConfigInfo get_cb_conf = {0, };
1082 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1085 if (at_resp && at_resp->success) {
1087 if (at_resp->lines) {
1088 GSList *tokens = NULL;
1089 char *line_token = NULL, *line = NULL;
1090 line = (char*)at_resp->lines->data;
1092 tokens = tcore_at_tok_new(line);
1095 * +CSCB: <mode>,<mids>,<dcss>
1097 line_token = g_slist_nth_data(tokens, 0);
1099 mode = atoi(line_token);
1100 dbg("mode:[%d]", mode);
1101 get_cb_conf.cb_enabled = mode;
1104 err("Line Token for Mode is NULL");
1105 tcore_at_tok_free(tokens);
1108 line_token = g_slist_nth_data(tokens, 1);
1110 cb_str_token = tcore_at_tok_extract(line_token);
1111 cb_tokens = tcore_at_tok_new((const char *)cb_str_token);
1113 num_cb_tokens = g_slist_length(cb_tokens);
1114 dbg("num_cb_tokens = %d", num_cb_tokens);
1115 if (num_cb_tokens == 0) {
1116 if (mode == 1) { /* All CBS Enabled */
1117 get_cb_conf.msg_id_range_cnt = 1;
1118 get_cb_conf.msg_ids[0].from_msg_id = 0x0000;
1119 get_cb_conf.msg_ids[0].to_msg_id = TEL_SMS_GSM_CBMI_LIST_SIZE_MAX + 1;
1120 get_cb_conf.msg_ids[0].selected = TRUE;
1122 else { /* All CBS Disabled */
1123 get_cb_conf.msg_id_range_cnt = 0;
1124 get_cb_conf.msg_ids[0].selected = FALSE;
1128 for(i = 0; i < num_cb_tokens; i++) {
1129 get_cb_conf.msg_ids[i].selected = TRUE;
1130 dbg("msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
1131 get_cb_conf.msg_id_range_cnt++;
1132 dbg("Incremented msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
1134 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1135 first_tok = strtok(mid_tok, delim);
1136 second_tok = strtok(NULL, delim);
1138 if ((first_tok != NULL) && (second_tok != NULL)) {/* mids in range (320-478) */
1139 get_cb_conf.msg_ids[i].from_msg_id = atoi(first_tok);
1140 get_cb_conf.msg_ids[i].to_msg_id = atoi(second_tok);
1142 else {/* single mid value (0,1,5, 922)*/
1143 get_cb_conf.msg_ids[i].from_msg_id = atoi(mid_tok);
1144 get_cb_conf.msg_ids[i].to_msg_id = atoi(mid_tok);
1149 err("Line Token for MID is NULL");
1150 tcore_at_tok_free(tokens);
1155 err("Line is NULL");
1157 result = TEL_SMS_RESULT_SUCCESS;
1158 tcore_at_tok_free(tokens);
1159 tcore_at_tok_free(cb_tokens);
1160 g_free(cb_str_token);
1163 err("Invalid Response.No Lines Received");
1167 err("Response NOK");
1171 /* Invoke callback */
1172 if (resp_cb_data->cb)
1173 resp_cb_data->cb(co, (gint)result, &get_cb_conf, resp_cb_data->cb_data);
1175 /* Free callback data */
1176 imc_destroy_resp_cb_data(resp_cb_data);
1179 static void on_response_imc_sms_set_memory_status(TcorePending *p,
1180 guint data_len, const void *data, void *user_data)
1182 const TcoreAtResponse *at_resp = data;
1183 CoreObject *co = tcore_pending_ref_core_object(p);
1184 ImcRespCbData *resp_cb_data = user_data;
1186 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1189 if (at_resp && at_resp->success) {
1191 result = TEL_SMS_RESULT_SUCCESS;
1194 err("Response NOK");
1197 /* Invoke callback */
1198 if (resp_cb_data->cb)
1199 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1201 /* Free callback data */
1202 imc_destroy_resp_cb_data(resp_cb_data);
1205 static void on_response_imc_sms_set_message_status(TcorePending *p,
1206 guint data_len, const void *data, void *user_data)
1208 const TcoreAtResponse *at_resp = data;
1209 CoreObject *co = tcore_pending_ref_core_object(p);
1210 ImcRespCbData *resp_cb_data = user_data;
1212 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1213 int response = 0, sw1 = 0, sw2 = 0;
1214 const char *line = NULL;
1215 char *line_token = NULL;
1216 GSList *tokens = NULL;
1219 if (at_resp && at_resp->success) {
1221 if (at_resp->lines) {
1222 line = (const char *) at_resp->lines->data;
1223 tokens = tcore_at_tok_new(line);
1224 line_token = g_slist_nth_data(tokens, 0);
1225 if (line_token != NULL) {
1226 sw1 = atoi(line_token);
1231 line_token = g_slist_nth_data(tokens, 1);
1232 if (line_token != NULL) {
1233 sw2 = atoi(line_token);
1234 if ((sw1 == 0x90) && (sw2 == 0)) {
1235 result = TEL_SMS_RESULT_SUCCESS;
1241 line_token = g_slist_nth_data(tokens, 3);
1243 if (line_token != NULL) {
1244 response = atoi(line_token);
1245 dbg("response is %s", response);
1247 tcore_at_tok_free(tokens);
1254 err("RESPONSE NOK");
1257 /* Invoke callback */
1258 if (resp_cb_data->cb)
1259 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1261 /* Free callback data */
1262 imc_destroy_resp_cb_data(resp_cb_data);
1265 static void _response_get_efsms_data(TcorePending *p,
1266 guint data_len, const void *data, void *user_data)
1269 const TcoreAtResponse *at_resp = data;
1270 CoreObject *co = tcore_pending_ref_core_object(p);
1271 ImcRespCbData *resp_cb_data = user_data;
1273 TelSmsStatusInfo *status_info;
1274 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1277 char *encoded_data = NULL;
1278 int encoded_len = 0;
1279 char msg_status = 0;
1280 char *line_token = NULL;
1281 GSList *tokens=NULL;
1282 const char *line = NULL;
1287 status_info = (TelSmsStatusInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1288 if (at_resp && at_resp->success) {
1290 if (at_resp->lines) {
1291 dbg("Entry:lines Ok");
1292 line = (const char *) at_resp->lines->data;
1293 tokens = tcore_at_tok_new(line);
1295 sw1 = atoi(g_slist_nth_data(tokens, 0));
1296 sw2 = atoi(g_slist_nth_data(tokens, 1));
1297 line_token = g_slist_nth_data(tokens, 2);
1299 dbg("line_token:[%s], Length of line token:[%d]", line_token, strlen(line_token));
1301 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1302 switch (status_info->status) {
1303 case TEL_SMS_STATUS_MT_READ:
1307 case TEL_SMS_STATUS_MT_UNREAD:
1311 case TEL_SMS_STATUS_MO_NOT_SENT:
1315 case TEL_SMS_STATUS_MO_SENT:
1319 case TEL_SMS_STATUS_MO_DELIVERED:
1323 case TEL_SMS_STATUS_MO_DELIVERY_NOT_CONFIRMED:
1327 case TEL_SMS_STATUS_REPLACED:/*Fall Through*/
1333 encoded_len = strlen(line_token);
1334 dbg("Encoded data length:[%d]", encoded_len);
1336 encoded_data = tcore_malloc0(2*encoded_len + 1);
1338 memcpy(encoded_data, line_token, encoded_len);
1339 dbg("encoded_data: [%s]", encoded_data);
1341 /* overwrite Status byte information */
1342 tcore_util_byte_to_hex((const char *)&msg_status, encoded_data, 1);
1345 * Updating EF-SMS File with status byte
1346 * Rest 175 bytes are same as received in Read Record
1349 at_cmd = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"",
1350 (status_info->index), IMC_AT_EF_SMS_RECORD_LEN, encoded_data);
1352 /* Send Request to modem */
1353 ret = tcore_at_prepare_and_send_request(co,
1355 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1357 on_response_imc_sms_set_message_status, resp_cb_data,
1358 on_send_imc_request, NULL);
1359 IMC_CHECK_REQUEST_RET(ret, resp_cb_data,
1360 "Set Message Status-Updating status in Record");
1362 g_free(encoded_data);
1363 g_free(status_info);
1364 tcore_at_tok_free(tokens);
1368 err("Invalid Response Received");
1372 err("Response NOK");
1375 /* Invoke callback */
1376 if (resp_cb_data->cb)
1377 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1379 /* Free callback data */
1380 imc_destroy_resp_cb_data(resp_cb_data);
1383 static void on_response_imc_sms_get_sms_params(TcorePending *p,
1384 guint data_len, const void *data, void *user_data)
1386 const TcoreAtResponse *at_resp = data;
1387 CoreObject *co = tcore_pending_ref_core_object(p);
1388 ImcRespCbData *resp_cb_data = user_data;
1389 ImcSmsParamsCbData *params_req_data;
1390 gint sw1 = 0, sw2 = 0, decoding_length = 0;
1391 const char *line = NULL;
1392 char *hex_data = NULL, *record_data = NULL;
1393 GSList *tokens = NULL;
1395 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1398 params_req_data = (ImcSmsParamsCbData *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1400 if (at_resp && at_resp->success) {
1402 if (at_resp->lines) {
1403 line = (const char *) at_resp->lines->data;
1404 tokens = tcore_at_tok_new(line);
1406 sw1 = atoi(g_slist_nth_data(tokens, 0));
1407 sw2 = atoi(g_slist_nth_data(tokens, 1));
1408 dbg("sw1 [0x%x], sw2[0x%x]", sw1, sw2);
1410 if (!(sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1411 err("invalid response received");
1415 hex_data = g_slist_nth_data(tokens, 2);
1416 if (hex_data == NULL) {
1417 err("invalid response received");
1420 hex_data = tcore_at_tok_extract((const gchar *)hex_data);
1422 tcore_util_hexstring_to_bytes(hex_data, &record_data, (guint*)&decoding_length);
1423 tcore_free(hex_data);
1425 * Decrementing the Record Count and Filling the ParamsInfo List
1426 * Final Response will be posted when Record count is ZERO
1428 params_req_data->params[params_req_data->index].index = params_req_data->index;
1430 tcore_util_decode_sms_parameters((unsigned char *)record_data,
1432 ¶ms_req_data->params[params_req_data->index]);
1434 params_req_data->total_param_count -= 1;
1436 if (params_req_data->total_param_count == 0) {
1437 dbg("Reading all Records - Complete");
1438 result = TEL_SMS_RESULT_SUCCESS;
1444 dbg("Reading all records incomplete [Pending - %d]",
1445 params_req_data->total_param_count);
1447 params_req_data->index++;
1450 at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
1451 params_req_data->index, params_req_data->record_length);
1453 /* Send Request to modem */
1454 ret = tcore_at_prepare_and_send_request(co,
1456 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1458 on_response_imc_sms_get_sms_params, resp_cb_data,
1459 on_send_imc_request, NULL);
1462 if (ret != TEL_RETURN_SUCCESS) {
1463 err("Failed to process request - [%s]", "Get SMS Parameters");
1467 tcore_at_tok_free(tokens);
1471 err("Invalid Response Received");
1474 err("RESPONSE NOK");
1479 TelSmsParamsInfoList param_info_list = {0, };
1481 if (result == TEL_SMS_RESULT_SUCCESS) {
1482 param_info_list.params = params_req_data->params;
1483 param_info_list.count = params_req_data->record_count;
1486 /* Invoke callback */
1487 if (resp_cb_data->cb)
1488 resp_cb_data->cb(co, (gint)result, (void *)¶m_info_list, resp_cb_data->cb_data);
1492 tcore_at_tok_free(tokens);
1494 tcore_free(params_req_data->params);
1495 g_free(record_data);
1497 /* Free callback data */
1498 imc_destroy_resp_cb_data(resp_cb_data);
1501 static void on_response_imc_sms_set_sms_params(TcorePending *p,
1502 guint data_len, const void *data, void *user_data)
1504 const TcoreAtResponse *at_resp = data;
1505 CoreObject *co = tcore_pending_ref_core_object(p);
1506 ImcRespCbData *resp_cb_data = user_data;
1508 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1509 gint sw1 = 0 , sw2 = 0;
1510 const char *line = NULL;
1511 GSList *tokens=NULL;
1514 if (at_resp && at_resp->success) {
1516 if (at_resp->lines) {
1517 line = (const char *) at_resp->lines->data;
1518 tokens = tcore_at_tok_new(line);
1520 sw1 = atoi(g_slist_nth_data(tokens, 0));
1521 sw2 = atoi(g_slist_nth_data(tokens, 1));
1523 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1524 result = TEL_SMS_RESULT_SUCCESS;
1527 result = TEL_SMS_RESULT_FAILURE;
1530 tcore_at_tok_free(tokens);
1532 err("Response NOK");
1535 /* Invoke callback */
1536 if (resp_cb_data->cb)
1537 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1539 /* Free callback data */
1540 imc_destroy_resp_cb_data(resp_cb_data);
1543 static gboolean async_callback(gpointer data)
1545 ImcRespCbData *resp_cb_data = data;
1547 TelSmsResult result = TEL_SMS_RESULT_SUCCESS;
1549 co = ((CoreObject **)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data));
1551 /* Invoke callback */
1552 if (resp_cb_data->cb)
1553 resp_cb_data->cb(*co, (gint)result, NULL, resp_cb_data->cb_data);
1555 /* Free callback data */
1556 imc_destroy_resp_cb_data(resp_cb_data);
1561 /* SMS Operations */
1563 * Operation - send_sms
1566 * AT-Command: AT+CMGS
1567 * For PDU mode (+CMGF=0):
1568 * +CMGS=<length><CR>
1569 * PDU is given<ctrl-Z/ESC>
1571 * <length> Length of the pdu.
1572 * <PDU> PDU to send.
1575 *+CMGS: <mr>[,<ackpdu>]
1578 * +CMS ERROR: <error>
1580 static TelReturn imc_sms_send_sms(CoreObject *co,
1581 const TelSmsSendInfo *send_info, TcoreObjectResponseCallback cb, void *cb_data)
1585 ImcRespCbData *resp_cb_data;
1588 const unsigned char *tpdu_byte_data;
1589 gint tpdu_byte_len, pdu_byte_len;
1590 char buf[HEX_PDU_LEN_MAX];
1591 char pdu[PDU_LEN_MAX];
1594 tpdu_byte_data = send_info->send_data.tpdu;
1596 /* TPDU length is in byte */
1597 tpdu_byte_len = send_info->send_data.tpdu_length;
1599 /* Use same Radio Resource Channel :More Messages to send*/
1600 dbg("More messages: [%d]", send_info->more_msgs);
1602 /* Prepare PDU for hex encoding */
1603 pdu_byte_len = tcore_util_encode_pdu(&(send_info->send_data.sca),
1604 tpdu_byte_data, tpdu_byte_len, pdu);
1605 tcore_util_hex_dump(" ", pdu_byte_len, pdu);
1607 tcore_util_encode_hex((unsigned char *)pdu, pdu_byte_len, buf);
1609 /* Response callback data */
1610 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1612 if (send_info->more_msgs == TRUE) {
1613 /* AT Command: More Msgs to Send */
1614 ret = tcore_at_prepare_and_send_request(co,
1615 "AT+CMMS=1", "+CMMS:",
1616 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1618 on_response_imc_sms_send_more_msg, NULL,
1619 on_send_imc_request, NULL);
1620 IMC_CHECK_REQUEST_RET(ret, NULL, "More Msgs to Send");
1623 /* AT-Command : Send SMS*/
1624 at_cmd = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
1626 /* Send Request to modem */
1627 ret = tcore_at_prepare_and_send_request(co,
1629 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1631 on_response_imc_sms_send_sms, resp_cb_data,
1632 on_send_imc_request, NULL);
1633 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send SMS");
1635 /* Free resources */
1642 * Operation - write_sms_in_sim
1645 * AT-Command: AT+CMGW
1646 * AT+CMGW = <length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
1648 * <length> length of the tpdu
1649 * <stat> status of the message
1650 * <PDU> PDu of the message
1654 * Success: (Single line)
1657 * +CMS ERROR: <error>
1659 static TelReturn imc_sms_write_sms_in_sim(CoreObject *co,
1660 const TelSmsSimDataInfo *wdata, TcoreObjectResponseCallback cb, void *cb_data)
1664 ImcRespCbData *resp_cb_data;
1667 const unsigned char *tpdu_byte_data;
1668 int tpdu_byte_len, pdu_byte_len;
1669 char buf[HEX_PDU_LEN_MAX];
1670 char hex_pdu[PDU_LEN_MAX];
1674 switch (wdata->status) {
1675 case TEL_SMS_STATUS_MT_UNREAD:
1676 status = AT_MT_UNREAD;
1679 case TEL_SMS_STATUS_MT_READ:
1680 status = AT_MT_READ;
1683 case TEL_SMS_STATUS_MO_NOT_SENT:
1684 status = AT_MO_UNSENT;
1687 case TEL_SMS_STATUS_MO_SENT:
1688 status = AT_MO_SENT;
1692 err("Invalid Message Status");
1693 return TEL_RETURN_INVALID_PARAMETER;
1695 tpdu_byte_data = wdata->data.tpdu;
1697 tpdu_byte_len = wdata->data.tpdu_length;
1698 dbg("TDPU length: [%d]", tpdu_byte_len);
1700 /* Prepare PDU for hex encoding */
1701 pdu_byte_len = tcore_util_encode_pdu(&(wdata->data.sca),
1702 tpdu_byte_data, tpdu_byte_len, hex_pdu);
1703 tcore_util_hex_dump(" ", pdu_byte_len, hex_pdu);
1705 tcore_util_encode_hex((unsigned char *)hex_pdu, pdu_byte_len, buf);
1708 at_cmd = g_strdup_printf("AT+CMGW=%d,%d%c%s%c",
1709 tpdu_byte_len, status, CR, buf, CTRL_Z);
1711 /* Response callback data */
1712 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1714 /* Send Request to modem */
1715 ret = tcore_at_prepare_and_send_request(co,
1717 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1719 on_response_imc_sms_write_sms_in_sim, resp_cb_data,
1720 on_send_imc_request, NULL);
1721 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Write SMS in SIM");
1723 /* Free resources */
1730 * Operation - read_sms_in_sim
1733 * AT-Command: At+CMGR=<index>
1735 * <index> index of the message to be read.
1738 * Success: (PDU: Multi-line output)
1739 * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
1742 * +CMS ERROR: <error>
1744 static TelReturn imc_sms_read_sms_in_sim(CoreObject *co,
1745 unsigned int index, TcoreObjectResponseCallback cb, void *cb_data)
1749 ImcRespCbData *resp_cb_data;
1754 at_cmd = g_strdup_printf("AT+CMGR=%d", index);
1756 /* Response callback data */
1757 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, ZERO);
1759 /* Send Request to modem */
1760 ret = tcore_at_prepare_and_send_request(co,
1762 TCORE_AT_COMMAND_TYPE_PDU,
1764 on_response_imc_sms_read_sms_in_sim, resp_cb_data,
1765 on_send_imc_request, NULL);
1766 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read SMS in SIM");
1768 /* Free resources */
1775 * Operation - delete_sms_in_sim
1778 * AT-Command: AT+CGMD
1779 * +CMGD=<index>[,<delflag>]
1782 * Success: (NO RESULT) -
1785 * +CMS ERROR: <error>
1787 static TelReturn imc_sms_delete_sms_in_sim(CoreObject *co,
1789 TcoreObjectResponseCallback cb, void *cb_data)
1793 ImcRespCbData *resp_cb_data;
1797 /* Response callback data */
1798 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1800 * TODO: Delete All Messages
1802 * at_cmd = g_strdup_printf("AT+CMGD=0,4");
1803 * Need to convey MSG_SERVICE to pass an index of
1804 * guint value to delete all Messages.probably as 0.
1808 at_cmd = g_strdup_printf("AT+CMGD=%d,0", index); /*Delete specified index*/
1810 /* Send Request to modem */
1811 ret = tcore_at_prepare_and_send_request(co,
1813 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1815 on_response_imc_sms_delete_sms_in_sim, resp_cb_data,
1816 on_send_imc_request, NULL);
1817 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete SMS in SIM");
1819 /* Free resources */
1826 * Operation - get_sms_count_in_sim
1829 * AT-Command: AT+CPMS
1830 * +CPMS=<mem1>[, <mem2>[,<mem3>]]
1832 * <mem1> memory storage to read.
1835 * Success: (Single-line output)
1836 * +CPMS: <mem1>,<used1>,<total1>,<mem2>,<used2>,<total2>,
1837 * <mem3>,<used3>,<total3>
1841 * +CMS ERROR: <error>
1843 static TelReturn imc_sms_get_msg_count_in_sim(CoreObject *co,
1844 TcoreObjectResponseCallback cb, void *cb_data)
1848 ImcRespCbData *resp_cb_data;
1853 at_cmd = g_strdup_printf("AT+CPMS=\"SM\"");
1855 /* Response callback data */
1856 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1858 /* Send Request to modem */
1859 ret = tcore_at_prepare_and_send_request(co,
1861 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1863 on_response_imc_sms_get_sms_count, resp_cb_data,
1864 on_send_imc_request, NULL);
1865 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Count");
1867 /* Free resources */
1874 * Operation - set SCA
1877 * AT-Command: AT+CSCA
1878 * AT+CSCA=<sca>[,<tosca>]
1880 * <sca> Service center number
1881 * <tosca> address type of SCA
1884 * Success: No result
1888 * +CMS ERROR: <error>
1890 static TelReturn imc_sms_set_sca(CoreObject *co,
1891 const TelSmsSca *sca, TcoreObjectResponseCallback cb, void *cb_data)
1895 ImcRespCbData *resp_cb_data;
1899 address_type = ((sca->ton << 4) | sca->npi ) | 0x80;
1902 at_cmd = g_strdup_printf("AT+CSCA=\"%s\",%d", sca->number, address_type);
1904 /* Response callback data */
1905 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1907 /* Send Request to modem */
1908 ret = tcore_at_prepare_and_send_request(co,
1910 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1912 on_response_imc_sms_set_sca, resp_cb_data,
1913 on_send_imc_request, NULL);
1914 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SCA");
1916 /* Free resources */
1923 * Operation - get SCA
1926 * AT-Command: AT+CSCA?
1929 * Success: Single-Line
1930 * +CSCA: <sca>,<tosca>
1933 * <sca> Service center number
1934 * <tosca> address type of SCA
1937 static TelReturn imc_sms_get_sca(CoreObject *co,
1938 TcoreObjectResponseCallback cb, void *cb_data)
1942 ImcRespCbData *resp_cb_data;
1947 at_cmd = g_strdup_printf("AT+CSCA?");
1949 /* Response callback data */
1950 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1952 /* Send Request to modem */
1953 ret = tcore_at_prepare_and_send_request(co,
1955 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1957 on_response_imc_sms_get_sca, resp_cb_data,
1958 on_send_imc_request, NULL);
1959 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SCA");
1961 /* Free resources */
1968 * Operation - set_cb_config
1971 * AT-Command: AT+CSCB
1972 * +CSCB=[<mode>[,<mids>[,<dcss>]]]
1979 * +CME ERROR: <error>
1981 static TelReturn imc_sms_set_cb_config(CoreObject *co,
1982 const TelSmsCbConfigInfo *cb_conf,
1983 TcoreObjectResponseCallback cb, void *cb_data)
1987 ImcRespCbData *resp_cb_data;
1990 unsigned short ctr1 = 0, ctr2 = 0, msg_id_range = 0;
1991 unsigned short append_msg_id = 0;
1994 if (cb_conf->msg_id_range_cnt != 0) { /* Enable Specific Msgid's */
1995 gchar *mids_str = NULL;
1996 GString *mid_string = NULL;
1999 mid_string = g_string_new("AT+CSCB=0,\"");
2000 for(ctr1 = 0; ctr1 < cb_conf->msg_id_range_cnt; ctr1++) {
2001 if (cb_conf->msg_ids[ctr1].selected == FALSE)
2003 msg_id_range = ((cb_conf->msg_ids[ctr1].to_msg_id) - (cb_conf->msg_ids[ctr1].from_msg_id));
2005 if (TEL_SMS_GSM_CBMI_LIST_SIZE_MAX <= msg_id_range) {
2006 mid_string = g_string_new("AT+CSCB=1"); /* Enable All CBS */
2009 append_msg_id = cb_conf->msg_ids[ctr1].from_msg_id;
2010 dbg( "%x", append_msg_id);
2012 for(ctr2 = 0; ctr2 <= msg_id_range; ctr2++) {
2013 mid_string = g_string_append(mid_string, g_strdup_printf("%d", append_msg_id));
2014 if (ctr2 == msg_id_range) {
2015 mid_string = g_string_append(mid_string, "\""); /*Mids string termination*/
2018 mid_string = g_string_append(mid_string, ",");
2023 mids_str = g_string_free(mid_string, FALSE);
2024 at_cmd = g_strdup_printf("%s", mids_str);
2028 at_cmd = g_strdup_printf("AT+CSCB=%d", cb_conf->cb_enabled); /* Enable or Disable MsgId's */
2031 /* Response callback data */
2032 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2034 /* Send Request to modem */
2035 ret = tcore_at_prepare_and_send_request(co,
2037 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2039 on_response_imc_sms_set_cb_config, resp_cb_data,
2040 on_send_imc_request, NULL);
2041 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Cb Config");
2043 /* Free resources */
2050 * Operation - get_cb_config
2053 * AT-Command: AT+CSCB
2057 * Success - (Single line)
2058 * +CSCB : <mode>,<mids>,<dcss>
2062 static TelReturn imc_sms_get_cb_config(CoreObject *co,
2063 TcoreObjectResponseCallback cb, void *cb_data)
2067 ImcRespCbData *resp_cb_data;
2072 at_cmd = g_strdup_printf("AT+CSCB?");
2074 /* Response callback data */
2075 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2077 /* Send Request to modem */
2078 ret = tcore_at_prepare_and_send_request(co,
2080 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2082 on_response_imc_sms_get_cb_config, resp_cb_data,
2083 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,
2157 on_response_imc_sms_set_memory_status, resp_cb_data,
2158 on_send_imc_request, NULL);
2159 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Memory Status");
2161 /* Free resources */
2167 /* Operation - set Message status
2170 * AT-Command: AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2172 * p3 SMSP record length
2175 * Response -Single Line
2180 * +CME ERROR: <error>
2182 static TelReturn imc_sms_set_message_status(CoreObject *co,
2183 const TelSmsStatusInfo *status_info,
2184 TcoreObjectResponseCallback cb, void *cb_data)
2188 ImcRespCbData *resp_cb_data;
2192 at_cmd = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d",
2193 (status_info->index), IMC_AT_EF_SMS_RECORD_LEN);
2195 /* Response callback data */
2196 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2197 (void *)status_info, sizeof(TelSmsStatusInfo));
2199 /* Send Request to modem */
2200 ret = tcore_at_prepare_and_send_request(co,
2202 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2204 _response_get_efsms_data, resp_cb_data,
2205 on_send_imc_request, NULL);
2206 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Message Status");
2208 /* Free resources */
2215 * Operation - get_sms_parameters
2218 * AT-Command: AT+CRSM
2219 * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2222 * Success: (Single-line output)
2224 * <sw1>,<sw2>[,<response>]
2228 * +CME ERROR: <error>
2230 static TelReturn imc_sms_get_sms_params(CoreObject *co,
2231 TcoreObjectResponseCallback cb, void *cb_data)
2233 TcorePlugin *plugin;
2234 ImcRespCbData *resp_cb_data;
2235 ImcSmsParamsCbData params_req_data = {0, };
2236 gint loop_count, record_count = 0, smsp_record_len = 0;
2240 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
2244 plugin = tcore_object_ref_plugin(co);
2246 /* Get Record count and SMSP record length*/
2247 if (FALSE == (imc_sim_get_smsp_info(plugin, &record_count,
2248 &smsp_record_len))) {
2249 err("Failed to get SMSP record Count and Record length");
2253 dbg("Record Count: [%d] SMSP Record Length: [%d]",
2254 record_count, smsp_record_len);
2256 /* Allocate Memory for params list data */
2257 params_req_data.params = tcore_malloc0(sizeof(TelSmsParamsInfo) * record_count);
2259 params_req_data.total_param_count = record_count;
2261 /* Actual count to be returned */
2262 params_req_data.record_count = record_count;
2263 /* SMSP record length */
2264 params_req_data.record_length = smsp_record_len;
2266 /* Response callback data */
2267 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2268 (void *)¶ms_req_data,
2269 sizeof(ImcSmsParamsCbData));
2271 /* Starting the Index with 1 */
2272 params_req_data.index = 1;
2275 at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
2276 params_req_data.index, params_req_data.record_length);
2278 /* Send Request to modem */
2279 ret = tcore_at_prepare_and_send_request(co,
2281 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2283 on_response_imc_sms_get_sms_params, resp_cb_data,
2284 on_send_imc_request, NULL);
2285 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Parameters");
2287 /* Free resources */
2288 if (ret != TEL_RETURN_SUCCESS)
2289 tcore_free(params_req_data.params);
2296 * Operation - set_sms_params
2299 * AT-Command: AT+CRSM
2300 * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2303 * Success: (Single-line output)
2305 * <sw1>,<sw2>[,<response>]
2309 * +CME ERROR: <error>
2311 static TelReturn imc_sms_set_sms_params(CoreObject *co,
2312 const TelSmsParamsInfo *params,
2313 TcoreObjectResponseCallback cb, void *cb_data)
2316 ImcRespCbData *resp_cb_data;
2319 TcorePlugin *plugin;
2320 gint smsp_record_len = 0;
2321 gchar *set_params_data = NULL;
2322 gchar *encoded_data = NULL;
2326 plugin = tcore_object_ref_plugin(co);
2328 if (FALSE == imc_sim_get_smsp_info(plugin, &record_count, &smsp_record_len)) {
2329 err("Failed to get SMSP record Count and Record length");
2330 return TEL_RETURN_INVALID_PARAMETER;
2333 dbg("SMSP Record Length: [%d]", smsp_record_len);
2335 /* Allocate memory for set_params_data */
2336 set_params_data = tcore_malloc0(sizeof(smsp_record_len));
2338 /* Allocate memory for encoded data*/
2339 encoded_data = tcore_malloc0((2 * sizeof(smsp_record_len)+1));
2341 tcore_util_encode_sms_parameters((TelSmsParamsInfo *)params,
2342 set_params_data, smsp_record_len);
2343 dbg("SCA Address: [%s]", params->sca.number);
2345 tcore_util_byte_to_hex((const char *)set_params_data,
2346 (char *)encoded_data, smsp_record_len);
2348 /* Response callback data */
2349 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, sizeof(gint));
2352 at_cmd = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",
2353 params->index, smsp_record_len, encoded_data);
2354 dbg("at_cmd - %s", at_cmd);
2355 /* Send Request to modem */
2356 ret = tcore_at_prepare_and_send_request(co,
2358 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2360 on_response_imc_sms_set_sms_params, resp_cb_data,
2361 on_send_imc_request, NULL);
2362 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SMS Parameters");
2364 /* Free resources */
2366 g_free(set_params_data);
2367 g_free(encoded_data);
2372 /* SMS Operations */
2373 static TcoreSmsOps imc_sms_ops = {
2374 .send_sms = imc_sms_send_sms,
2375 .read_in_sim = imc_sms_read_sms_in_sim,
2376 .write_in_sim = imc_sms_write_sms_in_sim,
2377 .delete_in_sim = imc_sms_delete_sms_in_sim,
2378 .get_count = imc_sms_get_msg_count_in_sim,
2379 .set_cb_config = imc_sms_set_cb_config,
2380 .get_cb_config = imc_sms_get_cb_config,
2381 .get_parameters = imc_sms_get_sms_params,
2382 .set_parameters = imc_sms_set_sms_params,
2383 .send_deliver_report = imc_sms_send_deliver_report,
2384 .set_sca = imc_sms_set_sca,
2385 .get_sca = imc_sms_get_sca,
2386 .set_memory_status = imc_sms_set_memory_status,
2387 .set_message_status = imc_sms_set_message_status
2390 gboolean imc_sms_init(TcorePlugin *p, CoreObject *co)
2394 /* Set operations */
2395 tcore_sms_set_ops(co, &imc_sms_ops);
2398 tcore_object_add_callback(co, "\e+CMT:",
2399 on_notification_imc_sms_incoming_msg, NULL);
2400 tcore_object_add_callback(co, "\e+CDS",
2401 on_notification_imc_sms_incoming_msg, NULL);
2403 tcore_object_add_callback(co, "\e+CBM",
2404 on_notification_imc_sms_cb_incom_msg, NULL);
2405 tcore_object_add_callback(co, "+CMTI",
2406 on_notification_imc_sms_class2_incoming_msg, NULL);
2410 * TODO - AT Command Description Not available
2412 tcore_object_add_callback(co, "+XSMSMMSTAT",
2413 on_notification_imc_sms_memory_status, NULL);
2419 void imc_sms_exit(TcorePlugin *p, CoreObject *co)