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)
54 tpduLen = encodeSubmit(&(pSmsTpdu->data.submit), pTpdu);
57 case SMS_TPDU_DELIVER:
58 tpduLen = encodeDeliver(&(pSmsTpdu->data.deliver), pTpdu);
61 case SMS_TPDU_DELIVER_REP:
62 tpduLen = encodeDeliverReport(&(pSmsTpdu->data.deliverRep), pTpdu);
65 case SMS_TPDU_STATUS_REP:
66 tpduLen = encodeStatusReport(&(pSmsTpdu->data.statusRep), pTpdu);
74 int SmsPluginTpduCodec::decodeTpdu(const unsigned char *pTpdu, int TpduLen, SMS_TPDU_S *pSmsTpdu)
78 char mti = pTpdu[0] & 0x03;
83 pSmsTpdu->tpduType = SMS_TPDU_DELIVER;
84 decodeLen = decodeDeliver(pTpdu, TpduLen, &(pSmsTpdu->data.deliver));
88 pSmsTpdu->tpduType = SMS_TPDU_SUBMIT;
89 decodeLen = decodeSubmit(pTpdu, TpduLen, &(pSmsTpdu->data.submit));
93 pSmsTpdu->tpduType = SMS_TPDU_STATUS_REP;
94 decodeLen = decodeStatusReport(pTpdu, TpduLen, &(pSmsTpdu->data.statusRep));
102 int SmsPluginTpduCodec::encodeSubmit(const SMS_SUBMIT_S *pSubmit, char *pTpdu)
104 int offset = 0, length = 0, encodeSize = 0;
106 char* address = NULL;
107 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
110 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
113 unique_ptr<char*, void(*)(char**)> vpBuf(&vpTime, unique_ptr_deleter);
116 pTpdu[offset] = 0x01;
119 if(pSubmit->bRejectDup == true)
120 pTpdu[offset] |= 0x04;
123 switch (pSubmit->vpf)
125 case SMS_VPF_NOT_PRESENT:
127 case SMS_VPF_ENHANCED:
128 pTpdu[offset] |= 0x08;
130 case SMS_VPF_RELATIVE:
131 pTpdu[offset] |= 0x10;
133 case SMS_VPF_ABSOLUTE:
134 pTpdu[offset] |= 0x18;
141 if (pSubmit->bStatusReport == true)
142 pTpdu[offset] |= 0x20;
144 MSG_DEBUG("TP-SRR pSubmit->bStatusReport : %d.", pSubmit->bStatusReport);
147 if (pSubmit->bHeaderInd == true)
148 pTpdu[offset] |= 0x40;
151 if (pSubmit->bReplyPath == true)
152 pTpdu[offset] |= 0x80;
157 pTpdu[offset++] = pSubmit->msgRef;
159 MSG_DEBUG("TP-MR pSubmit->msgRef : %d.", pSubmit->msgRef);
162 length = SmsPluginParamCodec::encodeAddress(&pSubmit->destAddress, &address);
163 memcpy(&(pTpdu[offset]), address, length);
166 MSG_DEBUG("TP-DA length : %d.", length);
169 pTpdu[offset++] = pSubmit->pid;
171 MSG_DEBUG("TP-PID pSubmit->pid : %d.", pSubmit->pid);
174 length = SmsPluginParamCodec::encodeDCS(&pSubmit->dcs, &dcs);
175 memcpy(&(pTpdu[offset]), dcs, length);
178 MSG_DEBUG("TP-DCS length : %d.", length);
181 if (pSubmit->vpf != SMS_VPF_NOT_PRESENT)
183 length = SmsPluginParamCodec::encodeTime(&pSubmit->validityPeriod, &vpTime);
187 memcpy(&(pTpdu[offset]), vpTime, length);
192 encodeSize = SmsPluginUDCodec::encodeUserData(&(pSubmit->userData), pSubmit->dcs.codingScheme, &(pTpdu[offset]));
194 MSG_DEBUG("encodeSize : %d", encodeSize);
196 offset += encodeSize;
199 printf("\n\n[encodeSubmit] pTpdu data.\n");
200 for (int i = 0; i < offset; i++)
202 printf(" [%02x]", pTpdu[i]);
211 int SmsPluginTpduCodec::encodeDeliver(const SMS_DELIVER_S *pDeliver, char *pTpdu)
213 int offset = 0, length = 0, encodeSize = 0;
215 char* address = NULL;
216 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
219 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
222 unique_ptr<char*, void(*)(char**)> timeBuf(&scts, unique_ptr_deleter);
225 pTpdu[offset] = 0x00;
228 if (pDeliver->bMoreMsg == false)
229 pTpdu[offset] |= 0x04;
232 if (pDeliver->bStatusReport == true)
233 pTpdu[offset] |= 0x20;
236 if (pDeliver->bHeaderInd == true)
237 pTpdu[offset] |= 0x40;
240 if (pDeliver->bReplyPath == true)
241 pTpdu[offset] |= 0x80;
246 length = SmsPluginParamCodec::encodeAddress(&pDeliver->originAddress, &address);
247 memcpy(&(pTpdu[offset]), address, length);
251 pTpdu[offset++] = pDeliver->pid;
254 length = SmsPluginParamCodec::encodeDCS(&pDeliver->dcs, &dcs);
255 memcpy(&(pTpdu[offset]), dcs, length);
259 length = SmsPluginParamCodec::encodeTime(&pDeliver->timeStamp, &scts);
260 memcpy(&(pTpdu[offset]), scts, length);
264 encodeSize = SmsPluginUDCodec::encodeUserData(&(pDeliver->userData), pDeliver->dcs.codingScheme, &(pTpdu[offset]));
266 MSG_DEBUG("encodeSize : %d", encodeSize);
268 offset += encodeSize;
274 int SmsPluginTpduCodec::encodeDeliverReport(const SMS_DELIVER_REPORT_S *pDeliverRep, char *pTpdu)
279 pTpdu[offset] = 0x00;
282 if (pDeliverRep->bHeaderInd == true)
283 pTpdu[offset] |= 0x40;
288 if (pDeliverRep->reportType == SMS_REPORT_NEGATIVE) {
289 pTpdu[offset++] = pDeliverRep->failCause;
290 MSG_DEBUG("Delivery report : fail cause = [%02x]", pDeliverRep->failCause);
294 pTpdu[offset++] = pDeliverRep->paramInd;
297 if (pDeliverRep->paramInd & 0x01)
298 pTpdu[offset++] = pDeliverRep->pid;
301 if (pDeliverRep->paramInd & 0x02)
306 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
308 length = SmsPluginParamCodec::encodeDCS(&pDeliverRep->dcs, &dcs);
309 memcpy(&(pTpdu[offset]), dcs, length);
315 if (pDeliverRep->paramInd & 0x04)
319 encodeSize = SmsPluginUDCodec::encodeUserData(&(pDeliverRep->userData), pDeliverRep->dcs.codingScheme, &(pTpdu[offset]));
321 MSG_DEBUG("encodeSize : %d", encodeSize);
323 offset += encodeSize;
326 pTpdu[offset] = '\0';
332 int SmsPluginTpduCodec::encodeStatusReport(const SMS_STATUS_REPORT_S *pStatusRep, char *pTpdu)
334 int offset = 0, length = 0;
336 char* address = NULL;
337 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
340 unique_ptr<char*, void(*)(char**)> sctsBuf(&scts, unique_ptr_deleter);
343 unique_ptr<char*, void(*)(char**)> dtBuf(&dt, unique_ptr_deleter);
346 pTpdu[offset] = 0x02;
349 if (pStatusRep->bMoreMsg == true)
350 pTpdu[offset] |= 0x04;
353 if (pStatusRep->bStatusReport == true)
354 pTpdu[offset] |= 0x20;
357 if (pStatusRep->bHeaderInd == true)
358 pTpdu[offset] |= 0x40;
363 pTpdu[offset++] = pStatusRep->msgRef;
366 length = SmsPluginParamCodec::encodeAddress(&pStatusRep->recipAddress, &address);
367 memcpy(&(pTpdu[offset]), address, length);
371 length = SmsPluginParamCodec::encodeTime(&pStatusRep->timeStamp, &scts);
372 memcpy(&(pTpdu[offset]), scts, length);
376 length = SmsPluginParamCodec::encodeTime(&pStatusRep->dischargeTime, &dt);
377 memcpy(&(pTpdu[offset]), dt, length);
381 pTpdu[offset++] = pStatusRep->status;
384 pTpdu[offset++] = pStatusRep->paramInd;
387 if (pStatusRep->paramInd & 0x01)
388 pTpdu[offset++] = pStatusRep->pid;
391 if (pStatusRep->paramInd & 0x02)
396 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
398 length = SmsPluginParamCodec::encodeDCS(&pStatusRep->dcs, &dcs);
399 memcpy(&(pTpdu[offset]), dcs, length);
405 if (pStatusRep->paramInd & 0x04)
409 encodeSize = SmsPluginUDCodec::encodeUserData(&(pStatusRep->userData), pStatusRep->dcs.codingScheme, &(pTpdu[offset]));
411 MSG_DEBUG("encodeSize : %d", encodeSize);
413 offset += encodeSize;
416 pTpdu[offset] = '\0';
422 int SmsPluginTpduCodec::decodeSubmit(const unsigned char *pTpdu, int TpduLen, SMS_SUBMIT_S *pSubmit)
424 int offset = 0, udLen = 0;
427 if (pTpdu[offset] & 0x04)
428 pSubmit->bRejectDup = false;
430 pSubmit->bRejectDup = true;
433 pSubmit->vpf = (SMS_VPF_T)(pTpdu[offset] & 0x18);
436 if (pTpdu[offset] & 0x20)
437 pSubmit->bStatusReport = true;
439 pSubmit->bStatusReport = false;
442 if (pTpdu[offset] & 0x40)
443 pSubmit->bHeaderInd = true;
445 pSubmit->bHeaderInd = false;
448 if (pTpdu[offset] & 0x80)
449 pSubmit->bReplyPath = true;
451 pSubmit->bReplyPath = false;
456 pSubmit->msgRef = pTpdu[offset++];
459 offset += SmsPluginParamCodec::decodeAddress(pTpdu+offset, &(pSubmit->destAddress));
462 pSubmit->pid = pTpdu[offset++];
465 offset += SmsPluginParamCodec::decodeDCS(pTpdu+offset, &(pSubmit->dcs));
468 if (pSubmit->vpf != SMS_VPF_NOT_PRESENT)
474 udLen = SmsPluginUDCodec::decodeUserData(pTpdu+offset, TpduLen, pSubmit->bHeaderInd, pSubmit->dcs.codingScheme, &(pSubmit->userData));
480 int SmsPluginTpduCodec::decodeDeliver(const unsigned char *pTpdu, int TpduLen, SMS_DELIVER_S *pDeliver)
482 int offset = 0, udLen = 0, tmpOffset = 0;
485 char tpduTmp[(TpduLen*2)+1];
486 memset(tpduTmp, 0x00, sizeof(tpduTmp));
487 for (int i = 0; i < TpduLen; i++) {
488 snprintf(tpduTmp+(i*2), sizeof(tpduTmp)-(i*2), "%02X", pTpdu[i]);
490 MSG_DEBUG("Deliver TPDU.");
491 MSG_INFO("[%s]", tpduTmp);
495 if (pTpdu[offset] & 0x04)
496 pDeliver->bMoreMsg = false;
498 pDeliver->bMoreMsg = true;
501 if (pTpdu[offset] & 0x20)
502 pDeliver->bStatusReport = true;
504 pDeliver->bStatusReport = false;
507 if (pTpdu[offset] & 0x40)
508 pDeliver->bHeaderInd = true;
510 pDeliver->bHeaderInd = false;
513 if (pTpdu[offset] & 0x80)
514 pDeliver->bReplyPath = true;
516 pDeliver->bReplyPath = false;
523 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pDeliver->originAddress));
526 pDeliver->pid = pTpdu[offset++];
529 offset += SmsPluginParamCodec::decodeDCS(&pTpdu[offset], &(pDeliver->dcs));
531 // Support KSC5601 :: Coding group bits == 0x84
532 if (pTpdu[offset-1] == 0x84) {
533 pDeliver->dcs.codingScheme = SMS_CHARSET_EUCKR;
537 //For alphanumeric address test
539 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pDeliver->originAddress));
541 char* address = new char[15];
558 SmsPluginParamCodec::decodeAddress((unsigned char*)address, &(pDeliver->originAddress));
560 pDeliver->pid = 0x20;
562 offset += SmsPluginParamCodec::decodeDCS((unsigned char*)address, &(pDeliver->dcs));
566 if (pDeliver->pid == 0x20 && pDeliver->originAddress.ton == SMS_TON_ALPHANUMERIC) {
570 bool bVmi = SmsPluginParamCodec::checkCphsVmiMsg(&pTpdu[tmpOffset], &setType, &indType);
572 MSG_DEBUG("bVmi = [%d], setType=[%d], indType=[%d]", bVmi, setType, indType);
575 pDeliver->dcs.bMWI = true;
578 pDeliver->dcs.bIndActive = false;
580 pDeliver->dcs.bIndActive = true;
584 pDeliver->dcs.indType = SMS_VOICE_INDICATOR;
585 else if (indType == 1)
586 pDeliver->dcs.indType = SMS_VOICE2_INDICATOR;
591 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pDeliver->timeStamp));
594 udLen = SmsPluginUDCodec::decodeUserData(&pTpdu[offset], TpduLen, pDeliver->bHeaderInd, pDeliver->dcs.codingScheme, &(pDeliver->userData), &(pDeliver->udData));
600 int SmsPluginTpduCodec::decodeStatusReport(const unsigned char *pTpdu, int TpduLen, SMS_STATUS_REPORT_S *pStatusRep)
603 printf("\n\n[decodeStatusReport] pTpdu data - Length [%d]\n", TpduLen);
605 for (int i = 0; i < TpduLen; i++)
607 printf(" [%02x]", pTpdu[i]);
612 int offset = 0, udLen = 0;
614 char* address = NULL;
615 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
618 unique_ptr<char*, void(*)(char**)> sctsBuf(&scts, unique_ptr_deleter);
621 unique_ptr<char*, void(*)(char**)> dtBuf(&dt, unique_ptr_deleter);
624 if (pTpdu[offset] & 0x04)
625 pStatusRep->bMoreMsg = false;
627 pStatusRep->bMoreMsg = true;
630 if (pTpdu[offset] & 0x20)
631 pStatusRep->bStatusReport = true;
633 pStatusRep->bStatusReport = false;
636 if (pTpdu[offset] & 0x40)
637 pStatusRep->bHeaderInd = true;
639 pStatusRep->bHeaderInd = false;
644 pStatusRep->msgRef = pTpdu[offset++];
647 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pStatusRep->recipAddress));
651 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pStatusRep->timeStamp));
655 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pStatusRep->dischargeTime));
658 pStatusRep->status = pTpdu[offset++];
661 pStatusRep->paramInd = pTpdu[offset++];
664 if (pStatusRep->paramInd == 0)
666 pStatusRep->pid = SMS_PID_NORMAL;
668 pStatusRep->dcs.bCompressed = false;
669 pStatusRep->dcs.bMWI = false;
670 pStatusRep->dcs.bIndActive = false;
672 pStatusRep->dcs.msgClass = MSG_CLASS_NONE;
673 pStatusRep->dcs.codingScheme = SMS_CHARSET_7BIT;
674 pStatusRep->dcs.codingGroup = SMS_GROUP_GENERAL;
675 pStatusRep->dcs.indType = SMS_OTHER_INDICATOR;
677 pStatusRep->userData.headerCnt = 0;
678 pStatusRep->userData.length = 0;
679 memset(pStatusRep->userData.data, 0x00, MAX_USER_DATA_LEN+1);
683 if (pStatusRep->paramInd & 0x01)
684 pStatusRep->pid = pTpdu[offset++];
687 if (pStatusRep->paramInd & 0x02)
689 offset += SmsPluginParamCodec::decodeDCS(&pTpdu[offset], &(pStatusRep->dcs));
693 if (pStatusRep->paramInd & 0x04)
696 udLen = SmsPluginUDCodec::decodeUserData(&pTpdu[offset], TpduLen, pStatusRep->bHeaderInd, pStatusRep->dcs.codingScheme, &(pStatusRep->userData));