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 *ppParam = new char[MAX_ADD_PARAM_LEN];
51 /* Set Address Length */
53 (*ppParam)[offset++] = strlen(temp) - 1;
56 ton = SMS_TON_INTERNATIONAL;
58 (*ppParam)[offset++] = strlen(temp);
64 (*ppParam)[offset++] = 0x80 + (ton << 4) + pAddress->npi;
66 MSG_DEBUG("Address length is %d.", (*ppParam)[0]);
67 MSG_DEBUG("pAddress->ton : %d.", ton);
68 MSG_DEBUG("pAddress->npi : %d.", pAddress->npi);
70 length = convertDigitToBcd(temp, strlen(temp), (unsigned char *) &((*ppParam)[offset]));
78 int SmsPluginParamCodec::encodeTime(const SMS_TIMESTAMP_S *pTimeStamp, char **ppParam)
82 if (pTimeStamp->format == SMS_TIME_ABSOLUTE) {
83 int timeZone = pTimeStamp->time.absolute.timeZone;
84 *ppParam = new char[MAX_ABS_TIME_PARAM_LEN];
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);
95 (*ppParam)[offset] = 0x08;
97 (*ppParam)[offset++] += ((pTimeStamp->time.absolute.timeZone % 10) << 4) + (pTimeStamp->time.absolute.timeZone / 10);
101 } else if (pTimeStamp->format == SMS_TIME_RELATIVE) {
102 *ppParam = new char[MAX_REL_TIME_PARAM_LEN+1];
104 memcpy(*ppParam, &(pTimeStamp->time.relative.time), MAX_REL_TIME_PARAM_LEN);
106 return MAX_REL_TIME_PARAM_LEN;
113 int SmsPluginParamCodec::encodeDCS(const SMS_DCS_S *pDCS, char **ppParam)
119 switch (pDCS->codingGroup) {
120 case SMS_GROUP_GENERAL: {
121 if (pDCS->msgClass != SMS_MSG_CLASS_NONE)
122 **ppParam = 0x10 + pDCS->msgClass;
124 if (pDCS->bCompressed)
129 case SMS_GROUP_CODING_CLASS: {
130 **ppParam = 0xF0 + pDCS->msgClass;
134 case SMS_GROUP_DELETION:
138 case SMS_GROUP_DISCARD:
142 case SMS_GROUP_STORE:
150 switch (pDCS->codingScheme) {
151 case SMS_CHARSET_7BIT:
155 case SMS_CHARSET_8BIT:
159 case SMS_CHARSET_UCS2:
171 int SmsPluginParamCodec::encodeSMSC(const char *pAddress, unsigned char *pEncodeAddr)
173 char newAddr[MAX_SMSC_LEN+1];
174 memset(newAddr, 0x00, sizeof(newAddr));
176 /* MSG_DEBUG("SMSC [%s]", pAddress);
178 if (pAddress[0] == '+')
179 strncpy(newAddr, pAddress+1, MAX_SMSC_LEN);
181 strncpy(newAddr, pAddress, MAX_SMSC_LEN);
184 int encodeLen = convertDigitToBcd(newAddr, strlen(newAddr), pEncodeAddr);
186 pEncodeAddr[encodeLen] = '\0';
192 int SmsPluginParamCodec::encodeSMSC(const SMS_ADDRESS_S *pAddress, unsigned char *pSMSC)
194 char newAddr[MAX_SMSC_LEN+1];
195 memset(newAddr, 0x00, sizeof(newAddr));
197 int dataSize = 0, addrLen = 0;
199 if (pAddress->address[0] == '+')
200 memcpy(newAddr, pAddress->address+1, strlen(pAddress->address)-1);
202 memcpy(newAddr, pAddress->address, strlen(pAddress->address));
204 addrLen = strlen(newAddr);
206 if (addrLen % 2 == 0)
207 dataSize = 2 + (addrLen/2);
209 dataSize = 2 + (addrLen/2) + 1;
211 if (dataSize > MAX_SMSC_LEN) {
212 MSG_DEBUG("addrLen is too long [%d]", addrLen);
213 MSG_DEBUG("dataSize is too long [%d]", dataSize);
218 /* Set Address Length
219 Check IPC 4.0 -> addrLen/2 */
223 pSMSC[1] = 0x80 + (pAddress->ton << 4) + pAddress->npi;
226 convertDigitToBcd(newAddr, addrLen, &(pSMSC[2]));
228 pSMSC[dataSize] = '\0';
234 /*==================================================================================================
236 ==================================================================================================*/
237 int SmsPluginParamCodec::decodeAddress(const unsigned char *pTpdu, SMS_ADDRESS_S *pAddress)
239 int offset = 0, addrLen = 0, bcdLen = 0;
240 MsgTextConvert *textCvt = MsgTextConvert::instance();
241 memset(pAddress->address, 0x00, sizeof(pAddress->address));
243 addrLen = (int)pTpdu[offset++];
245 if (addrLen % 2 == 0)
248 bcdLen = addrLen/2 + 1;
250 pAddress->ton = (pTpdu[offset] & 0x70) >> 4;
251 pAddress->npi = pTpdu[offset++] & 0x0F;
253 MSG_DEBUG("ton [%d]", pAddress->ton);
254 MSG_DEBUG("npi [%d]", pAddress->npi);
256 if (pAddress->ton == SMS_TON_ALPHANUMERIC) {
257 MSG_DEBUG("Alphanumeric address");
259 char* tmpAddress = new char[MAX_ADDRESS_LEN];
262 tmplength = SmsPluginUDCodec::unpack7bitChar(&(pTpdu[offset]), (addrLen*4)/7, 0, tmpAddress);
264 MSG_LANG_INFO_S langInfo = {0, };
266 langInfo.bSingleShift = false;
267 langInfo.bLockingShift = false;
269 textCvt->convertGSM7bitToUTF8((unsigned char*)pAddress->address, MAX_ADDRESS_LEN, (unsigned char*)tmpAddress, tmplength, &langInfo);
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] = '+';
278 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[0]));
283 /* MSG_DEBUG("address [%s]", pAddress->address);
289 int SmsPluginParamCodec::decodeTime(const unsigned char *pTpdu, SMS_TIMESTAMP_S *pTimeStamp)
293 /* decode in ABSOLUTE time type. */
294 pTimeStamp->format = SMS_TIME_ABSOLUTE;
296 pTimeStamp->time.absolute.year = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
299 pTimeStamp->time.absolute.month = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
302 pTimeStamp->time.absolute.day = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
305 pTimeStamp->time.absolute.hour = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
308 pTimeStamp->time.absolute.minute = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
311 pTimeStamp->time.absolute.second = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
314 pTimeStamp->time.absolute.timeZone = (pTpdu[offset] & 0x07)*10 + ((pTpdu[offset] & 0xF0) >> 4);
316 if (pTpdu[offset] & 0x08)
317 pTimeStamp->time.absolute.timeZone *= (-1);
325 int SmsPluginParamCodec::decodeDCS(const unsigned char *pTpdu, SMS_DCS_S *pDCS)
328 char dcs = pTpdu[offset++];
331 pDCS->bIndActive = false;
332 pDCS->indType = SMS_OTHER_INDICATOR;
334 if (((dcs & 0xC0) >> 6) == 0) {
335 pDCS->codingGroup = SMS_GROUP_GENERAL;
336 pDCS->bCompressed = (dcs & 0x20) >> 5;
337 pDCS->codingScheme = (dcs & 0x0C) >> 2;
339 if (((dcs & 0x10) >> 4) == 0)
340 pDCS->msgClass = SMS_MSG_CLASS_NONE;
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;
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;
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;
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;
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;
379 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
380 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
382 pDCS->codingGroup = SMS_GROUP_UNKNOWN;
384 pDCS->bCompressed = (dcs & 0x20) >> 5;
385 pDCS->codingScheme = (dcs & 0x0C) >> 2;
387 pDCS->msgClass = SMS_MSG_CLASS_NONE;
394 void SmsPluginParamCodec::decodeSMSC(unsigned char* pAddress, int AddrLen, MSG_SMS_TON_T ton, char *pDecodeAddr)
396 if (pAddress == NULL || AddrLen == 0)
399 if (ton == SMS_TON_INTERNATIONAL) {
400 pDecodeAddr[0] = '+';
401 convertBcdToDigit(pAddress, AddrLen, &(pDecodeAddr[1]));
403 convertBcdToDigit(pAddress, AddrLen, pDecodeAddr);
408 /*==================================================================================================
410 ==================================================================================================*/
411 int SmsPluginParamCodec::convertDigitToBcd(char *pDigit, int DigitLen, unsigned char *pBcd)
416 /* MSG_DEBUG("DigitLen [%d]", DigitLen);
417 MSG_DEBUG("pDigit [%s]", pDigit); */
419 for (int i = 0; i < DigitLen; i++) {
420 if (pDigit[i] == '*')
422 else if (pDigit[i] == '#')
424 else if (pDigit[i] == 'P' || pDigit[i] == 'p')
427 temp = pDigit[i] - '0';
430 pBcd[offset] = temp & 0x0F;
432 pBcd[offset++] |= ((temp & 0x0F) << 4);
435 if ((DigitLen%2) == 1)
436 pBcd[offset++] |= 0xF0;
442 int SmsPluginParamCodec::convertBcdToDigit(const unsigned char *pBcd, int BcdLen, char *pDigit)
447 for (int i = 0; i < BcdLen; i++) {
448 temp = pBcd[i] & 0x0F;
451 pDigit[offset++] = '*';
452 else if (temp == 0x0B)
453 pDigit[offset++] = '#';
454 else if (temp == 0x0C)
455 pDigit[offset++] = 'P';
457 pDigit[offset++] = temp + '0';
459 temp = (pBcd[i] & 0xF0) >> 4;
462 pDigit[offset] = '\0';
467 pDigit[offset++] = '*';
468 else if (temp == 0x0B)
469 pDigit[offset++] = '#';
470 else if (temp == 0x0C)
471 pDigit[offset++] = 'P';
473 pDigit[offset++] = temp + '0';
476 pDigit[offset] = '\0';
481 bool SmsPluginParamCodec::checkCphsVmiMsg(const unsigned char *pTpdu, int *setType, int *indType)
488 addrLen = (int)pTpdu[offset++];
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 */
495 *indType = (int)(pTpdu[offset+1] & 0x01); /* 0 : indicator 1, 1 : indicator 2 */
504 time_t SmsPluginParamCodec::convertTime(const SMS_TIMESTAMP_S *time_stamp)
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);
517 char displayTime[32];
521 memset(&timeinfo, 0x00, sizeof(tm));
523 timeinfo.tm_year = (time_stamp->time.absolute.year + 100);
524 timeinfo.tm_mon = (time_stamp->time.absolute.month - 1);
525 timeinfo.tm_mday = time_stamp->time.absolute.day;
526 timeinfo.tm_hour = time_stamp->time.absolute.hour;
527 timeinfo.tm_min = time_stamp->time.absolute.minute;
528 timeinfo.tm_sec = time_stamp->time.absolute.second;
529 timeinfo.tm_isdst = 0;
531 rawtime = mktime(&timeinfo);
533 MSG_DEBUG("tzname[0] [%s]", tzname[0]);
534 MSG_DEBUG("tzname[1] [%s]", tzname[1]);
535 MSG_DEBUG("timezone [%d]", timezone);
536 MSG_DEBUG("daylight [%d]", daylight);
538 memset(displayTime, 0x00, sizeof(displayTime));
539 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", &timeinfo);
540 MSG_DEBUG("displayTime [%s]", displayTime);
542 rawtime -= (time_stamp->time.absolute.timeZone * (3600/4));
544 timeTM = localtime(&rawtime);
545 memset(displayTime, 0x00, sizeof(displayTime));
546 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", timeTM);
547 MSG_DEBUG("displayTime [%s]", displayTime);
549 /* timezone value is tiemzone + daylight. So should not add daylight */
550 #ifdef __MSG_DAYLIGHT_APPLIED__
551 rawtime -= (timezone - daylight*3600);
556 timeTM = localtime(&rawtime);
557 memset(displayTime, 0x00, sizeof(displayTime));
558 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", timeTM);
559 MSG_DEBUG("displayTime [%s]", displayTime);
561 rawtime = time(NULL);