svace issues fixed
[platform/core/messaging/msg-service.git] / plugin / sms_plugin / SmsPluginUDCodec.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
3  *
4  * Licensed under the Apache License, Version 2.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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15 */
16
17 #include "MsgDebug.h"
18 #include "MsgCppTypes.h"
19 #include "SmsPluginParamCodec.h"
20 #include "SmsPluginUDCodec.h"
21
22 using namespace std;
23
24 /*==================================================================================================
25                                      IMPLEMENTATION OF SmsPluginUDCodec - Member Functions
26 ==================================================================================================*/
27 SmsPluginUDCodec::SmsPluginUDCodec()
28 {
29 }
30
31
32 SmsPluginUDCodec::~SmsPluginUDCodec()
33 {
34 }
35
36
37 int SmsPluginUDCodec::encodeUserData(const SMS_USERDATA_S *pUserData, SMS_CODING_SCHEME_T CodingScheme, char *pEncodeData)
38 {
39         int encodeSize = 0;
40
41         switch (CodingScheme) {
42         case SMS_CHARSET_7BIT:
43                 encodeSize = encodeGSMData(pUserData, pEncodeData);
44                 break;
45         case SMS_CHARSET_8BIT:
46                 encodeSize = encode8bitData(pUserData, pEncodeData);
47                 break;
48         case SMS_CHARSET_UCS2:
49                 encodeSize = encodeUCS2Data(pUserData, pEncodeData);
50                 break;
51         }
52
53         return encodeSize;
54 }
55
56
57 int SmsPluginUDCodec::decodeUserData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_CODING_SCHEME_T CodingScheme, SMS_USERDATA_S *pUserData)
58 {
59         int decodeSize = 0;
60
61         memset(pUserData, 0x00, sizeof(SMS_USERDATA_S));
62
63         switch (CodingScheme) {
64         case SMS_CHARSET_7BIT:
65                 decodeSize = decodeGSMData(pTpdu, tpduLen, bHeaderInd, pUserData, NULL);
66                 break;
67         case SMS_CHARSET_8BIT:
68                 decodeSize = decode8bitData(pTpdu, bHeaderInd, pUserData, NULL);
69                 break;
70         case SMS_CHARSET_UCS2:
71                 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, NULL);
72                 break;
73         }
74
75         return decodeSize;
76 }
77
78
79 int SmsPluginUDCodec::decodeUserData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_CODING_SCHEME_T CodingScheme, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
80 {
81         int decodeSize = 0;
82
83         memset(pUserData, 0x00, sizeof(SMS_USERDATA_S));
84
85         switch (CodingScheme) {
86         case SMS_CHARSET_7BIT:
87                 decodeSize = decodeGSMData(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
88                 break;
89         case SMS_CHARSET_8BIT:
90                 decodeSize = decode8bitData(pTpdu, bHeaderInd, pUserData, pTPUD);
91                 break;
92         case SMS_CHARSET_UCS2:
93                 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
94                 break;
95         case SMS_CHARSET_EUCKR:
96                 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
97                 break;
98         }
99
100         return decodeSize;
101 }
102
103
104 int SmsPluginUDCodec::encodeGSMData(const SMS_USERDATA_S *pUserData, char *pEncodeData)
105 {
106         int headerLen = 0, offset = 0, fillBits = 0, packSize = 0, encodeLen = 0;
107         unsigned char udhl = 0x00;
108
109         if (pUserData->headerCnt > 0)
110                 offset = 2;
111         else
112                 offset = 1;
113
114         MSG_DEBUG("pUserData->headerCnt [%d]", pUserData->headerCnt);
115
116         /* Encode User Data Header */
117         for (int i = 0; i < pUserData->headerCnt; i++) {
118                 headerLen = encodeHeader(pUserData->header[i], &(pEncodeData[offset]));
119
120                 MSG_DEBUG("headerLen [%d]", headerLen);
121
122                 udhl += headerLen;
123                 offset += headerLen;
124         }
125
126         MSG_DEBUG("udhl [%d]", udhl);
127
128         if (udhl > 0)
129                 fillBits = ((udhl+1)*8)%7; /* + UDHL */
130
131         if (fillBits > 0)
132                 fillBits = 7 - fillBits;
133
134         MSG_DEBUG("fillBits [%d]", fillBits);
135         MSG_DEBUG("dataLen [%d]", pUserData->length);
136
137         /* Set UDL, UDHL */
138         if (udhl > 0) {
139                 pEncodeData[0] = (((udhl+1)*8) + fillBits + (pUserData->length*7)) / 7;
140                 pEncodeData[1] =  udhl;
141         } else {
142                 pEncodeData[0] = (char)pUserData->length;
143         }
144
145         packSize = pack7bitChar((unsigned char*)pUserData->data, pUserData->length, fillBits, &(pEncodeData[offset]));
146
147         encodeLen = offset + packSize;
148
149         MSG_DEBUG("packSize [%d]", packSize);
150         MSG_DEBUG("encodeLen [%d]", encodeLen);
151
152 #if 0
153 printf("\n\n[encodeGSMData] userData data.\n");
154 for (int j = 0; j < encodeLen; j++)
155 {
156         printf(" [%02x]", pEncodeData[j]);
157 }
158 printf("\n\n");
159 #endif
160
161         return encodeLen;
162 }
163
164
165 int SmsPluginUDCodec::encode8bitData(const SMS_USERDATA_S *pUserData, char *pEncodeData)
166 {
167         int headerLen = 0, offset = 2, fillBits = 0, encodeLen = 0;
168         unsigned char udhl = 0x00;
169
170         if (pUserData->headerCnt > 0)
171                 offset = 2;
172         else
173                 offset = 1;
174
175         /* Encode User Data Header */
176         for (int i = 0; i < pUserData->headerCnt; i++) {
177                 headerLen = encodeHeader(pUserData->header[i], &(pEncodeData[offset]));
178
179                 udhl += headerLen;
180                 offset += headerLen;
181         }
182
183         MSG_DEBUG("fillBits [%d]", fillBits);
184         MSG_DEBUG("dataLen [%d]", pUserData->length);
185
186         /* Set UDL, UDHL */
187         if (udhl > 0) {
188                 pEncodeData[0] = (udhl+1) + fillBits + pUserData->length;
189                 pEncodeData[1] =  udhl;
190         } else {
191                 pEncodeData[0] = (char)pUserData->length;
192         }
193
194         memcpy(&(pEncodeData[offset]), pUserData->data, pUserData->length);
195
196         encodeLen = offset + pUserData->length;
197
198         return encodeLen;
199 }
200
201
202 int SmsPluginUDCodec::encodeUCS2Data(const SMS_USERDATA_S *pUserData, char *pEncodeData)
203 {
204         int headerLen = 0, offset = 2, fillBits = 0, encodeLen = 0;
205         unsigned char udhl = 0x00;
206
207         if (pUserData->headerCnt > 0)
208                 offset = 2;
209         else
210                 offset = 1;
211
212         /* Encode User Data Header */
213         for (int i = 0; i < pUserData->headerCnt; i++) {
214                 headerLen = encodeHeader(pUserData->header[i], &(pEncodeData[offset]));
215
216                 udhl += headerLen;
217                 offset += headerLen;
218         }
219
220         MSG_DEBUG("fillBits [%d]", fillBits);
221         MSG_DEBUG("dataLen [%d]", pUserData->length);
222
223         /* Set UDL, UDHL */
224         if (udhl > 0) {
225                 pEncodeData[0] = (udhl+1) + fillBits + pUserData->length;
226                 pEncodeData[1] =  udhl;
227         } else {
228                 pEncodeData[0] = (char)pUserData->length;
229         }
230
231         memcpy(&(pEncodeData[offset]), pUserData->data, pUserData->length);
232
233         encodeLen = offset + pUserData->length;
234
235 #if 0
236 printf("\n\n[encodeUCS2Data] userData data.\n");
237 for (int j = 0; j < encodeLen; j++)
238 {
239         printf(" [%02x]", pEncodeData[j]);
240 }
241 printf("\n\n");
242 #endif
243
244         return encodeLen;
245 }
246
247
248 int SmsPluginUDCodec::decodeGSMData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
249 {
250         int offset = 0, udl = 0, udhl = 0, headerLen = 0, fillBits = 0, octetUdl = 0;
251
252         /* UDL */
253         udl = pTpdu[offset++];
254         octetUdl = (udl*7)/8;
255
256         MSG_DEBUG("udl = %d, tpdulen = %d, octetUdl = %d.", udl, tpduLen, octetUdl);
257         MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
258
259         if (udl > MAX_GSM_7BIT_DATA_LEN || octetUdl > tpduLen) {
260                 pUserData->length = 0;
261                 pUserData->headerCnt = 0;
262                 return 0;
263         }
264
265         /* Setting for Wap Push */
266         if (pTPUD != NULL) {
267                 pTPUD->udl = udl;
268
269                 memcpy(pTPUD->ud, &(pTpdu[offset]), udl);
270                 pTPUD->ud[udl] = '\0';
271         }
272
273         /* Decode User Data Header */
274         if (bHeaderInd == true) {
275                 /* UDHL */
276                 udhl = pTpdu[offset++];
277
278                 MSG_DEBUG("udhl = %d", udhl);
279
280                 pUserData->headerCnt = 0;
281
282                 for (int i = 0; offset < udhl; i++) {
283                         headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
284
285                         if (headerLen <= 0) {
286                                 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
287
288                                 pUserData->length = 0;
289                                 memset(pUserData->data, 0x00, sizeof(pUserData->data));
290
291                                 return 0;
292                         }
293
294                         offset += headerLen;
295
296                         if (offset > (udhl+2)) {
297                                 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
298
299                                 pUserData->length = 0;
300                                 memset(pUserData->data, 0x00, sizeof(pUserData->data));
301
302                                 return 0;
303                         }
304
305                         pUserData->headerCnt++;
306                 }
307         } else {
308                 pUserData->headerCnt = 0;
309         }
310
311         MSG_DEBUG("headerCnt = %d", pUserData->headerCnt);
312
313         if (udhl > 0) {
314                 fillBits = ((udl*7) - ((udhl+1)*8)) % 7;
315                 udl = ((udl*7) - ((udhl+1)*8)) / 7;
316         }
317
318         MSG_DEBUG("fillBits = %d", fillBits);
319         MSG_DEBUG("udhl = %d", udhl);
320         MSG_DEBUG("udl = %d", udl);
321
322         MSG_DEBUG("offset = %d", offset);
323
324         pUserData->length = unpack7bitChar(&(pTpdu[offset]), udl, fillBits, pUserData->data);
325
326         return pUserData->length;
327 }
328
329
330 int SmsPluginUDCodec::decode8bitData(const unsigned char *pTpdu, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
331 {
332         int offset = 0, udl = 0, udhl = 0, headerLen = 0;
333
334         /* UDL */
335         udl = pTpdu[offset++];
336
337         if (udl > MAX_UCS2_DATA_LEN) {
338                 pUserData->length = 0;
339                 return 0;
340         }
341
342         /* Setting for Wap Push */
343         if (pTPUD != NULL) {
344                 pTPUD->udl = udl;
345
346                 memcpy(pTPUD->ud, &(pTpdu[offset]), udl);
347                 pTPUD->ud[udl] = '\0';
348         }
349
350         MSG_DEBUG("udl = %d", udl);
351         MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
352
353         /* Decode User Data Header */
354         if (bHeaderInd == true) {
355                 /* UDHL */
356                 udhl = pTpdu[offset++];
357
358                 MSG_DEBUG("udhl = %d", udhl);
359
360                 pUserData->headerCnt = 0;
361
362                 for (int i = 0; offset < udhl; i++) {
363                         headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
364
365                         if (headerLen <= 0) {
366                                 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
367
368                                 pUserData->length = 0;
369                                 memset(pUserData->data, 0x00, sizeof(pUserData->data));
370
371                                 return 0;
372                         }
373
374                         offset += headerLen;
375
376                         if (offset > (udhl+2)) {
377                                 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
378
379                                 pUserData->length = 0;
380                                 memset(pUserData->data, 0x00, sizeof(pUserData->data));
381
382                                 return 0;
383                         }
384
385                         pUserData->headerCnt++;
386                 }
387         } else {
388                 pUserData->headerCnt = 0;
389         }
390
391         MSG_DEBUG("headerCnt = %d", pUserData->headerCnt);
392
393         if (udhl > 0)
394                 pUserData->length = (udl) - (udhl+1);
395         else
396                 pUserData->length = udl;
397
398         MSG_DEBUG("pUserData->length = %d", pUserData->length);
399         MSG_DEBUG("offset = %d", offset);
400
401         memcpy(pUserData->data, &(pTpdu[offset]), pUserData->length);
402
403         return pUserData->length;
404 }
405
406
407 int SmsPluginUDCodec::decodeUCS2Data(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
408 {
409         int offset = 0, udl = 0, udhl = 0, headerLen = 0;
410
411         /* UDL */
412         udl = pTpdu[offset++];
413
414         MSG_DEBUG("udl = %d, tpdulen = %d.", udl, tpduLen);
415         MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
416
417         if (udl > MAX_UCS2_DATA_LEN || udl > tpduLen) {
418                 pUserData->length = 0;
419                 pUserData->headerCnt = 0;
420                 return 0;
421         }
422
423         /* Setting for Wap Push */
424         if (pTPUD != NULL) {
425                 pTPUD->udl = udl;
426
427                 memcpy(pTPUD->ud, &(pTpdu[offset]), udl);
428                 pTPUD->ud[udl] = '\0';
429         }
430
431         /* Decode User Data Header */
432         if (bHeaderInd == true) {
433                 /* UDHL */
434                 udhl = pTpdu[offset++];
435
436                 MSG_DEBUG("udhl = %d", udhl);
437
438                 pUserData->headerCnt = 0;
439
440                 for (int i = 0; offset < udhl; i++) {
441                         headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
442
443                         if (headerLen <= 0) {
444                                 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
445
446                                 pUserData->length = 0;
447                                 memset(pUserData->data, 0x00, sizeof(pUserData->data));
448
449                                 return 0;
450                         }
451
452                         offset += headerLen;
453
454                         if (offset > (udhl+2)) {
455                                 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
456
457                                 pUserData->length = 0;
458                                 memset(pUserData->data, 0x00, sizeof(pUserData->data));
459
460                                 return 0;
461                         }
462
463                         pUserData->headerCnt++;
464                 }
465         } else {
466                 pUserData->headerCnt = 0;
467         }
468
469         if (udhl > 0)
470                 pUserData->length = (udl) - (udhl+1);
471         else
472                 pUserData->length = udl;
473
474         MSG_DEBUG("pUserData->length = %d", pUserData->length);
475         MSG_DEBUG("offset = %d", offset);
476
477         memcpy(pUserData->data, &(pTpdu[offset]), pUserData->length);
478         pUserData->data[pUserData->length] = 0;
479
480         return pUserData->length;
481 }
482
483
484 int SmsPluginUDCodec::encodeHeader(const SMS_UDH_S header, char *pEncodeHeader)
485 {
486         int offset = 0, addrLen = 0;
487
488         char* encodedAddr = NULL;
489         unique_ptr<char*, void(*)(char**)> addressBuf(&encodedAddr, unique_ptr_deleter);
490
491         switch (header.udhType) {
492         case SMS_UDH_CONCAT_8BIT :
493                 /* IEI */
494                 pEncodeHeader[offset++] = SMS_UDH_CONCAT_8BIT;
495
496                 /* IEDL */
497                 pEncodeHeader[offset++] = 0x03;
498
499                 /* Reference Number */
500                 pEncodeHeader[offset++] = header.udh.concat8bit.msgRef;
501
502                 /* Number of Segments */
503                 pEncodeHeader[offset++] = header.udh.concat8bit.totalSeg;
504
505                 /* Sequence Number */
506                 pEncodeHeader[offset++] = header.udh.concat8bit.seqNum;
507
508                 break;
509
510         case SMS_UDH_CONCAT_16BIT :
511                 /* IEI */
512                 pEncodeHeader[offset++] = SMS_UDH_CONCAT_16BIT;
513
514                 /* IEDL */
515                 pEncodeHeader[offset++] = 0x04;
516
517                 /* Reference Number */
518                 pEncodeHeader[offset++] = (char)(header.udh.concat16bit.msgRef >> 8);
519                 pEncodeHeader[offset++] = header.udh.concat16bit.msgRef & 0x00FF;
520
521                 /* Number of Segments */
522                 pEncodeHeader[offset++] = header.udh.concat16bit.totalSeg;
523
524                 /* Sequence Number */
525                 pEncodeHeader[offset++] = header.udh.concat16bit.seqNum;
526
527                 break;
528
529         case SMS_UDH_APP_PORT_8BIT :
530                 /* IEI */
531                 pEncodeHeader[offset++] = SMS_UDH_APP_PORT_8BIT;
532
533                 /* IEDL */
534                 pEncodeHeader[offset++] = 0x02;
535
536                 /* Dest Port */
537                 pEncodeHeader[offset++] = header.udh.appPort8bit.destPort;
538
539                 /* Origin Port */
540                 pEncodeHeader[offset++] = header.udh.appPort8bit.originPort;
541
542                 break;
543
544         case SMS_UDH_APP_PORT_16BIT :
545                 /* IEI */
546                 pEncodeHeader[offset++] = SMS_UDH_APP_PORT_16BIT;
547
548                 /* IEDL */
549                 pEncodeHeader[offset++] = 0x04;
550
551                 /* Dest Port */
552                 pEncodeHeader[offset++] = (char)(header.udh.appPort16bit.destPort >> 8);
553                 pEncodeHeader[offset++] = header.udh.appPort16bit.destPort & 0x00FF;
554
555                 /* Origin Port */
556                 pEncodeHeader[offset++] = (char)(header.udh.appPort16bit.originPort >> 8);
557                 pEncodeHeader[offset++] = header.udh.appPort16bit.originPort & 0x00FF;
558
559                 break;
560
561         case SMS_UDH_ALTERNATE_REPLY_ADDRESS :
562                 /* IEI */
563                 pEncodeHeader[offset++] = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
564
565                 addrLen = SmsPluginParamCodec::encodeAddress(&(header.udh.alternateAddress), &encodedAddr);
566
567                 /* IEDL */
568                 pEncodeHeader[offset++] = addrLen;
569
570                 /* Alternate Reply Address */
571                 memcpy(&pEncodeHeader[offset], encodedAddr, addrLen);
572
573                 offset += addrLen;
574
575                 break;
576
577         case SMS_UDH_SINGLE_SHIFT :
578                 /* IEI */
579                 pEncodeHeader[offset++] = SMS_UDH_SINGLE_SHIFT;
580
581                 /* IEDL */
582                 pEncodeHeader[offset++] = 0x01;
583
584                 /* National Language Identifier */
585                 pEncodeHeader[offset++] = header.udh.singleShift.langId;
586
587                 break;
588
589         case SMS_UDH_LOCKING_SHIFT :
590                 /* IEI */
591                 pEncodeHeader[offset++] = SMS_UDH_LOCKING_SHIFT;
592
593                 /* IEDL */
594                 pEncodeHeader[offset++] = 0x01;
595
596                 /* National Language Identifier */
597                 pEncodeHeader[offset++] = header.udh.lockingShift.langId;
598
599                 break;
600
601         case SMS_UDH_NONE :
602         default :
603                 break;
604         }
605
606         return offset;
607 }
608
609
610 int SmsPluginUDCodec::decodeHeader(const unsigned char *pTpdu, SMS_UDH_S *pHeader)
611 {
612         int offset = 0;
613         unsigned char IEDL = 0;
614
615         pHeader->udhType = pTpdu[offset++];
616
617         switch (pHeader->udhType) {
618         case SMS_UDH_CONCAT_8BIT: {
619                 IEDL = pTpdu[offset++];
620
621                 if (IEDL == 0)
622                         return 0;
623
624                 pHeader->udh.concat8bit.msgRef = pTpdu[offset++];
625                 pHeader->udh.concat8bit.totalSeg = pTpdu[offset++];
626                 pHeader->udh.concat8bit.seqNum = pTpdu[offset++];
627
628                 MSG_DEBUG("concat8bit.msgRef [%02x]", pHeader->udh.concat8bit.msgRef);
629                 MSG_DEBUG("concat8bit.totalSeg [%02x]", pHeader->udh.concat8bit.totalSeg);
630                 MSG_DEBUG("concat8bit.seqNum [%02x]", pHeader->udh.concat8bit.seqNum);
631         }
632         break;
633
634         case SMS_UDH_CONCAT_16BIT: {
635                 IEDL = pTpdu[offset++];
636
637                 if (IEDL == 0)
638                         return 0;
639
640                 pHeader->udh.concat16bit.msgRef = pTpdu[offset++];
641                 pHeader->udh.concat16bit.msgRef = (unsigned short)((pHeader->udh.concat16bit.msgRef << 8) | pTpdu[offset++]);
642                 pHeader->udh.concat16bit.totalSeg = pTpdu[offset++];
643                 pHeader->udh.concat16bit.seqNum = pTpdu[offset++];
644
645                 MSG_DEBUG("concat16bit.msgRef [%04x]", pHeader->udh.concat16bit.msgRef);
646                 MSG_DEBUG("concat16bit.totalSeg [%02x]", pHeader->udh.concat16bit.totalSeg);
647                 MSG_DEBUG("concat16bit.seqNum [%02x]", pHeader->udh.concat16bit.seqNum);
648         }
649         break;
650
651         case SMS_UDH_APP_PORT_8BIT: {
652                 IEDL = pTpdu[offset++];
653
654                 if (IEDL == 0)
655                         return 0;
656
657                 pHeader->udh.appPort8bit.destPort = pTpdu[offset++];
658                 pHeader->udh.appPort8bit.originPort = pTpdu[offset++];
659
660                 MSG_DEBUG("appPort8bit.destPort [%02x]", pHeader->udh.appPort8bit.destPort);
661                 MSG_DEBUG("appPort8bit.originPort [%02x]", pHeader->udh.appPort8bit.originPort);
662         }
663         break;
664
665         case SMS_UDH_APP_PORT_16BIT: {
666                 IEDL = pTpdu[offset++];
667
668                 if (IEDL == 0)
669                         return 0;
670
671                 pHeader->udh.appPort16bit.destPort = pTpdu[offset++];
672                 pHeader->udh.appPort16bit.destPort = (unsigned short)((pHeader->udh.appPort16bit.destPort << 8) | pTpdu[offset++]);
673                 pHeader->udh.appPort16bit.originPort = pTpdu[offset++];
674                 pHeader->udh.appPort16bit.originPort = (unsigned short)((pHeader->udh.appPort16bit.originPort << 8) | pTpdu[offset++]);
675
676                 MSG_DEBUG("appPort16bit.destPort [%04x]", pHeader->udh.appPort16bit.destPort);
677                 MSG_DEBUG("appPort16bit.originPort [%04x]", pHeader->udh.appPort16bit.originPort);
678         }
679         break;
680
681         case SMS_UDH_SPECIAL_SMS: {
682                 IEDL = pTpdu[offset++];
683
684                 if (IEDL != 2)
685                         return 0;
686
687                 MSG_DEBUG("Decoding special sms udh.");
688
689                 pHeader->udh.specialInd.bStore = (bool) (pTpdu[offset] & 0x80);
690                 pHeader->udh.specialInd.msgInd = (unsigned short) (pTpdu[offset++] & 0x7F);
691                 pHeader->udh.specialInd.waitMsgNum = (unsigned short) pTpdu[offset];
692         }
693         break;
694
695         case SMS_UDH_ALTERNATE_REPLY_ADDRESS: {
696                 IEDL = pTpdu[offset++];
697
698                 if (IEDL == 0)
699                         return 0;
700
701                 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pHeader->udh.alternateAddress));
702
703                 MSG_SEC_DEBUG("alternate reply address [%s]", pHeader->udh.alternateAddress.address);
704         }
705         break;
706
707         case SMS_UDH_SINGLE_SHIFT: {
708                 IEDL = pTpdu[offset++];
709
710                 if (IEDL == 0)
711                         return 0;
712
713                 pHeader->udh.singleShift.langId = pTpdu[offset++];
714
715                 MSG_DEBUG("singleShift.langId [%02x]", pHeader->udh.singleShift.langId);
716         }
717         break;
718
719         case SMS_UDH_LOCKING_SHIFT: {
720                 IEDL = pTpdu[offset++];
721
722                 if (IEDL == 0)
723                         return 0;
724
725                 pHeader->udh.lockingShift.langId = pTpdu[offset++];
726
727                 MSG_DEBUG("lockingShift.langId [%02x]", pHeader->udh.lockingShift.langId);
728         }
729         break;
730
731         default: {
732                 MSG_DEBUG("Not Supported Header Type [%02x]", pHeader->udhType);
733
734                 IEDL = pTpdu[offset++];
735
736                 MSG_DEBUG("IEDL [%d]", IEDL);
737                 return (offset + IEDL);
738         }
739         break;
740         }
741
742         return offset;
743 }
744
745
746 int SmsPluginUDCodec::pack7bitChar(const unsigned char *pUserData, int dataLen, int fillBits, char *pPackData)
747 {
748         int srcIdx = 0, dstIdx = 0, shift = fillBits;
749
750         if (shift > 0)
751                 dstIdx = 1;
752
753         while (srcIdx < dataLen) {
754                 if (shift == 0) {
755                         pPackData[dstIdx] = pUserData[srcIdx];
756
757                         shift = 7;
758                         srcIdx++;
759                         dstIdx++;
760
761                         if (srcIdx >= dataLen)
762                                 break;
763                 }
764
765                 if (shift > 1) {
766                         pPackData[dstIdx-1] |= pUserData[srcIdx] << shift;
767                         pPackData[dstIdx] = pUserData[srcIdx] >> (8-shift);
768                         shift--;
769
770                         srcIdx++;
771                         dstIdx++;
772                 } else if (shift == 1) {
773                         pPackData[dstIdx-1] |= pUserData[srcIdx] << shift;
774
775                         srcIdx++;
776
777                         shift--;
778                 }
779         }
780
781         return dstIdx;
782 }
783
784
785 int SmsPluginUDCodec::unpack7bitChar(const unsigned char *pTpdu, unsigned char dataLen, int fillBits, char *pUnpackData)
786 {
787         int srcIdx = 0, dstIdx = 0, shift = fillBits;
788
789 MSG_DEBUG("dataLen = %d", dataLen);
790
791         if (shift > 0)
792                 srcIdx = 1;
793
794         for (; dstIdx < dataLen; dstIdx++) {
795                 if (shift == 0) {
796                         pUnpackData[dstIdx] = pTpdu[srcIdx] & 0x7F;
797
798                         shift = 7;
799                         srcIdx++;
800                         dstIdx++;
801
802                         if (dstIdx >= dataLen)
803                                 break;
804                 }
805
806                 if (shift > 0) {
807                         pUnpackData[dstIdx] = (pTpdu[srcIdx-1] >> shift) + (pTpdu[srcIdx] << (8 - shift));
808
809                         pUnpackData[dstIdx] &= 0x7F;
810
811                         shift--;
812
813                         if (shift > 0)
814                                 srcIdx++;
815                 }
816         }
817
818         return dstIdx;
819 }
820