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()
38 SmsPluginTpduCodec::~SmsPluginTpduCodec()
43 int SmsPluginTpduCodec::encodeTpdu(const SMS_TPDU_S *pSmsTpdu, char *pTpdu)
47 switch (pSmsTpdu->tpduType) {
49 tpduLen = encodeSubmit(&(pSmsTpdu->data.submit), pTpdu);
52 case SMS_TPDU_DELIVER:
53 tpduLen = encodeDeliver(&(pSmsTpdu->data.deliver), pTpdu);
56 case SMS_TPDU_DELIVER_REP:
57 tpduLen = encodeDeliverReport(&(pSmsTpdu->data.deliverRep), pTpdu);
60 case SMS_TPDU_STATUS_REP:
61 tpduLen = encodeStatusReport(&(pSmsTpdu->data.statusRep), pTpdu);
69 int SmsPluginTpduCodec::decodeTpdu(const unsigned char *pTpdu, int TpduLen, SMS_TPDU_S *pSmsTpdu)
73 char mti = pTpdu[0] & 0x03;
77 pSmsTpdu->tpduType = SMS_TPDU_DELIVER;
78 decodeLen = decodeDeliver(pTpdu, TpduLen, &(pSmsTpdu->data.deliver));
82 pSmsTpdu->tpduType = SMS_TPDU_SUBMIT;
83 decodeLen = decodeSubmit(pTpdu, TpduLen, &(pSmsTpdu->data.submit));
87 pSmsTpdu->tpduType = SMS_TPDU_STATUS_REP;
88 decodeLen = decodeStatusReport(pTpdu, TpduLen, &(pSmsTpdu->data.statusRep));
96 int SmsPluginTpduCodec::encodeSubmit(const SMS_SUBMIT_S *pSubmit, char *pTpdu)
98 int offset = 0, length = 0, encodeSize = 0;
100 char* address = NULL;
101 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
104 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
107 unique_ptr<char*, void(*)(char**)> vpBuf(&vpTime, unique_ptr_deleter);
110 pTpdu[offset] = 0x01;
113 if (pSubmit->bRejectDup == true)
114 pTpdu[offset] |= 0x04;
117 switch (pSubmit->vpf) {
118 case SMS_VPF_NOT_PRESENT:
120 case SMS_VPF_ENHANCED:
121 pTpdu[offset] |= 0x08;
123 case SMS_VPF_RELATIVE:
124 pTpdu[offset] |= 0x10;
126 case SMS_VPF_ABSOLUTE:
127 pTpdu[offset] |= 0x18;
134 if (pSubmit->bStatusReport == true)
135 pTpdu[offset] |= 0x20;
137 MSG_DEBUG("TP-SRR pSubmit->bStatusReport : %d.", pSubmit->bStatusReport);
140 if (pSubmit->bHeaderInd == true)
141 pTpdu[offset] |= 0x40;
144 if (pSubmit->bReplyPath == true)
145 pTpdu[offset] |= 0x80;
150 pTpdu[offset++] = pSubmit->msgRef;
152 MSG_DEBUG("TP-MR pSubmit->msgRef : %d.", pSubmit->msgRef);
155 length = SmsPluginParamCodec::encodeAddress(&pSubmit->destAddress, &address);
156 memcpy(&(pTpdu[offset]), address, length);
159 MSG_DEBUG("TP-DA length : %d.", length);
162 pTpdu[offset++] = pSubmit->pid;
164 MSG_DEBUG("TP-PID pSubmit->pid : %d.", pSubmit->pid);
167 length = SmsPluginParamCodec::encodeDCS(&pSubmit->dcs, &dcs);
168 memcpy(&(pTpdu[offset]), dcs, length);
171 MSG_DEBUG("TP-DCS length : %d.", length);
174 if (pSubmit->vpf != SMS_VPF_NOT_PRESENT) {
175 length = SmsPluginParamCodec::encodeTime(&pSubmit->validityPeriod, &vpTime);
178 memcpy(&(pTpdu[offset]), vpTime, length);
183 encodeSize = SmsPluginUDCodec::encodeUserData(&(pSubmit->userData), pSubmit->dcs.codingScheme, &(pTpdu[offset]));
185 MSG_DEBUG("encodeSize : %d", encodeSize);
187 offset += encodeSize;
190 printf("\n\n[encodeSubmit] pTpdu data.\n");
191 for (int i = 0; i < offset; i++) {
192 printf(" [%02x]", pTpdu[i]);
201 int SmsPluginTpduCodec::encodeDeliver(const SMS_DELIVER_S *pDeliver, char *pTpdu)
203 int offset = 0, length = 0, encodeSize = 0;
205 char* address = NULL;
206 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
209 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
212 unique_ptr<char*, void(*)(char**)> timeBuf(&scts, unique_ptr_deleter);
215 pTpdu[offset] = 0x00;
218 if (pDeliver->bMoreMsg == false)
219 pTpdu[offset] |= 0x04;
222 if (pDeliver->bStatusReport == true)
223 pTpdu[offset] |= 0x20;
226 if (pDeliver->bHeaderInd == true)
227 pTpdu[offset] |= 0x40;
230 if (pDeliver->bReplyPath == true)
231 pTpdu[offset] |= 0x80;
236 length = SmsPluginParamCodec::encodeAddress(&pDeliver->originAddress, &address);
237 memcpy(&(pTpdu[offset]), address, length);
241 pTpdu[offset++] = pDeliver->pid;
244 length = SmsPluginParamCodec::encodeDCS(&pDeliver->dcs, &dcs);
245 memcpy(&(pTpdu[offset]), dcs, length);
249 length = SmsPluginParamCodec::encodeTime(&pDeliver->timeStamp, &scts);
250 memcpy(&(pTpdu[offset]), scts, length);
254 encodeSize = SmsPluginUDCodec::encodeUserData(&(pDeliver->userData), pDeliver->dcs.codingScheme, &(pTpdu[offset]));
256 MSG_DEBUG("encodeSize : %d", encodeSize);
258 offset += encodeSize;
264 int SmsPluginTpduCodec::encodeDeliverReport(const SMS_DELIVER_REPORT_S *pDeliverRep, char *pTpdu)
269 pTpdu[offset] = 0x00;
272 if (pDeliverRep->bHeaderInd == true)
273 pTpdu[offset] |= 0x40;
278 if (pDeliverRep->reportType == SMS_REPORT_NEGATIVE) {
279 pTpdu[offset++] = pDeliverRep->failCause;
280 MSG_DEBUG("Delivery report : fail cause = [%02x]", pDeliverRep->failCause);
284 pTpdu[offset++] = pDeliverRep->paramInd;
287 if (pDeliverRep->paramInd & 0x01)
288 pTpdu[offset++] = pDeliverRep->pid;
291 if (pDeliverRep->paramInd & 0x02) {
295 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
297 length = SmsPluginParamCodec::encodeDCS(&pDeliverRep->dcs, &dcs);
298 memcpy(&(pTpdu[offset]), dcs, length);
304 if (pDeliverRep->paramInd & 0x04) {
307 encodeSize = SmsPluginUDCodec::encodeUserData(&(pDeliverRep->userData), pDeliverRep->dcs.codingScheme, &(pTpdu[offset]));
309 MSG_DEBUG("encodeSize : %d", encodeSize);
311 offset += encodeSize;
314 pTpdu[offset] = '\0';
320 int SmsPluginTpduCodec::encodeStatusReport(const SMS_STATUS_REPORT_S *pStatusRep, char *pTpdu)
322 int offset = 0, length = 0;
324 char* address = NULL;
325 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
328 unique_ptr<char*, void(*)(char**)> sctsBuf(&scts, unique_ptr_deleter);
331 unique_ptr<char*, void(*)(char**)> dtBuf(&dt, unique_ptr_deleter);
334 pTpdu[offset] = 0x02;
337 if (pStatusRep->bMoreMsg == true)
338 pTpdu[offset] |= 0x04;
341 if (pStatusRep->bStatusReport == true)
342 pTpdu[offset] |= 0x20;
345 if (pStatusRep->bHeaderInd == true)
346 pTpdu[offset] |= 0x40;
351 pTpdu[offset++] = pStatusRep->msgRef;
354 length = SmsPluginParamCodec::encodeAddress(&pStatusRep->recipAddress, &address);
355 memcpy(&(pTpdu[offset]), address, length);
359 length = SmsPluginParamCodec::encodeTime(&pStatusRep->timeStamp, &scts);
360 memcpy(&(pTpdu[offset]), scts, length);
364 length = SmsPluginParamCodec::encodeTime(&pStatusRep->dischargeTime, &dt);
365 memcpy(&(pTpdu[offset]), dt, length);
369 pTpdu[offset++] = pStatusRep->status;
372 pTpdu[offset++] = pStatusRep->paramInd;
375 if (pStatusRep->paramInd & 0x01)
376 pTpdu[offset++] = pStatusRep->pid;
379 if (pStatusRep->paramInd & 0x02) {
383 unique_ptr<char*, void(*)(char**)> dcsBuf(&dcs, unique_ptr_deleter);
385 length = SmsPluginParamCodec::encodeDCS(&pStatusRep->dcs, &dcs);
386 memcpy(&(pTpdu[offset]), dcs, length);
392 if (pStatusRep->paramInd & 0x04) {
395 encodeSize = SmsPluginUDCodec::encodeUserData(&(pStatusRep->userData), pStatusRep->dcs.codingScheme, &(pTpdu[offset]));
397 MSG_DEBUG("encodeSize : %d", encodeSize);
399 offset += encodeSize;
402 pTpdu[offset] = '\0';
408 int SmsPluginTpduCodec::decodeSubmit(const unsigned char *pTpdu, int TpduLen, SMS_SUBMIT_S *pSubmit)
410 int offset = 0, udLen = 0;
412 char tpduTmp[(TpduLen*2)+1];
413 memset(tpduTmp, 0x00, sizeof(tpduTmp));
414 for (int i = 0; i < TpduLen; i++) {
415 snprintf(tpduTmp+(i*2), sizeof(tpduTmp)-(i*2), "%02X", pTpdu[i]);
417 MSG_DEBUG("Sumbit TPDU.");
418 MSG_INFO("[%s]", tpduTmp);
421 if (pTpdu[offset] & 0x04)
422 pSubmit->bRejectDup = false;
424 pSubmit->bRejectDup = true;
427 pSubmit->vpf = (SMS_VPF_T)(pTpdu[offset] & 0x18);
430 if (pTpdu[offset] & 0x20)
431 pSubmit->bStatusReport = true;
433 pSubmit->bStatusReport = false;
436 if (pTpdu[offset] & 0x40)
437 pSubmit->bHeaderInd = true;
439 pSubmit->bHeaderInd = false;
442 if (pTpdu[offset] & 0x80)
443 pSubmit->bReplyPath = true;
445 pSubmit->bReplyPath = false;
450 pSubmit->msgRef = pTpdu[offset++];
453 offset += SmsPluginParamCodec::decodeAddress(pTpdu+offset, &(pSubmit->destAddress));
456 pSubmit->pid = pTpdu[offset++];
459 offset += SmsPluginParamCodec::decodeDCS(pTpdu+offset, &(pSubmit->dcs));
462 if (pSubmit->vpf != SMS_VPF_NOT_PRESENT) {
467 udLen = SmsPluginUDCodec::decodeUserData(pTpdu+offset, TpduLen, pSubmit->bHeaderInd, pSubmit->dcs.codingScheme, &(pSubmit->userData));
473 int SmsPluginTpduCodec::decodeDeliver(const unsigned char *pTpdu, int TpduLen, SMS_DELIVER_S *pDeliver)
475 int offset = 0, udLen = 0, tmpOffset = 0;
478 char tpduTmp[(TpduLen*2)+1];
479 memset(tpduTmp, 0x00, sizeof(tpduTmp));
480 for (int i = 0; i < TpduLen; i++) {
481 snprintf(tpduTmp+(i*2), sizeof(tpduTmp)-(i*2), "%02X", pTpdu[i]);
483 MSG_DEBUG("Deliver TPDU.");
484 MSG_INFO("[%s]", tpduTmp);
488 if (pTpdu[offset] & 0x04)
489 pDeliver->bMoreMsg = false;
491 pDeliver->bMoreMsg = true;
494 if (pTpdu[offset] & 0x20)
495 pDeliver->bStatusReport = true;
497 pDeliver->bStatusReport = false;
500 if (pTpdu[offset] & 0x40)
501 pDeliver->bHeaderInd = true;
503 pDeliver->bHeaderInd = false;
506 if (pTpdu[offset] & 0x80)
507 pDeliver->bReplyPath = true;
509 pDeliver->bReplyPath = false;
516 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pDeliver->originAddress));
519 pDeliver->pid = pTpdu[offset++];
522 offset += SmsPluginParamCodec::decodeDCS(&pTpdu[offset], &(pDeliver->dcs));
524 /* Support KSC5601 :: Coding group bits == 0x84 */
525 if (pTpdu[offset-1] == 0x84) {
526 pDeliver->dcs.codingScheme = SMS_CHARSET_EUCKR;
530 /* For alphanumeric address test */
532 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pDeliver->originAddress));
534 char* address = new char[15];
551 SmsPluginParamCodec::decodeAddress((unsigned char*)address, &(pDeliver->originAddress));
553 pDeliver->pid = 0x20;
555 offset += SmsPluginParamCodec::decodeDCS((unsigned char*)address, &(pDeliver->dcs));
559 if (pDeliver->pid == 0x20 && pDeliver->originAddress.ton == SMS_TON_ALPHANUMERIC) {
563 bool bVmi = SmsPluginParamCodec::checkCphsVmiMsg(&pTpdu[tmpOffset], &setType, &indType);
565 MSG_DEBUG("bVmi = [%d], setType=[%d], indType=[%d]", bVmi, setType, indType);
568 pDeliver->dcs.bMWI = true;
571 pDeliver->dcs.bIndActive = false;
573 pDeliver->dcs.bIndActive = true;
577 pDeliver->dcs.indType = SMS_VOICE_INDICATOR;
578 else if (indType == 1)
579 pDeliver->dcs.indType = SMS_VOICE2_INDICATOR;
584 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pDeliver->timeStamp));
587 udLen = SmsPluginUDCodec::decodeUserData(&pTpdu[offset], TpduLen, pDeliver->bHeaderInd, pDeliver->dcs.codingScheme, &(pDeliver->userData), &(pDeliver->udData));
593 int SmsPluginTpduCodec::decodeStatusReport(const unsigned char *pTpdu, int TpduLen, SMS_STATUS_REPORT_S *pStatusRep)
596 printf("\n\n[decodeStatusReport] pTpdu data - Length [%d]\n", TpduLen);
598 for (int i = 0; i < TpduLen; i++) {
599 printf(" [%02x]", pTpdu[i]);
604 int offset = 0, udLen = 0;
606 char* address = NULL;
607 unique_ptr<char*, void(*)(char**)> addressBuf(&address, unique_ptr_deleter);
610 unique_ptr<char*, void(*)(char**)> sctsBuf(&scts, unique_ptr_deleter);
613 unique_ptr<char*, void(*)(char**)> dtBuf(&dt, unique_ptr_deleter);
616 if (pTpdu[offset] & 0x04)
617 pStatusRep->bMoreMsg = false;
619 pStatusRep->bMoreMsg = true;
622 if (pTpdu[offset] & 0x20)
623 pStatusRep->bStatusReport = true;
625 pStatusRep->bStatusReport = false;
628 if (pTpdu[offset] & 0x40)
629 pStatusRep->bHeaderInd = true;
631 pStatusRep->bHeaderInd = false;
636 pStatusRep->msgRef = pTpdu[offset++];
639 offset += SmsPluginParamCodec::decodeAddress(&pTpdu[offset], &(pStatusRep->recipAddress));
642 /* Decode timestamp */
643 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pStatusRep->timeStamp));
646 /* Decode timestamp */
647 offset += SmsPluginParamCodec::decodeTime(&pTpdu[offset], &(pStatusRep->dischargeTime));
650 pStatusRep->status = pTpdu[offset++];
653 pStatusRep->paramInd = pTpdu[offset++];
656 if (pStatusRep->paramInd == 0) {
657 pStatusRep->pid = SMS_PID_NORMAL;
659 pStatusRep->dcs.bCompressed = false;
660 pStatusRep->dcs.bMWI = false;
661 pStatusRep->dcs.bIndActive = false;
663 pStatusRep->dcs.msgClass = MSG_CLASS_NONE;
664 pStatusRep->dcs.codingScheme = SMS_CHARSET_7BIT;
665 pStatusRep->dcs.codingGroup = SMS_GROUP_GENERAL;
666 pStatusRep->dcs.indType = SMS_OTHER_INDICATOR;
668 pStatusRep->userData.headerCnt = 0;
669 pStatusRep->userData.length = 0;
670 memset(pStatusRep->userData.data, 0x00, MAX_USER_DATA_LEN+1);
674 if (pStatusRep->paramInd & 0x01)
675 pStatusRep->pid = pTpdu[offset++];
678 if (pStatusRep->paramInd & 0x02)
679 offset += SmsPluginParamCodec::decodeDCS(&pTpdu[offset], &(pStatusRep->dcs));
682 if (pStatusRep->paramInd & 0x04)
683 /* Decode User Data */
684 udLen = SmsPluginUDCodec::decodeUserData(&pTpdu[offset], TpduLen, pStatusRep->bHeaderInd, pStatusRep->dcs.codingScheme, &(pStatusRep->userData));