• 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_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