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