2 * Copyright 2012-2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "MsgCppTypes.h"
19 #include "SmsPluginParamCodec.h"
20 #include "SmsPluginUDCodec.h"
23 /*==================================================================================================
24 IMPLEMENTATION OF SmsPluginUDCodec - Member Functions
25 ==================================================================================================*/
26 SmsPluginUDCodec::SmsPluginUDCodec()
32 SmsPluginUDCodec::~SmsPluginUDCodec()
38 int SmsPluginUDCodec::encodeUserData(const SMS_USERDATA_S *pUserData, SMS_CODING_SCHEME_T CodingScheme, char *pEncodeData)
44 case SMS_CHARSET_7BIT:
45 encodeSize = encodeGSMData(pUserData, pEncodeData);
47 case SMS_CHARSET_8BIT:
48 encodeSize = encode8bitData(pUserData, pEncodeData);
50 case SMS_CHARSET_UCS2:
51 encodeSize = encodeUCS2Data(pUserData, pEncodeData);
59 int SmsPluginUDCodec::decodeUserData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_CODING_SCHEME_T CodingScheme, SMS_USERDATA_S *pUserData)
63 memset(pUserData, 0x00, sizeof(SMS_USERDATA_S));
67 case SMS_CHARSET_7BIT:
68 decodeSize = decodeGSMData(pTpdu, tpduLen, bHeaderInd, pUserData, NULL);
70 case SMS_CHARSET_8BIT:
71 decodeSize = decode8bitData(pTpdu, bHeaderInd, pUserData, NULL);
73 case SMS_CHARSET_UCS2:
74 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, NULL);
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)
86 memset(pUserData, 0x00, sizeof(SMS_USERDATA_S));
90 case SMS_CHARSET_7BIT:
91 decodeSize = decodeGSMData(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
93 case SMS_CHARSET_8BIT:
94 decodeSize = decode8bitData(pTpdu, bHeaderInd, pUserData, pTPUD);
96 case SMS_CHARSET_UCS2:
97 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
99 case SMS_CHARSET_EUCKR:
100 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
108 int SmsPluginUDCodec::encodeGSMData(const SMS_USERDATA_S *pUserData, char *pEncodeData)
110 int headerLen = 0, offset = 0, fillBits = 0, packSize = 0, encodeLen = 0;
111 unsigned char udhl = 0x00;
113 if (pUserData->headerCnt > 0)
118 MSG_DEBUG("pUserData->headerCnt [%d]", pUserData->headerCnt);
120 // Encode User Data Header
121 for (int i = 0; i < pUserData->headerCnt; i++)
123 headerLen = encodeHeader(pUserData->header[i], &(pEncodeData[offset]));
125 MSG_DEBUG("headerLen [%d]", headerLen);
131 MSG_DEBUG("udhl [%d]", udhl);
134 fillBits = ((udhl+1)*8)%7; // + UDHL
137 fillBits = 7 - fillBits;
139 MSG_DEBUG("fillBits [%d]", fillBits);
140 MSG_DEBUG("dataLen [%d]", pUserData->length);
145 pEncodeData[0] = (((udhl+1)*8) + fillBits + (pUserData->length*7)) / 7;
146 pEncodeData[1] = udhl;
150 pEncodeData[0] = (char)pUserData->length;
153 packSize = pack7bitChar((unsigned char*)pUserData->data, pUserData->length, fillBits, &(pEncodeData[offset]));
155 encodeLen = offset + packSize;
157 MSG_DEBUG("packSize [%d]", packSize);
158 MSG_DEBUG("encodeLen [%d]", encodeLen);
164 int SmsPluginUDCodec::encode8bitData(const SMS_USERDATA_S *pUserData, char *pEncodeData)
166 int headerLen = 0, offset = 2, fillBits = 0, encodeLen = 0;
167 unsigned char udhl = 0x00;
169 if (pUserData->headerCnt > 0)
174 // Encode User Data Header
175 for (int i = 0; i < pUserData->headerCnt; i++)
177 headerLen = encodeHeader(pUserData->header[i], &(pEncodeData[offset]));
183 MSG_DEBUG("fillBits [%d]", fillBits);
184 MSG_DEBUG("dataLen [%d]", pUserData->length);
189 pEncodeData[0] = (udhl+1) + fillBits + pUserData->length;
190 pEncodeData[1] = udhl;
194 pEncodeData[0] = (char)pUserData->length;
197 memcpy(&(pEncodeData[offset]), pUserData->data, pUserData->length);
199 encodeLen = offset + pUserData->length;
205 int SmsPluginUDCodec::encodeUCS2Data(const SMS_USERDATA_S *pUserData, char *pEncodeData)
207 int headerLen = 0, offset = 2, fillBits = 0, encodeLen = 0;
208 unsigned char udhl = 0x00;
210 if (pUserData->headerCnt > 0)
215 // Encode User Data Header
216 for (int i = 0; i < pUserData->headerCnt; i++)
218 headerLen = encodeHeader(pUserData->header[i], &(pEncodeData[offset]));
224 MSG_DEBUG("fillBits [%d]", fillBits);
225 MSG_DEBUG("dataLen [%d]", pUserData->length);
230 pEncodeData[0] = (udhl+1) + fillBits + pUserData->length;
231 pEncodeData[1] = udhl;
235 pEncodeData[0] = (char)pUserData->length;
238 memcpy(&(pEncodeData[offset]), pUserData->data, pUserData->length);
240 encodeLen = offset + pUserData->length;
246 int SmsPluginUDCodec::decodeGSMData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
248 int offset = 0, udl = 0, udhl = 0, headerLen = 0, fillBits = 0, octetUdl = 0;
251 udl = pTpdu[offset++];
252 octetUdl = (udl*7)/8;
254 MSG_DEBUG("udl = %d, tpdulen = %d, octetUdl = %d.", udl, tpduLen, octetUdl);
255 MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
257 if (udl > MAX_GSM_7BIT_DATA_LEN || octetUdl > tpduLen)
259 pUserData->length = 0;
260 pUserData->headerCnt = 0;
264 // Setting for Wap Push
269 memcpy(pTPUD->ud, &(pTpdu[offset]), udl);
270 pTPUD->ud[udl] = '\0';
273 // Decode User Data Header
274 if (bHeaderInd == true)
277 udhl = pTpdu[offset++];
279 MSG_DEBUG("udhl = %d", udhl);
281 pUserData->headerCnt = 0;
283 for (int i = 0; offset < udhl; i++)
285 headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
287 if (headerLen <= 0) {
288 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
290 pUserData->length = 0;
291 memset(pUserData->data, 0x00, sizeof(pUserData->data));
298 if (offset > (udhl+2)) {
299 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
301 pUserData->length = 0;
302 memset(pUserData->data, 0x00, sizeof(pUserData->data));
307 pUserData->headerCnt++;
311 pUserData->headerCnt = 0;
313 MSG_DEBUG("headerCnt = %d", pUserData->headerCnt);
317 fillBits = ((udl*7) - ((udhl+1)*8)) % 7;
318 udl = ((udl*7) - ((udhl+1)*8)) / 7;
321 MSG_DEBUG("fillBits = %d", fillBits);
322 MSG_DEBUG("udhl = %d", udhl);
323 MSG_DEBUG("udl = %d", udl);
325 MSG_DEBUG("offset = %d", offset);
327 pUserData->length = unpack7bitChar(&(pTpdu[offset]), udl, fillBits, pUserData->data);
329 //MSG_DEBUG("data = [%s]", pUserData->data);
330 //MSG_DEBUG("length = [%d]", pUserData->length);
333 return pUserData->length;
337 int SmsPluginUDCodec::decode8bitData(const unsigned char *pTpdu, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
339 int offset = 0, udl = 0, udhl = 0, headerLen = 0;
342 udl = pTpdu[offset++];
344 if (udl > MAX_UCS2_DATA_LEN)
346 pUserData->length = 0;
350 // Setting for Wap Push
355 memcpy(pTPUD->ud, &(pTpdu[offset]), udl);
356 pTPUD->ud[udl] = '\0';
359 MSG_DEBUG("udl = %d", udl);
360 MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
362 // Decode User Data Header
363 if (bHeaderInd == true)
366 udhl = pTpdu[offset++];
368 MSG_DEBUG("udhl = %d", udhl);
370 pUserData->headerCnt = 0;
372 for (int i = 0; offset < udhl; i++)
374 headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
376 if (headerLen <= 0) {
377 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
379 pUserData->length = 0;
380 memset(pUserData->data, 0x00, sizeof(pUserData->data));
387 if (offset > (udhl+2)) {
388 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
390 pUserData->length = 0;
391 memset(pUserData->data, 0x00, sizeof(pUserData->data));
396 pUserData->headerCnt++;
400 pUserData->headerCnt = 0;
402 MSG_DEBUG("headerCnt = %d", pUserData->headerCnt);
405 pUserData->length = (udl) - (udhl+1);
407 pUserData->length = udl;
409 MSG_DEBUG("pUserData->length = %d", pUserData->length);
410 MSG_DEBUG("offset = %d", offset);
412 memcpy(pUserData->data, &(pTpdu[offset]), pUserData->length);
414 return pUserData->length;
418 int SmsPluginUDCodec::decodeUCS2Data(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
420 int offset = 0, udl = 0, udhl = 0, headerLen = 0;
423 udl = pTpdu[offset++];
425 MSG_DEBUG("udl = %d, tpdulen = %d.", udl, tpduLen);
426 MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
428 if (udl > MAX_UCS2_DATA_LEN || udl > tpduLen)
430 pUserData->length = 0;
431 pUserData->headerCnt = 0;
435 // Setting for Wap Push
440 memcpy(pTPUD->ud, &(pTpdu[offset]), udl);
441 pTPUD->ud[udl] = '\0';
444 // Decode User Data Header
445 if (bHeaderInd == true)
448 udhl = pTpdu[offset++];
450 MSG_DEBUG("udhl = %d", udhl);
452 pUserData->headerCnt = 0;
454 for (int i = 0; offset < udhl; i++)
456 headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
458 if (headerLen <= 0) {
459 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
461 pUserData->length = 0;
462 memset(pUserData->data, 0x00, sizeof(pUserData->data));
469 if (offset > (udhl+2)) {
470 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
472 pUserData->length = 0;
473 memset(pUserData->data, 0x00, sizeof(pUserData->data));
478 pUserData->headerCnt++;
482 pUserData->headerCnt = 0;
485 pUserData->length = (udl) - (udhl+1);
487 pUserData->length = udl;
489 MSG_DEBUG("pUserData->length = %d", pUserData->length);
490 MSG_DEBUG("offset = %d", offset);
492 memcpy(pUserData->data, &(pTpdu[offset]), pUserData->length);
493 pUserData->data[pUserData->length] = 0;
495 return pUserData->length;
499 int SmsPluginUDCodec::encodeHeader(const SMS_UDH_S header, char *pEncodeHeader)
501 int offset = 0, addrLen = 0;
503 char* encodedAddr = NULL;
504 AutoPtr<char> addressBuf(&encodedAddr);
506 switch (header.udhType)
508 case SMS_UDH_CONCAT_8BIT :
510 pEncodeHeader[offset++] = SMS_UDH_CONCAT_8BIT;
513 pEncodeHeader[offset++] = 0x03;
516 pEncodeHeader[offset++] = header.udh.concat8bit.msgRef;
518 // Number of Segments
519 pEncodeHeader[offset++] = header.udh.concat8bit.totalSeg;
522 pEncodeHeader[offset++] = header.udh.concat8bit.seqNum;
525 case SMS_UDH_CONCAT_16BIT :
527 pEncodeHeader[offset++] = SMS_UDH_CONCAT_16BIT;
530 pEncodeHeader[offset++] = 0x04;
533 pEncodeHeader[offset++] = (char)(header.udh.concat16bit.msgRef >> 8);
534 pEncodeHeader[offset++] = header.udh.concat16bit.msgRef & 0x00FF;
536 // Number of Segments
537 pEncodeHeader[offset++] = header.udh.concat16bit.totalSeg;
540 pEncodeHeader[offset++] = header.udh.concat16bit.seqNum;
543 case SMS_UDH_APP_PORT_8BIT :
545 pEncodeHeader[offset++] = SMS_UDH_APP_PORT_8BIT;
548 pEncodeHeader[offset++] = 0x02;
551 pEncodeHeader[offset++] = header.udh.appPort8bit.destPort;
554 pEncodeHeader[offset++] = header.udh.appPort8bit.originPort;
557 case SMS_UDH_APP_PORT_16BIT :
559 pEncodeHeader[offset++] = SMS_UDH_APP_PORT_16BIT;
562 pEncodeHeader[offset++] = 0x04;
565 pEncodeHeader[offset++] = (char)(header.udh.appPort16bit.destPort >> 8);
566 pEncodeHeader[offset++] = header.udh.appPort16bit.destPort & 0x00FF;
569 pEncodeHeader[offset++] = (char)(header.udh.appPort16bit.originPort >> 8);
570 pEncodeHeader[offset++] = header.udh.appPort16bit.originPort & 0x00FF;
573 case SMS_UDH_ALTERNATE_REPLY_ADDRESS :
575 pEncodeHeader[offset++] = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
577 addrLen = SmsPluginParamCodec::encodeAddress(&(header.udh.alternateAddress), &encodedAddr);
580 pEncodeHeader[offset++] = addrLen;
582 // Alternate Reply Address
583 memcpy(&pEncodeHeader[offset], encodedAddr, addrLen);
588 case SMS_UDH_SINGLE_SHIFT :
590 pEncodeHeader[offset++] = SMS_UDH_SINGLE_SHIFT;
593 pEncodeHeader[offset++] = 0x01;
595 // National Language Identifier
596 pEncodeHeader[offset++] = header.udh.singleShift.langId;
599 case SMS_UDH_LOCKING_SHIFT :
601 pEncodeHeader[offset++] = SMS_UDH_LOCKING_SHIFT;
604 pEncodeHeader[offset++] = 0x01;
606 // National Language Identifier
607 pEncodeHeader[offset++] = header.udh.lockingShift.langId;
619 int SmsPluginUDCodec::decodeHeader(const unsigned char *pTpdu, SMS_UDH_S *pHeader)
622 unsigned char IEDL = 0;
624 pHeader->udhType = pTpdu[offset++];
626 switch (pHeader->udhType)
628 case SMS_UDH_CONCAT_8BIT :
630 IEDL = pTpdu[offset++];
632 if (IEDL == 0) return 0;
634 pHeader->udh.concat8bit.msgRef = pTpdu[offset++];
635 pHeader->udh.concat8bit.totalSeg = pTpdu[offset++];
636 pHeader->udh.concat8bit.seqNum = pTpdu[offset++];
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);
644 case SMS_UDH_CONCAT_16BIT :
646 IEDL = pTpdu[offset++];
648 if (IEDL == 0) return 0;
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++];
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);
661 case SMS_UDH_APP_PORT_8BIT :
663 IEDL = pTpdu[offset++];
665 if (IEDL == 0) return 0;
667 pHeader->udh.appPort8bit.destPort = pTpdu[offset++];
668 pHeader->udh.appPort8bit.originPort = pTpdu[offset++];
670 MSG_DEBUG("appPort8bit.destPort [%02x]", pHeader->udh.appPort8bit.destPort);
671 MSG_DEBUG("appPort8bit.originPort [%02x]", pHeader->udh.appPort8bit.originPort);
675 case SMS_UDH_APP_PORT_16BIT :
677 IEDL = pTpdu[offset++];
679 if (IEDL == 0) return 0;
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++]);
686 MSG_DEBUG("appPort16bit.destPort [%04x]", pHeader->udh.appPort16bit.destPort);
687 MSG_DEBUG("appPort16bit.originPort [%04x]", pHeader->udh.appPort16bit.originPort);
691 case SMS_UDH_SPECIAL_SMS :
693 IEDL = pTpdu[offset++];
695 if (IEDL != 2) return 0;
696 MSG_DEBUG("Decoding special sms udh.");
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];
704 case SMS_UDH_ALTERNATE_REPLY_ADDRESS :
706 IEDL = pTpdu[offset++];
708 if (IEDL == 0) return 0;
710 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pHeader->udh.alternateAddress));
712 MSG_DEBUG("alternate reply address [%s]", pHeader->udh.alternateAddress.address);
716 case SMS_UDH_SINGLE_SHIFT :
718 IEDL = pTpdu[offset++];
720 if (IEDL == 0) return 0;
722 pHeader->udh.singleShift.langId = pTpdu[offset++];
724 MSG_DEBUG("singleShift.langId [%02x]", pHeader->udh.singleShift.langId);
728 case SMS_UDH_LOCKING_SHIFT :
730 IEDL = pTpdu[offset++];
732 if (IEDL == 0) return 0;
734 pHeader->udh.lockingShift.langId = pTpdu[offset++];
736 MSG_DEBUG("lockingShift.langId [%02x]", pHeader->udh.lockingShift.langId);
742 MSG_DEBUG("Not Supported Header Type [%02x]", pHeader->udhType);
744 IEDL = pTpdu[offset++];
746 MSG_DEBUG("IEDL [%d]", IEDL);
747 return (offset + IEDL);
756 int SmsPluginUDCodec::pack7bitChar(const unsigned char *pUserData, int dataLen, int fillBits, char *pPackData)
758 int srcIdx = 0, dstIdx = 0, shift = fillBits;
760 //MSG_DEBUG("dataLen = %d", dataLen);
765 while (srcIdx < dataLen)
769 // if (srcIdx > 0) srcIdx++;
771 //MSG_DEBUG("pUserData [%02x]", pUserData[srcIdx]);
772 //MSG_DEBUG("shift = %d", shift);
774 pPackData[dstIdx] = pUserData[srcIdx];
776 //MSG_DEBUG("pPackData [%02x]", pPackData[dstIdx]);
777 if (srcIdx >= dataLen) break;
786 //MSG_DEBUG("pUserData [%02x]", pUserData[srcIdx]);
788 //MSG_DEBUG("shift = %d", shift);
790 pPackData[dstIdx-1] |= pUserData[srcIdx] << shift;
791 pPackData[dstIdx] = pUserData[srcIdx] >> (8-shift);
793 //MSG_DEBUG("pPackData [%02x]", pPackData[dstIdx]);
800 //MSG_DEBUG("pUserData [%02x]", pUserData[srcIdx]);
801 //MSG_DEBUG("shift = %d", shift);
802 pPackData[dstIdx-1] |= pUserData[srcIdx] << shift;
804 //MSG_DEBUG("pPackData [%02x]", pPackData[dstIdx-1]);
812 //MSG_DEBUG("dstIdx = %d", dstIdx);
818 int SmsPluginUDCodec::unpack7bitChar(const unsigned char *pTpdu, unsigned char dataLen, int fillBits, char *pUnpackData)
820 int srcIdx = 0, dstIdx = 0, shift = fillBits;
822 MSG_DEBUG("dataLen = %d", dataLen);
827 for (; dstIdx < dataLen; dstIdx++)
831 //MSG_DEBUG("shift = %d", shift);
833 pUnpackData[dstIdx] = pTpdu[srcIdx] & 0x7F;
835 //MSG_DEBUG("UserData[%d] = %02x", dstIdx, pUnpackData[dstIdx]);
840 if (dstIdx >= dataLen) break;
845 //MSG_DEBUG("shift = %d", shift);
847 pUnpackData[dstIdx] = (pTpdu[srcIdx-1] >> shift) + (pTpdu[srcIdx] << (8 - shift));
849 pUnpackData[dstIdx] &= 0x7F;
851 //MSG_DEBUG("UserData[%d] = %02x", dstIdx, pUnpackData[dstIdx]);
855 if (shift > 0) srcIdx++;