• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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