2 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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"
24 /*==================================================================================================
25 IMPLEMENTATION OF SmsPluginUDCodec - Member Functions
26 ==================================================================================================*/
27 SmsPluginUDCodec::SmsPluginUDCodec()
32 SmsPluginUDCodec::~SmsPluginUDCodec()
37 int SmsPluginUDCodec::encodeUserData(const SMS_USERDATA_S *pUserData, SMS_CODING_SCHEME_T CodingScheme, char *pEncodeData)
41 switch (CodingScheme) {
42 case SMS_CHARSET_7BIT:
43 encodeSize = encodeGSMData(pUserData, pEncodeData);
45 case SMS_CHARSET_8BIT:
46 encodeSize = encode8bitData(pUserData, pEncodeData);
48 case SMS_CHARSET_UCS2:
49 encodeSize = encodeUCS2Data(pUserData, pEncodeData);
57 int SmsPluginUDCodec::decodeUserData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_CODING_SCHEME_T CodingScheme, SMS_USERDATA_S *pUserData)
61 memset(pUserData, 0x00, sizeof(SMS_USERDATA_S));
63 switch (CodingScheme) {
64 case SMS_CHARSET_7BIT:
65 decodeSize = decodeGSMData(pTpdu, tpduLen, bHeaderInd, pUserData, NULL);
67 case SMS_CHARSET_8BIT:
68 decodeSize = decode8bitData(pTpdu, bHeaderInd, pUserData, NULL);
70 case SMS_CHARSET_UCS2:
71 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, NULL);
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)
83 memset(pUserData, 0x00, sizeof(SMS_USERDATA_S));
85 switch (CodingScheme) {
86 case SMS_CHARSET_7BIT:
87 decodeSize = decodeGSMData(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
89 case SMS_CHARSET_8BIT:
90 decodeSize = decode8bitData(pTpdu, bHeaderInd, pUserData, pTPUD);
92 case SMS_CHARSET_UCS2:
93 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
95 case SMS_CHARSET_EUCKR:
96 decodeSize = decodeUCS2Data(pTpdu, tpduLen, bHeaderInd, pUserData, pTPUD);
104 int SmsPluginUDCodec::encodeGSMData(const SMS_USERDATA_S *pUserData, char *pEncodeData)
106 int headerLen = 0, offset = 0, fillBits = 0, packSize = 0, encodeLen = 0;
107 unsigned char udhl = 0x00;
109 if (pUserData->headerCnt > 0)
114 MSG_DEBUG("pUserData->headerCnt [%d]", pUserData->headerCnt);
116 /* Encode User Data Header */
117 for (int i = 0; i < pUserData->headerCnt; i++) {
118 headerLen = encodeHeader(pUserData->header[i], &(pEncodeData[offset]));
120 MSG_DEBUG("headerLen [%d]", headerLen);
126 MSG_DEBUG("udhl [%d]", udhl);
129 fillBits = ((udhl+1)*8)%7; /* + UDHL */
132 fillBits = 7 - fillBits;
134 MSG_DEBUG("fillBits [%d]", fillBits);
135 MSG_DEBUG("dataLen [%d]", pUserData->length);
139 pEncodeData[0] = (((udhl+1)*8) + fillBits + (pUserData->length*7)) / 7;
140 pEncodeData[1] = udhl;
142 pEncodeData[0] = (char)pUserData->length;
145 packSize = pack7bitChar((unsigned char*)pUserData->data, pUserData->length, fillBits, &(pEncodeData[offset]));
147 encodeLen = offset + packSize;
149 MSG_DEBUG("packSize [%d]", packSize);
150 MSG_DEBUG("encodeLen [%d]", encodeLen);
153 printf("\n\n[encodeGSMData] userData data.\n");
154 for (int j = 0; j < encodeLen; j++)
156 printf(" [%02x]", pEncodeData[j]);
165 int SmsPluginUDCodec::encode8bitData(const SMS_USERDATA_S *pUserData, char *pEncodeData)
167 int headerLen = 0, offset = 2, fillBits = 0, encodeLen = 0;
168 unsigned char udhl = 0x00;
170 if (pUserData->headerCnt > 0)
175 /* Encode User Data Header */
176 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);
188 pEncodeData[0] = (udhl+1) + fillBits + pUserData->length;
189 pEncodeData[1] = udhl;
191 pEncodeData[0] = (char)pUserData->length;
194 memcpy(&(pEncodeData[offset]), pUserData->data, pUserData->length);
196 encodeLen = offset + pUserData->length;
202 int SmsPluginUDCodec::encodeUCS2Data(const SMS_USERDATA_S *pUserData, char *pEncodeData)
204 int headerLen = 0, offset = 2, fillBits = 0, encodeLen = 0;
205 unsigned char udhl = 0x00;
207 if (pUserData->headerCnt > 0)
212 /* Encode User Data Header */
213 for (int i = 0; i < pUserData->headerCnt; i++) {
214 headerLen = encodeHeader(pUserData->header[i], &(pEncodeData[offset]));
220 MSG_DEBUG("fillBits [%d]", fillBits);
221 MSG_DEBUG("dataLen [%d]", pUserData->length);
225 pEncodeData[0] = (udhl+1) + fillBits + pUserData->length;
226 pEncodeData[1] = udhl;
228 pEncodeData[0] = (char)pUserData->length;
231 memcpy(&(pEncodeData[offset]), pUserData->data, pUserData->length);
233 encodeLen = offset + pUserData->length;
236 printf("\n\n[encodeUCS2Data] userData data.\n");
237 for (int j = 0; j < encodeLen; j++)
239 printf(" [%02x]", pEncodeData[j]);
248 int SmsPluginUDCodec::decodeGSMData(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
250 int offset = 0, udl = 0, udhl = 0, headerLen = 0, fillBits = 0, octetUdl = 0;
253 udl = pTpdu[offset++];
254 octetUdl = (udl*7)/8;
256 MSG_DEBUG("udl = %d, tpdulen = %d, octetUdl = %d.", udl, tpduLen, octetUdl);
257 MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
259 if (udl > MAX_GSM_7BIT_DATA_LEN || octetUdl > tpduLen) {
260 pUserData->length = 0;
261 pUserData->headerCnt = 0;
265 /* 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) {
276 udhl = pTpdu[offset++];
278 MSG_DEBUG("udhl = %d", udhl);
280 pUserData->headerCnt = 0;
282 for (int i = 0; offset < udhl; i++) {
283 headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
285 if (headerLen <= 0) {
286 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
288 pUserData->length = 0;
289 memset(pUserData->data, 0x00, sizeof(pUserData->data));
296 if (offset > (udhl+2)) {
297 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
299 pUserData->length = 0;
300 memset(pUserData->data, 0x00, sizeof(pUserData->data));
305 pUserData->headerCnt++;
308 pUserData->headerCnt = 0;
311 MSG_DEBUG("headerCnt = %d", pUserData->headerCnt);
314 fillBits = ((udl*7) - ((udhl+1)*8)) % 7;
315 udl = ((udl*7) - ((udhl+1)*8)) / 7;
318 MSG_DEBUG("fillBits = %d", fillBits);
319 MSG_DEBUG("udhl = %d", udhl);
320 MSG_DEBUG("udl = %d", udl);
322 MSG_DEBUG("offset = %d", offset);
324 pUserData->length = unpack7bitChar(&(pTpdu[offset]), udl, fillBits, pUserData->data);
326 return pUserData->length;
330 int SmsPluginUDCodec::decode8bitData(const unsigned char *pTpdu, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
332 int offset = 0, udl = 0, udhl = 0, headerLen = 0;
335 udl = pTpdu[offset++];
337 if (udl > MAX_UCS2_DATA_LEN) {
338 pUserData->length = 0;
342 /* Setting for Wap Push */
346 memcpy(pTPUD->ud, &(pTpdu[offset]), udl);
347 pTPUD->ud[udl] = '\0';
350 MSG_DEBUG("udl = %d", udl);
351 MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
353 /* Decode User Data Header */
354 if (bHeaderInd == true) {
356 udhl = pTpdu[offset++];
358 MSG_DEBUG("udhl = %d", udhl);
360 pUserData->headerCnt = 0;
362 for (int i = 0; offset < udhl; i++) {
363 headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
365 if (headerLen <= 0) {
366 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
368 pUserData->length = 0;
369 memset(pUserData->data, 0x00, sizeof(pUserData->data));
376 if (offset > (udhl+2)) {
377 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
379 pUserData->length = 0;
380 memset(pUserData->data, 0x00, sizeof(pUserData->data));
385 pUserData->headerCnt++;
388 pUserData->headerCnt = 0;
391 MSG_DEBUG("headerCnt = %d", pUserData->headerCnt);
394 pUserData->length = (udl) - (udhl+1);
396 pUserData->length = udl;
398 MSG_DEBUG("pUserData->length = %d", pUserData->length);
399 MSG_DEBUG("offset = %d", offset);
401 memcpy(pUserData->data, &(pTpdu[offset]), pUserData->length);
403 return pUserData->length;
407 int SmsPluginUDCodec::decodeUCS2Data(const unsigned char *pTpdu, const int tpduLen, bool bHeaderInd, SMS_USERDATA_S *pUserData, SMS_TPUD_S *pTPUD)
409 int offset = 0, udl = 0, udhl = 0, headerLen = 0;
412 udl = pTpdu[offset++];
414 MSG_DEBUG("udl = %d, tpdulen = %d.", udl, tpduLen);
415 MSG_DEBUG("bHeaderInd = %d", bHeaderInd);
417 if (udl > MAX_UCS2_DATA_LEN || udl > tpduLen) {
418 pUserData->length = 0;
419 pUserData->headerCnt = 0;
423 /* Setting for Wap Push */
427 memcpy(pTPUD->ud, &(pTpdu[offset]), udl);
428 pTPUD->ud[udl] = '\0';
431 /* Decode User Data Header */
432 if (bHeaderInd == true) {
434 udhl = pTpdu[offset++];
436 MSG_DEBUG("udhl = %d", udhl);
438 pUserData->headerCnt = 0;
440 for (int i = 0; offset < udhl; i++) {
441 headerLen = decodeHeader(&(pTpdu[offset]), &(pUserData->header[i]));
443 if (headerLen <= 0) {
444 MSG_DEBUG("Error to decode User Data Header. headerLen [%d]", headerLen);
446 pUserData->length = 0;
447 memset(pUserData->data, 0x00, sizeof(pUserData->data));
454 if (offset > (udhl+2)) {
455 MSG_DEBUG("Error to decode User Data Header. offset [%d] > (udhl [%d] + 2)", offset, udhl);
457 pUserData->length = 0;
458 memset(pUserData->data, 0x00, sizeof(pUserData->data));
463 pUserData->headerCnt++;
466 pUserData->headerCnt = 0;
470 pUserData->length = (udl) - (udhl+1);
472 pUserData->length = udl;
474 MSG_DEBUG("pUserData->length = %d", pUserData->length);
475 MSG_DEBUG("offset = %d", offset);
477 memcpy(pUserData->data, &(pTpdu[offset]), pUserData->length);
478 pUserData->data[pUserData->length] = 0;
480 return pUserData->length;
484 int SmsPluginUDCodec::encodeHeader(const SMS_UDH_S header, char *pEncodeHeader)
486 int offset = 0, addrLen = 0;
488 char* encodedAddr = NULL;
489 unique_ptr<char*, void(*)(char**)> addressBuf(&encodedAddr, unique_ptr_deleter);
491 switch (header.udhType) {
492 case SMS_UDH_CONCAT_8BIT :
494 pEncodeHeader[offset++] = SMS_UDH_CONCAT_8BIT;
497 pEncodeHeader[offset++] = 0x03;
499 /* Reference Number */
500 pEncodeHeader[offset++] = header.udh.concat8bit.msgRef;
502 /* Number of Segments */
503 pEncodeHeader[offset++] = header.udh.concat8bit.totalSeg;
505 /* Sequence Number */
506 pEncodeHeader[offset++] = header.udh.concat8bit.seqNum;
510 case SMS_UDH_CONCAT_16BIT :
512 pEncodeHeader[offset++] = SMS_UDH_CONCAT_16BIT;
515 pEncodeHeader[offset++] = 0x04;
517 /* Reference Number */
518 pEncodeHeader[offset++] = (char)(header.udh.concat16bit.msgRef >> 8);
519 pEncodeHeader[offset++] = header.udh.concat16bit.msgRef & 0x00FF;
521 /* Number of Segments */
522 pEncodeHeader[offset++] = header.udh.concat16bit.totalSeg;
524 /* Sequence Number */
525 pEncodeHeader[offset++] = header.udh.concat16bit.seqNum;
529 case SMS_UDH_APP_PORT_8BIT :
531 pEncodeHeader[offset++] = SMS_UDH_APP_PORT_8BIT;
534 pEncodeHeader[offset++] = 0x02;
537 pEncodeHeader[offset++] = header.udh.appPort8bit.destPort;
540 pEncodeHeader[offset++] = header.udh.appPort8bit.originPort;
544 case SMS_UDH_APP_PORT_16BIT :
546 pEncodeHeader[offset++] = SMS_UDH_APP_PORT_16BIT;
549 pEncodeHeader[offset++] = 0x04;
552 pEncodeHeader[offset++] = (char)(header.udh.appPort16bit.destPort >> 8);
553 pEncodeHeader[offset++] = header.udh.appPort16bit.destPort & 0x00FF;
556 pEncodeHeader[offset++] = (char)(header.udh.appPort16bit.originPort >> 8);
557 pEncodeHeader[offset++] = header.udh.appPort16bit.originPort & 0x00FF;
561 case SMS_UDH_ALTERNATE_REPLY_ADDRESS :
563 pEncodeHeader[offset++] = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
565 addrLen = SmsPluginParamCodec::encodeAddress(&(header.udh.alternateAddress), &encodedAddr);
568 pEncodeHeader[offset++] = addrLen;
570 /* Alternate Reply Address */
571 memcpy(&pEncodeHeader[offset], encodedAddr, addrLen);
577 case SMS_UDH_SINGLE_SHIFT :
579 pEncodeHeader[offset++] = SMS_UDH_SINGLE_SHIFT;
582 pEncodeHeader[offset++] = 0x01;
584 /* National Language Identifier */
585 pEncodeHeader[offset++] = header.udh.singleShift.langId;
589 case SMS_UDH_LOCKING_SHIFT :
591 pEncodeHeader[offset++] = SMS_UDH_LOCKING_SHIFT;
594 pEncodeHeader[offset++] = 0x01;
596 /* National Language Identifier */
597 pEncodeHeader[offset++] = header.udh.lockingShift.langId;
610 int SmsPluginUDCodec::decodeHeader(const unsigned char *pTpdu, SMS_UDH_S *pHeader)
613 unsigned char IEDL = 0;
615 pHeader->udhType = pTpdu[offset++];
617 switch (pHeader->udhType) {
618 case SMS_UDH_CONCAT_8BIT: {
619 IEDL = pTpdu[offset++];
624 pHeader->udh.concat8bit.msgRef = pTpdu[offset++];
625 pHeader->udh.concat8bit.totalSeg = pTpdu[offset++];
626 pHeader->udh.concat8bit.seqNum = pTpdu[offset++];
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);
634 case SMS_UDH_CONCAT_16BIT: {
635 IEDL = pTpdu[offset++];
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++];
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);
651 case SMS_UDH_APP_PORT_8BIT: {
652 IEDL = pTpdu[offset++];
657 pHeader->udh.appPort8bit.destPort = pTpdu[offset++];
658 pHeader->udh.appPort8bit.originPort = pTpdu[offset++];
660 MSG_DEBUG("appPort8bit.destPort [%02x]", pHeader->udh.appPort8bit.destPort);
661 MSG_DEBUG("appPort8bit.originPort [%02x]", pHeader->udh.appPort8bit.originPort);
665 case SMS_UDH_APP_PORT_16BIT: {
666 IEDL = pTpdu[offset++];
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++]);
676 MSG_DEBUG("appPort16bit.destPort [%04x]", pHeader->udh.appPort16bit.destPort);
677 MSG_DEBUG("appPort16bit.originPort [%04x]", pHeader->udh.appPort16bit.originPort);
681 case SMS_UDH_SPECIAL_SMS: {
682 IEDL = pTpdu[offset++];
687 MSG_DEBUG("Decoding special sms udh.");
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];
695 case SMS_UDH_ALTERNATE_REPLY_ADDRESS: {
696 IEDL = pTpdu[offset++];
701 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pHeader->udh.alternateAddress));
703 MSG_SEC_DEBUG("alternate reply address [%s]", pHeader->udh.alternateAddress.address);
707 case SMS_UDH_SINGLE_SHIFT: {
708 IEDL = pTpdu[offset++];
713 pHeader->udh.singleShift.langId = pTpdu[offset++];
715 MSG_DEBUG("singleShift.langId [%02x]", pHeader->udh.singleShift.langId);
719 case SMS_UDH_LOCKING_SHIFT: {
720 IEDL = pTpdu[offset++];
725 pHeader->udh.lockingShift.langId = pTpdu[offset++];
727 MSG_DEBUG("lockingShift.langId [%02x]", pHeader->udh.lockingShift.langId);
732 MSG_DEBUG("Not Supported Header Type [%02x]", pHeader->udhType);
734 IEDL = pTpdu[offset++];
736 MSG_DEBUG("IEDL [%d]", IEDL);
737 return (offset + IEDL);
746 int SmsPluginUDCodec::pack7bitChar(const unsigned char *pUserData, int dataLen, int fillBits, char *pPackData)
748 int srcIdx = 0, dstIdx = 0, shift = fillBits;
753 while (srcIdx < dataLen) {
755 pPackData[dstIdx] = pUserData[srcIdx];
761 if (srcIdx >= dataLen)
766 pPackData[dstIdx-1] |= pUserData[srcIdx] << shift;
767 pPackData[dstIdx] = pUserData[srcIdx] >> (8-shift);
772 } else if (shift == 1) {
773 pPackData[dstIdx-1] |= pUserData[srcIdx] << shift;
785 int SmsPluginUDCodec::unpack7bitChar(const unsigned char *pTpdu, unsigned char dataLen, int fillBits, char *pUnpackData)
787 int srcIdx = 0, dstIdx = 0, shift = fillBits;
789 MSG_DEBUG("dataLen = %d", dataLen);
794 for (; dstIdx < dataLen; dstIdx++) {
796 pUnpackData[dstIdx] = pTpdu[srcIdx] & 0x7F;
802 if (dstIdx >= dataLen)
807 pUnpackData[dstIdx] = (pTpdu[srcIdx-1] >> shift) + (pTpdu[srcIdx] << (8 - shift));
809 pUnpackData[dstIdx] &= 0x7F;