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