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