1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * 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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include "gsm_sms_tpdu_codec.h"
18
19 #include "gsm_sms_param_codec.h"
20 #include "gsm_sms_udata_codec.h"
21 #include "securec.h"
22 #include "telephony_log_wrapper.h"
23
24 namespace OHOS {
25 namespace Telephony {
26 using namespace std;
27 static constexpr uint8_t HEX_BYTE_STEP = 2;
28
29 template<typename T>
UniquePtrDeleterOneDimension(T ** (& ptr))30 inline void UniquePtrDeleterOneDimension(T **(&ptr))
31 {
32 if (ptr && *ptr) {
33 delete[] *ptr;
34 *ptr = nullptr;
35 }
36 }
37
EncodeTpdu(const struct SmsTpdu * pSmsTpdu,char * pTpdu,int pduLen)38 int GsmSmsTpduCodec::EncodeTpdu(const struct SmsTpdu *pSmsTpdu, char *pTpdu, int pduLen)
39 {
40 int tpduLen = 0;
41 TELEPHONY_LOGI("pduLen%{public}d", pduLen);
42 if (pSmsTpdu == nullptr) {
43 return tpduLen;
44 }
45 switch (pSmsTpdu->tpduType) {
46 case SMS_TPDU_SUBMIT:
47 tpduLen = EncodeSubmit(&(pSmsTpdu->data.submit), pTpdu);
48 break;
49 case SMS_TPDU_DELIVER:
50 tpduLen = EncodeDeliver(&(pSmsTpdu->data.deliver), pTpdu);
51 break;
52 case SMS_TPDU_DELIVER_REP:
53 tpduLen = EncodeDeliverReport(&(pSmsTpdu->data.deliverRep), pTpdu);
54 break;
55 case SMS_TPDU_STATUS_REP:
56 tpduLen = EncodeStatusReport(&(pSmsTpdu->data.statusRep), pTpdu);
57 break;
58 default:
59 break;
60 }
61 return tpduLen;
62 }
63
DecodeTpdu(const unsigned char * pTpdu,int TpduLen,struct SmsTpdu * pSmsTpdu)64 int GsmSmsTpduCodec::DecodeTpdu(const unsigned char *pTpdu, int TpduLen, struct SmsTpdu *pSmsTpdu)
65 {
66 int decodeLen = 0;
67 if (pTpdu == nullptr || pSmsTpdu == nullptr) {
68 return decodeLen;
69 }
70 const char mti = pTpdu[0] & 0x03;
71 switch (mti) {
72 case SMS_MTI_DELIVER:
73 pSmsTpdu->tpduType = SMS_TPDU_DELIVER;
74 decodeLen = DecodeDeliver(pTpdu, TpduLen, &(pSmsTpdu->data.deliver));
75 break;
76 case SMS_MTI_SUBMIT:
77 pSmsTpdu->tpduType = SMS_TPDU_SUBMIT;
78 decodeLen = DecodeSubmit(pTpdu, TpduLen, &(pSmsTpdu->data.submit));
79 break;
80 case SMS_MTI_STATUS_REP:
81 pSmsTpdu->tpduType = SMS_TPDU_STATUS_REP;
82 decodeLen = DecodeStatusReport(pTpdu, TpduLen, &(pSmsTpdu->data.statusRep));
83 break;
84 default:
85 break;
86 }
87 return decodeLen;
88 }
89
EncodeSubmit(const struct SmsSubmit * pSubmit,char * pTpdu)90 int GsmSmsTpduCodec::EncodeSubmit(const struct SmsSubmit *pSubmit, char *pTpdu)
91 {
92 int ret = 0;
93 int offset = 0;
94 int length = 0;
95 int encodeSize = 0;
96 char *address = nullptr;
97 char *dcs = nullptr;
98 char *vpTime = nullptr;
99 unique_ptr<char *, void (*)(char **(&))> addressBuf(&address, UniquePtrDeleterOneDimension);
100 unique_ptr<char *, void (*)(char **(&))> dcsBuf(&dcs, UniquePtrDeleterOneDimension);
101 unique_ptr<char *, void (*)(char **(&))> vpBuf(&vpTime, UniquePtrDeleterOneDimension);
102 if (pSubmit == nullptr || pTpdu == nullptr) {
103 return offset;
104 }
105 offset += EncodeSubmitTpduType(*pSubmit, reinterpret_cast<unsigned char *>(pTpdu));
106 /* TP-MR */
107 pTpdu[offset++] = pSubmit->msgRef;
108 /* TP-DA */
109 length = GsmSmsParamCodec::EncodeAddress(&pSubmit->destAddress, &address);
110 ret = memcpy_s(&(pTpdu[offset]), length, address, length);
111 if (ret != EOK) {
112 return offset;
113 }
114 offset += length;
115 TELEPHONY_LOGI("TP-DA len: =%{public}d,TP-MR msgRef:=%{public}d", length, pSubmit->msgRef);
116 /* TP-PID */
117 pTpdu[offset++] = pSubmit->pid;
118 TELEPHONY_LOGI("TP-PID pSubmit->pid : =%{public}d", pSubmit->pid);
119 /* TP-DCS */
120 length = GsmSmsParamCodec::EncodeDCS(&pSubmit->dcs, &dcs);
121 ret = memcpy_s(&(pTpdu[offset]), length, dcs, length);
122 if (ret != EOK) {
123 return offset;
124 }
125 offset += length;
126 TELEPHONY_LOGI("TP-DCS length : =%{public}d", length);
127 /* TP-VP */
128 if (pSubmit->vpf != SMS_VPF_NOT_PRESENT) {
129 length = GsmSmsParamCodec::EncodeTime(&pSubmit->validityPeriod, &vpTime);
130 if (length > 0) {
131 ret = memcpy_s(&(pTpdu[offset]), length, vpTime, length);
132 if (ret != EOK) {
133 TELEPHONY_LOGE("EncodeSubmit vpTime memcpy_s error.");
134 return offset;
135 }
136 offset += length;
137 }
138 }
139 const struct SmsUserData *pUserData = &(pSubmit->userData);
140 char *pEncodeData = &(pTpdu[offset]);
141 encodeSize = GsmSmsUDataCodec::EncodeUserData(pUserData, pSubmit->dcs.codingScheme, pEncodeData);
142 TELEPHONY_LOGI("encodeSize : =%{public}d", encodeSize);
143 offset += encodeSize;
144 return offset;
145 }
146
EncodeSubmitTpduType(const struct SmsSubmit & pSubmit,unsigned char * pTpdu)147 int GsmSmsTpduCodec::EncodeSubmitTpduType(const struct SmsSubmit &pSubmit, unsigned char *pTpdu)
148 {
149 int offset = 0;
150 pTpdu[offset] = 0x01;
151 /* TP-RD */
152 if (pSubmit.bRejectDup == true) {
153 pTpdu[offset] |= 0x04;
154 }
155 /* TP-VPF */
156 switch (pSubmit.vpf) {
157 case SMS_VPF_NOT_PRESENT:
158 break;
159 case SMS_VPF_ENHANCED:
160 pTpdu[offset] |= 0x08;
161 break;
162 case SMS_VPF_RELATIVE:
163 pTpdu[offset] |= 0x10;
164 break;
165 case SMS_VPF_ABSOLUTE:
166 pTpdu[offset] |= 0x18;
167 break;
168 default:
169 break;
170 }
171 /* TP-SRR */
172 if (pSubmit.bStatusReport == true) {
173 pTpdu[offset] |= 0x20;
174 }
175 TELEPHONY_LOGI("TP-SRR pSubmit->bStatusReport: =%{public}d", pSubmit.bStatusReport);
176 /* TP-UDHI */
177 if (pSubmit.bHeaderInd == true) {
178 pTpdu[offset] |= 0x40;
179 }
180 TELEPHONY_LOGI("TP-SRR pSubmit->bHeaderInd: =%{public}d", pSubmit.bHeaderInd);
181 /* TP-RP */
182 if (pSubmit.bReplyPath == true) {
183 pTpdu[offset] |= 0x80;
184 }
185 offset++;
186 return offset;
187 }
188
EncodeDeliver(const struct SmsDeliver * pDeliver,char * pTpdu)189 int GsmSmsTpduCodec::EncodeDeliver(const struct SmsDeliver *pDeliver, char *pTpdu)
190 {
191 int offset = 0;
192 int length = 0;
193 int encodeSize = 0;
194 char *address = nullptr;
195 char *dcs = nullptr;
196 char *scts = nullptr;
197 unique_ptr<char *, void (*)(char **(&))> addressBuf(&address, UniquePtrDeleterOneDimension);
198 unique_ptr<char *, void (*)(char **(&))> dcsBuf(&dcs, UniquePtrDeleterOneDimension);
199 unique_ptr<char *, void (*)(char **(&))> timeBuf(&scts, UniquePtrDeleterOneDimension);
200 if (pDeliver == nullptr || pTpdu == nullptr) {
201 return offset;
202 }
203 /* TP-MTI : 00 */
204 pTpdu[offset] = 0x00;
205 /* TP-MMS */
206 if (pDeliver->bMoreMsg == false) {
207 pTpdu[offset] |= 0x04;
208 }
209 /* TP-SRI */
210 if (pDeliver->bStatusReport == true) {
211 pTpdu[offset] |= 0x20;
212 }
213 /* TP-UDHI */
214 if (pDeliver->bHeaderInd == true) {
215 pTpdu[offset] |= 0x40;
216 }
217 /* TP-RP */
218 if (pDeliver->bReplyPath == true) {
219 pTpdu[offset] |= 0x80;
220 }
221 offset++;
222 /* TP-OA */
223 length = GsmSmsParamCodec::EncodeAddress(&pDeliver->originAddress, &address);
224 if (memcpy_s(&(pTpdu[offset]), length, address, length) != EOK) {
225 TELEPHONY_LOGE("EncodeDeliver originAddress memory error.");
226 return offset;
227 }
228 offset += length;
229 /* TP-PID */
230 pTpdu[offset++] = pDeliver->pid;
231 /* TP-DCS */
232 length = GsmSmsParamCodec::EncodeDCS(&pDeliver->dcs, &dcs);
233 if (memcpy_s(&(pTpdu[offset]), length, dcs, length) != EOK) {
234 TELEPHONY_LOGE("EncodeDeliver dcs memory error.");
235 return offset;
236 }
237 offset += length;
238 /* TP-SCTS */
239 length = GsmSmsParamCodec::EncodeTime(&pDeliver->timeStamp, &scts);
240 if (memcpy_s(&(pTpdu[offset]), length, scts, length) != EOK) {
241 return offset;
242 }
243 offset += length;
244 /* TP-UDL & TP-UD */
245 const struct SmsUserData *pUserData = &(pDeliver->userData);
246 char *pEncodeData = &(pTpdu[offset]);
247 encodeSize = GsmSmsUDataCodec::EncodeUserData(pUserData, pDeliver->dcs.codingScheme, pEncodeData);
248 TELEPHONY_LOGI("encodeSize : %{public}d", encodeSize);
249 offset += encodeSize;
250 return offset;
251 }
252
EncodeDeliverReport(const struct SmsDeliverReport * pDeliverRep,char * pTpdu)253 int GsmSmsTpduCodec::EncodeDeliverReport(const struct SmsDeliverReport *pDeliverRep, char *pTpdu)
254 {
255 int offset = 0;
256 if (pDeliverRep == nullptr || pTpdu == nullptr) {
257 return offset;
258 }
259 /* TP-MTI : 00 */
260 pTpdu[offset] = 0x00;
261 /* TP-UDHI */
262 if (pDeliverRep->bHeaderInd == true) {
263 pTpdu[offset] |= 0x40;
264 }
265 offset++;
266 /* TP-FCS */
267 if (pDeliverRep->reportType == SMS_REPORT_NEGATIVE) {
268 pTpdu[offset++] = pDeliverRep->failCause;
269 TELEPHONY_LOGI("Delivery report : fail cause = [%{public}02x]", pDeliverRep->failCause);
270 }
271 /* TP-PI */
272 pTpdu[offset++] = pDeliverRep->paramInd;
273 /* TP-PID */
274 if (pDeliverRep->paramInd & 0x01) {
275 pTpdu[offset++] = pDeliverRep->pid;
276 }
277 /* TP-DCS */
278 if (pDeliverRep->paramInd & 0x02) {
279 int length = 0;
280 char *dcs = nullptr;
281 unique_ptr<char *, void (*)(char **(&))> dcsBuf(&dcs, UniquePtrDeleterOneDimension);
282 length = GsmSmsParamCodec::EncodeDCS(&pDeliverRep->dcs, &dcs);
283 if (memcpy_s(&(pTpdu[offset]), length, dcs, length) != EOK) {
284 return offset;
285 }
286 offset += length;
287 }
288 /* TP-UDL & TP-UD */
289 if (pDeliverRep->paramInd & 0x04) {
290 int encodeSize = 0;
291 const struct SmsUserData *pUserData = &(pDeliverRep->userData);
292 char *pEncodeData = &(pTpdu[offset]);
293 encodeSize = GsmSmsUDataCodec::EncodeUserData(pUserData, pDeliverRep->dcs.codingScheme, pEncodeData);
294 TELEPHONY_LOGI("encodeSize : %{public}d", encodeSize);
295 offset += encodeSize;
296 }
297 pTpdu[offset] = '\0';
298 return offset;
299 }
300
EncodeStatusReport(const struct SmsStatusReport * pStatusRep,char * pTpdu)301 int GsmSmsTpduCodec::EncodeStatusReport(const struct SmsStatusReport *pStatusRep, char *pTpdu)
302 {
303 int offset = 0;
304 int length = 0;
305 char *address = nullptr;
306 char *scts = nullptr;
307 char *dt = nullptr;
308 unique_ptr<char *, void (*)(char **(&))> addressBuf(&address, UniquePtrDeleterOneDimension);
309 unique_ptr<char *, void (*)(char **(&))> sctsBuf(&scts, UniquePtrDeleterOneDimension);
310 unique_ptr<char *, void (*)(char **(&))> dtBuf(&dt, UniquePtrDeleterOneDimension);
311 if (pStatusRep == nullptr || pTpdu == nullptr) {
312 return offset;
313 }
314 /* TP-MTI : 10 */
315 pTpdu[offset] = 0x02;
316 /* TP-MMS */
317 if (pStatusRep->bMoreMsg == true) {
318 pTpdu[offset] |= 0x04;
319 }
320 /* TP-SRQ */
321 if (pStatusRep->bStatusReport == true) {
322 pTpdu[offset] |= 0x20;
323 }
324 /* TP-UDHI */
325 if (pStatusRep->bHeaderInd == true) {
326 pTpdu[offset] |= 0x40;
327 }
328 offset++;
329 /* TP-MR */
330 pTpdu[offset++] = pStatusRep->msgRef;
331 /* TP-RA */
332 length = GsmSmsParamCodec::EncodeAddress(&pStatusRep->recipAddress, &address);
333 if (memcpy_s(&(pTpdu[offset]), length, address, length) != EOK) {
334 TELEPHONY_LOGE("EncodeStatusReport memory EncodeAddress error");
335 return offset;
336 }
337 offset += length;
338 /* TP-SCTS */
339 length = GsmSmsParamCodec::EncodeTime(&pStatusRep->timeStamp, &scts);
340 if (memcpy_s(&(pTpdu[offset]), length, scts, length) != EOK) {
341 TELEPHONY_LOGE("EncodeStatusReport memory EncodeTime error");
342 return offset;
343 }
344 offset += length;
345 /* TP-DT */
346 length = GsmSmsParamCodec::EncodeTime(&pStatusRep->dischargeTime, &dt);
347 if (memcpy_s(&(pTpdu[offset]), length, dt, length) != EOK) {
348 TELEPHONY_LOGE("EncodeStatusReport memory EncodeTime dt error");
349 return offset;
350 }
351 offset += length;
352 /* TP-Status */
353 pTpdu[offset++] = pStatusRep->status;
354 /* TP-PI */
355 pTpdu[offset++] = pStatusRep->paramInd;
356 /* TP-PID */
357 if (pStatusRep->paramInd & 0x01) {
358 pTpdu[offset++] = pStatusRep->pid;
359 }
360 /* TP-DCS */
361 if (pStatusRep->paramInd & 0x02) {
362 char *dcs = nullptr;
363 unique_ptr<char *, void (*)(char **(&))> dcsBuf(&dcs, UniquePtrDeleterOneDimension);
364 length = GsmSmsParamCodec::EncodeDCS(&pStatusRep->dcs, &dcs);
365 if (memcpy_s(&(pTpdu[offset]), length, dcs, length) != EOK) {
366 TELEPHONY_LOGE("EncodeStatusReport memory EncodeDCS error");
367 return offset;
368 }
369 offset += length;
370 }
371 /* TP-UDL & TP-UD */
372 if (pStatusRep->paramInd & 0x04) {
373 int encodeSize = 0;
374 const struct SmsUserData *pUserData = &(pStatusRep->userData);
375 char *pEncodeData = &(pTpdu[offset]);
376 encodeSize = GsmSmsUDataCodec::EncodeUserData(pUserData, pStatusRep->dcs.codingScheme, pEncodeData);
377 offset += encodeSize;
378 }
379 pTpdu[offset] = '\0';
380 return offset;
381 }
382
DecodeSubmit(const unsigned char * pSubpdu,int pduLen,struct SmsSubmit * pSmsSub)383 int GsmSmsTpduCodec::DecodeSubmit(const unsigned char *pSubpdu, int pduLen, struct SmsSubmit *pSmsSub)
384 {
385 int offset = 0;
386 int udLen = 0;
387 if (pSubpdu == nullptr || pSmsSub == nullptr) {
388 return offset;
389 }
390 DebugTpdu(pSubpdu, pduLen, DECODE_SUBMIT_TYPE);
391 // TP-RD
392 if (pSubpdu[offset] & 0x04) {
393 pSmsSub->bRejectDup = false;
394 } else {
395 pSmsSub->bRejectDup = true;
396 }
397 // TP-VPF
398 pSmsSub->vpf = (enum SmsVpf)(pSubpdu[offset] & 0x18);
399 // TP-SRR
400 if (pSubpdu[offset] & 0x20) {
401 pSmsSub->bStatusReport = true;
402 } else {
403 pSmsSub->bStatusReport = false;
404 }
405 // TP-UDHI
406 if (pSubpdu[offset] & 0x40) {
407 pSmsSub->bHeaderInd = true;
408 } else {
409 pSmsSub->bHeaderInd = false;
410 }
411 // TP-RP
412 if (pSubpdu[offset] & 0x80) {
413 pSmsSub->bReplyPath = true;
414 } else {
415 pSmsSub->bReplyPath = false;
416 }
417 offset++;
418 // TP-MR
419 pSmsSub->msgRef = pSubpdu[offset++];
420 // TP-DA
421 offset += GsmSmsParamCodec::DecodeAddress(pSubpdu + offset, &(pSmsSub->destAddress));
422 // TP-PID
423 pSmsSub->pid = ParsePid(pSubpdu[offset++]);
424 // TP-DCS
425 offset += GsmSmsParamCodec::DecodeDCS(pSubpdu + offset, &(pSmsSub->dcs));
426 // TP-VP
427 if (pSmsSub->vpf != SMS_VPF_NOT_PRESENT) {
428 // Decode VP
429 }
430 // TP-UDL & TP-UD
431 udLen = GsmSmsUDataCodec::DecodeUserData(
432 pSubpdu + offset, pduLen, pSmsSub->bHeaderInd, pSmsSub->dcs.codingScheme, &(pSmsSub->userData));
433 return udLen + offset;
434 }
435
DecodePartData(const unsigned char & pTpdu,struct SmsDeliver & pDeliver)436 void DecodePartData(const unsigned char &pTpdu, struct SmsDeliver &pDeliver)
437 {
438 /* TP-MMS */
439 if (pTpdu & 0x04) {
440 pDeliver.bMoreMsg = false;
441 } else {
442 pDeliver.bMoreMsg = true;
443 }
444 /* TP-SRI */
445 if (pTpdu & 0x20) {
446 pDeliver.bStatusReport = true;
447 } else {
448 pDeliver.bStatusReport = false;
449 }
450 /* TP-UDHI */
451 if (pTpdu & 0x40) {
452 pDeliver.bHeaderInd = true;
453 } else {
454 pDeliver.bHeaderInd = false;
455 }
456 /* TP-RP */
457 if (pTpdu & 0x80) {
458 pDeliver.bReplyPath = true;
459 } else {
460 pDeliver.bReplyPath = false;
461 }
462 }
463
DecodeDeliver(const unsigned char * pTpdu,int TpduLen,struct SmsDeliver * pDeliver)464 int GsmSmsTpduCodec::DecodeDeliver(const unsigned char *pTpdu, int TpduLen, struct SmsDeliver *pDeliver)
465 {
466 int offset = 0;
467 int udLen = 0;
468 int tmpOffset = 0;
469 if (pTpdu == nullptr || pDeliver == nullptr) {
470 return offset;
471 }
472 DebugTpdu(pTpdu, TpduLen, DECODE_DELIVER_TYPE);
473 DecodePartData(pTpdu[offset], *pDeliver);
474 offset++;
475 tmpOffset = offset;
476 /* TP-OA */
477 offset += GsmSmsParamCodec::DecodeAddress(&pTpdu[offset], &(pDeliver->originAddress));
478 /* TP-PID */
479 pDeliver->pid = ParsePid(pTpdu[offset++]);
480 /* TP-DCS */
481 offset += GsmSmsParamCodec::DecodeDCS(&pTpdu[offset], &(pDeliver->dcs));
482 /* Support KSC5601 :: Coding group bits == 0x84 */
483 if (pTpdu[offset - 1] == 0x84) {
484 pDeliver->dcs.codingScheme = SMS_CODING_EUCKR;
485 }
486 if (pDeliver->pid == 0x20 && pDeliver->originAddress.ton == SMS_TON_ALPHA_NUMERIC) {
487 int setType = -1;
488 int indType = -1;
489 bool bVmi = GsmSmsParamCodec::CheckCphsVmiMsg(&pTpdu[tmpOffset], &setType, &indType);
490 TELEPHONY_LOGI("bVmi= [%{public}d], setType=[%{public}d], indType=[%{public}d]", bVmi, setType, indType);
491 if (bVmi) {
492 pDeliver->dcs.bMWI = true;
493 if (setType == 0) {
494 pDeliver->dcs.bIndActive = false;
495 } else {
496 pDeliver->dcs.bIndActive = true;
497 }
498 if (indType == 0) {
499 pDeliver->dcs.indType = SMS_VOICE_INDICATOR;
500 } else if (indType == 1) {
501 pDeliver->dcs.indType = SMS_VOICE2_INDICATOR;
502 }
503 }
504 }
505 /* TP-SCTS */
506 offset += GsmSmsParamCodec::DecodeTime(&pTpdu[offset], &(pDeliver->timeStamp));
507 /* TP-UD */
508 udLen = GsmSmsUDataCodec::DecodeUserData(&pTpdu[offset], TpduLen, pDeliver->bHeaderInd,
509 pDeliver->dcs.codingScheme, &(pDeliver->userData), &(pDeliver->udData));
510 return udLen + offset;
511 }
512
DecodeStatusReport(const unsigned char * pTpdu,int TpduLen,struct SmsStatusReport * pStatusRep)513 int GsmSmsTpduCodec::DecodeStatusReport(const unsigned char *pTpdu, int TpduLen, struct SmsStatusReport *pStatusRep)
514 {
515 int offset = 0;
516 int udLen = 0;
517 char *address = nullptr;
518 char *scts = nullptr;
519 char *dt = nullptr;
520 unique_ptr<char *, void (*)(char **(&))> addressBuf(&address, UniquePtrDeleterOneDimension);
521 unique_ptr<char *, void (*)(char **(&))> sctsBuf(&scts, UniquePtrDeleterOneDimension);
522 unique_ptr<char *, void (*)(char **(&))> dtBuf(&dt, UniquePtrDeleterOneDimension);
523 if (pTpdu == nullptr || pStatusRep == nullptr) {
524 return offset;
525 }
526 /* TP-MMS */
527 pStatusRep->bMoreMsg = (pTpdu[offset] & 0x04) ? false : true;
528 /* TP-SRQ */
529 pStatusRep->bStatusReport = (pTpdu[offset] & 0x20) ? true : false;
530 /* TP-UDHI */
531 pStatusRep->bHeaderInd = (pTpdu[offset] & 0x40) ? true : false;
532 offset++;
533 /* TP-MR */
534 pStatusRep->msgRef = pTpdu[offset++];
535 /* TP-RA */
536 offset += GsmSmsParamCodec::DecodeAddress(&pTpdu[offset], &(pStatusRep->recipAddress));
537 /* TP-SCTS */
538 /* Decode timestamp */
539 offset += GsmSmsParamCodec::DecodeTime(&pTpdu[offset], &(pStatusRep->timeStamp));
540 /* TP-DT */
541 /* Decode timestamp */
542 offset += GsmSmsParamCodec::DecodeTime(&pTpdu[offset], &(pStatusRep->dischargeTime));
543 /* TP-Status */
544 pStatusRep->status = pTpdu[offset++];
545 /* TP-PI */
546 pStatusRep->paramInd = pTpdu[offset++];
547 /* No Parameters */
548 if (pStatusRep->paramInd == 0) {
549 pStatusRep->pid = SMS_NORMAL_PID;
550 pStatusRep->dcs.bCompressed = false;
551 pStatusRep->dcs.bMWI = false;
552 pStatusRep->dcs.bIndActive = false;
553 pStatusRep->dcs.msgClass = SMS_CLASS_UNKNOWN;
554 pStatusRep->dcs.codingScheme = SMS_CODING_7BIT;
555 pStatusRep->dcs.codingGroup = SMS_GENERAL_GROUP;
556 pStatusRep->dcs.indType = SMS_OTHER_INDICATOR;
557 pStatusRep->userData.headerCnt = 0;
558 pStatusRep->userData.length = 0;
559 int ret = memset_s(pStatusRep->userData.data, sizeof(pStatusRep->userData.data), 0x00, MAX_USER_DATA_LEN + 1);
560 if (ret != EOK) {
561 return offset;
562 }
563 }
564 /* TP-PID */
565 if (pStatusRep->paramInd & 0x01) {
566 pStatusRep->pid = ParsePid(pTpdu[offset++]);
567 }
568 /* TP-DCS */
569 if (pStatusRep->paramInd & 0x02) {
570 offset += GsmSmsParamCodec::DecodeDCS(&pTpdu[offset], &(pStatusRep->dcs));
571 }
572 /* TP-UDL & TP-UD */
573 if (pStatusRep->paramInd & 0x04) {
574 /* Decode User Data */
575 udLen = GsmSmsUDataCodec::DecodeUserData(&pTpdu[offset], TpduLen, pStatusRep->bHeaderInd,
576 pStatusRep->dcs.codingScheme, &(pStatusRep->userData));
577 }
578 return udLen + offset;
579 }
580
ParsePid(const unsigned char pid)581 enum SmsPid GsmSmsTpduCodec::ParsePid(const unsigned char pid)
582 {
583 return (enum SmsPid)pid;
584 }
585
DebugTpdu(const unsigned char * pTpdu,int TpduLen,const enum DecodeType type)586 void GsmSmsTpduCodec::DebugTpdu(const unsigned char *pTpdu, int TpduLen, const enum DecodeType type)
587 {
588 if (pTpdu == nullptr) {
589 TELEPHONY_LOGE("debugTpdu error ptpdu nullptr");
590 return;
591 }
592 char tpduTmp[(TpduLen * HEX_BYTE_STEP) + 1];
593 if (memset_s(tpduTmp, sizeof(tpduTmp), 0x00, sizeof(tpduTmp)) != EOK) {
594 TELEPHONY_LOGE("memset_s error.");
595 return;
596 }
597 for (int i = 0; i < TpduLen; i++) {
598 uint8_t step = HEX_BYTE_STEP;
599 const int len = sizeof(tpduTmp) - (i * step);
600 if (snprintf_s(tpduTmp + (i * step), len - 1, len - 1, "%02X", pTpdu[i]) < 0) {
601 TELEPHONY_LOGE("DebugTpdu snprintf_s error");
602 return;
603 }
604 }
605 }
606 } // namespace Telephony
607 } // namespace OHOS