4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
28 #include <core_object.h>
38 #include "imc_common.h"
43 #define AT_MT_UNREAD 0 /* Received and Unread */
44 #define AT_MT_READ 1 /* Received and Read */
45 #define AT_MO_UNSENT 2 /* Unsent */
46 #define AT_MO_SENT 3 /* Sent */
47 #define AT_ALL 4 /* Unknown */
49 #define IMC_NUM_PLAN_ID(sca) (gchar)(sca & 0x0F)
50 #define IMC_TYPE_OF_NUM(sca) (gchar)((sca & 0x70) >> 4)
52 /* SCA 12 bytes long and TDPU is 164 bytes long */
53 #define PDU_LEN_MAX 176
54 #define HEX_PDU_LEN_MAX ((PDU_LEN_MAX * 2) + 1)
56 #define IMC_SIM_TON_INTERNATIONAL 1
57 #define IMC_SIM_TON_NATIONAL 2
59 #define IMC_AT_EF_SMS_RECORD_LEN 176
62 guint total_param_count;
65 TelSmsParamsInfo *params;
69 * Notification - SMS-DELIVER
70 * +CMT = [<alpha>],<length><CR><LF><pdu> (PDU mode enabled)
74 * <length> length of the PDU
75 * <pdu> Incomming SMS PDU
77 * Notification - SMS-STATUS-REPORT
78 * +CDS: <length><CR><LF><pdu> (PDU mode enabled)
81 * <length> length of the PDU
82 * <pdu> Incomming SMS PDU
85 static gboolean on_notification_imc_sms_incoming_msg(CoreObject *co,
86 const void *event_info, void *user_data)
88 GSList *tokens = NULL;
91 int pdu_len = 0, no_of_tokens = 0;
93 TelSmsDatapackageInfo incoming_msg = {{0}, };
99 lines = (GSList *)event_info;
100 if (2 != g_slist_length(lines)) {
101 err("Invalid number of lines for +CMT. Must be 2");
105 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
107 err("Line 1 is invalid");
110 dbg("Line 1: [%s]", line);
112 /* Split Line 1 into tokens */
113 tokens = tcore_at_tok_new(line);
114 no_of_tokens = g_slist_length(tokens);
118 * Number of tokens: 2
120 * Incoming SMS-STATUS-REPORT: +CDS
121 * Number of tokens: 1
123 if (2 == no_of_tokens) {
124 /* Token 0: Alpha ID */
125 dbg("Alpha ID: [0x%x]", g_slist_nth_data(tokens, 0));
127 /* Token 1: PDU Length */
128 pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
129 dbg("pdu_len: [%d]", pdu_len);
130 } else if (1 == no_of_tokens) {
131 /* Token 0: PDU Length */
132 pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
133 dbg("pdu_len: [%d]", pdu_len);
135 tcore_at_tok_free(tokens);
138 line = (char *)g_slist_nth_data(lines, 1);
140 err("Line 2 is invalid");
143 dbg("Line 2: [%s]", line);
145 /* Convert to Bytes */
146 tcore_util_hexstring_to_bytes(line, &byte_pdu, &byte_pdu_len);
148 sca_length = byte_pdu[0];
149 dbg("SCA length = %d", sca_length);
152 guint encoded_sca_len;
154 * byte_pdu[1] - sca_address_type
155 * Excluding sca_address_type and copy SCA
157 encoded_sca_len = sca_length - 1;
159 tcore_util_convert_bcd_to_ascii(&byte_pdu[2], encoded_sca_len, encoded_sca_len*2);
160 dbg("Decoded SCA: [%s]", decoded_sca);
161 g_strlcpy(incoming_msg.sca.number, decoded_sca, strlen(decoded_sca)+1);
162 tcore_free(decoded_sca);
164 /*SCA Conversion for Address type*/
165 incoming_msg.sca.ton = IMC_TYPE_OF_NUM(byte_pdu[1]);
166 incoming_msg.sca.npi = IMC_NUM_PLAN_ID(byte_pdu[1]);
167 dbg("TON: [%d] NPI: [%d] SCA: [%s]",
168 incoming_msg.sca.ton, incoming_msg.sca.npi,
169 incoming_msg.sca.number);
172 dbg("NO SCA Present");
176 incoming_msg.tpdu_length = pdu_len;
177 memcpy(incoming_msg.tpdu,
178 &byte_pdu[sca_length+1], incoming_msg.tpdu_length);
180 tcore_util_hex_dump(" ",incoming_msg.tpdu_length, &byte_pdu[sca_length+1]);
182 /* Send notification */
183 tcore_object_send_notification(co,
184 TCORE_NOTIFICATION_SMS_INCOM_MSG,
185 sizeof(TelSmsDatapackageInfo), &incoming_msg);
193 * +CBM: <length><CR><LF><pdu> (PDU mode enabled);
196 * <length> length of the PDU
197 * <pdu> Incomming SMS CB PDU
200 static gboolean on_notification_imc_sms_cb_incom_msg(CoreObject *co,
201 const void *event_info, void *user_data)
203 char * line = NULL, *pdu = NULL, *line_token = NULL;
204 GSList *tokens = NULL;
205 unsigned char *byte_pdu = NULL;
206 guint byte_pdu_len = 0;
207 GSList *lines = NULL;
209 TelSmsCbMsgInfo cb_noti = { 0, };
212 lines = (GSList *)event_info;
214 line = (char *)(lines->data);/*Fetch Line 1*/
216 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
217 line_token = g_slist_nth_data(tokens, 0);
219 cb_noti.length = atoi(line_token);
221 dbg("token 0 is NULL");
222 tcore_at_tok_free(tokens);
225 pdu = g_slist_nth_data(lines, 1);
227 cb_noti.cb_type = TEL_SMS_CB_MSG_GSM;
229 dbg("CB Msg LENGTH [%d]", cb_noti.length);
231 if ((cb_noti.length > 0) && (TEL_SMS_CB_DATA_SIZE_MAX >= cb_noti.length)) {
232 tcore_util_hexstring_to_bytes(pdu, (gchar **)&byte_pdu, &byte_pdu_len);
234 memcpy(cb_noti.cb_data, (char*)byte_pdu, cb_noti.length);
236 err("Invalid Message Length");
237 tcore_at_tok_free(tokens);
241 err("NULL PDU Recieved ");
242 tcore_at_tok_free(tokens);
245 tcore_object_send_notification(co,
246 TCORE_NOTIFICATION_SMS_CB_INCOM_MSG, sizeof(TelSmsCbMsgInfo), &cb_noti);
252 tcore_at_tok_free(tokens);
258 * TODO - AT Command Description Not available
261 static gboolean on_notification_imc_sms_memory_status(CoreObject *co,
262 const void *event_info, void *user_data)
264 gboolean memory_status = TRUE;
266 GSList *tokens = NULL;
267 GSList *lines = NULL;
268 char *line = NULL , *line_token = NULL;
271 lines = (GSList *)event_info;
272 if (1 != g_slist_length(lines)) {
273 dbg("Unsolicited msg but multiple line");
277 line = (char*)(lines->data);
279 tokens = tcore_at_tok_new(line);
280 line_token = g_slist_nth_data(tokens, 0);
282 /* SIM Full condition */
283 if (0 == atoi(line_token))
284 memory_status = FALSE;
286 /* Send notification */
287 tcore_object_send_notification(co,
288 TCORE_NOTIFICATION_SMS_MEMORY_STATUS,
289 sizeof(gboolean), &memory_status);
291 tcore_at_tok_free(tokens);
299 static void on_response_imc_class2_sms_incom_msg(TcorePending *p,
300 guint data_len, const void *data, void *user_data)
302 const TcoreAtResponse *at_resp = data;
303 CoreObject *co = tcore_pending_ref_core_object(p);
305 TelSmsDatapackageInfo incoming_msg = { { 0 }, };
308 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
310 guint byte_pdu_len = 0;
313 if (at_resp && at_resp->success) {
315 if (at_resp->lines) {
320 * Fetching First Line
322 gslist_line = (char *)at_resp->lines->data;
323 dbg("gslist_line: [%s]", gslist_line);
326 tokens = tcore_at_tok_new(gslist_line);
327 dbg("Number of tokens: [%d]", g_slist_length(tokens));
329 /* First Token : status
330 * Second Token: Alpha ID - not needed
332 line_token = g_slist_nth_data(tokens, 2); /* Third Token: PDU Length */
333 if (line_token != NULL) {
334 incoming_msg.tpdu_length = atoi(line_token);
335 dbg("Length: [%d]", incoming_msg.tpdu_length);
338 err("Line Token for PDU Length is NULL");
342 /* Fetching line: Second line is PDU */
343 hex_pdu = (char *) at_resp->lines->next->data;
344 dbg("EF-SMS PDU: [%s]", hex_pdu);
346 tcore_at_tok_free(tokens); /* free the consumed token */
347 if (NULL != hex_pdu) {
348 tcore_util_hexstring_to_bytes(hex_pdu, &byte_pdu, &byte_pdu_len);
350 sca_length = (int)byte_pdu[0];
352 dbg("SCA Length [%d], msgLength: [%d]", sca_length, incoming_msg.tpdu_length);
354 if (ZERO == sca_length) {
355 memcpy(incoming_msg.tpdu, &byte_pdu[1], incoming_msg.tpdu_length);
361 * byte_pdu[1] - sca_address_type
362 * Excluding sca_address_type and copy SCA
364 memcpy(incoming_msg.sca.number, &byte_pdu[2], (sca_length-1));
367 * SCA Conversion: Address Type
368 * 3GPP TS 23.040 V6.5.0 Section: 9.1.2.5
370 sca_toa = byte_pdu[1];
371 incoming_msg.sca.npi = IMC_NUM_PLAN_ID(sca_toa);
372 incoming_msg.sca.ton = IMC_TYPE_OF_NUM(sca_toa);
374 memcpy(incoming_msg.tpdu,
375 &byte_pdu[sca_length+1],
376 incoming_msg.tpdu_length);
380 tcore_object_send_notification(co,
381 TCORE_NOTIFICATION_SMS_INCOM_MSG,
382 sizeof(TelSmsDatapackageInfo), &incoming_msg);
383 tcore_at_tok_free(tokens);
387 err("Invalid Response Received");
397 * +CMTI: <mem>,<index>
400 * <mem> memory location
401 * <index> index where msg is stored
403 static gboolean on_notification_imc_sms_class2_incoming_msg(CoreObject *co, const void *event_info, void *user_data)
408 GSList *tokens = NULL , *lines = NULL;
410 gint index, mem_type = 0;
413 lines = (GSList *)event_info;
414 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
416 err("Line 1 is invalid");
419 dbg("Line 1: [%s]", line);
421 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
422 mem_type = atoi(g_slist_nth_data(tokens, 0));/* Type of Memory stored */
423 dbg("mem_type=[%d]", mem_type);
424 index = atoi((char *) g_slist_nth_data(tokens, 1));
425 dbg("index: [%d]", index);
428 * Operation - read_sms_in_sim
431 * AT-Command: At+CMGR=<index>
433 * <index> index of the message to be read.
436 * Success: (PDU: Multi-line output)
437 * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
440 * +CMS ERROR: <error>
443 at_cmd = g_strdup_printf("AT+CMGR=%d", index);
445 /* Send Request to modem */
446 ret = tcore_at_prepare_and_send_request(co,
448 TCORE_AT_COMMAND_TYPE_PDU,
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");
1421 tcore_util_hexstring_to_bytes(hex_data, &record_data, (guint*)&decoding_length);
1423 * Decrementing the Record Count and Filling the ParamsInfo List
1424 * Final Response will be posted when Record count is ZERO
1426 params_req_data->params[params_req_data->index].index = params_req_data->index;
1428 tcore_util_decode_sms_parameters((unsigned char *)record_data,
1430 ¶ms_req_data->params[params_req_data->index]);
1432 params_req_data->total_param_count -= 1;
1434 if (params_req_data->total_param_count == 0) {
1435 dbg("Reading all Records - Complete");
1436 result = TEL_SMS_RESULT_SUCCESS;
1439 dbg("Reading all records incomplete [%d - Pending]",
1440 params_req_data->total_param_count);
1441 tcore_at_tok_free(tokens);
1445 err("Invalid Response Received");
1448 err("RESPONSE NOK");
1453 TelSmsParamsInfoList param_info_list = {0, };
1455 if (result == TEL_SMS_RESULT_SUCCESS) {
1456 param_info_list.params = params_req_data->params;
1457 param_info_list.count = params_req_data->count;
1460 /* Invoke callback */
1461 if (resp_cb_data->cb)
1462 resp_cb_data->cb(co, (gint)result, (void *)¶m_info_list, resp_cb_data->cb_data);
1466 tcore_at_tok_free(tokens);
1468 tcore_free(params_req_data->params);
1469 g_free(record_data);
1471 /* Free callback data */
1472 imc_destroy_resp_cb_data(resp_cb_data);
1475 static void on_response_imc_sms_set_sms_params(TcorePending *p,
1476 guint data_len, const void *data, void *user_data)
1478 const TcoreAtResponse *at_resp = data;
1479 CoreObject *co = tcore_pending_ref_core_object(p);
1480 ImcRespCbData *resp_cb_data = user_data;
1482 TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1483 gint sw1 = 0 , sw2 = 0;
1484 const char *line = NULL;
1485 GSList *tokens=NULL;
1488 if (at_resp && at_resp->success) {
1490 if (at_resp->lines) {
1491 line = (const char *) at_resp->lines->data;
1492 tokens = tcore_at_tok_new(line);
1494 sw1 = atoi(g_slist_nth_data(tokens, 0));
1495 sw2 = atoi(g_slist_nth_data(tokens, 1));
1497 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1498 result = TEL_SMS_RESULT_SUCCESS;
1501 result = TEL_SMS_RESULT_FAILURE;
1504 tcore_at_tok_free(tokens);
1506 err("Response NOK");
1509 /* Invoke callback */
1510 if (resp_cb_data->cb)
1511 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1513 /* Free callback data */
1514 imc_destroy_resp_cb_data(resp_cb_data);
1517 static gboolean async_callback(gpointer data)
1519 ImcRespCbData *resp_cb_data = data;
1521 TelSmsResult result = TEL_SMS_RESULT_SUCCESS;
1523 co = ((CoreObject **)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data));
1525 /* Invoke callback */
1526 if (resp_cb_data->cb)
1527 resp_cb_data->cb(*co, (gint)result, NULL, resp_cb_data->cb_data);
1529 /* Free callback data */
1530 imc_destroy_resp_cb_data(resp_cb_data);
1535 /* SMS Operations */
1537 * Operation - send_sms
1540 * AT-Command: AT+CMGS
1541 * For PDU mode (+CMGF=0):
1542 * +CMGS=<length><CR>
1543 * PDU is given<ctrl-Z/ESC>
1545 * <length> Length of the pdu.
1546 * <PDU> PDU to send.
1549 *+CMGS: <mr>[,<ackpdu>]
1552 * +CMS ERROR: <error>
1554 static TelReturn imc_sms_send_sms(CoreObject *co,
1555 const TelSmsSendInfo *send_info, TcoreObjectResponseCallback cb, void *cb_data)
1559 ImcRespCbData *resp_cb_data;
1562 const unsigned char *tpdu_byte_data;
1563 gint tpdu_byte_len, pdu_byte_len;
1564 char buf[HEX_PDU_LEN_MAX];
1565 char pdu[PDU_LEN_MAX];
1568 tpdu_byte_data = send_info->send_data.tpdu;
1570 /* TPDU length is in byte */
1571 tpdu_byte_len = send_info->send_data.tpdu_length;
1573 /* Use same Radio Resource Channel :More Messages to send*/
1574 dbg("More messages: [%d]", send_info->more_msgs);
1576 /* Prepare PDU for hex encoding */
1577 pdu_byte_len = tcore_util_encode_pdu(&(send_info->send_data.sca),
1578 tpdu_byte_data, tpdu_byte_len, pdu);
1579 tcore_util_hex_dump(" ", pdu_byte_len, pdu);
1581 tcore_util_encode_hex((unsigned char *)pdu, pdu_byte_len, buf);
1583 /* Response callback data */
1584 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1586 if (send_info->more_msgs == TRUE) {
1587 /* AT Command: More Msgs to Send */
1588 ret = tcore_at_prepare_and_send_request(co,
1589 "AT+CMMS=1", "+CMMS:",
1590 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1592 on_response_imc_sms_send_more_msg, NULL,
1593 on_send_imc_request, NULL);
1594 IMC_CHECK_REQUEST_RET(ret, NULL, "More Msgs to Send");
1597 /* AT-Command : Send SMS*/
1598 at_cmd = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
1600 /* Send Request to modem */
1601 ret = tcore_at_prepare_and_send_request(co,
1603 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1605 on_response_imc_sms_send_sms, resp_cb_data,
1606 on_send_imc_request, NULL);
1607 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send SMS");
1609 /* Free resources */
1616 * Operation - write_sms_in_sim
1619 * AT-Command: AT+CMGW
1620 * AT+CMGW = <length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
1622 * <length> length of the tpdu
1623 * <stat> status of the message
1624 * <PDU> PDu of the message
1628 * Success: (Single line)
1631 * +CMS ERROR: <error>
1633 static TelReturn imc_sms_write_sms_in_sim(CoreObject *co,
1634 const TelSmsSimDataInfo *wdata, TcoreObjectResponseCallback cb, void *cb_data)
1638 ImcRespCbData *resp_cb_data;
1641 const unsigned char *tpdu_byte_data;
1642 int tpdu_byte_len, pdu_byte_len;
1643 char buf[HEX_PDU_LEN_MAX];
1644 char hex_pdu[PDU_LEN_MAX];
1648 switch (wdata->status) {
1649 case TEL_SMS_STATUS_MT_UNREAD:
1650 status = AT_MT_UNREAD;
1653 case TEL_SMS_STATUS_MT_READ:
1654 status = AT_MT_READ;
1657 case TEL_SMS_STATUS_MO_NOT_SENT:
1658 status = AT_MO_UNSENT;
1661 case TEL_SMS_STATUS_MO_SENT:
1662 status = AT_MO_SENT;
1666 err("Invalid Message Status");
1667 return TEL_RETURN_INVALID_PARAMETER;
1669 tpdu_byte_data = wdata->data.tpdu;
1671 tpdu_byte_len = wdata->data.tpdu_length;
1672 dbg("TDPU length: [%d]", tpdu_byte_len);
1674 /* Prepare PDU for hex encoding */
1675 pdu_byte_len = tcore_util_encode_pdu(&(wdata->data.sca),
1676 tpdu_byte_data, tpdu_byte_len, hex_pdu);
1677 tcore_util_hex_dump(" ", pdu_byte_len, hex_pdu);
1679 tcore_util_encode_hex((unsigned char *)hex_pdu, pdu_byte_len, buf);
1682 at_cmd = g_strdup_printf("AT+CMGW=%d,%d%c%s%c",
1683 tpdu_byte_len, status, CR, buf, CTRL_Z);
1685 /* Response callback data */
1686 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1688 /* Send Request to modem */
1689 ret = tcore_at_prepare_and_send_request(co,
1691 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1693 on_response_imc_sms_write_sms_in_sim, resp_cb_data,
1694 on_send_imc_request, NULL);
1695 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Write SMS in SIM");
1697 /* Free resources */
1704 * Operation - read_sms_in_sim
1707 * AT-Command: At+CMGR=<index>
1709 * <index> index of the message to be read.
1712 * Success: (PDU: Multi-line output)
1713 * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
1716 * +CMS ERROR: <error>
1718 static TelReturn imc_sms_read_sms_in_sim(CoreObject *co,
1719 unsigned int index, TcoreObjectResponseCallback cb, void *cb_data)
1723 ImcRespCbData *resp_cb_data;
1728 at_cmd = g_strdup_printf("AT+CMGR=%d", index);
1730 /* Response callback data */
1731 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, ZERO);
1733 /* Send Request to modem */
1734 ret = tcore_at_prepare_and_send_request(co,
1736 TCORE_AT_COMMAND_TYPE_PDU,
1738 on_response_imc_sms_read_sms_in_sim, resp_cb_data,
1739 on_send_imc_request, NULL);
1740 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read SMS in SIM");
1742 /* Free resources */
1749 * Operation - delete_sms_in_sim
1752 * AT-Command: AT+CGMD
1753 * +CMGD=<index>[,<delflag>]
1756 * Success: (NO RESULT) -
1759 * +CMS ERROR: <error>
1761 static TelReturn imc_sms_delete_sms_in_sim(CoreObject *co,
1763 TcoreObjectResponseCallback cb, void *cb_data)
1767 ImcRespCbData *resp_cb_data;
1771 /* Response callback data */
1772 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1774 * TODO: Delete All Messages
1776 * at_cmd = g_strdup_printf("AT+CMGD=0,4");
1777 * Need to convey MSG_SERVICE to pass an index of
1778 * guint value to delete all Messages.probably as 0.
1782 at_cmd = g_strdup_printf("AT+CMGD=%d,0", index); /*Delete specified index*/
1784 /* Send Request to modem */
1785 ret = tcore_at_prepare_and_send_request(co,
1787 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1789 on_response_imc_sms_delete_sms_in_sim, resp_cb_data,
1790 on_send_imc_request, NULL);
1791 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete SMS in SIM");
1793 /* Free resources */
1800 * Operation - get_sms_count_in_sim
1803 * AT-Command: AT+CPMS
1804 * +CPMS=<mem1>[, <mem2>[,<mem3>]]
1806 * <mem1> memory storage to read.
1809 * Success: (Single-line output)
1810 * +CPMS: <mem1>,<used1>,<total1>,<mem2>,<used2>,<total2>,
1811 * <mem3>,<used3>,<total3>
1815 * +CMS ERROR: <error>
1817 static TelReturn imc_sms_get_msg_count_in_sim(CoreObject *co,
1818 TcoreObjectResponseCallback cb, void *cb_data)
1822 ImcRespCbData *resp_cb_data;
1827 at_cmd = g_strdup_printf("AT+CPMS=\"SM\"");
1829 /* Response callback data */
1830 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1832 /* Send Request to modem */
1833 ret = tcore_at_prepare_and_send_request(co,
1835 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1837 on_response_imc_sms_get_sms_count, resp_cb_data,
1838 on_send_imc_request, NULL);
1839 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Count");
1841 /* Free resources */
1848 * Operation - set SCA
1851 * AT-Command: AT+CSCA
1852 * AT+CSCA=<sca>[,<tosca>]
1854 * <sca> Service center number
1855 * <tosca> address type of SCA
1858 * Success: No result
1862 * +CMS ERROR: <error>
1864 static TelReturn imc_sms_set_sca(CoreObject *co,
1865 const TelSmsSca *sca, TcoreObjectResponseCallback cb, void *cb_data)
1869 ImcRespCbData *resp_cb_data;
1873 address_type = ((sca->ton << 4) | sca->npi ) | 0x80;
1876 at_cmd = g_strdup_printf("AT+CSCA=\"%s\",%d", sca->number, address_type);
1878 /* Response callback data */
1879 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1881 /* Send Request to modem */
1882 ret = tcore_at_prepare_and_send_request(co,
1884 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1886 on_response_imc_sms_set_sca, resp_cb_data,
1887 on_send_imc_request, NULL);
1888 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SCA");
1890 /* Free resources */
1897 * Operation - get SCA
1900 * AT-Command: AT+CSCA?
1903 * Success: Single-Line
1904 * +CSCA: <sca>,<tosca>
1907 * <sca> Service center number
1908 * <tosca> address type of SCA
1911 static TelReturn imc_sms_get_sca(CoreObject *co,
1912 TcoreObjectResponseCallback cb, void *cb_data)
1916 ImcRespCbData *resp_cb_data;
1921 at_cmd = g_strdup_printf("AT+CSCA?");
1923 /* Response callback data */
1924 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1926 /* Send Request to modem */
1927 ret = tcore_at_prepare_and_send_request(co,
1929 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1931 on_response_imc_sms_get_sca, resp_cb_data,
1932 on_send_imc_request, NULL);
1933 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SCA");
1935 /* Free resources */
1942 * Operation - set_cb_config
1945 * AT-Command: AT+CSCB
1946 * +CSCB=[<mode>[,<mids>[,<dcss>]]]
1953 * +CME ERROR: <error>
1955 static TelReturn imc_sms_set_cb_config(CoreObject *co,
1956 const TelSmsCbConfigInfo *cb_conf,
1957 TcoreObjectResponseCallback cb, void *cb_data)
1961 ImcRespCbData *resp_cb_data;
1964 unsigned short ctr1 = 0, ctr2 = 0, msg_id_range = 0;
1965 unsigned short append_msg_id = 0;
1968 if (cb_conf->msg_id_range_cnt != 0) { /* Enable Specific Msgid's */
1969 gchar *mids_str = NULL;
1970 GString *mid_string = NULL;
1973 mid_string = g_string_new("AT+CSCB=0,\"");
1974 for(ctr1 = 0; ctr1 < cb_conf->msg_id_range_cnt; ctr1++) {
1975 if (cb_conf->msg_ids[ctr1].selected == FALSE)
1977 msg_id_range = ((cb_conf->msg_ids[ctr1].to_msg_id) - (cb_conf->msg_ids[ctr1].from_msg_id));
1979 if (TEL_SMS_GSM_CBMI_LIST_SIZE_MAX <= msg_id_range) {
1980 mid_string = g_string_new("AT+CSCB=1"); /* Enable All CBS */
1983 append_msg_id = cb_conf->msg_ids[ctr1].from_msg_id;
1984 dbg( "%x", append_msg_id);
1986 for(ctr2 = 0; ctr2 <= msg_id_range; ctr2++) {
1987 mid_string = g_string_append(mid_string, g_strdup_printf("%d", append_msg_id));
1988 if (ctr2 == msg_id_range) {
1989 mid_string = g_string_append(mid_string, "\""); /*Mids string termination*/
1992 mid_string = g_string_append(mid_string, ",");
1997 mids_str = g_string_free(mid_string, FALSE);
1998 at_cmd = g_strdup_printf("%s", mids_str);
2002 at_cmd = g_strdup_printf("AT+CSCB=%d", cb_conf->cb_enabled); /* Enable or Disable MsgId's */
2005 /* Response callback data */
2006 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2008 /* Send Request to modem */
2009 ret = tcore_at_prepare_and_send_request(co,
2011 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2013 on_response_imc_sms_set_cb_config, resp_cb_data,
2014 on_send_imc_request, NULL);
2015 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Cb Config");
2017 /* Free resources */
2024 * Operation - get_cb_config
2027 * AT-Command: AT+CSCB
2031 * Success - (Single line)
2032 * +CSCB : <mode>,<mids>,<dcss>
2036 static TelReturn imc_sms_get_cb_config(CoreObject *co,
2037 TcoreObjectResponseCallback cb, void *cb_data)
2041 ImcRespCbData *resp_cb_data;
2046 at_cmd = g_strdup_printf("AT+CSCB?");
2048 /* Response callback data */
2049 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2051 /* Send Request to modem */
2052 ret = tcore_at_prepare_and_send_request(co,
2054 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2056 on_response_imc_sms_get_cb_config, resp_cb_data,
2057 on_send_imc_request, NULL);
2058 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Cb Config");
2060 /* Free resources */
2067 * Operation - send_deliver_report
2070 * Modem Takes care of sending the ACK to the network
2073 * Success: Default response always SUCCESS posted
2076 static TelReturn imc_sms_send_deliver_report(CoreObject *co,
2077 const TelSmsDeliverReportInfo *dr_info,
2078 TcoreObjectResponseCallback cb, void *cb_data)
2080 ImcRespCbData *resp_cb_data;
2081 TelReturn ret = TEL_RETURN_FAILURE;
2083 dbg("CP takes care of sending SMS ack to network for all "
2084 "classes of SMS. Sending default success.!!!");
2085 ret = TEL_RETURN_SUCCESS;
2087 /* Response callback data */
2088 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2089 (void *)&co, sizeof(CoreObject*));
2091 g_idle_add(async_callback, (gpointer)resp_cb_data);
2097 /* Operation - set memory status
2100 * AT-Command: AT+XTESM=<mem_capacity>
2101 * <mem_capacity> status of the external SMS storage which may be:
2102 * 0: memory capacity free
2103 * 1: memory capacity full
2105 * Response -No Result
2110 * +CME ERROR: <error>
2112 static TelReturn imc_sms_set_memory_status(CoreObject *co,
2113 gboolean available, TcoreObjectResponseCallback cb, void *cb_data)
2117 ImcRespCbData *resp_cb_data;
2121 at_cmd = g_strdup_printf("AT+XTESM=%d", available? 0: 1);
2123 /* Response callback data */
2124 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2126 /* Send Request to modem */
2127 ret = tcore_at_prepare_and_send_request(co,
2129 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2131 on_response_imc_sms_set_memory_status, resp_cb_data,
2132 on_send_imc_request, NULL);
2133 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Memory Status");
2135 /* Free resources */
2141 /* Operation - set Message status
2144 * AT-Command: AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2146 * p3 SMSP record length
2149 * Response -Single Line
2154 * +CME ERROR: <error>
2156 static TelReturn imc_sms_set_message_status(CoreObject *co,
2157 const TelSmsStatusInfo *status_info,
2158 TcoreObjectResponseCallback cb, void *cb_data)
2162 ImcRespCbData *resp_cb_data;
2166 at_cmd = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d",
2167 (status_info->index), IMC_AT_EF_SMS_RECORD_LEN);
2169 /* Response callback data */
2170 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2171 (void *)status_info, sizeof(TelSmsStatusInfo));
2173 /* Send Request to modem */
2174 ret = tcore_at_prepare_and_send_request(co,
2176 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2178 _response_get_efsms_data, resp_cb_data,
2179 on_send_imc_request, NULL);
2180 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Message Status");
2182 /* Free resources */
2189 * Operation - get_sms_parameters
2192 * AT-Command: AT+CRSM
2193 * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2196 * Success: (Single-line output)
2198 * <sw1>,<sw2>[,<response>]
2202 * +CME ERROR: <error>
2204 static TelReturn imc_sms_get_sms_params(CoreObject *co,
2205 TcoreObjectResponseCallback cb, void *cb_data)
2207 TcorePlugin *plugin;
2208 ImcRespCbData *resp_cb_data;
2209 ImcSmsParamsCbData params_req_data = {0, };
2210 gint loop_count, record_count = 0, smsp_record_len = 0;
2211 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
2215 plugin = tcore_object_ref_plugin(co);
2217 /* Get Record count and SMSP record length*/
2218 if (FALSE == (imc_sim_get_smsp_info(plugin, &record_count,
2219 &smsp_record_len))) {
2220 err("Failed to get SMSP record Count and Record length");
2224 dbg("Record Count: [%d] SMSP Record Length: [%d]",
2225 record_count, smsp_record_len);
2227 /* Allocate Memory for params list data */
2228 params_req_data.params = tcore_malloc0(sizeof(TelSmsParamsInfo) * record_count);
2230 params_req_data.total_param_count = record_count;
2231 /* Saving actual count to be returned */
2232 params_req_data.count = record_count;
2233 /* Response callback data */
2234 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2235 (void *)¶ms_req_data,
2236 sizeof(ImcSmsParamsCbData));
2238 for (loop_count = 1; loop_count <= record_count; loop_count++) {
2241 /* Updating the Index */
2242 params_req_data.index = loop_count;
2244 at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
2245 params_req_data.index, smsp_record_len);
2247 /* Send Request to modem */
2248 ret = tcore_at_prepare_and_send_request(co,
2250 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2252 on_response_imc_sms_get_sms_params, resp_cb_data,
2253 on_send_imc_request, NULL);
2254 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Parameters");
2256 /* Free resources */
2257 if (ret != TEL_RETURN_SUCCESS)
2258 tcore_free(params_req_data.params);
2266 * Operation - set_sms_params
2269 * AT-Command: AT+CRSM
2270 * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2273 * Success: (Single-line output)
2275 * <sw1>,<sw2>[,<response>]
2279 * +CME ERROR: <error>
2281 static TelReturn imc_sms_set_sms_params(CoreObject *co,
2282 const TelSmsParamsInfo *params,
2283 TcoreObjectResponseCallback cb, void *cb_data)
2286 ImcRespCbData *resp_cb_data;
2289 TcorePlugin *plugin;
2290 gint smsp_record_len = 0;
2291 gchar *set_params_data = NULL;
2292 gchar *encoded_data = NULL;
2296 plugin = tcore_object_ref_plugin(co);
2298 if (FALSE == imc_sim_get_smsp_info(plugin, &record_count, &smsp_record_len)) {
2299 err("Failed to get SMSP record Count and Record length");
2300 return TEL_RETURN_INVALID_PARAMETER;
2303 dbg("SMSP Record Length: [%d]", smsp_record_len);
2305 /* Allocate memory for set_params_data */
2306 set_params_data = tcore_malloc0(sizeof(smsp_record_len));
2308 /* Allocate memory for encoded data*/
2309 encoded_data = tcore_malloc0((2 * sizeof(smsp_record_len)+1));
2311 tcore_util_encode_sms_parameters((TelSmsParamsInfo *)params,
2312 set_params_data, smsp_record_len);
2314 tcore_util_byte_to_hex((const char *)set_params_data,
2315 (char *)encoded_data, smsp_record_len);
2317 /* Response callback data */
2318 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, sizeof(gint));
2321 at_cmd = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",
2322 params->index, smsp_record_len, encoded_data);
2323 dbg("at_cmd - %s", at_cmd);
2324 /* Send Request to modem */
2325 ret = tcore_at_prepare_and_send_request(co,
2327 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2329 on_response_imc_sms_set_sms_params, resp_cb_data,
2330 on_send_imc_request, NULL);
2331 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SMS Parameters");
2333 /* Free resources */
2335 g_free(set_params_data);
2336 g_free(encoded_data);
2341 /* SMS Operations */
2342 static TcoreSmsOps imc_sms_ops = {
2343 .send_sms = imc_sms_send_sms,
2344 .read_in_sim = imc_sms_read_sms_in_sim,
2345 .write_in_sim = imc_sms_write_sms_in_sim,
2346 .delete_in_sim = imc_sms_delete_sms_in_sim,
2347 .get_count = imc_sms_get_msg_count_in_sim,
2348 .set_cb_config = imc_sms_set_cb_config,
2349 .get_cb_config = imc_sms_get_cb_config,
2350 .get_parameters = imc_sms_get_sms_params,
2351 .set_parameters = imc_sms_set_sms_params,
2352 .send_deliver_report = imc_sms_send_deliver_report,
2353 .set_sca = imc_sms_set_sca,
2354 .get_sca = imc_sms_get_sca,
2355 .set_memory_status = imc_sms_set_memory_status,
2356 .set_message_status = imc_sms_set_message_status
2359 gboolean imc_sms_init(TcorePlugin *p, CoreObject *co)
2363 /* Set operations */
2364 tcore_sms_set_ops(co, &imc_sms_ops);
2367 tcore_object_add_callback(co, "\e+CMT:",
2368 on_notification_imc_sms_incoming_msg, NULL);
2369 tcore_object_add_callback(co, "\e+CDS",
2370 on_notification_imc_sms_incoming_msg, NULL);
2372 tcore_object_add_callback(co, "\e+CBM",
2373 on_notification_imc_sms_cb_incom_msg, NULL);
2374 tcore_object_add_callback(co, "+CMTI",
2375 on_notification_imc_sms_class2_incoming_msg, NULL);
2379 * TODO - AT Command Description Not available
2381 tcore_object_add_callback(co, "+XSMSMMSTAT",
2382 on_notification_imc_sms_memory_status, NULL);
2388 void imc_sms_exit(TcorePlugin *p, CoreObject *co)