• 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_user_data_decode.h"
17 
18 #include "gsm_pdu_hex_value.h"
19 #include "gsm_sms_common_utils.h"
20 #include "securec.h"
21 #include "telephony_log_wrapper.h"
22 
23 namespace OHOS {
24 namespace Telephony {
25 using namespace std;
26 static constexpr uint8_t GSM_USER_DATA_LEN = 160;
27 static constexpr uint8_t NORMAL_BYTE_BITS = 8;
28 static constexpr uint8_t GSM_ENCODE_BITS = 7;
29 static constexpr uint8_t SLIDE_DATA_STEP = 2;
30 static constexpr uint8_t UCS2_USER_DATA_LEN = 140;
31 static constexpr uint8_t WAP_PUSH_UDHL = 7;
32 
GsmUserDataDecode(std::shared_ptr<GsmUserDataPdu> data)33 GsmUserDataDecode::GsmUserDataDecode(std::shared_ptr<GsmUserDataPdu> data)
34 {
35     userData_ = data;
36 }
37 
~GsmUserDataDecode()38 GsmUserDataDecode::~GsmUserDataDecode() {}
39 
DecodeGsmPdu(SmsReadBuffer & buffer,bool bHeaderInd,struct SmsUDPackage * userData,struct SmsTpud * pTPUD)40 bool GsmUserDataDecode::DecodeGsmPdu(
41     SmsReadBuffer &buffer, bool bHeaderInd, struct SmsUDPackage *userData, struct SmsTpud *pTPUD)
42 {
43     uint8_t udl = 0;
44     uint8_t fillBits = 0;
45     if (!DecodeGsmHeadPdu(buffer, bHeaderInd, userData, pTPUD, udl, fillBits)) {
46         TELEPHONY_LOGE("decode gsm head error");
47         return false;
48     }
49     return DecodeGsmBodyPdu(buffer, bHeaderInd, userData, pTPUD, udl, fillBits);
50 }
51 
DecodeGsmHeadPdu(SmsReadBuffer & buffer,bool bHeaderInd,struct SmsUDPackage * userData,struct SmsTpud * pTPUD,uint8_t & udl,uint8_t & fillBits)52 bool GsmUserDataDecode::DecodeGsmHeadPdu(SmsReadBuffer &buffer, bool bHeaderInd, struct SmsUDPackage *userData,
53     struct SmsTpud *pTPUD, uint8_t &udl, uint8_t &fillBits)
54 {
55     if (userData == nullptr) {
56         TELEPHONY_LOGE("nullptr error");
57         return false;
58     }
59 
60     /* UDL */
61     if (!buffer.ReadByte(udl)) {
62         TELEPHONY_LOGE("get data error.");
63         return false;
64     }
65     if (udl > GSM_USER_DATA_LEN) {
66         userData->length = 0;
67         userData->headerCnt = 0;
68         TELEPHONY_LOGE("udl error.");
69         return false;
70     }
71 
72     /* Setting for Wap Push */
73     if (pTPUD != nullptr && udl > 0) {
74         pTPUD->udl = udl;
75         if (udl > sizeof(pTPUD->ud)) {
76             TELEPHONY_LOGE("udl length error");
77             return false;
78         }
79         uint8_t len = udl;
80         if (buffer.GetIndex() + udl >= buffer.GetSize()) {
81             len = buffer.GetSize() - buffer.GetIndex();
82         }
83         if (buffer.data_ == nullptr || len > sizeof(pTPUD->ud)) {
84             TELEPHONY_LOGE("buffer error.");
85             return false;
86         }
87         if (memcpy_s(pTPUD->ud, sizeof(pTPUD->ud), buffer.data_.get() + buffer.GetIndex(), len) != EOK) {
88             TELEPHONY_LOGE("memcpy_s error");
89             return false;
90         }
91         pTPUD->ud[len] = '\0';
92     }
93     return DecodeGsmHeadPduPartData(buffer, bHeaderInd, userData, udl, fillBits);
94 }
95 
DecodeGsmHeadPduPartData(SmsReadBuffer & buffer,bool bHeaderInd,struct SmsUDPackage * userData,uint8_t & udl,uint8_t & fillBits)96 bool GsmUserDataDecode::DecodeGsmHeadPduPartData(
97     SmsReadBuffer &buffer, bool bHeaderInd, struct SmsUDPackage *userData, uint8_t &udl, uint8_t &fillBits)
98 {
99     if (userData_ == nullptr) {
100         TELEPHONY_LOGE("nullptr error.");
101         return false;
102     }
103     uint8_t udhl = 0;
104     /* Decode User Data Header */
105     if (bHeaderInd) {
106         /* UDHL */
107         if (!buffer.ReadByte(udhl)) {
108             TELEPHONY_LOGE("get data error.");
109             return false;
110         }
111         userData->headerCnt = 0;
112         uint8_t current = buffer.GetIndex();
113         for (int i = 0; buffer.GetIndex() < current + udhl && i < MAX_UD_HEADER_NUM; i++) {
114             uint16_t headerLen = 0;
115             if (!userData_->DecodeHeader(buffer, userData->header[i], headerLen)) {
116                 TELEPHONY_LOGE("DecodeHeader error");
117                 return false;
118             }
119             if (headerLen == 0) {
120                 userData_->ResetUserData(*userData);
121                 TELEPHONY_LOGE("headerLen error");
122                 return false;
123             }
124             if (buffer.GetIndex() > buffer.GetSize()) {
125                 TELEPHONY_LOGE("data buffer error)");
126                 userData_->ResetUserData(*userData);
127                 return false;
128             }
129             userData->headerCnt++;
130         }
131     } else {
132         userData->headerCnt = 0;
133     }
134 
135     if (udhl > 0) {
136         fillBits = ((udl * GSM_ENCODE_BITS) - ((udhl + 1) * NORMAL_BYTE_BITS)) % GSM_ENCODE_BITS;
137         udl = ((udl * GSM_ENCODE_BITS) - ((udhl + 1) * NORMAL_BYTE_BITS)) / GSM_ENCODE_BITS;
138     }
139     return true;
140 }
141 
DecodeGsmBodyPdu(SmsReadBuffer & buffer,bool bHeaderInd,struct SmsUDPackage * userData,struct SmsTpud * pTPUD,uint8_t & udl,uint8_t fillBits)142 bool GsmUserDataDecode::DecodeGsmBodyPdu(SmsReadBuffer &buffer, bool bHeaderInd, struct SmsUDPackage *userData,
143     struct SmsTpud *pTPUD, uint8_t &udl, uint8_t fillBits)
144 {
145     if (userData == nullptr) {
146         TELEPHONY_LOGE("nullptr error.");
147         return false;
148     }
149 
150     GsmSmsCommonUtils utils;
151     uint8_t length = 0;
152     bool ret = utils.Unpack7bitChar(
153         buffer, udl, fillBits, reinterpret_cast<uint8_t *>(userData->data), MAX_USER_DATA_LEN + 1, length);
154     if (ret) {
155         userData->length = length;
156     }
157     TELEPHONY_LOGI("decode gsm body result:%{public}d", ret);
158     return ret;
159 }
160 
Decode8bitPdu(SmsReadBuffer & buffer,bool bHeaderInd,struct SmsUDPackage * userData,struct SmsTpud * pTPUD)161 bool GsmUserDataDecode::Decode8bitPdu(
162     SmsReadBuffer &buffer, bool bHeaderInd, struct SmsUDPackage *userData, struct SmsTpud *pTPUD)
163 {
164     if (userData == nullptr) {
165         TELEPHONY_LOGE("nullptr error.");
166         return false;
167     }
168     /* UDL */
169     uint8_t udl = 0;
170     if (!buffer.ReadByte(udl)) {
171         TELEPHONY_LOGE("get data error.");
172         return false;
173     }
174     TELEPHONY_LOGI("udl:%{public}d", udl);
175     uint16_t current = buffer.GetIndex();
176 
177     if (udl > UCS2_USER_DATA_LEN) {
178         userData->length = 0;
179         TELEPHONY_LOGE("udl length error");
180         return false;
181     }
182     uint8_t udhl = 0;
183     if (!buffer.PickOneByte(udhl)) {
184         TELEPHONY_LOGE("get udhl error, use original value: 6");
185         udhl = WAP_PUSH_UDHL - 1;
186     }
187     /* Setting for Wap Push */
188     if (pTPUD != nullptr && udl > (udhl + 1)) {
189         pTPUD->udl = udl - (udhl + 1);
190         if (pTPUD->udl >= sizeof(pTPUD->ud)) {
191             TELEPHONY_LOGE("udl length error");
192             return false;
193         }
194 
195         if (buffer.data_ == nullptr || (buffer.GetIndex() + pTPUD->udl + (udhl + 1) > buffer.GetSize())) {
196             TELEPHONY_LOGE("buffer error.");
197             return false;
198         }
199         if (memcpy_s(pTPUD->ud, sizeof(pTPUD->ud), buffer.data_.get() + buffer.GetIndex() + (udhl + 1),
200                 pTPUD->udl) != EOK) {
201             TELEPHONY_LOGE("memcpy_s error.");
202             return false;
203         }
204         pTPUD->ud[pTPUD->udl] = '\0';
205     }
206     return Decode8bitPduPartData(buffer, bHeaderInd, userData, pTPUD, current, udl);
207 }
208 
Decode8bitPduPartData(SmsReadBuffer & buffer,bool bHeaderInd,struct SmsUDPackage * userData,struct SmsTpud * pTPUD,uint16_t current,uint8_t udl)209 bool GsmUserDataDecode::Decode8bitPduPartData(SmsReadBuffer &buffer, bool bHeaderInd, struct SmsUDPackage *userData,
210     struct SmsTpud *pTPUD, uint16_t current, uint8_t udl)
211 {
212     if (userData_ == nullptr) {
213         TELEPHONY_LOGE("nullptr error.");
214         return false;
215     }
216 
217     uint8_t udhl = 0;
218     /* Decode User Data Header */
219     if (bHeaderInd) {
220         /* UDHL */
221         if (!buffer.ReadByte(udhl)) {
222             TELEPHONY_LOGE("get data error.");
223             return false;
224         }
225         userData->headerCnt = 0;
226         current = buffer.GetIndex();
227         for (uint8_t i = 0; (buffer.GetIndex() - current) < udhl && i < MAX_UD_HEADER_NUM; i++) {
228             if (!userData_->GetHeaderCnt(buffer, userData, udhl, i)) {
229                 TELEPHONY_LOGI("data error");
230                 return false;
231             }
232         }
233     } else {
234         userData->headerCnt = 0;
235     }
236 
237     if (udhl > 0 && udl >= udhl + 1) {
238         userData->length = (udl) - (udhl + 1);
239         buffer.MoveForward(HEX_VALUE_01);
240     } else {
241         userData->length = udl;
242     }
243     if (udl > sizeof(pTPUD->ud) || buffer.GetIndex() > buffer.GetSize()) {
244         TELEPHONY_LOGE("udl length or buffer error");
245         return false;
246     }
247     uint8_t remain = buffer.GetSize() - buffer.GetIndex();
248     uint8_t len = userData->length < remain ? userData->length : remain;
249     if (len == 0) {
250         TELEPHONY_LOGI("user data length 0.");
251         return true;
252     }
253     if (buffer.data_ == nullptr || len > sizeof(userData->data)) {
254         TELEPHONY_LOGE("buffer error.");
255         return false;
256     }
257     if (memcpy_s(userData->data, sizeof(userData->data), buffer.data_.get() + buffer.GetIndex(), len) != EOK) {
258         TELEPHONY_LOGE("memcpy_s error");
259         return false;
260     }
261     buffer.MoveForward(userData->length);
262     return true;
263 }
264 
DecodeUcs2Pdu(SmsReadBuffer & buffer,bool bHeaderInd,struct SmsUDPackage * userData,struct SmsTpud * pTPUD)265 bool GsmUserDataDecode::DecodeUcs2Pdu(
266     SmsReadBuffer &buffer, bool bHeaderInd, struct SmsUDPackage *userData, struct SmsTpud *pTPUD)
267 {
268     if (userData == nullptr) {
269         TELEPHONY_LOGE("nullptr error.");
270         return false;
271     }
272     uint16_t current = buffer.GetIndex();
273 
274     /* UDL */
275     uint8_t udl = 0;
276     if (!buffer.ReadByte(udl)) {
277         TELEPHONY_LOGE("get data error.");
278         return false;
279     }
280     if (udl > UCS2_USER_DATA_LEN || (udl + buffer.GetIndex() - 1) > buffer.GetSize()) {
281         TELEPHONY_LOGE("udl error.");
282         userData->length = 0;
283         userData->headerCnt = 0;
284         return false;
285     }
286     if (buffer.data_ == nullptr) {
287         TELEPHONY_LOGE("buffer error.");
288         return false;
289     }
290     /* Setting for Wap Push */
291     if (pTPUD != nullptr) {
292         pTPUD->udl = udl;
293         if (udl > sizeof(pTPUD->ud) || (buffer.GetIndex() + udl) > buffer.GetSize()) {
294             TELEPHONY_LOGE("udl error.");
295             return false;
296         }
297         if (memcpy_s(pTPUD->ud, sizeof(pTPUD->ud), buffer.data_.get() + buffer.GetIndex(), udl) != EOK) {
298             TELEPHONY_LOGE("memcpy_s error.");
299             return false;
300         }
301         pTPUD->ud[udl] = '\0';
302     }
303     return DecodeUcs2PduPartData(buffer, bHeaderInd, userData, current, udl);
304 }
305 
DecodeUcs2PduPartData(SmsReadBuffer & buffer,bool bHeaderInd,struct SmsUDPackage * userData,uint16_t current,uint8_t udl)306 bool GsmUserDataDecode::DecodeUcs2PduPartData(
307     SmsReadBuffer &buffer, bool bHeaderInd, struct SmsUDPackage *userData, uint16_t current, uint8_t udl)
308 {
309     if (userData_ == nullptr) {
310         TELEPHONY_LOGE("nullptr error.");
311         return false;
312     }
313     uint8_t udhl = 0;
314     userData->headerCnt = 0;
315     /* Decode User Data Header */
316     if (bHeaderInd == true) {
317         /* UDHL */
318         if (!buffer.ReadByte(udhl)) {
319             TELEPHONY_LOGE("get data error.");
320             return false;
321         }
322         for (uint8_t i = 0; buffer.GetIndex() < udhl + current && i < MAX_UD_HEADER_NUM; i++) {
323             uint16_t headerLen;
324             if (!userData_->DecodeHeader(buffer, userData->header[i], headerLen)) {
325                 TELEPHONY_LOGE("DecodeHeader error");
326                 return false;
327             }
328             if (headerLen == 0 || buffer.GetIndex() > (current + udhl + SLIDE_DATA_STEP)) {
329                 userData_->ResetUserData(*userData);
330                 return false;
331             }
332             userData->headerCnt++;
333         }
334     }
335 
336     if (udhl > 0 && udl >= udhl + 1) {
337         userData->length = (udl) - (udhl + 1);
338     } else {
339         userData->length = udl;
340     }
341 
342     if (buffer.GetIndex() > buffer.GetSize()) {
343         TELEPHONY_LOGE("udl length or buffer error");
344         return false;
345     }
346     uint8_t remain = buffer.GetSize() - buffer.GetIndex();
347     uint8_t len = userData->length < remain ? userData->length : remain;
348     if (len == 0) {
349         return true;
350     }
351     if (buffer.data_ == nullptr || len > sizeof(userData->data)) {
352         return false;
353     }
354     if (memcpy_s(userData->data, sizeof(userData->data), buffer.data_.get() + buffer.GetIndex(), len) != EOK) {
355         return false;
356     }
357 
358     buffer.MoveForward(userData->length);
359     uint8_t index = userData->length >= sizeof(userData->data) ? sizeof(userData->data) - 1 : userData->length;
360     userData->data[index] = 0;
361     return true;
362 }
363 } // namespace Telephony
364 } // namespace OHOS