Fix vconf error check
[platform/core/messaging/msg-service.git] / plugin / sms_plugin / SmsPluginParamCodec.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <string.h>
19
20 #include "MsgDebug.h"
21 #include "MsgTextConvert.h"
22 #include "SmsPluginUDCodec.h"
23 #include "SmsPluginParamCodec.h"
24
25
26 /*==================================================================================================
27                                      IMPLEMENTATION OF SmsPluginParamCodec - Member Functions
28 ==================================================================================================*/
29 SmsPluginParamCodec::SmsPluginParamCodec()
30 {
31 }
32
33
34 SmsPluginParamCodec::~SmsPluginParamCodec()
35 {
36 }
37
38
39 /*==================================================================================================
40                                      Encode Functions
41 ==================================================================================================*/
42 int SmsPluginParamCodec::encodeAddress(const SMS_ADDRESS_S *pAddress, char **ppParam)
43 {
44         int offset = 0, length = 0;
45         char *temp = (char *)pAddress->address;
46
47         SMS_TON_T ton;
48
49         *ppParam = new char[MAX_ADD_PARAM_LEN];
50
51         /* Set Address Length */
52         if (temp[0] == '+') {
53                 (*ppParam)[offset++] = strlen(temp) - 1;
54                 temp++;
55
56                 ton = SMS_TON_INTERNATIONAL;
57         } else {
58                 (*ppParam)[offset++] = strlen(temp);
59
60                 ton = pAddress->ton;
61         }
62
63         /* Set TON, NPI */
64         (*ppParam)[offset++] = 0x80 + (ton << 4) + pAddress->npi;
65
66         MSG_DEBUG("Address length is %d.", (*ppParam)[0]);
67         MSG_DEBUG("pAddress->ton : %d.", ton);
68         MSG_DEBUG("pAddress->npi : %d.", pAddress->npi);
69
70         length = convertDigitToBcd(temp, strlen(temp), (unsigned char *) &((*ppParam)[offset]));
71
72         offset += length;
73
74         return offset ;
75 }
76
77
78 int SmsPluginParamCodec::encodeTime(const SMS_TIMESTAMP_S *pTimeStamp, char **ppParam)
79 {
80         int offset = 0;
81
82         if (pTimeStamp->format == SMS_TIME_ABSOLUTE) {
83                 int timeZone = pTimeStamp->time.absolute.timeZone;
84                 *ppParam = new char[MAX_ABS_TIME_PARAM_LEN];
85
86                 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.year % 10)  << 4) + (pTimeStamp->time.absolute.year / 10);
87                 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.month % 10) << 4) + (pTimeStamp->time.absolute.month / 10);
88                 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.day % 10) << 4) + (pTimeStamp->time.absolute.day / 10);
89                 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.hour % 10) << 4) + (pTimeStamp->time.absolute.hour / 10);
90                 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.minute % 10) << 4) + (pTimeStamp->time.absolute.minute / 10);
91                 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.second % 10) << 4) + (pTimeStamp->time.absolute.second / 10);
92
93                 if (timeZone < 0) {
94                         timeZone *= -1;
95                         (*ppParam)[offset] = 0x08;
96                 }
97                 (*ppParam)[offset++] += ((pTimeStamp->time.absolute.timeZone % 10) << 4) + (pTimeStamp->time.absolute.timeZone / 10);
98
99
100                 return offset;
101         } else if (pTimeStamp->format == SMS_TIME_RELATIVE) {
102                 *ppParam = new char[MAX_REL_TIME_PARAM_LEN+1];
103
104                 memcpy(*ppParam, &(pTimeStamp->time.relative.time), MAX_REL_TIME_PARAM_LEN);
105
106                 return MAX_REL_TIME_PARAM_LEN;
107         }
108
109         return offset;
110 }
111
112
113 int SmsPluginParamCodec::encodeDCS(const SMS_DCS_S *pDCS, char **ppParam)
114 {
115         *ppParam = new char[MAX_DCS_PARAM_LEN];
116
117         **ppParam = 0x00;
118
119         switch (pDCS->codingGroup) {
120         case SMS_GROUP_GENERAL: {
121                 if (pDCS->msgClass != SMS_MSG_CLASS_NONE)
122                         **ppParam = 0x10 + pDCS->msgClass;
123
124                 if (pDCS->bCompressed)
125                         **ppParam |= 0x20;
126         }
127                 break;
128
129         case SMS_GROUP_CODING_CLASS: {
130                 **ppParam = 0xF0 + pDCS->msgClass;
131         }
132                 break;
133
134         case SMS_GROUP_DELETION:
135                 /* not supported */
136                 break;
137
138         case SMS_GROUP_DISCARD:
139                 /* not supported */
140                 break;
141
142         case SMS_GROUP_STORE:
143                 /* not supported */
144                 break;
145
146         default:
147                 return 0;
148         }
149
150         switch (pDCS->codingScheme) {
151         case SMS_CHARSET_7BIT:
152
153                 break;
154
155         case SMS_CHARSET_8BIT:
156                 **ppParam |= 0x04;
157                 break;
158
159         case SMS_CHARSET_UCS2:
160                 **ppParam |= 0x08;
161                 break;
162
163         default:
164                 return 0;
165         }
166
167         return MAX_DCS_PARAM_LEN;
168 }
169
170
171 int SmsPluginParamCodec::encodeSMSC(const char *pAddress, unsigned char *pEncodeAddr)
172 {
173         char newAddr[MAX_SMSC_LEN+1];
174         memset(newAddr, 0x00, sizeof(newAddr));
175
176 /*      MSG_DEBUG("SMSC [%s]", pAddress);
177 */
178         if (pAddress[0] == '+')
179                 strncpy(newAddr, pAddress+1, MAX_SMSC_LEN);
180         else
181                 strncpy(newAddr, pAddress, MAX_SMSC_LEN);
182
183         /* Set Address */
184         int encodeLen = convertDigitToBcd(newAddr, strlen(newAddr), pEncodeAddr);
185
186         pEncodeAddr[encodeLen] = '\0';
187
188         return encodeLen;
189 }
190
191
192 int SmsPluginParamCodec::encodeSMSC(const SMS_ADDRESS_S *pAddress, unsigned char *pSMSC)
193 {
194         char newAddr[MAX_SMSC_LEN+1];
195         memset(newAddr, 0x00, sizeof(newAddr));
196
197         int dataSize = 0, addrLen = 0;
198
199         if (pAddress->address[0] == '+')
200                 memcpy(newAddr, pAddress->address+1, strlen(pAddress->address)-1);
201         else
202                 memcpy(newAddr, pAddress->address, strlen(pAddress->address));
203
204         addrLen = strlen(newAddr);
205
206         if (addrLen % 2 == 0)
207                 dataSize = 2 + (addrLen/2);
208         else
209                 dataSize = 2 + (addrLen/2) + 1;
210
211         if (dataSize > MAX_SMSC_LEN) {
212                 MSG_DEBUG("addrLen is too long [%d]", addrLen);
213                 MSG_DEBUG("dataSize is too long [%d]", dataSize);
214
215                 return 0;
216         }
217
218         /* Set Address Length
219            Check IPC 4.0 -> addrLen/2 */
220         pSMSC[0] = addrLen;
221
222         /* Set TON, NPI */
223         pSMSC[1] = 0x80 + (pAddress->ton << 4) + pAddress->npi;
224
225         /* Set Address */
226         convertDigitToBcd(newAddr, addrLen, &(pSMSC[2]));
227
228         pSMSC[dataSize] = '\0';
229
230         return dataSize;
231 }
232
233
234 /*==================================================================================================
235                                      Decode Functions
236 ==================================================================================================*/
237 int SmsPluginParamCodec::decodeAddress(const unsigned char *pTpdu, SMS_ADDRESS_S *pAddress)
238 {
239         int offset = 0, addrLen = 0, bcdLen = 0;
240         MsgTextConvert *textCvt = MsgTextConvert::instance();
241         memset(pAddress->address, 0x00, sizeof(pAddress->address));
242
243         addrLen = (int)pTpdu[offset++];
244
245         if (addrLen % 2 == 0)
246                 bcdLen = addrLen/2;
247         else
248                 bcdLen = addrLen/2 + 1;
249
250         pAddress->ton = (pTpdu[offset] & 0x70) >> 4;
251         pAddress->npi = pTpdu[offset++] & 0x0F;
252
253         MSG_DEBUG("ton [%d]", pAddress->ton);
254         MSG_DEBUG("npi [%d]", pAddress->npi);
255
256         if (pAddress->ton == SMS_TON_ALPHANUMERIC) {
257                 MSG_DEBUG("Alphanumeric address");
258
259                 char* tmpAddress = new char[MAX_ADDRESS_LEN];
260                 int tmplength = 0;
261
262                 tmplength = SmsPluginUDCodec::unpack7bitChar(&(pTpdu[offset]), (addrLen*4)/7, 0, tmpAddress);
263
264                 MSG_LANG_INFO_S langInfo = {0, };
265
266                 langInfo.bSingleShift = false;
267                 langInfo.bLockingShift = false;
268
269                 textCvt->convertGSM7bitToUTF8((unsigned char*)pAddress->address, MAX_ADDRESS_LEN, (unsigned char*)tmpAddress, tmplength, &langInfo);
270
271                 if (tmpAddress)
272                         delete[] tmpAddress;
273         } else if (pAddress->ton == SMS_TON_INTERNATIONAL) {
274                 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[1]));
275                 if (pAddress->address[1] != '\0')
276                         pAddress->address[0] = '+';
277         } else {
278                 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[0]));
279         }
280
281         offset +=       bcdLen;
282
283 /*      MSG_DEBUG("address [%s]", pAddress->address);
284 */
285         return offset;
286 }
287
288
289 int SmsPluginParamCodec::decodeTime(const unsigned char *pTpdu, SMS_TIMESTAMP_S *pTimeStamp)
290 {
291         int offset = 0;
292
293         /* decode in ABSOLUTE time type. */
294         pTimeStamp->format = SMS_TIME_ABSOLUTE;
295
296         pTimeStamp->time.absolute.year = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
297         offset++;
298
299         pTimeStamp->time.absolute.month = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
300         offset++;
301
302         pTimeStamp->time.absolute.day = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
303         offset++;
304
305         pTimeStamp->time.absolute.hour = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
306         offset++;
307
308         pTimeStamp->time.absolute.minute = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
309         offset++;
310
311         pTimeStamp->time.absolute.second = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
312         offset++;
313
314         pTimeStamp->time.absolute.timeZone = (pTpdu[offset] & 0x07)*10 + ((pTpdu[offset] & 0xF0) >> 4);
315
316         if (pTpdu[offset] & 0x08)
317                 pTimeStamp->time.absolute.timeZone *= (-1);
318
319         offset++;
320
321         return offset;
322 }
323
324
325 int SmsPluginParamCodec::decodeDCS(const unsigned char *pTpdu, SMS_DCS_S *pDCS)
326 {
327         int offset = 0;
328         char dcs = pTpdu[offset++];
329
330         pDCS->bMWI = false;
331         pDCS->bIndActive = false;
332         pDCS->indType = SMS_OTHER_INDICATOR;
333
334         if (((dcs & 0xC0) >> 6) == 0) {
335                 pDCS->codingGroup = SMS_GROUP_GENERAL;
336                 pDCS->bCompressed = (dcs & 0x20) >> 5;
337                 pDCS->codingScheme = (dcs & 0x0C) >> 2;
338
339                 if (((dcs & 0x10) >> 4) == 0)
340                         pDCS->msgClass = SMS_MSG_CLASS_NONE;
341                 else
342                         pDCS->msgClass = dcs & 0x03;
343         } else if (((dcs & 0xF0) >> 4) == 0x0F) {
344                 pDCS->codingGroup = SMS_GROUP_CODING_CLASS;
345                 pDCS->bCompressed = false;
346                 pDCS->codingScheme = (dcs & 0x0C) >> 2;
347
348                 pDCS->msgClass = dcs & 0x03;
349         } else if (((dcs & 0xC0) >> 6) == 1) {
350                 pDCS->codingGroup = SMS_GROUP_DELETION;
351                 pDCS->bCompressed = false;
352                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
353
354                 /* TODO: finish here. ?? */
355         } else if (((dcs & 0xF0) >> 4) == 0x0C) {
356                 pDCS->codingGroup = SMS_GROUP_DISCARD;
357                 pDCS->bCompressed = false;
358                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
359
360                 pDCS->bMWI = true;
361                 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
362                 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
363         } else if (((dcs & 0xF0) >> 4) == 0x0D) {
364                 pDCS->codingGroup = SMS_GROUP_STORE;
365                 pDCS->codingScheme = SMS_CHARSET_7BIT;
366                 pDCS->bCompressed = false;
367                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
368
369                 pDCS->bMWI = true;
370                 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
371                 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
372         } else if (((dcs & 0xF0) >> 4) == 0x0E) {
373                 pDCS->codingGroup = SMS_GROUP_STORE;
374                 pDCS->codingScheme = SMS_CHARSET_UCS2;
375                 pDCS->bCompressed = false;
376                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
377
378                 pDCS->bMWI = true;
379                 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
380                 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
381         } else {
382                 pDCS->codingGroup = SMS_GROUP_UNKNOWN;
383
384                 pDCS->bCompressed = (dcs & 0x20) >> 5;
385                 pDCS->codingScheme = (dcs & 0x0C) >> 2;
386
387                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
388         }
389
390         return offset;
391 }
392
393
394 void SmsPluginParamCodec::decodeSMSC(unsigned char* pAddress, int AddrLen, MSG_SMS_TON_T ton, char *pDecodeAddr)
395 {
396         if (pAddress == NULL || AddrLen == 0)
397                 return;
398
399         if (ton == SMS_TON_INTERNATIONAL) {
400                 pDecodeAddr[0] = '+';
401                 convertBcdToDigit(pAddress, AddrLen, &(pDecodeAddr[1]));
402         } else {
403                 convertBcdToDigit(pAddress, AddrLen, pDecodeAddr);
404         }
405 }
406
407
408 /*==================================================================================================
409                                      Util Functions
410 ==================================================================================================*/
411 int SmsPluginParamCodec::convertDigitToBcd(char *pDigit, int DigitLen, unsigned char *pBcd)
412 {
413         int offset = 0;
414         unsigned char temp;
415
416 /*      MSG_DEBUG("DigitLen [%d]", DigitLen);
417         MSG_DEBUG("pDigit [%s]", pDigit); */
418
419         for (int i = 0; i < DigitLen; i++) {
420                 if (pDigit[i] == '*')
421                         temp = 0x0A;
422                 else if (pDigit[i] == '#')
423                         temp = 0x0B;
424                 else if (pDigit[i] == 'P' || pDigit[i] == 'p')
425                         temp = 0x0C;
426                 else
427                         temp = pDigit[i] - '0';
428
429                 if ((i%2) == 0)
430                         pBcd[offset] = temp & 0x0F;
431                 else
432                         pBcd[offset++] |= ((temp & 0x0F) << 4);
433         }
434
435         if ((DigitLen%2) == 1)
436                 pBcd[offset++] |= 0xF0;
437
438         return offset;
439 }
440
441
442 int SmsPluginParamCodec::convertBcdToDigit(const unsigned char *pBcd, int BcdLen, char *pDigit)
443 {
444         int offset = 0;
445         unsigned char temp;
446
447         for (int i = 0; i < BcdLen; i++) {
448                 temp = pBcd[i] & 0x0F;
449
450                 if (temp == 0x0A)
451                         pDigit[offset++] = '*';
452                 else if (temp == 0x0B)
453                         pDigit[offset++] = '#';
454                 else if (temp == 0x0C)
455                         pDigit[offset++] = 'P';
456                 else
457                         pDigit[offset++] = temp + '0';
458
459                 temp = (pBcd[i] & 0xF0) >> 4;
460
461                 if (temp == 0x0F) {
462                         pDigit[offset] = '\0';
463                         return offset;
464                 }
465
466                 if (temp == 0x0A)
467                         pDigit[offset++] = '*';
468                 else if (temp == 0x0B)
469                         pDigit[offset++] = '#';
470                 else if (temp == 0x0C)
471                         pDigit[offset++] = 'P';
472                 else
473                         pDigit[offset++] = temp + '0';
474         }
475
476         pDigit[offset] = '\0';
477
478         return offset;
479 }
480
481 bool SmsPluginParamCodec::checkCphsVmiMsg(const unsigned char *pTpdu, int *setType, int *indType)
482 {
483         bool ret = false;
484
485         int offset = 0;
486         int addrLen = 0;
487
488         addrLen = (int)pTpdu[offset++];
489
490         if (addrLen == 0x04 && pTpdu[offset++] == 0xD0) {
491                 if (pTpdu[offset] == 0x11 || pTpdu[offset] == 0x10) {
492                         MSG_DEBUG("####### VMI msg ######");
493                         *setType = (int)(pTpdu[offset] & 0x01); /* 0 : clear, 1 : set */
494
495                         *indType = (int)(pTpdu[offset+1] & 0x01); /* 0 : indicator 1, 1 : indicator 2 */
496
497                         ret = true;
498                 }
499         }
500
501         return ret;
502 }
503
504 time_t SmsPluginParamCodec::convertTime(const SMS_TIMESTAMP_S *time_stamp)
505 {
506         time_t rawtime;
507
508         if (time_stamp->format == SMS_TIME_ABSOLUTE) {
509                 MSG_DEBUG("year : %d", time_stamp->time.absolute.year);
510                 MSG_DEBUG("month : %d", time_stamp->time.absolute.month);
511                 MSG_DEBUG("day : %d", time_stamp->time.absolute.day);
512                 MSG_DEBUG("hour : %d", time_stamp->time.absolute.hour);
513                 MSG_DEBUG("minute : %d", time_stamp->time.absolute.minute);
514                 MSG_DEBUG("second : %d", time_stamp->time.absolute.second);
515                 MSG_DEBUG("timezone : %d", time_stamp->time.absolute.timeZone);
516
517                 char displayTime[32];
518                 struct tm timeTM;
519                 memset(&timeTM, 0x00, sizeof(tm));
520
521                 struct tm timeinfo;
522                 memset(&timeinfo, 0x00, sizeof(tm));
523
524                 timeinfo.tm_year = (time_stamp->time.absolute.year + 100);
525                 timeinfo.tm_mon = (time_stamp->time.absolute.month - 1);
526                 timeinfo.tm_mday = time_stamp->time.absolute.day;
527                 timeinfo.tm_hour = time_stamp->time.absolute.hour;
528                 timeinfo.tm_min = time_stamp->time.absolute.minute;
529                 timeinfo.tm_sec = time_stamp->time.absolute.second;
530                 timeinfo.tm_isdst = 0;
531
532                 rawtime = mktime(&timeinfo);
533
534                 MSG_DEBUG("tzname[0] [%s]", tzname[0]);
535                 MSG_DEBUG("tzname[1] [%s]", tzname[1]);
536                 MSG_DEBUG("timezone [%d]", timezone);
537                 MSG_DEBUG("daylight [%d]", daylight);
538
539                 memset(displayTime, 0x00, sizeof(displayTime));
540                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", &timeinfo);
541                 MSG_DEBUG("displayTime [%s]", displayTime);
542
543                 rawtime -= (time_stamp->time.absolute.timeZone * (3600/4));
544
545                 localtime_r(&rawtime, &timeTM);
546                 memset(displayTime, 0x00, sizeof(displayTime));
547                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", &timeTM);
548                 MSG_DEBUG("displayTime [%s]", displayTime);
549
550 /* timezone value is tiemzone + daylight. So should not add daylight */
551 #ifdef __MSG_DAYLIGHT_APPLIED__
552                 rawtime -= (timezone - daylight*3600);
553 #else
554                 rawtime -= timezone;
555 #endif
556
557                 memset(&timeTM, 0x00, sizeof(tm));
558                 localtime_r(&rawtime, &timeTM);
559                 memset(displayTime, 0x00, sizeof(displayTime));
560                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", &timeTM);
561                 MSG_DEBUG("displayTime [%s]", displayTime);
562         } else {
563                 rawtime = time(NULL);
564         }
565
566         return rawtime;
567 }