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