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 "gsm_sms_param_decode.h"
17
18 #include "gsm_pdu_hex_value.h"
19 #include "gsm_sms_common_utils.h"
20 #include "gsm_user_data_pdu.h"
21 #include "securec.h"
22 #include "telephony_log_wrapper.h"
23 #include "text_coder.h"
24
25 namespace OHOS {
26 namespace Telephony {
27 static constexpr uint8_t SLIDE_DATA_STEP = 2;
28 static constexpr uint8_t BCD_TO_DIGITAL = 2;
29
DecodeAddressPdu(SmsReadBuffer & buffer,struct AddressNumber * resultNum)30 bool GsmSmsParamDecode::DecodeAddressPdu(SmsReadBuffer &buffer, struct AddressNumber *resultNum)
31 {
32 if (resultNum == nullptr) {
33 TELEPHONY_LOGE("nullptr error");
34 return false;
35 }
36 if (memset_s(resultNum->address, sizeof(resultNum->address), 0x00, sizeof(resultNum->address)) != EOK) {
37 TELEPHONY_LOGE("memset_s error!");
38 return false;
39 }
40
41 uint8_t oneByte = 0;
42 if (!buffer.ReadByte(oneByte) || oneByte >= BCD_TO_DIGITAL * (MAX_ADDRESS_LEN + 1)) {
43 TELEPHONY_LOGE("get data error.");
44 return false;
45 }
46 uint8_t addrLen = oneByte;
47 uint8_t bcdLen = 0;
48 if (addrLen % SLIDE_DATA_STEP == 0) {
49 bcdLen = addrLen / SLIDE_DATA_STEP;
50 } else {
51 bcdLen = addrLen / SLIDE_DATA_STEP + 1;
52 }
53
54 if (!buffer.PickOneByte(oneByte)) {
55 TELEPHONY_LOGE("get data error.");
56 return false;
57 }
58 resultNum->ton = (oneByte & HEX_VALUE_70) >> HEX_VALUE_04;
59
60 if (resultNum->ton == TYPE_ALPHA_NUMERIC) {
61 return DecodeAddressAlphaNum(buffer, resultNum, bcdLen, addrLen);
62 } else if (resultNum->ton == TYPE_INTERNATIONAL) {
63 return DecodeAddressInternationalNum(buffer, resultNum, bcdLen);
64 } else {
65 return DecodeAddressDefaultNum(buffer, resultNum, bcdLen);
66 }
67 }
68
DecodeAddressAlphaNum(SmsReadBuffer & buffer,struct AddressNumber * resultNum,uint8_t bcdLen,uint8_t addrLen)69 bool GsmSmsParamDecode::DecodeAddressAlphaNum(
70 SmsReadBuffer &buffer, struct AddressNumber *resultNum, uint8_t bcdLen, uint8_t addrLen)
71 {
72 uint8_t tmresultNum[MAX_ADDRESS_LEN] = { 0 };
73 uint8_t tmplength = 0;
74 GsmSmsCommonUtils utils;
75 uint8_t dataLen = (addrLen * HEX_VALUE_04) / HEX_VALUE_07;
76 if (!utils.Unpack7bitChar(buffer, dataLen, 0x00, tmresultNum, MAX_ADDRESS_LEN, tmplength)) {
77 TELEPHONY_LOGE("unpack 7bit char error!");
78 return false;
79 }
80 MsgLangInfo langInfo;
81 langInfo.bSingleShift = false;
82 langInfo.bLockingShift = false;
83 TextCoder::Instance().Gsm7bitToUtf8(
84 reinterpret_cast<uint8_t *>(resultNum->address), MAX_ADDRESS_LEN, tmresultNum, tmplength, langInfo);
85 return true;
86 }
87
DecodeAddressInternationalNum(SmsReadBuffer & buffer,struct AddressNumber * resultNum,uint8_t bcdLen)88 bool GsmSmsParamDecode::DecodeAddressInternationalNum(
89 SmsReadBuffer &buffer, struct AddressNumber *resultNum, uint8_t bcdLen)
90 {
91 buffer.MoveForward(1);
92 uint8_t oneByte = 0;
93 uint8_t index = 0;
94 uint8_t bcdArr[MAX_ADDRESS_LEN + 1] = { 0 };
95 while (index < bcdLen && index < MAX_ADDRESS_LEN) {
96 if (!buffer.ReadByte(oneByte)) {
97 TELEPHONY_LOGE("get data error.");
98 return false;
99 }
100 bcdArr[index++] = oneByte;
101 }
102
103 GsmSmsCommonUtils utils;
104 std::string addrNum;
105 if (!utils.BcdToDigit(bcdArr, bcdLen, addrNum, SMS_MAX_ADDRESS_LEN)) {
106 TELEPHONY_LOGE("BcdToDigit fail!");
107 return false;
108 }
109 for (uint8_t i = 0; i < addrNum.size() && i < MAX_ADDRESS_LEN; i++) {
110 resultNum->address[i + 1] = addrNum[i];
111 }
112
113 if (resultNum->address[1] != '\0') {
114 resultNum->address[0] = '+';
115 }
116 return true;
117 }
118
DecodeAddressDefaultNum(SmsReadBuffer & buffer,struct AddressNumber * resultNum,uint8_t bcdLen)119 bool GsmSmsParamDecode::DecodeAddressDefaultNum(SmsReadBuffer &buffer, struct AddressNumber *resultNum, uint8_t bcdLen)
120 {
121 uint8_t index = 0;
122 buffer.MoveForward(1);
123 uint8_t oneByte = 0;
124 uint8_t bcdArr[MAX_ADDRESS_LEN + 1] = { 0 };
125 while (index < bcdLen && index < MAX_ADDRESS_LEN) {
126 if (!buffer.ReadByte(oneByte)) {
127 TELEPHONY_LOGE("get data error.");
128 return false;
129 }
130 bcdArr[index++] = oneByte;
131 }
132 GsmSmsCommonUtils utils;
133 std::string addrNum;
134 if (!utils.BcdToDigit(bcdArr, bcdLen, addrNum, SMS_MAX_ADDRESS_LEN)) {
135 TELEPHONY_LOGE("BcdToDigit fail!");
136 return false;
137 }
138 for (uint8_t i = 0; i < addrNum.size() && i < MAX_ADDRESS_LEN; i++) {
139 resultNum->address[i] = addrNum[i];
140 }
141 return true;
142 }
143
DecodeSmscPdu(uint8_t * srcAddr,uint8_t addrLen,enum TypeOfNum ton,std::string & desAddr)144 void GsmSmsParamDecode::DecodeSmscPdu(uint8_t *srcAddr, uint8_t addrLen, enum TypeOfNum ton, std::string &desAddr)
145 {
146 if (srcAddr == nullptr || addrLen == 0) {
147 TELEPHONY_LOGE("smsc data error.");
148 return;
149 }
150
151 GsmSmsCommonUtils utils;
152 if (ton == TYPE_INTERNATIONAL) {
153 desAddr[0] = '+';
154 if (!utils.BcdToDigit(srcAddr, addrLen, desAddr, SMS_MAX_ADDRESS_LEN)) {
155 TELEPHONY_LOGE("BcdToDigit fail!");
156 return;
157 }
158 } else {
159 if (!utils.BcdToDigit(srcAddr, addrLen, desAddr, SMS_MAX_ADDRESS_LEN)) {
160 TELEPHONY_LOGE("BcdToDigit fail!");
161 return;
162 }
163 }
164 }
165
DecodeSmscPdu(const uint8_t * pTpdu,uint8_t pduLen,struct AddressNumber & desAddrObj)166 uint8_t GsmSmsParamDecode::DecodeSmscPdu(const uint8_t *pTpdu, uint8_t pduLen, struct AddressNumber &desAddrObj)
167 {
168 if (pTpdu == nullptr || pduLen == 0) {
169 TELEPHONY_LOGE("nullptr error.");
170 return 0;
171 }
172 if (memset_s(desAddrObj.address, sizeof(desAddrObj.address), 0x00, sizeof(desAddrObj.address)) != EOK) {
173 TELEPHONY_LOGE("memset_s error!");
174 return 0;
175 }
176
177 uint8_t offset = 0;
178 uint8_t addrLen = pTpdu[offset++];
179 if (addrLen == 0) {
180 TELEPHONY_LOGI("smsc is 00.");
181 return offset;
182 }
183 if (addrLen >= pduLen || offset >= pduLen) {
184 TELEPHONY_LOGI("smsc absent.");
185 return 0;
186 }
187 desAddrObj.ton = (pTpdu[offset] & HEX_VALUE_70) >> HEX_VALUE_04;
188 desAddrObj.npi = pTpdu[offset++] & HEX_VALUE_0F;
189
190 GsmSmsCommonUtils utils;
191 if (desAddrObj.ton == TYPE_INTERNATIONAL) {
192 if (addrLen > SMS_MAX_ADDRESS_LEN || (offset + addrLen) >= pduLen) {
193 TELEPHONY_LOGE("addrLen invalid.");
194 return 0;
195 }
196 std::string addrNum;
197 utils.BcdToDigit(&(pTpdu[offset]), addrLen, addrNum, SMS_MAX_ADDRESS_LEN);
198 for (uint8_t i = 0; i < addrNum.size() && i < MAX_ADDRESS_LEN; i++) {
199 desAddrObj.address[i + 1] = addrNum[i];
200 }
201 if (desAddrObj.address[1] != '\0') {
202 desAddrObj.address[0] = '+';
203 }
204 } else {
205 if (addrLen > SMS_MAX_ADDRESS_LEN || (offset + addrLen) >= pduLen) {
206 TELEPHONY_LOGE("addrLen invalid.");
207 return 0;
208 }
209 std::string addrNum;
210 utils.BcdToDigit(&(pTpdu[offset]), addrLen, addrNum, SMS_MAX_ADDRESS_LEN);
211 for (uint8_t i = 0; i < addrNum.size() && i < MAX_ADDRESS_LEN; i++) {
212 desAddrObj.address[i] = addrNum[i];
213 }
214 }
215
216 offset += (addrLen - 1);
217 return offset;
218 }
219
DecodeDcsPdu(SmsReadBuffer & buffer,struct SmsDcs * smsDcs)220 bool GsmSmsParamDecode::DecodeDcsPdu(SmsReadBuffer &buffer, struct SmsDcs *smsDcs)
221 {
222 if (smsDcs == nullptr) {
223 TELEPHONY_LOGE("smsDcs nullptr.");
224 return false;
225 }
226 uint8_t dcs = 0;
227 if (!buffer.ReadByte(dcs)) {
228 TELEPHONY_LOGE("get data error.");
229 return false;
230 }
231
232 smsDcs->bMWI = false;
233 smsDcs->bIndActive = false;
234 smsDcs->indType = SMS_OTHER_INDICATOR;
235 if (((dcs & HEX_VALUE_C0) >> HEX_VALUE_06) == 0) {
236 DecodeDcsGeneralGroupPdu(dcs, smsDcs);
237 } else if (((dcs & HEX_VALUE_F0) >> HEX_VALUE_04) == HEX_VALUE_0F) {
238 DecodeDcsClassGroupPdu(dcs, smsDcs);
239 } else if (((dcs & HEX_VALUE_C0) >> HEX_VALUE_06) == HEX_VALUE_01) {
240 DecodeDcsDeleteGroupPdu(dcs, smsDcs);
241 } else if (((dcs & HEX_VALUE_F0) >> HEX_VALUE_04) == HEX_VALUE_0C) {
242 DecodeDcsDiscardGroupPdu(dcs, smsDcs);
243 } else if (((dcs & HEX_VALUE_F0) >> HEX_VALUE_04) == HEX_VALUE_0D) {
244 DecodeDcsStoreGsmGroupPdu(dcs, smsDcs);
245 } else if (((dcs & HEX_VALUE_F0) >> HEX_VALUE_04) == HEX_VALUE_0E) {
246 DecodeDcsStoreUCS2GroupPdu(dcs, smsDcs);
247 } else {
248 DecodeDcsUnknownGroupPdu(dcs, smsDcs);
249 }
250 return true;
251 }
252
DecodeDcsGeneralGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)253 void GsmSmsParamDecode::DecodeDcsGeneralGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
254 {
255 if (smsDcs == nullptr) {
256 TELEPHONY_LOGE("smsDcs is nullptr.");
257 return;
258 }
259
260 smsDcs->codingGroup = CODING_GENERAL_GROUP;
261 smsDcs->bCompressed = (dcs & HEX_VALUE_20) >> HEX_VALUE_05;
262 smsDcs->codingScheme = GetMsgCodingScheme((dcs & HEX_VALUE_0C) >> HEX_VALUE_02);
263 if (((dcs & HEX_VALUE_10) >> HEX_VALUE_04) == 0) {
264 smsDcs->msgClass = SMS_CLASS_UNKNOWN;
265 } else {
266 smsDcs->msgClass = GetMsgClass(dcs & HEX_VALUE_03);
267 }
268 }
269
DecodeDcsClassGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)270 void GsmSmsParamDecode::DecodeDcsClassGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
271 {
272 if (smsDcs == nullptr) {
273 TELEPHONY_LOGE("smsDcs is nullptr.");
274 return;
275 }
276
277 smsDcs->codingGroup = SMS_CLASS_GROUP;
278 smsDcs->bCompressed = false;
279 smsDcs->codingScheme = GetMsgCodingScheme((dcs & HEX_VALUE_0C) >> HEX_VALUE_02);
280 smsDcs->msgClass = GetMsgClass(dcs & HEX_VALUE_03);
281 }
282
DecodeDcsDeleteGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)283 void GsmSmsParamDecode::DecodeDcsDeleteGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
284 {
285 if (smsDcs == nullptr) {
286 TELEPHONY_LOGE("smsDcs is nullptr.");
287 return;
288 }
289
290 smsDcs->codingGroup = CODING_DELETION_GROUP;
291 smsDcs->bCompressed = false;
292 smsDcs->msgClass = SMS_CLASS_UNKNOWN;
293 }
294
DecodeDcsDiscardGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)295 void GsmSmsParamDecode::DecodeDcsDiscardGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
296 {
297 if (smsDcs == nullptr) {
298 TELEPHONY_LOGE("smsDcs is null.");
299 return;
300 }
301
302 smsDcs->codingGroup = CODING_DISCARD_GROUP;
303 GetMwiType(dcs, *smsDcs);
304 }
305
DecodeDcsStoreGsmGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)306 void GsmSmsParamDecode::DecodeDcsStoreGsmGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
307 {
308 if (smsDcs == nullptr) {
309 TELEPHONY_LOGE("smsDcs is null.");
310 return;
311 }
312
313 smsDcs->codingGroup = CODING_STORE_GROUP;
314 smsDcs->codingScheme = DATA_CODING_7BIT;
315 GetMwiType(dcs, *smsDcs);
316 }
317
DecodeDcsStoreUCS2GroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)318 void GsmSmsParamDecode::DecodeDcsStoreUCS2GroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
319 {
320 if (smsDcs == nullptr) {
321 TELEPHONY_LOGE("smsDcs is null.");
322 return;
323 }
324
325 smsDcs->codingGroup = CODING_STORE_GROUP;
326 smsDcs->codingScheme = DATA_CODING_UCS2;
327 GetMwiType(dcs, *smsDcs);
328 }
329
DecodeDcsUnknownGroupPdu(uint8_t dcs,struct SmsDcs * smsDcs)330 void GsmSmsParamDecode::DecodeDcsUnknownGroupPdu(uint8_t dcs, struct SmsDcs *smsDcs)
331 {
332 if (smsDcs == nullptr) {
333 TELEPHONY_LOGE("smsDcs is null.");
334 return;
335 }
336
337 smsDcs->codingGroup = CODING_UNKNOWN_GROUP;
338 smsDcs->bCompressed = (dcs & HEX_VALUE_20) >> HEX_VALUE_05;
339 smsDcs->codingScheme = GetMsgCodingScheme((dcs & HEX_VALUE_0C) >> HEX_VALUE_02);
340 smsDcs->msgClass = SMS_CLASS_UNKNOWN;
341 }
342
GetMsgClass(uint8_t dcs)343 enum SmsMessageClass GsmSmsParamDecode::GetMsgClass(uint8_t dcs)
344 {
345 return (enum SmsMessageClass)(dcs & HEX_VALUE_03);
346 }
347
GetMsgCodingScheme(uint8_t dcs)348 enum DataCodingScheme GsmSmsParamDecode::GetMsgCodingScheme(uint8_t dcs)
349 {
350 return (enum DataCodingScheme)(dcs & HEX_VALUE_03);
351 }
352
GetMsgIndicatorType(const uint8_t dcs)353 enum SmsIndicatorType GsmSmsParamDecode::GetMsgIndicatorType(const uint8_t dcs)
354 {
355 return (enum SmsIndicatorType)(dcs & HEX_VALUE_03);
356 }
357
GetMwiType(const uint8_t dcs,struct SmsDcs & smsDcs)358 void GsmSmsParamDecode::GetMwiType(const uint8_t dcs, struct SmsDcs &smsDcs)
359 {
360 smsDcs.bCompressed = false;
361 smsDcs.msgClass = SMS_CLASS_UNKNOWN;
362 smsDcs.bMWI = true;
363 smsDcs.bIndActive = (((dcs & HEX_VALUE_08) >> HEX_VALUE_03) == HEX_VALUE_01) ? true : false;
364 smsDcs.indType = GetMsgIndicatorType(dcs & HEX_VALUE_03);
365 }
366
DecodeTimePdu(SmsReadBuffer & buffer,struct SmsTimeStamp * timeStamp)367 bool GsmSmsParamDecode::DecodeTimePdu(SmsReadBuffer &buffer, struct SmsTimeStamp *timeStamp)
368 {
369 if (timeStamp == nullptr) {
370 TELEPHONY_LOGE("nullptr error.");
371 return false;
372 }
373 /* decode in ABSOLUTE time type. */
374 timeStamp->format = SMS_TIME_ABSOLUTE;
375
376 uint8_t pickByte = 0;
377 if (!buffer.PickOneByte(pickByte)) {
378 TELEPHONY_LOGE("get data error.");
379 return false;
380 }
381 uint8_t oneByte = 0;
382 if (!buffer.ReadByte(oneByte)) {
383 TELEPHONY_LOGE("get data error.");
384 return false;
385 }
386
387 timeStamp->time.absolute.year =
388 (pickByte & HEX_VALUE_0F) * HEX_VALUE_10 + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
389
390 if (!buffer.PickOneByte(pickByte)) {
391 TELEPHONY_LOGE("get data error.");
392 return false;
393 }
394 if (!buffer.ReadByte(oneByte)) {
395 TELEPHONY_LOGE("get data error.");
396 return false;
397 }
398 timeStamp->time.absolute.month =
399 (pickByte & HEX_VALUE_0F) * HEX_VALUE_10 + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
400 return DecodeTimePduPartData(buffer, timeStamp);
401 }
402
DecodeTimePduPartData(SmsReadBuffer & buffer,struct SmsTimeStamp * timeStamp)403 bool GsmSmsParamDecode::DecodeTimePduPartData(SmsReadBuffer &buffer, struct SmsTimeStamp *timeStamp)
404 {
405 uint8_t pickByte = 0;
406 if (!buffer.PickOneByte(pickByte)) {
407 TELEPHONY_LOGE("get data error.");
408 return false;
409 }
410
411 uint8_t oneByte = 0;
412 if (!buffer.ReadByte(oneByte)) {
413 TELEPHONY_LOGE("get data error.");
414 return false;
415 }
416 timeStamp->time.absolute.day =
417 (pickByte & HEX_VALUE_0F) * HEX_VALUE_10 + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
418
419 if (!buffer.PickOneByte(pickByte)) {
420 TELEPHONY_LOGE("get data error.");
421 return false;
422 }
423 if (!buffer.ReadByte(oneByte)) {
424 TELEPHONY_LOGE("get data error.");
425 return false;
426 }
427 timeStamp->time.absolute.hour =
428 (pickByte & HEX_VALUE_0F) * HEX_VALUE_10 + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
429
430 if (!buffer.PickOneByte(pickByte)) {
431 TELEPHONY_LOGE("get data error.");
432 return false;
433 }
434 if (!buffer.ReadByte(oneByte)) {
435 TELEPHONY_LOGE("get data error.");
436 return false;
437 }
438 timeStamp->time.absolute.minute =
439 (pickByte & HEX_VALUE_0F) * HEX_VALUE_10 + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
440 return DecodeTimePduData(buffer, timeStamp);
441 }
442
DecodeTimePduData(SmsReadBuffer & buffer,struct SmsTimeStamp * timeStamp)443 bool GsmSmsParamDecode::DecodeTimePduData(SmsReadBuffer &buffer, struct SmsTimeStamp *timeStamp)
444 {
445 if (timeStamp == nullptr) {
446 TELEPHONY_LOGE("nullptr error.");
447 return false;
448 }
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.second =
462 (pickByte & HEX_VALUE_0F) * HEX_VALUE_10 + ((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.PickOneByte(oneByte)) {
469 TELEPHONY_LOGE("get data error.");
470 return false;
471 }
472 timeStamp->time.absolute.timeZone =
473 (pickByte & HEX_VALUE_07) * HEX_VALUE_10 + ((oneByte & HEX_VALUE_F0) >> HEX_VALUE_04);
474
475 if (!buffer.ReadByte(oneByte)) {
476 TELEPHONY_LOGE("get data error.");
477 return false;
478 }
479 if (oneByte & HEX_VALUE_08) {
480 timeStamp->time.absolute.timeZone *= (-1);
481 }
482 return true;
483 }
484 } // namespace Telephony
485 } // namespace OHOS
486