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