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