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