1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <regex>
17 #include <sstream>
18
19 #include "gsm_sms_param_decode.h"
20
21 #include "gsm_pdu_hex_value.h"
22 #include "gsm_sms_common_utils.h"
23 #include "gsm_user_data_pdu.h"
24 #include "securec.h"
25 #include "telephony_log_wrapper.h"
26 #include "text_coder.h"
27
28 namespace OHOS {
29 namespace Telephony {
30 static constexpr uint8_t SLIDE_DATA_STEP = 2;
31 static constexpr uint8_t BCD_TO_DIGITAL = 2;
32 static constexpr uint8_t MATCH_INDEX_ONE = 1;
33 static constexpr uint8_t MATCH_INDEX_TWO = 2;
34 static constexpr uint8_t MATCH_INDEX_THREE = 3;
35 static constexpr uint8_t MATCH_INDEX_FOUR = 4;
36 static constexpr uint8_t MATCH_INDEX_FIVE = 5;
37
DecodeAddressPdu(SmsReadBuffer & buffer,struct AddressNumber * resultNum)38 bool GsmSmsParamDecode::DecodeAddressPdu(SmsReadBuffer &buffer, struct AddressNumber *resultNum)
39 {
40 if (resultNum == nullptr) {
41 TELEPHONY_LOGE("nullptr error");
42 return false;
43 }
44 if (memset_s(resultNum->address, sizeof(resultNum->address), 0x00, sizeof(resultNum->address)) != EOK) {
45 TELEPHONY_LOGE("memset_s error!");
46 return false;
47 }
48
49 uint8_t oneByte = 0;
50 if (!buffer.ReadByte(oneByte) || oneByte >= BCD_TO_DIGITAL * (MAX_ADDRESS_LEN + 1)) {
51 TELEPHONY_LOGE("get data error. %{public}d", oneByte);
52 return false;
53 }
54 uint8_t addrLen = oneByte;
55 uint8_t bcdLen = 0;
56 if (addrLen % SLIDE_DATA_STEP == 0) {
57 bcdLen = addrLen / SLIDE_DATA_STEP;
58 } else {
59 bcdLen = addrLen / SLIDE_DATA_STEP + 1;
60 }
61
62 if (!buffer.PickOneByte(oneByte)) {
63 TELEPHONY_LOGE("get data error.");
64 return false;
65 }
66 resultNum->ton = (oneByte & HEX_VALUE_70) >> HEX_VALUE_04;
67
68 if (resultNum->ton == TYPE_ALPHA_NUMERIC) {
69 return DecodeAddressAlphaNum(buffer, resultNum, bcdLen, addrLen);
70 } else if (resultNum->ton == TYPE_INTERNATIONAL) {
71 return DecodeAddressInternationalNum(buffer, resultNum, bcdLen);
72 } else {
73 return DecodeAddressDefaultNum(buffer, resultNum, bcdLen);
74 }
75 }
76
DecodeAddressAlphaNum(SmsReadBuffer & buffer,struct AddressNumber * resultNum,uint8_t bcdLen,uint8_t addrLen)77 bool GsmSmsParamDecode::DecodeAddressAlphaNum(
78 SmsReadBuffer &buffer, struct AddressNumber *resultNum, uint8_t bcdLen, uint8_t addrLen)
79 {
80 uint8_t tmresultNum[MAX_ADDRESS_LEN] = { 0 };
81 uint8_t dataLen = (addrLen * HEX_VALUE_04) / HEX_VALUE_07;
82 TELEPHONY_LOGI("DecodeAddressAlphaNum, addrLen:%{public}d, dataLen: %{public}d", addrLen, dataLen);
83 uint8_t addressPduArr[MAX_ADDRESS_LEN + 1] = { 0 };
84 uint8_t oneByte = 0;
85 if (!buffer.ReadByte(oneByte)) {
86 TELEPHONY_LOGE("get data error.");
87 return false;
88 }
89 uint32_t encodeLen = (addrLen % HEX_VALUE_02 == 0) ? (addrLen / HEX_VALUE_02) :
90 (addrLen / HEX_VALUE_02 + HEX_VALUE_01);
91 TELEPHONY_LOGI("DecodeAddressAlphaNum, encodeLen %{public}d", encodeLen);
92 for (uint8_t i = 0; i < encodeLen; i++) {
93 if (!buffer.ReadByte(oneByte)) {
94 TELEPHONY_LOGE("get data error.");
95 return false;
96 }
97 addressPduArr[i] = oneByte;
98 }
99 if (!GsmSmsCommonUtils::Unpack7bitCharForMiddlePart(addressPduArr, dataLen, tmresultNum)) {
100 TELEPHONY_LOGE("unpack 7bit char error!");
101 return false;
102 }
103 MsgLangInfo langInfo;
104 langInfo.bSingleShift = false;
105 langInfo.bLockingShift = false;
106 TextCoder::Instance().Gsm7bitToUtf8(
107 reinterpret_cast<uint8_t *>(resultNum->address), MAX_ADDRESS_LEN, tmresultNum, dataLen, langInfo);
108 return true;
109 }
110
DecodeAddressInternationalNum(SmsReadBuffer & buffer,struct AddressNumber * resultNum,uint8_t bcdLen)111 bool GsmSmsParamDecode::DecodeAddressInternationalNum(
112 SmsReadBuffer &buffer, struct AddressNumber *resultNum, uint8_t bcdLen)
113 {
114 buffer.MoveForward(1);
115 uint8_t oneByte = 0;
116 uint8_t index = 0;
117 uint8_t bcdArr[MAX_ADDRESS_LEN + 1] = { 0 };
118 while (index < bcdLen && index < MAX_ADDRESS_LEN) {
119 if (!buffer.ReadByte(oneByte)) {
120 TELEPHONY_LOGE("get data error.");
121 return false;
122 }
123 bcdArr[index++] = oneByte;
124 }
125
126 GsmSmsCommonUtils utils;
127 std::string addrNum;
128 if (!utils.BcdToDigit(bcdArr, bcdLen, addrNum, SMS_MAX_ADDRESS_LEN)) {
129 TELEPHONY_LOGE("BcdToDigit fail!");
130 return false;
131 }
132 std::string newStrAddress = regProcessSmsAddrs(addrNum);
133 for (uint8_t i = 0; i < newStrAddress.size() && i < MAX_ADDRESS_LEN; i++) {
134 resultNum->address[i] = newStrAddress[i];
135 }
136 return true;
137 }
138
DecodeAddressDefaultNum(SmsReadBuffer & buffer,struct AddressNumber * resultNum,uint8_t bcdLen)139 bool GsmSmsParamDecode::DecodeAddressDefaultNum(SmsReadBuffer &buffer, struct AddressNumber *resultNum, uint8_t bcdLen)
140 {
141 uint8_t index = 0;
142 buffer.MoveForward(1);
143 uint8_t oneByte = 0;
144 uint8_t bcdArr[MAX_ADDRESS_LEN + 1] = { 0 };
145 while (index < bcdLen && index < MAX_ADDRESS_LEN) {
146 if (!buffer.ReadByte(oneByte)) {
147 TELEPHONY_LOGE("get data error.");
148 return false;
149 }
150 bcdArr[index++] = oneByte;
151 }
152 GsmSmsCommonUtils utils;
153 std::string addrNum;
154 if (!utils.BcdToDigit(bcdArr, bcdLen, addrNum, SMS_MAX_ADDRESS_LEN)) {
155 TELEPHONY_LOGE("BcdToDigit fail!");
156 return false;
157 }
158 for (uint8_t i = 0; i < addrNum.size() && i < MAX_ADDRESS_LEN; i++) {
159 resultNum->address[i] = addrNum[i];
160 }
161 return true;
162 }
163
164
regProcessSmsAddrs(std::string & smsAddrs)165 std::string GsmSmsParamDecode::regProcessSmsAddrs(std::string &smsAddrs)
166 {
167 std::regex pattern(R"((^[#*])(.*)([#*])(.*)(#)$)");
168 std::smatch match;
169 std::ostringstream ret;
170 if (std::regex_match(smsAddrs, match, pattern)) {
171 if (match[MATCH_INDEX_TWO] == "") {
172 ret << match[MATCH_INDEX_ONE] << match[MATCH_INDEX_THREE] <<
173 match[MATCH_INDEX_FOUR] << match[MATCH_INDEX_FIVE] << '+';
174 } else {
175 ret << match[MATCH_INDEX_ONE] << match[MATCH_INDEX_TWO] <<
176 match[MATCH_INDEX_THREE] << '+' << match[MATCH_INDEX_FOUR] << match[MATCH_INDEX_FIVE];
177 }
178 } else {
179 std::regex pattern2(R"((^[#*])(.*)([#*])(.*))");
180 if (std::regex_match(smsAddrs, match, pattern2)) {
181 ret << match[MATCH_INDEX_ONE] << match[MATCH_INDEX_TWO] <<
182 match[MATCH_INDEX_THREE] << '+' << match[MATCH_INDEX_FOUR];
183 } else {
184 ret << '+' << smsAddrs;
185 }
186 }
187 return ret.str();
188 }
189
DecodeSmscPdu(uint8_t * srcAddr,uint8_t addrLen,enum TypeOfNum ton,std::string & desAddr)190 void GsmSmsParamDecode::DecodeSmscPdu(uint8_t *srcAddr, uint8_t addrLen, enum TypeOfNum ton, std::string &desAddr)
191 {
192 if (srcAddr == nullptr || addrLen == 0) {
193 TELEPHONY_LOGE("smsc data error.");
194 return;
195 }
196
197 GsmSmsCommonUtils utils;
198 if (ton == TYPE_INTERNATIONAL) {
199 if (!utils.BcdToDigit(srcAddr, addrLen, desAddr, SMS_MAX_ADDRESS_LEN)) {
200 TELEPHONY_LOGE("BcdToDigit fail!");
201 return;
202 }
203 std::string newStrAddress = regProcessSmsAddrs(desAddr);
204 desAddr = newStrAddress;
205 } else {
206 if (!utils.BcdToDigit(srcAddr, addrLen, desAddr, SMS_MAX_ADDRESS_LEN)) {
207 TELEPHONY_LOGE("BcdToDigit fail!");
208 return;
209 }
210 }
211 }
212
DecodeSmscPdu(const uint8_t * pTpdu,uint8_t pduLen,struct AddressNumber & desAddrObj)213 uint8_t GsmSmsParamDecode::DecodeSmscPdu(const uint8_t *pTpdu, uint8_t pduLen, struct AddressNumber &desAddrObj)
214 {
215 if (pTpdu == nullptr || pduLen == 0) {
216 TELEPHONY_LOGE("nullptr error.");
217 return 0;
218 }
219 if (memset_s(desAddrObj.address, sizeof(desAddrObj.address), 0x00, sizeof(desAddrObj.address)) != EOK) {
220 TELEPHONY_LOGE("memset_s error!");
221 return 0;
222 }
223
224 uint8_t offset = 0;
225 uint8_t addrLen = pTpdu[offset++];
226 if (addrLen == 0) {
227 TELEPHONY_LOGI("smsc is 00.");
228 return offset;
229 }
230 if (addrLen >= pduLen || offset >= pduLen) {
231 TELEPHONY_LOGI("smsc absent.");
232 return 0;
233 }
234 desAddrObj.ton = (pTpdu[offset] & HEX_VALUE_70) >> HEX_VALUE_04;
235 desAddrObj.npi = pTpdu[offset++] & HEX_VALUE_0F;
236
237 GsmSmsCommonUtils utils;
238 if (desAddrObj.ton == TYPE_INTERNATIONAL) {
239 if (addrLen > SMS_MAX_ADDRESS_LEN || (offset + addrLen) >= pduLen) {
240 TELEPHONY_LOGE("addrLen invalid.");
241 return 0;
242 }
243 std::string addrNum;
244 utils.BcdToDigit(&(pTpdu[offset]), addrLen, addrNum, SMS_MAX_ADDRESS_LEN);
245 std::string newStrAddress = regProcessSmsAddrs(addrNum);
246 for (uint8_t i = 0; i < newStrAddress.size() && i < MAX_ADDRESS_LEN; i++) {
247 desAddrObj.address[i] = newStrAddress[i];
248 }
249 } else {
250 if (addrLen > SMS_MAX_ADDRESS_LEN || (offset + addrLen) >= pduLen) {
251 TELEPHONY_LOGE("addrLen invalid.");
252 return 0;
253 }
254 std::string addrNum;
255 utils.BcdToDigit(&(pTpdu[offset]), addrLen, addrNum, SMS_MAX_ADDRESS_LEN);
256 for (uint8_t i = 0; i < addrNum.size() && i < MAX_ADDRESS_LEN; i++) {
257 desAddrObj.address[i] = addrNum[i];
258 }
259 }
260
261 offset += (addrLen - 1);
262 return offset;
263 }
264
DecodeDcsPdu(SmsReadBuffer & buffer,struct SmsDcs * smsDcs)265 bool GsmSmsParamDecode::DecodeDcsPdu(SmsReadBuffer &buffer, struct SmsDcs *smsDcs)
266 {
267 if (smsDcs == nullptr) {
268 TELEPHONY_LOGE("smsDcs nullptr.");
269 return false;
270 }
271 uint8_t dcs = 0;
272 if (!buffer.ReadByte(dcs)) {
273 TELEPHONY_LOGE("get data error.");
274 return false;
275 }
276
277 smsDcs->bMWI = false;
278 smsDcs->bIndActive = false;
279 smsDcs->indType = SMS_OTHER_INDICATOR;
280 if (((dcs & HEX_VALUE_C0) >> HEX_VALUE_06) == 0) {
281 DecodeDcsGeneralGroupPdu(dcs, smsDcs);
282 } else if (((dcs & HEX_VALUE_F0) >> HEX_VALUE_04) == HEX_VALUE_0F) {
283 DecodeDcsClassGroupPdu(dcs, smsDcs);
284 } else if (((dcs & HEX_VALUE_C0) >> HEX_VALUE_06) == HEX_VALUE_01) {
285 DecodeDcsDeleteGroupPdu(dcs, smsDcs);
286 } else if (((dcs & HEX_VALUE_F0) >> HEX_VALUE_04) == HEX_VALUE_0C) {
287 DecodeDcsDiscardGroupPdu(dcs, smsDcs);
288 } else if (((dcs & HEX_VALUE_F0) >> HEX_VALUE_04) == HEX_VALUE_0D) {
289 DecodeDcsStoreGsmGroupPdu(dcs, smsDcs);
290 } else if (((dcs & HEX_VALUE_F0) >> HEX_VALUE_04) == HEX_VALUE_0E) {
291 DecodeDcsStoreUCS2GroupPdu(dcs, smsDcs);
292 } else {
293 DecodeDcsUnknownGroupPdu(dcs, smsDcs);
294 }
295 return true;
296 }
297
DecodeDcsGeneralGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)298 void GsmSmsParamDecode::DecodeDcsGeneralGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
299 {
300 if (smsDcs == nullptr) {
301 TELEPHONY_LOGE("smsDcs is nullptr.");
302 return;
303 }
304
305 smsDcs->codingGroup = CODING_GENERAL_GROUP;
306 smsDcs->bCompressed = (dcs & HEX_VALUE_20) >> HEX_VALUE_05;
307 smsDcs->codingScheme = GetMsgCodingScheme((dcs & HEX_VALUE_0C) >> HEX_VALUE_02);
308 if (((dcs & HEX_VALUE_10) >> HEX_VALUE_04) == 0) {
309 smsDcs->msgClass = SMS_CLASS_UNKNOWN;
310 } else {
311 smsDcs->msgClass = GetMsgClass(dcs & HEX_VALUE_03);
312 }
313 }
314
DecodeDcsClassGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)315 void GsmSmsParamDecode::DecodeDcsClassGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
316 {
317 if (smsDcs == nullptr) {
318 TELEPHONY_LOGE("smsDcs is nullptr.");
319 return;
320 }
321
322 smsDcs->codingGroup = SMS_CLASS_GROUP;
323 smsDcs->bCompressed = false;
324 smsDcs->codingScheme = GetMsgCodingScheme((dcs & HEX_VALUE_0C) >> HEX_VALUE_02);
325 smsDcs->msgClass = GetMsgClass(dcs & HEX_VALUE_03);
326 }
327
DecodeDcsDeleteGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)328 void GsmSmsParamDecode::DecodeDcsDeleteGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
329 {
330 if (smsDcs == nullptr) {
331 TELEPHONY_LOGE("smsDcs is nullptr.");
332 return;
333 }
334
335 smsDcs->codingGroup = CODING_DELETION_GROUP;
336 smsDcs->bCompressed = false;
337 smsDcs->msgClass = SMS_CLASS_UNKNOWN;
338 }
339
DecodeDcsDiscardGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)340 void GsmSmsParamDecode::DecodeDcsDiscardGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
341 {
342 if (smsDcs == nullptr) {
343 TELEPHONY_LOGE("smsDcs is null.");
344 return;
345 }
346
347 smsDcs->codingGroup = CODING_DISCARD_GROUP;
348 GetMwiType(dcs, *smsDcs);
349 }
350
DecodeDcsStoreGsmGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)351 void GsmSmsParamDecode::DecodeDcsStoreGsmGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
352 {
353 if (smsDcs == nullptr) {
354 TELEPHONY_LOGE("smsDcs is null.");
355 return;
356 }
357
358 smsDcs->codingGroup = CODING_STORE_GROUP;
359 smsDcs->codingScheme = DATA_CODING_7BIT;
360 GetMwiType(dcs, *smsDcs);
361 }
362
DecodeDcsStoreUCS2GroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)363 void GsmSmsParamDecode::DecodeDcsStoreUCS2GroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
364 {
365 if (smsDcs == nullptr) {
366 TELEPHONY_LOGE("smsDcs is null.");
367 return;
368 }
369
370 smsDcs->codingGroup = CODING_STORE_GROUP;
371 smsDcs->codingScheme = DATA_CODING_UCS2;
372 GetMwiType(dcs, *smsDcs);
373 }
374
DecodeDcsUnknownGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)375 void GsmSmsParamDecode::DecodeDcsUnknownGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
376 {
377 if (smsDcs == nullptr) {
378 TELEPHONY_LOGE("smsDcs is null.");
379 return;
380 }
381
382 smsDcs->codingGroup = CODING_UNKNOWN_GROUP;
383 smsDcs->bCompressed = (dcs & HEX_VALUE_20) >> HEX_VALUE_05;
384 smsDcs->codingScheme = GetMsgCodingScheme((dcs & HEX_VALUE_0C) >> HEX_VALUE_02);
385 smsDcs->msgClass = SMS_CLASS_UNKNOWN;
386 }
387
GetMsgClass(uint8_t dcs)388 enum SmsMessageClass GsmSmsParamDecode::GetMsgClass(uint8_t dcs)
389 {
390 return (enum SmsMessageClass)(dcs & HEX_VALUE_03);
391 }
392
GetMsgCodingScheme(uint8_t dcs)393 enum DataCodingScheme GsmSmsParamDecode::GetMsgCodingScheme(uint8_t dcs)
394 {
395 return (enum DataCodingScheme)(dcs & HEX_VALUE_03);
396 }
397
GetMsgIndicatorType(const uint8_t dcs)398 enum SmsIndicatorType GsmSmsParamDecode::GetMsgIndicatorType(const uint8_t dcs)
399 {
400 return (enum SmsIndicatorType)(dcs & HEX_VALUE_03);
401 }
402
GetMwiType(const uint8_t dcs,struct SmsDcs & smsDcs)403 void GsmSmsParamDecode::GetMwiType(const uint8_t dcs, struct SmsDcs &smsDcs)
404 {
405 smsDcs.bCompressed = false;
406 smsDcs.msgClass = SMS_CLASS_UNKNOWN;
407 smsDcs.bMWI = true;
408 smsDcs.bIndActive = (((dcs & HEX_VALUE_08) >> HEX_VALUE_03) == HEX_VALUE_01) ? true : false;
409 smsDcs.indType = GetMsgIndicatorType(dcs & HEX_VALUE_03);
410 }
411
DecodeTimePdu(SmsReadBuffer & buffer,struct SmsTimeStamp * timeStamp)412 bool GsmSmsParamDecode::DecodeTimePdu(SmsReadBuffer &buffer, struct SmsTimeStamp *timeStamp)
413 {
414 if (timeStamp == nullptr) {
415 TELEPHONY_LOGE("nullptr error.");
416 return false;
417 }
418 /* decode in ABSOLUTE time type. */
419 timeStamp->format = SMS_TIME_ABSOLUTE;
420
421 uint8_t pickByte = 0;
422 if (!buffer.PickOneByte(pickByte)) {
423 TELEPHONY_LOGE("get data error.");
424 return false;
425 }
426 uint8_t oneByte = 0;
427 if (!buffer.ReadByte(oneByte)) {
428 TELEPHONY_LOGE("get data error.");
429 return false;
430 }
431
432 timeStamp->time.absolute.year =
433 (pickByte & HEX_VALUE_0F) * HEX_VALUE_0A + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
434
435 if (!buffer.PickOneByte(pickByte)) {
436 TELEPHONY_LOGE("get data error.");
437 return false;
438 }
439 if (!buffer.ReadByte(oneByte)) {
440 TELEPHONY_LOGE("get data error.");
441 return false;
442 }
443 timeStamp->time.absolute.month =
444 (pickByte & HEX_VALUE_0F) * HEX_VALUE_0A + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
445 return DecodeTimePduPartData(buffer, timeStamp);
446 }
447
DecodeTimePduPartData(SmsReadBuffer & buffer,struct SmsTimeStamp * timeStamp)448 bool GsmSmsParamDecode::DecodeTimePduPartData(SmsReadBuffer &buffer, struct SmsTimeStamp *timeStamp)
449 {
450 uint8_t pickByte = 0;
451 if (!buffer.PickOneByte(pickByte)) {
452 TELEPHONY_LOGE("get data error.");
453 return false;
454 }
455
456 uint8_t oneByte = 0;
457 if (!buffer.ReadByte(oneByte)) {
458 TELEPHONY_LOGE("get data error.");
459 return false;
460 }
461 timeStamp->time.absolute.day =
462 (pickByte & HEX_VALUE_0F) * HEX_VALUE_0A + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
463
464 if (!buffer.PickOneByte(pickByte)) {
465 TELEPHONY_LOGE("get data error.");
466 return false;
467 }
468 if (!buffer.ReadByte(oneByte)) {
469 TELEPHONY_LOGE("get data error.");
470 return false;
471 }
472 timeStamp->time.absolute.hour =
473 (pickByte & HEX_VALUE_0F) * HEX_VALUE_0A + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
474
475 if (!buffer.PickOneByte(pickByte)) {
476 TELEPHONY_LOGE("get data error.");
477 return false;
478 }
479 if (!buffer.ReadByte(oneByte)) {
480 TELEPHONY_LOGE("get data error.");
481 return false;
482 }
483 timeStamp->time.absolute.minute =
484 (pickByte & HEX_VALUE_0F) * HEX_VALUE_0A + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
485 return DecodeTimePduData(buffer, timeStamp);
486 }
487
DecodeTimePduData(SmsReadBuffer & buffer,struct SmsTimeStamp * timeStamp)488 bool GsmSmsParamDecode::DecodeTimePduData(SmsReadBuffer &buffer, struct SmsTimeStamp *timeStamp)
489 {
490 if (timeStamp == nullptr) {
491 TELEPHONY_LOGE("nullptr error.");
492 return false;
493 }
494
495 uint8_t pickByte = 0;
496 if (!buffer.PickOneByte(pickByte)) {
497 TELEPHONY_LOGE("get data error.");
498 return false;
499 }
500
501 uint8_t oneByte = 0;
502 if (!buffer.ReadByte(oneByte)) {
503 TELEPHONY_LOGE("get data error.");
504 return false;
505 }
506 timeStamp->time.absolute.second =
507 (pickByte & HEX_VALUE_0F) * HEX_VALUE_0A + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
508
509 if (!buffer.PickOneByte(pickByte)) {
510 TELEPHONY_LOGE("get data error.");
511 return false;
512 }
513 if (!buffer.PickOneByte(oneByte)) {
514 TELEPHONY_LOGE("get data error.");
515 return false;
516 }
517 timeStamp->time.absolute.timeZone =
518 (pickByte & HEX_VALUE_07) * HEX_VALUE_0A + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
519
520 if (!buffer.ReadByte(oneByte)) {
521 TELEPHONY_LOGE("get data error.");
522 return false;
523 }
524 if (oneByte & HEX_VALUE_08) {
525 timeStamp->time.absolute.timeZone *= (-1);
526 }
527 return true;
528 }
529 } // namespace Telephony
530 } // namespace OHOS
531