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 TELEPHONY_LOGI("decode delivery result : =%{public}d", result);
242 return result;
243 }
244
DecodeStatusReport(SmsReadBuffer & buffer,struct SmsStatusReport * statusRep)245 bool GsmSmsTpduDecode::DecodeStatusReport(SmsReadBuffer &buffer, struct SmsStatusReport *statusRep)
246 {
247 /* TP-MMS */
248 if (statusRep == nullptr || paramCodec_ == nullptr) {
249 TELEPHONY_LOGE("nullptr error.");
250 return false;
251 }
252
253 uint8_t oneByte = 0;
254 if (!buffer.PickOneByte(oneByte)) {
255 TELEPHONY_LOGE("get data error.");
256 return false;
257 }
258 statusRep->bMoreMsg = (oneByte & HEX_VALUE_04) ? false : true;
259 /* TP-SRQ */
260
261 if (!buffer.PickOneByte(oneByte)) {
262 TELEPHONY_LOGE("get data error.");
263 return false;
264 }
265 statusRep->bStatusReport = (oneByte & HEX_VALUE_20) ? true : false;
266 /* TP-UDHI */
267 if (!buffer.ReadByte(oneByte)) {
268 TELEPHONY_LOGE("get data error.");
269 return false;
270 }
271 statusRep->bHeaderInd = (oneByte & HEX_VALUE_40) ? true : false;
272 /* TP-MR */
273 if (!buffer.ReadByte(oneByte)) {
274 TELEPHONY_LOGE("get data error.");
275 return false;
276 }
277 statusRep->msgRef = oneByte;
278 /* TP-RA */
279
280 if (!paramCodec_->DecodeAddressPdu(buffer, &(statusRep->recipAddress))) {
281 TELEPHONY_LOGE("decode addr fail.");
282 return false;
283 }
284
285 /* TP-SCTS */
286 /* Decode timestamp */
287 if (!paramCodec_->DecodeTimePdu(buffer, &(statusRep->timeStamp))) {
288 TELEPHONY_LOGE("decode time fail.");
289 return false;
290 }
291 return DecodeStatusReportPartData(buffer, statusRep);
292 }
293
DecodeStatusReportPartData(SmsReadBuffer & buffer,struct SmsStatusReport * statusRep)294 bool GsmSmsTpduDecode::DecodeStatusReportPartData(SmsReadBuffer &buffer, struct SmsStatusReport *statusRep)
295 {
296 /* TP-DT */
297 /* Decode timestamp */
298 if (!paramCodec_->DecodeTimePdu(buffer, &(statusRep->dischargeTime))) {
299 TELEPHONY_LOGE("decode time fail.");
300 return false;
301 }
302 /* TP-Status */
303 uint8_t oneByte = 0;
304 if (!buffer.ReadByte(oneByte)) {
305 TELEPHONY_LOGE("get data error.");
306 return false;
307 }
308 statusRep->status = oneByte;
309 /* TP-PI */
310 if (!buffer.ReadByte(oneByte)) {
311 TELEPHONY_LOGE("no pdu data remains.");
312 return true;
313 }
314 statusRep->paramInd = oneByte;
315 /* No Parameters */
316 if (statusRep->paramInd == 0) {
317 statusRep->pid = SMS_NORMAL_PID;
318 statusRep->dcs.bCompressed = false;
319 statusRep->dcs.bMWI = false;
320 statusRep->dcs.bIndActive = false;
321 statusRep->dcs.msgClass = SMS_CLASS_UNKNOWN;
322 statusRep->dcs.codingScheme = DATA_CODING_7BIT;
323 statusRep->dcs.codingGroup = CODING_GENERAL_GROUP;
324 statusRep->dcs.indType = SMS_OTHER_INDICATOR;
325 statusRep->userData.headerCnt = 0;
326 statusRep->userData.length = 0;
327 int ret = memset_s(statusRep->userData.data, sizeof(statusRep->userData.data), 0x00, MAX_USER_DATA_LEN + 1);
328 if (ret != EOK) {
329 TELEPHONY_LOGE("memset_s error.");
330 return false;
331 }
332 }
333 return DecodeStatusReportData(buffer, statusRep);
334 }
335
DecodeStatusReportData(SmsReadBuffer & buffer,struct SmsStatusReport * statusRep)336 bool GsmSmsTpduDecode::DecodeStatusReportData(SmsReadBuffer &buffer, struct SmsStatusReport *statusRep)
337 {
338 if (tpdu_ == nullptr || uDataCodec_ == nullptr) {
339 TELEPHONY_LOGE("nullptr error.");
340 return false;
341 }
342
343 uint8_t oneByte = 0;
344 /* TP-PID */
345 if (statusRep->paramInd & HEX_VALUE_01) {
346 if (!buffer.ReadByte(oneByte)) {
347 TELEPHONY_LOGE("get data error.");
348 return false;
349 }
350 statusRep->pid = tpdu_->ParsePid(oneByte);
351 }
352 /* TP-DCS */
353 if (statusRep->paramInd & HEX_VALUE_02) {
354 if (!paramCodec_->DecodeDcsPdu(buffer, &(statusRep->dcs))) {
355 TELEPHONY_LOGE("decode dcs fail.");
356 return false;
357 }
358 }
359 /* TP-UDL & TP-UD */
360 bool result = true;
361 if (statusRep->paramInd & HEX_VALUE_04) {
362 /* Decode User Data */
363 result = uDataCodec_->DecodeUserDataPdu(
364 buffer, statusRep->bHeaderInd, statusRep->dcs.codingScheme, &(statusRep->userData));
365 }
366 TELEPHONY_LOGI("decode status result : =%{public}d", result);
367 return result;
368 }
369 } // namespace Telephony
370 } // namespace OHOS