4 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
24 #include "MsgTextConvert.h"
25 #include "SmsPluginUDCodec.h"
26 #include "SmsPluginParamCodec.h"
29 /*==================================================================================================
30 IMPLEMENTATION OF SmsPluginParamCodec - Member Functions
31 ==================================================================================================*/
32 SmsPluginParamCodec::SmsPluginParamCodec()
39 SmsPluginParamCodec::~SmsPluginParamCodec()
46 /*==================================================================================================
48 ==================================================================================================*/
49 int SmsPluginParamCodec::encodeAddress(const SMS_ADDRESS_S *pAddress, char **ppParam)
51 int offset = 0, length = 0;
52 char *temp = (char *)pAddress->address;
56 *ppParam = new char[MAX_ADD_PARAM_LEN];
61 (*ppParam)[offset++] = strlen(temp) - 1;
64 ton = SMS_TON_INTERNATIONAL;
68 (*ppParam)[offset++] = strlen(temp);
74 (*ppParam)[offset++] = 0x80 + (ton << 4) + pAddress->npi;
76 MSG_DEBUG("Address length is %d.", (*ppParam)[0]);
77 MSG_DEBUG("pAddress->ton : %d.", ton);
78 MSG_DEBUG("pAddress->npi : %d.", pAddress->npi);
80 length = convertDigitToBcd(temp, strlen(temp), (unsigned char *) &((*ppParam)[offset]));
88 int SmsPluginParamCodec::encodeTime(const SMS_TIMESTAMP_S *pTimeStamp, char **ppParam)
92 if(pTimeStamp->format == SMS_TIME_ABSOLUTE)
94 int timeZone = pTimeStamp->time.absolute.timeZone;
95 *ppParam = new char[MAX_ABS_TIME_PARAM_LEN];
97 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.year % 10) << 4) + (pTimeStamp->time.absolute.year / 10);
98 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.month % 10) << 4) + (pTimeStamp->time.absolute.month / 10);
99 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.day % 10) << 4) + (pTimeStamp->time.absolute.day / 10);
100 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.hour % 10) << 4) + (pTimeStamp->time.absolute.hour / 10);
101 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.minute % 10) << 4) + (pTimeStamp->time.absolute.minute / 10);
102 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.second % 10) << 4) + (pTimeStamp->time.absolute.second / 10);
107 (*ppParam)[offset] = 0x08;
109 (*ppParam)[offset++] += ((pTimeStamp->time.absolute.timeZone % 10) << 4) + (pTimeStamp->time.absolute.timeZone / 10);
114 else if(pTimeStamp->format == SMS_TIME_RELATIVE)
116 *ppParam = new char[MAX_REL_TIME_PARAM_LEN+1];
118 memcpy(*ppParam, &(pTimeStamp->time.relative.time), MAX_REL_TIME_PARAM_LEN);
120 return MAX_REL_TIME_PARAM_LEN;
127 int SmsPluginParamCodec::encodeDCS(const SMS_DCS_S *pDCS, char **ppParam)
133 switch (pDCS->codingGroup)
135 case SMS_GROUP_GENERAL:
137 if (pDCS->msgClass != SMS_MSG_CLASS_NONE)
139 **ppParam = 0x10 + pDCS->msgClass;
142 if (pDCS->bCompressed)
149 case SMS_GROUP_CODING_CLASS:
151 **ppParam = 0xF0 + pDCS->msgClass;
155 case SMS_GROUP_DELETION:
159 case SMS_GROUP_DISCARD:
163 case SMS_GROUP_STORE:
171 switch (pDCS->codingScheme)
173 case SMS_CHARSET_7BIT:
177 case SMS_CHARSET_8BIT:
181 case SMS_CHARSET_UCS2:
193 int SmsPluginParamCodec::encodeSMSC(const char *pAddress, unsigned char *pEncodeAddr)
195 char newAddr[MAX_SMSC_LEN+1];
196 memset(newAddr, 0x00, sizeof(newAddr));
198 //MSG_DEBUG("SMSC [%s]", pAddress);
200 if (pAddress[0] == '+')
202 strncpy(newAddr, pAddress+1, MAX_SMSC_LEN);
206 strncpy(newAddr, pAddress, MAX_SMSC_LEN);
210 int encodeLen = convertDigitToBcd(newAddr, strlen(newAddr), pEncodeAddr);
212 pEncodeAddr[encodeLen] = '\0';
218 int SmsPluginParamCodec::encodeSMSC(const SMS_ADDRESS_S *pAddress, unsigned char *pSMSC)
220 char newAddr[MAX_SMSC_LEN+1];
221 memset(newAddr, 0x00, sizeof(newAddr));
223 int dataSize = 0, addrLen = 0;
225 if (pAddress->address[0] == '+')
226 memcpy(newAddr, pAddress->address+1, strlen(pAddress->address)-1);
228 memcpy(newAddr, pAddress->address, strlen(pAddress->address));
230 addrLen = strlen(newAddr);
232 if (addrLen % 2 == 0)
233 dataSize = 2 + (addrLen/2);
235 dataSize = 2 + (addrLen/2) + 1;
237 if (dataSize > MAX_SMSC_LEN)
239 MSG_DEBUG("addrLen is too long [%d]", addrLen);
240 MSG_DEBUG("dataSize is too long [%d]", dataSize);
245 // Set Address Length
246 // Check IPC 4.0 -> addrLen/2
250 pSMSC[1] = 0x80 + (pAddress->ton << 4) + pAddress->npi;
253 convertDigitToBcd(newAddr, addrLen, &(pSMSC[2]));
255 pSMSC[dataSize] = '\0';
261 /*==================================================================================================
263 ==================================================================================================*/
264 int SmsPluginParamCodec::decodeAddress(const unsigned char *pTpdu, SMS_ADDRESS_S *pAddress)
266 int offset = 0, addrLen = 0, bcdLen = 0;
267 MsgTextConvert textCvt;
268 memset(pAddress->address, 0x00, sizeof(pAddress->address));
270 addrLen = (int)pTpdu[offset++];
272 if (addrLen % 2 == 0)
275 bcdLen = addrLen/2 + 1;
277 pAddress->ton = (pTpdu[offset] & 0x70) >> 4;
278 pAddress->npi = pTpdu[offset++] & 0x0F;
280 MSG_DEBUG("ton [%d]", pAddress->ton);
281 MSG_DEBUG("npi [%d]", pAddress->npi);
283 if (pAddress->ton == SMS_TON_ALPHANUMERIC)
285 MSG_DEBUG("Alphanumeric address");
287 char* tmpAddress = new char[MAX_ADDRESS_LEN];
290 tmplength = SmsPluginUDCodec::unpack7bitChar(&(pTpdu[offset]), bcdLen, 0, tmpAddress);
292 MSG_LANG_INFO_S langInfo = {0,};
294 langInfo.bSingleShift = false;
295 langInfo.bLockingShift = false;
297 textCvt.convertGSM7bitToUTF8((unsigned char*)pAddress->address, MAX_ADDRESS_LEN, (unsigned char*)tmpAddress, tmplength, &langInfo);
302 else if (pAddress->ton == SMS_TON_INTERNATIONAL)
304 (pAddress->address)[0] = '+';
305 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[1]));
309 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[0]));
314 //MSG_DEBUG("address [%s]", pAddress->address);
320 int SmsPluginParamCodec::decodeTime(const unsigned char *pTpdu, SMS_TIMESTAMP_S *pTimeStamp)
324 // decode in ABSOLUTE time type.
325 pTimeStamp->format = SMS_TIME_ABSOLUTE;
327 pTimeStamp->time.absolute.year = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
330 pTimeStamp->time.absolute.month = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
333 pTimeStamp->time.absolute.day = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
336 pTimeStamp->time.absolute.hour = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
339 pTimeStamp->time.absolute.minute = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
342 pTimeStamp->time.absolute.second = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
345 pTimeStamp->time.absolute.timeZone = (pTpdu[offset] & 0x07)*10 + ((pTpdu[offset] & 0xF0) >> 4);
347 if (pTpdu[offset] & 0x08)
348 pTimeStamp->time.absolute.timeZone *= (-1);
356 int SmsPluginParamCodec::decodeDCS(const unsigned char *pTpdu, SMS_DCS_S *pDCS)
359 char dcs = pTpdu[offset++];
362 pDCS->bIndActive = false;
363 pDCS->indType = SMS_OTHER_INDICATOR;
365 if (((dcs & 0xC0) >> 6) == 0)
367 pDCS->codingGroup = SMS_GROUP_GENERAL;
368 pDCS->bCompressed = (dcs & 0x20) >> 5;
369 pDCS->codingScheme = (dcs & 0x0C) >> 2;
371 if (((dcs & 0x10) >> 4) == 0)
372 pDCS->msgClass = SMS_MSG_CLASS_NONE;
374 pDCS->msgClass = dcs & 0x03;
376 else if (((dcs & 0xF0) >> 4) == 0x0F)
378 pDCS->codingGroup = SMS_GROUP_CODING_CLASS;
379 pDCS->bCompressed = false;
380 pDCS->codingScheme = (dcs & 0x0C) >> 2;
382 pDCS->msgClass = dcs & 0x03;
384 else if (((dcs & 0xC0) >> 6) == 1)
386 pDCS->codingGroup = SMS_GROUP_DELETION;
387 pDCS->bCompressed = false;
388 pDCS->msgClass = SMS_MSG_CLASS_NONE;
390 // TODO: finish here. ??
392 else if (((dcs & 0xF0) >> 4) == 0x0C)
394 pDCS->codingGroup = SMS_GROUP_DISCARD;
395 pDCS->bCompressed = false;
396 pDCS->msgClass = SMS_MSG_CLASS_NONE;
399 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
400 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
402 else if (((dcs & 0xF0) >> 4) == 0x0D)
404 pDCS->codingGroup = SMS_GROUP_STORE;
405 pDCS->codingScheme = SMS_CHARSET_7BIT;
406 pDCS->bCompressed = false;
407 pDCS->msgClass = SMS_MSG_CLASS_NONE;
410 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
411 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
413 else if (((dcs & 0xF0) >> 4) == 0x0E)
415 pDCS->codingGroup = SMS_GROUP_STORE;
416 pDCS->codingScheme = SMS_CHARSET_UCS2;
417 pDCS->bCompressed = false;
418 pDCS->msgClass = SMS_MSG_CLASS_NONE;
421 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? false:true;
422 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
426 pDCS->codingGroup = SMS_GROUP_UNKNOWN;
428 pDCS->bCompressed = (dcs & 0x20) >> 5;
429 pDCS->codingScheme = (dcs & 0x0C) >> 2;
431 pDCS->msgClass = SMS_MSG_CLASS_NONE;
438 void SmsPluginParamCodec::decodeSMSC(unsigned char* pAddress, int AddrLen, MSG_SMS_TON_T ton, char *pDecodeAddr)
440 if (pAddress == NULL || AddrLen == 0)
443 if (ton == SMS_TON_INTERNATIONAL)
445 pDecodeAddr[0] = '+';
446 convertBcdToDigit(pAddress, AddrLen, &(pDecodeAddr[1]));
450 convertBcdToDigit(pAddress, AddrLen, pDecodeAddr);
455 /*==================================================================================================
457 ==================================================================================================*/
458 int SmsPluginParamCodec::convertDigitToBcd(char *pDigit, int DigitLen, unsigned char *pBcd)
463 //MSG_DEBUG("DigitLen [%d]", DigitLen);
464 //MSG_DEBUG("pDigit [%s]", pDigit);
466 for (int i = 0; i < DigitLen; i++)
468 if (pDigit[i] == '*')
470 else if (pDigit[i] == '#')
472 else if (pDigit[i] == 'P' || pDigit[i] == 'p')
475 temp = pDigit[i] - '0';
478 pBcd[offset] = temp & 0x0F;
480 pBcd[offset++] |= ((temp & 0x0F) << 4);
483 if ((DigitLen%2) == 1)
485 pBcd[offset++] |= 0xF0;
492 int SmsPluginParamCodec::convertBcdToDigit(const unsigned char *pBcd, int BcdLen, char *pDigit)
497 for (int i = 0; i < BcdLen; i++)
499 temp = pBcd[i] & 0x0F;
502 pDigit[offset++] = '*';
503 else if (temp == 0x0B)
504 pDigit[offset++] = '#';
505 else if (temp == 0x0C)
506 pDigit[offset++] = 'P';
508 pDigit[offset++] = temp + '0';
510 temp = (pBcd[i] & 0xF0) >> 4;
514 pDigit[offset] = '\0';
519 pDigit[offset++] = '*';
520 else if (temp == 0x0B)
521 pDigit[offset++] = '#';
522 else if (temp == 0x0C)
523 pDigit[offset++] = 'P';
525 pDigit[offset++] = temp + '0';
528 pDigit[offset] = '\0';