2 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include "MsgTextConvert.h"
22 #include "SmsPluginUDCodec.h"
23 #include "SmsPluginParamCodec.h"
26 /*==================================================================================================
27 IMPLEMENTATION OF SmsPluginParamCodec - Member Functions
28 ==================================================================================================*/
29 SmsPluginParamCodec::SmsPluginParamCodec()
34 SmsPluginParamCodec::~SmsPluginParamCodec()
39 /*==================================================================================================
41 ==================================================================================================*/
42 int SmsPluginParamCodec::encodeAddress(const SMS_ADDRESS_S *pAddress, char **ppParam)
44 int offset = 0, length = 0;
45 char *temp = (char *)pAddress->address;
49 char *tempParam = new char[MAX_ADD_PARAM_LEN];
50 if (tempParam == NULL)
53 memset(tempParam, 0x00, sizeof(char)*MAX_ADD_PARAM_LEN);
55 /* Set Address Length */
57 tempParam[offset++] = strlen(temp) - 1;
60 ton = SMS_TON_INTERNATIONAL;
62 tempParam[offset++] = strlen(temp);
68 tempParam[offset++] = 0x80 + (ton << 4) + pAddress->npi;
70 MSG_DEBUG("Address length is %d.", tempParam[0]);
71 MSG_DEBUG("pAddress->ton : %d.", ton);
72 MSG_DEBUG("pAddress->npi : %d.", pAddress->npi);
74 length = convertDigitToBcd(temp, strlen(temp), (unsigned char *) &(tempParam[offset]));
84 int SmsPluginParamCodec::encodeTime(const SMS_TIMESTAMP_S *pTimeStamp, char **ppParam)
88 if (pTimeStamp->format == SMS_TIME_ABSOLUTE) {
89 int timeZone = pTimeStamp->time.absolute.timeZone;
90 *ppParam = new char[MAX_ABS_TIME_PARAM_LEN];
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);
101 (*ppParam)[offset] = 0x08;
103 (*ppParam)[offset++] += ((pTimeStamp->time.absolute.timeZone % 10) << 4) + (pTimeStamp->time.absolute.timeZone / 10);
107 } else if (pTimeStamp->format == SMS_TIME_RELATIVE) {
108 *ppParam = new char[MAX_REL_TIME_PARAM_LEN+1];
110 memcpy(*ppParam, &(pTimeStamp->time.relative.time), MAX_REL_TIME_PARAM_LEN);
112 return MAX_REL_TIME_PARAM_LEN;
119 int SmsPluginParamCodec::encodeDCS(const SMS_DCS_S *pDCS, char **ppParam)
121 *ppParam = new char[MAX_DCS_PARAM_LEN];
125 switch (pDCS->codingGroup) {
126 case SMS_GROUP_GENERAL: {
127 if (pDCS->msgClass != SMS_MSG_CLASS_NONE)
128 **ppParam = 0x10 + pDCS->msgClass;
130 if (pDCS->bCompressed)
135 case SMS_GROUP_CODING_CLASS: {
136 **ppParam = 0xF0 + pDCS->msgClass;
140 case SMS_GROUP_DELETION:
144 case SMS_GROUP_DISCARD:
148 case SMS_GROUP_STORE:
156 switch (pDCS->codingScheme) {
157 case SMS_CHARSET_7BIT:
161 case SMS_CHARSET_8BIT:
165 case SMS_CHARSET_UCS2:
173 return MAX_DCS_PARAM_LEN;
177 int SmsPluginParamCodec::encodeSMSC(const char *pAddress, unsigned char *pEncodeAddr)
179 char newAddr[MAX_SMSC_LEN+1];
180 memset(newAddr, 0x00, sizeof(newAddr));
182 /* MSG_DEBUG("SMSC [%s]", pAddress);
184 if (pAddress[0] == '+')
185 strncpy(newAddr, pAddress+1, MAX_SMSC_LEN);
187 strncpy(newAddr, pAddress, MAX_SMSC_LEN);
190 int encodeLen = convertDigitToBcd(newAddr, strlen(newAddr), pEncodeAddr);
192 pEncodeAddr[encodeLen] = '\0';
198 int SmsPluginParamCodec::encodeSMSC(const SMS_ADDRESS_S *pAddress, unsigned char *pSMSC)
200 char newAddr[MAX_SMSC_LEN+1];
201 memset(newAddr, 0x00, sizeof(newAddr));
203 int dataSize = 0, addrLen = 0;
205 if (pAddress->address[0] == '+')
206 memcpy(newAddr, pAddress->address+1, strlen(pAddress->address)-1);
208 memcpy(newAddr, pAddress->address, strlen(pAddress->address));
210 addrLen = strlen(newAddr);
212 if (addrLen % 2 == 0)
213 dataSize = 2 + (addrLen/2);
215 dataSize = 2 + (addrLen/2) + 1;
217 if (dataSize > MAX_SMSC_LEN) {
218 MSG_DEBUG("addrLen is too long [%d]", addrLen);
219 MSG_DEBUG("dataSize is too long [%d]", dataSize);
224 /* Set Address Length
225 Check IPC 4.0 -> addrLen/2 */
229 pSMSC[1] = 0x80 + (pAddress->ton << 4) + pAddress->npi;
232 convertDigitToBcd(newAddr, addrLen, &(pSMSC[2]));
234 pSMSC[dataSize] = '\0';
240 /*==================================================================================================
242 ==================================================================================================*/
243 int SmsPluginParamCodec::decodeAddress(const unsigned char *pTpdu, SMS_ADDRESS_S *pAddress)
245 int offset = 0, addrLen = 0, bcdLen = 0;
246 MsgTextConvert *textCvt = MsgTextConvert::instance();
247 memset(pAddress->address, 0x00, sizeof(pAddress->address));
249 addrLen = (int)pTpdu[offset++];
251 if (addrLen % 2 == 0)
254 bcdLen = addrLen/2 + 1;
256 pAddress->ton = (pTpdu[offset] & 0x70) >> 4;
257 pAddress->npi = pTpdu[offset++] & 0x0F;
259 MSG_DEBUG("ton [%d]", pAddress->ton);
260 MSG_DEBUG("npi [%d]", pAddress->npi);
262 if (pAddress->ton == SMS_TON_ALPHANUMERIC) {
263 MSG_DEBUG("Alphanumeric address");
265 char* tmpAddress = new char[MAX_ADDRESS_LEN];
268 tmplength = SmsPluginUDCodec::unpack7bitChar(&(pTpdu[offset]), (addrLen*4)/7, 0, tmpAddress);
270 MSG_LANG_INFO_S langInfo = {0, };
272 langInfo.bSingleShift = false;
273 langInfo.bLockingShift = false;
275 textCvt->convertGSM7bitToUTF8((unsigned char*)pAddress->address, MAX_ADDRESS_LEN, (unsigned char*)tmpAddress, tmplength, &langInfo);
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] = '+';
284 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[0]));
289 /* MSG_DEBUG("address [%s]", pAddress->address);
295 int SmsPluginParamCodec::decodeTime(const unsigned char *pTpdu, SMS_TIMESTAMP_S *pTimeStamp)
299 /* decode in ABSOLUTE time type. */
300 pTimeStamp->format = SMS_TIME_ABSOLUTE;
302 pTimeStamp->time.absolute.year = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
305 pTimeStamp->time.absolute.month = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
308 pTimeStamp->time.absolute.day = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
311 pTimeStamp->time.absolute.hour = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
314 pTimeStamp->time.absolute.minute = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
317 pTimeStamp->time.absolute.second = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
320 pTimeStamp->time.absolute.timeZone = (pTpdu[offset] & 0x07)*10 + ((pTpdu[offset] & 0xF0) >> 4);
322 if (pTpdu[offset] & 0x08)
323 pTimeStamp->time.absolute.timeZone *= (-1);
331 int SmsPluginParamCodec::decodeDCS(const unsigned char *pTpdu, SMS_DCS_S *pDCS)
334 char dcs = pTpdu[offset++];
337 pDCS->bIndActive = false;
338 pDCS->indType = SMS_OTHER_INDICATOR;
340 if (((dcs & 0xC0) >> 6) == 0) {
341 pDCS->codingGroup = SMS_GROUP_GENERAL;
342 pDCS->bCompressed = (dcs & 0x20) >> 5;
343 pDCS->codingScheme = (dcs & 0x0C) >> 2;
345 if (((dcs & 0x10) >> 4) == 0)
346 pDCS->msgClass = SMS_MSG_CLASS_NONE;
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;
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;
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;
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;
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;
385 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
386 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
388 pDCS->codingGroup = SMS_GROUP_UNKNOWN;
390 pDCS->bCompressed = (dcs & 0x20) >> 5;
391 pDCS->codingScheme = (dcs & 0x0C) >> 2;
393 pDCS->msgClass = SMS_MSG_CLASS_NONE;
400 void SmsPluginParamCodec::decodeSMSC(unsigned char* pAddress, int AddrLen, MSG_SMS_TON_T ton, char *pDecodeAddr)
402 if (pAddress == NULL || AddrLen == 0)
405 if (ton == SMS_TON_INTERNATIONAL) {
406 pDecodeAddr[0] = '+';
407 convertBcdToDigit(pAddress, AddrLen, &(pDecodeAddr[1]));
409 convertBcdToDigit(pAddress, AddrLen, pDecodeAddr);
414 /*==================================================================================================
416 ==================================================================================================*/
417 int SmsPluginParamCodec::convertDigitToBcd(char *pDigit, int DigitLen, unsigned char *pBcd)
422 /* MSG_DEBUG("DigitLen [%d]", DigitLen);
423 MSG_DEBUG("pDigit [%s]", pDigit); */
425 for (int i = 0; i < DigitLen; i++) {
426 if (pDigit[i] == '*')
428 else if (pDigit[i] == '#')
430 else if (pDigit[i] == 'P' || pDigit[i] == 'p')
433 temp = pDigit[i] - '0';
436 pBcd[offset] = temp & 0x0F;
438 pBcd[offset++] |= ((temp & 0x0F) << 4);
441 if ((DigitLen%2) == 1)
442 pBcd[offset++] |= 0xF0;
448 int SmsPluginParamCodec::convertBcdToDigit(const unsigned char *pBcd, int BcdLen, char *pDigit)
453 for (int i = 0; i < BcdLen; i++) {
454 temp = pBcd[i] & 0x0F;
457 pDigit[offset++] = '*';
458 else if (temp == 0x0B)
459 pDigit[offset++] = '#';
460 else if (temp == 0x0C)
461 pDigit[offset++] = 'P';
463 pDigit[offset++] = temp + '0';
465 temp = (pBcd[i] & 0xF0) >> 4;
468 pDigit[offset] = '\0';
473 pDigit[offset++] = '*';
474 else if (temp == 0x0B)
475 pDigit[offset++] = '#';
476 else if (temp == 0x0C)
477 pDigit[offset++] = 'P';
479 pDigit[offset++] = temp + '0';
482 pDigit[offset] = '\0';
487 bool SmsPluginParamCodec::checkCphsVmiMsg(const unsigned char *pTpdu, int *setType, int *indType)
494 addrLen = (int)pTpdu[offset++];
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 */
501 *indType = (int)(pTpdu[offset+1] & 0x01); /* 0 : indicator 1, 1 : indicator 2 */
510 time_t SmsPluginParamCodec::convertTime(const SMS_TIMESTAMP_S *time_stamp)
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);
523 char displayTime[32];
525 memset(&timeTM, 0x00, sizeof(tm));
528 memset(&timeinfo, 0x00, sizeof(tm));
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;
538 rawtime = mktime(&timeinfo);
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);
545 memset(displayTime, 0x00, sizeof(displayTime));
546 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", &timeinfo);
547 MSG_DEBUG("displayTime [%s]", displayTime);
549 rawtime -= (time_stamp->time.absolute.timeZone * (3600/4));
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);
556 /* timezone value is tiemzone + daylight. So should not add daylight */
557 #ifdef __MSG_DAYLIGHT_APPLIED__
558 rawtime -= (timezone - daylight*3600);
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);
569 rawtime = time(NULL);