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_tpdu_decode.h"
17
18 #include "gsm_pdu_hex_value.h"
19 #include "gsm_user_data_pdu.h"
20 #include "securec.h"
21 #include "telephony_log_wrapper.h"
22
23 namespace OHOS {
24 namespace Telephony {
25 using namespace std;
GsmSmsTpduDecode(std::shared_ptr<GsmUserDataPdu> dataCodec,std::shared_ptr<GsmSmsParamCodec> paramCodec,std::shared_ptr<GsmSmsTpduCodec> tpdu)26 GsmSmsTpduDecode::GsmSmsTpduDecode(std::shared_ptr<GsmUserDataPdu> dataCodec,
27 std::shared_ptr<GsmSmsParamCodec> paramCodec, std::shared_ptr<GsmSmsTpduCodec> tpdu)
28 {
29 uDataCodec_ = dataCodec;
30 paramCodec_ = paramCodec;
31 tpdu_ = tpdu;
32 }
33
~GsmSmsTpduDecode()34 GsmSmsTpduDecode::~GsmSmsTpduDecode() {}
35
DecodeSubmit(SmsReadBuffer & buffer,struct SmsSubmit * submit)36 bool GsmSmsTpduDecode::DecodeSubmit(SmsReadBuffer &buffer, struct SmsSubmit *submit)
37 {
38 if (submit == nullptr || tpdu_ == nullptr) {
39 TELEPHONY_LOGE("nullptr error.");
40 return false;
41 }
42
43 tpdu_->DebugTpdu(buffer, PARSE_SUBMIT_TYPE);
44 // TP-RD
45 uint8_t oneByte = 0;
46 if (!buffer.PickOneByte(oneByte)) {
47 TELEPHONY_LOGE("get data error.");
48 return false;
49 }
50 if (oneByte & HEX_VALUE_04) {
51 submit->bRejectDup = false;
52 } else {
53 submit->bRejectDup = true;
54 }
55 // TP-VPF
56 if (!buffer.PickOneByte(oneByte)) {
57 TELEPHONY_LOGE("get data error.");
58 return false;
59 }
60 submit->vpf = static_cast<enum SmsVpf>(oneByte & HEX_VALUE_18);
61 // TP-SRR
62 if (!buffer.PickOneByte(oneByte)) {
63 TELEPHONY_LOGE("get data error.");
64 return false;
65 }
66 if (oneByte & HEX_VALUE_20) {
67 submit->bStatusReport = true;
68 } else {
69 submit->bStatusReport = false;
70 }
71 // TP-UDHI
72 if (!buffer.PickOneByte(oneByte)) {
73 TELEPHONY_LOGE("get data error.");
74 return false;
75 }
76 if (oneByte & HEX_VALUE_40) {
77 submit->bHeaderInd = true;
78 } else {
79 submit->bHeaderInd = false;
80 }
81 return DecodeSubmitPartData(buffer, submit);
82 }
83
DecodeSubmitPartData(SmsReadBuffer & buffer,struct SmsSubmit * submit)84 bool GsmSmsTpduDecode::DecodeSubmitPartData(SmsReadBuffer &buffer, struct SmsSubmit *submit)
85 {
86 if (paramCodec_ == nullptr || uDataCodec_ == nullptr) {
87 TELEPHONY_LOGE("nullptr error.");
88 return false;
89 }
90 uint8_t oneByte = 0;
91 // TP-RP
92 if (!buffer.PickOneByte(oneByte)) {
93 TELEPHONY_LOGE("get data error.");
94 return false;
95 }
96 if (oneByte & HEX_VALUE_80) {
97 submit->bReplyPath = true;
98 } else {
99 submit->bReplyPath = false;
100 }
101 buffer.MoveForward(1);
102
103 // TP-MR
104 if (!buffer.ReadByte(oneByte)) {
105 TELEPHONY_LOGE("get data error.");
106 return false;
107 }
108 submit->msgRef = oneByte;
109 // TP-DA
110 if (!paramCodec_->DecodeAddressPdu(buffer, &(submit->destAddress))) {
111 TELEPHONY_LOGE("DecodeAddressPdu Fail");
112 return false;
113 }
114 // TP-PID
115 if (!buffer.ReadByte(oneByte)) {
116 TELEPHONY_LOGE("get data error.");
117 return false;
118 }
119 submit->pid = tpdu_->ParsePid(oneByte);
120 // TP-DCS
121 if (!paramCodec_->DecodeDcsPdu(buffer, &(submit->dcs))) {
122 TELEPHONY_LOGE("DecodeDcsPdu Fail");
123 return false;
124 }
125 // TP-VP
126 if (submit->vpf != SMS_VPF_NOT_PRESENT) {
127 // Decode VP
128 }
129 // TP-UDL & TP-UD
130 bool result =
131 uDataCodec_->DecodeUserDataPdu(buffer, submit->bHeaderInd, submit->dcs.codingScheme, &(submit->userData));
132 TELEPHONY_LOGI("decode submit result : =%{public}d", result);
133 return result;
134 }
135
DecodePartData(const uint8_t & pTpdu,struct SmsDeliver & deliver)136 void DecodePartData(const uint8_t &pTpdu, struct SmsDeliver &deliver)
137 {
138 /* TP-MMS */
139 if (pTpdu & HEX_VALUE_04) {
140 deliver.bMoreMsg = false;
141 } else {
142 deliver.bMoreMsg = true;
143 }
144 /* TP-SRI */
145 if (pTpdu & HEX_VALUE_20) {
146 deliver.bStatusReport = true;
147 } else {
148 deliver.bStatusReport = false;
149 }
150 /* TP-UDHI */
151 if (pTpdu & HEX_VALUE_40) {
152 deliver.bHeaderInd = true;
153 } else {
154 deliver.bHeaderInd = false;
155 }
156 /* TP-RP */
157 if (pTpdu & HEX_VALUE_80) {
158 deliver.bReplyPath = true;
159 } else {
160 deliver.bReplyPath = false;
161 }
162 }
163
DecodeDeliver(SmsReadBuffer & buffer,struct SmsDeliver * deliver)164 bool GsmSmsTpduDecode::DecodeDeliver(SmsReadBuffer &buffer, struct SmsDeliver *deliver)
165 {
166 if (deliver == nullptr || tpdu_ == nullptr || paramCodec_ == nullptr) {
167 TELEPHONY_LOGE("nullptr error.");
168 return false;
169 }
170
171 uint8_t oneByte = 0;
172 if (!buffer.ReadByte(oneByte)) {
173 TELEPHONY_LOGE("get data error.");
174 return false;
175 }
176 tpdu_->DebugTpdu(buffer, PARSE_DELIVER_TYPE);
177 DecodePartData(oneByte, *deliver);
178
179 /* TP-OA */
180 if (!paramCodec_->DecodeAddressPdu(buffer, &(deliver->originAddress))) {
181 TELEPHONY_LOGE("DecodeAddressPdu fail");
182 return false;
183 }
184
185 /* TP-PID */
186 if (!buffer.ReadByte(oneByte)) {
187 TELEPHONY_LOGE("get data error.");
188 return false;
189 }
190 deliver->pid = tpdu_->ParsePid(oneByte);
191 /* TP-DCS */
192 if (!paramCodec_->DecodeDcsPdu(buffer, &(deliver->dcs))) {
193 TELEPHONY_LOGE("decode dcs fail.");
194 return false;
195 }
196 /* Support KSC5601 :: Coding group bits == 0x84 */
197 if (!buffer.PickOneByteFromIndex(buffer.GetIndex() - 1, oneByte)) {
198 TELEPHONY_LOGE("get data error.");
199 return false;
200 }
201 if (oneByte == HEX_VALUE_84) {
202 deliver->dcs.codingScheme = DATA_CODING_EUCKR;
203 }
204 return DecodeDeliverPartData(buffer, deliver);
205 }
206
DecodeDeliverPartData(SmsReadBuffer & buffer,struct SmsDeliver * deliver)207 bool GsmSmsTpduDecode::DecodeDeliverPartData(SmsReadBuffer &buffer, struct SmsDeliver *deliver)
208 {
209 if (uDataCodec_ == nullptr) {
210 TELEPHONY_LOGE("nullptr error.");
211 return false;
212 }
213
214 if (deliver->pid == HEX_VALUE_20 && deliver->originAddress.ton == TYPE_ALPHA_NUMERIC) {
215 int32_t setType = -1;
216 int32_t indType = -1;
217 bool voicemail = paramCodec_->CheckVoicemail(buffer, &setType, &indType);
218 if (voicemail) {
219 deliver->dcs.bMWI = true;
220 if (setType == 0) {
221 deliver->dcs.bIndActive = false;
222 } else {
223 deliver->dcs.bIndActive = true;
224 }
225 if (indType == 0) {
226 deliver->dcs.indType = SMS_VOICE_INDICATOR;
227 } else if (indType == 1) {
228 deliver->dcs.indType = SMS_VOICE2_INDICATOR;
229 }
230 }
231 }
232
233 /* TP-SCTS */
234 if (!paramCodec_->DecodeTimePdu(buffer, &(deliver->timeStamp))) {
235 TELEPHONY_LOGE("decode time fail.");
236 return false;
237 }
238 /* TP-UD */
239 bool result = uDataCodec_->DecodeUserDataPdu(
240 buffer, deliver->bHeaderInd, deliver->dcs.codingScheme, &(deliver->userData), &(deliver->udData));
241 if (!result) {
242 TELEPHONY_LOGE("decode delivery fail.");
243 }
244 return result;
245 }
246
DecodeStatusReport(SmsReadBuffer & buffer,struct SmsStatusReport * statusRep)247 bool GsmSmsTpduDecode::DecodeStatusReport(SmsReadBuffer &buffer, struct SmsStatusReport *statusRep)
248 {
249 /* TP-MMS */
250 if (statusRep == nullptr || paramCodec_ == nullptr) {
251 TELEPHONY_LOGE("nullptr error.");
252 return false;
253 }
254
255 uint8_t oneByte = 0;
256 if (!buffer.PickOneByte(oneByte)) {
257 TELEPHONY_LOGE("get data error.");
258 return false;
259 }
260 statusRep->bMoreMsg = (oneByte & HEX_VALUE_04) ? false : true;
261 /* TP-SRQ */
262
263 if (!buffer.PickOneByte(oneByte)) {
264 TELEPHONY_LOGE("get data error.");
265 return false;
266 }
267 statusRep->bStatusReport = (oneByte & HEX_VALUE_20) ? true : false;
268 /* TP-UDHI */
269 if (!buffer.ReadByte(oneByte)) {
270 TELEPHONY_LOGE("get data error.");
271 return false;
272 }
273 statusRep->bHeaderInd = (oneByte & HEX_VALUE_40) ? true : false;
274 /* TP-MR */
275 if (!buffer.ReadByte(oneByte)) {
276 TELEPHONY_LOGE("get data error.");
277 return false;
278 }
279 statusRep->msgRef = oneByte;
280 /* TP-RA */
281
282 if (!paramCodec_->DecodeAddressPdu(buffer, &(statusRep->recipAddress))) {
283 TELEPHONY_LOGE("decode addr fail.");
284 return false;
285 }
286
287 /* TP-SCTS */
288 /* Decode timestamp */
289 if (!paramCodec_->DecodeTimePdu(buffer, &(statusRep->timeStamp))) {
290 TELEPHONY_LOGE("decode time fail.");
291 return false;
292 }
293 return DecodeStatusReportPartData(buffer, statusRep);
294 }
295
DecodeStatusReportPartData(SmsReadBuffer & buffer,struct SmsStatusReport * statusRep)296 bool GsmSmsTpduDecode::DecodeStatusReportPartData(SmsReadBuffer &buffer, struct SmsStatusReport *statusRep)
297 {
298 /* TP-DT */
299 /* Decode timestamp */
300 if (!paramCodec_->DecodeTimePdu(buffer, &(statusRep->dischargeTime))) {
301 TELEPHONY_LOGE("decode time fail.");
302 return false;
303 }
304 /* TP-Status */
305 uint8_t oneByte = 0;
306 if (!buffer.ReadByte(oneByte)) {
307 TELEPHONY_LOGE("get data error.");
308 return false;
309 }
310 statusRep->status = oneByte;
311 /* TP-PI */
312 if (!buffer.ReadByte(oneByte)) {
313 TELEPHONY_LOGE("no pdu data remains.");
314 return true;
315 }
316 statusRep->paramInd = oneByte;
317 /* No Parameters */
318 if (statusRep->paramInd == 0) {
319 statusRep->pid = SMS_NORMAL_PID;
320 statusRep->dcs.bCompressed = false;
321 statusRep->dcs.bMWI = false;
322 statusRep->dcs.bIndActive = false;
323 statusRep->dcs.msgClass = SMS_CLASS_UNKNOWN;
324 statusRep->dcs.codingScheme = DATA_CODING_7BIT;
325 statusRep->dcs.codingGroup = CODING_GENERAL_GROUP;
326 statusRep->dcs.indType = SMS_OTHER_INDICATOR;
327 statusRep->userData.headerCnt = 0;
328 statusRep->userData.length = 0;
329 int ret = memset_s(statusRep->userData.data, sizeof(statusRep->userData.data), 0x00, MAX_USER_DATA_LEN + 1);
330 if (ret != EOK) {
331 TELEPHONY_LOGE("memset_s error.");
332 return false;
333 }
334 }
335 return DecodeStatusReportData(buffer, statusRep);
336 }
337
DecodeStatusReportData(SmsReadBuffer & buffer,struct SmsStatusReport * statusRep)338 bool GsmSmsTpduDecode::DecodeStatusReportData(SmsReadBuffer &buffer, struct SmsStatusReport *statusRep)
339 {
340 if (tpdu_ == nullptr || uDataCodec_ == nullptr) {
341 TELEPHONY_LOGE("nullptr error.");
342 return false;
343 }
344
345 /* TP-PID */
346 if (statusRep->paramInd & HEX_VALUE_01) {
347 uint8_t oneByte = 0;
348 if (!buffer.ReadByte(oneByte)) {
349 TELEPHONY_LOGE("get data error.");
350 return false;
351 }
352 statusRep->pid = tpdu_->ParsePid(oneByte);
353 }
354 /* TP-DCS */
355 if (statusRep->paramInd & HEX_VALUE_02) {
356 if (!paramCodec_->DecodeDcsPdu(buffer, &(statusRep->dcs))) {
357 TELEPHONY_LOGE("decode dcs fail.");
358 return false;
359 }
360 }
361 /* TP-UDL & TP-UD */
362 bool result = true;
363 if (statusRep->paramInd & HEX_VALUE_04) {
364 /* Decode User Data */
365 result = uDataCodec_->DecodeUserDataPdu(
366 buffer, statusRep->bHeaderInd, statusRep->dcs.codingScheme, &(statusRep->userData));
367 }
368 TELEPHONY_LOGI("decode status result : =%{public}d", result);
369 return result;
370 }
371 } // namespace Telephony
372 } // namespace OHOS