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()
36 SmsPluginParamCodec::~SmsPluginParamCodec()
43 /*==================================================================================================
45 ==================================================================================================*/
46 int SmsPluginParamCodec::encodeAddress(const SMS_ADDRESS_S *pAddress, char **ppParam)
48 int offset = 0, length = 0;
49 char *temp = (char *)pAddress->address;
53 *ppParam = new char[MAX_ADD_PARAM_LEN];
58 (*ppParam)[offset++] = strlen(temp) - 1;
61 ton = SMS_TON_INTERNATIONAL;
65 (*ppParam)[offset++] = strlen(temp);
71 (*ppParam)[offset++] = 0x80 + (ton << 4) + pAddress->npi;
73 MSG_DEBUG("Address length is %d.", (*ppParam)[0]);
74 MSG_DEBUG("pAddress->ton : %d.", ton);
75 MSG_DEBUG("pAddress->npi : %d.", pAddress->npi);
77 length = convertDigitToBcd(temp, strlen(temp), (unsigned char *) &((*ppParam)[offset]));
85 int SmsPluginParamCodec::encodeTime(const SMS_TIMESTAMP_S *pTimeStamp, char **ppParam)
89 if(pTimeStamp->format == SMS_TIME_ABSOLUTE)
91 int timeZone = pTimeStamp->time.absolute.timeZone;
92 *ppParam = new char[MAX_ABS_TIME_PARAM_LEN];
94 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.year % 10) << 4) + (pTimeStamp->time.absolute.year / 10);
95 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.month % 10) << 4) + (pTimeStamp->time.absolute.month / 10);
96 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.day % 10) << 4) + (pTimeStamp->time.absolute.day / 10);
97 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.hour % 10) << 4) + (pTimeStamp->time.absolute.hour / 10);
98 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.minute % 10) << 4) + (pTimeStamp->time.absolute.minute / 10);
99 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.second % 10) << 4) + (pTimeStamp->time.absolute.second / 10);
104 (*ppParam)[offset] = 0x08;
106 (*ppParam)[offset++] += ((pTimeStamp->time.absolute.timeZone % 10) << 4) + (pTimeStamp->time.absolute.timeZone / 10);
111 else if(pTimeStamp->format == SMS_TIME_RELATIVE)
113 *ppParam = new char[MAX_REL_TIME_PARAM_LEN+1];
115 memcpy(*ppParam, &(pTimeStamp->time.relative.time), MAX_REL_TIME_PARAM_LEN);
117 return MAX_REL_TIME_PARAM_LEN;
124 int SmsPluginParamCodec::encodeDCS(const SMS_DCS_S *pDCS, char **ppParam)
130 switch (pDCS->codingGroup)
132 case SMS_GROUP_GENERAL:
134 if (pDCS->msgClass != SMS_MSG_CLASS_NONE)
136 **ppParam = 0x10 + pDCS->msgClass;
139 if (pDCS->bCompressed)
146 case SMS_GROUP_CODING_CLASS:
148 **ppParam = 0xF0 + pDCS->msgClass;
152 case SMS_GROUP_DELETION:
156 case SMS_GROUP_DISCARD:
160 case SMS_GROUP_STORE:
168 switch (pDCS->codingScheme)
170 case SMS_CHARSET_7BIT:
174 case SMS_CHARSET_8BIT:
178 case SMS_CHARSET_UCS2:
190 int SmsPluginParamCodec::encodeSMSC(const char *pAddress, unsigned char *pEncodeAddr)
192 char newAddr[MAX_SMSC_LEN+1];
193 memset(newAddr, 0x00, sizeof(newAddr));
195 //MSG_DEBUG("SMSC [%s]", pAddress);
197 if (pAddress[0] == '+')
199 strncpy(newAddr, pAddress+1, MAX_SMSC_LEN);
203 strncpy(newAddr, pAddress, MAX_SMSC_LEN);
207 int encodeLen = convertDigitToBcd(newAddr, strlen(newAddr), pEncodeAddr);
209 pEncodeAddr[encodeLen] = '\0';
215 int SmsPluginParamCodec::encodeSMSC(const SMS_ADDRESS_S *pAddress, unsigned char *pSMSC)
217 char newAddr[MAX_SMSC_LEN+1];
218 memset(newAddr, 0x00, sizeof(newAddr));
220 int dataSize = 0, addrLen = 0;
222 if (pAddress->address[0] == '+')
223 memcpy(newAddr, pAddress->address+1, strlen(pAddress->address)-1);
225 memcpy(newAddr, pAddress->address, strlen(pAddress->address));
227 addrLen = strlen(newAddr);
229 if (addrLen % 2 == 0)
230 dataSize = 2 + (addrLen/2);
232 dataSize = 2 + (addrLen/2) + 1;
234 if (dataSize > MAX_SMSC_LEN)
236 MSG_DEBUG("addrLen is too long [%d]", addrLen);
237 MSG_DEBUG("dataSize is too long [%d]", dataSize);
242 // Set Address Length
243 // Check IPC 4.0 -> addrLen/2
247 pSMSC[1] = 0x80 + (pAddress->ton << 4) + pAddress->npi;
250 convertDigitToBcd(newAddr, addrLen, &(pSMSC[2]));
252 pSMSC[dataSize] = '\0';
258 /*==================================================================================================
260 ==================================================================================================*/
261 int SmsPluginParamCodec::decodeAddress(const unsigned char *pTpdu, SMS_ADDRESS_S *pAddress)
263 int offset = 0, addrLen = 0, bcdLen = 0;
264 MsgTextConvert *textCvt = MsgTextConvert::instance();
265 memset(pAddress->address, 0x00, sizeof(pAddress->address));
267 addrLen = (int)pTpdu[offset++];
269 if (addrLen % 2 == 0)
272 bcdLen = addrLen/2 + 1;
274 pAddress->ton = (pTpdu[offset] & 0x70) >> 4;
275 pAddress->npi = pTpdu[offset++] & 0x0F;
277 MSG_DEBUG("ton [%d]", pAddress->ton);
278 MSG_DEBUG("npi [%d]", pAddress->npi);
280 if (pAddress->ton == SMS_TON_ALPHANUMERIC)
282 MSG_DEBUG("Alphanumeric address");
284 char* tmpAddress = new char[MAX_ADDRESS_LEN];
287 tmplength = SmsPluginUDCodec::unpack7bitChar(&(pTpdu[offset]), (addrLen*4 )/7, 0, tmpAddress);
289 MSG_LANG_INFO_S langInfo = {0,};
291 langInfo.bSingleShift = false;
292 langInfo.bLockingShift = false;
294 textCvt->convertGSM7bitToUTF8((unsigned char*)pAddress->address, MAX_ADDRESS_LEN, (unsigned char*)tmpAddress, tmplength, &langInfo);
299 else if (pAddress->ton == SMS_TON_INTERNATIONAL)
301 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[1]));
302 if (pAddress->address[1] != '\0')
303 pAddress->address[0] = '+';
307 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[0]));
312 //MSG_DEBUG("address [%s]", pAddress->address);
318 int SmsPluginParamCodec::decodeTime(const unsigned char *pTpdu, SMS_TIMESTAMP_S *pTimeStamp)
322 // decode in ABSOLUTE time type.
323 pTimeStamp->format = SMS_TIME_ABSOLUTE;
325 pTimeStamp->time.absolute.year = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
328 pTimeStamp->time.absolute.month = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
331 pTimeStamp->time.absolute.day = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
334 pTimeStamp->time.absolute.hour = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
337 pTimeStamp->time.absolute.minute = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
340 pTimeStamp->time.absolute.second = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
343 pTimeStamp->time.absolute.timeZone = (pTpdu[offset] & 0x07)*10 + ((pTpdu[offset] & 0xF0) >> 4);
345 if (pTpdu[offset] & 0x08)
346 pTimeStamp->time.absolute.timeZone *= (-1);
354 int SmsPluginParamCodec::decodeDCS(const unsigned char *pTpdu, SMS_DCS_S *pDCS)
357 char dcs = pTpdu[offset++];
360 pDCS->bIndActive = false;
361 pDCS->indType = SMS_OTHER_INDICATOR;
363 if (((dcs & 0xC0) >> 6) == 0)
365 pDCS->codingGroup = SMS_GROUP_GENERAL;
366 pDCS->bCompressed = (dcs & 0x20) >> 5;
367 pDCS->codingScheme = (dcs & 0x0C) >> 2;
369 if (((dcs & 0x10) >> 4) == 0)
370 pDCS->msgClass = SMS_MSG_CLASS_NONE;
372 pDCS->msgClass = dcs & 0x03;
374 else if (((dcs & 0xF0) >> 4) == 0x0F)
376 pDCS->codingGroup = SMS_GROUP_CODING_CLASS;
377 pDCS->bCompressed = false;
378 pDCS->codingScheme = (dcs & 0x0C) >> 2;
380 pDCS->msgClass = dcs & 0x03;
382 else if (((dcs & 0xC0) >> 6) == 1)
384 pDCS->codingGroup = SMS_GROUP_DELETION;
385 pDCS->bCompressed = false;
386 pDCS->msgClass = SMS_MSG_CLASS_NONE;
388 // TODO: finish here. ??
390 else if (((dcs & 0xF0) >> 4) == 0x0C)
392 pDCS->codingGroup = SMS_GROUP_DISCARD;
393 pDCS->bCompressed = false;
394 pDCS->msgClass = SMS_MSG_CLASS_NONE;
397 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
398 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
400 else if (((dcs & 0xF0) >> 4) == 0x0D)
402 pDCS->codingGroup = SMS_GROUP_STORE;
403 pDCS->codingScheme = SMS_CHARSET_7BIT;
404 pDCS->bCompressed = false;
405 pDCS->msgClass = SMS_MSG_CLASS_NONE;
408 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
409 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
411 else if (((dcs & 0xF0) >> 4) == 0x0E)
413 pDCS->codingGroup = SMS_GROUP_STORE;
414 pDCS->codingScheme = SMS_CHARSET_UCS2;
415 pDCS->bCompressed = false;
416 pDCS->msgClass = SMS_MSG_CLASS_NONE;
419 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
420 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
424 pDCS->codingGroup = SMS_GROUP_UNKNOWN;
426 pDCS->bCompressed = (dcs & 0x20) >> 5;
427 pDCS->codingScheme = (dcs & 0x0C) >> 2;
429 pDCS->msgClass = SMS_MSG_CLASS_NONE;
436 void SmsPluginParamCodec::decodeSMSC(unsigned char* pAddress, int AddrLen, MSG_SMS_TON_T ton, char *pDecodeAddr)
438 if (pAddress == NULL || AddrLen == 0)
441 if (ton == SMS_TON_INTERNATIONAL)
443 pDecodeAddr[0] = '+';
444 convertBcdToDigit(pAddress, AddrLen, &(pDecodeAddr[1]));
448 convertBcdToDigit(pAddress, AddrLen, pDecodeAddr);
453 /*==================================================================================================
455 ==================================================================================================*/
456 int SmsPluginParamCodec::convertDigitToBcd(char *pDigit, int DigitLen, unsigned char *pBcd)
461 //MSG_DEBUG("DigitLen [%d]", DigitLen);
462 //MSG_DEBUG("pDigit [%s]", pDigit);
464 for (int i = 0; i < DigitLen; i++)
466 if (pDigit[i] == '*')
468 else if (pDigit[i] == '#')
470 else if (pDigit[i] == 'P' || pDigit[i] == 'p')
473 temp = pDigit[i] - '0';
476 pBcd[offset] = temp & 0x0F;
478 pBcd[offset++] |= ((temp & 0x0F) << 4);
481 if ((DigitLen%2) == 1)
483 pBcd[offset++] |= 0xF0;
490 int SmsPluginParamCodec::convertBcdToDigit(const unsigned char *pBcd, int BcdLen, char *pDigit)
495 for (int i = 0; i < BcdLen; i++)
497 temp = pBcd[i] & 0x0F;
500 pDigit[offset++] = '*';
501 else if (temp == 0x0B)
502 pDigit[offset++] = '#';
503 else if (temp == 0x0C)
504 pDigit[offset++] = 'P';
506 pDigit[offset++] = temp + '0';
508 temp = (pBcd[i] & 0xF0) >> 4;
512 pDigit[offset] = '\0';
517 pDigit[offset++] = '*';
518 else if (temp == 0x0B)
519 pDigit[offset++] = '#';
520 else if (temp == 0x0C)
521 pDigit[offset++] = 'P';
523 pDigit[offset++] = temp + '0';
526 pDigit[offset] = '\0';
531 bool SmsPluginParamCodec::checkCphsVmiMsg(const unsigned char *pTpdu, int *setType, int *indType)
538 addrLen = (int)pTpdu[offset++];
540 if (addrLen == 0x04 && pTpdu[offset++] == 0xD0) {
541 if (pTpdu[offset] == 0x11 || pTpdu[offset] == 0x10) {
542 MSG_DEBUG("####### VMI msg ######");
543 *setType = (int)(pTpdu[offset] & 0x01); // 0 : clear, 1 : set
545 *indType = (int)(pTpdu[offset+1] & 0x01); // 0 : indicator 1, 1 : indicator 2