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