• 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 "cdma_sms_parameter_record.h"
17 
18 #include "securec.h"
19 #include "sms_common_utils.h"
20 #include "telephony_log_wrapper.h"
21 
22 namespace OHOS {
23 namespace Telephony {
IsInvalidPdu(SmsReadBuffer & pdu)24 bool CdmaSmsParameterRecord::IsInvalidPdu(SmsReadBuffer &pdu)
25 {
26     uint8_t id = RESERVED;
27     if (pdu.IsEmpty() || !pdu.ReadByte(id) || !pdu.ReadByte(len_) || id != id_) {
28         TELEPHONY_LOGE("parameter record: pdu is invalid[%{public}d]: [%{public}d]", id_, id);
29         return true;
30     }
31     return false;
32 }
33 
CdmaSmsTeleserviceId(uint16_t & id)34 CdmaSmsTeleserviceId::CdmaSmsTeleserviceId(uint16_t &id) : teleserviceId_(id)
35 {
36     id_ = TELESERVICE_ID;
37     len_ = sizeof(teleserviceId_);
38 }
39 
Encode(SmsWriteBuffer & pdu)40 bool CdmaSmsTeleserviceId::Encode(SmsWriteBuffer &pdu)
41 {
42     if (pdu.IsEmpty()) {
43         TELEPHONY_LOGE("pdu is empty");
44         return false;
45     }
46 
47     if (pdu.WriteByte(id_) && pdu.WriteByte(len_) && pdu.WriteWord(teleserviceId_)) {
48         return true;
49     }
50 
51     TELEPHONY_LOGE("encode error");
52     return false;
53 }
54 
Decode(SmsReadBuffer & pdu)55 bool CdmaSmsTeleserviceId::Decode(SmsReadBuffer &pdu)
56 {
57     if (IsInvalidPdu(pdu)) {
58         TELEPHONY_LOGE("invalid pdu");
59         return false;
60     }
61     return pdu.ReadWord(teleserviceId_);
62 }
63 
CdmaSmsServiceCategory(uint16_t & cat)64 CdmaSmsServiceCategory::CdmaSmsServiceCategory(uint16_t &cat) : serviceCat_(cat)
65 {
66     id_ = SERVICE_CATEGORY;
67     len_ = sizeof(serviceCat_);
68 }
69 
Encode(SmsWriteBuffer & pdu)70 bool CdmaSmsServiceCategory::Encode(SmsWriteBuffer &pdu)
71 {
72     if (pdu.IsEmpty()) {
73         TELEPHONY_LOGE("pdu is empty");
74         return false;
75     }
76 
77     if (pdu.WriteByte(id_) && pdu.WriteByte(len_) && pdu.WriteWord(serviceCat_)) {
78         return true;
79     }
80 
81     TELEPHONY_LOGE("encode error");
82     return false;
83 }
84 
Decode(SmsReadBuffer & pdu)85 bool CdmaSmsServiceCategory::Decode(SmsReadBuffer &pdu)
86 {
87     if (IsInvalidPdu(pdu)) {
88         TELEPHONY_LOGE("invalid pdu");
89         return false;
90     }
91     return pdu.ReadWord(serviceCat_);
92 }
93 
CdmaSmsBearerReply(uint8_t & replySeq)94 CdmaSmsBearerReply::CdmaSmsBearerReply(uint8_t &replySeq) : replySeq_(replySeq)
95 {
96     id_ = BEARER_REPLY_OPTION;
97     len_ = sizeof(replySeq_);
98 }
99 
Encode(SmsWriteBuffer & pdu)100 bool CdmaSmsBearerReply::Encode(SmsWriteBuffer &pdu)
101 {
102     if (pdu.IsEmpty()) {
103         TELEPHONY_LOGE("pdu is empty");
104         return false;
105     }
106 
107     if (pdu.WriteByte(id_) && pdu.WriteByte(len_) && pdu.WriteBits(replySeq_, BIT6)) {
108         pdu.SkipBits();
109         return true;
110     }
111 
112     TELEPHONY_LOGE("encode error");
113     return false;
114 }
115 
Decode(SmsReadBuffer & pdu)116 bool CdmaSmsBearerReply::Decode(SmsReadBuffer &pdu)
117 {
118     if (IsInvalidPdu(pdu)) {
119         TELEPHONY_LOGE("invalid pdu");
120         return false;
121     }
122     if (pdu.ReadBits(replySeq_, BIT6)) {
123         pdu.SkipBits();
124         return true;
125     }
126     TELEPHONY_LOGE("decode error");
127     return false;
128 }
129 
CdmaSmsCauseCodes(TransportCauseCode & code)130 CdmaSmsCauseCodes::CdmaSmsCauseCodes(TransportCauseCode &code) : code_(code)
131 {
132     id_ = CAUSE_CODES;
133 }
134 
Encode(SmsWriteBuffer & pdu)135 bool CdmaSmsCauseCodes::Encode(SmsWriteBuffer &pdu)
136 {
137     if (pdu.IsEmpty()) {
138         TELEPHONY_LOGE("pdu is empty");
139         return false;
140     }
141 
142     if (!pdu.WriteByte(id_)) {
143         TELEPHONY_LOGE("id write error");
144         return false;
145     }
146     uint16_t lenIndex = pdu.MoveForward();
147     if (!pdu.WriteBits(code_.transReplySeq, BIT6) || !pdu.WriteBits(static_cast<uint8_t>(code_.errorClass), BIT2)) {
148         TELEPHONY_LOGE("replyseq or errorclass write error");
149         return false;
150     }
151     if (code_.errorClass != TransportErrClass::NONE) {
152         if (!pdu.WriteBits(static_cast<uint8_t>(code_.causeCode), BIT8)) {
153             TELEPHONY_LOGE("cause code write error");
154             return false;
155         }
156     }
157     len_ = pdu.SkipBits() - lenIndex - 1;
158     return pdu.InsertByte(len_, lenIndex);
159 }
160 
Decode(SmsReadBuffer & pdu)161 bool CdmaSmsCauseCodes::Decode(SmsReadBuffer &pdu)
162 {
163     if (IsInvalidPdu(pdu)) {
164         TELEPHONY_LOGE("invalid pdu");
165         return false;
166     }
167 
168     if (!pdu.ReadBits(code_.transReplySeq, BIT6)) {
169         TELEPHONY_LOGE("replyseq read error");
170         return false;
171     }
172     uint8_t v = 0;
173     if (!pdu.ReadBits(v, BIT2)) {
174         TELEPHONY_LOGE("error class read error");
175         return false;
176     }
177     if (v == NONE) {
178         code_.errorClass = TransportErrClass::NONE;
179     } else if (v == TEMPORARY) {
180         code_.errorClass = TransportErrClass::TEMPORARY;
181     } else if (v == PERMANENT) {
182         code_.errorClass = TransportErrClass::PERMANENT;
183     }
184     if (code_.errorClass != TransportErrClass::NONE) {
185         if (!pdu.ReadBits(v, BIT8)) {
186             TELEPHONY_LOGE("cause code read error");
187             return false;
188         }
189         code_.causeCode = TransportCauseCodeType(v);
190     }
191     pdu.SkipBits();
192     return true;
193 }
194 
CdmaSmsAddressParameter(TransportAddr & address,uint8_t id)195 CdmaSmsAddressParameter::CdmaSmsAddressParameter(TransportAddr &address, uint8_t id) : address_(address)
196 {
197     if (id == ORG_ADDRESS || id == DEST_ADDRESS) {
198         id_ = id;
199     } else {
200         isInvalid_ = true;
201         TELEPHONY_LOGE("invalid ID[%{public}d]", id);
202     }
203 }
204 
Encode(SmsWriteBuffer & pdu)205 bool CdmaSmsAddressParameter::Encode(SmsWriteBuffer &pdu)
206 {
207     if (isInvalid_ || pdu.IsEmpty()) {
208         TELEPHONY_LOGE("invalid ID or pdu");
209         return false;
210     }
211     if (!pdu.WriteByte(id_)) {
212         TELEPHONY_LOGE("id write error");
213         return false;
214     }
215     uint16_t lenIndex = pdu.MoveForward();
216     if (!pdu.WriteBits(address_.digitMode ? 0b1 : 0b0) || !pdu.WriteBits(address_.numberMode ? 0b1 : 0b0)) {
217         TELEPHONY_LOGE("digit mode or number mode write error");
218         return false;
219     }
220     if (address_.digitMode) {
221         if (!pdu.WriteBits(address_.numberType, BIT3)) {
222             TELEPHONY_LOGE("number type write error");
223             return false;
224         }
225         if (!address_.numberMode && !pdu.WriteBits(address_.numberPlan, BIT4)) {
226             TELEPHONY_LOGE("number plan write error");
227             return false;
228         }
229     }
230     if (!EncodeAddress(pdu)) {
231         TELEPHONY_LOGE("encode address error");
232         return false;
233     }
234     len_ = pdu.SkipBits() - lenIndex - 1;
235     return pdu.InsertByte(len_, lenIndex);
236 }
237 
Decode(SmsReadBuffer & pdu)238 bool CdmaSmsAddressParameter::Decode(SmsReadBuffer &pdu)
239 {
240     if (isInvalid_ || IsInvalidPdu(pdu)) {
241         TELEPHONY_LOGE("invalid ID or pdu");
242         return false;
243     }
244     if (memset_s(&address_, sizeof(address_), 0x0, sizeof(address_)) != EOK) {
245         TELEPHONY_LOGE("memset_s error");
246         return false;
247     }
248 
249     uint8_t v1 = 0;
250     uint8_t v2 = 0;
251     if (!pdu.ReadBits(v1) || !pdu.ReadBits(v2)) {
252         TELEPHONY_LOGE("digit mode or number mode read error");
253         return false;
254     }
255     address_.digitMode = (v1 == 0b1) ? true : false;
256     address_.numberMode = (v2 == 0b1) ? true : false;
257     if (address_.digitMode) {
258         if (!pdu.ReadBits(address_.numberType, BIT3)) {
259             TELEPHONY_LOGE("number type read error");
260             return false;
261         }
262         if (!address_.numberMode && !pdu.ReadBits(address_.numberPlan, BIT4)) {
263             TELEPHONY_LOGE("number plan read error");
264             return false;
265         }
266     }
267     if (!DecodeAddress(pdu)) {
268         TELEPHONY_LOGE("decode address error");
269         return false;
270     }
271     pdu.SkipBits();
272     return true;
273 }
274 
EncodeAddress(SmsWriteBuffer & pdu)275 bool CdmaSmsAddressParameter::EncodeAddress(SmsWriteBuffer &pdu)
276 {
277     if (!pdu.WriteBits(address_.addrLen, BIT8)) {
278         TELEPHONY_LOGE("addlen write error");
279         return false;
280     }
281     if (static_cast<unsigned long>(address_.addrLen) > (sizeof(address_.szData) / sizeof(address_.szData[0]))) {
282         TELEPHONY_LOGE("address length error");
283         return false;
284     }
285     if (address_.digitMode) {
286         for (uint8_t i = 0; i < address_.addrLen; i++) {
287             if (!pdu.WriteBits(address_.szData[i], BIT8)) {
288                 TELEPHONY_LOGE("address write error");
289                 return false;
290             }
291         }
292     } else {
293         for (uint8_t i = 0; i < address_.addrLen; i++) {
294             if (!pdu.WriteBits(SmsCommonUtils::DigitToDtmfChar(address_.szData[i]), BIT4)) {
295                 TELEPHONY_LOGE("address write error");
296                 return false;
297             }
298         }
299     }
300     return true;
301 }
302 
DecodeAddress(SmsReadBuffer & pdu)303 bool CdmaSmsAddressParameter::DecodeAddress(SmsReadBuffer &pdu)
304 {
305     uint8_t v1 = 0;
306     if (!pdu.ReadBits(v1, BIT8)) {
307         TELEPHONY_LOGE("addrlen read error");
308         return false;
309     }
310     address_.addrLen = v1;
311     if (static_cast<unsigned long>(address_.addrLen) > (sizeof(address_.szData) / sizeof(address_.szData[0]))) {
312         TELEPHONY_LOGE("address length error");
313         return false;
314     }
315     if (address_.digitMode) {
316         for (uint8_t i = 0; i < address_.addrLen; i++) {
317             if (!pdu.ReadBits(v1, BIT8)) {
318                 TELEPHONY_LOGE("address read error");
319                 return false;
320             }
321             address_.szData[i] = v1;
322         }
323     } else {
324         for (uint8_t i = 0; i < address_.addrLen; i++) {
325             if (!pdu.ReadBits(v1, BIT4)) {
326                 TELEPHONY_LOGE("address read error");
327                 return false;
328             }
329             address_.szData[i] = SmsCommonUtils::DtmfCharToDigit(v1);
330         }
331     }
332     return true;
333 }
334 
CdmaSmsSubaddress(TransportSubAddr & address,uint8_t id)335 CdmaSmsSubaddress::CdmaSmsSubaddress(TransportSubAddr &address, uint8_t id) : address_(address)
336 {
337     if (id == ORG_SUB_ADDRESS || id == DEST_SUB_ADDRESS) {
338         id_ = id;
339     } else {
340         isInvalid_ = true;
341         TELEPHONY_LOGE("invalid ID[%{public}d]", id);
342     }
343 }
344 
Encode(SmsWriteBuffer & pdu)345 bool CdmaSmsSubaddress::Encode(SmsWriteBuffer &pdu)
346 {
347     if (isInvalid_ || pdu.IsEmpty()) {
348         TELEPHONY_LOGE("invalid ID or pdu");
349         return false;
350     }
351 
352     if (!pdu.WriteByte(id_)) {
353         TELEPHONY_LOGE("id write error");
354         return false;
355     }
356     uint16_t lenIndex = pdu.MoveForward();
357     if (!pdu.WriteBits(static_cast<uint8_t>(address_.type), BIT3) || !pdu.WriteBits(address_.odd ? 0b1 : 0b0) ||
358         !pdu.WriteBits(address_.addrLen, BIT8)) {
359         TELEPHONY_LOGE("type, odd or addrlen write error");
360         return false;
361     }
362 
363     if (static_cast<unsigned long>(address_.addrLen) > (sizeof(address_.szData) / sizeof(address_.szData[0]))) {
364         TELEPHONY_LOGE("address length error");
365         return false;
366     }
367 
368     for (uint8_t i = 0; i < address_.addrLen; i++) {
369         if (!pdu.WriteBits(address_.szData[i], BIT8)) {
370             TELEPHONY_LOGE("address write error");
371             return false;
372         }
373     }
374     len_ = pdu.SkipBits() - lenIndex - 1;
375     return pdu.InsertByte(len_, lenIndex);
376 }
377 
Decode(SmsReadBuffer & pdu)378 bool CdmaSmsSubaddress::Decode(SmsReadBuffer &pdu)
379 {
380     if (isInvalid_ || IsInvalidPdu(pdu)) {
381         TELEPHONY_LOGE("invalid ID or pdu");
382         return false;
383     }
384     if (memset_s(&address_, sizeof(address_), 0x0, sizeof(address_)) != EOK) {
385         TELEPHONY_LOGE("memset_s error");
386         return false;
387     }
388 
389     uint8_t v1 = 0;
390     uint8_t v2 = 0;
391     uint8_t v3 = 0;
392     if (!pdu.ReadBits(v1, BIT3) || !pdu.ReadBits(v2) || !pdu.ReadBits(v3, BIT8)) {
393         TELEPHONY_LOGE("type, odd or addrlen read error");
394         return false;
395     }
396     if (v1 == NSAP) {
397         address_.type = TransportSubAddrType::NSAP;
398     } else if (v1 == USER) {
399         address_.type = TransportSubAddrType::USER;
400     } else {
401         address_.type = TransportSubAddrType::RESERVED;
402     }
403     address_.odd = (v2 == 0b1) ? true : false;
404     address_.addrLen = v3;
405     if (static_cast<unsigned long>(address_.addrLen) > (sizeof(address_.szData) / sizeof(address_.szData[0]))) {
406         TELEPHONY_LOGE("address length error");
407         return false;
408     }
409     for (uint8_t i = 0; i < address_.addrLen; i++) {
410         if (!pdu.ReadBits(v1, BIT8)) {
411             TELEPHONY_LOGE("address read error");
412             return false;
413         }
414         address_.szData[i] = v1;
415     }
416     pdu.SkipBits();
417     return true;
418 }
419 
CdmaSmsBearerData(CdmaTeleserviceMsg & msg)420 CdmaSmsBearerData::CdmaSmsBearerData(CdmaTeleserviceMsg &msg)
421 {
422     id_ = BEARER_DATA;
423     if (msg.type == TeleserviceMsgType::SUBMIT) {
424         teleserviceMessage_ = std::make_unique<CdmaSmsSubmitMessage>(msg.data.submit);
425     } else if (msg.type == TeleserviceMsgType::CANCEL) {
426         teleserviceMessage_ = std::make_unique<CdmaSmsCancelMessage>(msg.data.cancel);
427     } else if (msg.type == TeleserviceMsgType::DELIVER_REPORT) {
428         teleserviceMessage_ = std::make_unique<CdmaSmsDeliverReport>(msg.data.report);
429     } else {
430         TELEPHONY_LOGE("no matching type[%{public}d]", static_cast<uint8_t>(msg.type));
431     }
432 }
433 
CdmaSmsBearerData(CdmaTeleserviceMsg & msg,SmsReadBuffer & pdu,bool isCMAS)434 CdmaSmsBearerData::CdmaSmsBearerData(CdmaTeleserviceMsg &msg, SmsReadBuffer &pdu, bool isCMAS)
435 {
436     id_ = BEARER_DATA;
437     // teleservice pdu, does not include id and length
438     uint8_t index = pdu.GetIndex();
439     uint8_t type = CdmaSmsTeleserviceMessage::GetMessageType(pdu);
440     pdu.SetIndex(index);
441     if (type == CdmaSmsTeleserviceMessage::DELIVER) {
442         msg.type = TeleserviceMsgType::DELIVER;
443         teleserviceMessage_ = std::make_unique<CdmaSmsDeliverMessage>(msg.data.deliver, pdu, isCMAS);
444     } else if (type == CdmaSmsTeleserviceMessage::SUBMIT) {
445         msg.type = TeleserviceMsgType::SUBMIT;
446         teleserviceMessage_ = std::make_unique<CdmaSmsSubmitMessage>(msg.data.submit, pdu);
447     } else if (type == CdmaSmsTeleserviceMessage::DELIVERY_ACK) {
448         msg.type = TeleserviceMsgType::DELIVERY_ACK;
449         teleserviceMessage_ = std::make_unique<CdmaSmsDeliveryAck>(msg.data.deliveryAck, pdu);
450     } else if (type == CdmaSmsTeleserviceMessage::USER_ACK) {
451         msg.type = TeleserviceMsgType::USER_ACK;
452         teleserviceMessage_ = std::make_unique<CdmaSmsUserAck>(msg.data.userAck, pdu);
453     } else if (type == CdmaSmsTeleserviceMessage::READ_ACK) {
454         msg.type = TeleserviceMsgType::READ_ACK;
455         teleserviceMessage_ = std::make_unique<CdmaSmsReadAck>(msg.data.readAck, pdu);
456     } else {
457         msg.type = TeleserviceMsgType::RESERVED;
458         TELEPHONY_LOGE("no matching type[%{public}d]", type);
459     }
460 }
461 
Encode(SmsWriteBuffer & pdu)462 bool CdmaSmsBearerData::Encode(SmsWriteBuffer &pdu)
463 {
464     if (pdu.IsEmpty()) {
465         TELEPHONY_LOGE("pdu is empty");
466         return false;
467     }
468     if (teleserviceMessage_ == nullptr) {
469         TELEPHONY_LOGE("teleservice message is null");
470         return false;
471     }
472 
473     if (!pdu.WriteByte(id_)) {
474         TELEPHONY_LOGE("id write error");
475         return false;
476     }
477     uint16_t lenIndex = pdu.MoveForward();
478     if (!teleserviceMessage_->Encode(pdu)) {
479         TELEPHONY_LOGE("teleservice message encode error");
480         return false;
481     }
482     len_ = pdu.GetIndex() - lenIndex - 1;
483     return pdu.InsertByte(len_, lenIndex);
484 }
485 
Decode(SmsReadBuffer & pdu)486 bool CdmaSmsBearerData::Decode(SmsReadBuffer &pdu)
487 {
488     if (teleserviceMessage_ == nullptr) {
489         TELEPHONY_LOGE("Teleservice message is null");
490         return false;
491     }
492     if (IsInvalidPdu(pdu)) {
493         TELEPHONY_LOGE("invalid pdu");
494         return false;
495     }
496 
497     return teleserviceMessage_->Decode(pdu);
498 }
499 
500 } // namespace Telephony
501 } // namespace OHOS
502