3 * Copyright (c) 2000-2012 Samsung Electronics Co., Ltd. All Rights Reserved.
5 * This file is part of msg-service.
7 * Contact: Jaeyun Jeong <jyjeong@samsung.com>
8 * Sangkoo Kim <sangkoo.kim@samsung.com>
9 * Seunghwan Lee <sh.cat.lee@samsung.com>
10 * SoonMin Jung <sm0415.jung@samsung.com>
11 * Jae-Young Lee <jy4710.lee@samsung.com>
12 * KeeBum Kim <keebum.kim@samsung.com>
14 * PROPRIETARY/CONFIDENTIAL
16 * This software is the confidential and proprietary information of
17 * SAMSUNG ELECTRONICS ("Confidential Information"). You shall not
18 * disclose such Confidential Information and shall use it only in
19 * accordance with the terms of the license agreement you entered
20 * into with SAMSUNG ELECTRONICS.
22 * SAMSUNG make no representations or warranties about the suitability
23 * of the software, either express or implied, including but not limited
24 * to the implied warranties of merchantability, fitness for a particular
25 * purpose, or non-infringement. SAMSUNG shall not be liable for any
26 * damages suffered by licensee as a result of using, modifying or
27 * distributing this software or its derivatives.
35 #include "SmsPluginUDCodec.h"
36 #include "SmsPluginTextConvert.h"
37 #include "SmsPluginParamCodec.h"
40 /*==================================================================================================
41 IMPLEMENTATION OF SmsPluginParamCodec - Member Functions
42 ==================================================================================================*/
43 SmsPluginParamCodec::SmsPluginParamCodec()
50 SmsPluginParamCodec::~SmsPluginParamCodec()
57 /*==================================================================================================
59 ==================================================================================================*/
60 int SmsPluginParamCodec::encodeAddress(const SMS_ADDRESS_S *pAddress, char **ppParam)
62 int offset = 0, length = 0;
63 char *temp = (char *)pAddress->address;
67 *ppParam = new char[MAX_ADD_PARAM_LEN];
72 (*ppParam)[offset++] = strlen(temp) - 1;
75 ton = SMS_TON_INTERNATIONAL;
79 (*ppParam)[offset++] = strlen(temp);
85 (*ppParam)[offset++] = 0x80 + (ton << 4) + pAddress->npi;
87 MSG_DEBUG("Address length is %d.", (*ppParam)[0]);
88 MSG_DEBUG("pAddress->ton : %d.", ton);
89 MSG_DEBUG("pAddress->npi : %d.", pAddress->npi);
91 length = convertDigitToBcd(temp, strlen(temp), (unsigned char *) &((*ppParam)[offset]));
99 int SmsPluginParamCodec::encodeTime(const SMS_TIMESTAMP_S *pTimeStamp, char **ppParam)
103 if(pTimeStamp->format == SMS_TIME_ABSOLUTE)
105 int timeZone = pTimeStamp->time.absolute.timeZone;
106 *ppParam = new char[MAX_ABS_TIME_PARAM_LEN];
108 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.year % 10) << 4) + (pTimeStamp->time.absolute.year / 10);
109 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.month % 10) << 4) + (pTimeStamp->time.absolute.month / 10);
110 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.day % 10) << 4) + (pTimeStamp->time.absolute.day / 10);
111 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.hour % 10) << 4) + (pTimeStamp->time.absolute.hour / 10);
112 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.minute % 10) << 4) + (pTimeStamp->time.absolute.minute / 10);
113 (*ppParam)[offset++] = ((pTimeStamp->time.absolute.second % 10) << 4) + (pTimeStamp->time.absolute.second / 10);
118 (*ppParam)[offset] = 0x08;
120 (*ppParam)[offset++] += ((pTimeStamp->time.absolute.timeZone % 10) << 4) + (pTimeStamp->time.absolute.timeZone / 10);
125 else if(pTimeStamp->format == SMS_TIME_RELATIVE)
127 *ppParam = new char[MAX_REL_TIME_PARAM_LEN+1];
129 memcpy(*ppParam, &(pTimeStamp->time.relative.time), MAX_REL_TIME_PARAM_LEN);
131 return MAX_REL_TIME_PARAM_LEN;
138 int SmsPluginParamCodec::encodeDCS(const SMS_DCS_S *pDCS, char **ppParam)
144 switch (pDCS->codingGroup)
146 case SMS_GROUP_GENERAL:
148 if (pDCS->msgClass != SMS_MSG_CLASS_NONE)
150 **ppParam = 0x10 + pDCS->msgClass;
153 if (pDCS->bCompressed)
160 case SMS_GROUP_CODING_CLASS:
162 **ppParam = 0xF0 + pDCS->msgClass;
166 case SMS_GROUP_DELETION:
170 case SMS_GROUP_DISCARD:
174 case SMS_GROUP_STORE:
182 switch (pDCS->codingScheme)
184 case SMS_CHARSET_7BIT:
188 case SMS_CHARSET_8BIT:
192 case SMS_CHARSET_UCS2:
204 int SmsPluginParamCodec::encodeSMSC(const char *pAddress, unsigned char *pEncodeAddr)
206 char newAddr[MAX_SMSC_LEN+1];
207 memset(newAddr, 0x00, sizeof(newAddr));
209 if (pAddress[0] == '+')
211 strncpy(newAddr, pAddress+1, MAX_SMSC_LEN);
215 strncpy(newAddr, pAddress, MAX_SMSC_LEN);
219 int encodeLen = convertDigitToBcd(newAddr, strlen(newAddr), pEncodeAddr);
221 pEncodeAddr[encodeLen] = '\0';
227 int SmsPluginParamCodec::encodeSMSC(const SMS_ADDRESS_S *pAddress, unsigned char *pSMSC)
229 char newAddr[MAX_SMSC_LEN+1];
230 memset(newAddr, 0x00, sizeof(newAddr));
232 int dataSize = 0, addrLen = 0;
234 if (pAddress->address[0] == '+')
235 memcpy(newAddr, pAddress->address+1, strlen(pAddress->address)-1);
237 memcpy(newAddr, pAddress->address, strlen(pAddress->address));
239 addrLen = strlen(newAddr);
241 if (addrLen % 2 == 0)
242 dataSize = 2 + (addrLen/2);
244 dataSize = 2 + (addrLen/2) + 1;
246 if (dataSize > MAX_SMSC_LEN)
248 MSG_DEBUG("addrLen is too long [%d]", addrLen);
249 MSG_DEBUG("dataSize is too long [%d]", dataSize);
254 // Set Address Length
255 // Check IPC 4.0 -> addrLen/2
259 pSMSC[1] = 0x80 + (pAddress->ton << 4) + pAddress->npi;
262 convertDigitToBcd(newAddr, addrLen, &(pSMSC[2]));
264 pSMSC[dataSize] = '\0';
270 /*==================================================================================================
272 ==================================================================================================*/
273 int SmsPluginParamCodec::decodeAddress(const unsigned char *pTpdu, SMS_ADDRESS_S *pAddress)
275 int offset = 0, addrLen = 0, bcdLen = 0;
276 memset(pAddress->address, 0x00, sizeof(pAddress->address));
278 addrLen = (int)pTpdu[offset++];
280 if (addrLen % 2 == 0)
283 bcdLen = addrLen/2 + 1;
285 pAddress->ton = (pTpdu[offset] & 0x70) >> 4;
286 pAddress->npi = pTpdu[offset++] & 0x0F;
288 MSG_DEBUG("ton [%d]", pAddress->ton);
289 MSG_DEBUG("npi [%d]", pAddress->npi);
291 if (pAddress->ton == SMS_TON_ALPHANUMERIC)
293 MSG_DEBUG("Alphanumeric address");
295 char* tmpAddress = new char[MAX_ADDRESS_LEN];
298 tmplength = SmsPluginUDCodec::unpack7bitChar(&(pTpdu[offset]), bcdLen, 0, tmpAddress);
300 SMS_LANG_INFO_S langInfo = {0};
302 langInfo.bSingleShift = false;
303 langInfo.bLockingShift = false;
305 SmsPluginTextConvert::instance()->convertGSM7bitToUTF8((unsigned char*)pAddress->address, MAX_ADDRESS_LEN, (unsigned char*)tmpAddress, tmplength, &langInfo);
307 else if (pAddress->ton == SMS_TON_INTERNATIONAL)
309 (pAddress->address)[0] = '+';
310 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[1]));
314 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[0]));
323 int SmsPluginParamCodec::decodeTime(const unsigned char *pTpdu, SMS_TIMESTAMP_S *pTimeStamp)
327 // decode in ABSOLUTE time type.
328 pTimeStamp->format = SMS_TIME_ABSOLUTE;
330 pTimeStamp->time.absolute.year = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
333 pTimeStamp->time.absolute.month = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
336 pTimeStamp->time.absolute.day = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
339 pTimeStamp->time.absolute.hour = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
342 pTimeStamp->time.absolute.minute = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
345 pTimeStamp->time.absolute.second = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
348 pTimeStamp->time.absolute.timeZone = (pTpdu[offset] & 0x07)*10 + ((pTpdu[offset] & 0xF0) >> 4);
350 if (pTpdu[offset] & 0x08)
351 pTimeStamp->time.absolute.timeZone *= (-1);
359 int SmsPluginParamCodec::decodeDCS(const unsigned char *pTpdu, SMS_DCS_S *pDCS)
362 char dcs = pTpdu[offset++];
365 pDCS->bIndActive = false;
366 pDCS->indType = SMS_OTHER_INDICATOR;
368 if (((dcs & 0xC0) >> 6) == 0)
370 pDCS->codingGroup = SMS_GROUP_GENERAL;
371 pDCS->bCompressed = (dcs & 0x20) >> 5;
372 pDCS->codingScheme = (dcs & 0x0C) >> 2;
374 if (((dcs & 0x10) >> 4) == 0)
375 pDCS->msgClass = SMS_MSG_CLASS_NONE;
377 pDCS->msgClass = dcs & 0x03;
379 else if (((dcs & 0xF0) >> 4) == 0x0F)
381 pDCS->codingGroup = SMS_GROUP_CODING_CLASS;
382 pDCS->bCompressed = false;
383 pDCS->codingScheme = (dcs & 0x0C) >> 2;
385 pDCS->msgClass = dcs & 0x03;
387 else if (((dcs & 0xC0) >> 6) == 1)
389 pDCS->codingGroup = SMS_GROUP_DELETION;
390 pDCS->bCompressed = false;
391 pDCS->msgClass = SMS_MSG_CLASS_NONE;
393 // TODO: finish here. ??
395 else if (((dcs & 0xF0) >> 4) == 0x0C)
397 pDCS->codingGroup = SMS_GROUP_DISCARD;
398 pDCS->bCompressed = false;
399 pDCS->msgClass = SMS_MSG_CLASS_NONE;
402 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? false:true;
403 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
405 else if (((dcs & 0xF0) >> 4) == 0x0D)
407 pDCS->codingGroup = SMS_GROUP_STORE;
408 pDCS->codingScheme = SMS_CHARSET_7BIT;
409 pDCS->bCompressed = false;
410 pDCS->msgClass = SMS_MSG_CLASS_NONE;
413 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? false:true;
414 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
416 else if (((dcs & 0xF0) >> 4) == 0x0E)
418 pDCS->codingGroup = SMS_GROUP_STORE;
419 pDCS->codingScheme = SMS_CHARSET_UCS2;
420 pDCS->bCompressed = false;
421 pDCS->msgClass = SMS_MSG_CLASS_NONE;
424 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? false:true;
425 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
429 pDCS->codingGroup = SMS_GROUP_UNKNOWN;
431 pDCS->bCompressed = (dcs & 0x20) >> 5;
432 pDCS->codingScheme = (dcs & 0x0C) >> 2;
434 pDCS->msgClass = SMS_MSG_CLASS_NONE;
441 void SmsPluginParamCodec::decodeSMSC(unsigned char* pAddress, int AddrLen, MSG_SMS_TON_T ton, char *pDecodeAddr)
443 if (pAddress == NULL || AddrLen == 0)
446 if (ton == SMS_TON_INTERNATIONAL)
448 pDecodeAddr[0] = '+';
449 convertBcdToDigit(pAddress, AddrLen, &(pDecodeAddr[1]));
453 convertBcdToDigit(pAddress, AddrLen, pDecodeAddr);
458 /*==================================================================================================
460 ==================================================================================================*/
461 int SmsPluginParamCodec::convertDigitToBcd(char *pDigit, int DigitLen, unsigned char *pBcd)
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';