2 * Copyright 2012-2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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;
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]), bcdLen, 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 (pAddress->address)[0] = '+';
302 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[1]));
306 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[0]));
311 //MSG_DEBUG("address [%s]", pAddress->address);
317 int SmsPluginParamCodec::decodeTime(const unsigned char *pTpdu, SMS_TIMESTAMP_S *pTimeStamp)
321 // decode in ABSOLUTE time type.
322 pTimeStamp->format = SMS_TIME_ABSOLUTE;
324 pTimeStamp->time.absolute.year = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
327 pTimeStamp->time.absolute.month = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
330 pTimeStamp->time.absolute.day = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
333 pTimeStamp->time.absolute.hour = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
336 pTimeStamp->time.absolute.minute = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
339 pTimeStamp->time.absolute.second = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
342 pTimeStamp->time.absolute.timeZone = (pTpdu[offset] & 0x07)*10 + ((pTpdu[offset] & 0xF0) >> 4);
344 if (pTpdu[offset] & 0x08)
345 pTimeStamp->time.absolute.timeZone *= (-1);
353 int SmsPluginParamCodec::decodeDCS(const unsigned char *pTpdu, SMS_DCS_S *pDCS)
356 char dcs = pTpdu[offset++];
359 pDCS->bIndActive = false;
360 pDCS->indType = SMS_OTHER_INDICATOR;
362 if (((dcs & 0xC0) >> 6) == 0)
364 pDCS->codingGroup = SMS_GROUP_GENERAL;
365 pDCS->bCompressed = (dcs & 0x20) >> 5;
366 pDCS->codingScheme = (dcs & 0x0C) >> 2;
368 if (((dcs & 0x10) >> 4) == 0)
369 pDCS->msgClass = SMS_MSG_CLASS_NONE;
371 pDCS->msgClass = dcs & 0x03;
373 else if (((dcs & 0xF0) >> 4) == 0x0F)
375 pDCS->codingGroup = SMS_GROUP_CODING_CLASS;
376 pDCS->bCompressed = false;
377 pDCS->codingScheme = (dcs & 0x0C) >> 2;
379 pDCS->msgClass = dcs & 0x03;
381 else if (((dcs & 0xC0) >> 6) == 1)
383 pDCS->codingGroup = SMS_GROUP_DELETION;
384 pDCS->bCompressed = false;
385 pDCS->msgClass = SMS_MSG_CLASS_NONE;
387 // TODO: finish here. ??
389 else if (((dcs & 0xF0) >> 4) == 0x0C)
391 pDCS->codingGroup = SMS_GROUP_DISCARD;
392 pDCS->bCompressed = false;
393 pDCS->msgClass = SMS_MSG_CLASS_NONE;
396 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
397 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
399 else if (((dcs & 0xF0) >> 4) == 0x0D)
401 pDCS->codingGroup = SMS_GROUP_STORE;
402 pDCS->codingScheme = SMS_CHARSET_7BIT;
403 pDCS->bCompressed = false;
404 pDCS->msgClass = SMS_MSG_CLASS_NONE;
407 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? true:false;
408 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
410 else if (((dcs & 0xF0) >> 4) == 0x0E)
412 pDCS->codingGroup = SMS_GROUP_STORE;
413 pDCS->codingScheme = SMS_CHARSET_UCS2;
414 pDCS->bCompressed = false;
415 pDCS->msgClass = SMS_MSG_CLASS_NONE;
418 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? false:true;
419 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
423 pDCS->codingGroup = SMS_GROUP_UNKNOWN;
425 pDCS->bCompressed = (dcs & 0x20) >> 5;
426 pDCS->codingScheme = (dcs & 0x0C) >> 2;
428 pDCS->msgClass = SMS_MSG_CLASS_NONE;
435 void SmsPluginParamCodec::decodeSMSC(unsigned char* pAddress, int AddrLen, MSG_SMS_TON_T ton, char *pDecodeAddr)
437 if (pAddress == NULL || AddrLen == 0)
440 if (ton == SMS_TON_INTERNATIONAL)
442 pDecodeAddr[0] = '+';
443 convertBcdToDigit(pAddress, AddrLen, &(pDecodeAddr[1]));
447 convertBcdToDigit(pAddress, AddrLen, pDecodeAddr);
452 /*==================================================================================================
454 ==================================================================================================*/
455 int SmsPluginParamCodec::convertDigitToBcd(char *pDigit, int DigitLen, unsigned char *pBcd)
460 //MSG_DEBUG("DigitLen [%d]", DigitLen);
461 //MSG_DEBUG("pDigit [%s]", pDigit);
463 for (int i = 0; i < DigitLen; i++)
465 if (pDigit[i] == '*')
467 else if (pDigit[i] == '#')
469 else if (pDigit[i] == 'P' || pDigit[i] == 'p')
472 temp = pDigit[i] - '0';
475 pBcd[offset] = temp & 0x0F;
477 pBcd[offset++] |= ((temp & 0x0F) << 4);
480 if ((DigitLen%2) == 1)
482 pBcd[offset++] |= 0xF0;
489 int SmsPluginParamCodec::convertBcdToDigit(const unsigned char *pBcd, int BcdLen, char *pDigit)
494 for (int i = 0; i < BcdLen; i++)
496 temp = pBcd[i] & 0x0F;
499 pDigit[offset++] = '*';
500 else if (temp == 0x0B)
501 pDigit[offset++] = '#';
502 else if (temp == 0x0C)
503 pDigit[offset++] = 'P';
505 pDigit[offset++] = temp + '0';
507 temp = (pBcd[i] & 0xF0) >> 4;
511 pDigit[offset] = '\0';
516 pDigit[offset++] = '*';
517 else if (temp == 0x0B)
518 pDigit[offset++] = '#';
519 else if (temp == 0x0C)
520 pDigit[offset++] = 'P';
522 pDigit[offset++] = temp + '0';
525 pDigit[offset] = '\0';