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;
999 line = (char *)at_resp->lines->data;
1000 tokens = tcore_at_tok_new(line);
1001 sca_tok_addr = g_slist_nth_data(tokens, 0);
1002 sca_toa = g_slist_nth_data(tokens, 1);
1004 sca_addr = tcore_at_tok_extract(sca_tok_addr);
1005 dbg("SCA: [%s] SCA-TOA: [%s]", sca_addr, sca_toa);
1006 if ((NULL != sca_addr) && (NULL != sca_toa)) {
1007 memcpy(sca_resp.number, sca_addr, strlen(sca_addr));
1009 hexa_toa = atoi(sca_toa);
1010 dbg("SCA-TOA: [0x%x]", hexa_toa);
1011 sca_resp.npi = hexa_toa & 0x0F;
1012 sca_resp.ton = (hexa_toa & 0x70) >> 4;
1013 result = TEL_SMS_RESULT_SUCCESS;
1018 tcore_at_tok_free(tokens);
1022 err("Invalid Response.No Lines Received");
1026 err("Response NOK");
1029 /* Invoke callback */
1030 if (resp_cb_data->cb)
1031 resp_cb_data->cb(co, (gint)result, &sca_resp, resp_cb_data->cb_data);
1033 /* Free callback data */
1034 imc_destroy_resp_cb_data(resp_cb_data);
1037 static void on_response_imc_sms_set_cb_config(TcorePending *p,
1038 guint data_len, const void *data, void *user_data)
1040 const TcoreAtResponse *at_resp = data;
1041 CoreObject *co = tcore_pending_ref_core_object(p);
1042 ImcRespCbData *resp_cb_data = user_data;
1044 TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CME error mapping required */
1047 if (at_resp && at_resp->success) {
1049 result = TEL_SMS_RESULT_SUCCESS;
1052 err("Response NOK");
1055 /* Invoke callback */
1056 if (resp_cb_data->cb)
1057 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1059 /* Free callback data */
1060 imc_destroy_resp_cb_data(resp_cb_data);
1063 static void on_response_imc_sms_get_cb_config(TcorePending *p,
1064 guint data_len, const void *data, void *user_data)
1066 const TcoreAtResponse *at_resp = data;
1067 CoreObject *co = tcore_pending_ref_core_object(p);
1068 ImcRespCbData *resp_cb_data = user_data;
1070 GSList *cb_tokens = NULL;
1071 char *cb_str_token = NULL;
1072 int num_cb_tokens = 0;
1073 char *mid_tok = NULL;
1074 char *first_tok = NULL, *second_tok = NULL;
1075 gint i = 0, mode = 0;
1078 TelSmsCbConfigInfo get_cb_conf = {0, };
1079 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1082 if (at_resp && at_resp->success) {
1084 if (at_resp->lines) {
1085 GSList *tokens = NULL;
1086 char *line_token = NULL, *line = NULL;
1087 line = (char*)at_resp->lines->data;
1089 tokens = tcore_at_tok_new(line);
1092 * +CSCB: <mode>,<mids>,<dcss>
1094 line_token = g_slist_nth_data(tokens, 0);
1096 mode = atoi(line_token);
1097 dbg("mode:[%d]", mode);
1098 get_cb_conf.cb_enabled = mode;
1101 err("Line Token for Mode is NULL");
1102 tcore_at_tok_free(tokens);
1105 line_token = g_slist_nth_data(tokens, 1);
1107 cb_str_token = tcore_at_tok_extract(line_token);
1108 cb_tokens = tcore_at_tok_new((const char *)cb_str_token);
1110 num_cb_tokens = g_slist_length(cb_tokens);
1111 dbg("num_cb_tokens = %d", num_cb_tokens);
1112 if (num_cb_tokens == 0) {
1113 if (mode == 1) { /* All CBS Enabled */
1114 get_cb_conf.msg_id_range_cnt = 1;
1115 get_cb_conf.msg_ids[0].from_msg_id = 0x0000;
1116 get_cb_conf.msg_ids[0].to_msg_id = TEL_SMS_GSM_CBMI_LIST_SIZE_MAX + 1;
1117 get_cb_conf.msg_ids[0].selected = TRUE;
1119 else { /* All CBS Disabled */
1120 get_cb_conf.msg_id_range_cnt = 0;
1121 get_cb_conf.msg_ids[0].selected = FALSE;
1125 for(i = 0; i < num_cb_tokens; i++) {
1126 get_cb_conf.msg_ids[i].selected = TRUE;
1127 dbg("msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
1128 get_cb_conf.msg_id_range_cnt++;
1129 dbg("Incremented msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
1131 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1132 first_tok = strtok(mid_tok, delim);
1133 second_tok = strtok(NULL, delim);
1135 if ((first_tok != NULL) && (second_tok != NULL)) {/* mids in range (320-478) */
1136 get_cb_conf.msg_ids[i].from_msg_id = atoi(first_tok);
1137 get_cb_conf.msg_ids[i].to_msg_id = atoi(second_tok);
1139 else {/* single mid value (0,1,5, 922)*/
1140 get_cb_conf.msg_ids[i].from_msg_id = atoi(mid_tok);
1141 get_cb_conf.msg_ids[i].to_msg_id = atoi(mid_tok);
1146 err("Line Token for MID is NULL");
1147 tcore_at_tok_free(tokens);
1152 err("Line is NULL");
1154 result = TEL_SMS_RESULT_SUCCESS;
1155 tcore_at_tok_free(tokens);
1156 tcore_at_tok_free(cb_tokens);
1157 g_free(cb_str_token);
1160 err("Invalid Response.No Lines Received");
1164 err("Response NOK");
1168 /* Invoke callback */
1169 if (resp_cb_data->cb)
1170 resp_cb_data->cb(co, (gint)result, &get_cb_conf, resp_cb_data->cb_data);
1172 /* Free callback data */
1173 imc_destroy_resp_cb_data(resp_cb_data);
1176 static void on_response_imc_sms_set_memory_status(TcorePending *p,
1177 guint data_len, const void *data, void *user_data)
1179 const TcoreAtResponse *at_resp = data;
1180 CoreObject *co = tcore_pending_ref_core_object(p);
1181 ImcRespCbData *resp_cb_data = user_data;
1183 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1186 if (at_resp && at_resp->success) {
1188 result = TEL_SMS_RESULT_SUCCESS;
1191 err("Response NOK");
1194 /* Invoke callback */
1195 if (resp_cb_data->cb)
1196 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1198 /* Free callback data */
1199 imc_destroy_resp_cb_data(resp_cb_data);
1202 static void on_response_imc_sms_set_message_status(TcorePending *p,
1203 guint data_len, const void *data, void *user_data)
1205 const TcoreAtResponse *at_resp = data;
1206 CoreObject *co = tcore_pending_ref_core_object(p);
1207 ImcRespCbData *resp_cb_data = user_data;
1209 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1210 int response = 0, sw1 = 0, sw2 = 0;
1211 const char *line = NULL;
1212 char *line_token = NULL;
1213 GSList *tokens = NULL;
1216 if (at_resp && at_resp->success) {
1218 if (at_resp->lines) {
1219 line = (const char *) at_resp->lines->data;
1220 tokens = tcore_at_tok_new(line);
1221 line_token = g_slist_nth_data(tokens, 0);
1222 if (line_token != NULL) {
1223 sw1 = atoi(line_token);
1228 line_token = g_slist_nth_data(tokens, 1);
1229 if (line_token != NULL) {
1230 sw2 = atoi(line_token);
1231 if ((sw1 == 0x90) && (sw2 == 0)) {
1232 result = TEL_SMS_RESULT_SUCCESS;
1238 line_token = g_slist_nth_data(tokens, 3);
1240 if (line_token != NULL) {
1241 response = atoi(line_token);
1242 dbg("response is %s", response);
1244 tcore_at_tok_free(tokens);
1251 err("RESPONSE NOK");
1254 /* Invoke callback */
1255 if (resp_cb_data->cb)
1256 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1258 /* Free callback data */
1259 imc_destroy_resp_cb_data(resp_cb_data);
1262 static void _response_get_efsms_data(TcorePending *p,
1263 guint data_len, const void *data, void *user_data)
1266 const TcoreAtResponse *at_resp = data;
1267 CoreObject *co = tcore_pending_ref_core_object(p);
1268 ImcRespCbData *resp_cb_data = user_data;
1270 TelSmsStatusInfo *status_info;
1271 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1274 char *encoded_data = NULL;
1275 int encoded_len = 0;
1276 char msg_status = 0;
1277 char *line_token = NULL;
1278 GSList *tokens=NULL;
1279 const char *line = NULL;
1284 status_info = (TelSmsStatusInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1285 if (at_resp && at_resp->success) {
1287 if (at_resp->lines) {
1288 dbg("Entry:lines Ok");
1289 line = (const char *) at_resp->lines->data;
1290 tokens = tcore_at_tok_new(line);
1292 sw1 = atoi(g_slist_nth_data(tokens, 0));
1293 sw2 = atoi(g_slist_nth_data(tokens, 1));
1294 line_token = g_slist_nth_data(tokens, 2);
1296 dbg("line_token:[%s], Length of line token:[%d]", line_token, strlen(line_token));
1298 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1299 switch (status_info->status) {
1300 case TEL_SMS_STATUS_MT_READ:
1304 case TEL_SMS_STATUS_MT_UNREAD:
1308 case TEL_SMS_STATUS_MO_NOT_SENT:
1312 case TEL_SMS_STATUS_MO_SENT:
1316 case TEL_SMS_STATUS_MO_DELIVERED:
1320 case TEL_SMS_STATUS_MO_DELIVERY_NOT_CONFIRMED:
1324 case TEL_SMS_STATUS_REPLACED:/*Fall Through*/
1330 encoded_len = strlen(line_token);
1331 dbg("Encoded data length:[%d]", encoded_len);
1333 encoded_data = tcore_malloc0(2*encoded_len + 1);
1335 memcpy(encoded_data, line_token, encoded_len);
1336 dbg("encoded_data: [%s]", encoded_data);
1338 /* overwrite Status byte information */
1339 tcore_util_byte_to_hex((const char *)&msg_status, encoded_data, 1);
1342 * Updating EF-SMS File with status byte
1343 * Rest 175 bytes are same as received in Read Record
1346 at_cmd = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"",
1347 (status_info->index), IMC_AT_EF_SMS_RECORD_LEN, encoded_data);
1349 /* Send Request to modem */
1350 ret = tcore_at_prepare_and_send_request(co,
1352 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1354 on_response_imc_sms_set_message_status, resp_cb_data,
1355 on_send_imc_request, NULL);
1356 IMC_CHECK_REQUEST_RET(ret, resp_cb_data,
1357 "Set Message Status-Updating status in Record");
1359 g_free(encoded_data);
1360 g_free(status_info);
1361 tcore_at_tok_free(tokens);
1365 err("Invalid Response Received");
1369 err("Response NOK");
1372 /* Invoke callback */
1373 if (resp_cb_data->cb)
1374 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1376 /* Free callback data */
1377 imc_destroy_resp_cb_data(resp_cb_data);
1380 static void on_response_imc_sms_get_sms_params(TcorePending *p,
1381 guint data_len, const void *data, void *user_data)
1383 const TcoreAtResponse *at_resp = data;
1384 CoreObject *co = tcore_pending_ref_core_object(p);
1385 ImcRespCbData *resp_cb_data = user_data;
1386 ImcSmsParamsCbData *params_req_data;
1387 gint sw1 = 0, sw2 = 0, decoding_length = 0;
1388 const char *line = NULL;
1389 char *hex_data = NULL, *record_data = NULL;
1390 GSList *tokens = NULL;
1392 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1395 params_req_data = (ImcSmsParamsCbData *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1397 if (at_resp && at_resp->success) {
1399 if (at_resp->lines) {
1400 line = (const char *) at_resp->lines->data;
1401 tokens = tcore_at_tok_new(line);
1403 sw1 = atoi(g_slist_nth_data(tokens, 0));
1404 sw2 = atoi(g_slist_nth_data(tokens, 1));
1405 dbg("sw1 [0x%x], sw2[0x%x]", sw1, sw2);
1407 if (!(sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1408 err("invalid response received");
1412 hex_data = g_slist_nth_data(tokens, 2);
1413 if (hex_data == NULL) {
1414 err("invalid response received");
1417 hex_data = tcore_at_tok_extract((const gchar *)hex_data);
1419 tcore_util_hexstring_to_bytes(hex_data, &record_data, (guint*)&decoding_length);
1420 tcore_free(hex_data);
1422 * Decrementing the Record Count and Filling the ParamsInfo List
1423 * Final Response will be posted when Record count is ZERO
1425 params_req_data->params[params_req_data->index].index = params_req_data->index;
1427 tcore_util_decode_sms_parameters((unsigned char *)record_data,
1429 ¶ms_req_data->params[params_req_data->index]);
1431 params_req_data->total_param_count -= 1;
1433 if (params_req_data->total_param_count == 0) {
1434 dbg("Reading all Records - Complete");
1435 result = TEL_SMS_RESULT_SUCCESS;
1441 dbg("Reading all records incomplete [Pending - %d]",
1442 params_req_data->total_param_count);
1444 params_req_data->index++;
1447 at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
1448 params_req_data->index, params_req_data->record_length);
1450 /* Send Request to modem */
1451 ret = tcore_at_prepare_and_send_request(co,
1453 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1455 on_response_imc_sms_get_sms_params, resp_cb_data,
1456 on_send_imc_request, NULL);
1459 if (ret != TEL_RETURN_SUCCESS) {
1460 err("Failed to process request - [%s]", "Get SMS Parameters");
1464 tcore_at_tok_free(tokens);
1468 err("Invalid Response Received");
1471 err("RESPONSE NOK");
1476 TelSmsParamsInfoList param_info_list = {0, };
1478 if (result == TEL_SMS_RESULT_SUCCESS) {
1479 param_info_list.params = params_req_data->params;
1480 param_info_list.count = params_req_data->record_count;
1483 /* Invoke callback */
1484 if (resp_cb_data->cb)
1485 resp_cb_data->cb(co, (gint)result, (void *)¶m_info_list, resp_cb_data->cb_data);
1489 tcore_at_tok_free(tokens);
1491 tcore_free(params_req_data->params);
1492 g_free(record_data);
1494 /* Free callback data */
1495 imc_destroy_resp_cb_data(resp_cb_data);
1498 static void on_response_imc_sms_set_sms_params(TcorePending *p,
1499 guint data_len, const void *data, void *user_data)
1501 const TcoreAtResponse *at_resp = data;
1502 CoreObject *co = tcore_pending_ref_core_object(p);
1503 ImcRespCbData *resp_cb_data = user_data;
1505 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1506 gint sw1 = 0 , sw2 = 0;
1507 const char *line = NULL;
1508 GSList *tokens=NULL;
1511 if (at_resp && at_resp->success) {
1513 if (at_resp->lines) {
1514 line = (const char *) at_resp->lines->data;
1515 tokens = tcore_at_tok_new(line);
1517 sw1 = atoi(g_slist_nth_data(tokens, 0));
1518 sw2 = atoi(g_slist_nth_data(tokens, 1));
1520 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1521 result = TEL_SMS_RESULT_SUCCESS;
1524 result = TEL_SMS_RESULT_FAILURE;
1527 tcore_at_tok_free(tokens);
1529 err("Response NOK");
1532 /* Invoke callback */
1533 if (resp_cb_data->cb)
1534 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1536 /* Free callback data */
1537 imc_destroy_resp_cb_data(resp_cb_data);
1540 static gboolean async_callback(gpointer data)
1542 ImcRespCbData *resp_cb_data = data;
1544 TelSmsResult result = TEL_SMS_RESULT_SUCCESS;
1546 co = ((CoreObject **)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data));
1548 /* Invoke callback */
1549 if (resp_cb_data->cb)
1550 resp_cb_data->cb(*co, (gint)result, NULL, resp_cb_data->cb_data);
1552 /* Free callback data */
1553 imc_destroy_resp_cb_data(resp_cb_data);
1558 /* SMS Operations */
1560 * Operation - send_sms
1563 * AT-Command: AT+CMGS
1564 * For PDU mode (+CMGF=0):
1565 * +CMGS=<length><CR>
1566 * PDU is given<ctrl-Z/ESC>
1568 * <length> Length of the pdu.
1569 * <PDU> PDU to send.
1572 *+CMGS: <mr>[,<ackpdu>]
1575 * +CMS ERROR: <error>
1577 static TelReturn imc_sms_send_sms(CoreObject *co,
1578 const TelSmsSendInfo *send_info, TcoreObjectResponseCallback cb, void *cb_data)
1582 ImcRespCbData *resp_cb_data;
1585 const unsigned char *tpdu_byte_data;
1586 gint tpdu_byte_len, pdu_byte_len;
1587 char buf[HEX_PDU_LEN_MAX];
1588 char pdu[PDU_LEN_MAX];
1591 tpdu_byte_data = send_info->send_data.tpdu;
1593 /* TPDU length is in byte */
1594 tpdu_byte_len = send_info->send_data.tpdu_length;
1596 /* Use same Radio Resource Channel :More Messages to send*/
1597 dbg("More messages: [%d]", send_info->more_msgs);
1599 /* Prepare PDU for hex encoding */
1600 pdu_byte_len = tcore_util_encode_pdu(&(send_info->send_data.sca),
1601 tpdu_byte_data, tpdu_byte_len, pdu);
1602 tcore_util_hex_dump(" ", pdu_byte_len, pdu);
1604 tcore_util_encode_hex((unsigned char *)pdu, pdu_byte_len, buf);
1606 /* Response callback data */
1607 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1609 if (send_info->more_msgs == TRUE) {
1610 /* AT Command: More Msgs to Send */
1611 ret = tcore_at_prepare_and_send_request(co,
1612 "AT+CMMS=1", "+CMMS:",
1613 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1615 on_response_imc_sms_send_more_msg, NULL,
1616 on_send_imc_request, NULL);
1617 IMC_CHECK_REQUEST_RET(ret, NULL, "More Msgs to Send");
1620 /* AT-Command : Send SMS*/
1621 at_cmd = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
1623 /* Send Request to modem */
1624 ret = tcore_at_prepare_and_send_request(co,
1626 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1628 on_response_imc_sms_send_sms, resp_cb_data,
1629 on_send_imc_request, NULL);
1630 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send SMS");
1632 /* Free resources */
1639 * Operation - write_sms_in_sim
1642 * AT-Command: AT+CMGW
1643 * AT+CMGW = <length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
1645 * <length> length of the tpdu
1646 * <stat> status of the message
1647 * <PDU> PDu of the message
1651 * Success: (Single line)
1654 * +CMS ERROR: <error>
1656 static TelReturn imc_sms_write_sms_in_sim(CoreObject *co,
1657 const TelSmsSimDataInfo *wdata, TcoreObjectResponseCallback cb, void *cb_data)
1661 ImcRespCbData *resp_cb_data;
1664 const unsigned char *tpdu_byte_data;
1665 int tpdu_byte_len, pdu_byte_len;
1666 char buf[HEX_PDU_LEN_MAX];
1667 char hex_pdu[PDU_LEN_MAX];
1671 switch (wdata->status) {
1672 case TEL_SMS_STATUS_MT_UNREAD:
1673 status = AT_MT_UNREAD;
1676 case TEL_SMS_STATUS_MT_READ:
1677 status = AT_MT_READ;
1680 case TEL_SMS_STATUS_MO_NOT_SENT:
1681 status = AT_MO_UNSENT;
1684 case TEL_SMS_STATUS_MO_SENT:
1685 status = AT_MO_SENT;
1689 err("Invalid Message Status");
1690 return TEL_RETURN_INVALID_PARAMETER;
1692 tpdu_byte_data = wdata->data.tpdu;
1694 tpdu_byte_len = wdata->data.tpdu_length;
1695 dbg("TDPU length: [%d]", tpdu_byte_len);
1697 /* Prepare PDU for hex encoding */
1698 pdu_byte_len = tcore_util_encode_pdu(&(wdata->data.sca),
1699 tpdu_byte_data, tpdu_byte_len, hex_pdu);
1700 tcore_util_hex_dump(" ", pdu_byte_len, hex_pdu);
1702 tcore_util_encode_hex((unsigned char *)hex_pdu, pdu_byte_len, buf);
1705 at_cmd = g_strdup_printf("AT+CMGW=%d,%d%c%s%c",
1706 tpdu_byte_len, status, CR, buf, CTRL_Z);
1708 /* Response callback data */
1709 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1711 /* Send Request to modem */
1712 ret = tcore_at_prepare_and_send_request(co,
1714 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1716 on_response_imc_sms_write_sms_in_sim, resp_cb_data,
1717 on_send_imc_request, NULL);
1718 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Write SMS in SIM");
1720 /* Free resources */
1727 * Operation - read_sms_in_sim
1730 * AT-Command: At+CMGR=<index>
1732 * <index> index of the message to be read.
1735 * Success: (PDU: Multi-line output)
1736 * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
1739 * +CMS ERROR: <error>
1741 static TelReturn imc_sms_read_sms_in_sim(CoreObject *co,
1742 unsigned int index, TcoreObjectResponseCallback cb, void *cb_data)
1746 ImcRespCbData *resp_cb_data;
1751 at_cmd = g_strdup_printf("AT+CMGR=%d", index);
1753 /* Response callback data */
1754 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, ZERO);
1756 /* Send Request to modem */
1757 ret = tcore_at_prepare_and_send_request(co,
1759 TCORE_AT_COMMAND_TYPE_PDU,
1761 on_response_imc_sms_read_sms_in_sim, resp_cb_data,
1762 on_send_imc_request, NULL);
1763 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read SMS in SIM");
1765 /* Free resources */
1772 * Operation - delete_sms_in_sim
1775 * AT-Command: AT+CGMD
1776 * +CMGD=<index>[,<delflag>]
1779 * Success: (NO RESULT) -
1782 * +CMS ERROR: <error>
1784 static TelReturn imc_sms_delete_sms_in_sim(CoreObject *co,
1786 TcoreObjectResponseCallback cb, void *cb_data)
1790 ImcRespCbData *resp_cb_data;
1794 /* Response callback data */
1795 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1797 * TODO: Delete All Messages
1799 * at_cmd = g_strdup_printf("AT+CMGD=0,4");
1800 * Need to convey MSG_SERVICE to pass an index of
1801 * guint value to delete all Messages.probably as 0.
1805 at_cmd = g_strdup_printf("AT+CMGD=%d,0", index); /*Delete specified index*/
1807 /* Send Request to modem */
1808 ret = tcore_at_prepare_and_send_request(co,
1810 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1812 on_response_imc_sms_delete_sms_in_sim, resp_cb_data,
1813 on_send_imc_request, NULL);
1814 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete SMS in SIM");
1816 /* Free resources */
1823 * Operation - get_sms_count_in_sim
1826 * AT-Command: AT+CPMS
1827 * +CPMS=<mem1>[, <mem2>[,<mem3>]]
1829 * <mem1> memory storage to read.
1832 * Success: (Single-line output)
1833 * +CPMS: <mem1>,<used1>,<total1>,<mem2>,<used2>,<total2>,
1834 * <mem3>,<used3>,<total3>
1838 * +CMS ERROR: <error>
1840 static TelReturn imc_sms_get_msg_count_in_sim(CoreObject *co,
1841 TcoreObjectResponseCallback cb, void *cb_data)
1845 ImcRespCbData *resp_cb_data;
1850 at_cmd = g_strdup_printf("AT+CPMS=\"SM\"");
1852 /* Response callback data */
1853 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1855 /* Send Request to modem */
1856 ret = tcore_at_prepare_and_send_request(co,
1858 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1860 on_response_imc_sms_get_sms_count, resp_cb_data,
1861 on_send_imc_request, NULL);
1862 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Count");
1864 /* Free resources */
1871 * Operation - set SCA
1874 * AT-Command: AT+CSCA
1875 * AT+CSCA=<sca>[,<tosca>]
1877 * <sca> Service center number
1878 * <tosca> address type of SCA
1881 * Success: No result
1885 * +CMS ERROR: <error>
1887 static TelReturn imc_sms_set_sca(CoreObject *co,
1888 const TelSmsSca *sca, TcoreObjectResponseCallback cb, void *cb_data)
1892 ImcRespCbData *resp_cb_data;
1896 address_type = ((sca->ton << 4) | sca->npi ) | 0x80;
1899 at_cmd = g_strdup_printf("AT+CSCA=\"%s\",%d", sca->number, address_type);
1901 /* Response callback data */
1902 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1904 /* Send Request to modem */
1905 ret = tcore_at_prepare_and_send_request(co,
1907 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1909 on_response_imc_sms_set_sca, resp_cb_data,
1910 on_send_imc_request, NULL);
1911 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SCA");
1913 /* Free resources */
1920 * Operation - get SCA
1923 * AT-Command: AT+CSCA?
1926 * Success: Single-Line
1927 * +CSCA: <sca>,<tosca>
1930 * <sca> Service center number
1931 * <tosca> address type of SCA
1934 static TelReturn imc_sms_get_sca(CoreObject *co,
1935 TcoreObjectResponseCallback cb, void *cb_data)
1939 ImcRespCbData *resp_cb_data;
1944 at_cmd = g_strdup_printf("AT+CSCA?");
1946 /* Response callback data */
1947 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1949 /* Send Request to modem */
1950 ret = tcore_at_prepare_and_send_request(co,
1952 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1954 on_response_imc_sms_get_sca, resp_cb_data,
1955 on_send_imc_request, NULL);
1956 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SCA");
1958 /* Free resources */
1965 * Operation - set_cb_config
1968 * AT-Command: AT+CSCB
1969 * +CSCB=[<mode>[,<mids>[,<dcss>]]]
1976 * +CME ERROR: <error>
1978 static TelReturn imc_sms_set_cb_config(CoreObject *co,
1979 const TelSmsCbConfigInfo *cb_conf,
1980 TcoreObjectResponseCallback cb, void *cb_data)
1984 ImcRespCbData *resp_cb_data;
1987 unsigned short ctr1 = 0, ctr2 = 0, msg_id_range = 0;
1988 unsigned short append_msg_id = 0;
1991 if (cb_conf->msg_id_range_cnt != 0) { /* Enable Specific Msgid's */
1992 gchar *mids_str = NULL;
1993 GString *mid_string = NULL;
1996 mid_string = g_string_new("AT+CSCB=0,\"");
1997 for(ctr1 = 0; ctr1 < cb_conf->msg_id_range_cnt; ctr1++) {
1998 if (cb_conf->msg_ids[ctr1].selected == FALSE)
2000 msg_id_range = ((cb_conf->msg_ids[ctr1].to_msg_id) - (cb_conf->msg_ids[ctr1].from_msg_id));
2002 if (TEL_SMS_GSM_CBMI_LIST_SIZE_MAX <= msg_id_range) {
2003 mid_string = g_string_new("AT+CSCB=1"); /* Enable All CBS */
2006 append_msg_id = cb_conf->msg_ids[ctr1].from_msg_id;
2007 dbg( "%x", append_msg_id);
2009 for(ctr2 = 0; ctr2 <= msg_id_range; ctr2++) {
2010 mid_string = g_string_append(mid_string, g_strdup_printf("%d", append_msg_id));
2011 if (ctr2 == msg_id_range) {
2012 mid_string = g_string_append(mid_string, "\""); /*Mids string termination*/
2015 mid_string = g_string_append(mid_string, ",");
2020 mids_str = g_string_free(mid_string, FALSE);
2021 at_cmd = g_strdup_printf("%s", mids_str);
2025 at_cmd = g_strdup_printf("AT+CSCB=%d", cb_conf->cb_enabled); /* Enable or Disable MsgId's */
2028 /* Response callback data */
2029 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2031 /* Send Request to modem */
2032 ret = tcore_at_prepare_and_send_request(co,
2034 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2036 on_response_imc_sms_set_cb_config, resp_cb_data,
2037 on_send_imc_request, NULL);
2038 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Cb Config");
2040 /* Free resources */
2047 * Operation - get_cb_config
2050 * AT-Command: AT+CSCB
2054 * Success - (Single line)
2055 * +CSCB : <mode>,<mids>,<dcss>
2059 static TelReturn imc_sms_get_cb_config(CoreObject *co,
2060 TcoreObjectResponseCallback cb, void *cb_data)
2064 ImcRespCbData *resp_cb_data;
2069 at_cmd = g_strdup_printf("AT+CSCB?");
2071 /* Response callback data */
2072 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2074 /* Send Request to modem */
2075 ret = tcore_at_prepare_and_send_request(co,
2077 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2079 on_response_imc_sms_get_cb_config, resp_cb_data,
2080 on_send_imc_request, NULL);
2081 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Cb Config");
2083 /* Free resources */
2090 * Operation - send_deliver_report
2093 * Modem Takes care of sending the ACK to the network
2096 * Success: Default response always SUCCESS posted
2099 static TelReturn imc_sms_send_deliver_report(CoreObject *co,
2100 const TelSmsDeliverReportInfo *dr_info,
2101 TcoreObjectResponseCallback cb, void *cb_data)
2103 ImcRespCbData *resp_cb_data;
2104 TelReturn ret = TEL_RETURN_FAILURE;
2106 dbg("CP takes care of sending SMS ack to network for all "
2107 "classes of SMS. Sending default success.!!!");
2108 ret = TEL_RETURN_SUCCESS;
2110 /* Response callback data */
2111 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2112 (void *)&co, sizeof(CoreObject*));
2114 g_idle_add(async_callback, (gpointer)resp_cb_data);
2120 /* Operation - set memory status
2123 * AT-Command: AT+XTESM=<mem_capacity>
2124 * <mem_capacity> status of the external SMS storage which may be:
2125 * 0: memory capacity free
2126 * 1: memory capacity full
2128 * Response -No Result
2133 * +CME ERROR: <error>
2135 static TelReturn imc_sms_set_memory_status(CoreObject *co,
2136 gboolean available, TcoreObjectResponseCallback cb, void *cb_data)
2140 ImcRespCbData *resp_cb_data;
2144 at_cmd = g_strdup_printf("AT+XTESM=%d", available? 0: 1);
2146 /* Response callback data */
2147 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2149 /* Send Request to modem */
2150 ret = tcore_at_prepare_and_send_request(co,
2152 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2154 on_response_imc_sms_set_memory_status, resp_cb_data,
2155 on_send_imc_request, NULL);
2156 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Memory Status");
2158 /* Free resources */
2164 /* Operation - set Message status
2167 * AT-Command: AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2169 * p3 SMSP record length
2172 * Response -Single Line
2177 * +CME ERROR: <error>
2179 static TelReturn imc_sms_set_message_status(CoreObject *co,
2180 const TelSmsStatusInfo *status_info,
2181 TcoreObjectResponseCallback cb, void *cb_data)
2185 ImcRespCbData *resp_cb_data;
2189 at_cmd = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d",
2190 (status_info->index), IMC_AT_EF_SMS_RECORD_LEN);
2192 /* Response callback data */
2193 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2194 (void *)status_info, sizeof(TelSmsStatusInfo));
2196 /* Send Request to modem */
2197 ret = tcore_at_prepare_and_send_request(co,
2199 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2201 _response_get_efsms_data, resp_cb_data,
2202 on_send_imc_request, NULL);
2203 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Message Status");
2205 /* Free resources */
2212 * Operation - get_sms_parameters
2215 * AT-Command: AT+CRSM
2216 * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2219 * Success: (Single-line output)
2221 * <sw1>,<sw2>[,<response>]
2225 * +CME ERROR: <error>
2227 static TelReturn imc_sms_get_sms_params(CoreObject *co,
2228 TcoreObjectResponseCallback cb, void *cb_data)
2230 TcorePlugin *plugin;
2231 ImcRespCbData *resp_cb_data;
2232 ImcSmsParamsCbData params_req_data = {0, };
2233 gint loop_count, record_count = 0, smsp_record_len = 0;
2237 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
2241 plugin = tcore_object_ref_plugin(co);
2243 /* Get Record count and SMSP record length*/
2244 if (FALSE == (imc_sim_get_smsp_info(plugin, &record_count,
2245 &smsp_record_len))) {
2246 err("Failed to get SMSP record Count and Record length");
2250 dbg("Record Count: [%d] SMSP Record Length: [%d]",
2251 record_count, smsp_record_len);
2253 /* Allocate Memory for params list data */
2254 params_req_data.params = tcore_malloc0(sizeof(TelSmsParamsInfo) * record_count);
2256 params_req_data.total_param_count = record_count;
2258 /* Actual count to be returned */
2259 params_req_data.record_count = record_count;
2260 /* SMSP record length */
2261 params_req_data.record_length = smsp_record_len;
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 /* Starting the Index with 1 */
2269 params_req_data.index = 1;
2272 at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
2273 params_req_data.index, params_req_data.record_length);
2275 /* Send Request to modem */
2276 ret = tcore_at_prepare_and_send_request(co,
2278 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2280 on_response_imc_sms_get_sms_params, resp_cb_data,
2281 on_send_imc_request, NULL);
2282 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Parameters");
2284 /* Free resources */
2285 if (ret != TEL_RETURN_SUCCESS)
2286 tcore_free(params_req_data.params);
2293 * Operation - set_sms_params
2296 * AT-Command: AT+CRSM
2297 * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2300 * Success: (Single-line output)
2302 * <sw1>,<sw2>[,<response>]
2306 * +CME ERROR: <error>
2308 static TelReturn imc_sms_set_sms_params(CoreObject *co,
2309 const TelSmsParamsInfo *params,
2310 TcoreObjectResponseCallback cb, void *cb_data)
2313 ImcRespCbData *resp_cb_data;
2316 TcorePlugin *plugin;
2317 gint smsp_record_len = 0;
2318 gchar *set_params_data = NULL;
2319 gchar *encoded_data = NULL;
2323 plugin = tcore_object_ref_plugin(co);
2325 if (FALSE == imc_sim_get_smsp_info(plugin, &record_count, &smsp_record_len)) {
2326 err("Failed to get SMSP record Count and Record length");
2327 return TEL_RETURN_INVALID_PARAMETER;
2330 dbg("SMSP Record Length: [%d]", smsp_record_len);
2332 /* Allocate memory for set_params_data */
2333 set_params_data = tcore_malloc0(smsp_record_len);
2335 /* Allocate memory for encoded data*/
2336 encoded_data = tcore_malloc0((2*smsp_record_len)+1);
2338 tcore_util_encode_sms_parameters((TelSmsParamsInfo *)params,
2339 set_params_data, smsp_record_len);
2340 dbg("SCA Address: [%s]", params->sca.number);
2342 tcore_util_byte_to_hex((const char *)set_params_data,
2343 (char *)encoded_data, smsp_record_len);
2345 /* Response callback data */
2346 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2349 at_cmd = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",
2350 params->index, smsp_record_len, encoded_data);
2351 dbg("at_cmd - %s", at_cmd);
2352 /* Send Request to modem */
2353 ret = tcore_at_prepare_and_send_request(co,
2355 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2357 on_response_imc_sms_set_sms_params, resp_cb_data,
2358 on_send_imc_request, NULL);
2359 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SMS Parameters");
2361 /* Free resources */
2363 g_free(set_params_data);
2364 g_free(encoded_data);
2369 /* SMS Operations */
2370 static TcoreSmsOps imc_sms_ops = {
2371 .send_sms = imc_sms_send_sms,
2372 .read_in_sim = imc_sms_read_sms_in_sim,
2373 .write_in_sim = imc_sms_write_sms_in_sim,
2374 .delete_in_sim = imc_sms_delete_sms_in_sim,
2375 .get_count = imc_sms_get_msg_count_in_sim,
2376 .set_cb_config = imc_sms_set_cb_config,
2377 .get_cb_config = imc_sms_get_cb_config,
2378 .get_parameters = imc_sms_get_sms_params,
2379 .set_parameters = imc_sms_set_sms_params,
2380 .send_deliver_report = imc_sms_send_deliver_report,
2381 .set_sca = imc_sms_set_sca,
2382 .get_sca = imc_sms_get_sca,
2383 .set_memory_status = imc_sms_set_memory_status,
2384 .set_message_status = imc_sms_set_message_status
2387 gboolean imc_sms_init(TcorePlugin *p, CoreObject *co)
2391 /* Set operations */
2392 tcore_sms_set_ops(co, &imc_sms_ops);
2395 tcore_object_add_callback(co, "\e+CMT:",
2396 on_notification_imc_sms_incoming_msg, NULL);
2397 tcore_object_add_callback(co, "\e+CDS",
2398 on_notification_imc_sms_incoming_msg, NULL);
2400 tcore_object_add_callback(co, "\e+CBM",
2401 on_notification_imc_sms_cb_incom_msg, NULL);
2402 tcore_object_add_callback(co, "+CMTI",
2403 on_notification_imc_sms_class2_incoming_msg, NULL);
2407 * TODO - AT Command Description Not available
2409 tcore_object_add_callback(co, "+XSMSMMSTAT",
2410 on_notification_imc_sms_memory_status, NULL);
2416 void imc_sms_exit(TcorePlugin *p, CoreObject *co)