Revert manifest to default one
[profile/ivi/tel-plugin-atmodem.git] / src / s_sms.c
1 /*
2  * tel-plugin-samsung-atmodem
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hayoon Ko <hayoon.ko@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
25 #include <glib.h>
26
27 #include <tcore.h>
28 #include <hal.h>
29 #include <core_object.h>
30 #include <plugin.h>
31 #include <queue.h>
32 #include <co_sms.h>
33 #include <co_sim.h>
34 #include <user_request.h>
35 #include <storage.h>
36 #include <server.h>
37
38 #include "s_common.h"
39 #include "s_sms.h"
40
41 #include "atchannel.h"
42 #include "at_tok.h"
43
44 #define MAX_GSM_SMS_TPDU_SIZE               244
45 #define MAX_GSM_SMS_PARAM_RECORD_SIZE       156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
46 #define SWAPBYTES16(x) \
47 { \
48     unsigned short int data = *(unsigned short int*)&(x); \
49     data = ((data & 0xff00) >> 8) |    \
50            ((data & 0x00ff) << 8);     \
51     *(unsigned short int*)&(x) = data ;      \
52 }
53
54 extern struct ATResponse *sp_response;
55 extern char *s_responsePrefix;
56 extern enum ATCommandType s_type;
57
58 static TReturn Send_SmsSubmitTpdu(CoreObject *o, UserRequest *ur);
59
60 /************************************************************/
61 /*********************  Utility for SMS  *************************/
62 /************************************************************/
63 static void util_sms_get_length_of_sca(int* nScLength) {
64         if (*nScLength % 2) {
65                 *nScLength = (*nScLength / 2) + 1;
66         } else {
67                 *nScLength = *nScLength / 2;
68         }
69
70         return;
71 }
72
73 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
74 {
75         int alpha_id_len = 0;
76         int i = 0;
77         int nOffset = 0;
78
79         dbg(" RecordLen = %d", length);
80
81         if(incoming == NULL || params == NULL)
82                 return FALSE;
83
84         alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
85
86         if ( alpha_id_len > 0 )
87         {
88                 if(alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX)
89                 {
90                         alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
91                 }
92
93                 for( i=0 ; i < alpha_id_len ; i++)
94                 {
95                         if( 0xff == incoming[i])
96                         {
97                                 dbg(" found");
98                                 break;
99                         }
100                 }
101
102                 memcpy(params->szAlphaId, incoming, i);
103
104                 params->alphaIdLen = i;
105
106                 dbg(" Alpha id length = %d", i);
107
108         }
109         else
110         {
111                 params->alphaIdLen = 0;
112                 dbg(" Alpha id length is zero");
113         }
114
115         // start parse from here.
116         params->paramIndicator = incoming[alpha_id_len];
117
118         dbg(" Param Indicator = %02x", params->paramIndicator);
119
120         // DestAddr
121         if( (params->paramIndicator & SMSPValidDestAddr) == 0)
122         {
123                 nOffset = nDestAddrOffset;
124
125                 if( 0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset])
126                 {
127                         params->tpDestAddr.dialNumLen = 0;
128
129                         dbg("DestAddr Length is 0");
130                 }
131                 else
132                 {
133                         if ( 0 < (int)incoming[alpha_id_len + nOffset] )
134                         {
135                                 params->tpDestAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1 );
136
137                                 if(params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
138                                         params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
139                         }
140                         else
141                         {
142                                 params->tpDestAddr.dialNumLen = 0;
143                         }
144
145                         params->tpDestAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
146                         params->tpDestAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70 )>>4 ;
147
148                         memcpy( params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen)) ;
149
150                         dbg("Dest TON is %d",params->tpDestAddr.typeOfNum);
151                         dbg("Dest NPI is %d",params->tpDestAddr.numPlanId);
152                         dbg("Dest Length = %d",params->tpDestAddr.dialNumLen);
153                         dbg("Dest Addr = %s",params->tpDestAddr.diallingNum);
154
155                 }
156         }
157
158         // SvcAddr
159         if( (params->paramIndicator & SMSPValidSvcAddr) == 0)
160         {
161                 nOffset = nSCAAddrOffset;
162
163                 if( 0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset] )
164                 {
165                         params->tpSvcCntrAddr.dialNumLen = 0;
166
167                         dbg(" SCAddr Length is 0");
168                 }
169                 else
170                 {
171                         if ( 0 < (int)incoming[alpha_id_len + nOffset]  )
172                         {
173                                 params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
174
175                                 if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
176                                         params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
177
178                                 params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
179                                 params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
180
181                                 memcpy( params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
182
183                                 dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
184                                 dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
185                                 dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
186
187                                 for( i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
188                                         dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
189                         }
190                         else
191                         {
192                                 params->tpSvcCntrAddr.dialNumLen = 0;
193                         }
194                 }
195         }
196         else if ( (0x00 < (int)incoming[alpha_id_len +nSCAAddrOffset] && (int)incoming[alpha_id_len +nSCAAddrOffset] <= 12 )
197                         || 0xff != (int)incoming[alpha_id_len +nSCAAddrOffset])
198         {
199                 nOffset = nSCAAddrOffset;
200
201                 if( 0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset] )
202                 {
203                         params->tpSvcCntrAddr.dialNumLen = 0;
204                         dbg("SCAddr Length is 0");
205                 }
206                 else
207                 {
208
209                         if ( 0 < (int)incoming[alpha_id_len + nOffset]  )
210                         {
211                                 params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
212
213                                 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] -1;
214
215                                 if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
216                                         params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
217
218                                 params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
219                                 params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
220
221                                 memcpy( params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
222                                                 (params->tpSvcCntrAddr.dialNumLen)) ;
223
224                                 dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
225                                 dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
226                                 dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
227
228                                 for( i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
229                                         dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
230                         }
231                         else
232                         {
233                                 params->tpSvcCntrAddr.dialNumLen = 0;
234                         }
235                 }
236
237         }
238
239         if( (params->paramIndicator & SMSPValidPID) == 0 &&     (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
240         {
241                 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
242         }
243         if( (params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
244         {
245                 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
246         }
247         if( (params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
248         {
249                 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
250         }
251
252         dbg(" Alpha Id(Len) = %d",(int)params->alphaIdLen);
253
254         for (i=0; i< (int)params->alphaIdLen ; i++)
255         {
256                 dbg(" Alpha Id = [%d] [%c]",i,params->szAlphaId[i]);
257         }
258         dbg(" PID = %d",params->tpProtocolId);
259         dbg(" DCS = %d",params->tpDataCodingScheme);
260         dbg(" VP = %d",params->tpValidityPeriod);
261
262         return TRUE;
263 }
264
265 static int util_sms_ipcError2SmsError(int err)
266 {
267         int returnStatus=0;
268
269         switch(err)
270         {
271                 case 300: //ME Failure;
272                         returnStatus = SMS_PHONE_FAILURE;
273                         break;
274                 case 302: //Operation not allowed;
275                 case 303: //Operation not supported;
276                         returnStatus = SMS_OPERATION_NOT_SUPPORTED;
277                         break;
278                 case 304: //Invalid PDU mode parameter;
279                 case 305: //Invalid text mode parameter;
280                         returnStatus = SMS_INVALID_PARAMETER_FORMAT;
281                         break;
282                 case 320: //memory failure;
283                 case 321: //invalid memory index;
284                 case 322: //memory full;
285                         returnStatus = SMS_MEMORY_FAILURE;
286                         break;
287                 case 330: //SCA unknown;
288                 case 500: //Unknown error;
289                 default:
290                         returnStatus = SMS_UNKNOWN;
291                         break;
292         }
293
294         return returnStatus;
295 }
296
297 /************************************************************/
298 /************************  Events Cb  *************************/
299 /************************************************************/
300
301 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
302 {
303         struct smsDeliveryPDU *smsPdu = (struct smsDeliveryPDU *)event_info;
304         struct property_sms_info *property;
305         struct tnoti_sms_umts_msg gsmMsgInfo;
306
307         int ScLength = 0, i = 0;
308         unsigned char LastSemiOctect;
309
310         memset(&gsmMsgInfo, 0, sizeof(struct tnoti_sms_umts_msg));
311         // +CMT: <length><CR><LF><pdu>
312         ScLength = smsPdu->pdu[0];
313
314         dbg(" ScLength is %d",ScLength);
315
316         LastSemiOctect = smsPdu->pdu[ScLength + 1] & 0xf0;
317         if( LastSemiOctect == 0xf0 )
318         {
319                 smsPdu->pdu[0] = (ScLength-1)*2 - 1;
320         }
321         else
322         {
323                 smsPdu->pdu[0] = (ScLength-1)*2;
324         }
325
326         gsmMsgInfo.msgInfo.msgLength = smsPdu->len - ScLength;
327         dbg(" MSG LENGTH [%d]", gsmMsgInfo.msgInfo.msgLength);
328
329         if ( (gsmMsgInfo.msgInfo.msgLength >0) && (0xff >= gsmMsgInfo.msgInfo.msgLength))
330         {
331                 property = tcore_plugin_ref_property(tcore_object_ref_plugin(o), "SMS");
332                 if(!property) {
333                         dbg("property is NULL");
334                         return TRUE;
335                 }
336
337                 memcpy(gsmMsgInfo.msgInfo.sca, &smsPdu->pdu[0], (ScLength+1));
338
339                 for(i=0;i<(ScLength+1);i++)
340                 {
341                         dbg("SCA is [%02x] ",gsmMsgInfo.msgInfo.sca[i]);
342                 }
343
344                 if(gsmMsgInfo.msgInfo.msgLength > SMS_SMDATA_SIZE_MAX)
345                 {
346                         gsmMsgInfo.msgInfo.msgLength = SMS_SMDATA_SIZE_MAX;
347                 }
348
349                 memcpy(gsmMsgInfo.msgInfo.tpduData, &smsPdu->pdu[ScLength +1], gsmMsgInfo.msgInfo.msgLength);
350
351                 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);
352
353         }
354         else
355         {
356                 dbg("Invalid Message Length");
357         }
358
359         return TRUE;
360 }
361
362 static gboolean on_event_sms_device_ready(CoreObject *o, const void *event_info, void *user_data)
363 {
364         struct tnoti_sms_ready_status readyStatusInfo = {0,};
365         int rtn = -1;
366
367         dbg(" Func Entrance");
368         readyStatusInfo.status = TRUE;
369         tcore_sms_set_ready_status(o, readyStatusInfo.status);
370
371         dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
372
373         rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_DEVICE_READY, sizeof(struct tnoti_sms_ready_status), &readyStatusInfo);
374
375         dbg(" Return value [%d]",rtn);
376
377         return TRUE;
378 }
379
380 /*************************************************************/
381 /***********************  Responses Cb  ************************/
382 /************************************************************/
383 static void on_confirmation_sms_message_send( TcorePending *p, gboolean result, void *user_data )
384 {
385         UserRequest* ur = NULL;
386         struct ATReqMetaInfo* metainfo = NULL;
387         unsigned int info_len =0;
388         dbg("on_confirmation_call_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
389
390         ReleaseResponse(); //release leftover
391
392         sp_response = at_response_new();
393
394         ur = tcore_pending_ref_user_request(p);
395         metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
396
397         if((metainfo->type == SINGLELINE)||
398                 (metainfo->type == MULTILINE))
399         {
400                 //cp rsp prefix
401                 s_responsePrefix = strdup(metainfo->responsePrefix);
402                 dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
403         }
404         else
405         {
406                 s_responsePrefix = NULL;
407         }
408
409         //set atcmd type into s_type
410         s_type = metainfo->type;
411
412         if (result == FALSE) {
413                 /* Fail */
414                 dbg("SEND FAIL");
415         }
416         else {
417                 dbg("SEND OK");
418         }
419 }
420
421 static void on_response_send_umts_msg(TcorePending *p, int data_len, const void *data, void *user_data)
422 {
423         UserRequest *ur;
424         struct tresp_sms_send_umts_msg respSendMsg;
425
426         int error;
427         char *line = NULL;
428         int ret;
429
430         memset(&respSendMsg, 0, sizeof(struct tresp_sms_send_umts_msg));
431         ur = tcore_pending_ref_user_request(p);
432         if (!ur)
433         {
434                 dbg("no user_request");
435                 return;
436         }
437
438         printResponse();
439
440         if(sp_response->success == TRUE)
441         {
442                 ReleaseResponse();
443                 ur = tcore_user_request_ref(ur);
444                 ret = (int) Send_SmsSubmitTpdu(tcore_pending_ref_core_object(p), ur);
445
446                 if(ret != (int)TCORE_RETURN_SUCCESS)
447                 {
448                         respSendMsg.result = SMS_INVALID_PARAMETER;
449                         tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
450                 }
451         }
452         else
453         {
454                 //failure case - consider this later
455                 line = sp_response->finalResponse;
456
457                 ret = at_tok_start(&line);
458                 if (ret < 0)
459                         AT_TOK_ERROR(line);
460
461                 ret = at_tok_nextint(&line,&error);
462                 if (ret < 0)
463                         AT_TOK_ERROR(line);
464
465                 respSendMsg.result = util_sms_ipcError2SmsError(error);
466
467                 tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
468         }
469
470         return;
471 }
472
473 static void on_response_send_smsSubmitTpdu(TcorePending *p, int data_len, const void *data, void *user_data)
474 {
475         UserRequest *ur = NULL;
476         struct tresp_sms_send_umts_msg respUmtsInfo;
477
478         char *line = NULL;
479         char *ackpdu = NULL;
480         int ret;
481         int mr;
482         int error;
483         char *hexData;
484
485         char cSCA = '\0';
486
487         printResponse();
488
489         if(sp_response->success > 0)
490         {
491                 line = sp_response->p_intermediates->line;
492
493                 memset(&respUmtsInfo, 0 , sizeof(struct tresp_sms_send_umts_msg));
494                 // +CMGS: <mr>[, <ackpdu>]
495                 // SMS_SMDATA_SIZE_MAX + 1
496                 ret = at_tok_start(&line);
497                 if (ret < 0)
498                         AT_TOK_ERROR(line);
499
500                 ret = at_tok_nextint(&line, &mr);
501                 if (ret < 0)
502                         return;
503
504                 ret = at_tok_nextstr(&line, &hexData);
505                 if (ret < 0)
506                 {
507                         dbg(" ackpdu is NULL ");
508                         ackpdu = NULL;
509                 } else {
510                         ackpdu = util_hexStringToBytes(hexData);
511                         util_hex_dump("    ", strlen(hexData)/2, ackpdu);
512                 }
513
514                 dbg(" Func Entrance ");
515
516                 ur = tcore_pending_ref_user_request(p);
517                 if(ur)
518                 {
519                         memcpy(respUmtsInfo.dataInfo.sca, &cSCA, sizeof(char));
520
521                         if (ackpdu) {
522                                 respUmtsInfo.dataInfo.msgLength = strlen(ackpdu);
523                         } else {
524                                 respUmtsInfo.dataInfo.msgLength = 0;
525                         }
526
527                         if ( (respUmtsInfo.dataInfo.msgLength >= 0) && (0xff >= respUmtsInfo.dataInfo.msgLength))
528                         {
529                                 if(respUmtsInfo.dataInfo.msgLength > SMS_SMDATA_SIZE_MAX)
530                                 {
531                                         respUmtsInfo.dataInfo.msgLength = SMS_SMDATA_SIZE_MAX;
532                                 }
533
534                                 memcpy(respUmtsInfo.dataInfo.tpduData, ackpdu, respUmtsInfo.dataInfo.msgLength);
535
536                                 dbg(" MR : %d", mr);
537                                 dbg(" msg length : %d", respUmtsInfo.dataInfo.msgLength);
538                                 dbg(" TRESP_SMS_SEND_UMTS_MSG : 0x%x", TRESP_SMS_SEND_UMTS_MSG);
539
540                                 respUmtsInfo.result = SMS_SENDSMS_SUCCESS;
541
542                                 tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respUmtsInfo);
543
544                         }
545                         else
546                         {
547                                 respUmtsInfo.result = SMS_INVALID_PARAMETER_FORMAT;
548
549                                 tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respUmtsInfo);
550
551                 }
552                 }
553                 else
554                 {
555                         dbg("no user_request");
556                 }
557         }
558         else
559         {
560                 //failure case - consider this later
561                 line = sp_response->finalResponse;
562
563                 ret = at_tok_start(&line);
564                 if (ret < 0)
565                         AT_TOK_ERROR(line);
566
567                 ret = at_tok_nextint(&line,&error);
568                 if (ret < 0)
569                         AT_TOK_ERROR(line);
570
571
572                 //5. release sp_response & s_responsePrefix - before sending user callback, because user callback can request additional request
573                 // and if queue is empty, that req can be directly sent to mdm - can cause sp_response, s_responsePrefix dangling
574                 ReleaseResponse();
575
576                 ur = tcore_pending_ref_user_request(p);
577                 if (ur) {
578                         struct tresp_sms_send_umts_msg respSendMsg;
579
580                         memset(&respSendMsg, 0, sizeof(struct tresp_sms_send_umts_msg));
581                         respSendMsg.result = SMS_INVALID_MANDATORY_INFO;
582
583                         respSendMsg.result = util_sms_ipcError2SmsError(error);
584
585                         tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
586                 }
587                 else {
588                         dbg("no user_request");
589                 }
590         }
591 }
592
593 static void on_response_get_storedMsgCnt(TcorePending *p, int data_len, const void *data, void *user_data)
594 {
595         UserRequest *ur;
596         struct tresp_sms_get_storedMsgCnt respStoredMsgCnt;
597
598         int error;
599         char *line = NULL;
600         int ret;
601         int usedCount = 0;
602         int totalCount = 0;
603
604         memset(&respStoredMsgCnt, 0, sizeof(struct tresp_sms_get_storedMsgCnt));
605         ur = tcore_pending_ref_user_request(p);
606         if (!ur)
607         {
608                 dbg("no user_request");
609                 return;
610         }
611
612         printResponse();
613
614         if(sp_response->success > 0)
615         {
616                 //failure case - consider this later
617                 line = sp_response->p_intermediates->line;
618
619                 ret = at_tok_start(&line);
620                 if (ret < 0)
621                         AT_TOK_ERROR(line);
622
623                 ret = at_tok_nextint(&line,&usedCount);
624                 if (ret < 0)
625                         AT_TOK_ERROR(line);
626                 ret = at_tok_nextint(&line,&totalCount);
627                 if (ret < 0)
628                         AT_TOK_ERROR(line);
629
630                 respStoredMsgCnt.storedMsgCnt.totalCount = totalCount;
631                 respStoredMsgCnt.storedMsgCnt.usedCount = usedCount;
632
633                 dbg(" totalCount:%d, usedCount:%d",respStoredMsgCnt.storedMsgCnt.totalCount , respStoredMsgCnt.storedMsgCnt.usedCount );
634
635                 respStoredMsgCnt.result = SMS_SUCCESS;
636         }
637         else
638         {
639                 //failure case - consider this later
640                 line = sp_response->finalResponse;
641
642                 ret = at_tok_start(&line);
643                 if (ret < 0)
644                         AT_TOK_ERROR(line);
645
646                 ret = at_tok_nextint(&line,&error);
647                 if (ret < 0)
648                         AT_TOK_ERROR(line);
649
650                 respStoredMsgCnt.result = util_sms_ipcError2SmsError(error);
651         }
652
653         ReleaseResponse();
654
655
656         tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
657
658         return;
659
660 }
661
662 static void on_response_get_sca(TcorePending *p, int data_len, const void *data, void *user_data)
663 {
664         UserRequest *ur;
665         struct tresp_sms_get_sca respGetSca;
666
667         char* line=NULL;
668         int ret = 0;
669         char *scaStr = NULL;
670         int scaType = 0;
671         int error;
672
673         ur = tcore_pending_ref_user_request(p);
674         if (!ur)
675         {
676                 dbg("no user_request");
677                 return;
678         }
679
680         printResponse();
681
682         // +CSCA: <sca number>,<sca type>
683         if(sp_response->success > 0)
684         {
685                 respGetSca.result = SMS_SUCCESS;
686
687                 line = sp_response->p_intermediates->line;
688                 ret = at_tok_start(&line);
689                 if (ret < 0)
690                         AT_TOK_ERROR(line);
691
692                 ret = at_tok_nextstr(&line, &scaStr);
693                 if (ret < 0)
694                         AT_TOK_ERROR(line);
695                 memcpy(respGetSca.scaAddress.diallingNum, scaStr, strlen(scaStr));
696
697
698                 line = sp_response->p_intermediates->line;
699                 ret = at_tok_start(&line);
700                 if (ret < 0)
701                         AT_TOK_ERROR(line);
702
703                 ret = at_tok_nextstr(&line,&scaStr);
704                 if(scaStr!=NULL)
705                         ret = at_tok_nextint(&line,&scaType);
706
707                 respGetSca.scaAddress.dialNumLen = strlen(scaStr);
708                 if(scaType == 145)
709                         respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
710                 else            respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
711                 respGetSca.scaAddress.numPlanId = 0;
712
713                 memcpy(respGetSca.scaAddress.diallingNum, scaStr, strlen(scaStr));
714
715         }
716         else
717         {
718                 //failure case - consider this later
719                 line = sp_response->finalResponse;
720
721                 ret = at_tok_start(&line);
722                 if (ret < 0)
723                         AT_TOK_ERROR(line);
724
725                 ret = at_tok_nextint(&line,&error);
726                 if (ret < 0)
727                         AT_TOK_ERROR(line);
728
729                 respGetSca.result = util_sms_ipcError2SmsError(error);
730
731         }
732
733         ReleaseResponse();
734
735         tcore_user_request_send_response(ur, TRESP_SMS_GET_SCA, sizeof(struct tresp_sms_get_sca), &respGetSca);
736
737         return;
738 }
739
740 static void on_response_set_sca(TcorePending *p, int data_len, const void *data, void *user_data)
741 {
742         UserRequest *ur;
743         struct tresp_sms_set_sca respSetSca;
744         int ret;
745         int error;
746         char *line = NULL;
747
748         ur = tcore_pending_ref_user_request(p);
749         if (!ur)
750         {
751                 dbg("no user_request");
752                 return;
753         }
754
755         printResponse();
756
757         if(sp_response->success > 0)
758         {
759                 respSetSca.result = SMS_SUCCESS;
760         }
761         else
762         {
763                 //failure case - consider this later
764                 line = sp_response->finalResponse;
765
766                 ret = at_tok_start(&line);
767                 if (ret < 0)
768                         AT_TOK_ERROR(line);
769
770                 ret = at_tok_nextint(&line,&error);
771                 if (ret < 0)
772                         AT_TOK_ERROR(line);
773
774                 respSetSca.result = util_sms_ipcError2SmsError(error);
775         }
776
777         ReleaseResponse();
778
779         tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_get_sca), &respSetSca);
780
781         return;
782 }
783
784 static void on_response_set_delivery_report(TcorePending *p, int data_len, const void *data, void *user_data)
785 {
786         UserRequest *ur;
787         struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
788
789         int error;
790         char *line = NULL;
791         int ret;
792
793         ur = tcore_pending_ref_user_request(p);
794         if (!ur)
795         {
796                 dbg("no user_request");
797                 return;
798         }
799
800         printResponse();
801
802         if(sp_response->success > 0)
803         {
804                 respSetDeliveryReport.result = SMS_SUCCESS;
805         }
806         else
807         {
808                 //failure case - consider this later
809                 line = sp_response->finalResponse;
810
811                 ret = at_tok_start(&line);
812                 if (ret < 0)
813                         AT_TOK_ERROR(line);
814
815                 ret = at_tok_nextint(&line,&error);
816                 if (ret < 0)
817                         AT_TOK_ERROR(line);
818
819                 respSetDeliveryReport.result = util_sms_ipcError2SmsError(error);
820         }
821
822         ReleaseResponse();
823
824
825         tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
826
827         return;
828 }
829
830 static void on_response_get_sms_params(TcorePending *p, int data_len, const void *data, void *user_data)
831 {
832         UserRequest *ur;
833         struct tresp_sms_get_params respGetSmsParams;
834         struct property_sms_info *property = NULL;
835
836         char *line = NULL;
837         int error;
838         int ret = 0;
839         int sw1 = 0;
840         int sw2 = 0;
841         char *recordData;
842
843         memset(&respGetSmsParams, 0, sizeof(struct tresp_sms_get_params));
844         printResponse();
845
846
847         ur = tcore_pending_ref_user_request(p);
848         if (!ur)
849         {
850                 dbg("no user_request");
851                 return;
852         }
853
854         if(sp_response->success > 0)
855         {
856                 line = sp_response->p_intermediates->line;
857
858                 ret = at_tok_start(&line);
859                 if (ret < 0)
860                         AT_TOK_ERROR(line);
861
862                 ret = at_tok_nextint(&line,&sw1);
863                 if (ret < 0)
864                         AT_TOK_ERROR(line);
865                 ret = at_tok_nextint(&line,&sw2);
866                 if (ret < 0)
867                         AT_TOK_ERROR(line);
868
869                 if(sw1 != 144 || sw2 != 0)
870                         respGetSmsParams.result = SMS_UNKNOWN;
871                 else
872                 {
873                         char *hexData;
874
875                         ret = at_tok_nextstr(&line,&hexData);
876                         if (ret < 0)
877                                 AT_TOK_ERROR(line);
878
879                         recordData = util_hexStringToBytes(hexData);
880                         util_hex_dump("    ", strlen(hexData)/2, recordData);
881
882                         // respGetSmsParams.paramsInfo.recordIndex = 0;
883                         respGetSmsParams.paramsInfo.recordLen = strlen(hexData)/2;
884
885                         property = tcore_plugin_ref_property(tcore_object_ref_plugin(tcore_pending_ref_core_object(p)), "SMS");
886
887                         if(!property) {
888                                 dbg("property is NULL");
889                                 free(recordData);
890                                 return;
891                         }
892
893                         util_sms_decode_smsParameters((unsigned char *)recordData, strlen(hexData)/2, &respGetSmsParams.paramsInfo);
894                         property->SMSPRecordLen = respGetSmsParams.paramsInfo.recordLen;
895
896                         respGetSmsParams.result = SMS_SUCCESS;
897
898                         free(recordData);
899                 }
900         }
901         else
902         {
903                 respGetSmsParams.result = SMS_UNKNOWN;
904                 //failure case - consider this later
905                 line = sp_response->finalResponse;
906
907                 ret = at_tok_start(&line);
908                 if (ret < 0)
909                         AT_TOK_ERROR(line);
910
911                 ret = at_tok_nextint(&line,&error);
912                 if (ret < 0)
913                         AT_TOK_ERROR(line);
914
915                 respGetSmsParams.result = util_sms_ipcError2SmsError(error);
916         }
917
918         ReleaseResponse();
919
920         tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetSmsParams);
921
922         return;
923 }
924
925 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
926 {
927         UserRequest *ur;
928         struct tresp_sms_get_paramcnt respGetParamCnt = {0,};
929         CoreObject *co_sim = NULL;
930         char *line = NULL;
931         int ret = 0;
932         int sw1 = 0;
933         int sw2 = 0;
934
935         ur = tcore_pending_ref_user_request(p);
936
937         if(sp_response->success == TRUE)
938         {
939                 line = sp_response->p_intermediates->line;
940                 ret = at_tok_start(&line);
941                 if (ret < 0)
942                         AT_TOK_ERROR(line);
943
944                 ret = at_tok_nextint(&line,&sw1);
945                 if (ret < 0)
946                         AT_TOK_ERROR(line);
947                 ret = at_tok_nextint(&line,&sw2);
948                 if (ret < 0)
949                         AT_TOK_ERROR(line);
950
951                 /*1. SIM access success case*/
952                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
953                         unsigned char tag_len = 0; /*   1 or 2 bytes ??? */
954                         unsigned short record_len = 0;
955                         char num_of_records = 0;
956                         unsigned char file_id_len = 0;
957                         unsigned short file_id = 0;
958                         unsigned short file_size = 0;
959                         unsigned short file_type = 0;
960                         unsigned short arr_file_id = 0;
961                         int arr_file_id_rec_num = 0;
962
963                         /*      handling only last 3 bits */
964                         unsigned char file_type_tag = 0x07;
965                         unsigned char *ptr_data;
966
967                         char *hexData;
968                         char *recordData;
969                         ret = at_tok_nextstr(&line,&hexData);
970                         if (ret < 0)
971                                 AT_TOK_ERROR(line);
972
973                         recordData = util_hexStringToBytes(hexData);
974                         util_hex_dump("    ", strlen(hexData)/2, recordData);
975
976                         ptr_data = (unsigned char *)recordData;
977
978                         co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), "sim");
979                         if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
980                                 /*
981                                  ETSI TS 102 221 v7.9.0
982                                  - Response Data
983                                  '62'   FCP template tag
984                                  - Response for an EF
985                                  '82'   M       File Descriptor
986                                  '83'   M       File Identifier
987                                  'A5'   O       Proprietary information
988                                  '8A'   M       Life Cycle Status Integer
989                                  '8B', '8C' or 'AB'     C1      Security attributes
990                                  '80'   M       File size
991                                  '81'   O       Total file size
992                                  '88'   O       Short File Identifier (SFI)
993                                  */
994
995                                 /* rsim.res_len  has complete data length received  */
996
997                                 /* FCP template tag - File Control Parameters tag*/
998                                 if (*ptr_data == 0x62) {
999                                         /* parse complete FCP tag*/
1000                                         /* increment to next byte */
1001                                         ptr_data++;
1002                                         tag_len = *ptr_data++;
1003                                         /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1004                                         if (*ptr_data == 0x82) {
1005                                                 /* increment to next byte */
1006                                                 ptr_data++;
1007                                                 /*2 or 5 value*/
1008                                                 ptr_data++;
1009                                                 /*      unsigned char file_desc_len = *ptr_data++;*/
1010                                                 /*      dbg("file descriptor length: [%d]", file_desc_len);*/
1011                                                 /* TBD:  currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1012                                                 /* consider only last 3 bits*/
1013                                                 file_type_tag = file_type_tag & (*ptr_data);
1014
1015                                                 switch (file_type_tag) {
1016                                                         /* increment to next byte */
1017                                                         ptr_data++;
1018                                                         case 0x1:
1019                                                                 dbg("Getting FileType: [Transparent file type]");
1020                                                                 /* increment to next byte */
1021                                                                 ptr_data++;
1022                                                                 file_type = 0x01;       //SIM_FTYPE_TRANSPARENT
1023                                                                 /*      data coding byte - value 21 */
1024                                                                 ptr_data++;
1025                                                                 break;
1026
1027                                                         case 0x2:
1028                                                                 dbg("Getting FileType: [Linear fixed file type]");
1029                                                                 /* increment to next byte */
1030                                                                 ptr_data++;
1031                                                                 /*      data coding byte - value 21 */
1032                                                                 ptr_data++;
1033                                                                 /*      2bytes */
1034                                                                 memcpy(&record_len, ptr_data, 2);
1035                                                                 /* swap bytes */
1036                                                                 SWAPBYTES16(record_len);
1037                                                                 ptr_data = ptr_data + 2;
1038                                                                 num_of_records = *ptr_data++;
1039                                                                 /* Data lossy conversation from enum (int) to unsigned char */
1040                                                                 file_type = 0x02;       // SIM_FTYPE_LINEAR_FIXED
1041                                                                 break;
1042
1043                                                         case 0x6:
1044                                                                 dbg(" Cyclic fixed file type");
1045                                                                 /* increment to next byte */
1046                                                                 ptr_data++;
1047                                                                 /*      data coding byte - value 21 */
1048                                                                 ptr_data++;
1049                                                                 /*      2bytes */
1050                                                                 memcpy(&record_len, ptr_data, 2);
1051                                                                 /* swap bytes  */
1052                                                                 SWAPBYTES16(record_len);
1053                                                                 ptr_data = ptr_data + 2;
1054                                                                 num_of_records = *ptr_data++;
1055                                                                 file_type = 0x04;       //SIM_FTYPE_CYCLIC
1056                                                                 break;
1057
1058                                                 default:
1059                                                         dbg("not handled file type [0x%x]", *ptr_data);
1060                                                         break;
1061                                                 }
1062                                         } else {
1063                                                 dbg("INVALID FCP received - DEbug!");
1064                                                 return;
1065                                         }
1066
1067                                         /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1068                                         if (*ptr_data == 0x83) {
1069                                                 /* increment to next byte */
1070                                                 ptr_data++;
1071                                                 file_id_len = *ptr_data++;
1072                                                 memcpy(&file_id, ptr_data, file_id_len);
1073                                                 /* swap bytes    */
1074                                                 SWAPBYTES16(file_id);
1075                                                 ptr_data = ptr_data + 2;
1076                                                 dbg("Getting FileID=[0x%x]", file_id);
1077                                         } else {
1078                                                 dbg("INVALID FCP received - DEbug!");
1079                                                 free(recordData);
1080                                                 ReleaseResponse();
1081                                                 return;
1082                                         }
1083
1084                                         /*      proprietary information  */
1085                                         if (*ptr_data == 0xA5) {
1086                                                 unsigned short prop_len;
1087                                                 /* increment to next byte */
1088                                                 ptr_data++;
1089                                                 /* length */
1090                                                 prop_len = *ptr_data;
1091                                                 /* skip data */
1092                                                 ptr_data = ptr_data + prop_len + 1;
1093                                         } else {
1094                                                 dbg("INVALID FCP received - DEbug!");
1095                                         }
1096
1097                                         /* life cycle status integer [8A][length:0x01][status]*/
1098                                         /*
1099                                          status info b8~b1
1100                                          00000000 : No information given
1101                                          00000001 : creation state
1102                                          00000011 : initialization state
1103                                          000001-1 : operation state -activated
1104                                          000001-0 : operation state -deactivated
1105                                          000011-- : Termination state
1106                                          b8~b5 !=0, b4~b1=X : Proprietary
1107                                          Any other value : RFU
1108                                          */
1109                                         if (*ptr_data == 0x8A) {
1110                                                 /* increment to next byte */
1111                                                 ptr_data++;
1112                                                 /* length - value 1 */
1113                                                 ptr_data++;
1114
1115                                                 switch (*ptr_data) {
1116                                                         case 0x04:
1117                                                         case 0x06:
1118                                                                 dbg("<IPC_RX> operation state -deactivated");
1119                                                                 ptr_data++;
1120                                                                 break;
1121                                                         case 0x05:
1122                                                         case 0x07:
1123                                                                 dbg("<IPC_RX> operation state -activated");
1124                                                                 ptr_data++;
1125                                                                 break;
1126                                                         default:
1127                                                                 dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
1128                                                                 ptr_data++;
1129                                                                 break;
1130                                                 }
1131                                         }
1132
1133                                         /* related to security attributes : currently not handled*/
1134                                         if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1135                                                 /* increment to next byte */
1136                                                 ptr_data++;
1137                                                 /* if tag length is 3 */
1138                                                 if (*ptr_data == 0x03) {
1139                                                         /* increment to next byte */
1140                                                         ptr_data++;
1141                                                         /* EFARR file id */
1142                                                         memcpy(&arr_file_id, ptr_data, 2);
1143                                                         /* swap byes */
1144                                                         SWAPBYTES16(arr_file_id);
1145                                                         ptr_data = ptr_data + 2;
1146                                                         arr_file_id_rec_num = *ptr_data++;
1147                                                 } else {
1148                                                         /* if tag length is not 3 */
1149                                                         /* ignoring bytes       */
1150                                                         //      ptr_data = ptr_data + 4;
1151                                                         dbg("Useless security attributes, so jump to next tag");
1152                                                         ptr_data = ptr_data + (*ptr_data + 1);
1153                                                 }
1154                                         } else {
1155                                                 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1156                                                 free(recordData);
1157                                                 ReleaseResponse();
1158                                                 return;
1159                                         }
1160
1161                                         dbg("Current ptr_data value is [%x]", *ptr_data);
1162
1163                                         /* file size excluding structural info*/
1164                                         if (*ptr_data == 0x80) {
1165                                                 /* for EF file size is body of file and for Linear or cyclic it is
1166                                                  * number of recXsizeof(one record)
1167                                                  */
1168                                                 /* increment to next byte */
1169                                                 ptr_data++;
1170                                                 /* length is 1 byte - value is 2 bytes or more */
1171                                                 ptr_data++;
1172                                                 memcpy(&file_size, ptr_data, 2);
1173                                                 /* swap bytes */
1174                                                 SWAPBYTES16(file_size);
1175                                                 ptr_data = ptr_data + 2;
1176                                         } else {
1177                                                 dbg("INVALID FCP received - DEbug!");
1178                                                 free(recordData);
1179                                                 ReleaseResponse();
1180                                                 return;
1181                                         }
1182
1183                                         /* total file size including structural info*/
1184                                         if (*ptr_data == 0x81) {
1185                                                 int len;
1186                                                 /* increment to next byte */
1187                                                 ptr_data++;
1188                                                 /* length */
1189                                                 len = *ptr_data;
1190                                                 /* ignored bytes */
1191                                                 ptr_data = ptr_data + 3;
1192                                         } else {
1193                                                 dbg("INVALID FCP received - DEbug!");
1194                                                 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1195                                                 /* return -1; */
1196                                         }
1197                                         /*short file identifier ignored*/
1198                                         if (*ptr_data == 0x88) {
1199                                                 dbg("0x88: Do Nothing");
1200                                                 /*DO NOTHING*/
1201                                         }
1202                                 } else {
1203                                         dbg("INVALID FCP received - DEbug!");
1204                                         free(recordData);
1205                                         ReleaseResponse();
1206                                         return;
1207                                 }
1208                         }
1209                         else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM)
1210                         {
1211                                 unsigned char gsm_specific_file_data_len = 0;
1212                                 /*      ignore RFU byte1 and byte2 */
1213                                 ptr_data++;
1214                                 ptr_data++;
1215                                 /*      file size */
1216                                 //file_size = p_info->response_len;
1217                                 memcpy(&file_size, ptr_data, 2);
1218                                 /* swap bytes */
1219                                 SWAPBYTES16(file_size);
1220                                 /*      parsed file size */
1221                                 ptr_data = ptr_data + 2;
1222                                 /*  file id  */
1223                                 memcpy(&file_id, ptr_data, 2);
1224                                 SWAPBYTES16(file_id);
1225                                 dbg(" FILE id --> [%x]", file_id);
1226                                 ptr_data = ptr_data + 2;
1227                                 /* save file type - transparent, linear fixed or cyclic */
1228                                 file_type_tag = (*(ptr_data + 7));
1229
1230                                 switch (*ptr_data) {
1231                                         case 0x0:
1232                                                 /* RFU file type */
1233                                                 dbg(" RFU file type- not handled - Debug!");
1234                                                 break;
1235                                         case 0x1:
1236                                                 /* MF file type */
1237                                                 dbg(" MF file type - not handled - Debug!");
1238                                                 break;
1239                                         case 0x2:
1240                                                 /* DF file type */
1241                                                 dbg(" DF file type - not handled - Debug!");
1242                                                 break;
1243                                         case 0x4:
1244                                                 /* EF file type */
1245                                                 dbg(" EF file type [%d] ", file_type_tag);
1246                                                 /*      increment to next byte */
1247                                                 ptr_data++;
1248
1249                                                 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1250                                                         /* increament to next byte as this byte is RFU */
1251                                                         ptr_data++;
1252                                                         file_type =
1253                                                                         (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
1254                                                 } else {
1255                                                         /* increment to next byte */
1256                                                         ptr_data++;
1257                                                         /*      For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1258                                                         /* the INCREASE command is allowed on the selected cyclic file. */
1259                                                         file_type = 0x04;       // SIM_FTYPE_CYCLIC;
1260                                                 }
1261                                                 /* bytes 9 to 11 give SIM file access conditions */
1262                                                 ptr_data++;
1263                                                 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1264                                                 ptr_data++;
1265                                                 /* byte 11 is invalidate and rehabilate nibbles */
1266                                                 ptr_data++;
1267                                                 /* byte 12 - file status */
1268                                                 ptr_data++;
1269                                                 /* byte 13 - GSM specific data */
1270                                                 gsm_specific_file_data_len = *ptr_data;
1271                                                 ptr_data++;
1272                                                 /*      byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1273                                                 ptr_data++;
1274                                                 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1275                                                 record_len = *ptr_data;
1276                                                 dbg("record length[%d], file size[%d]", record_len, file_size);
1277
1278                                                 if (record_len != 0)
1279                                                         num_of_records = (file_size / record_len);
1280
1281                                                 dbg("Number of records [%d]", num_of_records);
1282                                                 break;
1283
1284                                         default:
1285                                                 dbg(" not handled file type");
1286                                                 break;
1287                                 }
1288                         }
1289                         else
1290                         {
1291                                 dbg(" Card Type - UNKNOWN  [%d]", tcore_sim_get_type(co_sim));
1292                         }
1293
1294                         dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
1295
1296                         respGetParamCnt.recordCount = num_of_records;
1297                         respGetParamCnt.result = SMS_SUCCESS;
1298
1299                         free(recordData);
1300                 }
1301                 else
1302                 {
1303                         /*2. SIM access fail case*/
1304                         dbg("SIM access fail");
1305                         respGetParamCnt.result = SMS_UNKNOWN;
1306                 }
1307         }
1308         else
1309         {
1310                 dbg("response error!!!");
1311                 respGetParamCnt.result = SMS_UNKNOWN;
1312         }
1313
1314         ReleaseResponse();
1315
1316         tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
1317
1318         return;
1319
1320 }
1321
1322 /********************************************************/
1323 /***********************  Requests ************************/
1324 /********************************************************/
1325 static TReturn send_umts_msg(CoreObject *o, UserRequest *ur)
1326 {
1327         TcorePlugin *p = NULL;
1328         TcoreHal *h = NULL;
1329         TcorePending *pending = NULL;
1330         const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
1331         char *cmd_str = NULL;
1332         struct ATReqMetaInfo metainfo;
1333         int info_len =0;
1334
1335         dbg("new pending(IPC_SMS_SEND_MSG)");
1336
1337         sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
1338
1339         p = tcore_object_ref_plugin(o);
1340         h = tcore_object_get_hal(o);
1341
1342         if (!sendUmtsMsg || !h)
1343                 return TCORE_RETURN_ENOSYS;
1344
1345         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1346         metainfo.type = NO_RESULT;
1347         metainfo.responsePrefix[0] ='\0';
1348         info_len = sizeof(struct ATReqMetaInfo);
1349
1350         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1351
1352         // AT+CMMS=<mode>
1353         cmd_str = g_strdup_printf("AT+CMMS=%d%s", sendUmtsMsg->more, "\r");
1354         dbg("[tcore_SMS] *************************MsgLen[%d]", sendUmtsMsg->msgDataPackage.msgLength);
1355
1356         pending = tcore_pending_new(o, ID_RESERVED_AT);
1357         tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1358         tcore_pending_set_timeout(pending, 0);
1359         tcore_pending_set_response_callback(pending, on_response_send_umts_msg, NULL);
1360         tcore_pending_link_user_request(pending, ur);
1361
1362         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1363
1364         free(cmd_str);
1365
1366         return tcore_hal_send_request(h, pending);
1367 }
1368
1369 static TReturn Send_SmsSubmitTpdu(CoreObject *o, UserRequest *ur)
1370 {
1371         TcorePlugin *p = NULL;
1372         TcoreHal *h = NULL;
1373         TcorePending *pending = NULL;
1374         const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
1375         char *cmd_str = NULL;
1376         struct ATReqMetaInfo metainfo;
1377         int info_len =0;
1378         char tpdu[MAX_GSM_SMS_TPDU_SIZE];
1379         int ScLength = 0;
1380         char *hexString = NULL;
1381         int tpduDataLen = 0;
1382         int i = 0;
1383
1384         TReturn api_err = TCORE_RETURN_SUCCESS;
1385
1386         dbg("new pending(IPC_SMS_SEND_MSG)");
1387
1388         sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
1389
1390         p = tcore_object_ref_plugin(o);
1391         h = tcore_object_get_hal(o);
1392
1393         if (!sendUmtsMsg || !h)
1394                 return TCORE_RETURN_ENOSYS;
1395
1396         /* Populate data */
1397         dbg("[tcore_SMS] MoreToSend[0x%x](1:Persist, 2:NotPersist) MsgLen[%d]",sendUmtsMsg->more, sendUmtsMsg->msgDataPackage.msgLength);
1398         for(i=0; i<sendUmtsMsg->msgDataPackage.msgLength; i++)
1399                 dbg("[%02x]", sendUmtsMsg->msgDataPackage.tpduData[i]);
1400
1401         if ((sendUmtsMsg->msgDataPackage.msgLength > 0) && (MAX_GSM_SMS_TPDU_SIZE > sendUmtsMsg->msgDataPackage.msgLength))
1402         {
1403                 if (sendUmtsMsg->msgDataPackage.msgLength < SMS_SMDATA_SIZE_MAX)
1404                 {
1405                         memset(tpdu, 0, sizeof(MAX_GSM_SMS_TPDU_SIZE));
1406
1407                         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1408                         metainfo.type = SINGLELINE;
1409                         memcpy(metainfo.responsePrefix,"+CMGS:",strlen("+CMGS:"));
1410                         info_len = sizeof(struct ATReqMetaInfo);
1411
1412                         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1413
1414                         ScLength = sendUmtsMsg->msgDataPackage.sca[0];
1415                         if(sendUmtsMsg->msgDataPackage.sca[0] == 0)
1416                         {
1417                                 memcpy(&tpdu[0], sendUmtsMsg->msgDataPackage.sca, ScLength+2);
1418                         }
1419                         else
1420                         {
1421                                 dbg("SC length in ipc tx is %d - before", ScLength);
1422
1423                                 util_sms_get_length_of_sca(&ScLength);
1424
1425                                 dbg(" SC length in ipc tx is %d - after", ScLength);
1426
1427                                 tpdu[0] = ScLength +1 ;
1428                                 //1Copy SCA to the ipc stream first
1429                                 memcpy(&(tpdu[1]), &( sendUmtsMsg->msgDataPackage.sca[1]), (ScLength + 1));
1430                         }
1431
1432                         if ((ScLength <= SMS_MAX_SMS_SERVICE_CENTER_ADDR) && (sendUmtsMsg->msgDataPackage.msgLength < SMS_SMDATA_SIZE_MAX))
1433                         {
1434                                 //1Copy rest of the SMS-SUBMIT TPDU
1435                                 memcpy(&(tpdu[ScLength + 2]), sendUmtsMsg->msgDataPackage.tpduData, sendUmtsMsg->msgDataPackage.msgLength);
1436                         } else
1437                         {
1438                                 dbg("SCA len is %d", ScLength);
1439                                 api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
1440                                 return api_err;
1441                         }
1442
1443                         tpduDataLen = sendUmtsMsg->msgDataPackage.msgLength + (ScLength + 2);
1444                         hexString = calloc(tpduDataLen*2, 1);;
1445
1446                         for( i=0; i<tpduDataLen*2; i+=2)
1447                         {
1448                                 char value = 0;
1449
1450                                 value = (tpdu[i/2] & 0xf0 ) >> 4;
1451                                 if(value < 0xA)
1452                                         hexString[i] = ((tpdu[i/2] & 0xf0 ) >> 4) + '0';
1453                                 else hexString[i] = ((tpdu[i/2] & 0xf0 ) >> 4) + 'A' -10;
1454
1455                                 value = tpdu[i/2] & 0x0f;
1456                                 if(value < 0xA)
1457                                         hexString[i+1] = (tpdu[i/2] & 0x0f ) + '0';
1458                                 else hexString[i+1] = (tpdu[i/2] & 0x0f ) + 'A' -10;
1459
1460                         }
1461
1462                         // AT+CMGS=<length><CR>pdu_is_given<ctrl-z/ESC>
1463                         cmd_str = g_strdup_printf("AT+CMGS=%d%s%s%x%s", sendUmtsMsg->msgDataPackage.msgLength, "\r", hexString, 0x1A,"\r");
1464                         dbg("cmd_str is %s", cmd_str);
1465
1466                         pending = tcore_pending_new(o, ID_RESERVED_AT);
1467                         tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1468                         tcore_pending_set_timeout(pending, 0);
1469                         tcore_pending_set_response_callback(pending, on_response_send_smsSubmitTpdu, NULL);
1470                         tcore_pending_link_user_request(pending, ur);
1471
1472                         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1473
1474                         api_err = tcore_hal_send_request(h, pending);
1475
1476                         free(cmd_str);
1477                         free(hexString);
1478                 }
1479                 else
1480                 {
1481                         dbg("[tcore_SMS] TPDU size[%d] is over !!!, max is [%d]", sendUmtsMsg->msgDataPackage.msgLength, SMS_SMDATA_SIZE_MAX);
1482                         api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
1483                         return api_err;
1484                 }
1485         }
1486         else
1487         {
1488                 dbg("[tcore_SMS] Invalid Data Length");
1489                 api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
1490         }
1491
1492         return api_err;
1493
1494 }
1495
1496 static TReturn send_cdma_msg(CoreObject *o, UserRequest *ur)
1497 {
1498         dbg("[tcore_SMS] Not supported");
1499         return TCORE_RETURN_ENOSYS;}
1500
1501 static TReturn read_msg(CoreObject *o, UserRequest *ur)
1502 {
1503         dbg("[tcore_SMS] Not supported");
1504         return TCORE_RETURN_ENOSYS;
1505 }
1506
1507 static TReturn save_msg(CoreObject *o, UserRequest *ur)
1508 {
1509         dbg("[tcore_SMS] Not supported");
1510         return TCORE_RETURN_ENOSYS;
1511 }
1512
1513 static TReturn delete_msg(CoreObject *o, UserRequest *ur)
1514 {
1515         dbg("[tcore_SMS] Not supported");
1516         return TCORE_RETURN_ENOSYS;
1517 }
1518
1519 static TReturn get_storedMsgCnt(CoreObject *o, UserRequest *ur)
1520 {
1521         TcorePlugin *p = NULL;
1522         TcoreHal *h = NULL;
1523         TcorePending *pending = NULL;
1524         const struct treq_sms_get_msg_count *getStoredMsgCnt = NULL;
1525
1526         char *cmd_str = NULL;
1527         struct ATReqMetaInfo metainfo;
1528         int info_len =0;
1529
1530         dbg("new pending(IPC_SMS_GET_STORED_MSG_COUNT)");
1531
1532         getStoredMsgCnt = tcore_user_request_ref_data(ur, NULL);
1533
1534         p = tcore_object_ref_plugin(o);
1535         h = tcore_object_get_hal(o);
1536
1537         if (!h)
1538         {
1539                 dbg("[ERR]  tcore_object_get_hal() pointer is NULL");
1540                 return TCORE_RETURN_ENOSYS;
1541         }
1542
1543         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1544         metainfo.type = SINGLELINE;
1545         memcpy(metainfo.responsePrefix,"+CPMS:",strlen("+CPMS:"));
1546         info_len = sizeof(struct ATReqMetaInfo);
1547
1548         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1549
1550         // AT+CPMS=<mem1>[,<mem2>[,<mem3>]]
1551         // Possible response(s) : +CPMS: <used1>,<total1>,<used2>,<total2>,<used3>,<total3>
1552         cmd_str = g_strdup_printf("AT+CPMS=\"SM\"%s", "\r");
1553
1554         pending = tcore_pending_new(o, ID_RESERVED_AT);
1555         tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1556         tcore_pending_set_timeout(pending, 0);
1557         tcore_pending_set_response_callback(pending, on_response_get_storedMsgCnt, NULL);
1558         tcore_pending_link_user_request(pending, ur);
1559
1560         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1561
1562         free(cmd_str);
1563
1564         return tcore_hal_send_request(h, pending);
1565
1566 }
1567
1568 static TReturn get_sca(CoreObject *o, UserRequest *ur)
1569 {
1570         TcorePlugin *p = NULL;
1571         TcoreHal *h = NULL;
1572         TcorePending *pending = NULL;
1573         const struct treq_sms_get_sca *getSca = NULL;
1574         char *cmd_str = NULL;
1575         struct ATReqMetaInfo metainfo;
1576         int info_len =0;
1577
1578         dbg("new pending(IPC_SMS_GET_SCA)");
1579
1580         getSca = tcore_user_request_ref_data(ur, NULL);
1581
1582         p = tcore_object_ref_plugin(o);
1583         h = tcore_object_get_hal(o);
1584
1585         if (!getSca || !h)
1586                 return TCORE_RETURN_ENOSYS;
1587
1588         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1589         metainfo.type = SINGLELINE;
1590         memcpy(metainfo.responsePrefix,"+CSCA:",strlen("+CSCA:"));
1591         info_len = sizeof(struct ATReqMetaInfo);
1592
1593         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1594
1595         // AT +CSCA?
1596         // Possible response(s) : +CSCA: <sca number>,<sca type>
1597         cmd_str = g_strdup_printf("AT +CSCA?%s", "\r");
1598
1599         pending = tcore_pending_new(o, ID_RESERVED_AT);
1600         tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1601         tcore_pending_set_timeout(pending, 0);
1602         tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
1603         tcore_pending_link_user_request(pending, ur);
1604
1605         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1606
1607         free(cmd_str);
1608
1609         return tcore_hal_send_request(h, pending);
1610
1611 }
1612
1613 static TReturn set_sca(CoreObject *o, UserRequest *ur)
1614 {
1615         TcorePlugin *p = NULL;
1616         TcoreHal *h = NULL;
1617         TcorePending *pending = NULL;
1618         const struct treq_sms_set_sca *setSca;
1619         int scaType = 0;
1620         char *cmd_str = NULL;
1621         struct ATReqMetaInfo metainfo;
1622         int info_len =0;
1623
1624         dbg("new pending(IPC_SMS_SET_SCA)");
1625
1626         setSca = tcore_user_request_ref_data(ur, NULL);
1627
1628         if(setSca->index != 0){
1629                 dbg("Index except 0 is supported");
1630                 return TCORE_RETURN_EINVAL;     // TCORE_API_NOT_SUPPORTED;
1631         }
1632
1633         p = tcore_object_ref_plugin(o);
1634         h = tcore_object_get_hal(o);
1635
1636         if (!setSca || !h)
1637                 return TCORE_RETURN_ENOSYS;
1638
1639         if(setSca->scaInfo.typeOfNum == SIM_TON_INTERNATIONAL)
1640                         scaType = 145;
1641         else            scaType = 129;
1642
1643         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1644         metainfo.type = NO_RESULT;
1645         metainfo.responsePrefix[0] ='\0';
1646         info_len = sizeof(struct ATReqMetaInfo);
1647
1648         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1649
1650         // AT +CSCA=<sca number>[,<sca type>]
1651         // 129:Unknown numbering plan, national/international number unknown, 145:international number
1652         cmd_str = g_strdup_printf("AT+CSCA=\"%s\", %d%s", setSca->scaInfo.diallingNum, scaType, "\r");
1653
1654         pending = tcore_pending_new(o, ID_RESERVED_AT);
1655         tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1656         tcore_pending_set_timeout(pending, 0);
1657         tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
1658         tcore_pending_link_user_request(pending, ur);
1659
1660         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1661
1662         free(cmd_str);
1663
1664         return tcore_hal_send_request(h, pending);
1665
1666 }
1667
1668 static TReturn get_cb_config(CoreObject *o, UserRequest *ur)
1669 {
1670         dbg("[tcore_SMS] Not supported");
1671         return TCORE_RETURN_ENOSYS;
1672 }
1673
1674 static TReturn set_cb_config(CoreObject *o, UserRequest *ur)
1675 {
1676         dbg("[tcore_SMS] Not supported");
1677         return TCORE_RETURN_ENOSYS;
1678 }
1679
1680 static TReturn set_mem_status(CoreObject *o, UserRequest *ur)
1681 {
1682         dbg("[tcore_SMS] Not supported");
1683         return TCORE_RETURN_ENOSYS;
1684 }
1685
1686 static TReturn get_pref_brearer(CoreObject *o, UserRequest *ur)
1687 {
1688         dbg("[tcore_SMS] Not supported");
1689         return TCORE_RETURN_ENOSYS;
1690 }
1691
1692 static TReturn set_pref_brearer(CoreObject *o, UserRequest *ur)
1693 {
1694         dbg("[tcore_SMS] Not supported");
1695         return TCORE_RETURN_ENOSYS;
1696 }
1697
1698 static TReturn set_delivery_report(CoreObject *o, UserRequest *ur)
1699 {
1700         TcorePlugin *p = NULL;
1701         TcoreHal *h = NULL;
1702         TcorePending *pending = NULL;
1703         const struct treq_sms_set_delivery_report *deliveryReport = NULL;
1704         char *cmd_str;
1705         struct ATReqMetaInfo metainfo;
1706         int info_len =0;
1707
1708         dbg("new pending(IPC_SMS_SVC_CENTER_ADDR)");
1709
1710         deliveryReport = tcore_user_request_ref_data(ur, NULL);
1711
1712         p = tcore_object_ref_plugin(o);
1713         h = tcore_object_get_hal(o);
1714
1715         if (!deliveryReport || !h)
1716                 return TCORE_RETURN_ENOSYS;
1717
1718         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1719         metainfo.type = NO_RESULT;
1720         metainfo.responsePrefix[0] ='\0';
1721         info_len = sizeof(struct ATReqMetaInfo);
1722
1723         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1724
1725         // AT+CNMA
1726         if(deliveryReport->rspType == SMS_SENDSMS_SUCCESS)
1727                 cmd_str = g_strdup_printf("AT+CNMA=0%s", "\r");
1728         else
1729                 cmd_str = g_strdup_printf("AT+CNMA=2,3%s%x%s", "/n", 0x00ff00, "");
1730
1731         pending = tcore_pending_new(o, ID_RESERVED_AT);
1732         tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1733         tcore_pending_set_timeout(pending, 0);
1734         tcore_pending_set_response_callback(pending, on_response_set_delivery_report, NULL);
1735         tcore_pending_link_user_request(pending, ur);
1736
1737         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1738
1739         free(cmd_str);
1740
1741         return tcore_hal_send_request(h, pending);
1742
1743 }
1744
1745 static TReturn set_msg_status(CoreObject *o, UserRequest *ur)
1746 {
1747         dbg("[tcore_SMS] Not supported");
1748         return TCORE_RETURN_ENOSYS;
1749 }
1750
1751 static TReturn get_sms_params(CoreObject *o, UserRequest *ur)
1752 {
1753         TcorePlugin *p = NULL;
1754         TcoreHal *h = NULL;
1755         TcorePending *pending = NULL;
1756         const struct treq_sms_get_params *getSmsParams = NULL;
1757
1758         char *cmd_str = NULL;
1759         struct ATReqMetaInfo metainfo;
1760         int info_len =0;
1761
1762         dbg("new pending(IPC_SMS_GET_CBS_CFG)");
1763
1764         getSmsParams = tcore_user_request_ref_data(ur, NULL);
1765
1766         p = tcore_object_ref_plugin(o);
1767         h = tcore_object_get_hal(o);
1768
1769         if (!getSmsParams || !h)
1770         {
1771                 dbg("[ERR]  pointer is NULL, getSmsParams=0x%x, h=0x%x", getSmsParams, h);
1772                 return TCORE_RETURN_ENOSYS;
1773         }
1774
1775         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1776         metainfo.type = SINGLELINE;
1777         memcpy(metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
1778         info_len = sizeof(struct ATReqMetaInfo);
1779
1780         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1781
1782         // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>
1783         cmd_str = g_strdup_printf("AT+CRSM=%d, %d, %d, 4, 40%s", 178, 0x6F42, getSmsParams->index + 1, "\r");
1784
1785         pending = tcore_pending_new(o, ID_RESERVED_AT);
1786         tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1787         tcore_pending_set_timeout(pending, 0);
1788         tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
1789         tcore_pending_link_user_request(pending, ur);
1790
1791         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1792
1793         free(cmd_str);
1794
1795         return tcore_hal_send_request(h, pending);
1796
1797 }
1798
1799 static TReturn set_sms_params(CoreObject *o, UserRequest *ur)
1800 {
1801         dbg("[tcore_SMS] Not supported");
1802         return TCORE_RETURN_ENOSYS;
1803 }
1804
1805 static TReturn get_paramcnt(CoreObject *o, UserRequest *ur)
1806 {
1807         TcorePlugin *p = NULL;
1808         TcoreHal *h = NULL;
1809         TcorePending *pending = NULL;
1810         const struct treq_sms_get_paramcnt *getParamCnt = NULL;
1811
1812         char *cmd_str = NULL;
1813         struct ATReqMetaInfo metainfo;
1814         int info_len =0;
1815
1816         getParamCnt = tcore_user_request_ref_data(ur, NULL);
1817
1818         p = tcore_object_ref_plugin(o);
1819         h = tcore_object_get_hal(o);
1820
1821         if (!h) // request data is NULL, so do not NULL check for getParamCnt
1822         {
1823                 dbg("[ERR]  pointer is NULL, getParamCnt=0x%x, h=0x%x", getParamCnt, h);
1824                 return TCORE_RETURN_ENOSYS;
1825         }
1826
1827         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1828         metainfo.type = SINGLELINE;
1829         memcpy(metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
1830         info_len = sizeof(struct ATReqMetaInfo);
1831
1832         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1833
1834         // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>, EFsmsp: 0x6F42
1835         cmd_str = g_strdup_printf("AT+CRSM=192, %d%s", 0x6F42, "\r");
1836
1837         pending = tcore_pending_new(o, ID_RESERVED_AT);
1838         tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1839         tcore_pending_set_timeout(pending, 0);
1840         tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
1841         tcore_pending_link_user_request(pending, ur);
1842
1843         tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1844
1845         free(cmd_str);
1846
1847         return tcore_hal_send_request(h, pending);
1848 }
1849
1850 static struct tcore_sms_operations sms_ops =
1851 {
1852         .send_umts_msg = send_umts_msg,
1853         .read_msg = read_msg,
1854         .save_msg = save_msg,
1855         .delete_msg = delete_msg,
1856         .get_storedMsgCnt = get_storedMsgCnt,
1857         .get_sca = get_sca,
1858         .set_sca = set_sca,
1859         .get_cb_config = get_cb_config,
1860         .set_cb_config = set_cb_config,
1861         .set_mem_status = set_mem_status,
1862         .get_pref_brearer = get_pref_brearer,
1863         .set_pref_brearer = set_pref_brearer,
1864         .set_delivery_report = set_delivery_report,
1865         .set_msg_status = set_msg_status,
1866         .get_sms_params = get_sms_params,
1867         .set_sms_params = set_sms_params,
1868         .get_paramcnt = get_paramcnt,
1869         .send_cdma_msg = send_cdma_msg,
1870 };
1871
1872 gboolean s_sms_init(TcorePlugin *p, TcoreHal *h)
1873 {
1874         CoreObject *o;
1875         struct property_sms_info *data;
1876         GQueue *work_queue;
1877
1878         o = tcore_sms_new(p, "umts_sms", &sms_ops, h);
1879         if (!o)
1880                 return FALSE;
1881
1882         work_queue = g_queue_new();
1883         tcore_object_link_user_data(o, work_queue);
1884
1885         tcore_object_add_callback(o, EVENT_SMS_INCOM_MSG, on_event_sms_incom_msg, NULL);
1886         tcore_object_add_callback(o, EVENT_SMS_DEVICE_READY, on_event_sms_device_ready, NULL);
1887
1888         data = calloc(sizeof(struct property_sms_info), 1);
1889         tcore_plugin_link_property(p, "SMS", data);
1890
1891         return TRUE;
1892 }
1893
1894
1895 void s_sms_exit(TcorePlugin *p)
1896 {
1897         CoreObject *o;
1898         struct property_sms_info *data;
1899
1900         o = tcore_plugin_ref_core_object(p, "umts_sms");
1901         if (!o)
1902                 return;
1903
1904         data = tcore_plugin_ref_property(p, "SMS");
1905         if (data)
1906                 free(data);
1907
1908         tcore_sms_free(o);
1909 }
1910