a303e2fe410a6db50a829e5597d17b660520c9da
[profile/ivi/tel-plugin-imc.git] / src / s_sms.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Madhavi Akella <madhavi.a@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdint.h>
25
26 #include <glib.h>
27
28 #include <tcore.h>
29 #include <hal.h>
30 #include <core_object.h>
31 #include <plugin.h>
32 #include <queue.h>
33 #include <co_sms.h>
34 #include <co_sim.h>
35 #include <user_request.h>
36 #include <storage.h>
37 #include <server.h>
38 #include <at.h>
39 #include <plugin.h>
40
41 #include "common/TelErr.h"
42 #include "s_common.h"
43 #include "s_sms.h"
44
45 /*=============================================================
46                                                         GSM-SMS Size
47 ==============================================================*/
48 #define MAX_GSM_SMS_TPDU_SIZE                                           244
49 #define MAX_GSM_SMS_MSG_NUM                                                     255
50 #define MAX_GSM_SMS_SERVICE_CENTER_ADDR                         12              /* Maximum number of bytes of service center address */
51 #define MAX_GSM_SMS_CBMI_LIST_SIZE                                      100             /* Maximum number of CBMI list size for CBS 30*2=60  */
52 #define MAX_GSM_SMS_PARAM_RECORD_SIZE                           156             /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
53 #define MAX_GSM_SMS_STATUS_FILE_SIZE                                    2               /* Last Used TP-MR + SMS "Memory Cap. Exceeded" Noti Flag */
54 #define TAPI_SIM_SMSP_ADDRESS_LEN                                       20
55
56 /*=============================================================
57                                                         Device Ready
58 ==============================================================*/
59 #define AT_SMS_DEVICE_READY                     12              /* AT device ready */
60 #define SMS_DEVICE_READY                                1               /* Telephony device ready */
61 #define SMS_DEVICE_NOT_READY                    0               /* Telephony device not ready */
62
63 /*=============================================================
64                                                         CBMI Selection
65 ==============================================================*/
66 #define SMS_CBMI_SELECTED_SOME          0x02    /* Some CBMIs are selected */
67 #define SMS_CBMI_SELECTED_ALL                   0x01    /* All CBMIs are selected */
68
69 /*=============================================================
70                                                         Message Status
71 ==============================================================*/
72 #define AT_REC_UNREAD                                   0               /* Received and Unread */
73 #define AT_REC_READ                                     1               /* Received and Read */
74 #define AT_STO_UNSENT                                   2               /* Unsent */
75 #define AT_STO_SENT                                     3               /* Sent */
76 #define AT_ALL                                                  4               /* Unknown */
77
78 /*=============================================================
79                                                         Memory Status
80 ==============================================================*/
81 #define AT_MEMORY_AVAILABLE                     0               /* Memory Available */
82 #define AT_MEMORY_FULL                          1               /* Memory Full */
83
84 /*=============================================================
85                 SIM CRSM SW1 and Sw2 Error definitions */
86
87 #define AT_SW1_SUCCESS 0x90
88 #define AT_SW2_SUCCESS 0
89 #define AT_SW1_LEN_RESP 0x9F
90
91 #define AT_MAX_RECORD_LEN 256
92 #define AT_EF_SMS_RECORD_LEN 176
93
94 /*=============================================================*/
95
96
97 /*=========================================================
98                                                         Security
99 ==============================================================*/
100 #define MAX_SEC_PIN_LEN                                                 8
101 #define MAX_SEC_PUK_LEN                                                 8
102 #define MAX_SEC_PHONE_LOCK_PW_LEN                               39              /* Maximum Phone Locking Password Length */
103 #define MAX_SEC_SIM_DATA_STRING                                 256             /* Maximum Length of the DATA or RESPONSE. Restricted SIM Access, Generic SIM Access Message */
104 #define MAX_SEC_NUM_LOCK_TYPE                                           8               /* Maximum number of Lock Type used in Lock Information Message */
105 #define MAX_SEC_IMS_AUTH_LEN                                            512             /* Maximum Length of IMS Authentication Message */
106
107 /*=============================================================
108                                                         String Preprocessor
109 ==============================================================*/
110 #define CR              '\r'            /* Carriage Return */
111
112 /*=============================================================
113                                                         Developer
114 ==============================================================*/
115 #define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
116
117 void print_glib_list_elem(gpointer data, gpointer user_data);
118
119 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data);
120
121
122 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
123
124 /* gaurav.kalra: For test */
125 void print_glib_list_elem(gpointer data, gpointer user_data)
126 {
127         char *item = (char *)data;
128         dbg("item: [%s]", item);
129 }
130
131 /*=============================================================
132                                                         Send Callback
133 ==============================================================*/
134 static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
135 {
136         dbg("Entered Function. Request message out from queue");
137
138         dbg("TcorePending: [%p]", p);
139         dbg("result: [%02x]", result);
140         dbg("user_data: [%p]", user_data);
141
142         if(result == TRUE)
143         {
144                 dbg("SEND OK");
145         }
146         else /* Failed */
147         {
148                 dbg("SEND NOK");
149         }
150
151         dbg("Exiting Function. Nothing to return");
152 }
153
154 /*=============================================================
155                                                         Utilities
156 ==============================================================*/
157 static void util_sms_free_memory(void *sms_ptr)
158 {
159         dbg("Entry");
160
161         if(NULL != sms_ptr)
162         {
163                 dbg("Freeing memory location: [%p]", sms_ptr);
164                 free(sms_ptr);
165                 sms_ptr = NULL;
166         }
167         else
168         {
169                 err("Invalid memory location. Nothing to do.");
170         }
171
172         dbg("Exit");
173 }
174
175  
176 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
177 {
178         int alpha_id_len = 0;
179         int i = 0;
180         int nOffset = 0;
181
182         dbg(" RecordLen = %d", length);
183
184         if(incoming == NULL || params == NULL)
185                 return FALSE;
186
187         alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
188
189         if (alpha_id_len > 0)
190         {
191                 if(alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX)
192                 {
193                         alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
194                 }
195
196                 for(i=0 ; i < alpha_id_len ; i++)
197                 {
198                         if(0xff == incoming[i])
199                         {
200                                 dbg(" found");
201                                 break;
202                         }
203                 }
204
205                 memcpy(params->szAlphaId, incoming, i);
206
207                 params->alphaIdLen = i;
208
209                 dbg(" Alpha id length = %d", i);
210
211         }
212         else
213         {
214                 params->alphaIdLen = 0;
215                 dbg(" Alpha id length is zero");
216         }
217
218         //dongil01.park - start parse from here.
219         params->paramIndicator = incoming[alpha_id_len];
220
221         dbg(" Param Indicator = %02x", params->paramIndicator);
222
223         //dongil01.park(2008/12/26) - DestAddr
224         if((params->paramIndicator & SMSPValidDestAddr) == 0)
225         {
226                 nOffset = nDestAddrOffset;
227
228                 if(0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset])
229                 {
230                         params->tpDestAddr.dialNumLen = 0;
231
232                         dbg("DestAddr Length is 0");
233                 }
234                 else
235                 {
236                         if (0 < (int)incoming[alpha_id_len + nOffset])
237                         {
238                                 params->tpDestAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
239
240                                 if(params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
241                                         params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
242                         }
243                         else
244                         {
245                                 params->tpDestAddr.dialNumLen = 0;
246                         }
247
248                         params->tpDestAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
249                         params->tpDestAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70)>>4 ;
250
251                         memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen)) ;
252
253                         dbg("Dest TON is %d",params->tpDestAddr.typeOfNum);
254                         dbg("Dest NPI is %d",params->tpDestAddr.numPlanId);
255                         dbg("Dest Length = %d",params->tpDestAddr.dialNumLen);
256                         dbg("Dest Addr = %s",params->tpDestAddr.diallingNum);
257
258                 }
259         }
260
261         //dongil01.park(2008/12/26) - SvcAddr
262         if((params->paramIndicator & SMSPValidSvcAddr) == 0)
263         {
264                 nOffset = nSCAAddrOffset;
265
266                 if(0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset])
267                 {
268                         params->tpSvcCntrAddr.dialNumLen = 0;
269
270                         dbg(" SCAddr Length is 0");
271                 }
272                 else
273                 {
274                         if (0 < (int)incoming[alpha_id_len + nOffset] )
275                         {
276                                 params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
277
278                                 if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
279                                         params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
280
281                                 params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
282                                 params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
283
284                                 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
285
286                                 dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
287                                 dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
288                                 dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
289
290                                 for(i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
291                                         dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
292                         }
293                         else
294                         {
295                                 params->tpSvcCntrAddr.dialNumLen = 0;
296                         }
297                 }
298         }
299         else if ((0x00 < (int)incoming[alpha_id_len +nSCAAddrOffset] && (int)incoming[alpha_id_len +nSCAAddrOffset] <= 12)
300                         || 0xff != (int)incoming[alpha_id_len +nSCAAddrOffset])
301         {
302                 nOffset = nSCAAddrOffset;
303
304                 if(0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset])
305                 {
306                         params->tpSvcCntrAddr.dialNumLen = 0;
307                         dbg("SCAddr Length is 0");
308                 }
309                 else
310                 {
311
312                         if (0 < (int)incoming[alpha_id_len + nOffset] )
313                         {
314                                 params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
315
316                                 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] -1;
317
318                                 if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
319                                         params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
320
321                                 params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
322                                 params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
323
324                                 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
325                                                 (params->tpSvcCntrAddr.dialNumLen)) ;
326
327                                 dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
328                                 dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
329                                 dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
330
331                                 for(i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
332                                         dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
333                         }
334                         else
335                         {
336                                 params->tpSvcCntrAddr.dialNumLen = 0;
337                         }
338                 }
339
340         }
341
342         if((params->paramIndicator & SMSPValidPID) == 0 &&      (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
343         {
344                 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
345         }
346         if((params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
347         {
348                 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
349         }
350         if((params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
351         {
352                 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
353         }
354
355         dbg(" Alpha Id(Len) = %d",(int)params->alphaIdLen);
356
357         for (i=0; i< (int)params->alphaIdLen ; i++)
358         {
359                 dbg(" Alpha Id = [%d] [%c]",i,params->szAlphaId[i]);
360         }
361         dbg(" PID = %d",params->tpProtocolId);
362         dbg(" DCS = %d",params->tpDataCodingScheme);
363         dbg(" VP = %d",params->tpValidityPeriod);
364
365         return TRUE;
366 }
367
368
369 /*=============================================================
370                                                         Notifications
371 ==============================================================*/
372 static gboolean on_event_sms_ready_status(CoreObject *o, const void *event_info, void *user_data)
373 {
374         struct tnoti_sms_ready_status readyStatusInfo = {0,};
375         char *line = NULL;
376         GSList* tokens = NULL;
377         GSList* lines = NULL;
378         char *pResp = NULL;
379         //CoreObject *o = NULL;
380
381         int rtn = -1 , status = 0;
382
383         dbg(" Func Entrance");
384
385         lines = (GSList *)event_info;
386         if (1 != g_slist_length(lines))
387         {
388                 dbg("unsolicited msg but multiple line");
389                 goto OUT;
390         }
391         line = (char *)(lines->data);
392
393         dbg(" Func Entrance");
394
395         if(line!=NULL)
396         {
397                 dbg("Response OK");
398                         dbg("noti line is %s", line);
399                         tokens = tcore_at_tok_new(line);
400                         pResp = g_slist_nth_data(tokens, 0);
401                         if (pResp !=NULL)
402                                 status = atoi(pResp);
403
404         }
405         else
406         {
407                 dbg("Response NOK");
408         }
409
410         if (status == AT_SMS_DEVICE_READY)
411         {
412                 readyStatusInfo.status = SMS_DEVICE_READY;
413                 tcore_sms_set_ready_status(o, readyStatusInfo.status);
414                 dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
415                 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_DEVICE_READY, sizeof(struct tnoti_sms_ready_status), &readyStatusInfo);
416                 dbg(" Return value [%d]",rtn);
417         }
418         else
419         {
420                 readyStatusInfo.status = SMS_DEVICE_NOT_READY;
421         }
422
423 OUT:
424         if(NULL!=tokens)
425                 tcore_at_tok_free(tokens);
426         return TRUE;
427 }
428
429 static gboolean on_event_class2_sms_incom_msg(CoreObject *obj, const void *event_info, void *user_data)
430 {
431         //+CMTI: <mem>,<index>
432         
433         GSList *tokens = NULL , *lines = NULL;
434         char *line = NULL, *cmd_str = NULL;
435         int index = 0, mem_type = 0;
436         TcoreHal *hal = NULL;
437         TcoreATRequest *atreq = NULL;
438         TcorePending *pending = NULL;
439
440         dbg("Entered Function");
441
442         lines = (GSList *)event_info;
443         line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
444
445         dbg("Line 1: [%s]", line);
446
447         if (!line)
448         {
449                 err("Line 1 is invalid");
450                 return FALSE;
451         }
452
453         tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
454         mem_type = atoi(g_slist_nth_data(tokens, 0));     //Type of Memory stored
455         index         = atoi((char *)g_slist_nth_data(tokens, 1));
456
457         hal = tcore_object_get_hal(obj);
458         if (NULL == hal)
459         {
460                 err("NULL input. Unable to proceed");
461                 dbg("readMsg: hal: [%p]", hal);
462
463                 dbg("Exit");
464                 return TCORE_RETURN_EINVAL;
465         }
466
467         dbg("index: [%d]", index);
468
469         cmd_str = g_strdup_printf("AT+CMGR=%d", index); 
470         atreq     = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
471         pending = tcore_pending_new(obj, 0);
472
473         if(NULL == cmd_str || NULL == atreq || NULL == pending)
474         {
475                 err("Out of memory. Unable to proceed");
476                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
477
478                 //free memory we own
479                 g_free(cmd_str);
480                 util_sms_free_memory(atreq);
481                 util_sms_free_memory(pending);
482
483                 dbg("Exit");
484                 return TCORE_RETURN_ENOMEM;
485         }
486
487         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
488
489         tcore_pending_set_request_data(pending, 0, atreq);
490         tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *)(uintptr_t)index); //storing index as user data for response
491         tcore_pending_link_user_request(pending, NULL);
492         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
493         tcore_hal_send_request(hal, pending);
494         g_free(cmd_str);
495
496         return TRUE;
497 }
498
499 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
500 {
501         //+CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
502         
503         int rtn = -1;
504         GSList *tokens = NULL;
505         GSList *lines = NULL;
506         char *line = NULL;
507         int length = 0, no_of_tokens = 0;
508         unsigned char *bytePDU = NULL;
509         struct tnoti_sms_umts_msg gsmMsgInfo;
510
511         dbg("Entered Function");
512
513         lines = (GSList *)event_info;
514         memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
515
516         if(2 != g_slist_length(lines))
517         {
518                 err("Invalid number of lines for +CMT. Must be 2");
519                 return FALSE;
520         }
521
522         line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
523
524         dbg("Line 1: [%s]", line);
525
526         if (!line)
527         {
528                 err("Line 1 is invalid");
529                 return FALSE;
530         }
531
532         tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
533
534         no_of_tokens = g_slist_length(tokens);
535
536         if (no_of_tokens == 2) // in case of incoming SMS +CMT
537         {
538                 dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
539         length = atoi((char *)g_slist_nth_data(tokens, 1));
540         dbg("Length: [%d]", length);    /* 1: PDU Length */
541         }
542         else if (no_of_tokens == 1) // in case of incoming status report +CDS
543         {
544                 length = atoi((char *)g_slist_nth_data(tokens, 0));
545                 dbg("Length: [%d]", length);    /* 1: PDU Length */
546         }
547
548         gsmMsgInfo.msgInfo.msgLength = length;
549
550         line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
551
552         dbg("Line 2: [%s]", line);
553
554         if (!line)
555         {
556                 err("Line 2 is invalid");
557                 return FALSE;
558         }
559
560         /* Convert to Bytes */
561         bytePDU = (unsigned char *)util_hexStringToBytes(line);
562
563         if(NULL == bytePDU)
564         {
565                 err("bytePDU is NULL");
566                 return FALSE;
567         }
568
569         memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, (strlen(line)/2 - length));
570         memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[(strlen(line)/2 - length)], length);
571
572         util_hex_dump("      ", strlen(line)/2, bytePDU);
573         util_hex_dump("      ", (strlen(line)/2 - length), gsmMsgInfo.msgInfo.sca);
574         util_hex_dump("      ", length, gsmMsgInfo.msgInfo.tpduData);
575
576         rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
577
578         return TRUE;
579 }
580
581
582
583 static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
584 {
585         struct tnoti_sms_memory_status memStatusInfo = {0,};
586
587         int rtn = -1 ,memoryStatus = -1;
588         GSList *tokens=NULL;
589         GSList *lines=NULL;
590         char *line = NULL , *pResp = NULL;
591
592         lines = (GSList *)event_info;
593         if (1 != g_slist_length(lines))
594         {
595                 dbg("unsolicited msg but multiple line");
596         }
597
598         line = (char*)(lines->data);
599
600
601         dbg(" Func Entrance");
602
603         if (line)
604         {
605                 dbg("Response OK");
606                 tokens = tcore_at_tok_new(line);
607                 pResp = g_slist_nth_data(tokens, 0);
608
609                 if(pResp)
610                 {
611                         memoryStatus = atoi(pResp);
612                         dbg("memoryStatus is %d",memoryStatus);
613                 }
614
615         }else
616         {
617                 dbg("Response NOK");
618
619         }
620
621         if (memoryStatus == 0) //SIM Full condition
622         {
623                 memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
624         }
625
626
627         dbg("memory status - %d",memStatusInfo.status);
628
629         rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_MEMORY_STATUS, sizeof(struct tnoti_sms_memory_status), &memStatusInfo);
630         dbg(" Return value [%d]",rtn);
631         return TRUE;
632
633 }
634
635 static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
636 {
637         //+CBM: <length><CR><LF><pdu>
638
639         struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
640
641         int rtn = -1 , length = 0;
642         char * line = NULL, *pdu = NULL, *pResp = NULL;
643         GSList *tokens = NULL;
644         GSList *lines = NULL;
645
646         dbg(" Func Entrance");
647
648         lines = (GSList *)event_info;
649
650         memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
651
652         line = (char *)(lines->data);
653
654         if (line != NULL)
655         {
656                         dbg("Response OK");
657                         dbg("Noti line is %s",line);
658                         tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
659
660                         pResp = g_slist_nth_data(tokens, 0);
661                         if (pResp) {
662                                 length = atoi(pResp);
663                         }else {
664                                 dbg("token 0 is null");
665                         }
666                         
667                         pdu = g_slist_nth_data(lines, 1);
668                         if (pdu != NULL)
669                         {
670                                 cbMsgInfo.cbMsg.length = length/2;
671                                 cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_CBS ; //TODO - Need to check for other CB types
672
673                                 dbg("CB Msg LENGTH [%2x]", length);
674
675                                 if (cbMsgInfo.cbMsg.length >0)// && (SMS_CB_PAGE_SIZE_MAX >= cbMsgInfo.cbMsg.length))
676                                 {
677                                         unsigned char *byte_pdu = NULL;
678                                         
679                                         byte_pdu = (unsigned char *)util_hexStringToBytes(pdu);
680                                         
681                                         memcpy(cbMsgInfo.cbMsg.msgData, (char*)byte_pdu, cbMsgInfo.cbMsg.length);
682                                         rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_CB_INCOM_MSG, sizeof(struct tnoti_sms_cellBroadcast_msg), &cbMsgInfo);
683                                         free(byte_pdu);
684                                 }
685                                 else
686                                 {
687                                         dbg("Invalid Message Length");
688                                 }
689                         }
690                         else
691                         {
692                                 dbg("Recieved NULL pdu");
693                         }
694         }
695         else
696         {
697                         dbg("Response NOK");
698         }
699
700         dbg(" Return value [%d]",rtn);
701
702         return TRUE;
703 }
704
705 /*=============================================================
706                                                         Responses
707 ==============================================================*/
708 static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
709 {
710         struct tresp_sms_delete_msg delMsgInfo = {0,};
711         UserRequest *ur = NULL;
712         const TcoreATResponse *atResp = data;
713
714         int rtn = -1;
715         int *index = (int *)user_data;
716
717         dbg(" Func Entrance");
718
719         ur = tcore_pending_ref_user_request(p);
720         if (atResp->success)
721         {
722                 dbg("Response OK");
723                 delMsgInfo.index = *index;
724                 delMsgInfo.result = SMS_SENDSMS_SUCCESS;
725
726         }
727         else
728         {
729                 dbg("Response NOK");
730                 delMsgInfo.index = *index;
731                 delMsgInfo.result = SMS_DEVICE_FAILURE;
732
733         }
734
735         rtn = tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
736
737         return;
738 }
739
740 static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
741 {
742         struct tresp_sms_save_msg saveMsgInfo = {0,};
743         UserRequest *ur = NULL;
744         const TcoreATResponse *atResp = data;
745         GSList *tokens = NULL;
746         char *line = NULL;
747         char *pResp = NULL;
748         int rtn = -1;
749
750         ur = tcore_pending_ref_user_request(p);
751         if (atResp->success)
752         {
753                 dbg("Response OK");
754                 if(atResp->lines)
755                 {
756                         line = (char *)atResp->lines->data;
757                         tokens = tcore_at_tok_new(line);
758                         pResp = g_slist_nth_data(tokens, 0);
759                         if (pResp)
760                         {
761                                 dbg("0: %s", pResp);
762                                 saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
763                                 saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
764                         }
765                         else
766                         {
767                                 dbg("No Tokens");
768                                 saveMsgInfo.index = -1;
769                                 saveMsgInfo.result = SMS_DEVICE_FAILURE;
770                         }
771
772                 }
773         }
774         else
775         {
776                 dbg("Response NOK");
777                 saveMsgInfo.index = -1;
778                 saveMsgInfo.result = SMS_DEVICE_FAILURE;
779         }
780
781         rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
782         dbg("Return value [%d]", rtn);
783         return;
784 }
785
786 static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
787 {
788         const TcoreATResponse *at_response = data;
789         struct tresp_sms_send_umts_msg resp_umts;
790         UserRequest *user_req = NULL;
791
792         int msg_ref = 0;
793         GSList *tokens = NULL;
794         char *gslist_line = NULL, *line_token = NULL;
795
796         dbg("Entry");
797
798         user_req = tcore_pending_ref_user_request(pending);
799
800         if(NULL == user_req)
801         {
802                 err("No user request");
803
804                 dbg("Exit");
805                 return;
806         }
807
808         memset(&resp_umts, 0x00, sizeof(resp_umts));
809         resp_umts.result = SMS_DEVICE_FAILURE;
810
811         if(at_response->success > 0) //success
812         {
813                 dbg("Response OK");
814                 if(at_response->lines)  //lines present in at_response
815                 {
816                         gslist_line = (char *)at_response->lines->data;
817                         dbg("gslist_line: [%s]", gslist_line);
818
819                         tokens = tcore_at_tok_new(gslist_line); //extract tokens
820
821                         line_token = g_slist_nth_data(tokens, 0);
822                         if (line_token != NULL)
823                         {
824                                 msg_ref = atoi(line_token);
825                                 dbg("Message Reference: [%d]", msg_ref);
826
827                                 resp_umts.result = SMS_SENDSMS_SUCCESS;
828                         }
829                         else
830                         {
831                                 dbg("No Message Reference received");
832                         }
833                 }
834                 else //no lines in at_response
835                 {
836                         dbg("No lines");
837                 }
838         }
839         else //failure
840         {
841                 dbg("Response NOK");
842         }
843
844         tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
845
846         dbg("Exit");
847         return;
848 }
849
850 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
851 {
852         const TcoreATResponse *at_response = data;
853         GSList *tokens=NULL;
854         char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
855         int  pdu_len = 0, rtn = 0;
856         unsigned char *bytePDU = NULL;
857         struct tnoti_sms_umts_msg gsmMsgInfo;
858
859         dbg("Entry");
860         dbg("lines: [%p]", at_response->lines);
861         g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
862
863         if (at_response->success > 0)
864         {
865                 dbg("Response OK");
866                 if (at_response->lines)
867                 {
868                         //fetch first line
869                         gslist_line = (char *)at_response->lines->data;
870
871                         dbg("gslist_line: [%s]", gslist_line);
872
873                         tokens = tcore_at_tok_new(gslist_line);
874                         dbg("Number of tokens: [%d]", g_slist_length(tokens));
875                         g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
876
877                         line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
878                         if (line_token != NULL)
879                         {
880                                 pdu_len = atoi(line_token);
881                                 dbg("Length: [%d]", pdu_len);
882                         }
883
884                         //fetch second line
885                         gslist_line = (char *)at_response->lines->next->data;
886
887                         dbg("gslist_line: [%s]", gslist_line);
888
889                         tokens = tcore_at_tok_new(gslist_line);
890                         dbg("Number of tokens: [%d]", g_slist_length(tokens));
891                         g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
892
893                         hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
894                         
895                 }
896                 else
897                 {
898                         dbg("No lines");
899                 }
900         }
901         else
902         {
903                 err("Response NOK");
904         }
905
906         gsmMsgInfo.msgInfo.msgLength = pdu_len;
907
908         
909         /* Convert to Bytes */
910         bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
911
912         if(NULL == bytePDU)
913         {
914                 err("bytePDU is NULL");
915                 return ;
916         }
917
918         memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, (strlen(hex_pdu)/2 - pdu_len));
919         memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[(strlen(hex_pdu)/2 - pdu_len)], pdu_len);
920
921         util_hex_dump("      ", strlen(hex_pdu)/2, bytePDU);
922         util_hex_dump("      ", (strlen(hex_pdu)/2 - pdu_len), gsmMsgInfo.msgInfo.sca);
923         util_hex_dump("      ", pdu_len, gsmMsgInfo.msgInfo.tpduData);
924
925         rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(tcore_pending_ref_core_object(pending))), tcore_pending_ref_core_object(pending), TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
926
927
928         dbg("Exit");
929         return;
930 }
931
932 static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
933 {
934         const TcoreATResponse *at_response = data;
935         struct tresp_sms_read_msg resp_read_msg;
936         UserRequest *user_req = NULL;
937
938         GSList *tokens=NULL;
939         char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
940         int sca_length = 0;
941         int msg_status = 0, alpha_id = 0, pdu_len = 0;
942         int index = (int)(uintptr_t)user_data;
943
944         dbg("Entry");
945         dbg("index: [%d]", index);
946         dbg("lines: [%p]", at_response->lines);
947         g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
948
949         user_req = tcore_pending_ref_user_request(pending);
950         if (NULL == user_req)
951         {
952                 err("No user request");
953
954                 dbg("Exit");
955                 return;
956         }
957
958         memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
959         resp_read_msg.result = SMS_PHONE_FAILURE;
960
961         if (at_response->success > 0)
962         {
963                 dbg("Response OK");
964                 if (at_response->lines)
965                 {
966                         //fetch first line
967                         gslist_line = (char *)at_response->lines->data;
968
969                         dbg("gslist_line: [%s]", gslist_line);
970
971                         tokens = tcore_at_tok_new(gslist_line);
972                         dbg("Number of tokens: [%d]", g_slist_length(tokens));
973                         g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
974
975                         line_token = g_slist_nth_data(tokens, 0); //First Token: Message Status
976                         if (line_token != NULL)
977                         {
978                                 msg_status = atoi(line_token);
979                                 dbg("msg_status is %d",msg_status);
980                                 switch (msg_status)
981                                 {
982                                         case AT_REC_UNREAD:
983                                                 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
984                                                 break;
985
986                                         case AT_REC_READ:
987                                                 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
988                                                 break;
989
990                                         case AT_STO_UNSENT:
991                                                 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
992                                                 break;
993
994                                         case AT_STO_SENT:
995                                                 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
996                                                 break;
997
998                                         case AT_ALL: //Fall Through
999                                         default: //Fall Through
1000                                                 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
1001                                                 break;
1002                                 }
1003                         }
1004
1005                         line_token = g_slist_nth_data(tokens, 1); //Second Token: AlphaID
1006                         if (line_token != NULL)
1007                         {
1008                                 alpha_id = atoi(line_token);
1009                                 dbg("AlphaID: [%d]", alpha_id);
1010                         }
1011
1012                         line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
1013                         if (line_token != NULL)
1014                         {
1015                                 pdu_len = atoi(line_token);
1016                                 dbg("Length: [%d]", pdu_len);
1017                         }
1018
1019                         //fetch second line
1020                         gslist_line = (char *)at_response->lines->next->data;
1021
1022                         dbg("gslist_line: [%s]", gslist_line);
1023
1024                         tokens = tcore_at_tok_new(gslist_line);
1025                         dbg("Number of tokens: [%d]", g_slist_length(tokens));
1026                         g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
1027
1028                         hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
1029                         if (NULL != hex_pdu)
1030                         {
1031                                 util_hex_dump("    ", sizeof(hex_pdu), (void *)hex_pdu);
1032
1033                                 byte_pdu = util_hexStringToBytes(hex_pdu);
1034
1035                                 sca_length = (int)byte_pdu[0];
1036
1037                                 resp_read_msg.dataInfo.simIndex = index; //Retrieving index stored as user_data
1038
1039                                 if(0 == sca_length)
1040                                 {
1041                                         dbg("SCA Length is 0");
1042
1043                                         resp_read_msg.dataInfo.smsData.msgLength =  pdu_len  - (sca_length+1);
1044                                         dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
1045
1046                                         if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
1047                                                 && (resp_read_msg.dataInfo.smsData.msgLength <= 0xff))
1048                                         {
1049                                                 memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
1050                                                 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[2], resp_read_msg.dataInfo.smsData.msgLength);
1051
1052                                                 resp_read_msg.result = SMS_SUCCESS;
1053                                         }
1054                                         else
1055                                         {
1056                                                 err("Invalid Message Length");
1057
1058                                                 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
1059                                         }
1060                                 }
1061                                 else
1062                                 {
1063                                         dbg("SCA Length : %d", sca_length);
1064
1065                                         resp_read_msg.dataInfo.smsData.msgLength =  (pdu_len - (sca_length+1));
1066                                         dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
1067
1068                                         if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
1069                                                 && (resp_read_msg.dataInfo.smsData.msgLength <= 0xff))
1070                                         {
1071                                                 memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
1072                                                 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
1073
1074                                                 util_hex_dump("    ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
1075                                                 util_hex_dump("    ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
1076                                                 util_hex_dump("    ", sizeof(byte_pdu), (void *)byte_pdu);
1077
1078                                                 resp_read_msg.result = SMS_SUCCESS;
1079                                         }
1080                                         else
1081                                         {
1082                                                 err("Invalid Message Length");
1083                                                 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
1084                                         }
1085                                 }
1086                         }
1087                         else
1088                         {
1089                                 dbg("NULL PDU");
1090                         }
1091                 }
1092                 else
1093                 {
1094                         dbg("No lines");
1095                 }
1096         }
1097         else
1098         {
1099                 err("Response NOK");
1100         }
1101
1102         tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
1103
1104         dbg("Exit");
1105         return;
1106 }
1107
1108 static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
1109 {
1110         const TcoreATResponse *at_response = data;
1111         struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
1112         UserRequest *user_req = NULL;
1113         struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
1114
1115         GSList *tokens = NULL;
1116         char *gslist_line = NULL, *line_token = NULL;
1117         int gslist_line_count = 0, ctr_loop = 0;
1118
1119         dbg("Entry");
1120
1121         resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
1122         user_req = tcore_pending_ref_user_request(pending);
1123
1124         memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
1125         resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
1126
1127         if (at_response->success)
1128         {
1129                 dbg("Response OK");
1130                 if(at_response->lines)
1131                 {
1132                         gslist_line_count = g_slist_length(at_response->lines);
1133
1134                         if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
1135                                 gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
1136
1137                         dbg("Number of lines: [%d]", gslist_line_count);
1138                         g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
1139
1140                         for (ctr_loop = 0; ctr_loop < gslist_line_count ; ctr_loop++)
1141                         {
1142                                 gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
1143
1144                                 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
1145
1146                                 if (NULL != gslist_line)
1147                                 {
1148                                         tokens = tcore_at_tok_new(gslist_line);
1149
1150                                         g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
1151
1152                                         line_token = g_slist_nth_data(tokens, 0);
1153                                         if (NULL != line_token)
1154                                         {
1155                                                 resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
1156                                                 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1157                                         }
1158                                         else
1159                                         {
1160                                                 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
1161                                                 continue;
1162                                         }
1163                                         tcore_at_tok_free(tokens);
1164                                 }
1165                                 else
1166                                 {
1167                                         dbg("gslist_line [%d] is NULL", ctr_loop);
1168                                         continue;
1169                                 }
1170                         }
1171                 }
1172                 else
1173                 {
1174                         dbg("No lines.");
1175                         if(resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) //Check if used count is zero
1176                         {
1177                                 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1178                         }
1179                 }
1180         }
1181         else
1182         {
1183                 dbg("Respnose NOK");
1184         }
1185
1186         resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
1187         resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
1188
1189         util_sms_free_memory(resp_stored_msg_cnt_prev);
1190
1191         dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
1192         for(ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++)
1193         {
1194                 dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
1195         }
1196
1197         tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
1198
1199         dbg("Exit");
1200         return;
1201 }
1202
1203 static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
1204 {
1205         UserRequest *ur = NULL, *ur_dup = NULL;
1206         struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
1207         const TcoreATResponse *atResp = data;
1208         GSList *tokens=NULL;
1209         char *line = NULL , *pResp = NULL , *cmd_str = NULL;
1210         TcoreATRequest *atReq = NULL;
1211         int usedCnt = 0, totalCnt = 0, result = 0;
1212
1213         TcorePending *pending_new = NULL;
1214         CoreObject *o = NULL;
1215
1216         dbg("Entered");
1217
1218         respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
1219
1220         ur = tcore_pending_ref_user_request(pending);
1221         ur_dup = tcore_user_request_ref(ur);
1222         o = tcore_pending_ref_core_object(pending);
1223
1224         if (atResp->success > 0)
1225         {
1226                 dbg("Response OK");
1227                 if(NULL != atResp->lines)
1228                 {
1229                         line = (char *)atResp->lines->data;
1230                         dbg("line is %s",line);
1231
1232                         tokens = tcore_at_tok_new(line);
1233                         pResp = g_slist_nth_data(tokens, 0);
1234
1235                         if (pResp)
1236                         {
1237                                 usedCnt =atoi(pResp);
1238                                 dbg("used cnt is %d",usedCnt);
1239                         }
1240
1241                         pResp = g_slist_nth_data(tokens, 1);
1242                         if (pResp)
1243                         {
1244                                 totalCnt =atoi(pResp);
1245                                 result = SMS_SENDSMS_SUCCESS;
1246
1247                                 respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
1248                                 respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
1249                                 respStoredMsgCnt->result = result;
1250
1251                                 dbg("used %d, total %d, result %d",usedCnt, totalCnt,result);
1252
1253                                 pending_new = tcore_pending_new(o, 0);
1254                                 //Get all messages information
1255                                 cmd_str = g_strdup_printf("AT+CMGL=4");
1256                                 atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
1257
1258                                 dbg("cmd str is %s",cmd_str);
1259
1260                                 tcore_pending_set_request_data(pending_new, 0,atReq);
1261                                 tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
1262                                 tcore_pending_link_user_request(pending_new, ur_dup);
1263                                 tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
1264                                 tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
1265                                 
1266                                 g_free(cmd_str);
1267
1268                                 dbg("Exit");
1269                                 return;
1270
1271                         }
1272                 }else
1273                 {
1274                         dbg("No data");
1275                         result = SMS_DEVICE_FAILURE;
1276                 }
1277         }
1278
1279         err("Response NOK");
1280
1281         dbg("Exit");
1282         return;
1283 }
1284
1285 static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1286 {
1287         const TcoreATResponse *at_response = data;
1288         struct tresp_sms_get_sca respGetSca;
1289         UserRequest *user_req = NULL;
1290
1291         GSList *tokens = NULL;
1292         char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1293
1294         dbg("Entry");
1295
1296         memset(&respGetSca, 0, sizeof(respGetSca));
1297         respGetSca.result = SMS_DEVICE_FAILURE;
1298
1299         user_req = tcore_pending_ref_user_request(pending);
1300
1301         if (at_response->success)
1302         {
1303                 dbg("Response OK");
1304                 if(at_response->lines)
1305                 {
1306                         gslist_line = (char *)at_response->lines->data;
1307
1308                         tokens = tcore_at_tok_new(gslist_line);
1309                         sca_addr = g_slist_nth_data(tokens, 0);
1310                         sca_toa = g_slist_nth_data(tokens, 1);
1311
1312                         if ((NULL != sca_addr)
1313                                 && (NULL != sca_toa))
1314                         {
1315                                 dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
1316
1317                                 respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
1318
1319                                 if(145 == atoi(sca_toa))
1320                                 {
1321                                         respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
1322                                 }
1323                                 else
1324                                 {
1325                                         respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
1326                                 }
1327
1328                                 respGetSca.scaAddress.numPlanId = 0;
1329
1330                                 memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
1331
1332                                 dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
1333
1334                                 respGetSca.result = SMS_SENDSMS_SUCCESS;
1335                         }
1336                         else
1337                         {
1338                                 err("sca_addr OR sca_toa NULL");
1339                         }
1340                 }
1341                 else
1342                 {
1343                         dbg("NO Lines");
1344                 }
1345         }
1346         else
1347         {
1348                 dbg("Response NOK");
1349         }
1350
1351         tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
1352
1353         dbg("Exit");
1354         return;
1355 }
1356
1357 static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1358 {
1359         /*
1360         Response is expected in this format
1361         OK
1362                 or
1363         +CMS ERROR: <err>
1364         */
1365
1366         //CoreObject *obj = user_data;
1367         UserRequest *ur;
1368         //copies the AT response data to resp
1369         const TcoreATResponse *atResp = data;
1370         struct tresp_sms_set_sca respSetSca;
1371
1372         memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
1373
1374         ur = tcore_pending_ref_user_request(pending);
1375         if (!ur)
1376         {
1377                 dbg("no user_request");
1378                 return;
1379         }
1380
1381         if (atResp->success >0)
1382         {
1383                 dbg("RESPONSE OK");
1384                 respSetSca.result = SMS_SUCCESS;
1385         }
1386         else
1387         {
1388                 dbg("RESPONSE NOK");
1389                 respSetSca.result = SMS_DEVICE_FAILURE;
1390         }
1391
1392         tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
1393
1394         return;
1395 }
1396
1397 static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
1398 {
1399         UserRequest *ur;
1400         struct tresp_sms_get_cb_config respGetCbConfig;
1401         const TcoreATResponse *atResp = data;
1402         GSList *tokens=NULL;
1403
1404         int i = 0, mode =0;
1405         char *mid = NULL, *pResp = NULL, *line = NULL, *res = NULL;
1406         char delim[] = ",";
1407
1408         memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
1409         respGetCbConfig.result = SMS_DEVICE_FAILURE;
1410         
1411         ur = tcore_pending_ref_user_request(p);
1412         if (!ur)
1413         {
1414                 dbg("no user_request");
1415                 return;
1416         }
1417
1418         if (atResp->success)
1419         {
1420                 dbg("Response OK");
1421                 if(atResp->lines)
1422                 {
1423                         line = (char*)atResp->lines->data;
1424                         if (line != NULL)
1425                         {
1426                                 dbg("line is %s",line);
1427                                 tokens = tcore_at_tok_new(line);
1428                                 pResp = g_slist_nth_data(tokens, 0);
1429                                 if (pResp)
1430                                 {
1431                                         mode = atoi(pResp);
1432                                         respGetCbConfig.cbConfig.bCBEnabled = mode;
1433
1434                                         respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1435
1436                                         pResp = g_slist_nth_data(tokens, 1);
1437                                         if (pResp)
1438                                         {
1439                                                 mid = strtok(pResp, delim); i = 0;
1440                                                         while( res != NULL )
1441                                                         {
1442                                                                 res = strtok( NULL, delim );
1443                                                                 dbg("mid is %s%s\n", mid,res);
1444                                                                 if (res != NULL)
1445                                                                 {
1446                                                                         if (strlen(res) >0)
1447                                                                         {
1448                                                                                 respGetCbConfig.cbConfig.msgIDs[i] = atoi(res);
1449                                                                                 i++;
1450                                                                         }
1451                                                                 }
1452                                                         }
1453                                         }
1454                                         respGetCbConfig.cbConfig.msgIdCount = i;
1455                                 }
1456                                 //dcs = g_slist_nth_data(tokens, 2); DCS not needed by telephony
1457                         }
1458                         else
1459                         {
1460                                 dbg("line is NULL");
1461                         }
1462                 }
1463                 else
1464                 {
1465                                 dbg("atresp->lines is NULL");
1466                 }
1467         }
1468         else
1469         {
1470                         dbg("RESPONSE NOK");
1471         }
1472
1473         tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
1474
1475         return;
1476 }
1477
1478 static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
1479 {
1480         /*
1481         Response is expected in this format
1482         OK
1483                 or
1484         +CMS ERROR: <err>
1485         */
1486
1487         UserRequest *ur;
1488         const TcoreATResponse *resp = data;
1489         int response = 0;
1490         const char *line = NULL;
1491         GSList *tokens=NULL;
1492
1493         struct tresp_sms_set_cb_config respSetCbConfig = {0,};
1494
1495         memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
1496
1497         ur = tcore_pending_ref_user_request(pending);
1498         respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
1499         
1500         if(resp->success > 0)
1501         {
1502                 dbg("RESPONSE OK");
1503
1504         }
1505         else
1506         {
1507                 dbg("RESPONSE NOK");
1508                 line = (const char*)resp->final_response;
1509                 tokens = tcore_at_tok_new(line);
1510
1511                 if (g_slist_length(tokens) < 1) {
1512                         dbg("err cause not specified or string corrupted");
1513                         respSetCbConfig.result = SMS_DEVICE_FAILURE;
1514                 }
1515                 else
1516                 {
1517                         response = atoi(g_slist_nth_data(tokens, 0));
1518                         /* TODO: CMEE error mapping is required. */
1519                         respSetCbConfig.result = SMS_DEVICE_FAILURE;
1520                 }
1521         }
1522         if (!ur)
1523         {
1524                 dbg("no user_request");
1525                 return;
1526         }
1527
1528         tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
1529
1530         return;
1531 }
1532
1533 static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
1534 {
1535         UserRequest *ur;
1536         struct tresp_sms_set_mem_status respSetMemStatus = {0,};
1537         const TcoreATResponse *resp = data;
1538
1539         memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
1540
1541         if(resp->success > 0)
1542         {
1543                 dbg("RESPONSE OK");
1544                 respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
1545
1546         }
1547         else
1548         {
1549                 dbg("RESPONSE NOK");
1550                 respSetMemStatus.result = SMS_DEVICE_FAILURE;
1551         }
1552
1553         ur = tcore_pending_ref_user_request(p);
1554         if (!ur)
1555         {
1556                 dbg("no user_request");
1557                 return;
1558         }
1559
1560         tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
1561
1562         return;
1563 }
1564
1565 static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
1566 {
1567         UserRequest *ur;
1568         struct tresp_sms_set_msg_status respMsgStatus = {0,};
1569         const TcoreATResponse *atResp = data;
1570         int response = 0, sw1 =0 , sw2 = 0;
1571         const char *line = NULL;
1572         char *pResp = NULL;
1573         GSList *tokens=NULL;
1574
1575         dbg("Entry");
1576
1577         memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
1578         respMsgStatus.result = SMS_DEVICE_FAILURE;
1579  
1580         ur = tcore_pending_ref_user_request(pending);
1581
1582         if(atResp->success > 0)
1583         {
1584                 dbg("RESPONSE OK");
1585
1586                 if(atResp->lines)
1587                 {
1588                         line = (const char*)atResp->lines->data;
1589                         tokens = tcore_at_tok_new(line);
1590                         pResp = g_slist_nth_data(tokens, 0);
1591                         if (pResp != NULL)
1592                         {
1593                                 sw1 = atoi(pResp);
1594                         }
1595                         else
1596                         {
1597                                 dbg("sw1 is NULL");
1598                         }
1599                         pResp = g_slist_nth_data(tokens, 1);
1600                         if (pResp != NULL)
1601                         {
1602                                 sw2 = atoi(pResp);
1603                                 if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0))
1604                                 {
1605                                         respMsgStatus.result = SMS_SENDSMS_SUCCESS;
1606                                 }
1607                         }
1608                         else
1609                         {
1610                                 dbg("sw2 is NULL");
1611                         }
1612                         pResp = g_slist_nth_data(tokens, 3);
1613
1614                         if (pResp != NULL)
1615                         {
1616                                 response = atoi(pResp);
1617                                 dbg("response is %s", response);
1618                         }
1619
1620                 }
1621                 else
1622                 {
1623                         dbg("No lines");
1624                 }
1625         }
1626         else
1627         {
1628                 dbg("RESPONSE NOK");
1629         }
1630
1631         tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
1632
1633         if(tokens)
1634                 tcore_at_tok_free(tokens);
1635         
1636         dbg("Exit");
1637         return;
1638 }
1639
1640 static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1641 {
1642         UserRequest *ur;
1643         struct tresp_sms_get_params respGetParams;
1644         const TcoreATResponse *atResp = data;
1645         int sw1 =0 , sw2 = 0;
1646         const char *line = NULL;
1647         char *pResp = NULL;
1648         GSList *tokens=NULL;
1649         char *hexData = NULL;
1650     char *recordData = NULL;
1651     int i = 0;
1652
1653         memset(&respGetParams, 0, sizeof(struct tresp_sms_set_params));
1654         respGetParams.result = SMS_DEVICE_FAILURE;
1655
1656         ur = tcore_pending_ref_user_request(pending);
1657
1658         if(atResp->success > 0)
1659         {
1660                 dbg("RESPONSE OK");
1661
1662                 if(atResp->lines)
1663                 {
1664                         line = (const char*)atResp->lines->data;
1665                         tokens = tcore_at_tok_new(line);
1666                         pResp = g_slist_nth_data(tokens, 0);
1667                         if (pResp != NULL)
1668                         {
1669                                 sw1 = atoi(pResp);
1670                                 dbg("sw1 is %d",sw1);
1671                         }
1672                         else
1673                         {
1674                                 dbg("sw1 is NULL");
1675                         }
1676                         pResp = g_slist_nth_data(tokens, 1);
1677                         if (pResp != NULL)
1678                         {
1679                                 sw2 = atoi(pResp);
1680                                 dbg("sw2 is %d",sw2);
1681                                  if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
1682                                 {
1683                                         respGetParams.result = SMS_SENDSMS_SUCCESS;
1684                                 }
1685                         }
1686                         else
1687                         {
1688                                 dbg("sw2 is NULL");
1689                         }
1690                         pResp = g_slist_nth_data(tokens, 2);
1691                         if (pResp != NULL)
1692                         {
1693                                 hexData = util_removeQuotes(pResp);
1694  
1695                 recordData = util_hexStringToBytes(hexData);
1696                 util_hex_dump("    ", strlen(hexData)/2, recordData);
1697
1698                  respGetParams.paramsInfo.recordLen = strlen(hexData)/2;
1699
1700                 util_sms_decode_smsParameters((unsigned char *)recordData , strlen(hexData)/2 , &(respGetParams.paramsInfo));
1701                 respGetParams.result = SMS_SENDSMS_SUCCESS;
1702
1703                                 for(i = 0 ; i < (int)respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen ; i ++)
1704                                         dbg("SCAddr = %d [%02x]",i,respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1705
1706                 free(recordData);
1707                 free(hexData);
1708                         }
1709                         else
1710                         {
1711                                 dbg("No response");
1712                         }
1713                         tcore_at_tok_free(tokens);
1714                 }
1715         }
1716         else
1717         {
1718                 dbg("RESPONSE NOK");
1719         }
1720
1721         tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
1722
1723         dbg("Exit");
1724         return;
1725 }
1726
1727 static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1728 {
1729         UserRequest *ur;
1730         struct tresp_sms_set_params respSetParams = {0,};
1731         const TcoreATResponse *atResp = data;
1732         int sw1 =0 , sw2 = 0;
1733         const char *line = NULL;
1734         char *pResp = NULL;
1735         GSList *tokens=NULL;
1736
1737
1738         memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
1739         ur = tcore_pending_ref_user_request(pending);
1740
1741         respSetParams.result = SMS_DEVICE_FAILURE;
1742
1743         if(atResp->success > 0)
1744         {
1745                 dbg("RESPONSE OK");
1746
1747                 if(atResp->lines)
1748                 {
1749                         line = (const char*)atResp->lines->data;
1750                         tokens = tcore_at_tok_new(line);
1751                         pResp = g_slist_nth_data(tokens, 0);
1752                         if (pResp != NULL) {
1753                                 sw1 = atoi(pResp);
1754                         }
1755                         else     {
1756                                 dbg("sw1 is NULL");
1757                         }
1758                         
1759                         pResp = g_slist_nth_data(tokens, 1);
1760                         if (pResp != NULL)
1761                         {
1762                                 sw2 = atoi(pResp);
1763                                 if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)){
1764                                         respSetParams.result = SMS_SENDSMS_SUCCESS;
1765                                 }
1766                         }
1767                         else
1768                         {
1769                                 dbg("sw2 is NULL");
1770                         }
1771                 }
1772                 else
1773                 {
1774                         dbg("No lines");
1775                 }
1776         }
1777         else
1778         {
1779                 dbg("RESPONSE NOK");
1780         }
1781
1782         tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
1783
1784         if(tokens)
1785                 tcore_at_tok_free(tokens);
1786                 
1787         dbg("Exit");
1788         return;
1789 }
1790
1791 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
1792 {
1793
1794         UserRequest *ur = NULL;
1795         struct tresp_sms_get_paramcnt respGetParamCnt = {0,};
1796         const TcoreATResponse *atResp = data;
1797         char *line = NULL , *pResp = NULL;
1798         int sw1 = 0 , sw2 = 0, *smsp_record_len = NULL;
1799         int sim_type = 0;
1800         GSList *tokens=NULL;
1801         CoreObject *co_sim = NULL;  //need this to get the sim type GSM/USIM
1802         TcorePlugin *plugin = NULL;
1803
1804         dbg("Entry");
1805
1806         ur = tcore_pending_ref_user_request(p);
1807         respGetParamCnt.result = SMS_DEVICE_FAILURE;
1808
1809         if(atResp->success > 0)
1810         {
1811                 dbg("RESPONSE OK");
1812
1813                 if(atResp->lines)
1814                 {
1815                         line = (char*)atResp->lines->data;
1816
1817                         dbg("line is %s",line);
1818
1819                         tokens = tcore_at_tok_new(line);
1820                         pResp = g_slist_nth_data(tokens, 0);
1821                         if (pResp != NULL)
1822                         {
1823                                 sw1 = atoi(pResp);
1824                         }
1825                         else
1826                         {
1827                                 dbg("sw1 is NULL");
1828                         }
1829                         pResp = g_slist_nth_data(tokens, 1);
1830                         if (pResp != NULL)
1831                         {
1832                                 sw2 = atoi(pResp);
1833                                 if ((sw1 == 144) && (sw2 == 0))
1834                                 {
1835                                         respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
1836                                 }
1837                         }
1838                         else
1839                         {
1840                                 dbg("sw2 is NULL");
1841                         }
1842                         pResp = g_slist_nth_data(tokens, 2);
1843                         if (pResp != NULL)
1844                         {
1845                                 char *hexData = NULL;
1846                                 char *recordData = NULL;
1847                                 hexData = util_removeQuotes(pResp);
1848
1849                                 /*1. SIM access success case*/
1850                                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
1851                                 {
1852                                         unsigned char tag_len = 0; /*   1 or 2 bytes ??? */
1853                                         int record_len = 0;
1854                                         char num_of_records = 0;
1855                                         unsigned char file_id_len = 0;
1856                                         unsigned short file_id = 0;
1857                                         unsigned short file_size = 0;
1858                                         unsigned short file_type = 0;
1859                                         unsigned short arr_file_id = 0;
1860                                         int arr_file_id_rec_num = 0;
1861
1862                                         /*      handling only last 3 bits */
1863                                         unsigned char file_type_tag = 0x07;
1864                                         unsigned char *ptr_data;
1865
1866                                         recordData = util_hexStringToBytes(hexData);
1867                                         util_hex_dump("    ", strlen(hexData)/2, recordData);
1868
1869                                         ptr_data = (unsigned char *)recordData;
1870
1871                                         co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), "sim");
1872                                         sim_type = tcore_sim_get_type(co_sim);
1873                                         dbg("sim type is %d",sim_type);
1874
1875                                         if (sim_type ==  SIM_TYPE_USIM) {
1876                                                 /*
1877                                                  ETSI TS 102 221 v7.9.0
1878                                                         - Response Data
1879                                                          '62'   FCP template tag
1880                                                          - Response for an EF
1881                                                          '82'   M       File Descriptor
1882                                                          '83'   M       File Identifier
1883                                                         'A5'    O       Proprietary information
1884                                                          '8A'   M       Life Cycle Status Integer
1885                                                          '8B', '8C' or 'AB'     C1      Security attributes
1886                                                         '80'    M       File size
1887                                                          '81'   O       Total file size
1888                                                          '88'   O       Short File Identifier (SFI)
1889                                                 */
1890
1891                                                 /* rsim.res_len  has complete data length received  */
1892
1893                                                 /* FCP template tag - File Control Parameters tag*/
1894                                                 if (*ptr_data == 0x62) {
1895                                                         /* parse complete FCP tag*/
1896                                                         /* increment to next byte */
1897                                                         ptr_data++;
1898                                                         tag_len = *ptr_data++;
1899                                                         /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1900                                                         if (*ptr_data == 0x82) {
1901                                                                         /* increment to next byte */
1902                                                                         ptr_data++;
1903                                                                         /*2 or 5 value*/
1904                                                                         ptr_data++;
1905                                                         /*      unsigned char file_desc_len = *ptr_data++;*/
1906                                                         /*      dbg("file descriptor length: [%d]", file_desc_len);*/
1907                                                         /* TBD:  currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1908                                                         /* consider only last 3 bits*/
1909                                                         file_type_tag = file_type_tag & (*ptr_data);
1910
1911                                                         switch (file_type_tag) {
1912                                                                 /* increment to next byte */
1913                                                                 ptr_data++;
1914                                                                 case 0x1:
1915                                                                         dbg("Getting FileType: [Transparent file type]");
1916                                                                         /* increment to next byte */
1917                                                                         ptr_data++;
1918                                                                         file_type = 0x01;       //SIM_FTYPE_TRANSPARENT
1919                                                                         /*      data coding byte - value 21 */
1920                                                                         ptr_data++;
1921                                                                         break;
1922
1923                                                                 case 0x2:
1924                                                                         dbg("Getting FileType: [Linear fixed file type]");
1925                                                                         /* increment to next byte */
1926                                                                         ptr_data++;
1927                                                                         /*      data coding byte - value 21 */
1928                                                                         ptr_data++;
1929                                                                         /*      2bytes */
1930                                                                         memcpy(&record_len, ptr_data, 2);
1931                                                                         /* swap bytes */
1932                                                                         record_len = SMS_SWAPBYTES16(record_len);
1933                                                                         ptr_data = ptr_data + 2;
1934                                                                         num_of_records = *ptr_data++;
1935                                                                         /* Data lossy conversation from enum (int) to unsigned char */
1936                                                                         file_type = 0x02;       // SIM_FTYPE_LINEAR_FIXED
1937                                                                         break;
1938
1939                                                                 case 0x6:
1940                                                                         dbg(" Cyclic fixed file type");
1941                                                                         /* increment to next byte */
1942                                                                         ptr_data++;
1943                                                                         /*      data coding byte - value 21 */
1944                                                                         ptr_data++;
1945                                                                         /*      2bytes */
1946                                                                         memcpy(&record_len, ptr_data, 2);
1947                                                                         /* swap bytes  */
1948                                                                         record_len = SMS_SWAPBYTES16(record_len);
1949                                                                         ptr_data = ptr_data + 2;
1950                                                                         num_of_records = *ptr_data++;
1951                                                                         file_type = 0x04;       //SIM_FTYPE_CYCLIC
1952                                                                         break;
1953
1954                                                                 default:
1955                                                                         dbg("not handled file type [0x%x]", *ptr_data);
1956                                                                         break;
1957                                                                 }
1958                                                         }
1959                                                         else
1960                                                         {
1961                                                                 dbg("INVALID FCP received - DEbug!");
1962                                                                 return;
1963                                                         }
1964
1965                                                         /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1966                                                         if (*ptr_data == 0x83) {
1967                                                                 /* increment to next byte */
1968                                                                 ptr_data++;
1969                                                                 file_id_len = *ptr_data++;
1970                                                                 memcpy(&file_id, ptr_data, file_id_len);
1971                                                                 /* swap bytes    */
1972                                                                 file_id = SMS_SWAPBYTES16(file_id);
1973                                                                 ptr_data = ptr_data + 2;
1974                                                                 dbg("Getting FileID=[0x%x]", file_id);
1975                                                         } else {
1976                                                                 dbg("INVALID FCP received - DEbug!");
1977                                                                 free(hexData);
1978                                                                 free(recordData);
1979                                                                 //ReleaseResponse();
1980                                                                 return;
1981                                                         }
1982
1983                                                         /*      proprietary information  */
1984                                                         if (*ptr_data == 0xA5) {
1985                                                                 unsigned short prop_len;
1986                                                                 /* increment to next byte */
1987                                                                 ptr_data++;
1988                                                                 /* length */
1989                                                                 prop_len = *ptr_data;
1990                                                                 /* skip data */
1991                                                                 ptr_data = ptr_data + prop_len + 1;
1992                                                         } else {
1993                                                                 dbg("INVALID FCP received - DEbug!");
1994                                                         }
1995
1996                                                         /* life cycle status integer [8A][length:0x01][status]*/
1997                                                         /*
1998                                                          status info b8~b1
1999                                                          00000000 : No information given
2000                                                          00000001 : creation state
2001                                                          00000011 : initialization state
2002                                                          000001-1 : operation state -activated
2003                                                          000001-0 : operation state -deactivated
2004                                                          000011-- : Termination state
2005                                                          b8~b5 !=0, b4~b1=X : Proprietary
2006                                                          Any other value : RFU
2007                                                          */
2008                                                         if (*ptr_data == 0x8A) {
2009                                                                 /* increment to next byte */
2010                                                                 ptr_data++;
2011                                                                 /* length - value 1 */
2012                                                                 ptr_data++;
2013
2014                                                                 switch (*ptr_data) {
2015                                                                         case 0x04:
2016                                                                         case 0x06:
2017                                                                                 dbg("<IPC_RX> operation state -deactivated");
2018                                                                                 ptr_data++;
2019                                                                                 break;
2020                                                                         case 0x05:
2021                                                                         case 0x07:
2022                                                                                 dbg("<IPC_RX> operation state -activated");
2023                                                                                 ptr_data++;
2024                                                                                 break;
2025                                                                         default:
2026                                                                                 dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
2027                                                                                 ptr_data++;
2028                                                                                 break;
2029                                                                 }
2030                                                         }
2031
2032                                                         /* related to security attributes : currently not handled*/
2033                                                         if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
2034                                                                 /* increment to next byte */
2035                                                                 ptr_data++;
2036                                                                 /* if tag length is 3 */
2037                                                                 if (*ptr_data == 0x03) {
2038                                                                         /* increment to next byte */
2039                                                                         ptr_data++;
2040                                                                         /* EFARR file id */
2041                                                                         memcpy(&arr_file_id, ptr_data, 2);
2042                                                                         /* swap byes */
2043                                                                         arr_file_id = SMS_SWAPBYTES16(arr_file_id);
2044                                                                         ptr_data = ptr_data + 2;
2045                                                                         arr_file_id_rec_num = *ptr_data++;
2046                                                                 } else {
2047                                                                         /* if tag length is not 3 */
2048                                                                         /* ignoring bytes       */
2049                                                                         //      ptr_data = ptr_data + 4;
2050                                                                         dbg("Useless security attributes, so jump to next tag");
2051                                                                         ptr_data = ptr_data + (*ptr_data + 1);
2052                                                                 }
2053                                                         } else {
2054                                                                 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
2055                                                                 free(hexData);
2056                                                                 free(recordData);
2057
2058                                                                 return;
2059                                                         }
2060
2061                                                         dbg("Current ptr_data value is [%x]", *ptr_data);
2062
2063                                                         /* file size excluding structural info*/
2064                                                         if (*ptr_data == 0x80) {
2065                                                                 /* for EF file size is body of file and for Linear or cyclic it is
2066                                                                  * number of recXsizeof(one record)
2067                                                                  */
2068                                                                 /* increment to next byte */
2069                                                                 ptr_data++;
2070                                                                 /* length is 1 byte - value is 2 bytes or more */
2071                                                                 ptr_data++;
2072                                                                 memcpy(&file_size, ptr_data, 2);
2073                                                                 /* swap bytes */
2074                                                                 file_size = SMS_SWAPBYTES16(file_size);
2075                                                                 ptr_data = ptr_data + 2;
2076                                                         } else {
2077                                                                 dbg("INVALID FCP received - DEbug!");
2078                                                                 free(hexData);
2079                                                                 free(recordData);
2080                                                                 return;
2081                                                         }
2082
2083                                                         /* total file size including structural info*/
2084                                                         if (*ptr_data == 0x81) {
2085                                                                 int len;
2086                                                                 /* increment to next byte */
2087                                                                 ptr_data++;
2088                                                                 /* length */
2089                                                                 len = *ptr_data;
2090                                                                 /* ignored bytes */
2091                                                                 ptr_data = ptr_data + 3;
2092                                                         } else {
2093                                                                 dbg("INVALID FCP received - DEbug!");
2094                                                                 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
2095                                                                 /* return -1; */
2096                                                         }
2097                                                         /*short file identifier ignored*/
2098                                                         if (*ptr_data == 0x88) {
2099                                                                 dbg("0x88: Do Nothing");
2100                                                                 /*DO NOTHING*/
2101                                                         }
2102                                                 } else {
2103                                                         dbg("INVALID FCP received - DEbug!");
2104                                                         free(hexData);
2105                                                         free(recordData);
2106                                                         return;
2107                                                 }
2108                                         }
2109                                         else if (sim_type == SIM_TYPE_GSM)
2110                                         {
2111                                                 unsigned char gsm_specific_file_data_len = 0;
2112                                                 /*      ignore RFU byte1 and byte2 */
2113                                                 ptr_data++;
2114                                                 ptr_data++;
2115                                                 /*      file size */
2116                                                 //file_size = p_info->response_len;
2117                                                 memcpy(&file_size, ptr_data, 2);
2118                                                 /* swap bytes */
2119                                                 file_size = SMS_SWAPBYTES16(file_size);
2120                                                 /*      parsed file size */
2121                                                 ptr_data = ptr_data + 2;
2122                                                 /*  file id  */
2123                                                 memcpy(&file_id, ptr_data, 2);
2124                                                 file_id = SMS_SWAPBYTES16(file_id);
2125                                                 dbg(" FILE id --> [%x]", file_id);
2126                                                 ptr_data = ptr_data + 2;
2127                                                 /* save file type - transparent, linear fixed or cyclic */
2128                                                 file_type_tag = (*(ptr_data + 7));
2129
2130                                                 switch (*ptr_data) {
2131                                                         case 0x0:
2132                                                                 /* RFU file type */
2133                                                                 dbg(" RFU file type- not handled - Debug!");
2134                                                                 break;
2135                                                         case 0x1:
2136                                                                 /* MF file type */
2137                                                                 dbg(" MF file type - not handled - Debug!");
2138                                                                 break;
2139                                                         case 0x2:
2140                                                                 /* DF file type */
2141                                                                 dbg(" DF file type - not handled - Debug!");
2142                                                                 break;
2143                                                         case 0x4:
2144                                                                 /* EF file type */
2145                                                                 dbg(" EF file type [%d] ", file_type_tag);
2146                                                                 /*      increment to next byte */
2147                                                                 ptr_data++;
2148
2149                                                                 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
2150                                                                         /* increament to next byte as this byte is RFU */
2151                                                                         ptr_data++;
2152                                                                         file_type =
2153                                                                                         (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
2154                                                                 } else {
2155                                                                         /* increment to next byte */
2156                                                                         ptr_data++;
2157                                                                         /*      For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
2158                                                                         /* the INCREASE command is allowed on the selected cyclic file. */
2159                                                                         file_type = 0x04;       // SIM_FTYPE_CYCLIC;
2160                                                                 }
2161                                                                 /* bytes 9 to 11 give SIM file access conditions */
2162                                                                 ptr_data++;
2163                                                                 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
2164                                                                 ptr_data++;
2165                                                                 /* byte 11 is invalidate and rehabilate nibbles */
2166                                                                 ptr_data++;
2167                                                                 /* byte 12 - file status */
2168                                                                 ptr_data++;
2169                                                                 /* byte 13 - GSM specific data */
2170                                                                 gsm_specific_file_data_len = *ptr_data;
2171                                                                 ptr_data++;
2172                                                                 /*      byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
2173                                                                 ptr_data++;
2174                                                                 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
2175                                                                 record_len = *ptr_data;
2176                                                                 dbg("record length[%d], file size[%d]", record_len, file_size);
2177
2178                                                                 if (record_len != 0)
2179                                                                         num_of_records = (file_size / record_len);
2180
2181                                                                 dbg("Number of records [%d]", num_of_records);
2182                                                                 break;
2183
2184                                                         default:
2185                                                                 dbg(" not handled file type");
2186                                                                 break;
2187                                                 }
2188                                         }
2189                                         else
2190                                         {
2191                                                 dbg(" Card Type - UNKNOWN  [%d]", sim_type);
2192                                         }
2193
2194                                         dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
2195
2196                                         respGetParamCnt.recordCount = num_of_records;
2197                                         respGetParamCnt.result = SMS_SUCCESS;
2198
2199                                         //TO Store smsp record length in the property
2200                                         plugin = tcore_pending_ref_plugin(p);
2201                                         smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
2202                                         memcpy(smsp_record_len, &record_len, sizeof(int));
2203
2204                                         free(recordData);
2205                                         free(hexData);
2206                                 }
2207                                 else
2208                                 {
2209                                         /*2. SIM access fail case*/
2210                                         dbg("SIM access fail");
2211                                         respGetParamCnt.result = SMS_UNKNOWN;
2212                                 }
2213                         }
2214                         else
2215                         {
2216                                 dbg("presp is NULL");
2217                         }
2218
2219                 }else
2220                 {
2221                         dbg("line is blank");
2222                 }
2223         }
2224         else
2225         {
2226                 dbg("RESPONSE NOK");
2227         }
2228
2229
2230         tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
2231
2232         dbg("Exit");
2233         return;
2234 }
2235
2236 static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
2237 {
2238         UserRequest *ur = NULL;
2239         UserRequest *dup_ur = NULL;
2240         struct tresp_sms_set_msg_status resp_msg_status = {0,};
2241         const struct treq_sms_set_msg_status *req_msg_status = NULL ;
2242
2243         const TcoreATResponse *resp = data;
2244         char *encoded_data = NULL;
2245         char msg_status = 0;
2246         char *pResp = NULL;
2247         GSList *tokens=NULL;
2248         const char *line = NULL;
2249         int sw1 = 0;
2250         int sw2 = 0;
2251         
2252         TcoreHal *hal = NULL;
2253         TcoreATRequest *atreq = NULL;
2254         TcorePending *pending = NULL;
2255         gchar *cmd_str = NULL;
2256
2257         ur = tcore_pending_ref_user_request(p);
2258
2259         req_msg_status = tcore_user_request_ref_data(ur, NULL);
2260
2261         resp_msg_status.result = SMS_DEVICE_FAILURE;
2262                 
2263         hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
2264         dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
2265
2266         if(resp->success <= 0)
2267         {
2268                 goto OUT;
2269         }
2270                 
2271         {
2272                 dbg("RESPONSE OK");
2273                 if(resp->lines)
2274                 {
2275                         line = (const char*)resp->lines->data;
2276                         tokens = tcore_at_tok_new(line);
2277                         if (g_slist_length(tokens) != 3)
2278                         {
2279                                 msg("invalid message");
2280                                 goto OUT;
2281                         }
2282                 }
2283                 sw1 = atoi(g_slist_nth_data(tokens, 0));
2284                 sw2 = atoi(g_slist_nth_data(tokens, 1));
2285                 pResp  = g_slist_nth_data(tokens, 2);
2286                 
2287                 if((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
2288                 {
2289                         switch (req_msg_status->msgStatus)
2290                         {
2291                                 case SMS_STATUS_READ:
2292                                         msg_status = 0x01;
2293                                         break;
2294
2295                                 case SMS_STATUS_UNREAD:
2296                                         msg_status = 0x03;
2297                                         break;
2298
2299                                 case SMS_STATUS_UNSENT:
2300                                         msg_status = 0x07;
2301                                         break;
2302
2303                                 case SMS_STATUS_SENT:
2304                                         msg_status = 0x05;
2305                                         break;
2306
2307                                 case SMS_STATUS_DELIVERED:
2308                                         msg_status = 0x1D;
2309                                         break;
2310
2311                                 case SMS_STATUS_DELIVERY_UNCONFIRMED:
2312                                         msg_status = 0xD;
2313                                         break;
2314
2315                                 case SMS_STATUS_MESSAGE_REPLACED:
2316                                 case SMS_STATUS_RESERVED:
2317                                 default:
2318                                         msg_status = 0x03;
2319                                         break;
2320                         }
2321
2322                         encoded_data = util_removeQuotes(pResp);
2323
2324                         //overwrite Status byte information
2325                         util_byte_to_hex((const char *)&msg_status, (char *)encoded_data, 1);
2326
2327                         //Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
2328                         cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", (req_msg_status->index+1), AT_EF_SMS_RECORD_LEN, encoded_data);
2329                         atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2330                         pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
2331                         if(NULL == cmd_str || NULL == atreq || NULL == pending)
2332                         {
2333                                 err("Out of memory. Unable to proceed");
2334                                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2335
2336                                 //free memory we own
2337                                 g_free(cmd_str);
2338                                 free(encoded_data);
2339                                 util_sms_free_memory(atreq);
2340                                 util_sms_free_memory(pending);
2341
2342                                 goto OUT;
2343                         }
2344
2345                         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2346
2347                         dup_ur = tcore_user_request_ref(ur);
2348
2349                         tcore_pending_set_request_data(pending, 0, atreq);
2350                         tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
2351                         tcore_pending_link_user_request(pending, dup_ur);
2352                         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2353                         tcore_hal_send_request(hal, pending);
2354
2355                         g_free(cmd_str);
2356                         free(encoded_data);
2357                 }
2358         }
2359
2360 OUT:
2361         if(tokens)
2362                 tcore_at_tok_free(tokens);
2363         
2364         tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &msg_status);
2365
2366         dbg("Exit");
2367
2368         return;
2369 }
2370
2371 /*=============================================================
2372                                                         Requests
2373 ==============================================================*/
2374 static TReturn send_umts_msg(CoreObject *obj, UserRequest *ur)
2375 {
2376         gchar *cmd_str = NULL;
2377         TcoreHal *hal = NULL;
2378         TcoreATRequest *atreq = NULL;
2379         TcorePending *pending = NULL;
2380         const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
2381         char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2382         int ScLength = 0;
2383         int pdu_len = 0;
2384
2385         dbg("Entry");
2386
2387         sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
2388         hal = tcore_object_get_hal(obj);
2389         if(NULL == sendUmtsMsg || NULL == hal)
2390         {
2391                 err("NULL input. Unable to proceed");
2392                 dbg("sendUmtsMsg: [%p], hal: [%p]", sendUmtsMsg, hal);
2393
2394                 dbg("Exit");
2395                 return TCORE_RETURN_EINVAL;
2396         }
2397
2398         dbg("msgLength: [%d]", sendUmtsMsg->msgDataPackage.msgLength);
2399         util_hex_dump("    ", (SMS_SMDATA_SIZE_MAX+1), (void *)sendUmtsMsg->msgDataPackage.tpduData);
2400         util_hex_dump("    ", SMS_SMSP_ADDRESS_LEN, (void *)sendUmtsMsg->msgDataPackage.sca);
2401
2402         ScLength = (int)sendUmtsMsg->msgDataPackage.sca[0];
2403
2404         dbg("ScLength: [%d]", ScLength);
2405
2406         if ((sendUmtsMsg->msgDataPackage.msgLength > 0)
2407                 && (sendUmtsMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)
2408                 && (ScLength <= SMS_MAX_SMS_SERVICE_CENTER_ADDR))
2409         {
2410                 if(ScLength == 0) //ScAddress not specified
2411                 {
2412                         buf[0] = '0';
2413                         buf[1] = '0';
2414                         pdu_len = 2;
2415                 }
2416                 else
2417                 {
2418                         dbg("Specifying SCA in TPDU is currently not supported");
2419
2420                         buf[0] = '0';
2421                         buf[1] = '0';
2422                         pdu_len = 2;
2423                 }
2424
2425                 util_byte_to_hex((const char *)sendUmtsMsg->msgDataPackage.tpduData, (char *)&buf[pdu_len], sendUmtsMsg->msgDataPackage.msgLength);
2426
2427                 pdu_len = pdu_len + 2*sendUmtsMsg->msgDataPackage.msgLength;
2428
2429                 buf[pdu_len] = '\0'; //Ensure termination
2430
2431                 dbg("pdu_len: [%d]", pdu_len);
2432                 util_hex_dump("    ", sizeof(buf), (void *)buf);
2433
2434                 //AT+CMGS=<length><CR>PDU is given<ctrl-Z/ESC>
2435                 cmd_str = g_strdup_printf("AT+CMGS=%d%s%s\x1A", sendUmtsMsg->msgDataPackage.msgLength,"\r",buf);
2436                 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGS", TCORE_AT_SINGLELINE);
2437                 pending = tcore_pending_new(obj, 0);
2438
2439                 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2440                 {
2441                         err("Out of memory. Unable to proceed");
2442                         dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2443
2444                         //free memory we own
2445                         g_free(cmd_str);
2446                         util_sms_free_memory(atreq);
2447                         util_sms_free_memory(pending);
2448
2449                         dbg("Exit");
2450                         return TCORE_RETURN_ENOMEM;
2451                 }
2452
2453                 util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2454
2455                 tcore_pending_set_request_data(pending, 0, atreq);
2456                 tcore_pending_set_response_callback(pending, on_response_send_umts_msg, NULL);
2457                 tcore_pending_link_user_request(pending, ur);
2458                 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2459                 tcore_hal_send_request(hal, pending);
2460
2461                 g_free(cmd_str);
2462
2463                 dbg("Exit");
2464                 return TCORE_RETURN_SUCCESS;
2465         }
2466
2467         err("Invalid Data len");
2468         dbg("Exit");
2469         return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2470 }
2471
2472 static TReturn read_msg(CoreObject *obj, UserRequest *ur)
2473 {
2474         gchar *cmd_str = NULL;
2475         TcoreHal *hal = NULL;
2476         TcoreATRequest *atreq = NULL;
2477         TcorePending *pending = NULL;
2478         const struct treq_sms_read_msg *readMsg = NULL;
2479
2480         dbg("Entry");
2481
2482         readMsg = tcore_user_request_ref_data(ur, NULL);
2483         hal = tcore_object_get_hal(obj);
2484         if(NULL == readMsg || NULL == hal)
2485         {
2486                 err("NULL input. Unable to proceed");
2487                 dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
2488
2489                 dbg("Exit");
2490                 return TCORE_RETURN_EINVAL;
2491         }
2492
2493         dbg("index: [%d]", readMsg->index);
2494
2495         cmd_str = g_strdup_printf("AT+CMGR=%d", (readMsg->index + 1)); //IMC index is one ahead of TAPI
2496         atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
2497         pending = tcore_pending_new(obj, 0);
2498
2499         if(NULL == cmd_str || NULL == atreq || NULL == pending)
2500         {
2501                 err("Out of memory. Unable to proceed");
2502                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2503
2504                 //free memory we own
2505                 g_free(cmd_str);
2506                 util_sms_free_memory(atreq);
2507                 util_sms_free_memory(pending);
2508
2509                 dbg("Exit");
2510                 return TCORE_RETURN_ENOMEM;
2511         }
2512
2513         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2514
2515         tcore_pending_set_request_data(pending, 0, atreq);
2516         tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); //storing index as user data for response
2517         tcore_pending_link_user_request(pending, ur);
2518         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2519         tcore_hal_send_request(hal, pending);
2520
2521         g_free(cmd_str);
2522
2523         dbg("Exit");
2524         return TCORE_RETURN_SUCCESS;
2525 }
2526
2527 static TReturn save_msg(CoreObject *obj, UserRequest *ur)
2528 {
2529         gchar *cmd_str = NULL;
2530         TcoreHal *hal = NULL;
2531         TcoreATRequest *atreq = NULL;
2532         TcorePending *pending = NULL;
2533         const struct treq_sms_save_msg *saveMsg = NULL;
2534         int ScLength = 0, pdu_len = 0, stat = 0;
2535         char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2536
2537         dbg("Entry");
2538
2539         saveMsg = tcore_user_request_ref_data(ur, NULL);
2540         hal = tcore_object_get_hal(obj);
2541         if(NULL == saveMsg || NULL == hal)
2542         {
2543                 err("NULL input. Unable to proceed");
2544                 dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
2545
2546                 dbg("Exit");
2547                 return TCORE_RETURN_EINVAL;
2548         }
2549
2550         dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
2551         util_hex_dump("    ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
2552         util_hex_dump("    ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
2553
2554         switch (saveMsg->msgStatus) {
2555                 case SMS_STATUS_READ:
2556                         stat = AT_REC_READ;
2557                         break;
2558
2559                 case SMS_STATUS_UNREAD:
2560                         stat = AT_REC_UNREAD;
2561                         break;
2562
2563                 case SMS_STATUS_SENT:
2564                         stat = AT_STO_SENT;
2565                         break;
2566
2567                 case SMS_STATUS_UNSENT:
2568                         stat = AT_STO_UNSENT;
2569                         break;
2570
2571                 default:
2572                         err("Invalid msgStatus");
2573                         dbg("Exit");
2574                         return TCORE_RETURN_EINVAL;
2575         }
2576
2577         if ((saveMsg->msgDataPackage.msgLength > 0)
2578                 && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX))
2579         {
2580                 ScLength = (int)saveMsg->msgDataPackage.sca[0];
2581
2582                 if(ScLength == 0)
2583                 {
2584                         dbg("ScLength is zero");
2585                         buf[0] = '0';
2586                         buf[1] = '0';
2587                         pdu_len = 2;
2588                 }
2589                 else {
2590                         dbg("Specifying SCA is currently not supported");
2591                         buf[0] = '0';
2592                         buf[1] = '0';
2593                         pdu_len = 2;
2594                 }
2595
2596                 util_byte_to_hex((const char *)saveMsg->msgDataPackage.tpduData, (char *)&(buf[pdu_len]), saveMsg->msgDataPackage.msgLength);
2597
2598                 pdu_len = pdu_len + 2*saveMsg->msgDataPackage.msgLength;
2599
2600                 buf[pdu_len] = '\0'; //Ensure termination
2601
2602                 dbg("pdu_len: [%d]", pdu_len);
2603                 util_hex_dump("    ", sizeof(buf), (void *)buf);
2604
2605                 //AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
2606                 cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", buf);
2607                 pending = tcore_pending_new(obj, 0);
2608                 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
2609
2610                 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2611                 {
2612                         err("Out of memory. Unable to proceed");
2613                         dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2614
2615                         //free memory we own
2616                         g_free(cmd_str);
2617                         util_sms_free_memory(atreq);
2618                         util_sms_free_memory(pending);
2619
2620                         dbg("Exit");
2621                         return TCORE_RETURN_ENOMEM;
2622                 }
2623
2624                 util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2625
2626                 tcore_pending_set_request_data(pending, 0, atreq);
2627                 tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
2628                 tcore_pending_link_user_request(pending, ur);
2629                 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2630                 tcore_hal_send_request(hal, pending);
2631
2632                 g_free(cmd_str);
2633
2634                 dbg("Exit");
2635                 return TCORE_RETURN_SUCCESS;
2636         }
2637
2638         err("Invalid Data len");
2639         dbg("Exit");
2640         return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2641 }
2642
2643 static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
2644 {
2645         gchar *cmd_str = NULL;
2646         TcoreHal *hal = NULL;
2647         TcoreATRequest *atreq = NULL;
2648         TcorePending *pending = NULL;
2649         const struct treq_sms_delete_msg *deleteMsg = NULL;
2650
2651         dbg("Entry");
2652
2653         deleteMsg = tcore_user_request_ref_data(ur, NULL);
2654         hal = tcore_object_get_hal(obj);
2655         if(NULL == deleteMsg || NULL == hal)
2656         {
2657                 err("NULL input. Unable to proceed");
2658                 dbg("deleteMsg: [%p], hal: [%p]", deleteMsg, hal);
2659
2660                 dbg("Exit");
2661                 return TCORE_RETURN_EINVAL;
2662         }
2663
2664         dbg("index: %d", deleteMsg->index);
2665
2666         cmd_str =g_strdup_printf("AT+CMGD=%d,0", deleteMsg->index+1);
2667         pending = tcore_pending_new(obj, 0);
2668         atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2669         if(NULL == cmd_str || NULL == atreq || NULL == pending)
2670         {
2671                 err("Out of memory. Unable to proceed");
2672                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2673
2674                 //free memory we own
2675                 g_free(cmd_str);
2676                 util_sms_free_memory(atreq);
2677                 util_sms_free_memory(pending);
2678
2679                 dbg("Exit");
2680                 return TCORE_RETURN_ENOMEM;
2681         }
2682
2683         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2684
2685         tcore_pending_set_request_data(pending, 0, atreq);
2686         tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *)(uintptr_t)(deleteMsg->index)); //storing index as user data for response
2687         tcore_pending_link_user_request(pending, ur);
2688         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2689         tcore_hal_send_request(hal, pending);
2690
2691         g_free(cmd_str);
2692
2693         dbg("Exit");
2694         return TCORE_RETURN_SUCCESS;
2695 }
2696
2697 static TReturn get_storedMsgCnt(CoreObject *obj, UserRequest *ur)
2698 {
2699         gchar *cmd_str = NULL;
2700         TcoreHal *hal = NULL;
2701         TcoreATRequest *atreq = NULL;
2702         TcorePending *pending = NULL;
2703
2704         dbg("Entry");
2705
2706         hal = tcore_object_get_hal(obj);
2707         if(NULL == hal)
2708         {
2709                 err("NULL HAL. Unable to proceed");
2710
2711                 dbg("Exit");
2712                 return TCORE_RETURN_EINVAL;
2713         }
2714
2715         cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
2716         pending = tcore_pending_new(obj, 0);
2717         atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
2718
2719         if(NULL == cmd_str || NULL == atreq || NULL == pending)
2720         {
2721                 err("Out of memory. Unable to proceed");
2722                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2723
2724                 //free memory we own
2725                 g_free(cmd_str);
2726                 util_sms_free_memory(atreq);
2727                 util_sms_free_memory(pending);
2728
2729                 dbg("Exit");
2730                 return TCORE_RETURN_ENOMEM;
2731         }
2732
2733         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2734
2735         tcore_pending_set_request_data(pending, 0, atreq);
2736         tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
2737         tcore_pending_link_user_request(pending, ur);
2738         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2739         tcore_hal_send_request(hal, pending);
2740
2741         g_free(cmd_str);
2742
2743         dbg("Exit");
2744         return TCORE_RETURN_SUCCESS;
2745 }
2746
2747 static TReturn get_sca(CoreObject *obj, UserRequest *ur)
2748 {
2749         gchar * cmd_str = NULL;
2750         TcoreHal *hal = NULL;
2751         TcoreATRequest *atreq = NULL;
2752         TcorePending *pending = NULL;
2753         
2754         dbg("Entry");
2755
2756         hal = tcore_object_get_hal(obj);
2757         if(NULL == hal)
2758         {
2759                 err("HAL NULL. Unable to proceed");
2760
2761                 dbg("Exit");
2762                 return TCORE_RETURN_EINVAL;
2763         }
2764
2765         cmd_str = g_strdup_printf("AT+CSCA?");
2766         pending = tcore_pending_new(obj, 0);
2767         atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
2768
2769         if(NULL == cmd_str || NULL == atreq || NULL == pending)
2770         {
2771                 err("Out of memory. Unable to proceed");
2772                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2773
2774                 //free memory we own
2775                 g_free(cmd_str);
2776                 util_sms_free_memory(atreq);
2777                 util_sms_free_memory(pending);
2778
2779                 dbg("Exit");
2780                 return TCORE_RETURN_ENOMEM;
2781         }
2782
2783         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2784
2785         tcore_pending_set_request_data(pending, 0, atreq);
2786         tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
2787         tcore_pending_link_user_request(pending, ur);
2788         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2789         tcore_hal_send_request(hal, pending);
2790
2791         g_free(cmd_str);
2792
2793         dbg("Exit");
2794         return TCORE_RETURN_SUCCESS;
2795 }
2796
2797 static TReturn set_sca(CoreObject *obj, UserRequest *ur)
2798 {
2799         gchar *cmd_str = NULL;
2800         TcoreHal *hal = NULL;
2801         TcoreATRequest *atreq = NULL;
2802         TcorePending *pending = NULL;
2803         const struct treq_sms_set_sca *setSca = NULL;
2804         int addrType = 0;
2805
2806         dbg("Entry");
2807
2808         setSca = tcore_user_request_ref_data(ur, NULL);
2809         hal = tcore_object_get_hal(obj);
2810         if(NULL == setSca || NULL == hal)
2811         {
2812                 err("NULL input. Unable to proceed");
2813                 dbg("setSca: [%p], hal: [%p]", setSca, hal);
2814
2815                 dbg("Exit");
2816                 return TCORE_RETURN_EINVAL;
2817         }
2818
2819         dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
2820
2821         util_hex_dump("    ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
2822
2823         addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
2824
2825         cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
2826         pending = tcore_pending_new(obj, 0);
2827         atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2828
2829         if(NULL == cmd_str || NULL == atreq || NULL == pending)
2830         {
2831                 err("Out of memory. Unable to proceed");
2832                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2833
2834                 //free memory we own
2835                 g_free(cmd_str);
2836                 util_sms_free_memory(atreq);
2837                 util_sms_free_memory(pending);
2838
2839                 dbg("Exit");
2840                 return TCORE_RETURN_ENOMEM;
2841         }
2842
2843         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2844
2845         tcore_pending_set_request_data(pending, 0, atreq);
2846         tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
2847         tcore_pending_link_user_request(pending, ur);
2848         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2849         tcore_hal_send_request(hal, pending);
2850
2851         g_free(cmd_str);
2852
2853         dbg("Exit");
2854         return TCORE_RETURN_SUCCESS;
2855 }
2856
2857 static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
2858 {
2859         gchar *cmd_str = NULL;
2860         TcoreHal *hal = NULL;
2861         TcoreATRequest *atreq = NULL;
2862         TcorePending *pending = NULL;
2863
2864         dbg("Entry");
2865
2866         hal = tcore_object_get_hal(obj);
2867         if(NULL == hal)
2868         {
2869                 err("NULL HAL. Unable to proceed");
2870
2871                 dbg("Exit");
2872                 return TCORE_RETURN_EINVAL;
2873         }
2874
2875         cmd_str = g_strdup_printf("AT+CSCB?");
2876         pending = tcore_pending_new(obj, 0);
2877         atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
2878         if(NULL == cmd_str || NULL == atreq || NULL == pending)
2879         {
2880                 err("Out of memory. Unable to proceed");
2881                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2882
2883                 //free memory we own
2884                 g_free(cmd_str);
2885                 util_sms_free_memory(atreq);
2886                 util_sms_free_memory(pending);
2887
2888                 dbg("Exit");
2889                 return TCORE_RETURN_ENOMEM;
2890         }
2891
2892         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2893
2894         tcore_pending_set_request_data(pending, 0, atreq);
2895         tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
2896         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2897         tcore_pending_link_user_request(pending, ur);
2898         tcore_hal_send_request(hal, pending);
2899
2900         g_free(cmd_str);
2901
2902         dbg("Exit");
2903         return TCORE_RETURN_SUCCESS;
2904 }
2905
2906 static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
2907 {
2908         gchar *cmd_str = NULL;
2909         gchar *mids_str = NULL;
2910         GString *mids_GString = NULL;
2911
2912         TcoreHal *hal = NULL;
2913         TcoreATRequest *atreq = NULL;
2914         TcorePending *pending = NULL;
2915         const struct treq_sms_set_cb_config *setCbConfig = NULL;
2916         int loop_ctr = 0;
2917
2918         dbg("Entry");
2919
2920         setCbConfig = tcore_user_request_ref_data(ur, NULL);
2921         hal = tcore_object_get_hal(obj);
2922         if(NULL == setCbConfig || NULL == hal)
2923         {
2924                 err("NULL input. Unable to proceed");
2925                 dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
2926
2927                 dbg("Exit");
2928                 return TCORE_RETURN_EINVAL;
2929         }
2930
2931         dbg("bCBEnabled: %d, selectedId: %x, msgIdMaxCount: %x, msgIdCount: %d", setCbConfig->bCBEnabled, setCbConfig->selectedId, setCbConfig->msgIdMaxCount, setCbConfig->msgIdCount);
2932         util_hex_dump("    ", SMS_GSM_SMS_CBMI_LIST_SIZE_MAX, (void *)setCbConfig->msgIDs);
2933
2934         if (setCbConfig->bCBEnabled == FALSE) //AT+CSCB=0: Disable CBS
2935         {
2936                 cmd_str = g_strdup_printf("AT+CSCB=0");
2937         }
2938         else
2939         {
2940                 if(setCbConfig->selectedId == SMS_CBMI_SELECTED_SOME) //AT+CSCB=0,<mids>,<dcss>: Enable CBS for specified <mids> and <dcss>
2941                 {
2942                         dbg("Enabling specified CBMIs");
2943                         mids_GString = g_string_new(g_strdup_printf("%d", setCbConfig->msgIDs[0]));
2944
2945                         for(loop_ctr=1; loop_ctr <setCbConfig->msgIdCount; loop_ctr++)
2946                         {
2947                                 mids_GString = g_string_append(mids_GString, ",");
2948                                 mids_GString = g_string_append(mids_GString, g_strdup_printf("%d", setCbConfig->msgIDs[loop_ctr]));
2949                         }
2950
2951                         mids_str = g_string_free(mids_GString, FALSE);
2952                         cmd_str = g_strdup_printf("AT+CSCB=0,\"%s\"", mids_str);
2953
2954                         g_free(mids_str);
2955                 }
2956                 else if (setCbConfig->selectedId == SMS_CBMI_SELECTED_ALL) //AT+CSCB=1: Enable CBS for all <mids> and <dcss>
2957                 {
2958                         dbg("Enabling all CBMIs");
2959                         cmd_str = g_strdup_printf("AT+CSCB=1");
2960                 }
2961         }
2962
2963         pending = tcore_pending_new(obj, 0);
2964         atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2965         if(NULL == cmd_str || NULL == atreq || NULL == pending)
2966         {
2967                 err("Out of memory. Unable to proceed");
2968                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2969
2970                 //free memory we own
2971                 g_free(cmd_str);
2972                 util_sms_free_memory(atreq);
2973                 util_sms_free_memory(pending);
2974
2975                 dbg("Exit");
2976                 return TCORE_RETURN_ENOMEM;
2977         }
2978
2979         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
2980
2981         tcore_pending_set_request_data(pending, 0, atreq);
2982         tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
2983         tcore_pending_link_user_request(pending, ur);
2984         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2985         tcore_hal_send_request(hal, pending);
2986
2987         g_free(cmd_str);
2988
2989         dbg("Exit");
2990         return TCORE_RETURN_SUCCESS;
2991 }
2992
2993 static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
2994 {
2995         gchar *cmd_str = NULL;
2996         TcoreHal *hal = NULL;
2997         TcoreATRequest *atreq = NULL;
2998         TcorePending *pending = NULL;
2999         const struct treq_sms_set_mem_status *setMemStatus = NULL;
3000         int memoryStatus = 0;
3001
3002         dbg("Entry");
3003
3004         setMemStatus = tcore_user_request_ref_data(ur, NULL);
3005         hal = tcore_object_get_hal(obj);
3006         if(NULL == setMemStatus || NULL == hal)
3007         {
3008                 err("NULL input. Unable to proceed");
3009                 dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
3010
3011                 dbg("Exit");
3012                 return TCORE_RETURN_EINVAL;
3013         }
3014
3015         dbg("memory_status: %d", setMemStatus->memory_status);
3016
3017         if(setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
3018                 || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL)
3019         {
3020                 err("Invalid memory_status");
3021
3022                 dbg("Exit");
3023                 return TCORE_RETURN_EINVAL;
3024         }
3025
3026         switch (setMemStatus->memory_status)
3027         {
3028                 case SMS_PDA_MEMORY_STATUS_AVAILABLE:
3029                         memoryStatus = AT_MEMORY_AVAILABLE;
3030                         break;
3031
3032                 case SMS_PDA_MEMORY_STATUS_FULL:
3033                         memoryStatus = AT_MEMORY_FULL;
3034                         break;
3035
3036                 default:
3037                         err("Invalid memory_status");
3038                         dbg("Exit");
3039                         return TCORE_RETURN_EINVAL;
3040         }
3041
3042         cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
3043         pending = tcore_pending_new(obj, 0);
3044         atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
3045
3046         if(NULL == cmd_str || NULL == atreq || NULL == pending)
3047         {
3048                 err("Out of memory. Unable to proceed");
3049                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3050
3051                 //free memory we own
3052                 g_free(cmd_str);
3053                 util_sms_free_memory(atreq);
3054                 util_sms_free_memory(pending);
3055
3056                 dbg("Exit");
3057                 return TCORE_RETURN_ENOMEM;
3058         }
3059
3060         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
3061
3062         tcore_pending_set_request_data(pending, 0, atreq);
3063         tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
3064         tcore_pending_link_user_request(pending, ur);
3065         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3066         tcore_hal_send_request(hal, pending);
3067
3068         g_free(cmd_str);
3069
3070         dbg("Exit");
3071         return TCORE_RETURN_SUCCESS;
3072 }
3073
3074 static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
3075 {
3076         struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
3077
3078         respSetDeliveryReport.result = SMS_SUCCESS;
3079
3080         dbg("Entry");
3081         
3082         dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
3083
3084         tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
3085         
3086         dbg("Exit");
3087         return TCORE_RETURN_SUCCESS;
3088 }
3089
3090 static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
3091 {
3092         gchar *cmd_str = NULL;
3093         TcoreHal *hal = NULL;
3094         TcoreATRequest *atreq = NULL;
3095         TcorePending *pending = NULL;
3096         const struct treq_sms_set_msg_status *msg_status = NULL;
3097
3098         dbg("Entry");
3099
3100         msg_status = tcore_user_request_ref_data(ur, NULL);
3101
3102         cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", (msg_status->index+1), AT_EF_SMS_RECORD_LEN);
3103         atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3104         pending = tcore_pending_new(obj, 0);
3105         if(NULL == cmd_str || NULL == atreq || NULL == pending)
3106         {
3107                 err("Out of memory. Unable to proceed");
3108                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3109
3110                 //free memory we own
3111                 g_free(cmd_str);
3112                 util_sms_free_memory(atreq);
3113                 util_sms_free_memory(pending);
3114
3115                 dbg("Exit");
3116                 return TCORE_RETURN_ENOMEM;
3117         }
3118
3119         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
3120
3121         tcore_pending_set_request_data(pending, 0, atreq);
3122         tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
3123         tcore_pending_link_user_request(pending, ur);
3124         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3125         tcore_hal_send_request(hal, pending);
3126
3127         g_free(cmd_str);
3128
3129         dbg("Exit");
3130         return TCORE_RETURN_SUCCESS;
3131 }
3132
3133 static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
3134 {
3135         gchar *cmd_str = NULL;
3136         TcoreHal *hal = NULL;
3137         TcoreATRequest *atreq = NULL;
3138         TcorePending *pending = NULL;
3139         const struct treq_sms_get_params *getSmsParams = NULL;
3140         int record_len = 0 , *smsp_record_len = NULL;
3141
3142         dbg("Entry");
3143
3144         getSmsParams = tcore_user_request_ref_data(ur, NULL);
3145         hal = tcore_object_get_hal(obj);
3146         if(NULL == getSmsParams || NULL == hal)
3147         {
3148                 err("NULL input. Unable to proceed");
3149                 dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
3150
3151                 dbg("Exit");
3152                 return TCORE_RETURN_EINVAL;
3153         }
3154
3155         smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
3156         record_len = *smsp_record_len;
3157         dbg("record len from property %d", record_len);
3158
3159         //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3160         cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
3161
3162         dbg("cmd_str is %s",cmd_str);
3163
3164         atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3165         pending = tcore_pending_new(obj, 0);
3166         if(NULL == cmd_str || NULL == atreq || NULL == pending)
3167         {
3168                 err("Out of memory. Unable to proceed");
3169                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3170
3171                 //free memory we own
3172                 g_free(cmd_str);
3173                 util_sms_free_memory(atreq);
3174                 util_sms_free_memory(pending);
3175
3176                 dbg("Exit");
3177                 return TCORE_RETURN_ENOMEM;
3178         }
3179
3180         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
3181
3182         tcore_pending_set_request_data(pending, 0, atreq);
3183         tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
3184         tcore_pending_link_user_request(pending, ur);
3185         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3186         tcore_hal_send_request(hal, pending);
3187
3188         g_free(cmd_str);
3189
3190         dbg("Exit");
3191         return TCORE_RETURN_SUCCESS;
3192 }
3193
3194 static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
3195 {
3196         gchar *cmd_str = NULL;
3197         char *encoded_data = NULL;
3198         unsigned char *temp_data = NULL;
3199         int SMSPRecordLen = 0;
3200
3201         TcoreHal *hal = NULL;
3202         TcoreATRequest *atreq = NULL;
3203         TcorePending *pending = NULL;
3204         const struct treq_sms_set_params *setSmsParams = NULL;
3205         int encoded_data_len = 0;
3206
3207         dbg("Entry");
3208
3209         setSmsParams = tcore_user_request_ref_data(ur, NULL);
3210         hal = tcore_object_get_hal(obj);
3211         if(NULL == setSmsParams || NULL == hal)
3212         {
3213                 err("NULL input. Unable to proceed");
3214                 dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
3215                 return FALSE;
3216         }
3217
3218
3219         //EFsmsp file size is 28 +Y bytes (Y is alpha id size)
3220         SMSPRecordLen = 28 + setSmsParams->params.alphaIdLen;
3221         temp_data = calloc(SMSPRecordLen,1);
3222         encoded_data = calloc(SMSPRecordLen*2 + 1,1);
3223         
3224         _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
3225
3226         util_byte_to_hex((const char *)temp_data, (char *)encoded_data,SMSPRecordLen);
3227         
3228         encoded_data_len = ((SMSPRecordLen) * 2);
3229
3230         hal = tcore_object_get_hal(obj);
3231         pending = tcore_pending_new(obj, 0);
3232
3233         dbg("alpha id len %d encoded data %s. Encoded data len %d",setSmsParams->params.alphaIdLen,encoded_data, encoded_data_len);
3234         cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",(setSmsParams->params.recordIndex+1),SMSPRecordLen,encoded_data);
3235
3236         dbg("cmd str is %s",cmd_str);
3237         atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3238
3239         if(NULL == cmd_str || NULL == atreq || NULL == pending)
3240         {
3241                 err("Out of memory. Unable to proceed");
3242                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3243
3244                 //free memory we own
3245                 g_free(cmd_str);
3246                 util_sms_free_memory(atreq);
3247                 util_sms_free_memory(pending);
3248
3249                 util_sms_free_memory(temp_data);
3250                 util_sms_free_memory(encoded_data);
3251
3252                 dbg("Exit");
3253                 return TCORE_RETURN_ENOMEM;
3254         }
3255
3256         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
3257
3258         tcore_pending_set_request_data(pending, 0,atreq);
3259         tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
3260         tcore_pending_link_user_request(pending, ur);
3261         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3262         tcore_hal_send_request(hal, pending);
3263
3264         g_free(cmd_str);
3265         util_sms_free_memory(temp_data);
3266         util_sms_free_memory(encoded_data);
3267
3268         return TRUE;
3269 }
3270
3271 static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
3272 {
3273         gchar *cmd_str = NULL;
3274         TcoreHal *hal = NULL;
3275         TcoreATRequest *atreq = NULL;
3276         TcorePending *pending = NULL;
3277
3278         dbg("Entry");
3279
3280         hal = tcore_object_get_hal(obj);
3281         if(NULL == hal)
3282         {
3283                 err("NULL HAL. Unable to proceed");
3284
3285                 dbg("Exit");
3286                 return TCORE_RETURN_EINVAL;
3287         }
3288
3289         //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3290         cmd_str = g_strdup_printf("AT+CRSM=192,28482");
3291         atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3292         pending = tcore_pending_new(obj, 0);
3293
3294         if (NULL == cmd_str || NULL == atreq || NULL == pending)
3295         {
3296                 err("NULL pointer. Unable to proceed");
3297                 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3298
3299                 //free memory we own
3300                 g_free(cmd_str);
3301                 util_sms_free_memory(atreq);
3302                 util_sms_free_memory(pending);
3303
3304                 dbg("Exit");
3305                 return TCORE_RETURN_FAILURE;
3306         }
3307
3308         util_hex_dump("    ", strlen(cmd_str), (void *)cmd_str);
3309
3310         tcore_pending_set_request_data(pending, 0, atreq);
3311         tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
3312         tcore_pending_link_user_request(pending, ur);
3313         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3314         tcore_hal_send_request(hal, pending);
3315
3316         g_free(cmd_str);
3317
3318         dbg("Exit");
3319         return TCORE_RETURN_SUCCESS;
3320 }
3321
3322 static struct tcore_sms_operations sms_ops =
3323 {
3324         .send_umts_msg = send_umts_msg,
3325         .read_msg = read_msg,
3326         .save_msg = save_msg,
3327         .delete_msg = delete_msg,
3328         .get_storedMsgCnt = get_storedMsgCnt,
3329         .get_sca = get_sca,
3330         .set_sca = set_sca,
3331         .get_cb_config = get_cb_config,
3332         .set_cb_config = set_cb_config,
3333         .set_mem_status = set_mem_status,
3334         .get_pref_brearer = NULL,
3335         .set_pref_brearer = NULL,
3336         .set_delivery_report = set_delivery_report,
3337         .set_msg_status = set_msg_status,
3338         .get_sms_params = get_sms_params,
3339         .set_sms_params = set_sms_params,
3340         .get_paramcnt = get_paramcnt,
3341 };
3342
3343 gboolean s_sms_init(TcorePlugin *plugin, TcoreHal *hal)
3344 {
3345         CoreObject *obj = NULL;
3346         struct property_sms_info *data = NULL;
3347         GQueue *work_queue = NULL;
3348         int *smsp_record_len = NULL;
3349
3350         dbg("Entry");
3351         dbg("plugin: [%p]", plugin);
3352         dbg("hal: [%p]", hal);
3353
3354         obj = tcore_sms_new(plugin, "umts_sms", &sms_ops, hal);
3355
3356         data = calloc(sizeof(struct property_sms_info), 1);
3357
3358         if (NULL == obj || NULL == data)
3359         {
3360                 err("Unable to initialize. Exiting");
3361                 s_sms_exit(plugin);
3362
3363                 dbg("Exit");
3364                 return FALSE;
3365         }
3366
3367         work_queue = g_queue_new();
3368         tcore_object_link_user_data(obj, work_queue);
3369
3370         //Registering for SMS notifications
3371         tcore_object_add_callback(obj, "\e+CMTI", on_event_class2_sms_incom_msg, NULL);
3372         tcore_object_add_callback(obj, "\e+CMT", on_event_sms_incom_msg, NULL);
3373
3374         tcore_object_add_callback(obj, "\e+CDS", on_event_sms_incom_msg, NULL);
3375         tcore_object_add_callback(obj, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
3376         tcore_object_add_callback(obj, "+CMS", on_event_sms_memory_status, NULL);
3377
3378         tcore_object_add_callback(obj, "\e+CBMI", on_event_sms_cb_incom_msg, NULL);
3379         tcore_object_add_callback(obj, "\e+CBM", on_event_sms_cb_incom_msg, NULL);
3380         tcore_object_add_callback(obj, "+XSIM", on_event_sms_ready_status, NULL);
3381
3382         tcore_plugin_link_property(plugin, "SMS", data);
3383
3384         //storing smsp record length
3385         smsp_record_len = calloc(sizeof(int), 1);
3386         tcore_plugin_link_property(plugin, "SMSPRECORDLEN", smsp_record_len);
3387
3388         dbg("Exit");
3389         return TRUE;
3390 }
3391
3392 void s_sms_exit(TcorePlugin *plugin)
3393 {
3394         CoreObject *obj = NULL;
3395         struct property_sms_info *data = NULL;
3396
3397         dbg("Entry");
3398         dbg("plugin: [%p]", plugin);
3399
3400         obj = tcore_plugin_ref_core_object(plugin, "umts_sms");
3401         if (NULL == obj)
3402         {
3403                 err("NULL core object. Nothing to do.");
3404                 return;
3405         }
3406         tcore_sms_free(obj);
3407
3408         data = tcore_plugin_ref_property(plugin, "SMS");
3409         util_sms_free_memory(data);
3410
3411         dbg("Exit");
3412         return;
3413 }