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.
21 #include "MsgCppTypes.h"
22 #include "MsgException.h"
23 #include "MsgGconfWrapper.h"
25 #include "SmsPluginTpduCodec.h"
26 #include "SmsPluginParamCodec.h"
27 #include "SmsPluginUDCodec.h"
30 /*==================================================================================================
31 IMPLEMENTATION OF SmsPluginTpduCodec - Member Functions
32 ==================================================================================================*/
33 SmsPluginTpduCodec::SmsPluginTpduCodec()
40 SmsPluginTpduCodec::~SmsPluginTpduCodec()
47 int SmsPluginTpduCodec::encodeTpdu(const SMS_TPDU_S *pSmsTpdu, char *pTpdu)
51 switch (pSmsTpdu->tpduType) {
53 tpduLen = encodeSubmit(&(pSmsTpdu->data.submit), pTpdu);
56 case SMS_TPDU_DELIVER:
57 tpduLen = encodeDeliver(&(pSmsTpdu->data.deliver), pTpdu);
60 case SMS_TPDU_DELIVER_REP:
61 tpduLen = encodeDeliverReport(&(pSmsTpdu->data.deliverRep), pTpdu);
64 case SMS_TPDU_STATUS_REP:
65 tpduLen = encodeStatusReport(&(pSmsTpdu->data.statusRep), pTpdu);
73 int SmsPluginTpduCodec::decodeTpdu(const unsigned char *pTpdu, int TpduLen, SMS_TPDU_S *pSmsTpdu)
77 char mti = pTpdu[0] & 0x03;
81 pSmsTpdu->tpduType = SMS_TPDU_DELIVER;
82 decodeLen = decodeDeliver(pTpdu, TpduLen, &(pSmsTpdu->data.deliver));
86 pSmsTpdu->tpduType = SMS_TPDU_SUBMIT;
87 decodeLen = decodeSubmit(pTpdu, TpduLen, &(pSmsTpdu->data.submit));
91 pSmsTpdu->tpduType = SMS_TPDU_STATUS_REP;
92 decodeLen = decodeStatusReport(pTpdu, TpduLen, &(pSmsTpdu->data.statusRep));
100 int SmsPluginTpduCodec::encodeSubmit(const SMS_SUBMIT_S *pSubmit, char *pTpdu)
102 int offset = 0, length = 0, encodeSize = 0;
104 char* address = NULL;
105 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
108 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
111 unique_ptr<char*, void(*)(char**)> vpBuf(&vpTime, unique_ptr_deleter);
114 pTpdu[offset] = 0x01;
117 if (pSubmit->bRejectDup == true)
118 pTpdu[offset] |= 0x04;
121 switch (pSubmit->vpf) {
122 case SMS_VPF_NOT_PRESENT:
124 case SMS_VPF_ENHANCED:
125 pTpdu[offset] |= 0x08;
127 case SMS_VPF_RELATIVE:
128 pTpdu[offset] |= 0x10;
130 case SMS_VPF_ABSOLUTE:
131 pTpdu[offset] |= 0x18;
138 if (pSubmit->bStatusReport == true)
139 pTpdu[offset] |= 0x20;
141 MSG_DEBUG("TP-SRR pSubmit->bStatusReport : %d.", pSubmit->bStatusReport);
144 if (pSubmit->bHeaderInd == true)
145 pTpdu[offset] |= 0x40;
148 if (pSubmit->bReplyPath == true)
149 pTpdu[offset] |= 0x80;
154 pTpdu[offset++] = pSubmit->msgRef;
156 MSG_DEBUG("TP-MR pSubmit->msgRef : %d.", pSubmit->msgRef);
159 length = SmsPluginParamCodec::encodeAddress(&pSubmit->destAddress, &address);
160 memcpy(&(pTpdu[offset]), address, length);
163 MSG_DEBUG("TP-DA length : %d.", length);
166 pTpdu[offset++] = pSubmit->pid;
168 MSG_DEBUG("TP-PID pSubmit->pid : %d.", pSubmit->pid);
171 length = SmsPluginParamCodec::encodeDCS(&pSubmit->dcs, &dcs);
172 memcpy(&(pTpdu[offset]), dcs, length);
175 MSG_DEBUG("TP-DCS length : %d.", length);
178 if (pSubmit->vpf != SMS_VPF_NOT_PRESENT) {
179 length = SmsPluginParamCodec::encodeTime(&pSubmit->validityPeriod, &vpTime);
182 memcpy(&(pTpdu[offset]), vpTime, length);
187 encodeSize = SmsPluginUDCodec::encodeUserData(&(pSubmit->userData), pSubmit->dcs.codingScheme, &(pTpdu[offset]));
189 MSG_DEBUG("encodeSize : %d", encodeSize);
191 offset += encodeSize;
194 printf("\n\n[encodeSubmit] pTpdu data.\n");
195 for (int i = 0; i < offset; i++)
197 printf(" [%02x]", pTpdu[i]);
206 int SmsPluginTpduCodec::encodeDeliver(const SMS_DELIVER_S *pDeliver, char *pTpdu)
208 int offset = 0, length = 0, encodeSize = 0;
210 char* address = NULL;
211 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
214 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
217 unique_ptr<char*, void(*)(char**)> timeBuf(&scts, unique_ptr_deleter);
220 pTpdu[offset] = 0x00;
223 if (pDeliver->bMoreMsg == false)
224 pTpdu[offset] |= 0x04;
227 if (pDeliver->bStatusReport == true)
228 pTpdu[offset] |= 0x20;
231 if (pDeliver->bHeaderInd == true)
232 pTpdu[offset] |= 0x40;
235 if (pDeliver->bReplyPath == true)
236 pTpdu[offset] |= 0x80;
241 length = SmsPluginParamCodec::encodeAddress(&pDeliver->originAddress, &address);
242 memcpy(&(pTpdu[offset]), address, length);
246 pTpdu[offset++] = pDeliver->pid;
249 length = SmsPluginParamCodec::encodeDCS(&pDeliver->dcs, &dcs);
250 memcpy(&(pTpdu[offset]), dcs, length);
254 length = SmsPluginParamCodec::encodeTime(&pDeliver->timeStamp, &scts);
255 memcpy(&(pTpdu[offset]), scts, length);
259 encodeSize = SmsPluginUDCodec::encodeUserData(&(pDeliver->userData), pDeliver->dcs.codingScheme, &(pTpdu[offset]));
261 MSG_DEBUG("encodeSize : %d", encodeSize);
263 offset += encodeSize;
269 int SmsPluginTpduCodec::encodeDeliverReport(const SMS_DELIVER_REPORT_S *pDeliverRep, char *pTpdu)
274 pTpdu[offset] = 0x00;
277 if (pDeliverRep->bHeaderInd == true)
278 pTpdu[offset] |= 0x40;
283 if (pDeliverRep->reportType == SMS_REPORT_NEGATIVE) {
284 pTpdu[offset++] = pDeliverRep->failCause;
285 MSG_DEBUG("Delivery report : fail cause = [%02x]", pDeliverRep->failCause);
289 pTpdu[offset++] = pDeliverRep->paramInd;
292 if (pDeliverRep->paramInd & 0x01)
293 pTpdu[offset++] = pDeliverRep->pid;
296 if (pDeliverRep->paramInd & 0x02) {
300 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
302 length = SmsPluginParamCodec::encodeDCS(&pDeliverRep->dcs, &dcs);
303 memcpy(&(pTpdu[offset]), dcs, length);
309 if (pDeliverRep->paramInd & 0x04) {
312 encodeSize = SmsPluginUDCodec::encodeUserData(&(pDeliverRep->userData), pDeliverRep->dcs.codingScheme, &(pTpdu[offset]));
314 MSG_DEBUG("encodeSize : %d", encodeSize);
316 offset += encodeSize;
319 pTpdu[offset] = '\0';
325 int SmsPluginTpduCodec::encodeStatusReport(const SMS_STATUS_REPORT_S *pStatusRep, char *pTpdu)
327 int offset = 0, length = 0;
329 char* address = NULL;
330 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
333 unique_ptr<char*, void(*)(char**)> sctsBuf(&scts, unique_ptr_deleter);
336 unique_ptr<char*, void(*)(char**)> dtBuf(&dt, unique_ptr_deleter);
339 pTpdu[offset] = 0x02;
342 if (pStatusRep->bMoreMsg == true)
343 pTpdu[offset] |= 0x04;
346 if (pStatusRep->bStatusReport == true)
347 pTpdu[offset] |= 0x20;
350 if (pStatusRep->bHeaderInd == true)
351 pTpdu[offset] |= 0x40;
356 pTpdu[offset++] = pStatusRep->msgRef;
359 length = SmsPluginParamCodec::encodeAddress(&pStatusRep->recipAddress, &address);
360 memcpy(&(pTpdu[offset]), address, length);
364 length = SmsPluginParamCodec::encodeTime(&pStatusRep->timeStamp, &scts);
365 memcpy(&(pTpdu[offset]), scts, length);
369 length = SmsPluginParamCodec::encodeTime(&pStatusRep->dischargeTime, &dt);
370 memcpy(&(pTpdu[offset]), dt, length);
374 pTpdu[offset++] = pStatusRep->status;
377 pTpdu[offset++] = pStatusRep->paramInd;
380 if (pStatusRep->paramInd & 0x01)
381 pTpdu[offset++] = pStatusRep->pid;
384 if (pStatusRep->paramInd & 0x02) {
388 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
390 length = SmsPluginParamCodec::encodeDCS(&pStatusRep->dcs, &dcs);
391 memcpy(&(pTpdu[offset]), dcs, length);
397 if (pStatusRep->paramInd & 0x04) {
400 encodeSize = SmsPluginUDCodec::encodeUserData(&(pStatusRep->userData), pStatusRep->dcs.codingScheme, &(pTpdu[offset]));
402 MSG_DEBUG("encodeSize : %d", encodeSize);
404 offset += encodeSize;
407 pTpdu[offset] = '\0';
413 int SmsPluginTpduCodec::decodeSubmit(const unsigned char *pTpdu, int TpduLen, SMS_SUBMIT_S *pSubmit)
415 int offset = 0, udLen = 0;
417 char tpduTmp[(TpduLen*2)+1];
418 memset(tpduTmp, 0x00, sizeof(tpduTmp));
419 for (int i = 0; i < TpduLen; i++) {
420 snprintf(tpduTmp+(i*2), sizeof(tpduTmp)-(i*2), "%02X", pTpdu[i]);
422 MSG_DEBUG("Sumbit TPDU.");
423 MSG_INFO("[%s]", tpduTmp);
426 if (pTpdu[offset] & 0x04)
427 pSubmit->bRejectDup = false;
429 pSubmit->bRejectDup = true;
432 pSubmit->vpf = (SMS_VPF_T)(pTpdu[offset] & 0x18);
435 if (pTpdu[offset] & 0x20)
436 pSubmit->bStatusReport = true;
438 pSubmit->bStatusReport = false;
441 if (pTpdu[offset] & 0x40)
442 pSubmit->bHeaderInd = true;
444 pSubmit->bHeaderInd = false;
447 if (pTpdu[offset] & 0x80)
448 pSubmit->bReplyPath = true;
450 pSubmit->bReplyPath = false;
455 pSubmit->msgRef = pTpdu[offset++];
458 offset += SmsPluginParamCodec::decodeAddress(pTpdu+offset, &(pSubmit->destAddress));
461 pSubmit->pid = pTpdu[offset++];
464 offset += SmsPluginParamCodec::decodeDCS(pTpdu+offset, &(pSubmit->dcs));
467 if (pSubmit->vpf != SMS_VPF_NOT_PRESENT) {
472 udLen = SmsPluginUDCodec::decodeUserData(pTpdu+offset, TpduLen, pSubmit->bHeaderInd, pSubmit->dcs.codingScheme, &(pSubmit->userData));
478 int SmsPluginTpduCodec::decodeDeliver(const unsigned char *pTpdu, int TpduLen, SMS_DELIVER_S *pDeliver)
480 int offset = 0, udLen = 0, tmpOffset = 0;
483 char tpduTmp[(TpduLen*2)+1];
484 memset(tpduTmp, 0x00, sizeof(tpduTmp));
485 for (int i = 0; i < TpduLen; i++) {
486 snprintf(tpduTmp+(i*2), sizeof(tpduTmp)-(i*2), "%02X", pTpdu[i]);
488 MSG_DEBUG("Deliver TPDU.");
489 MSG_INFO("[%s]", tpduTmp);
493 if (pTpdu[offset] & 0x04)
494 pDeliver->bMoreMsg = false;
496 pDeliver->bMoreMsg = true;
499 if (pTpdu[offset] & 0x20)
500 pDeliver->bStatusReport = true;
502 pDeliver->bStatusReport = false;
505 if (pTpdu[offset] & 0x40)
506 pDeliver->bHeaderInd = true;
508 pDeliver->bHeaderInd = false;
511 if (pTpdu[offset] & 0x80)
512 pDeliver->bReplyPath = true;
514 pDeliver->bReplyPath = false;
521 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pDeliver->originAddress));
524 pDeliver->pid = pTpdu[offset++];
527 offset += SmsPluginParamCodec::decodeDCS(&pTpdu[offset], &(pDeliver->dcs));
529 /* Support KSC5601 :: Coding group bits == 0x84 */
530 if (pTpdu[offset-1] == 0x84) {
531 pDeliver->dcs.codingScheme = SMS_CHARSET_EUCKR;
535 //For alphanumeric address test
537 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pDeliver->originAddress));
539 char* address = new char[15];
556 SmsPluginParamCodec::decodeAddress((unsigned char*)address, &(pDeliver->originAddress));
558 pDeliver->pid = 0x20;
560 offset += SmsPluginParamCodec::decodeDCS((unsigned char*)address, &(pDeliver->dcs));
564 if (pDeliver->pid == 0x20 && pDeliver->originAddress.ton == SMS_TON_ALPHANUMERIC) {
568 bool bVmi = SmsPluginParamCodec::checkCphsVmiMsg(&pTpdu[tmpOffset], &setType, &indType);
570 MSG_DEBUG("bVmi = [%d], setType=[%d], indType=[%d]", bVmi, setType, indType);
573 pDeliver->dcs.bMWI = true;
576 pDeliver->dcs.bIndActive = false;
578 pDeliver->dcs.bIndActive = true;
582 pDeliver->dcs.indType = SMS_VOICE_INDICATOR;
583 else if (indType == 1)
584 pDeliver->dcs.indType = SMS_VOICE2_INDICATOR;
589 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pDeliver->timeStamp));
592 udLen = SmsPluginUDCodec::decodeUserData(&pTpdu[offset], TpduLen, pDeliver->bHeaderInd, pDeliver->dcs.codingScheme, &(pDeliver->userData), &(pDeliver->udData));
598 int SmsPluginTpduCodec::decodeStatusReport(const unsigned char *pTpdu, int TpduLen, SMS_STATUS_REPORT_S *pStatusRep)
601 printf("\n\n[decodeStatusReport] pTpdu data - Length [%d]\n", TpduLen);
603 for (int i = 0; i < TpduLen; i++)
605 printf(" [%02x]", pTpdu[i]);
610 int offset = 0, udLen = 0;
612 char* address = NULL;
613 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
616 unique_ptr<char*, void(*)(char**)> sctsBuf(&scts, unique_ptr_deleter);
619 unique_ptr<char*, void(*)(char**)> dtBuf(&dt, unique_ptr_deleter);
622 if (pTpdu[offset] & 0x04)
623 pStatusRep->bMoreMsg = false;
625 pStatusRep->bMoreMsg = true;
628 if (pTpdu[offset] & 0x20)
629 pStatusRep->bStatusReport = true;
631 pStatusRep->bStatusReport = false;
634 if (pTpdu[offset] & 0x40)
635 pStatusRep->bHeaderInd = true;
637 pStatusRep->bHeaderInd = false;
642 pStatusRep->msgRef = pTpdu[offset++];
645 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pStatusRep->recipAddress));
648 /* Decode timestamp */
649 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pStatusRep->timeStamp));
652 /* Decode timestamp */
653 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pStatusRep->dischargeTime));
656 pStatusRep->status = pTpdu[offset++];
659 pStatusRep->paramInd = pTpdu[offset++];
662 if (pStatusRep->paramInd == 0) {
663 pStatusRep->pid = SMS_PID_NORMAL;
665 pStatusRep->dcs.bCompressed = false;
666 pStatusRep->dcs.bMWI = false;
667 pStatusRep->dcs.bIndActive = false;
669 pStatusRep->dcs.msgClass = MSG_CLASS_NONE;
670 pStatusRep->dcs.codingScheme = SMS_CHARSET_7BIT;
671 pStatusRep->dcs.codingGroup = SMS_GROUP_GENERAL;
672 pStatusRep->dcs.indType = SMS_OTHER_INDICATOR;
674 pStatusRep->userData.headerCnt = 0;
675 pStatusRep->userData.length = 0;
676 memset(pStatusRep->userData.data, 0x00, MAX_USER_DATA_LEN+1);
680 if (pStatusRep->paramInd & 0x01)
681 pStatusRep->pid = pTpdu[offset++];
684 if (pStatusRep->paramInd & 0x02)
685 offset += SmsPluginParamCodec::decodeDCS(&pTpdu[offset], &(pStatusRep->dcs));
688 if (pStatusRep->paramInd & 0x04)
689 /* Decode User Data */
690 udLen = SmsPluginUDCodec::decodeUserData(&pTpdu[offset], TpduLen, pStatusRep->bHeaderInd, pStatusRep->dcs.codingScheme, &(pStatusRep->userData));