update tizen source
[framework/messaging/msg-service.git] / plugin / sms_plugin / SmsPluginParamCodec.cpp
1 /*
2 *
3 * Copyright (c) 2000-2012 Samsung Electronics Co., Ltd. All Rights Reserved.
4 *
5 * This file is part of msg-service.
6 *
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>
13 *
14 * PROPRIETARY/CONFIDENTIAL
15 *
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.
21 *
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.
28 *
29 */
30
31 #include <stdio.h>
32 #include <string.h>
33
34 #include "MsgDebug.h"
35 #include "SmsPluginUDCodec.h"
36 #include "SmsPluginTextConvert.h"
37 #include "SmsPluginParamCodec.h"
38
39
40 /*==================================================================================================
41                                      IMPLEMENTATION OF SmsPluginParamCodec - Member Functions
42 ==================================================================================================*/
43 SmsPluginParamCodec::SmsPluginParamCodec()
44 {
45
46
47 }
48
49
50 SmsPluginParamCodec::~SmsPluginParamCodec()
51 {
52
53
54 }
55
56
57 /*==================================================================================================
58                                      Encode Functions
59 ==================================================================================================*/
60 int SmsPluginParamCodec::encodeAddress(const SMS_ADDRESS_S *pAddress, char **ppParam)
61 {
62         int offset = 0, length = 0;
63         char *temp = (char *)pAddress->address;
64
65         SMS_TON_T ton;
66
67         *ppParam = new char[MAX_ADD_PARAM_LEN];
68
69         // Set Address Length
70         if (temp[0] == '+')
71         {
72                 (*ppParam)[offset++] = strlen(temp) - 1;
73                 temp++;
74
75                 ton = SMS_TON_INTERNATIONAL;
76         }
77         else
78         {
79                 (*ppParam)[offset++] = strlen(temp);
80
81                 ton = pAddress->ton;
82         }
83
84         // Set TON, NPI
85         (*ppParam)[offset++] = 0x80 + (ton << 4) + pAddress->npi;
86
87         MSG_DEBUG("Address length is %d.", (*ppParam)[0]);
88         MSG_DEBUG("pAddress->ton : %d.", ton);
89         MSG_DEBUG("pAddress->npi : %d.", pAddress->npi);
90
91         length = convertDigitToBcd(temp, strlen(temp), (unsigned char *) &((*ppParam)[offset]));
92
93         offset += length;
94
95         return offset ;
96 }
97
98
99 int SmsPluginParamCodec::encodeTime(const SMS_TIMESTAMP_S *pTimeStamp, char **ppParam)
100 {
101         int offset = 0;
102
103         if(pTimeStamp->format == SMS_TIME_ABSOLUTE)
104         {
105                 int timeZone = pTimeStamp->time.absolute.timeZone;
106                 *ppParam = new char[MAX_ABS_TIME_PARAM_LEN];
107
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);
114
115                 if(timeZone < 0)
116                 {
117                         timeZone *= -1;
118                         (*ppParam)[offset] = 0x08;
119                 }
120                 (*ppParam)[offset++] += ((pTimeStamp->time.absolute.timeZone % 10) << 4) + (pTimeStamp->time.absolute.timeZone / 10);
121
122
123                 return offset;
124         }
125         else if(pTimeStamp->format == SMS_TIME_RELATIVE)
126         {
127                 *ppParam = new char[MAX_REL_TIME_PARAM_LEN+1];
128
129                 memcpy(*ppParam, &(pTimeStamp->time.relative.time), MAX_REL_TIME_PARAM_LEN);
130
131                 return MAX_REL_TIME_PARAM_LEN;
132         }
133
134         return offset;
135 }
136
137
138 int SmsPluginParamCodec::encodeDCS(const SMS_DCS_S *pDCS, char **ppParam)
139 {
140         *ppParam = new char;
141
142         **ppParam = 0x00;
143
144         switch (pDCS->codingGroup)
145         {
146                 case SMS_GROUP_GENERAL:
147                 {
148                         if (pDCS->msgClass != SMS_MSG_CLASS_NONE)
149                         {
150                                 **ppParam = 0x10 + pDCS->msgClass;
151                         }
152
153                         if (pDCS->bCompressed)
154                         {
155                                 **ppParam |= 0x20;
156                         }
157                 }
158                 break;
159
160                 case SMS_GROUP_CODING_CLASS:
161                 {
162                         **ppParam = 0xF0 + pDCS->msgClass;
163                 }
164                 break;
165
166                 case SMS_GROUP_DELETION:
167                         //not supported
168                 break;
169
170                 case SMS_GROUP_DISCARD:
171                         //not supported
172                 break;
173
174                 case SMS_GROUP_STORE:
175                         //not supported
176                 break;
177
178                 default:
179                         return 0;
180         }
181
182         switch (pDCS->codingScheme)
183         {
184                 case SMS_CHARSET_7BIT:
185
186                 break;
187
188                 case SMS_CHARSET_8BIT:
189                         **ppParam |= 0x04;
190                 break;
191
192                 case SMS_CHARSET_UCS2:
193                         **ppParam |= 0x08;
194                 break;
195
196                 default:
197                         return 0;
198         }
199
200         return 1;
201 }
202
203
204 int SmsPluginParamCodec::encodeSMSC(const char *pAddress, unsigned char *pEncodeAddr)
205 {
206         char newAddr[MAX_SMSC_LEN+1];
207         memset(newAddr, 0x00, sizeof(newAddr));
208
209         if (pAddress[0] == '+')
210         {
211                 strncpy(newAddr, pAddress+1, MAX_SMSC_LEN);
212         }
213         else
214         {
215                 strncpy(newAddr, pAddress, MAX_SMSC_LEN);
216         }
217
218         // Set Address
219         int encodeLen = convertDigitToBcd(newAddr, strlen(newAddr), pEncodeAddr);
220
221         pEncodeAddr[encodeLen] = '\0';
222
223         return encodeLen;
224 }
225
226
227 int SmsPluginParamCodec::encodeSMSC(const SMS_ADDRESS_S *pAddress, unsigned char *pSMSC)
228 {
229         char newAddr[MAX_SMSC_LEN+1];
230         memset(newAddr, 0x00, sizeof(newAddr));
231
232         int dataSize = 0, addrLen = 0;
233
234         if (pAddress->address[0] == '+')
235                 memcpy(newAddr, pAddress->address+1, strlen(pAddress->address)-1);
236         else
237                 memcpy(newAddr, pAddress->address, strlen(pAddress->address));
238
239         addrLen = strlen(newAddr);
240
241         if (addrLen % 2 == 0)
242                 dataSize = 2 + (addrLen/2);
243         else
244                 dataSize = 2 + (addrLen/2) + 1;
245
246         if (dataSize > MAX_SMSC_LEN)
247         {
248                 MSG_DEBUG("addrLen is too long [%d]", addrLen);
249                 MSG_DEBUG("dataSize is too long [%d]", dataSize);
250
251                 return 0;
252         }
253
254         // Set Address Length
255         // Check IPC 4.0 -> addrLen/2
256         pSMSC[0] = addrLen;
257
258         // Set TON, NPI
259         pSMSC[1] = 0x80 + (pAddress->ton << 4) + pAddress->npi;
260
261         // Set Address
262         convertDigitToBcd(newAddr, addrLen, &(pSMSC[2]));
263
264         pSMSC[dataSize] = '\0';
265
266         return dataSize;
267 }
268
269
270 /*==================================================================================================
271                                      Decode Functions
272 ==================================================================================================*/
273 int SmsPluginParamCodec::decodeAddress(const unsigned char *pTpdu, SMS_ADDRESS_S *pAddress)
274 {
275         int offset = 0, addrLen = 0, bcdLen = 0;
276         memset(pAddress->address, 0x00, sizeof(pAddress->address));
277
278         addrLen = (int)pTpdu[offset++];
279
280         if (addrLen % 2 == 0)
281                 bcdLen = addrLen/2;
282         else
283                 bcdLen = addrLen/2 + 1;
284
285         pAddress->ton = (pTpdu[offset] & 0x70) >> 4;
286         pAddress->npi = pTpdu[offset++] & 0x0F;
287
288 MSG_DEBUG("ton [%d]", pAddress->ton);
289 MSG_DEBUG("npi [%d]", pAddress->npi);
290
291         if (pAddress->ton == SMS_TON_ALPHANUMERIC)
292         {
293                 MSG_DEBUG("Alphanumeric address");
294
295                 char* tmpAddress = new char[MAX_ADDRESS_LEN];
296                 int tmplength = 0;
297
298                 tmplength = SmsPluginUDCodec::unpack7bitChar(&(pTpdu[offset]), bcdLen, 0, tmpAddress);
299
300                 SMS_LANG_INFO_S langInfo = {0};
301
302                 langInfo.bSingleShift = false;
303                 langInfo.bLockingShift = false;
304
305                 SmsPluginTextConvert::instance()->convertGSM7bitToUTF8((unsigned char*)pAddress->address, MAX_ADDRESS_LEN, (unsigned char*)tmpAddress, tmplength, &langInfo);
306         }
307         else if (pAddress->ton == SMS_TON_INTERNATIONAL)
308         {
309                 (pAddress->address)[0] = '+';
310                 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[1]));
311         }
312         else
313         {
314                 convertBcdToDigit(&(pTpdu[offset]), bcdLen, &((pAddress->address)[0]));
315         }
316
317         offset +=       bcdLen;
318
319         return offset;
320 }
321
322
323 int SmsPluginParamCodec::decodeTime(const unsigned char *pTpdu, SMS_TIMESTAMP_S *pTimeStamp)
324 {
325         int offset = 0;
326
327         // decode in ABSOLUTE time type.
328         pTimeStamp->format = SMS_TIME_ABSOLUTE;
329
330         pTimeStamp->time.absolute.year = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
331         offset++;
332
333         pTimeStamp->time.absolute.month = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
334         offset++;
335
336         pTimeStamp->time.absolute.day = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
337         offset++;
338
339         pTimeStamp->time.absolute.hour = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
340         offset++;
341
342         pTimeStamp->time.absolute.minute = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
343         offset++;
344
345         pTimeStamp->time.absolute.second = (pTpdu[offset] & 0x0F)*10 + ((pTpdu[offset] & 0xF0) >> 4);
346         offset++;
347
348         pTimeStamp->time.absolute.timeZone = (pTpdu[offset] & 0x07)*10 + ((pTpdu[offset] & 0xF0) >> 4);
349
350         if (pTpdu[offset] & 0x08)
351                 pTimeStamp->time.absolute.timeZone *= (-1);
352
353         offset++;
354
355         return offset;
356 }
357
358
359 int SmsPluginParamCodec::decodeDCS(const unsigned char *pTpdu, SMS_DCS_S *pDCS)
360 {
361         int offset = 0;
362         char dcs = pTpdu[offset++];
363
364         pDCS->bMWI = false;
365         pDCS->bIndActive = false;
366         pDCS->indType = SMS_OTHER_INDICATOR;
367
368         if (((dcs & 0xC0) >> 6) == 0)
369         {
370                 pDCS->codingGroup = SMS_GROUP_GENERAL;
371                 pDCS->bCompressed = (dcs & 0x20) >> 5;
372                 pDCS->codingScheme = (dcs & 0x0C) >> 2;
373
374                 if (((dcs & 0x10) >> 4) == 0)
375                         pDCS->msgClass = SMS_MSG_CLASS_NONE;
376                 else
377                         pDCS->msgClass = dcs & 0x03;
378         }
379         else if (((dcs & 0xF0) >> 4) == 0x0F)
380         {
381                 pDCS->codingGroup = SMS_GROUP_CODING_CLASS;
382                 pDCS->bCompressed = false;
383                 pDCS->codingScheme = (dcs & 0x0C) >> 2;
384
385                 pDCS->msgClass = dcs & 0x03;
386         }
387         else if (((dcs & 0xC0) >> 6) == 1)
388         {
389                 pDCS->codingGroup = SMS_GROUP_DELETION;
390                 pDCS->bCompressed = false;
391                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
392
393                 // TODO: finish here. ??
394         }
395         else if (((dcs & 0xF0) >> 4) == 0x0C)
396         {
397                 pDCS->codingGroup = SMS_GROUP_DISCARD;
398                 pDCS->bCompressed = false;
399                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
400
401                 pDCS->bMWI = true;
402                 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? false:true;
403                 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
404         }
405         else if (((dcs & 0xF0) >> 4) == 0x0D)
406         {
407                 pDCS->codingGroup = SMS_GROUP_STORE;
408                 pDCS->codingScheme = SMS_CHARSET_7BIT;
409                 pDCS->bCompressed = false;
410                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
411
412                 pDCS->bMWI = true;
413                 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? false:true;
414                 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
415         }
416         else if (((dcs & 0xF0) >> 4) == 0x0E)
417         {
418                 pDCS->codingGroup = SMS_GROUP_STORE;
419                 pDCS->codingScheme = SMS_CHARSET_UCS2;
420                 pDCS->bCompressed = false;
421                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
422
423                 pDCS->bMWI = true;
424                 pDCS->bIndActive = (((dcs & 0x08) >> 3) == 1)? false:true;
425                 pDCS->indType = (SMS_INDICATOR_TYPE_T)(dcs & 0x03);
426         }
427         else
428         {
429                 pDCS->codingGroup = SMS_GROUP_UNKNOWN;
430
431                 pDCS->bCompressed = (dcs & 0x20) >> 5;
432                 pDCS->codingScheme = (dcs & 0x0C) >> 2;
433
434                 pDCS->msgClass = SMS_MSG_CLASS_NONE;
435         }
436
437         return offset;
438 }
439
440
441 void SmsPluginParamCodec::decodeSMSC(unsigned char* pAddress, int AddrLen, MSG_SMS_TON_T ton, char *pDecodeAddr)
442 {
443         if (pAddress == NULL || AddrLen == 0)
444                 return;
445
446         if (ton == SMS_TON_INTERNATIONAL)
447         {
448                 pDecodeAddr[0] = '+';
449                 convertBcdToDigit(pAddress, AddrLen, &(pDecodeAddr[1]));
450         }
451         else
452         {
453                 convertBcdToDigit(pAddress, AddrLen, pDecodeAddr);
454         }
455 }
456
457
458 /*==================================================================================================
459                                      Util Functions
460 ==================================================================================================*/
461 int SmsPluginParamCodec::convertDigitToBcd(char *pDigit, int DigitLen, unsigned char *pBcd)
462 {
463         int offset = 0;
464         unsigned char temp;
465
466         for (int i = 0; i < DigitLen; i++)
467         {
468                 if (pDigit[i] == '*')
469                         temp = 0x0A;
470                 else if (pDigit[i] == '#')
471                         temp = 0x0B;
472                 else if (pDigit[i] == 'P' || pDigit[i] == 'p')
473                         temp = 0x0C;
474                 else
475                         temp = pDigit[i] - '0';
476
477                 if ((i%2) == 0)
478                         pBcd[offset] = temp & 0x0F;
479                 else
480                         pBcd[offset++] |= ((temp & 0x0F) << 4);
481         }
482
483         if ((DigitLen%2) == 1)
484         {
485                 pBcd[offset++] |= 0xF0;
486         }
487
488         return offset;
489 }
490
491
492 int SmsPluginParamCodec::convertBcdToDigit(const unsigned char *pBcd, int BcdLen, char *pDigit)
493 {
494         int offset = 0;
495         unsigned char temp;
496
497         for (int i = 0; i < BcdLen; i++)
498         {
499                 temp = pBcd[i] & 0x0F;
500
501                 if (temp == 0x0A)
502                         pDigit[offset++] = '*';
503                 else if (temp == 0x0B)
504                         pDigit[offset++] = '#';
505                 else if (temp == 0x0C)
506                         pDigit[offset++] = 'P';
507                 else
508                         pDigit[offset++] = temp + '0';
509
510                 temp = (pBcd[i] & 0xF0) >> 4;
511
512                 if (temp == 0x0F)
513                 {
514                         pDigit[offset] = '\0';
515                         return offset;
516                 }
517
518                 if (temp == 0x0A)
519                         pDigit[offset++] = '*';
520                 else if (temp == 0x0B)
521                         pDigit[offset++] = '#';
522                 else if (temp == 0x0C)
523                         pDigit[offset++] = 'P';
524                 else
525                         pDigit[offset++] = temp + '0';
526         }
527
528         pDigit[offset] = '\0';
529
530         return offset;
531 }
532