IMC plugin update
[platform/core/telephony/tel-plugin-imc.git] / src / imc_sms.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <glib.h>
24
25 #include <tcore.h>
26 #include <server.h>
27 #include <plugin.h>
28 #include <core_object.h>
29 #include <hal.h>
30 #include <queue.h>
31 #include <storage.h>
32 #include <at.h>
33
34 #include <co_sms.h>
35
36 #include "imc_sms.h"
37 #include "imc_sim.h"
38 #include "imc_common.h"
39
40 #define CR  '\r'
41 #define CTRL_Z   '\x1A'
42
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 */
48
49 #define IMC_NUM_PLAN_ID(sca)    (gchar)(sca & 0x0F)
50 #define IMC_TYPE_OF_NUM(sca)    (gchar)((sca & 0x70) >> 4)
51
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)
55
56 #define IMC_SIM_TON_INTERNATIONAL       1
57 #define IMC_SIM_TON_NATIONAL            2
58
59 #define IMC_AT_EF_SMS_RECORD_LEN        176
60
61 typedef struct {
62         guint total_param_count;
63         guint record_count;
64         guint record_length;
65         guint index;
66         TelSmsParamsInfo *params;
67 } ImcSmsParamsCbData;
68
69 static TelSmsResult
70 __imc_sms_convert_cms_error_tel_sms_result(const TcoreAtResponse *at_resp)
71 {
72         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
73         const gchar *line;
74         GSList *tokens = NULL;
75         dbg("Entry");
76
77         if (!at_resp || !at_resp->lines) {
78                 err("Invalid response data");
79                 return result;
80         }
81
82         line = (const gchar *)at_resp->lines->data;
83         tokens = tcore_at_tok_new(line);
84         if (g_slist_length(tokens) > 0) {
85                 gchar *resp_str;
86                 gint cms_err;
87
88                 resp_str = g_slist_nth_data(tokens, 0);
89                 if (!resp_str) {
90                         err("invalid cms error data");
91                         tcore_at_tok_free(tokens);
92                         return result;
93                 }
94                 cms_err = atoi(resp_str);
95                 dbg("CMS error[%d]", cms_err);
96
97                 switch (cms_err) {
98                 case 96:
99                         result = TEL_SMS_RESULT_INVALID_MANDATORY_INFO;
100                 break;
101
102                 case 208:
103                 case 209:
104                 case 211:
105                 case 320:
106                 case 321:
107                 case 322:
108                         result =  TEL_SMS_RESULT_MEMORY_FAILURE;
109                 break;
110
111                 case 42:
112                         result = TEL_SMS_RESULT_NETWORK_CONGESTION;
113                 break;
114
115                 case 17:
116                 case 38:
117                 case 287:
118                 case 290:
119                 case 331:
120                 case 332:
121                 case 538:
122                         result = TEL_SMS_RESULT_NETWORK_FAILURE;
123                 break;
124
125                 case 8:
126                 case 10:
127                 case 302:
128                 case 303:
129                         result = TEL_SMS_RESULT_OPERATION_NOT_SUPPORTED;
130                 break;
131
132                 case 255:
133                 case 500:
134                 case 548:
135                 case 547:
136                         result = TEL_SMS_RESULT_UNKNOWN_FAILURE;
137                 break;
138
139                 case 310:
140                 case 311:
141                 case 312:
142                 case 313:
143                 case 314:
144                 case 315:
145                         result =  TEL_SMS_RESULT_SIM_FAILURE;
146                 break;
147
148                 case 84:
149                 case 95:
150                 case 161:
151                 case 176:
152                 case 195:
153                 case 304:
154                 case 305:
155                 case 516:
156                 case 521:
157                 case 524:
158                 case 525:
159                 case 526:
160                 case 527:
161                 case 528:
162                 case 529:
163                 case 530:
164                 case 531:
165                 case 532:
166                 case 533:
167                 case 534:
168                 case 535:
169                         result = TEL_SMS_RESULT_INVALID_PARAMETER;
170                 break;
171
172                 default:
173                         result = TEL_SMS_RESULT_FAILURE;
174                 }
175         }
176         tcore_at_tok_free(tokens);
177
178         return result;
179 }
180
181 static TelSmsResult
182 __imc_sms_convert_cme_error_tel_sms_result(const TcoreAtResponse *at_resp)
183 {
184         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
185         const gchar *line;
186         GSList *tokens = NULL;
187         dbg("Entry");
188
189         if (!at_resp || !at_resp->lines) {
190                 err("Invalid response data");
191                 return result;
192         }
193
194         line = (const gchar *)at_resp->lines->data;
195         tokens = tcore_at_tok_new(line);
196         if (g_slist_length(tokens) > 0) {
197                 gchar *resp_str;
198                 gint cme_err;
199
200                 resp_str = g_slist_nth_data(tokens, 0);
201                 if (!resp_str) {
202                         err("Invalid CME Error data");
203                         tcore_at_tok_free(tokens);
204                         return result;
205                 }
206                 cme_err = atoi(resp_str);
207                 dbg("CME error[%d]", cme_err);
208
209                 switch (cme_err) {
210                 case 3:
211                 case 4:
212                         result = TEL_SMS_RESULT_OPERATION_NOT_SUPPORTED;
213                 break;
214
215                 case 10:
216                 case 11:
217                 case 12:
218                 case 13:
219                 case 14:
220                 case 15:
221                 case 17:
222                 case 18:
223                         result = TEL_SMS_RESULT_SIM_FAILURE;
224                 break;
225
226                 case 20:
227                         result = TEL_SMS_RESULT_MEMORY_FAILURE;
228                 break;
229
230                 case 30:
231                 case 31:
232                         result = TEL_SMS_RESULT_NETWORK_FAILURE;
233                 break;
234
235                 case 50:
236                         result =  TEL_SMS_RESULT_INVALID_PARAMETER;
237                 break;
238
239                 case 100:
240                         result =  TEL_SMS_RESULT_UNKNOWN_FAILURE;
241                 break;
242
243                 default:
244                         result = TEL_SMS_RESULT_FAILURE;
245                 }
246         }
247         tcore_at_tok_free(tokens);
248
249         return result;
250 }
251
252 /*
253  * Notification - SMS-DELIVER
254  * +CMT = [<alpha>],<length><CR><LF><pdu> (PDU mode enabled)
255  *
256  * where,
257  * <alpha> alpha_id
258  * <length> length of the PDU
259  * <pdu> Incomming SMS PDU
260  *
261  * Notification - SMS-STATUS-REPORT
262  * +CDS: <length><CR><LF><pdu> (PDU mode enabled)
263  *
264  * where,
265  * <length> length of the PDU
266  * <pdu> Incomming SMS PDU
267  *
268  */
269 static gboolean on_notification_imc_sms_incoming_msg(CoreObject *co,
270         const void *event_info, void *user_data)
271 {
272         GSList *tokens = NULL;
273         GSList *lines = NULL;
274         char *line = NULL;
275         int pdu_len = 0, no_of_tokens = 0;
276
277         TelSmsDatapackageInfo incoming_msg = {{0}, };
278         int sca_length = 0;
279         gchar *byte_pdu;
280         guint byte_pdu_len;
281         dbg("Enter");
282
283         lines = (GSList *)event_info;
284         if (2 != g_slist_length(lines)) {
285                 err("Invalid number of lines for +CMT. Must be 2");
286                 return TRUE;
287         }
288
289         /* Fetch Line 1 */
290         line = (char *)g_slist_nth_data(lines, 0);
291         if (!line) {
292                 err("Line 1 is invalid");
293                 return TRUE;
294         }
295         dbg("Line 1: [%s]", line);
296
297         /* Split Line 1 into tokens */
298         tokens = tcore_at_tok_new(line);
299         no_of_tokens = g_slist_length(tokens);
300
301         /*
302          * Incoming SMS: +CMT
303          *              Number of tokens: 2
304          *
305          * Incoming SMS-STATUS-REPORT: +CDS
306          *              Number of tokens: 1
307          */
308         if (2 == no_of_tokens) {
309                 /* Token 0: Alpha ID */
310                 dbg("Alpha ID: [0x%x]", g_slist_nth_data(tokens, 0));
311
312                 /* Token 1: PDU Length */
313                 pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
314                 dbg("pdu_len: [%d]", pdu_len);
315         } else if (1 == no_of_tokens) {
316                 /* Token 0: PDU Length */
317                 pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
318                 dbg("pdu_len: [%d]", pdu_len);
319         }
320         tcore_at_tok_free(tokens);
321
322         /* Fetch Line 2 */
323         line = (char *)g_slist_nth_data(lines, 1);
324         if (!line) {
325                 err("Line 2 is invalid");
326                 return TRUE;
327         }
328         dbg("Line 2: [%s]", line);
329
330         /* Convert to Bytes */
331         tcore_util_hexstring_to_bytes(line, &byte_pdu, &byte_pdu_len);
332
333         sca_length = byte_pdu[0];
334         dbg("SCA length = %d", sca_length);
335         if (sca_length) {
336                 gchar *decoded_sca;
337                 guint encoded_sca_len;
338                 /*
339                  * byte_pdu[1] - sca_address_type
340                  * Excluding sca_address_type and copy SCA
341                  */
342                 encoded_sca_len = sca_length - 1;
343                 decoded_sca =
344                         tcore_util_convert_bcd_to_ascii(&byte_pdu[2], encoded_sca_len, encoded_sca_len * 2);
345                 dbg("Decoded SCA: [%s]", decoded_sca);
346                 g_strlcpy(incoming_msg.sca.number, decoded_sca, strlen(decoded_sca)+1);
347                 tcore_free(decoded_sca);
348
349                 /*SCA Conversion for Address type*/
350                 incoming_msg.sca.ton = IMC_TYPE_OF_NUM(byte_pdu[1]);
351                 incoming_msg.sca.npi = IMC_NUM_PLAN_ID(byte_pdu[1]);
352                 dbg("TON: [%d] NPI: [%d] SCA: [%s]",
353                         incoming_msg.sca.ton, incoming_msg.sca.npi,
354                         incoming_msg.sca.number);
355         } else {
356                 dbg("NO SCA Present");
357         }
358
359         /* TPDU */
360         incoming_msg.tpdu_length = pdu_len;
361         memcpy(incoming_msg.tpdu,
362                 &byte_pdu[sca_length+1], incoming_msg.tpdu_length);
363
364         tcore_util_hex_dump("    ",incoming_msg.tpdu_length, &byte_pdu[sca_length+1]);
365
366         /* Send notification */
367         tcore_object_send_notification(co,
368                 TCORE_NOTIFICATION_SMS_INCOM_MSG,
369                 sizeof(TelSmsDatapackageInfo), &incoming_msg);
370
371         g_free(byte_pdu);
372         return TRUE;
373 }
374
375 /*
376  * Notification
377  * +CBM: <length><CR><LF><pdu> (PDU mode enabled);
378  *
379  * where,
380  * <length> length of the PDU
381  * <pdu> Incomming SMS CB PDU
382  *
383  */
384 static gboolean on_notification_imc_sms_cb_incom_msg(CoreObject *co,
385         const void *event_info, void *user_data)
386 {
387         char * line = NULL, *pdu = NULL, *line_token = NULL;
388         GSList *tokens = NULL;
389         unsigned char *byte_pdu = NULL;
390         guint byte_pdu_len = 0;
391         GSList *lines = NULL;
392
393         TelSmsCbMsgInfo cb_noti = {0, };
394         dbg("Enter");
395
396         lines = (GSList *)event_info;
397         /* Fetch Line 1 */
398         line = (char *)(lines->data);
399         if (line != NULL) {
400                 /* Split Line 1 into tokens */
401                 tokens = tcore_at_tok_new(line);
402                 line_token = g_slist_nth_data(tokens, 0);
403                 if (!line_token) {
404                         err("invalid token");
405                         goto OUT;
406                 }
407
408                 cb_noti.length = atoi(line_token);
409                 pdu = g_slist_nth_data(lines, 1);
410                 if (!pdu) {
411                         err("NULL PDU Recieved ");
412                         goto OUT;
413                 }
414
415                 cb_noti.cb_type = TEL_SMS_CB_MSG_GSM;
416                 dbg("CB Msg LENGTH [%d]", cb_noti.length);
417
418                 if ((cb_noti.length > 0) && (cb_noti.length <= TEL_SMS_CB_DATA_SIZE_MAX)) {
419                         tcore_util_hexstring_to_bytes(pdu, (gchar **)&byte_pdu, &byte_pdu_len);
420                         cb_noti.cb_data = tcore_malloc0(cb_noti.length + 1);
421                         memcpy(cb_noti.cb_data, (char*)byte_pdu, cb_noti.length);
422                 } else {
423                         err("Invalid Message Length");
424                         goto OUT;
425                 }
426
427                 tcore_object_send_notification(co,
428                         TCORE_NOTIFICATION_SMS_CB_INCOM_MSG,
429                         sizeof(TelSmsCbMsgInfo), &cb_noti);
430                 g_free(byte_pdu);
431                 tcore_free(cb_noti.cb_data);
432         } else {
433                 err("Invalid Message received");
434         }
435 OUT:
436         tcore_at_tok_free(tokens);
437         return TRUE;
438 }
439
440 /*
441  * Notification
442  * TODO - AT Command Description Not available
443  *
444  */
445 static gboolean on_notification_imc_sms_memory_status(CoreObject *co,
446         const void *event_info, void *user_data)
447 {
448         gboolean memory_status = TRUE;
449
450         GSList *tokens = NULL;
451         GSList *lines = NULL;
452         char *line = NULL , *line_token = NULL;
453         dbg(" Enter");
454
455         lines = (GSList *)event_info;
456         if (1 != g_slist_length(lines)) {
457                 dbg("Unsolicited msg but multiple line");
458                 return TRUE;
459         }
460
461         line = (char*)(lines->data);
462         if (line) {
463                 tokens = tcore_at_tok_new(line);
464                 line_token = g_slist_nth_data(tokens, 0);
465                 if (line_token) {
466                         /* SIM Full condition */
467                         if (0 == atoi(line_token))
468                                 memory_status = FALSE;
469
470                 /* Send notification */
471                 tcore_object_send_notification(co,
472                         TCORE_NOTIFICATION_SMS_MEMORY_STATUS,
473                         sizeof(gboolean), &memory_status);
474                 }
475                 tcore_at_tok_free(tokens);
476         } else {
477                 err("invalid message received");
478         }
479
480         return TRUE;
481 }
482
483 static void on_response_imc_class2_sms_incom_msg(TcorePending *p,
484         guint data_len, const void *data, void *user_data)
485 {
486         const TcoreAtResponse *at_resp = data;
487         CoreObject *co = tcore_pending_ref_core_object(p);
488         GSList *tokens = NULL;
489         char *gslist_line = NULL, *line_token = NULL;
490         char *byte_pdu = NULL, *hex_pdu = NULL;
491         gint sca_length = 0;
492         guint byte_pdu_len = 0;
493         TelSmsDatapackageInfo incoming_msg = { { 0 }, };
494         dbg("Enter");
495
496         if (at_resp && at_resp->success) {
497                 dbg("RESPONSE OK");
498                 if (!at_resp->lines) {
499                         err("Invalid Response Received");
500                         return;
501                 }
502                 /*
503                  * TCORE_AT_PDU:
504                  * Multi-line output
505                  *
506                  * Fetching First Line
507                  */
508                 gslist_line = (char *)at_resp->lines->data;
509                 dbg("gslist_line: [%s]", gslist_line);
510
511                 /* Tokenize */
512                 tokens = tcore_at_tok_new(gslist_line);
513                 dbg("Number of tokens: [%d]", g_slist_length(tokens));
514
515                 /* First Token : status (ignore)
516                  * Second Token: Alpha ID(ignore)
517                  * Third Token: PDU Length.
518                  */
519                 line_token = g_slist_nth_data(tokens, 2);
520                 if (line_token != NULL) {
521                         incoming_msg.tpdu_length = atoi(line_token);
522                         dbg("Length: [%d]", incoming_msg.tpdu_length);
523                 } else {
524                         err("Line Token for PDU Length is NULL");
525                         tcore_at_tok_free(tokens);
526                         return;
527                 }
528
529                 /* Fetching line: Second line is PDU */
530                 hex_pdu = (char *) at_resp->lines->next->data;
531                 dbg("EF-SMS PDU: [%s]", hex_pdu);
532
533                 if (NULL != hex_pdu) {
534                         tcore_util_hexstring_to_bytes(hex_pdu, &byte_pdu, &byte_pdu_len);
535                         sca_length = (int)byte_pdu[0];
536                         dbg("SCA Length [%d], msgLength: [%d]",
537                                 sca_length, incoming_msg.tpdu_length);
538
539                         if (ZERO == sca_length) {
540                                 memcpy(incoming_msg.tpdu, &byte_pdu[1],
541                                         incoming_msg.tpdu_length);
542                         } else {
543                                 char sca_toa;
544
545                                 /*
546                                  * byte_pdu[1] - sca_address_type
547                                  * Excluding sca_address_type and copy SCA
548                                  */
549                                 memcpy(incoming_msg.sca.number, &byte_pdu[2],
550                                         (sca_length - 1));
551
552                                 /*
553                                  * SCA Conversion: Address Type
554                                  * 3GPP TS 23.040 V6.5.0 Section: 9.1.2.5
555                                  */
556                                 sca_toa = byte_pdu[1];
557                                 incoming_msg.sca.npi = IMC_NUM_PLAN_ID(sca_toa);
558                                 incoming_msg.sca.ton = IMC_TYPE_OF_NUM(sca_toa);
559
560                                 memcpy(incoming_msg.tpdu,&byte_pdu[sca_length+1],
561                                         incoming_msg.tpdu_length);
562                         }
563                 }
564
565                 tcore_object_send_notification(co,
566                         TCORE_NOTIFICATION_SMS_INCOM_MSG,
567                         sizeof(TelSmsDatapackageInfo), &incoming_msg);
568                 tcore_at_tok_free(tokens);
569                 g_free(byte_pdu);
570         } else {
571                 err("RESPONSE NOK");
572         }
573 }
574
575 /*
576  * Notification
577  * +CMTI: <mem>,<index>
578  *
579  * where,
580  * <mem> memory location
581  * <index> index where msg is stored
582  */
583 static gboolean on_notification_imc_sms_class2_incoming_msg(CoreObject *co,
584         const void *event_info, void *user_data)
585 {
586         gchar *at_cmd = NULL;
587         TelReturn ret;
588         GSList *tokens = NULL , *lines = NULL;
589         char *line = NULL;
590         gint index, mem_type = 0;
591         dbg("Enter");
592
593         lines = (GSList *)event_info;
594         /* Fetch Line 1 */
595         line = (char *)g_slist_nth_data(lines, 0);
596         if (!line) {
597                 err("Line 1 is invalid");
598                 return TRUE;
599         }
600         dbg("Line 1: [%s]", line);
601
602         /* Split Line 1 into tokens */
603         tokens = tcore_at_tok_new(line);
604         /* Type of Memory stored */
605         mem_type = atoi(g_slist_nth_data(tokens, 0));
606         dbg("mem_type = [%d]", mem_type);
607         index = atoi((char *) g_slist_nth_data(tokens, 1));
608         dbg("index: [%d]", index);
609         /* Free resources */
610         tcore_at_tok_free(tokens);
611
612         /*
613          * Operation - read_sms_in_sim
614          *
615          * Request -
616          * AT-Command: At+CMGR=<index>
617          *  where
618          * <index> index of the message to be read.
619          *
620          * Response -
621          * Success: (PDU: Multi-line output)
622          * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
623          *
624          * Failure:
625          *      +CMS ERROR: <error>
626          */
627
628         /* AT Command */
629         at_cmd = g_strdup_printf("AT+CMGR=%d", index);
630
631         /* Send Request to modem */
632         ret = tcore_at_prepare_and_send_request(co,
633                 at_cmd, "+CMGR:",
634                 TCORE_AT_COMMAND_TYPE_PDU,
635                 NULL,
636                 on_response_imc_class2_sms_incom_msg, NULL,
637                 on_send_imc_request, NULL);
638
639         if (ret != TEL_RETURN_SUCCESS) {
640                 err("Failed to Read Class2 Incomming Message");
641         }
642         g_free(at_cmd);
643         return TRUE;
644 }
645
646 static void on_response_imc_sms_send_more_msg(TcorePending *p,
647         guint data_len, const void *data, void *user_data)
648 {
649         const TcoreAtResponse *at_resp = data;
650
651         dbg("Enter");
652
653         if (at_resp && at_resp->success)
654                 dbg("Response OK for AT+CMMS: More msgs to send!!");
655         else
656                 err("Response NOK for AT+CMMS: More msgs to send");
657
658         /* Need not send any response */
659 }
660
661 static void on_response_imc_sms_send_sms(TcorePending *p,
662         guint data_len, const void *data, void *user_data)
663 {
664         const TcoreAtResponse *at_resp = data;
665         CoreObject *co = tcore_pending_ref_core_object(p);
666         ImcRespCbData *resp_cb_data = user_data;
667
668         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
669         dbg("Enter");
670
671         tcore_check_return_assert(co != NULL);
672         tcore_check_return_assert(resp_cb_data != NULL);
673
674         if (at_resp && at_resp->success) {
675                 dbg("Response OK");
676                 if (at_resp->lines) {
677                         const gchar *line;
678                         gchar* line_token;
679                         GSList *tokens = NULL;
680                         gint msg_ref = 0;
681
682                         line = (const gchar *)at_resp->lines->data;
683                         tokens = tcore_at_tok_new(line);
684                         line_token = g_slist_nth_data(tokens, 0);
685                         if (line_token != NULL) {
686                                 /* Response from MODEM for send SMS: +CMGS:
687                                  *  <mr>[,<ackpdu>].
688                                  *
689                                  * Message Reference is not used by MSG_SERVER,
690                                  * and application. So Filling only result
691                                  */
692                                 msg_ref = atoi(line_token);
693                                 dbg("Message Reference: [%d]", msg_ref);
694                                 result = TEL_SMS_RESULT_SUCCESS;
695                         } else {
696                                 err("No Message Reference received");
697                         }
698                         tcore_at_tok_free(tokens);
699                 }
700         } else {
701                 err("RESPONSE NOK");
702                 result = __imc_sms_convert_cms_error_tel_sms_result(at_resp);
703         }
704
705         /* Invoke callback */
706         if (resp_cb_data->cb)
707                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
708
709         /* Free callback data */
710         imc_destroy_resp_cb_data(resp_cb_data);
711 }
712
713 static void on_response_imc_sms_write_sms_in_sim(TcorePending *p,
714         guint data_len, const void *data, void *user_data)
715 {
716         const TcoreAtResponse *at_resp = data;
717         CoreObject *co = tcore_pending_ref_core_object(p);
718         ImcRespCbData *resp_cb_data = user_data;
719
720         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
721         GSList *tokens = NULL;
722         char *line = NULL, *line_token = NULL;
723         gint index = -1;
724         dbg("Enter");
725
726         tcore_check_return_assert(co != NULL);
727         tcore_check_return_assert(resp_cb_data != NULL);
728         if (at_resp && at_resp->success) {
729                 dbg("Response OK");
730                 if (at_resp->lines) {
731                         line = (char *)at_resp->lines->data;
732                         tokens = tcore_at_tok_new(line);
733                         line_token = g_slist_nth_data(tokens, 0);
734                         if (line_token) {
735                                 index = atoi(line_token);
736                                 dbg("SMS written to '%d' index", index);
737                                 result = TEL_SMS_RESULT_SUCCESS;
738                         } else {
739                                 err("invalid message");
740                         }
741                 } else {
742                         err("Lines NOT present");
743                 }
744         } else {
745                 err("RESPONSE NOK");
746                 result = __imc_sms_convert_cms_error_tel_sms_result(at_resp);
747         }
748
749         /* Invoke callback */
750         if (resp_cb_data->cb)
751                 resp_cb_data->cb(co, (gint)result, &index, resp_cb_data->cb_data);
752
753         /* Free callback data */
754         imc_destroy_resp_cb_data(resp_cb_data);
755 }
756
757 static void on_response_imc_sms_read_sms_in_sim(TcorePending *p,
758         guint data_len, const void *data, void *user_data)
759 {
760         const TcoreAtResponse *at_resp = data;
761         CoreObject *co = tcore_pending_ref_core_object(p);
762         ImcRespCbData *resp_cb_data = user_data;
763         TelSmsSimDataInfo read_resp = {0,};
764         GSList *tokens = NULL;
765
766         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
767         dbg("Enter");
768
769         tcore_check_return_assert(co != NULL);
770         tcore_check_return_assert(resp_cb_data != NULL);
771
772         if (at_resp && at_resp->success) {
773                 dbg("RESPONSE OK");
774                 if (at_resp->lines) {
775                         gchar *gslist_line = NULL, *line_token = NULL;
776                         gchar *byte_pdu = NULL, *hex_pdu = NULL;
777                         gint msg_status = 0, pdu_len = 0, alpha_id = 0;
778                         gint sca_length = 0;
779                         guint byte_pdu_len = 0;
780
781                         /*
782                          * TCORE_AT_PDU:
783                          * Multi-line output
784                          *
785                          * Fetching First Line
786                          */
787                         gslist_line = (char *)at_resp->lines->data;
788                         dbg("gslist_line: [%s]", gslist_line);
789
790                         /* Tokenize */
791                         tokens = tcore_at_tok_new(gslist_line);
792                         dbg("Number of tokens: [%d]", g_slist_length(tokens));
793
794                         /* +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu> */
795                         /* First Token: Message status */
796                         line_token = g_slist_nth_data(tokens, 0);
797                         if (line_token == NULL) {
798                                 err("Invalid stat");
799                                 goto OUT;
800                         }
801
802                         msg_status = atoi(line_token);
803                         dbg("msg_status [%d]", msg_status);
804
805                         switch (msg_status) {
806                         case AT_MT_UNREAD:
807                                 read_resp.status = TEL_SMS_STATUS_MT_UNREAD;
808                         break;
809                         case AT_MT_READ:
810                                 read_resp.status = TEL_SMS_STATUS_MT_READ;
811                         break;
812                         case AT_MO_UNSENT:
813                                 read_resp.status = TEL_SMS_STATUS_MO_NOT_SENT;
814                         break;
815                         case AT_MO_SENT:
816                                 read_resp.status = TEL_SMS_STATUS_MO_SENT;
817                         break;
818                         case AT_ALL:
819                         default:
820                                 read_resp.status = TEL_SMS_STATUS_REPLACED;
821                         break;
822                         }
823
824                          /* Second Token: Alpha ID */
825                         line_token = g_slist_nth_data(tokens, 1);
826                         if (line_token != NULL) {
827                                 alpha_id = atoi(line_token);
828                                 dbg("alpha_id: [%d]", alpha_id);
829                         }
830
831                         /* Third Token: Length */
832                         line_token = g_slist_nth_data(tokens, 2);
833                         if (line_token == NULL) {
834                                 err("Invalid PDU length");
835                                 goto OUT;
836                         }
837                         pdu_len = atoi(line_token);
838                         dbg("PDU length: [%d]", pdu_len);
839
840                         /* Fetching line: Second line is PDU */
841                         hex_pdu = (char *) at_resp->lines->next->data;
842                         dbg("EF-SMS PDU: [%s]", hex_pdu);
843
844                         if (NULL == hex_pdu) {
845                                 err("Invalid Response Received");
846                                 goto OUT;
847                         }
848
849                         tcore_util_hex_dump("    ", sizeof(hex_pdu), (void *)hex_pdu);
850
851                         tcore_util_hexstring_to_bytes(hex_pdu, &byte_pdu, &byte_pdu_len);
852
853                         sca_length = byte_pdu[0];
854                         dbg("SCA length = %d", sca_length);
855                         if (sca_length) {
856                                 gchar *decoded_sca;
857                                 guint encoded_sca_len;
858
859                                 /*
860                                  * byte_pdu[1] - sca_address_type
861                                  * Excluding sca_address_type and copy SCA
862                                  */
863                                 encoded_sca_len = sca_length - 1;
864                                 decoded_sca =
865                                         tcore_util_convert_bcd_to_ascii(&byte_pdu[2],
866                                                 encoded_sca_len, encoded_sca_len * 2);
867
868                                 dbg("Decoded SCA: [%s]", decoded_sca);
869                                 memcpy(read_resp.data.sca.number, decoded_sca,
870                                         TEL_SMS_SCA_LEN_MAX);
871                                 tcore_free(decoded_sca);
872
873                                 /* SCA Conversion for Address type */
874                                 read_resp.data.sca.ton = IMC_TYPE_OF_NUM(byte_pdu[1]);
875                                 read_resp.data.sca.npi = IMC_NUM_PLAN_ID(byte_pdu[1]);
876                                 dbg("TON: [%d] NPI: [%d] SCA: [%s]",
877                                         read_resp.data.sca.ton, read_resp.data.sca.npi,
878                                         read_resp.data.sca.number);
879                         } else {
880                                 err("NO SCA Present");
881                         }
882
883                         /* TPDU */
884                         read_resp.data.tpdu_length  = pdu_len;
885                         if ((read_resp.data.tpdu_length > 0)
886                                 && (read_resp.data.tpdu_length <= TEL_SMS_SMDATA_SIZE_MAX)) {
887                                         memcpy(read_resp.data.tpdu, &byte_pdu[sca_length+1],
888                                                 read_resp.data.tpdu_length);
889                         } else {
890                                 warn("Invalid TPDU length: [%d]",
891                                         read_resp.data.tpdu_length);
892                         }
893
894                         result = TEL_SMS_RESULT_SUCCESS;
895                         g_free(byte_pdu);
896                 }
897
898         } else {
899                 err("RESPONSE NOK");
900                 result = __imc_sms_convert_cms_error_tel_sms_result(at_resp);
901         }
902 OUT:
903         /* Invoke callback */
904         if (resp_cb_data->cb)
905                 resp_cb_data->cb(co, (gint)result, &read_resp, resp_cb_data->cb_data);
906
907         /* Free callback data */
908         imc_destroy_resp_cb_data(resp_cb_data);
909
910         /* free the consumed token */
911         tcore_at_tok_free(tokens);
912 }
913
914 static void on_response_imc_sms_delete_sms_in_sim(TcorePending *p,
915         guint data_len, const void *data, void *user_data)
916 {
917         const TcoreAtResponse *at_resp = data;
918         CoreObject *co = tcore_pending_ref_core_object(p);
919         ImcRespCbData *resp_cb_data = user_data;
920
921         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
922         dbg("Enter");
923
924         tcore_check_return_assert(co != NULL);
925         tcore_check_return_assert(resp_cb_data != NULL);
926
927         if (at_resp && at_resp->success) {
928                 dbg("Response OK");
929                 result = TEL_SMS_RESULT_SUCCESS;
930         } else {
931                 err("RESPONSE NOK");
932                 result = __imc_sms_convert_cms_error_tel_sms_result(at_resp);
933         }
934
935         /* Invoke callback */
936         if (resp_cb_data->cb)
937                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
938
939         /* Free callback data */
940         imc_destroy_resp_cb_data(resp_cb_data);
941 }
942
943 static void on_response_imc_sms_get_msg_indices(TcorePending *p,
944         guint data_len, const void *data, void *user_data)
945 {
946         /* Response from get_count Request */
947         TelSmsStoredMsgCountInfo *count_info;
948         const TcoreAtResponse *at_resp = data;
949         CoreObject *co = tcore_pending_ref_core_object(p);
950         ImcRespCbData *resp_cb_data = user_data;
951         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
952         dbg("Enter");
953
954         tcore_check_return_assert(co != NULL);
955         tcore_check_return_assert(resp_cb_data != NULL);
956         count_info = (TelSmsStoredMsgCountInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
957
958         if (at_resp && at_resp->success) {
959                 dbg("RESPONSE OK");
960                 if (at_resp->lines) {
961                         gchar *gslist_line = NULL;
962                         gint gslist_line_count = 0, ctr_loop = 0;
963
964                         gslist_line_count = g_slist_length(at_resp->lines);
965
966                         if (gslist_line_count > TEL_SMS_GSM_MSG_NUM_MAX)
967                                 gslist_line_count = TEL_SMS_GSM_MSG_NUM_MAX;
968                         dbg("Number of lines: [%d]", gslist_line_count);
969
970                         for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
971                                 /* Fetch Line 'ctr_loop' */
972                                 gslist_line = (char *)g_slist_nth_data(at_resp->lines, ctr_loop);
973                                 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
974
975                                 if (NULL != gslist_line) {
976                                         GSList *tokens = NULL;
977                                         gchar *line_token = NULL;
978
979                                         tokens = tcore_at_tok_new(gslist_line);
980
981                                         line_token = g_slist_nth_data(tokens, 0);
982                                         if (NULL != line_token) {
983                                                 count_info->index_list[ctr_loop] =
984                                                         atoi(line_token);
985                                         } else {
986                                                 dbg("line_token of gslist_line [%d] is NULL",
987                                                         ctr_loop);
988                                         }
989
990                                         tcore_at_tok_free(tokens);
991                                 } else {
992                                         err("gslist_line is NULL");
993                                         goto OUT;
994                                 }
995                         }
996
997                         result = TEL_SMS_RESULT_SUCCESS;
998                 } else {
999                         err("Invalid Response received. No Lines present in response");
1000                         /* Check if used count is zero*/
1001                         if (count_info->used_count == 0)
1002                                 result = TEL_SMS_RESULT_SUCCESS;
1003                 }
1004         }  else {
1005                 err("RESPONSE NOK");
1006                 result = __imc_sms_convert_cms_error_tel_sms_result(at_resp);
1007         }
1008
1009 OUT:
1010         dbg("get msg indices: [%s]",
1011                         (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1012
1013         /* Invoke callback */
1014         if (resp_cb_data->cb)
1015                 resp_cb_data->cb(co, (gint)result, count_info, resp_cb_data->cb_data);
1016
1017         /* Free callback data */
1018         imc_destroy_resp_cb_data(resp_cb_data);
1019 }
1020
1021 static void on_response_imc_sms_get_sms_count(TcorePending *p,
1022         guint data_len, const void *data, void *user_data)
1023 {
1024         gchar *at_cmd;
1025         TelReturn ret;
1026         TelSmsStoredMsgCountInfo count_info = {0, };
1027         int used_count = 0, total_count = 0;
1028         const TcoreAtResponse *at_resp = data;
1029         CoreObject *co = tcore_pending_ref_core_object(p);
1030         ImcRespCbData *resp_cb_data = user_data;
1031         ImcRespCbData *getcnt_resp_cb_data;
1032         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1033         dbg("Enter");
1034
1035         tcore_check_return_assert(co != NULL);
1036         tcore_check_return_assert(resp_cb_data != NULL);
1037
1038         if (at_resp && at_resp->success) {
1039                 dbg("RESPONSE OK");
1040                 if (at_resp->lines) {
1041                         GSList *tokens = NULL;
1042                         gchar *line = NULL, *line_token = NULL;
1043
1044                         line = (gchar *)at_resp->lines->data;
1045                         dbg("line: [%s]", line);
1046
1047                         /*
1048                          * Tokenize
1049                          *
1050                          * +CPMS: <used1>, <total1>, <used2>, <total2>,
1051                          * <used3>, <total3>
1052                          */
1053                         tokens = tcore_at_tok_new(line);
1054
1055                         /* <used1> */
1056                         line_token = g_slist_nth_data(tokens, 0);
1057                         if (!line_token) {
1058                                 err("Line Token for used count is NULL");
1059                                 tcore_at_tok_free(tokens);
1060                                 goto OUT;
1061                         }
1062                         used_count = atoi(line_token);
1063                         dbg("used count [%d]", used_count);
1064
1065                         /* <total1> */
1066                         line_token = g_slist_nth_data(tokens, 1);
1067                         if (!line_token) {
1068                                 err("Line Token for Total count is NULL");
1069                                 tcore_at_tok_free(tokens);
1070                                 goto OUT;
1071                         }
1072                         total_count = atoi(line_token);
1073                         count_info.total_count = total_count;
1074                         count_info.used_count = used_count;
1075                         dbg("Count - used: [%d] total: [%d]", used_count, total_count);
1076
1077                         /*
1078                          * Operation - get_msg_indices_in_sim
1079                          *
1080                          * Request -
1081                          * AT-Command: AT+CMGL
1082                          * +CPMS=<mem1>[, <mem2>[,<mem3>]]
1083                          * where
1084                          * <mem1> memory storage to read.
1085                          *
1086                          * Response -
1087                          * Success: (Multi-line output)
1088                          * +CMGL=<stat>]
1089                          *
1090                          * <stat> status of the message.
1091                          * Failure:
1092                          * +CMS ERROR: <error>
1093                          */
1094
1095                         /* Sending the Second AT Request to fetch msg indices */
1096                         at_cmd = g_strdup_printf("AT+CMGL=4");
1097
1098                         /* Response callback data */
1099                         getcnt_resp_cb_data = imc_create_resp_cb_data(resp_cb_data->cb,
1100                                         resp_cb_data->cb_data,
1101                                         &count_info, sizeof(TelSmsStoredMsgCountInfo));
1102
1103                         /* Free previous request callback data */
1104                         imc_destroy_resp_cb_data(resp_cb_data);
1105                         resp_cb_data = NULL;
1106                         /* free the consumed token */
1107                         tcore_at_tok_free(tokens);
1108
1109                         /* Send Request to modem */
1110                         ret = tcore_at_prepare_and_send_request(co,
1111                                 at_cmd, "+CMGL",
1112                                 TCORE_AT_COMMAND_TYPE_MULTILINE,
1113                                 NULL,
1114                                 on_response_imc_sms_get_msg_indices,
1115                                 getcnt_resp_cb_data,
1116                                 on_send_imc_request, NULL);
1117
1118                         g_free(at_cmd);
1119                         if (ret != TEL_RETURN_SUCCESS) {
1120                                 err("Failed to Process Get Msg Indices Request");
1121                                 imc_destroy_resp_cb_data(getcnt_resp_cb_data);
1122                                 goto OUT;
1123                         }
1124                         dbg("Exit");
1125                         return;
1126
1127                 } else {
1128                         err("Invalid Response Received: NO Lines Present");
1129                 }
1130         } else {
1131                 err("RESPONSE NOK");
1132                 result = __imc_sms_convert_cms_error_tel_sms_result(at_resp);
1133         }
1134
1135 OUT:
1136         dbg("Get sms count: [%s]",
1137                         (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1138
1139         /* Invoke callback in case of error*/
1140         if (resp_cb_data->cb)
1141                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1142
1143         /* Free callback data */
1144         imc_destroy_resp_cb_data(resp_cb_data);
1145 }
1146
1147 static void on_response_imc_sms_set_sca(TcorePending *p,
1148         guint data_len, const void *data, void *user_data)
1149 {
1150         const TcoreAtResponse *at_resp = data;
1151         CoreObject *co = tcore_pending_ref_core_object(p);
1152         ImcRespCbData *resp_cb_data = user_data;
1153
1154         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1155         dbg("Enter");
1156
1157         tcore_check_return_assert(co != NULL);
1158         tcore_check_return_assert(resp_cb_data != NULL);
1159
1160         if (at_resp && at_resp->success) {
1161                 dbg("Response OK");
1162                 result = TEL_SMS_RESULT_SUCCESS;
1163         } else {
1164                 err("Response NOK");
1165         }
1166
1167         dbg("Set sca: [%s]",
1168                 (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1169
1170         /* Invoke callback */
1171         if (resp_cb_data->cb)
1172                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1173
1174         /* Free callback data */
1175         imc_destroy_resp_cb_data(resp_cb_data);
1176 }
1177
1178 static void on_response_imc_sms_get_sca(TcorePending *p,
1179         guint data_len, const void *data, void *user_data)
1180 {
1181         const TcoreAtResponse *at_resp = data;
1182         CoreObject *co = tcore_pending_ref_core_object(p);
1183         ImcRespCbData *resp_cb_data = user_data;
1184
1185         TelSmsSca sca_resp = { 0, };
1186         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1187         dbg("Enter");
1188
1189         tcore_check_return_assert(co != NULL);
1190         tcore_check_return_assert(resp_cb_data != NULL);
1191
1192         if (at_resp && at_resp->success) {
1193                 dbg("Response OK");
1194                 if (at_resp->lines) {
1195                         GSList *tokens = NULL;
1196                         const char *sca_tok_addr;
1197                         gchar *line = NULL, *sca_addr = NULL;
1198                         gint hexa_toa = 0;
1199                         gchar *sca_toa = NULL;
1200
1201                         line = (gchar *)at_resp->lines->data;
1202                         tokens = tcore_at_tok_new(line);
1203                         sca_tok_addr = g_slist_nth_data(tokens, 0);
1204                         sca_toa = g_slist_nth_data(tokens, 1);
1205
1206                         sca_addr = tcore_at_tok_extract(sca_tok_addr);
1207                         dbg("SCA: [%s] SCA-TOA: [%s]", sca_addr, sca_toa);
1208                         if ((NULL != sca_addr) && (NULL != sca_toa)) {
1209                                 memcpy(sca_resp.number, sca_addr, strlen(sca_addr));
1210
1211                                 hexa_toa = atoi(sca_toa);
1212                                 dbg("SCA-TOA: [0x%x]", hexa_toa);
1213                                 sca_resp.npi = hexa_toa & 0x0F;
1214                                 sca_resp.ton = (hexa_toa & 0x70) >> 4;
1215                                 result = TEL_SMS_RESULT_SUCCESS;
1216                         } else {
1217                                 err("SCA is NULL");
1218                         }
1219                         tcore_at_tok_free(tokens);
1220                         g_free(sca_addr);
1221                 } else {
1222                         err("Invalid RESPONSE. No Lines Received");
1223                 }
1224         } else {
1225                 err("RESPONSE NOK");
1226                 result = __imc_sms_convert_cms_error_tel_sms_result(at_resp);
1227         }
1228
1229         dbg("Get sca: [%s]",
1230                 (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1231
1232         /* Invoke callback */
1233         if (resp_cb_data->cb)
1234                 resp_cb_data->cb(co, (gint)result, &sca_resp, resp_cb_data->cb_data);
1235
1236         /* Free callback data */
1237         imc_destroy_resp_cb_data(resp_cb_data);
1238 }
1239
1240 static void on_response_imc_sms_set_cb_config(TcorePending *p,
1241         guint data_len, const void *data, void *user_data)
1242 {
1243         const TcoreAtResponse *at_resp = data;
1244         CoreObject *co = tcore_pending_ref_core_object(p);
1245         ImcRespCbData *resp_cb_data = user_data;
1246
1247         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1248         dbg("Enter");
1249
1250         tcore_check_return_assert(co != NULL);
1251         tcore_check_return_assert(resp_cb_data != NULL);
1252
1253         if (at_resp && at_resp->success) {
1254                 dbg("Response OK");
1255                 result = TEL_SMS_RESULT_SUCCESS;
1256         } else {
1257                 err("RESPONSE NOK");
1258                 result = __imc_sms_convert_cme_error_tel_sms_result(at_resp);
1259         }
1260
1261         dbg("Set cb config: [%s]",
1262                 (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1263
1264         /* Invoke callback */
1265         if (resp_cb_data->cb)
1266                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1267
1268         /* Free callback data */
1269         imc_destroy_resp_cb_data(resp_cb_data);
1270 }
1271
1272 static void on_response_imc_sms_get_cb_config(TcorePending *p,
1273         guint data_len, const void *data, void *user_data)
1274 {
1275         const TcoreAtResponse *at_resp = data;
1276         CoreObject *co = tcore_pending_ref_core_object(p);
1277         ImcRespCbData *resp_cb_data = user_data;
1278
1279         TelSmsCbConfigInfo get_cb_conf = {0, };
1280         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1281         dbg("Enter");
1282
1283         tcore_check_return_assert(co != NULL);
1284         tcore_check_return_assert(resp_cb_data != NULL);
1285
1286         if (at_resp && at_resp->success) {
1287                 dbg("Response OK");
1288                 if (at_resp->lines) {
1289                         GSList *tokens = NULL;
1290                         gchar *data = NULL, *line = NULL;
1291                         gchar *msg_ids = NULL;
1292                         GSList *cb_tokens = NULL;
1293                         gint num_cb_tokens = 0;
1294                         gchar *mid_tok = NULL;
1295                         gint i = 0, mode = 0;
1296                         gchar *first_tok = NULL, *second_tok = NULL;
1297                         gchar delim[] = "-";
1298
1299                         line = (gchar*)at_resp->lines->data;
1300                         if (!line) {
1301                                 err("Line is NULL");
1302                                 goto OUT;
1303                         }
1304
1305                         tokens = tcore_at_tok_new(line);
1306                         /*
1307                          * Response -
1308                          * +CSCB: <mode>,<mids>,<dcss>
1309                          */
1310                         data = g_slist_nth_data(tokens, 0);
1311                         if (data) {
1312                                 mode = atoi(data);
1313                                 dbg("mode:[%d]", mode);
1314                                 get_cb_conf.cb_enabled = mode;
1315                         } else {
1316                                 err("Line Token for Mode is NULL");
1317                                 tcore_at_tok_free(tokens);
1318                                 goto OUT;
1319                         }
1320
1321                         data = g_slist_nth_data(tokens, 1);
1322                         if (!data) {
1323                                 err("Line Token for MID is NULL");
1324                                 tcore_at_tok_free(tokens);
1325                                 goto OUT;
1326                         }
1327                         msg_ids = tcore_at_tok_extract(data);
1328                         cb_tokens = tcore_at_tok_new((const char *)msg_ids);
1329                         num_cb_tokens = g_slist_length(cb_tokens);
1330                         dbg("num_cb_tokens = %d", num_cb_tokens);
1331
1332                         if (num_cb_tokens == 0) {
1333                                 if (mode == 1) { /* All CBS Enabled */
1334                                         get_cb_conf.msg_id_range_cnt = 1;
1335                                         get_cb_conf.msg_ids[0].from_msg_id = 0x0000;
1336                                         get_cb_conf.msg_ids[0].to_msg_id =
1337                                                 TEL_SMS_GSM_CBMI_LIST_SIZE_MAX + 1;
1338                                         get_cb_conf.msg_ids[0].selected = TRUE;
1339                                 } else { /* All CBS Disabled */
1340                                         get_cb_conf.msg_id_range_cnt = 0;
1341                                         get_cb_conf.msg_ids[0].selected = FALSE;
1342                                 }
1343                         }
1344
1345                         for (i = 0; i < num_cb_tokens; i++) {
1346                                 get_cb_conf.msg_ids[i].selected = TRUE;
1347                                 dbg("msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
1348
1349                                 get_cb_conf.msg_id_range_cnt++;
1350                                 dbg("Incremented msgIdRangeCount:[%d]",
1351                                         get_cb_conf.msg_id_range_cnt);
1352
1353                                 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1354                                 first_tok = strtok(mid_tok, delim);
1355                                 second_tok = strtok(NULL, delim);
1356
1357                                 /* mids in range (320-478) */
1358                                 if ((first_tok != NULL) && (second_tok != NULL)) {
1359                                         get_cb_conf.msg_ids[i].from_msg_id = atoi(first_tok);
1360                                         get_cb_conf.msg_ids[i].to_msg_id = atoi(second_tok);
1361                                 } else { /* single mid value (0,1,5, 922)*/
1362                                         get_cb_conf.msg_ids[i].from_msg_id = atoi(mid_tok);
1363                                         get_cb_conf.msg_ids[i].to_msg_id = atoi(mid_tok);
1364                                 }
1365                         }
1366
1367                         result = TEL_SMS_RESULT_SUCCESS;
1368                         tcore_at_tok_free(tokens);
1369                         tcore_at_tok_free(cb_tokens);
1370                         g_free(msg_ids);
1371                 } else {
1372                         err("Invalid Response.No Lines Received");
1373                 }
1374         } else {
1375                 err("RESPONSE NOK");
1376                 result = __imc_sms_convert_cme_error_tel_sms_result(at_resp);
1377         }
1378
1379 OUT:
1380         dbg("Get cb config: [%s]",
1381                 (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1382
1383         /* Invoke callback */
1384         if (resp_cb_data->cb)
1385                 resp_cb_data->cb(co, (gint)result, &get_cb_conf, resp_cb_data->cb_data);
1386
1387         /* Free callback data */
1388         imc_destroy_resp_cb_data(resp_cb_data);
1389 }
1390
1391 static void on_response_imc_sms_set_memory_status(TcorePending *p,
1392         guint data_len, const void *data, void *user_data)
1393 {
1394         const TcoreAtResponse *at_resp = data;
1395         CoreObject *co = tcore_pending_ref_core_object(p);
1396         ImcRespCbData *resp_cb_data = user_data;
1397
1398         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1399         dbg("Enter");
1400
1401         tcore_check_return_assert(co != NULL);
1402         tcore_check_return_assert(resp_cb_data != NULL);
1403
1404         if (at_resp && at_resp->success) {
1405                 dbg("Response OK");
1406                 result = TEL_SMS_RESULT_SUCCESS;
1407         } else {
1408                 err("RESPONSE NOK");
1409                 result = __imc_sms_convert_cme_error_tel_sms_result(at_resp);
1410         }
1411
1412         dbg("Set memory status: [%s]",
1413                 (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1414         /* Invoke callback */
1415         if (resp_cb_data->cb)
1416                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1417
1418         /* Free callback data */
1419         imc_destroy_resp_cb_data(resp_cb_data);
1420 }
1421
1422 static void on_response_imc_sms_set_message_status(TcorePending *p,
1423         guint data_len, const void *data, void *user_data)
1424 {
1425         const TcoreAtResponse *at_resp = data;
1426         CoreObject *co = tcore_pending_ref_core_object(p);
1427         ImcRespCbData *resp_cb_data = user_data;
1428
1429         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1430         dbg("Enter");
1431
1432         tcore_check_return_assert(co != NULL);
1433         tcore_check_return_assert(resp_cb_data != NULL);
1434
1435         if (at_resp && at_resp->success) {
1436                 dbg("RESPONSE OK");
1437                 if (at_resp->lines) {
1438                         gint response = 0, sw1 = 0, sw2 = 0;
1439                         const char *line = NULL;
1440                         gchar *data = NULL;
1441                         GSList *tokens = NULL;
1442
1443                         line = (const char *) at_resp->lines->data;
1444                         tokens = tcore_at_tok_new(line);
1445                         data = g_slist_nth_data(tokens, 0);
1446                         if (data != NULL) {
1447                                 sw1 = atoi(data);
1448                         } else {
1449                                 dbg("sw1 is NULL");
1450                         }
1451
1452                         data = g_slist_nth_data(tokens, 1);
1453                         if (data != NULL) {
1454                                 sw2 = atoi(data);
1455                                 if ((sw1 == 0x90) && (sw2 == 0)) {
1456                                         result = TEL_SMS_RESULT_SUCCESS;
1457                                 }
1458                         } else {
1459                                 dbg("sw2 is NULL");
1460                         }
1461
1462                         data = g_slist_nth_data(tokens, 3);
1463                         if (data != NULL) {
1464                                 response = atoi(data);
1465                                 dbg("response is %s", response);
1466                         }
1467                         tcore_at_tok_free(tokens);
1468                 } else {
1469                         err("No lines");
1470                 }
1471         } else {
1472                 err("RESPONSE NOK");
1473                 result = __imc_sms_convert_cme_error_tel_sms_result(at_resp);
1474         }
1475
1476         dbg("Set message status: [%s]",
1477                 (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1478
1479         /* Invoke callback */
1480         if (resp_cb_data->cb)
1481                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1482
1483         /* Free callback data */
1484         imc_destroy_resp_cb_data(resp_cb_data);
1485 }
1486
1487 static void _response_get_efsms_data(TcorePending *p,
1488         guint data_len, const void *data, void *user_data)
1489 {
1490         gchar *at_cmd;
1491         const TcoreAtResponse *at_resp = data;
1492         CoreObject *co = tcore_pending_ref_core_object(p);
1493         ImcRespCbData *resp_cb_data = user_data;
1494
1495         TelSmsStatusInfo *status_info;
1496         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1497         TelReturn ret;
1498         dbg("Enter");
1499
1500         tcore_check_return_assert(co != NULL);
1501         tcore_check_return_assert(resp_cb_data != NULL);
1502
1503         status_info = (TelSmsStatusInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1504         if (at_resp && at_resp->success) {
1505                 dbg("RESPONSE OK");
1506                 if (at_resp->lines) {
1507                         char *encoded_data = NULL;
1508                         int encoded_len = 0;
1509                         char msg_status = 0;
1510                         char *line_token = NULL;
1511                         GSList *tokens = NULL;
1512                         const char *line = NULL;
1513                         gint sw1 = 0, sw2 = 0;
1514
1515                         line = (const char *) at_resp->lines->data;
1516                         tokens = tcore_at_tok_new(line);
1517
1518                         sw1 = atoi(g_slist_nth_data(tokens, 0));
1519                         sw2 = atoi(g_slist_nth_data(tokens, 1));
1520                         line_token = g_slist_nth_data(tokens, 2);
1521                         encoded_len = strlen(line_token);
1522
1523                         dbg("line_token:[%s], Length of line token:[%d]",
1524                                 line_token, encoded_len);
1525
1526                         encoded_data = tcore_malloc0(2 * encoded_len + 1);
1527                         memcpy(encoded_data, line_token, encoded_len);
1528                         dbg("encoded_data: [%s]", encoded_data);
1529
1530                         if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1531                                 switch (status_info->status) {
1532                                 case TEL_SMS_STATUS_MT_READ:
1533                                         msg_status = 0x01;
1534                                 break;
1535
1536                                 case TEL_SMS_STATUS_MT_UNREAD:
1537                                         msg_status = 0x03;
1538                                 break;
1539
1540                                 case TEL_SMS_STATUS_MO_NOT_SENT:
1541                                         msg_status = 0x07;
1542                                 break;
1543
1544                                 case TEL_SMS_STATUS_MO_SENT:
1545                                         msg_status = 0x05;
1546                                 break;
1547
1548                                 case TEL_SMS_STATUS_MO_DELIVERED:
1549                                         msg_status = 0x1D;
1550                                 break;
1551
1552                                 case TEL_SMS_STATUS_MO_DELIVERY_NOT_CONFIRMED:
1553                                         msg_status = 0xD;
1554                                 break;
1555
1556                                 case TEL_SMS_STATUS_REPLACED:/*Fall Through*/
1557                                 default:
1558                                         msg_status = 0x03;
1559                                 break;
1560                                 }
1561                         }
1562                         /* overwrite Status byte information */
1563                         tcore_util_byte_to_hex((const char *)&msg_status, encoded_data, 1);
1564
1565                         /*
1566                          * Updating EF-SMS File with status byte
1567                          * Rest 175 bytes are same as received in Read Record
1568                          *
1569                          */
1570                         at_cmd = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"",
1571                                         (status_info->index), IMC_AT_EF_SMS_RECORD_LEN, encoded_data);
1572
1573                         /* Send Request to modem */
1574                         ret = tcore_at_prepare_and_send_request(co,
1575                                 at_cmd, "+CRSM:",
1576                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1577                                 NULL,
1578                                 on_response_imc_sms_set_message_status,
1579                                 resp_cb_data,
1580                                 on_send_imc_request, NULL);
1581                         IMC_CHECK_REQUEST_RET(ret, resp_cb_data,
1582                                 "Set Message Status-Updating status in Record");
1583
1584                         g_free(encoded_data);
1585                         g_free(status_info);
1586                         tcore_at_tok_free(tokens);
1587                         return;
1588                 } else {
1589                         err("Invalid Response Received");
1590                 }
1591         }
1592         else {
1593                 err("RESPONSE NOK");
1594                 result = __imc_sms_convert_cme_error_tel_sms_result(at_resp);
1595         }
1596
1597         dbg("get efsms status: [%s]",
1598                 (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1599
1600         /* Invoke callback */
1601         if (resp_cb_data->cb)
1602                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1603
1604         /* Free callback data */
1605         imc_destroy_resp_cb_data(resp_cb_data);
1606 }
1607
1608 static void on_response_imc_sms_get_sms_params(TcorePending *p,
1609         guint data_len, const void *data, void *user_data)
1610 {
1611         const TcoreAtResponse *at_resp = data;
1612         CoreObject *co = tcore_pending_ref_core_object(p);
1613         ImcRespCbData *resp_cb_data = user_data;
1614         ImcSmsParamsCbData *params_req_data;
1615         gint sw1 = 0, sw2 = 0, decoding_length = 0;
1616         const char *line = NULL;
1617         char *hex_data = NULL, *record_data = NULL;
1618         GSList *tokens = NULL;
1619
1620         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1621         dbg("Enter");
1622
1623         params_req_data = (ImcSmsParamsCbData *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1624
1625         if (at_resp && at_resp->success) {
1626                 dbg("RESPONSE OK");
1627                 if (at_resp->lines) {
1628                         line = (const char *) at_resp->lines->data;
1629                         tokens = tcore_at_tok_new(line);
1630
1631                         sw1 = atoi(g_slist_nth_data(tokens, 0));
1632                         sw2 = atoi(g_slist_nth_data(tokens, 1));
1633                         dbg("sw1 [0x%x], sw2[0x%x]", sw1, sw2);
1634
1635                         if (!(sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1636                                 err("invalid response received");
1637                                 goto OUT;
1638                         }
1639
1640                         hex_data = g_slist_nth_data(tokens, 2);
1641                         if (hex_data == NULL) {
1642                                 err("invalid response received");
1643                                 goto OUT;
1644                         }
1645
1646                         hex_data = tcore_at_tok_extract((const gchar *)hex_data);
1647                         tcore_util_hexstring_to_bytes(hex_data, &record_data, (guint*)&decoding_length);
1648                         tcore_free(hex_data);
1649                         /*
1650                         * Decrementing the Record Count and Filling the ParamsInfo List
1651                         * Final RESPONSE will be posted when Record count is ZERO
1652                         */
1653                         params_req_data->params[params_req_data->index].index = params_req_data->index;
1654
1655                         tcore_util_decode_sms_parameters((unsigned char *)record_data,
1656                                         decoding_length,
1657                                         &params_req_data->params[params_req_data->index]);
1658
1659                         params_req_data->total_param_count -= 1;
1660
1661                         if (params_req_data->total_param_count == 0) {
1662                                 dbg("Reading all Records - Complete");
1663                                 result = TEL_SMS_RESULT_SUCCESS;
1664                                 goto OUT;
1665                         } else {
1666                                 gchar *at_cmd;
1667                                 TelReturn ret;
1668
1669                                 dbg("Reading all records incomplete [Pending - %d]",
1670                                         params_req_data->total_param_count);
1671
1672                                 params_req_data->index++;
1673
1674                                 /* AT-Command */
1675                                 at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
1676                                         params_req_data->index, params_req_data->record_length);
1677
1678                                 /* Send Request to modem */
1679                                 ret = tcore_at_prepare_and_send_request(co,
1680                                                 at_cmd, "+CRSM",
1681                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1682                                                 NULL,
1683                                                 on_response_imc_sms_get_sms_params, resp_cb_data,
1684                                                 on_send_imc_request, NULL);
1685                                 g_free(at_cmd);
1686
1687                                 if (ret != TEL_RETURN_SUCCESS) {
1688                                         err("Failed to process request - [%s]", "Get SMS Parameters");
1689                                         goto OUT;
1690                                 }
1691
1692                                 tcore_at_tok_free(tokens);
1693                                 return;
1694                         }
1695                 } else {
1696                         err("Invalid RESPONSE Received");
1697                 }
1698         } else {
1699                 err("RESPONSE NOK");
1700                 result = __imc_sms_convert_cme_error_tel_sms_result(at_resp);
1701         }
1702
1703 OUT:
1704         {
1705                 TelSmsParamsInfoList param_info_list = {0, };
1706                 if (result == TEL_SMS_RESULT_SUCCESS) {
1707                         param_info_list.params = params_req_data->params;
1708                         param_info_list.count = params_req_data->record_count;
1709                 }
1710
1711                 /* Invoke callback */
1712                 if (resp_cb_data->cb)
1713                         resp_cb_data->cb(co, (gint)result, (void *)&param_info_list, resp_cb_data->cb_data);
1714         }
1715
1716         /* Free resource */
1717         tcore_at_tok_free(tokens);
1718
1719         tcore_free(params_req_data->params);
1720         g_free(record_data);
1721
1722         /* Free callback data */
1723         imc_destroy_resp_cb_data(resp_cb_data);
1724 }
1725
1726 static void on_response_imc_sms_set_sms_params(TcorePending *p,
1727         guint data_len, const void *data, void *user_data)
1728 {
1729         const TcoreAtResponse *at_resp = data;
1730         CoreObject *co = tcore_pending_ref_core_object(p);
1731         ImcRespCbData *resp_cb_data = user_data;
1732         TelSmsResult result = TEL_SMS_RESULT_FAILURE;
1733         dbg("Enter");
1734
1735         tcore_check_return_assert(co != NULL);
1736         tcore_check_return_assert(resp_cb_data != NULL);
1737
1738         if (at_resp && at_resp->success) {
1739                 dbg("Response OK");
1740                 if (at_resp->lines) {
1741                         gint sw1 = 0 , sw2 = 0;
1742                         const char *line = NULL;
1743                         GSList *tokens = NULL;
1744
1745                         line = (const char *) at_resp->lines->data;
1746                         tokens = tcore_at_tok_new(line);
1747
1748                         sw1 = atoi(g_slist_nth_data(tokens, 0));
1749                         sw2 = atoi(g_slist_nth_data(tokens, 1));
1750
1751                         if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1752                                 result = TEL_SMS_RESULT_SUCCESS;
1753                         }
1754                         tcore_at_tok_free(tokens);
1755                 }
1756
1757         } else {
1758                 err("RESPONSE NOK");
1759                 result = __imc_sms_convert_cme_error_tel_sms_result(at_resp);
1760         }
1761
1762         dbg("set sms params: [%s]",
1763                 (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1764
1765         /* Invoke callback */
1766         if (resp_cb_data->cb)
1767                 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1768
1769         /* Free callback data */
1770         imc_destroy_resp_cb_data(resp_cb_data);
1771 }
1772
1773 static gboolean async_callback(gpointer data)
1774 {
1775         ImcRespCbData *resp_cb_data = data;
1776         CoreObject **co;
1777         TelSmsResult result = TEL_SMS_RESULT_SUCCESS;
1778
1779         co = ((CoreObject **)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data));
1780
1781         /* Invoke callback */
1782         if (resp_cb_data->cb)
1783                 resp_cb_data->cb(*co, (gint)result, NULL, resp_cb_data->cb_data);
1784
1785         /* Free callback data */
1786         imc_destroy_resp_cb_data(resp_cb_data);
1787
1788         return FALSE;
1789 }
1790
1791 /* SMS Operations */
1792 /*
1793  * Operation - send_sms
1794  *
1795  * Request -
1796  * AT-Command: AT+CMGS
1797  * For PDU mode (+CMGF=0):
1798  * +CMGS=<length><CR>
1799  * PDU is given<ctrl-Z/ESC>
1800  * where,
1801  * <length> Length of the pdu.
1802  * <PDU>    PDU to send.
1803  *
1804  * Response -
1805  * +CMGS: <mr>[,<ackpdu>]
1806  * OK
1807  * Failure:
1808  * +CMS ERROR: <error>
1809  */
1810 static TelReturn imc_sms_send_sms(CoreObject *co,
1811         const TelSmsSendInfo *send_info, TcoreObjectResponseCallback cb, void *cb_data)
1812 {
1813         gchar *at_cmd;
1814
1815         ImcRespCbData *resp_cb_data;
1816         TelReturn ret;
1817
1818         const unsigned char *tpdu_byte_data;
1819         gint tpdu_byte_len, pdu_byte_len;
1820         char buf[HEX_PDU_LEN_MAX];
1821         char pdu[PDU_LEN_MAX];
1822         dbg("Enter");
1823
1824         tpdu_byte_data = send_info->send_data.tpdu;
1825
1826         /* TPDU length is in byte */
1827         tpdu_byte_len = send_info->send_data.tpdu_length;
1828
1829         /* Use same Radio Resource Channel :More Messages to send*/
1830         dbg("More messages: [%d]", send_info->more_msgs);
1831
1832         /* Prepare PDU for hex encoding */
1833         pdu_byte_len = tcore_util_encode_pdu(&(send_info->send_data.sca),
1834                                 tpdu_byte_data, tpdu_byte_len, pdu);
1835         tcore_util_hex_dump("    ", pdu_byte_len, pdu);
1836
1837         tcore_util_encode_hex((unsigned char *)pdu, pdu_byte_len, buf);
1838
1839         /* Response callback data */
1840         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1841
1842         if (send_info->more_msgs == TRUE) {
1843                 /* AT Command: More Msgs to Send */
1844                 ret = tcore_at_prepare_and_send_request(co,
1845                         "AT+CMMS=1", "+CMMS:",
1846                         TCORE_AT_COMMAND_TYPE_SINGLELINE,
1847                         NULL,
1848                         on_response_imc_sms_send_more_msg, NULL,
1849                         on_send_imc_request, NULL);
1850                 IMC_CHECK_REQUEST_RET(ret, NULL, "More Msgs to Send");
1851         }
1852
1853         /* AT-Command : Send SMS*/
1854         at_cmd = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
1855
1856         /* Send Request to modem */
1857         ret = tcore_at_prepare_and_send_request(co,
1858                 at_cmd, "+CMGS:",
1859                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1860                 NULL,
1861                 on_response_imc_sms_send_sms, resp_cb_data,
1862                 on_send_imc_request, NULL);
1863         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send SMS");
1864
1865         /* Free resources */
1866         g_free(at_cmd);
1867
1868         return ret;
1869 }
1870
1871 /*
1872  * Operation - write_sms_in_sim
1873  *
1874  * Request -
1875  * AT-Command: AT+CMGW
1876  * AT+CMGW = <length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
1877  * where
1878  * <length>     length of the tpdu
1879  * <stat>       status of the message
1880  * <PDU>        PDu of the message
1881  *
1882  * Response -
1883  * +CMGW: <index>
1884  * Success: (Single line)
1885  *      OK
1886  * Failure:
1887  * +CMS ERROR: <error>
1888  */
1889 static TelReturn imc_sms_write_sms_in_sim(CoreObject *co,
1890         const TelSmsSimDataInfo *wdata, TcoreObjectResponseCallback cb, void *cb_data)
1891 {
1892         gchar *at_cmd;
1893
1894         ImcRespCbData *resp_cb_data;
1895         TelReturn ret;
1896
1897         const unsigned char *tpdu_byte_data;
1898         int tpdu_byte_len, pdu_byte_len;
1899         char buf[HEX_PDU_LEN_MAX];
1900         char hex_pdu[PDU_LEN_MAX];
1901         gint status = 0;
1902         dbg("Enter");
1903
1904         switch (wdata->status) {
1905         case TEL_SMS_STATUS_MT_UNREAD:
1906                 status = AT_MT_UNREAD;
1907         break;
1908
1909         case TEL_SMS_STATUS_MT_READ:
1910                 status = AT_MT_READ;
1911         break;
1912
1913         case TEL_SMS_STATUS_MO_NOT_SENT:
1914                 status = AT_MO_UNSENT;
1915         break;
1916
1917         case TEL_SMS_STATUS_MO_SENT:
1918                 status = AT_MO_SENT;
1919         break;
1920
1921         default:
1922                 err("Invalid Message Status");
1923                 return TEL_RETURN_INVALID_PARAMETER;
1924         }
1925         tpdu_byte_data = wdata->data.tpdu;
1926
1927         tpdu_byte_len = wdata->data.tpdu_length;
1928         dbg("TDPU length: [%d]", tpdu_byte_len);
1929
1930         /* Prepare PDU for hex encoding */
1931         pdu_byte_len = tcore_util_encode_pdu(&(wdata->data.sca),
1932                                 tpdu_byte_data, tpdu_byte_len, hex_pdu);
1933         tcore_util_hex_dump("    ", pdu_byte_len, hex_pdu);
1934
1935         tcore_util_encode_hex((unsigned char *)hex_pdu, pdu_byte_len, buf);
1936
1937         /*AT Command*/
1938         at_cmd = g_strdup_printf("AT+CMGW=%d,%d%c%s%c",
1939                         tpdu_byte_len, status, CR, buf, CTRL_Z);
1940
1941         /* Response callback data */
1942         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1943
1944         /* Send Request to modem */
1945         ret = tcore_at_prepare_and_send_request(co,
1946                 at_cmd, "+CMGW:",
1947                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1948                 NULL,
1949                 on_response_imc_sms_write_sms_in_sim, resp_cb_data,
1950                 on_send_imc_request, NULL);
1951         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Write SMS in SIM");
1952
1953         /* Free resources */
1954         g_free(at_cmd);
1955
1956         return ret;
1957 }
1958
1959 /*
1960  * Operation - read_sms_in_sim
1961  *
1962  * Request -
1963  * AT-Command: At+CMGR=<index>
1964  * where
1965  * <index> index of the message to be read.
1966  *
1967  * Response -
1968  * Success: (PDU: Multi-line output)
1969  * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
1970  *
1971  * Failure:
1972  * +CMS ERROR: <error>
1973  */
1974 static TelReturn imc_sms_read_sms_in_sim(CoreObject *co,
1975         unsigned int index, TcoreObjectResponseCallback cb, void *cb_data)
1976 {
1977         gchar *at_cmd;
1978
1979         ImcRespCbData *resp_cb_data;
1980         TelReturn ret;
1981         dbg("Enter");
1982
1983         /* AT+Command */
1984         at_cmd = g_strdup_printf("AT+CMGR=%d", index);
1985
1986         /* Response callback data */
1987         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, ZERO);
1988
1989         /* Send Request to modem */
1990         ret = tcore_at_prepare_and_send_request(co,
1991                 at_cmd, "+CMGR:",
1992                 TCORE_AT_COMMAND_TYPE_PDU,
1993                 NULL,
1994                 on_response_imc_sms_read_sms_in_sim, resp_cb_data,
1995                 on_send_imc_request, NULL);
1996         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read SMS in SIM");
1997
1998         /* Free resources */
1999         g_free(at_cmd);
2000
2001         return ret;
2002 }
2003
2004 /*
2005  * Operation - delete_sms_in_sim
2006  *
2007  * Request -
2008  * AT-Command: AT+CGMD
2009  * +CMGD=<index>[,<delflag>]
2010  *
2011  * Response -
2012  * Success: (NO RESULT) -
2013  * OK
2014  * Failure:
2015  * +CMS ERROR: <error>
2016  */
2017 static TelReturn imc_sms_delete_sms_in_sim(CoreObject *co,
2018         unsigned int index,
2019         TcoreObjectResponseCallback cb, void *cb_data)
2020 {
2021         gchar *at_cmd;
2022
2023         ImcRespCbData *resp_cb_data;
2024         TelReturn ret;
2025         dbg("Enter");
2026
2027         /* Response callback data */
2028         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2029         /*
2030          * TODO: Delete All Messages
2031          *
2032          * at_cmd = g_strdup_printf("AT+CMGD=0,4");
2033          * Need to convey MSG_SERVICE to pass an index of
2034          * guint value to delete all Messages.probably as 0.
2035          */
2036
2037         /* AT-Command */
2038         at_cmd = g_strdup_printf("AT+CMGD=%d,0", index); /* Delete specified index */
2039
2040         /* Send Request to modem */
2041         ret = tcore_at_prepare_and_send_request(co,
2042                 at_cmd, "+CMGD:",
2043                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2044                 NULL,
2045                 on_response_imc_sms_delete_sms_in_sim, resp_cb_data,
2046                 on_send_imc_request, NULL);
2047         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete SMS in SIM");
2048
2049         /* Free resources */
2050         g_free(at_cmd);
2051
2052         return ret;
2053 }
2054
2055 /*
2056  * Operation - get_sms_count_in_sim
2057  *
2058  * Request -
2059  * AT-Command: AT+CPMS
2060  * +CPMS=<mem1>[, <mem2>[,<mem3>]]
2061  * where
2062  * <mem1> memory storage to read.
2063  *
2064  * Response -
2065  * Success: (Single-line output)
2066  * +CPMS: <mem1>,<used1>,<total1>,<mem2>,<used2>,<total2>,
2067  * <mem3>,<used3>,<total3>
2068  * OK
2069  *
2070  * Failure:
2071  * +CMS ERROR: <error>
2072  */
2073 static TelReturn imc_sms_get_msg_count_in_sim(CoreObject *co,
2074         TcoreObjectResponseCallback cb, void *cb_data)
2075 {
2076         gchar *at_cmd;
2077
2078         ImcRespCbData *resp_cb_data;
2079         TelReturn ret;
2080         dbg("Enter");
2081
2082         /*AT Command*/
2083         at_cmd = g_strdup_printf("AT+CPMS=\"SM\"");
2084
2085         /* Response callback data */
2086         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2087
2088         /* Send Request to modem */
2089         ret = tcore_at_prepare_and_send_request(co,
2090                 at_cmd, "+CPMS",
2091                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2092                 NULL,
2093                 on_response_imc_sms_get_sms_count, resp_cb_data,
2094                 on_send_imc_request, NULL);
2095         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Count");
2096
2097         /* Free resources */
2098         g_free(at_cmd);
2099
2100         return ret;
2101 }
2102
2103 /*
2104  * Operation - set SCA
2105  *
2106  * Request -
2107  * AT-Command: AT+CSCA
2108  * AT+CSCA=<sca>[,<tosca>]
2109  * where
2110  * <sca> Service center number
2111  * <tosca> address type of SCA
2112  *
2113  * Response -
2114  * Success: No result
2115  * OK
2116  *
2117  * Failure:
2118  * +CMS ERROR: <error>
2119  */
2120  static TelReturn imc_sms_set_sca(CoreObject *co,
2121         const TelSmsSca *sca, TcoreObjectResponseCallback cb, void *cb_data)
2122 {
2123         gchar *at_cmd;
2124
2125         ImcRespCbData *resp_cb_data;
2126         TelReturn ret;
2127         gint address_type;
2128
2129         address_type = ((sca->ton << 4) | sca->npi ) | 0x80;
2130
2131         /* AT Command */
2132         at_cmd = g_strdup_printf("AT+CSCA=\"%s\",%d", sca->number, address_type);
2133
2134         /* Response callback data */
2135         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2136
2137         /* Send Request to modem */
2138         ret = tcore_at_prepare_and_send_request(co,
2139                 at_cmd, NULL,
2140                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2141                 NULL,
2142                 on_response_imc_sms_set_sca, resp_cb_data,
2143                 on_send_imc_request, NULL);
2144         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SCA");
2145
2146         /* Free resources */
2147         g_free(at_cmd);
2148
2149         return ret;
2150 }
2151
2152 /*
2153  * Operation - get SCA
2154  *
2155  * Request -
2156  * AT-Command: AT+CSCA?
2157  *
2158  * Response -
2159  * Success: Single-Line
2160  * +CSCA: <sca>,<tosca>
2161  * OK
2162  * where
2163  * <sca> Service center number
2164  * <tosca> address type of SCA
2165  *
2166  */
2167  static TelReturn imc_sms_get_sca(CoreObject *co,
2168         TcoreObjectResponseCallback cb, void *cb_data)
2169 {
2170         ImcRespCbData *resp_cb_data;
2171         TelReturn ret;
2172         dbg("Enter");
2173
2174         /* Response callback data */
2175         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2176
2177         /* Send Request to modem */
2178         ret = tcore_at_prepare_and_send_request(co,
2179                 "AT+CSCA?", "+CSCA",
2180                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2181                 NULL,
2182                 on_response_imc_sms_get_sca, resp_cb_data,
2183                 on_send_imc_request, NULL);
2184         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SCA");
2185
2186         return ret;
2187 }
2188
2189 /*
2190  * Operation - set_cb_config
2191  *
2192  * Request -
2193  * AT-Command: AT+CSCB
2194  * +CSCB=[<mode>[,<mids>[,<dcss>]]]
2195  *
2196  * Response -
2197  * Success
2198  * OK
2199  *
2200  * Failure:
2201  * +CME ERROR: <error>
2202  */
2203 static TelReturn imc_sms_set_cb_config(CoreObject *co,
2204         const TelSmsCbConfigInfo *cb_conf,
2205         TcoreObjectResponseCallback cb, void *cb_data)
2206 {
2207         gchar *at_cmd;
2208         ImcRespCbData *resp_cb_data;
2209         TelReturn ret;
2210         unsigned short ctr1 = 0, ctr2 = 0, msg_id_range = 0;
2211         unsigned short append_msg_id = 0;
2212         dbg("Enter");
2213
2214         if (cb_conf->msg_id_range_cnt != 0) {   /* Enable Specific Msgid's */
2215                 gchar *mids_str = NULL;
2216                 GString *mid_string = NULL;
2217                 at_cmd = NULL;
2218
2219                 mid_string = g_string_new("AT+CSCB=0,\"");
2220                 for (ctr1 = 0; ctr1 < cb_conf->msg_id_range_cnt; ctr1++) {
2221                         if (cb_conf->msg_ids[ctr1].selected == FALSE)
2222                                 continue;
2223                         msg_id_range = ((cb_conf->msg_ids[ctr1].to_msg_id) -
2224                                 (cb_conf->msg_ids[ctr1].from_msg_id));
2225
2226                         if (TEL_SMS_GSM_CBMI_LIST_SIZE_MAX <= msg_id_range) {
2227                                 mid_string = g_string_new("AT+CSCB=1"); /* Enable All CBS */
2228                                 break;
2229                         }
2230                         append_msg_id = cb_conf->msg_ids[ctr1].from_msg_id;
2231                         dbg( "%x", append_msg_id);
2232
2233                         for (ctr2 = 0; ctr2 <= msg_id_range; ctr2++) {
2234                                 mid_string = g_string_append(mid_string,
2235                                         g_strdup_printf("%d", append_msg_id));
2236                                 if (ctr2 == msg_id_range) {
2237                                         /* Mids string termination */
2238                                         mid_string = g_string_append(mid_string, "\"");
2239                                 } else {
2240                                         mid_string = g_string_append(mid_string, ",");
2241                                 }
2242                                 append_msg_id++;
2243                         }
2244                 }
2245                 mids_str = g_string_free(mid_string, FALSE);
2246                 at_cmd = g_strdup_printf("%s", mids_str);
2247                 g_free(mids_str);
2248         } else {
2249                 /* Enable or Disable MsgId's */
2250                 at_cmd = g_strdup_printf("AT+CSCB=%d", cb_conf->cb_enabled);
2251         }
2252
2253         /* Response callback data */
2254         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2255
2256         /* Send Request to modem */
2257         ret = tcore_at_prepare_and_send_request(co,
2258                 at_cmd, NULL,
2259                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2260                 NULL,
2261                 on_response_imc_sms_set_cb_config, resp_cb_data,
2262                 on_send_imc_request, NULL);
2263         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Cb Config");
2264
2265         /* Free resources */
2266         g_free(at_cmd);
2267
2268         return ret;
2269 }
2270
2271 /*
2272  * Operation - get_cb_config
2273  *
2274  * Request -
2275  * AT-Command: AT+CSCB
2276  * +CSCB?
2277  *
2278  * Response -
2279  * Success - (Single line)
2280  * +CSCB : <mode>,<mids>,<dcss>
2281  * OK
2282  *
2283  */
2284  static TelReturn imc_sms_get_cb_config(CoreObject *co,
2285         TcoreObjectResponseCallback cb, void *cb_data)
2286 {
2287         ImcRespCbData *resp_cb_data;
2288         TelReturn ret;
2289         dbg("Enter");
2290
2291         /* Response callback data */
2292         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2293
2294         /* Send Request to modem */
2295         ret = tcore_at_prepare_and_send_request(co,
2296                 "AT+CSCB?", NULL,
2297                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2298                 NULL,
2299                 on_response_imc_sms_get_cb_config, resp_cb_data,
2300                 on_send_imc_request, NULL);
2301         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Cb Config");
2302
2303         return ret;
2304 }
2305
2306 /*
2307  * Operation - send_deliver_report
2308  *
2309  * Request -
2310  * Modem Takes care of sending the ACK to the network
2311  *
2312  * Response -
2313  * Success: Default response always SUCCESS posted
2314  *
2315  */
2316 static TelReturn imc_sms_send_deliver_report(CoreObject *co,
2317         const TelSmsDeliverReportInfo *dr_info,
2318         TcoreObjectResponseCallback cb, void *cb_data)
2319 {
2320         ImcRespCbData *resp_cb_data;
2321         TelReturn ret = TEL_RETURN_FAILURE;
2322
2323         dbg("CP takes care of sending SMS ack to network for all "
2324                 "classes of SMS. Sending default success.!!!");
2325         ret =  TEL_RETURN_SUCCESS;
2326
2327         /* Response callback data */
2328         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2329                 (void *)&co, sizeof(CoreObject*));
2330
2331         g_idle_add(async_callback, (gpointer)resp_cb_data);
2332
2333         return ret;
2334 }
2335
2336
2337 /* Operation - set memory status
2338  *
2339  * Request -
2340  * AT-Command: AT+XTESM=<mem_capacity>
2341  * <mem_capacity> status of the external SMS storage which may be:
2342  * 0: memory capacity free
2343  * 1: memory capacity full
2344  *
2345  * Response -No Result
2346  * Success
2347  * OK
2348  *
2349  * Failure:
2350  * +CME ERROR: <error>
2351  */
2352 static TelReturn imc_sms_set_memory_status(CoreObject *co,
2353         gboolean available, TcoreObjectResponseCallback cb, void *cb_data)
2354 {
2355         gchar *at_cmd;
2356
2357         ImcRespCbData *resp_cb_data;
2358         TelReturn ret;
2359
2360         /*AT+Command*/
2361         at_cmd = g_strdup_printf("AT+XTESM=%d", available? 0: 1);
2362
2363         /* Response callback data */
2364         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2365
2366         /* Send Request to modem */
2367         ret = tcore_at_prepare_and_send_request(co,
2368                 at_cmd, NULL,
2369                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
2370                 NULL,
2371                 on_response_imc_sms_set_memory_status, resp_cb_data,
2372                 on_send_imc_request, NULL);
2373         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Memory Status");
2374
2375         /* Free resources */
2376         g_free(at_cmd);
2377
2378         return ret;
2379 }
2380
2381 /* Operation - set Message status
2382  *
2383  * Request -
2384  * AT-Command: AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2385  * p1 Index
2386  * p3 SMSP record length
2387  *
2388  *
2389  * Response -Single Line
2390  * Success
2391  * OK
2392  *
2393  * Failure:
2394  * +CME ERROR: <error>
2395  */
2396 static TelReturn imc_sms_set_message_status(CoreObject *co,
2397         const TelSmsStatusInfo *status_info,
2398         TcoreObjectResponseCallback cb, void *cb_data)
2399 {
2400         gchar *at_cmd;
2401
2402         ImcRespCbData *resp_cb_data;
2403         TelReturn ret;
2404
2405         /*AT+Command*/
2406         at_cmd = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d",
2407                 (status_info->index), IMC_AT_EF_SMS_RECORD_LEN);
2408
2409         /* Response callback data */
2410         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2411                 (void *)status_info, sizeof(TelSmsStatusInfo));
2412
2413         /* Send Request to modem */
2414         ret = tcore_at_prepare_and_send_request(co,
2415                 at_cmd, "+CRSM:",
2416                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2417                 NULL,
2418                 _response_get_efsms_data, resp_cb_data,
2419                 on_send_imc_request, NULL);
2420         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Message Status");
2421
2422         /* Free resources */
2423         g_free(at_cmd);
2424
2425         return ret;
2426 }
2427
2428 /*
2429  * Operation - get_sms_parameters
2430  *
2431  * Request -
2432  * AT-Command: AT+CRSM
2433  * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2434  *
2435  * Response -
2436  * Success: (Single-line output)
2437  * +CRSM:
2438  * <sw1>,<sw2>[,<response>]
2439  * OK
2440  *
2441  * Failure:
2442  * +CME ERROR: <error>
2443  */
2444 static TelReturn imc_sms_get_sms_params(CoreObject *co,
2445         TcoreObjectResponseCallback cb, void *cb_data)
2446 {
2447         TcorePlugin *plugin;
2448         ImcRespCbData *resp_cb_data;
2449         ImcSmsParamsCbData params_req_data = {0, };
2450         gint record_count = 0, smsp_record_len = 0;
2451
2452         gchar *at_cmd;
2453
2454         TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
2455
2456         dbg("Enter");
2457
2458         plugin = tcore_object_ref_plugin(co);
2459
2460         /* Get Record count and SMSP record length*/
2461         if (FALSE == (imc_sim_get_smsp_info(plugin, &record_count,
2462                                 &smsp_record_len))) {
2463                 err("Failed to get SMSP record Count and Record length");
2464                 return ret;
2465         }
2466
2467         dbg("Record Count: [%d] SMSP Record Length: [%d]",
2468                 record_count, smsp_record_len);
2469
2470         /* Allocate Memory for params list data */
2471         params_req_data.params = tcore_malloc0(sizeof(TelSmsParamsInfo) * record_count);
2472         /* Counter */
2473         params_req_data.total_param_count = record_count;
2474
2475         /* Actual count to be returned */
2476         params_req_data.record_count = record_count;
2477         /* SMSP record length */
2478         params_req_data.record_length = smsp_record_len;
2479
2480         /* RESPONSE callback data */
2481         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
2482                                         (void *)&params_req_data,
2483                                         sizeof(ImcSmsParamsCbData));
2484
2485         /* Starting the Index with 1 */
2486         params_req_data.index = 1;
2487
2488         /* AT-Command */
2489         at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
2490                 params_req_data.index, params_req_data.record_length);
2491
2492         /* Send Request to modem */
2493         ret = tcore_at_prepare_and_send_request(co,
2494                         at_cmd, "+CRSM",
2495                         TCORE_AT_COMMAND_TYPE_SINGLELINE,
2496                         NULL,
2497                         on_response_imc_sms_get_sms_params, resp_cb_data,
2498                         on_send_imc_request, NULL);
2499         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Parameters");
2500
2501         /* Free resources */
2502         if (ret != TEL_RETURN_SUCCESS)
2503                 tcore_free(params_req_data.params);
2504         g_free(at_cmd);
2505
2506         return ret;
2507 }
2508
2509 /*
2510  * Operation - set_sms_params
2511  *
2512  * Request -
2513  * AT-Command: AT+CRSM
2514  * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2515  *
2516  * Response -
2517  * Success: (Single-line output)
2518  * +CRSM:
2519  * <sw1>,<sw2>[,<response>]
2520  * OK
2521  *
2522  * Failure:
2523  *      +CME ERROR: <error>
2524  */
2525 static TelReturn imc_sms_set_sms_params(CoreObject *co,
2526         const TelSmsParamsInfo *params,
2527         TcoreObjectResponseCallback cb, void *cb_data)
2528 {
2529         gchar *at_cmd;
2530         ImcRespCbData *resp_cb_data;
2531         TelReturn ret;
2532
2533         TcorePlugin *plugin;
2534         gint smsp_record_len = 0;
2535         gchar *set_params_data = NULL;
2536         gchar *encoded_data = NULL;
2537         gint record_count;
2538         dbg("Enter");
2539
2540         plugin = tcore_object_ref_plugin(co);
2541
2542         if (FALSE  == imc_sim_get_smsp_info(plugin, &record_count, &smsp_record_len)) {
2543                 err("Failed to get SMSP record Count and Record length");
2544                 return TEL_RETURN_INVALID_PARAMETER;
2545         }
2546
2547         dbg("SMSP Record Length: [%d]", smsp_record_len);
2548
2549         /* Allocate memory for set_params_data */
2550         set_params_data = tcore_malloc0(smsp_record_len);
2551
2552         /* Allocate memory for encoded data*/
2553         encoded_data = tcore_malloc0((2*smsp_record_len)+1);
2554
2555         tcore_util_encode_sms_parameters((TelSmsParamsInfo *)params,
2556                 set_params_data, smsp_record_len);
2557         dbg("SCA Address: [%s]", params->sca.number);
2558
2559         tcore_util_byte_to_hex((const char *)set_params_data,
2560                 (char *)encoded_data, smsp_record_len);
2561
2562         /* RESPONSE callback data */
2563         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
2564
2565         /* AT+ Command*/
2566         at_cmd = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",
2567                 params->index, smsp_record_len, encoded_data);
2568         dbg("at_cmd  - %s", at_cmd);
2569         /* Send Request to modem */
2570         ret = tcore_at_prepare_and_send_request(co,
2571                 at_cmd, "+CRSM",
2572                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2573                 NULL,
2574                 on_response_imc_sms_set_sms_params, resp_cb_data,
2575                 on_send_imc_request, NULL);
2576         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SMS Parameters");
2577
2578         /* Free resources */
2579         g_free(at_cmd);
2580         g_free(set_params_data);
2581         g_free(encoded_data);
2582
2583         return ret;
2584 }
2585
2586 /* SMS Operations */
2587 static TcoreSmsOps imc_sms_ops = {
2588         .send_sms = imc_sms_send_sms,
2589         .read_in_sim = imc_sms_read_sms_in_sim,
2590         .write_in_sim = imc_sms_write_sms_in_sim,
2591         .delete_in_sim = imc_sms_delete_sms_in_sim,
2592         .get_count = imc_sms_get_msg_count_in_sim,
2593         .set_cb_config = imc_sms_set_cb_config,
2594         .get_cb_config = imc_sms_get_cb_config,
2595         .get_parameters = imc_sms_get_sms_params,
2596         .set_parameters = imc_sms_set_sms_params,
2597         .send_deliver_report = imc_sms_send_deliver_report,
2598         .set_sca = imc_sms_set_sca,
2599         .get_sca = imc_sms_get_sca,
2600         .set_memory_status = imc_sms_set_memory_status,
2601         .set_message_status = imc_sms_set_message_status
2602 };
2603
2604 gboolean imc_sms_init(TcorePlugin *p, CoreObject *co)
2605 {
2606         dbg("Entry");
2607
2608         /* Set operations */
2609         tcore_sms_set_ops(co, &imc_sms_ops);
2610
2611         /* Add Callbacks */
2612         tcore_object_add_callback(co, "\e+CMT:",
2613                 on_notification_imc_sms_incoming_msg, NULL);
2614         tcore_object_add_callback(co, "\e+CDS",
2615                 on_notification_imc_sms_incoming_msg, NULL);
2616
2617         tcore_object_add_callback(co, "\e+CBM",
2618                 on_notification_imc_sms_cb_incom_msg, NULL);
2619         tcore_object_add_callback(co, "+CMTI",
2620                 on_notification_imc_sms_class2_incoming_msg, NULL);
2621
2622         /*
2623          * Notification
2624          * TODO - AT Command Description Not available
2625          */
2626         tcore_object_add_callback(co, "+XSMSMMSTAT",
2627                 on_notification_imc_sms_memory_status, NULL);
2628
2629         dbg("Exit");
2630         return TRUE;
2631 }
2632
2633 void imc_sms_exit(TcorePlugin *p, CoreObject *co)
2634 {
2635         dbg("Exit");
2636 }