• 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_sub_parameter.h"
17 
18 #include "gsm_user_data_pdu.h"
19 #include "securec.h"
20 #include "sms_common_utils.h"
21 #include "telephony_log_wrapper.h"
22 
23 namespace OHOS {
24 namespace Telephony {
25 static constexpr uint8_t HEX_STEP = 2;
26 static constexpr uint8_t DECIMAL_NUM = 10;
27 static constexpr uint8_t MESSAGE_ID_LEN = 3;
28 static constexpr uint8_t ABSOLUTE_TIME_LEN = 6;
29 
IsInvalidPdu(SmsReadBuffer & pdu)30 bool CdmaSmsSubParameter::IsInvalidPdu(SmsReadBuffer &pdu)
31 {
32     uint8_t id = RESERVED;
33     if (pdu.IsEmpty() || !pdu.ReadByte(id) || !pdu.ReadByte(len_) || id != id_) {
34         TELEPHONY_LOGE("sub parameter: pdu is invalid[%{public}d]: [%{public}d]", id_, id);
35         return true;
36     }
37     return false;
38 }
39 
CdmaSmsBaseParameter(uint8_t id,uint8_t & data)40 CdmaSmsBaseParameter::CdmaSmsBaseParameter(uint8_t id, uint8_t &data) : data_(data)
41 {
42     id_ = id;
43     len_ = sizeof(id_);
44 }
45 
Encode(SmsWriteBuffer & pdu)46 bool CdmaSmsBaseParameter::Encode(SmsWriteBuffer &pdu)
47 {
48     if (pdu.IsEmpty()) {
49         TELEPHONY_LOGE("pdu is empty");
50         return false;
51     }
52     if (pdu.WriteByte(id_) && pdu.WriteByte(len_) && pdu.WriteByte(data_)) {
53         return true;
54     }
55     TELEPHONY_LOGE("encode error");
56     return false;
57 }
58 
Decode(SmsReadBuffer & pdu)59 bool CdmaSmsBaseParameter::Decode(SmsReadBuffer &pdu)
60 {
61     if (IsInvalidPdu(pdu)) {
62         TELEPHONY_LOGE("invalid pdu");
63         return false;
64     }
65     return pdu.ReadByte(data_);
66 }
67 
CdmaSmsReservedParameter(uint8_t id)68 CdmaSmsReservedParameter::CdmaSmsReservedParameter(uint8_t id)
69 {
70     id_ = id;
71 }
72 
Encode(SmsWriteBuffer & pdu)73 bool CdmaSmsReservedParameter::Encode(SmsWriteBuffer &pdu)
74 {
75     if (pdu.IsEmpty()) {
76         TELEPHONY_LOGE("pdu is empty");
77         return false;
78     }
79     return true;
80 }
81 
Decode(SmsReadBuffer & pdu)82 bool CdmaSmsReservedParameter::Decode(SmsReadBuffer &pdu)
83 {
84     if (IsInvalidPdu(pdu)) {
85         TELEPHONY_LOGE("invalid pdu");
86         return false;
87     }
88     pdu.MoveForward(len_);
89     return true;
90 }
91 
CdmaSmsMessageId(SmsTeleSvcMsgId & msgId,uint8_t type)92 CdmaSmsMessageId::CdmaSmsMessageId(SmsTeleSvcMsgId &msgId, uint8_t type) : msgId_(msgId)
93 {
94     id_ = MESSAGE_IDENTIFIER;
95     type_ = type; // 4 bits
96     len_ = MESSAGE_ID_LEN;
97 }
98 
Encode(SmsWriteBuffer & pdu)99 bool CdmaSmsMessageId::Encode(SmsWriteBuffer &pdu)
100 {
101     if (pdu.IsEmpty()) {
102         TELEPHONY_LOGE("pdu is empty");
103         return false;
104     }
105 
106     if (pdu.WriteByte(id_) && pdu.WriteByte(len_)) {
107         if (pdu.WriteBits(type_, BIT4) && pdu.WriteBits(msgId_.msgId >> BIT8, BIT8) &&
108             pdu.WriteBits(msgId_.msgId, BIT8) && pdu.WriteBits(msgId_.headerInd ? 0b1 : 0b0, BIT1)) {
109             pdu.SkipBits();
110             return true;
111         }
112     }
113 
114     TELEPHONY_LOGE("encode error");
115     return false;
116 }
117 
Decode(SmsReadBuffer & pdu)118 bool CdmaSmsMessageId::Decode(SmsReadBuffer &pdu)
119 {
120     if (IsInvalidPdu(pdu)) {
121         TELEPHONY_LOGE("invalid pdu");
122         return false;
123     }
124 
125     if (!pdu.ReadBits(type_, BIT4)) {
126         TELEPHONY_LOGE("type read error");
127         return false;
128     }
129     uint8_t vh = 0;
130     uint8_t v = 0;
131     if (!pdu.ReadBits(vh, BIT8) || !pdu.ReadBits(v, BIT8)) {
132         TELEPHONY_LOGE("msgid read error");
133         return false;
134     }
135     msgId_.msgId = (vh << BIT8) | v;
136 
137     if (!pdu.ReadBits(v, BIT1)) {
138         TELEPHONY_LOGE("header ind read error");
139         return false;
140     }
141     msgId_.headerInd = v == 0b1 ? true : false;
142 
143     pdu.SkipBits();
144     return true;
145 }
146 
GetMessageType()147 uint8_t CdmaSmsMessageId::GetMessageType()
148 {
149     return type_;
150 }
151 
CdmaSmsAbsoluteTime(uint8_t id,SmsTimeAbs & time)152 CdmaSmsAbsoluteTime::CdmaSmsAbsoluteTime(uint8_t id, SmsTimeAbs &time) : time_(time)
153 {
154     id_ = id;
155     len_ = ABSOLUTE_TIME_LEN;
156 }
157 
Encode(SmsWriteBuffer & pdu)158 bool CdmaSmsAbsoluteTime::Encode(SmsWriteBuffer &pdu)
159 {
160     if (pdu.IsEmpty()) {
161         TELEPHONY_LOGE("pdu is empty");
162         return false;
163     }
164 
165     if (pdu.WriteByte(id_) && pdu.WriteByte(len_)) {
166         if (pdu.WriteByte(EncodeBCD(time_.year)) && pdu.WriteByte(EncodeBCD(time_.month)) &&
167             pdu.WriteByte(EncodeBCD(time_.day)) && pdu.WriteByte(EncodeBCD(time_.hour)) &&
168             pdu.WriteByte(EncodeBCD(time_.minute)) && pdu.WriteByte(EncodeBCD(time_.second))) {
169             return true;
170         }
171     }
172 
173     TELEPHONY_LOGE("encode error");
174     return false;
175 }
176 
Decode(SmsReadBuffer & pdu)177 bool CdmaSmsAbsoluteTime::Decode(SmsReadBuffer &pdu)
178 {
179     if (IsInvalidPdu(pdu)) {
180         TELEPHONY_LOGE("invalid pdu");
181         return false;
182     }
183     uint8_t v1 = 0;
184     uint8_t v2 = 0;
185     uint8_t v3 = 0;
186     uint8_t v4 = 0;
187     uint8_t v5 = 0;
188     uint8_t v6 = 0;
189     if (!pdu.ReadByte(v1) || !pdu.ReadByte(v2) || !pdu.ReadByte(v3) || !pdu.ReadByte(v4) || !pdu.ReadByte(v5) ||
190         !pdu.ReadByte(v6)) {
191         TELEPHONY_LOGE("read error");
192         return false;
193     }
194     time_.year = DecodeBCD(v1);
195     time_.month = DecodeBCD(v2);
196     time_.day = DecodeBCD(v3);
197     time_.hour = DecodeBCD(v4);
198     time_.minute = DecodeBCD(v5);
199     time_.second = DecodeBCD(v6);
200     return true;
201 }
202 
EncodeBCD(const uint8_t v)203 uint8_t CdmaSmsAbsoluteTime::EncodeBCD(const uint8_t v)
204 {
205     return ((v / DECIMAL_NUM) << BIT4) | (v % DECIMAL_NUM);
206 }
207 
DecodeBCD(const uint8_t v)208 uint8_t CdmaSmsAbsoluteTime::DecodeBCD(const uint8_t v)
209 {
210     return ((v & 0xf0) >> BIT4) * DECIMAL_NUM + (v & 0x0f);
211 }
212 
CdmaSmsPriorityInd(SmsPriorityIndicator & priority)213 CdmaSmsPriorityInd::CdmaSmsPriorityInd(SmsPriorityIndicator &priority) : priority_(priority)
214 {
215     id_ = PRIORITY_INDICATOR;
216     len_ = sizeof(uint8_t);
217 }
218 
Encode(SmsWriteBuffer & pdu)219 bool CdmaSmsPriorityInd::Encode(SmsWriteBuffer &pdu)
220 {
221     if (pdu.IsEmpty()) {
222         TELEPHONY_LOGE("pdu is empty");
223         return false;
224     }
225 
226     if (pdu.WriteByte(id_) && pdu.WriteByte(len_)) {
227         if (pdu.WriteBits(static_cast<uint8_t>(priority_), BIT2)) {
228             pdu.SkipBits();
229             return true;
230         }
231     }
232 
233     TELEPHONY_LOGE("encode error");
234     return false;
235 }
236 
Decode(SmsReadBuffer & pdu)237 bool CdmaSmsPriorityInd::Decode(SmsReadBuffer &pdu)
238 {
239     if (IsInvalidPdu(pdu)) {
240         TELEPHONY_LOGE("invalid pdu");
241         return false;
242     }
243 
244     uint8_t v = 0;
245     if (!pdu.ReadBits(v, BIT2)) {
246         TELEPHONY_LOGE("read error");
247         return false;
248     }
249     pdu.SkipBits();
250     priority_ = SmsPriorityIndicator(v);
251     return true;
252 }
253 
CdmaSmsPrivacyInd(SmsPrivacyIndicator & privacy)254 CdmaSmsPrivacyInd::CdmaSmsPrivacyInd(SmsPrivacyIndicator &privacy) : privacy_(privacy)
255 {
256     id_ = PRIVACY_INDICATOR;
257     len_ = sizeof(uint8_t);
258 }
259 
Encode(SmsWriteBuffer & pdu)260 bool CdmaSmsPrivacyInd::Encode(SmsWriteBuffer &pdu)
261 {
262     if (pdu.IsEmpty()) {
263         TELEPHONY_LOGE("pdu is empty");
264         return false;
265     }
266 
267     if (pdu.WriteByte(id_) && pdu.WriteByte(len_)) {
268         if (pdu.WriteBits(static_cast<uint8_t>(privacy_), BIT2)) {
269             pdu.SkipBits();
270             return true;
271         }
272     }
273 
274     TELEPHONY_LOGE("encode error");
275     return false;
276 }
277 
Decode(SmsReadBuffer & pdu)278 bool CdmaSmsPrivacyInd::Decode(SmsReadBuffer &pdu)
279 {
280     if (IsInvalidPdu(pdu)) {
281         TELEPHONY_LOGE("invalid pdu");
282         return false;
283     }
284 
285     uint8_t v = 0;
286     if (!pdu.ReadBits(v, BIT2)) {
287         TELEPHONY_LOGE("read error");
288         return false;
289     }
290     pdu.SkipBits();
291     privacy_ = SmsPrivacyIndicator(v);
292     return true;
293 }
294 
CdmaSmsReplyOption(SmsReplyOption & replyOpt)295 CdmaSmsReplyOption::CdmaSmsReplyOption(SmsReplyOption &replyOpt) : replyOpt_(replyOpt)
296 {
297     id_ = REPLY_OPTION;
298     len_ = sizeof(uint8_t);
299 }
300 
Encode(SmsWriteBuffer & pdu)301 bool CdmaSmsReplyOption::Encode(SmsWriteBuffer &pdu)
302 {
303     if (pdu.IsEmpty()) {
304         TELEPHONY_LOGE("pdu is empty");
305         return false;
306     }
307 
308     if (pdu.WriteByte(id_) && pdu.WriteByte(len_)) {
309         if (pdu.WriteBits(replyOpt_.userAck ? 0b1 : 0b0, BIT1) && pdu.WriteBits(replyOpt_.dak ? 0b1 : 0b0, BIT1) &&
310             pdu.WriteBits(replyOpt_.readAck ? 0b1 : 0b0, BIT1) && pdu.WriteBits(replyOpt_.report ? 0b1 : 0b0, BIT1)) {
311             pdu.SkipBits();
312             return true;
313         }
314     }
315 
316     TELEPHONY_LOGE("encode error");
317     return false;
318 }
319 
Decode(SmsReadBuffer & pdu)320 bool CdmaSmsReplyOption::Decode(SmsReadBuffer &pdu)
321 {
322     if (IsInvalidPdu(pdu)) {
323         TELEPHONY_LOGE("invalid pdu");
324         return false;
325     }
326 
327     uint8_t v1 = 0;
328     uint8_t v2 = 0;
329     uint8_t v3 = 0;
330     uint8_t v4 = 0;
331     if (!pdu.ReadBits(v1, BIT1) || !pdu.ReadBits(v2, BIT1) || !pdu.ReadBits(v3, BIT1) || !pdu.ReadBits(v4, BIT1)) {
332         TELEPHONY_LOGE("read error");
333         return false;
334     }
335     replyOpt_.userAck = (v1 == 0b1) ? true : false;
336     replyOpt_.dak = (v2 == 0b1) ? true : false;
337     replyOpt_.readAck = (v3 == 0b1) ? true : false;
338     replyOpt_.report = (v4 == 0b1) ? true : false;
339     pdu.SkipBits();
340     return true;
341 }
342 
CdmaSmsUserData(SmsTeleSvcUserData & data,bool & headerInd)343 CdmaSmsUserData::CdmaSmsUserData(SmsTeleSvcUserData &data, bool &headerInd) : data_(data), headerInd_(headerInd)
344 {
345     id_ = USER_DATA;
346 }
347 
Encode(SmsWriteBuffer & pdu)348 bool CdmaSmsUserData::Encode(SmsWriteBuffer &pdu)
349 {
350     if (pdu.IsEmpty() || !pdu.WriteByte(id_)) {
351         TELEPHONY_LOGE("pdu is empty or id write error");
352         return false;
353     }
354     uint16_t lenIndex = pdu.MoveForward();
355     if (!pdu.WriteBits(static_cast<uint8_t>(data_.encodeType), BIT5)) {
356         TELEPHONY_LOGE("encode type write error");
357         return false;
358     }
359     if (data_.encodeType == SmsEncodingType::EPM || data_.encodeType == SmsEncodingType::GSMDCS) {
360         if (!pdu.WriteBits(data_.msgType, BIT8)) {
361             TELEPHONY_LOGE("msg type write error");
362             return false;
363         }
364     }
365     if (data_.encodeType == SmsEncodingType::ASCII_7BIT || data_.encodeType == SmsEncodingType::IA5) {
366         if (!EncodeAscii7Bit(pdu)) {
367             TELEPHONY_LOGE("ascii 7bit encode error");
368             return false;
369         }
370     } else if (data_.encodeType == SmsEncodingType::GSM7BIT) {
371         if (!EncodeGsm7Bit(pdu)) {
372             TELEPHONY_LOGE("gsm 7bit encode error");
373             return false;
374         }
375     } else if (data_.encodeType == SmsEncodingType::UNICODE) {
376         if (!EncodeUnicode(pdu)) {
377             TELEPHONY_LOGE("unicode encode error");
378             return false;
379         }
380     } else {
381         if (!Encode8BitData(pdu)) {
382             TELEPHONY_LOGE("8bit encode error");
383             return false;
384         }
385     }
386     len_ = pdu.SkipBits() - lenIndex - 1;
387     return pdu.InsertByte(len_, lenIndex);
388 }
389 
EncodeHeader7Bit(SmsWriteBuffer & pdu)390 bool CdmaSmsUserData::EncodeHeader7Bit(SmsWriteBuffer &pdu)
391 {
392     if (static_cast<unsigned long>(data_.userData.headerCnt) >
393         (sizeof(data_.userData.header) / sizeof(data_.userData.header[0]))) {
394         TELEPHONY_LOGE("user data header length error");
395         return false;
396     }
397     SmsWriteBuffer headerPdu;
398     GsmUserDataPdu gsmUdPdu;
399     for (uint8_t i = 0; i < data_.userData.headerCnt; i++) {
400         gsmUdPdu.EncodeHeader(headerPdu, data_.userData.header[i]);
401     }
402     uint8_t udhBytes = headerPdu.GetIndex();
403     if (udhBytes > 0) {
404         uint8_t udhLen = (udhBytes + 1) * BIT8 / BIT7;
405         // The header data is encoded in 7bit, the remaining bits need to be ignored.
406         uint8_t ignoredBits = BIT7 - (udhBytes + 1) * BIT8 % BIT7;
407         if (ignoredBits != BIT7) {
408             udhLen++;
409         }
410         if (data_.encodeType == SmsEncodingType::GSM7BIT) {
411             ignoredBits = BIT8;
412             udhLen++;
413         }
414         uint8_t numFields = udhLen + data_.userData.length;
415         if (!pdu.WriteBits(numFields, BIT8) || !pdu.WriteBits(udhBytes, BIT8)) {
416             TELEPHONY_LOGE("num fields or udh bytes write error");
417             return false;
418         }
419         uint8_t v = 0;
420         for (uint8_t i = 0; i < udhBytes; i++) {
421             if (!headerPdu.GetValueFromIndex(i, v) || !pdu.WriteBits(v, BIT8)) {
422                 TELEPHONY_LOGE("data write error");
423                 return false;
424             }
425         }
426         if (ignoredBits != BIT7 && !pdu.WriteBits(0b0, ignoredBits)) {
427             TELEPHONY_LOGE("write error");
428             return false;
429         }
430     } else {
431         return pdu.WriteBits(data_.userData.length, BIT8);
432     }
433     return true;
434 }
435 
EncodeAscii7Bit(SmsWriteBuffer & pdu)436 bool CdmaSmsUserData::EncodeAscii7Bit(SmsWriteBuffer &pdu)
437 {
438     if (!EncodeHeader7Bit(pdu)) {
439         TELEPHONY_LOGE("header encode error");
440         return false;
441     }
442     if (static_cast<unsigned long>(data_.userData.length) >
443         (sizeof(data_.userData.data) / sizeof(data_.userData.data[0]))) {
444         TELEPHONY_LOGE("user data length error");
445         return false;
446     }
447     for (uint8_t i = 0; i < data_.userData.length; i++) {
448         if (!pdu.WriteBits(data_.userData.data[i], BIT7)) {
449             TELEPHONY_LOGE("data write error");
450             return false;
451         }
452     }
453     return true;
454 }
455 
EncodeGsm7Bit(SmsWriteBuffer & pdu)456 bool CdmaSmsUserData::EncodeGsm7Bit(SmsWriteBuffer &pdu)
457 {
458     if (!EncodeHeader7Bit(pdu)) {
459         TELEPHONY_LOGE("header encode error");
460         return false;
461     }
462     std::unique_ptr<uint8_t[]> destPtr = std::make_unique<uint8_t[]>(MAX_USER_DATA_LEN + 1);
463     if (destPtr == nullptr) {
464         TELEPHONY_LOGE("make_unique error");
465         return false;
466     }
467     uint16_t size = SmsCommonUtils::Pack7bitChar(reinterpret_cast<const uint8_t *>(data_.userData.data),
468         data_.userData.length, 0, destPtr.get(), MAX_USER_DATA_LEN + 1);
469     if (size > MAX_USER_DATA_LEN + 1) {
470         TELEPHONY_LOGE("user data length error");
471         return false;
472     }
473     for (uint16_t i = 0; i < size; i++) {
474         if (!pdu.WriteBits(destPtr.get()[i], BIT8)) {
475             TELEPHONY_LOGE("data write error");
476             return false;
477         }
478     }
479     return true;
480 }
481 
EncodeHeaderUnicode(SmsWriteBuffer & pdu)482 bool CdmaSmsUserData::EncodeHeaderUnicode(SmsWriteBuffer &pdu)
483 {
484     if (static_cast<unsigned long>(data_.userData.headerCnt) >
485         (sizeof(data_.userData.header) / sizeof(data_.userData.header[0]))) {
486         TELEPHONY_LOGE("user data header length error");
487         return false;
488     }
489     SmsWriteBuffer headerPdu;
490     GsmUserDataPdu gsmUdPdu;
491     for (uint8_t i = 0; i < data_.userData.headerCnt; i++) {
492         gsmUdPdu.EncodeHeader(headerPdu, data_.userData.header[i]);
493     }
494     uint8_t udhBytes = headerPdu.GetIndex();
495     uint8_t numFields = 0;
496     if (udhBytes > 0) {
497         numFields = (udhBytes + data_.userData.length) / HEX_STEP + 1;
498         if (!pdu.WriteBits(numFields, BIT8) || !pdu.WriteBits(udhBytes, BIT8)) {
499             TELEPHONY_LOGE("num fields or udh bytes write error");
500             return false;
501         }
502         uint8_t v = 0;
503         for (uint8_t i = 0; i < udhBytes; i++) {
504             if (!headerPdu.GetValueFromIndex(i, v) || !pdu.WriteBits(v, BIT8)) {
505                 TELEPHONY_LOGE("data write error");
506                 return false;
507             }
508         }
509     } else {
510         numFields = data_.userData.length / HEX_STEP;
511         return pdu.WriteBits(numFields, BIT8);
512     }
513     return true;
514 }
515 
EncodeUnicode(SmsWriteBuffer & pdu)516 bool CdmaSmsUserData::EncodeUnicode(SmsWriteBuffer &pdu)
517 {
518     if (!EncodeHeaderUnicode(pdu)) {
519         TELEPHONY_LOGE("header encode error");
520         return false;
521     }
522     if (static_cast<unsigned long>(data_.userData.length) >
523         (sizeof(data_.userData.data) / sizeof(data_.userData.data[0]))) {
524         TELEPHONY_LOGE("user data length error");
525         return false;
526     }
527     for (uint8_t i = 0; i < data_.userData.length; i++) {
528         if (!pdu.WriteBits(data_.userData.data[i], BIT8)) {
529             TELEPHONY_LOGE("user data write error");
530             return false;
531         }
532     }
533     return true;
534 }
535 
Encode8BitData(SmsWriteBuffer & pdu)536 bool CdmaSmsUserData::Encode8BitData(SmsWriteBuffer &pdu)
537 {
538     if (static_cast<unsigned long>(data_.userData.length) >
539         (sizeof(data_.userData.data) / sizeof(data_.userData.data[0]))) {
540         TELEPHONY_LOGE("user data length error");
541         return false;
542     }
543     if (!pdu.WriteBits(data_.userData.length, BIT8)) {
544         TELEPHONY_LOGE("data length write error");
545         return false;
546     }
547     for (uint8_t i = 0; i < data_.userData.length; i++) {
548         if (!pdu.WriteBits(data_.userData.data[i], BIT8)) {
549             TELEPHONY_LOGE("data write error");
550             return false;
551         }
552     }
553     return true;
554 }
555 
Decode(SmsReadBuffer & pdu)556 bool CdmaSmsUserData::Decode(SmsReadBuffer &pdu)
557 {
558     if (IsInvalidPdu(pdu)) {
559         TELEPHONY_LOGE("invalid pdu");
560         return false;
561     }
562     uint8_t v = 0;
563     if (!pdu.ReadBits(v, BIT5)) {
564         TELEPHONY_LOGE("encode type read error");
565         return false;
566     }
567     data_.encodeType = GetEncodingType(v);
568     if (data_.encodeType == SmsEncodingType::EPM || data_.encodeType == SmsEncodingType::GSMDCS) {
569         if (!pdu.ReadBits(data_.msgType, BIT8)) {
570             TELEPHONY_LOGE("msg type read error");
571             return false;
572         }
573     }
574     uint8_t numFields = 0;
575     if (!pdu.ReadBits(numFields, BIT8)) {
576         TELEPHONY_LOGE("num fields read error");
577         return false;
578     }
579     uint8_t udhBytes = DecodeHeader7Bit(pdu);
580     if (data_.encodeType == SmsEncodingType::ASCII_7BIT || data_.encodeType == SmsEncodingType::IA5) {
581         return DecodeAscii7Bit(pdu, numFields, udhBytes);
582     } else if (data_.encodeType == SmsEncodingType::GSM7BIT) {
583         return DecodeGsm7Bit(pdu, numFields, udhBytes);
584     } else if (data_.encodeType == SmsEncodingType::UNICODE) {
585         data_.userData.length = headerInd_ ? (numFields * HEX_STEP - udhBytes - 1) : (numFields * HEX_STEP);
586         if (!Decode8BitData(pdu)) {
587             TELEPHONY_LOGE("unicode decode error");
588             return false;
589         }
590     } else if (data_.encodeType == SmsEncodingType::EPM || data_.encodeType == SmsEncodingType::GSMDCS) {
591         TELEPHONY_LOGW("Encode type not support [%{public}d]", static_cast<int>(data_.encodeType));
592         return false;
593     } else {
594         data_.userData.length = headerInd_ ? (numFields - udhBytes - 1) : numFields;
595         if (!Decode8BitData(pdu)) {
596             TELEPHONY_LOGE("8bit decode error");
597             return false;
598         }
599     }
600     pdu.SkipBits();
601     return true;
602 }
603 
DecodeHeader7Bit(SmsReadBuffer & pdu)604 uint8_t CdmaSmsUserData::DecodeHeader7Bit(SmsReadBuffer &pdu)
605 {
606     uint8_t udhBytes = 0;
607     if (headerInd_) {
608         if (!pdu.ReadBits(udhBytes, BIT8) || (udhBytes > MAX_USER_DATA_LEN + 1)) {
609             TELEPHONY_LOGE("udh bytes read error");
610             return 0;
611         }
612     }
613     data_.userData.headerCnt = 0;
614     if (udhBytes > 0) {
615         uint8_t index = 0;
616         GsmUserDataPdu gsmUdPdu;
617         for (uint8_t i = 0; index < udhBytes; i++) {
618             if (static_cast<unsigned long>(i) > (sizeof(data_.userData.header) / sizeof(data_.userData.header[0]))) {
619                 TELEPHONY_LOGE("user data header length error");
620                 return 0;
621             }
622             uint16_t length = 0;
623             if (!gsmUdPdu.DecodeHeader(pdu, data_.userData.header[i], length)) {
624                 TELEPHONY_LOGE("decode header error");
625                 return 0;
626             }
627             if (length == 0) {
628                 TELEPHONY_LOGW("Decode header error, header len [%{public}d]", length);
629                 gsmUdPdu.ResetUserData(data_.userData);
630                 return 0;
631             }
632             index += length;
633             if (index > udhBytes + HEX_STEP) {
634                 TELEPHONY_LOGW("Decode header error, over data [%{public}d > %{public}d + 2]", index, udhBytes);
635                 gsmUdPdu.ResetUserData(data_.userData);
636                 return 0;
637             } else {
638                 data_.userData.headerCnt++;
639             }
640         }
641     }
642     return udhBytes;
643 }
644 
DecodeAscii7Bit(SmsReadBuffer & pdu,uint8_t numFields,uint8_t udhBytes)645 bool CdmaSmsUserData::DecodeAscii7Bit(SmsReadBuffer &pdu, uint8_t numFields, uint8_t udhBytes)
646 {
647     uint8_t v = 0;
648     uint8_t udhLen = udhBytes == 0 ? 0 : (udhBytes + 1) * BIT8 / BIT7;
649     if (udhLen > 0) {
650         // The header data is encoded in 7bit, the remaining bits need to be ignored.
651         uint8_t ignoredBits = BIT7 - (udhBytes + 1) * BIT8 % BIT7;
652         if (ignoredBits < BIT7) {
653             if (!pdu.ReadBits(v, ignoredBits)) {
654                 TELEPHONY_LOGE("read error");
655                 return false;
656             }
657             udhLen++;
658         }
659     }
660     data_.userData.length = numFields - udhLen;
661     if (static_cast<unsigned long>(data_.userData.length) >
662         (sizeof(data_.userData.data) / sizeof(data_.userData.data[0]))) {
663         TELEPHONY_LOGE("user data length error");
664         return false;
665     }
666     for (uint8_t i = 0; i < data_.userData.length; i++) {
667         if (!pdu.ReadBits(v, BIT7)) {
668             TELEPHONY_LOGE("data read error");
669             return false;
670         }
671         data_.userData.data[i] = v;
672     }
673     pdu.SkipBits();
674     return true;
675 }
676 
DecodeGsm7Bit(SmsReadBuffer & pdu,uint8_t numFields,uint8_t udhBytes)677 bool CdmaSmsUserData::DecodeGsm7Bit(SmsReadBuffer &pdu, uint8_t numFields, uint8_t udhBytes)
678 {
679     uint8_t udhLen = udhBytes == 0 ? 0 : (udhBytes + 1) * BIT8 / BIT7;
680     if (udhLen > 0) {
681         udhLen++;
682         // The header data is encoded in 7bit, the remaining bits need to be ignored.
683         uint8_t ignoredBits = BIT7 - (udhBytes + 1) * BIT8 % BIT7;
684         if (ignoredBits != BIT7) {
685             uint8_t v = 0;
686             if (!pdu.ReadBits(v, BIT8)) {
687                 TELEPHONY_LOGE("read error");
688                 return false;
689             }
690             udhLen++;
691         }
692     }
693     data_.userData.length = numFields - udhLen;
694     uint8_t udBytes = data_.userData.length * BIT7 / BIT8;
695     if (data_.userData.length * BIT7 % BIT8 > 0) {
696         udBytes++;
697     }
698     if (udBytes > MAX_USER_DATA_LEN + 1) {
699         TELEPHONY_LOGE("user data length error");
700         return false;
701     }
702     std::unique_ptr<uint8_t[]> dest = std::make_unique<uint8_t[]>(udBytes);
703     if (dest == nullptr) {
704         TELEPHONY_LOGE("make_unique error");
705         return false;
706     }
707     for (uint8_t i = 0; i < udBytes; i++) {
708         if (!pdu.ReadBits(dest[i], BIT8)) {
709             TELEPHONY_LOGE("data read error");
710             return false;
711         }
712     }
713     SmsCommonUtils::Unpack7bitChar(dest.get(), data_.userData.length, 0x00,
714         reinterpret_cast<uint8_t *>(data_.userData.data), MAX_USER_DATA_LEN + 1);
715     pdu.SkipBits();
716     return true;
717 }
718 
Decode8BitData(SmsReadBuffer & pdu)719 bool CdmaSmsUserData::Decode8BitData(SmsReadBuffer &pdu)
720 {
721     if (static_cast<unsigned long>(data_.userData.length) >
722         (sizeof(data_.userData.data) / sizeof(data_.userData.data[0]))) {
723         TELEPHONY_LOGE("user data length error");
724         return false;
725     }
726     uint8_t v = 0;
727     for (uint8_t i = 0; i < data_.userData.length; i++) {
728         if (!pdu.ReadBits(v, BIT8)) {
729             TELEPHONY_LOGE("data read error");
730             return false;
731         }
732         data_.userData.data[i] = v;
733     }
734     return true;
735 }
736 
GetEncodingType(uint8_t v)737 SmsEncodingType CdmaSmsUserData::GetEncodingType(uint8_t v)
738 {
739     if (v <= static_cast<uint8_t>(SmsEncodingType::GSMDCS) || v == static_cast<uint8_t>(SmsEncodingType::EUCKR)) {
740         return SmsEncodingType(v);
741     } else {
742         return SmsEncodingType::RESERVED;
743     }
744 }
745 
CdmaSmsCmasData(SmsTeleSvcCmasData & data)746 CdmaSmsCmasData::CdmaSmsCmasData(SmsTeleSvcCmasData &data) : data_(data)
747 {
748     id_ = USER_DATA;
749 }
750 
Encode(SmsWriteBuffer & pdu)751 bool CdmaSmsCmasData::Encode(SmsWriteBuffer &pdu)
752 {
753     TELEPHONY_LOGE("encode not support");
754     return false;
755 }
756 
Decode(SmsReadBuffer & pdu)757 bool CdmaSmsCmasData::Decode(SmsReadBuffer &pdu)
758 {
759     if (IsInvalidPdu(pdu)) {
760         TELEPHONY_LOGE("invalid pdu");
761         return false;
762     }
763 
764     if (memset_s(&data_, sizeof(SmsTeleSvcCmasData), 0x00, sizeof(SmsTeleSvcCmasData)) != EOK) {
765         TELEPHONY_LOGE("memset_s fail");
766         return false;
767     }
768     uint16_t index = pdu.GetIndex();
769     uint8_t v = 0;
770     if (!pdu.ReadBits(v, BIT5)) {
771         TELEPHONY_LOGE("encode type read error");
772         return false;
773     }
774     SmsEncodingType encodeType = CdmaSmsUserData::GetEncodingType(v);
775     if (encodeType != SmsEncodingType::OCTET) {
776         TELEPHONY_LOGE("wrong encode type [%{public}d], must be 0", v);
777         return false;
778     }
779     if (!pdu.ReadBits(v, BIT8) || !pdu.ReadBits(v, BIT8)) {
780         TELEPHONY_LOGE("protocol version read error");
781         return false;
782     }
783     if (v != 0x00) {
784         TELEPHONY_LOGE("wrong protocol version [%{public}d], must be 0", v);
785         data_.isWrongRecodeType = true;
786         return false;
787     }
788 
789     while (pdu.GetIndex() < index + len_ - 1) {
790         if (!DecodeData(pdu)) {
791             TELEPHONY_LOGE("decode data error");
792             return false;
793         }
794     }
795     pdu.SkipBits();
796     return true;
797 }
798 
DecodeData(SmsReadBuffer & pdu)799 bool CdmaSmsCmasData::DecodeData(SmsReadBuffer &pdu)
800 {
801     uint8_t v = 0;
802     if (!pdu.ReadBits(v, BIT8)) {
803         TELEPHONY_LOGE("type read error");
804         return false;
805     }
806     if (v == 0x00) {
807         if (!DecodeType0Data(pdu)) {
808             TELEPHONY_LOGE("type 0 decode error");
809             return false;
810         }
811     } else if (v == 0x01) {
812         if (!DecodeType1Data(pdu)) {
813             TELEPHONY_LOGE("type 1 decode error");
814             return false;
815         }
816     } else if (v == 0x02) {
817         if (!DecodeType2Data(pdu)) {
818             TELEPHONY_LOGE("type 2 decode error");
819             return false;
820         }
821     }
822     return true;
823 }
824 
DecodeType0Data(SmsReadBuffer & pdu)825 bool CdmaSmsCmasData::DecodeType0Data(SmsReadBuffer &pdu)
826 {
827     uint8_t len = 0;
828     uint8_t v = 0;
829     if (!pdu.ReadBits(len, BIT8) || !pdu.ReadBits(v, BIT5)) {
830         TELEPHONY_LOGE("len read error");
831         return false;
832     }
833     SmsEncodingType encodeType = CdmaSmsUserData::GetEncodingType(v);
834     if (encodeType == SmsEncodingType::ASCII_7BIT || encodeType == SmsEncodingType::IA5 ||
835         encodeType == SmsEncodingType::GSM7BIT) {
836         data_.dataLen = (len * BIT8 - BIT5) / BIT7;
837         if (static_cast<unsigned long>(data_.dataLen) > (sizeof(data_.alertText) / sizeof(data_.alertText[0]))) {
838             TELEPHONY_LOGE("alert text length error");
839             return false;
840         }
841         for (uint16_t i = 0; i < data_.dataLen; i++) {
842             if (!pdu.ReadBits(data_.alertText[i], BIT7)) {
843                 TELEPHONY_LOGE("alert text read error");
844                 return false;
845             }
846         }
847         uint8_t ignoredBits = (len * BIT8 - BIT5) % BIT7;
848         if (ignoredBits == BIT0) {
849             return true;
850         }
851         return pdu.ReadBits(v, ignoredBits);
852     } else if (encodeType == SmsEncodingType::EPM || encodeType == SmsEncodingType::GSMDCS) {
853         TELEPHONY_LOGE("encode type not support");
854         return false;
855     } else {
856         data_.dataLen = (len == 0) ? 0 : (len - 1);
857         if (static_cast<unsigned long>(data_.dataLen) > (sizeof(data_.alertText) / sizeof(data_.alertText[0]))) {
858             TELEPHONY_LOGE("alert text length invalid.");
859             return false;
860         }
861         for (uint16_t i = 0; i < data_.dataLen; i++) {
862             if (!pdu.ReadBits(data_.alertText[i], BIT8)) {
863                 TELEPHONY_LOGE("alert text read error");
864                 return false;
865             }
866         }
867     }
868     return true;
869 }
870 
DecodeType1Data(SmsReadBuffer & pdu)871 bool CdmaSmsCmasData::DecodeType1Data(SmsReadBuffer &pdu)
872 {
873     uint8_t v1 = 0;
874     uint8_t v2 = 0;
875     uint8_t v3 = 0;
876     uint8_t v4 = 0;
877     uint8_t v5 = 0;
878     if (!pdu.ReadBits(v1, BIT8)) {
879         TELEPHONY_LOGE("read error");
880         return false;
881     }
882     if (!pdu.ReadBits(v1, BIT8) || !pdu.ReadBits(v2, BIT8) || !pdu.ReadBits(v3, BIT4) || !pdu.ReadBits(v4, BIT4) ||
883         !pdu.ReadBits(v5, BIT4)) {
884         TELEPHONY_LOGE("data read error");
885         return false;
886     }
887     data_.category = static_cast<enum SmsCmaeCategory>(v1);
888     data_.responseType = static_cast<enum SmsCmaeResponseType>(v2);
889     data_.severity = static_cast<enum SmsCmaeSeverity>(v3);
890     data_.urgency = static_cast<enum SmsCmaeUrgency>(v4);
891     data_.certainty = static_cast<enum SmsCmaeCertainty>(v5);
892     return pdu.ReadBits(v1, BIT4);
893 }
894 
DecodeType2Data(SmsReadBuffer & pdu)895 bool CdmaSmsCmasData::DecodeType2Data(SmsReadBuffer &pdu)
896 {
897     uint8_t v1 = 0;
898     uint8_t v2 = 0;
899     if (!pdu.ReadBits(v1, BIT8)) {
900         TELEPHONY_LOGE("read error");
901         return false;
902     }
903     if (!pdu.ReadBits(v1, BIT8) || !pdu.ReadBits(v2, BIT8)) {
904         TELEPHONY_LOGE("id read error");
905         return false;
906     }
907     data_.id = v1;
908     data_.id = (data_.id << BIT8) + v2;
909     if (!pdu.ReadBits(v1, BIT8)) {
910         TELEPHONY_LOGE("alert handle read error");
911         return false;
912     }
913     data_.alertHandle = static_cast<enum SmsCmaeAlertHandle>(v1);
914     if (!DecodeAbsTime(pdu)) {
915         TELEPHONY_LOGE("abs time decode error");
916         return false;
917     }
918     if (!pdu.ReadBits(v1, BIT8)) {
919         TELEPHONY_LOGE("language read error");
920         return false;
921     }
922     data_.language = static_cast<enum SmsLanguageType>(v1);
923     return true;
924 }
925 
DecodeAbsTime(SmsReadBuffer & pdu)926 bool CdmaSmsCmasData::DecodeAbsTime(SmsReadBuffer &pdu)
927 {
928     uint8_t v1 = 0;
929     uint8_t v2 = 0;
930     if (!pdu.ReadBits(v1, BIT4) || !pdu.ReadBits(v2, BIT4)) {
931         TELEPHONY_LOGE("year read error");
932         return false;
933     }
934     data_.expires.year = (v1 * DECIMAL_NUM) + v2;
935     if (!pdu.ReadBits(v1, BIT4) || !pdu.ReadBits(v2, BIT4)) {
936         TELEPHONY_LOGE("month read error");
937         return false;
938     }
939     data_.expires.month = (v1 * DECIMAL_NUM) + v2;
940     if (!pdu.ReadBits(v1, BIT4) || !pdu.ReadBits(v2, BIT4)) {
941         TELEPHONY_LOGE("day read error");
942         return false;
943     }
944     data_.expires.day = (v1 * DECIMAL_NUM) + v2;
945     if (!pdu.ReadBits(v1, BIT4) || !pdu.ReadBits(v2, BIT4)) {
946         TELEPHONY_LOGE("hour read error");
947         return false;
948     }
949     data_.expires.hour = (v1 * DECIMAL_NUM) + v2;
950     if (!pdu.ReadBits(v1, BIT4) || !pdu.ReadBits(v2, BIT4)) {
951         TELEPHONY_LOGE("minute read error");
952         return false;
953     }
954     data_.expires.minute = (v1 * DECIMAL_NUM) + v2;
955     if (!pdu.ReadBits(v1, BIT4) || !pdu.ReadBits(v2, BIT4)) {
956         TELEPHONY_LOGE("second read error");
957         return false;
958     }
959     data_.expires.second = (v1 * DECIMAL_NUM) + v2;
960     return true;
961 }
962 
CdmaSmsAlertPriority(SmsAlertPriority & alertPriority)963 CdmaSmsAlertPriority::CdmaSmsAlertPriority(SmsAlertPriority &alertPriority) : alertPriority_(alertPriority)
964 {
965     id_ = ALERT_ON_MSG_DELIVERY;
966     len_ = sizeof(uint8_t);
967 }
968 
Encode(SmsWriteBuffer & pdu)969 bool CdmaSmsAlertPriority::Encode(SmsWriteBuffer &pdu)
970 {
971     if (pdu.IsEmpty()) {
972         TELEPHONY_LOGE("pdu is empty");
973         return false;
974     }
975 
976     if (pdu.WriteByte(id_) && pdu.WriteByte(len_)) {
977         if (pdu.WriteBits(static_cast<uint8_t>(alertPriority_), BIT2)) {
978             pdu.SkipBits();
979             return true;
980         }
981     }
982 
983     TELEPHONY_LOGE("encode error");
984     return false;
985 }
986 
Decode(SmsReadBuffer & pdu)987 bool CdmaSmsAlertPriority::Decode(SmsReadBuffer &pdu)
988 {
989     if (IsInvalidPdu(pdu)) {
990         TELEPHONY_LOGE("invalid pdu");
991         return false;
992     }
993 
994     uint8_t v = 0;
995     if (!pdu.ReadBits(v, BIT2)) {
996         TELEPHONY_LOGE("data read error");
997         return false;
998     }
999     pdu.SkipBits();
1000     alertPriority_ = SmsAlertPriority(v);
1001     return true;
1002 }
1003 
CdmaSmsLanguageInd(SmsLanguageType & language)1004 CdmaSmsLanguageInd::CdmaSmsLanguageInd(SmsLanguageType &language) : language_(language)
1005 {
1006     id_ = LANGUAGE_INDICATOR;
1007     len_ = sizeof(uint8_t);
1008 }
1009 
Encode(SmsWriteBuffer & pdu)1010 bool CdmaSmsLanguageInd::Encode(SmsWriteBuffer &pdu)
1011 {
1012     if (pdu.IsEmpty()) {
1013         TELEPHONY_LOGE("pdu is empty");
1014         return false;
1015     }
1016 
1017     if (pdu.WriteByte(id_) && pdu.WriteByte(len_) && pdu.WriteByte(static_cast<uint8_t>(language_))) {
1018         return true;
1019     }
1020 
1021     TELEPHONY_LOGE("encode error");
1022     return false;
1023 }
1024 
Decode(SmsReadBuffer & pdu)1025 bool CdmaSmsLanguageInd::Decode(SmsReadBuffer &pdu)
1026 {
1027     if (IsInvalidPdu(pdu)) {
1028         TELEPHONY_LOGE("invalid pdu");
1029         return false;
1030     }
1031 
1032     uint8_t v = 0;
1033     if (!pdu.ReadByte(v)) {
1034         TELEPHONY_LOGE("data read error");
1035         return false;
1036     }
1037     language_ = SmsLanguageType(v);
1038     return true;
1039 }
1040 
CdmaSmsCallbackNumber(SmsTeleSvcAddr & address)1041 CdmaSmsCallbackNumber::CdmaSmsCallbackNumber(SmsTeleSvcAddr &address) : address_(address)
1042 {
1043     id_ = CALLBACK_NUMBER;
1044 }
1045 
Encode(SmsWriteBuffer & pdu)1046 bool CdmaSmsCallbackNumber::Encode(SmsWriteBuffer &pdu)
1047 {
1048     if (pdu.IsEmpty()) {
1049         TELEPHONY_LOGE("pdu is empty");
1050         return false;
1051     }
1052 
1053     if (!pdu.WriteByte(id_)) {
1054         TELEPHONY_LOGE("id write error");
1055         return false;
1056     }
1057     uint16_t lenIndex = pdu.MoveForward();
1058     if (!pdu.WriteBits(address_.digitMode ? 0b1 : 0b0)) {
1059         TELEPHONY_LOGE("digit mode write error");
1060         return false;
1061     }
1062     if (static_cast<unsigned long>(address_.addrLen) > (sizeof(address_.szData) / sizeof(address_.szData[0]))) {
1063         TELEPHONY_LOGE("address length error");
1064         return false;
1065     }
1066     if (address_.digitMode) {
1067         // Type of number and Numbering plan
1068         if (!pdu.WriteBits(address_.numberType, BIT3) || !pdu.WriteBits(address_.numberPlan, BIT4) ||
1069             !pdu.WriteBits(address_.addrLen, BIT8)) {
1070             TELEPHONY_LOGE("number type, number plan or addrlen write error");
1071             return false;
1072         }
1073 
1074         for (uint8_t i = 0; i < address_.addrLen; i++) {
1075             if (!pdu.WriteBits(address_.szData[i], BIT8)) {
1076                 TELEPHONY_LOGE("data write error");
1077                 return false;
1078             }
1079         }
1080     } else {
1081         if (!pdu.WriteBits(address_.addrLen, BIT8)) {
1082             TELEPHONY_LOGE("addrlen write error");
1083             return false;
1084         }
1085         for (uint8_t i = 0; i < address_.addrLen; i++) {
1086             if (!pdu.WriteBits(SmsCommonUtils::DigitToDtmfChar(address_.szData[i]), BIT4)) {
1087                 TELEPHONY_LOGE("data write error");
1088                 return false;
1089             }
1090         }
1091     }
1092     len_ = pdu.SkipBits() - lenIndex - 1;
1093     return pdu.InsertByte(len_, lenIndex);
1094 }
1095 
Decode(SmsReadBuffer & pdu)1096 bool CdmaSmsCallbackNumber::Decode(SmsReadBuffer &pdu)
1097 {
1098     if (IsInvalidPdu(pdu)) {
1099         TELEPHONY_LOGE("invalid pdu");
1100         return false;
1101     }
1102 
1103     uint8_t v = 0;
1104     if (!pdu.ReadBits(v)) {
1105         TELEPHONY_LOGE("digit mode read error");
1106         return false;
1107     }
1108     address_.digitMode = (v == 0b1) ? true : false;
1109     if (address_.digitMode) {
1110         // Type of number and Numbering plan
1111         if (!pdu.ReadBits(address_.numberType, BIT3) || !pdu.ReadBits(address_.numberPlan, BIT4)) {
1112             TELEPHONY_LOGE("number type or number plan read error");
1113             return false;
1114         }
1115     }
1116 
1117     if (!pdu.ReadBits(v, BIT8)) {
1118         TELEPHONY_LOGE("addrlen read error");
1119         return false;
1120     }
1121     address_.addrLen = v;
1122     if (static_cast<unsigned long>(address_.addrLen) > (sizeof(address_.szData) / sizeof(address_.szData[0]))) {
1123         TELEPHONY_LOGE("address length error");
1124         return false;
1125     }
1126     if (address_.digitMode) {
1127         for (uint8_t i = 0; i < address_.addrLen; i++) {
1128             if (!pdu.ReadBits(v, BIT8)) {
1129                 TELEPHONY_LOGE("data read error");
1130                 return false;
1131             }
1132             address_.szData[i] = v;
1133         }
1134     } else {
1135         for (uint8_t i = 0; i < address_.addrLen; i++) {
1136             if (!pdu.ReadBits(v, BIT4)) {
1137                 TELEPHONY_LOGE("data read error");
1138                 return false;
1139             }
1140             address_.szData[i] = SmsCommonUtils::DtmfCharToDigit(v);
1141         }
1142     }
1143     pdu.SkipBits();
1144     return true;
1145 }
1146 
CdmaSmsDepositIndex(uint16_t & index)1147 CdmaSmsDepositIndex::CdmaSmsDepositIndex(uint16_t &index) : index_(index)
1148 {
1149     id_ = MESSAGE_DEPOSIT_INDEX;
1150     len_ = sizeof(index_);
1151 }
1152 
Encode(SmsWriteBuffer & pdu)1153 bool CdmaSmsDepositIndex::Encode(SmsWriteBuffer &pdu)
1154 {
1155     if (pdu.IsEmpty()) {
1156         TELEPHONY_LOGE("pdu is empty");
1157         return false;
1158     }
1159 
1160     if (pdu.WriteByte(id_) && pdu.WriteByte(len_) && pdu.WriteWord(index_)) {
1161         return true;
1162     }
1163 
1164     TELEPHONY_LOGE("encode error");
1165     return false;
1166 }
1167 
Decode(SmsReadBuffer & pdu)1168 bool CdmaSmsDepositIndex::Decode(SmsReadBuffer &pdu)
1169 {
1170     if (IsInvalidPdu(pdu)) {
1171         TELEPHONY_LOGE("invalid pdu");
1172         return false;
1173     }
1174 
1175     return pdu.ReadWord(index_);
1176 }
1177 
CdmaSmsDisplayMode(SmsDisplayMode & mode)1178 CdmaSmsDisplayMode::CdmaSmsDisplayMode(SmsDisplayMode &mode) : mode_(mode)
1179 {
1180     id_ = MESSAGE_DISPLAY_MODE;
1181     len_ = sizeof(uint8_t);
1182 }
1183 
Encode(SmsWriteBuffer & pdu)1184 bool CdmaSmsDisplayMode::Encode(SmsWriteBuffer &pdu)
1185 {
1186     if (pdu.IsEmpty()) {
1187         TELEPHONY_LOGE("pdu is empty");
1188         return false;
1189     }
1190 
1191     if (pdu.WriteByte(id_) && pdu.WriteByte(len_)) {
1192         if (pdu.WriteBits(static_cast<uint8_t>(mode_), BIT2)) {
1193             pdu.SkipBits();
1194             return true;
1195         }
1196     }
1197 
1198     TELEPHONY_LOGE("encode error");
1199     return false;
1200 }
1201 
Decode(SmsReadBuffer & pdu)1202 bool CdmaSmsDisplayMode::Decode(SmsReadBuffer &pdu)
1203 {
1204     if (IsInvalidPdu(pdu)) {
1205         TELEPHONY_LOGE("invalid pdu");
1206         return false;
1207     }
1208 
1209     uint8_t v = 0;
1210     if (!pdu.ReadBits(v, BIT2)) {
1211         TELEPHONY_LOGE("data read error");
1212         return false;
1213     }
1214     pdu.SkipBits();
1215     mode_ = SmsDisplayMode(v);
1216     return true;
1217 }
1218 
CdmaSmsMessageStatus(SmsStatusCode & status)1219 CdmaSmsMessageStatus::CdmaSmsMessageStatus(SmsStatusCode &status) : status_(status)
1220 {
1221     id_ = MESSAGE_STATUS;
1222 }
1223 
Encode(SmsWriteBuffer & pdu)1224 bool CdmaSmsMessageStatus::Encode(SmsWriteBuffer &pdu)
1225 {
1226     TELEPHONY_LOGE("encode not support");
1227     return false;
1228 }
1229 
Decode(SmsReadBuffer & pdu)1230 bool CdmaSmsMessageStatus::Decode(SmsReadBuffer &pdu)
1231 {
1232     if (IsInvalidPdu(pdu)) {
1233         TELEPHONY_LOGE("invalid pdu");
1234         return false;
1235     }
1236 
1237     uint8_t v = 0;
1238     if (!pdu.ReadByte(v)) {
1239         TELEPHONY_LOGE("data read error");
1240         return false;
1241     }
1242     status_ = (SmsStatusCode)v;
1243     return true;
1244 }
1245 
CdmaSmsNumberMessages(uint32_t & num)1246 CdmaSmsNumberMessages::CdmaSmsNumberMessages(uint32_t &num) : num_(num)
1247 {
1248     id_ = NUMBER_OF_MESSAGES;
1249 }
1250 
Encode(SmsWriteBuffer & pdu)1251 bool CdmaSmsNumberMessages::Encode(SmsWriteBuffer &pdu)
1252 {
1253     TELEPHONY_LOGE("encode not support");
1254     return false;
1255 }
1256 
Decode(SmsReadBuffer & pdu)1257 bool CdmaSmsNumberMessages::Decode(SmsReadBuffer &pdu)
1258 {
1259     if (IsInvalidPdu(pdu)) {
1260         TELEPHONY_LOGE("invalid pdu");
1261         return false;
1262     }
1263 
1264     uint8_t v = 0;
1265     if (!pdu.ReadByte(v)) {
1266         TELEPHONY_LOGE("data read error");
1267         return false;
1268     }
1269     num_ = (((v & 0xf0) >> BIT4) * DECIMAL_NUM) + (v & 0x0f);
1270     return true;
1271 }
1272 
CdmaSmsEnhancedVmn(SmsEnhancedVmn & vmn)1273 CdmaSmsEnhancedVmn::CdmaSmsEnhancedVmn(SmsEnhancedVmn &vmn) : vmn_(vmn)
1274 {
1275     id_ = ENHANCED_VMN;
1276 }
1277 
Encode(SmsWriteBuffer & pdu)1278 bool CdmaSmsEnhancedVmn::Encode(SmsWriteBuffer &pdu)
1279 {
1280     TELEPHONY_LOGE("encode not support");
1281     return false;
1282 }
1283 
Decode(SmsReadBuffer & pdu)1284 bool CdmaSmsEnhancedVmn::Decode(SmsReadBuffer &pdu)
1285 {
1286     if (IsInvalidPdu(pdu)) {
1287         TELEPHONY_LOGE("invalid pdu");
1288         return false;
1289     }
1290 
1291     if (memset_s(&vmn_, sizeof(SmsEnhancedVmn), 0x00, sizeof(SmsEnhancedVmn)) != EOK) {
1292         TELEPHONY_LOGE("memset_s fail");
1293         return false;
1294     }
1295     if (DecodeHeader(pdu) && DecodeVoiceMail(pdu) && DecodeAccessNumber(pdu) && DecodeCallingPartyNumber(pdu)) {
1296         pdu.SkipBits();
1297         return true;
1298     }
1299 
1300     TELEPHONY_LOGE("decode error");
1301     return false;
1302 }
1303 
DecodeHeader(SmsReadBuffer & pdu)1304 bool CdmaSmsEnhancedVmn::DecodeHeader(SmsReadBuffer &pdu)
1305 {
1306     uint8_t v1 = 0;
1307     uint8_t v2 = 0;
1308     uint8_t v3 = 0;
1309     uint8_t v4 = 0;
1310     if (!pdu.ReadBits(v1, BIT2) || !pdu.ReadBits(v2, BIT1) || !pdu.ReadBits(v3, BIT1) || !pdu.ReadBits(v4, BIT1)) {
1311         TELEPHONY_LOGE("data read error");
1312         return false;
1313     }
1314     vmn_.priority = SmsPriorityIndicator(v1);
1315     vmn_.passwordReq = (v2 == 0b1) ? true : false;
1316     vmn_.setupReq = (v3 == 0b1) ? true : false;
1317     vmn_.pwChangeReq = (v4 == 0b1) ? true : false;
1318     if (vmn_.setupReq || vmn_.pwChangeReq) {
1319         if (!pdu.ReadBits(vmn_.minPwLen, BIT4) || !pdu.ReadBits(vmn_.maxPwLen, BIT4)) {
1320             TELEPHONY_LOGE("min pwlen or max pwlen read error");
1321             return false;
1322         }
1323     }
1324 
1325     return true;
1326 }
1327 
DecodeVoiceMail(SmsReadBuffer & pdu)1328 bool CdmaSmsEnhancedVmn::DecodeVoiceMail(SmsReadBuffer &pdu)
1329 {
1330     uint8_t v1 = 0;
1331     uint8_t v2 = 0;
1332     uint8_t v3 = 0;
1333     uint8_t v4 = 0;
1334     if (!pdu.ReadBits(vmn_.vmNumUnheardMsg, BIT8)) {
1335         TELEPHONY_LOGE("num unheard msg read error");
1336         return false;
1337     }
1338     if (!pdu.ReadBits(v1, BIT1) || !pdu.ReadBits(v2, BIT1) || !pdu.ReadBits(v3, BIT1) || !pdu.ReadBits(v4, BIT1)) {
1339         TELEPHONY_LOGE("data read error");
1340         return false;
1341     }
1342     vmn_.vmMailboxAlmFull = (v1 == 0b1) ? true : false;
1343     vmn_.vmMailboxFull = (v2 == 0b1) ? true : false;
1344     vmn_.replyAllowed = (v3 == 0b1) ? true : false;
1345     vmn_.faxIncluded = (v4 == 0b1) ? true : false;
1346 
1347     if (!pdu.ReadBits(v1, BIT7) || !pdu.ReadBits(v2, BIT5) || !pdu.ReadBits(vmn_.vmRetDay, BIT7)) {
1348         TELEPHONY_LOGE("vmlen or vmretday read error");
1349         return false;
1350     }
1351     vmn_.vmLen = v1;
1352     vmn_.vmLen = (vmn_.vmLen << BIT5) | v2;
1353 
1354     if (!pdu.ReadBits(v1, BIT8) || !pdu.ReadBits(v2, BIT8) || !pdu.ReadBits(v3, BIT8) || !pdu.ReadBits(v4, BIT8)) {
1355         TELEPHONY_LOGE("msgid or mailboxid read error");
1356         return false;
1357     }
1358     vmn_.vmMsgId = v1;
1359     vmn_.vmMsgId = (vmn_.vmMsgId << BIT8) | v2;
1360     vmn_.vmMailboxId = v3;
1361     vmn_.vmMailboxId = (vmn_.vmMailboxId << BIT8) | v4;
1362 
1363     return true;
1364 }
1365 
DecodeAccessNumber(SmsReadBuffer & pdu)1366 bool CdmaSmsEnhancedVmn::DecodeAccessNumber(SmsReadBuffer &pdu)
1367 {
1368     uint8_t v1 = 0;
1369     uint8_t v2 = 0;
1370     if (!pdu.ReadBits(v1, BIT1) || !pdu.ReadBits(v2, BIT3)) {
1371         TELEPHONY_LOGE("digitmode or numbertype read error");
1372         return false;
1373     }
1374     vmn_.anDigitMode = (v1 == 0b1) ? true : false;
1375     vmn_.anNumberType = v2;
1376     if (vmn_.anDigitMode) {
1377         if (!pdu.ReadBits(vmn_.anNumberPlan, BIT4) || !pdu.ReadBits(vmn_.anNumField, BIT8)) {
1378             TELEPHONY_LOGE("number plan or num field read error");
1379             return false;
1380         }
1381         if (static_cast<unsigned long>(vmn_.anNumField) > (sizeof(vmn_.anChar) / sizeof(vmn_.anChar[0]))) {
1382             TELEPHONY_LOGE("enhancedVmn data length invalid.");
1383             return false;
1384         }
1385         for (uint8_t i = 0; i < vmn_.anNumField; i++) {
1386             if (!pdu.ReadBits(v1, BIT4)) {
1387                 TELEPHONY_LOGE("char read error");
1388                 return false;
1389             }
1390             vmn_.anChar[i] = SmsCommonUtils::DtmfCharToDigit(v1);
1391         }
1392         vmn_.anChar[vmn_.anNumField] = '\0';
1393     } else {
1394         if (!pdu.ReadBits(vmn_.anNumField, BIT8)) {
1395             TELEPHONY_LOGE("num field read error");
1396             return false;
1397         }
1398         if (static_cast<unsigned long>(vmn_.anNumField) > (sizeof(vmn_.anChar) / sizeof(vmn_.anChar[0]))) {
1399             TELEPHONY_LOGE("enhancedVmn data length invalid.");
1400             return false;
1401         }
1402         for (uint8_t i = 0; i < vmn_.anNumField; i++) {
1403             if (!pdu.ReadBits(vmn_.anChar[i], BIT8)) {
1404                 TELEPHONY_LOGE("char read error");
1405                 return false;
1406             }
1407         }
1408     }
1409     return true;
1410 }
1411 
DecodeCallingPartyNumber(SmsReadBuffer & pdu)1412 bool CdmaSmsEnhancedVmn::DecodeCallingPartyNumber(SmsReadBuffer &pdu)
1413 {
1414     uint8_t v = 0;
1415     if (!pdu.ReadBits(v, BIT1) || !pdu.ReadBits(vmn_.cliNumberType, BIT3)) {
1416         TELEPHONY_LOGE("digit mode or number type read error");
1417         return false;
1418     }
1419     vmn_.cliDigitMode = (v == 0b1) ? true : false;
1420     if (vmn_.cliDigitMode) {
1421         if (!pdu.ReadBits(vmn_.cliNumberPlan, BIT4) || !pdu.ReadBits(vmn_.cliNumField, BIT8)) {
1422             TELEPHONY_LOGE("number plan or num field read error");
1423             return false;
1424         }
1425         if (static_cast<unsigned long>(vmn_.cliNumField) > (sizeof(vmn_.cliChar) / sizeof(vmn_.cliChar[0]))) {
1426             TELEPHONY_LOGE("enhancedVmn data length invalid.");
1427             return false;
1428         }
1429         for (uint8_t i = 0; i < vmn_.cliNumField; i++) {
1430             if (!pdu.ReadBits(v, BIT4)) {
1431                 TELEPHONY_LOGE("char read error");
1432                 return false;
1433             }
1434             vmn_.cliChar[i] = SmsCommonUtils::DtmfCharToDigit(v);
1435         }
1436         vmn_.cliChar[vmn_.cliNumField] = '\0';
1437     } else {
1438         if (!pdu.ReadBits(vmn_.cliNumField, BIT8)) {
1439             TELEPHONY_LOGE("num field read error");
1440             return false;
1441         }
1442         if (static_cast<unsigned long>(vmn_.cliNumField) > (sizeof(vmn_.cliChar) / sizeof(vmn_.cliChar[0]))) {
1443             TELEPHONY_LOGE("enhancedVmn data length invalid.");
1444             return false;
1445         }
1446         for (uint8_t i = 0; i < vmn_.cliNumField; i++) {
1447             if (!pdu.ReadBits(vmn_.cliChar[i], BIT8)) {
1448                 TELEPHONY_LOGE("char read error");
1449                 return false;
1450             }
1451         }
1452     }
1453     return true;
1454 }
1455 
CdmaSmsEnhancedVmnAck(SmsEnhancedVmnAck & ack)1456 CdmaSmsEnhancedVmnAck::CdmaSmsEnhancedVmnAck(SmsEnhancedVmnAck &ack) : ack_(ack)
1457 {
1458     id_ = ENHANCED_VMN_ACK;
1459 }
1460 
Encode(SmsWriteBuffer & pdu)1461 bool CdmaSmsEnhancedVmnAck::Encode(SmsWriteBuffer &pdu)
1462 {
1463     TELEPHONY_LOGE("encode not support");
1464     return false;
1465 }
1466 
Decode(SmsReadBuffer & pdu)1467 bool CdmaSmsEnhancedVmnAck::Decode(SmsReadBuffer &pdu)
1468 {
1469     if (IsInvalidPdu(pdu)) {
1470         TELEPHONY_LOGE("invalid pdu");
1471         return false;
1472     }
1473 
1474     if (memset_s(&ack_, sizeof(SmsEnhancedVmnAck), 0x00, sizeof(SmsEnhancedVmnAck)) != EOK) {
1475         TELEPHONY_LOGE("memset_s fail");
1476         return false;
1477     }
1478     if (!pdu.ReadWord(ack_.vmMailboxId) || !pdu.ReadByte(ack_.vmNumUnheardMsg)) {
1479         TELEPHONY_LOGE("mail boxid or num unheard msg read error");
1480         return false;
1481     }
1482     uint8_t v1 = 0;
1483     uint8_t v2 = 0;
1484     if (!pdu.ReadBits(v1, BIT3) || !pdu.ReadBits(v2, BIT3)) {
1485         TELEPHONY_LOGE("delete ack or play ack read error");
1486         return false;
1487     }
1488     ack_.numDeleteAck = v1;
1489     ack_.numPlayAck = v2;
1490     if (static_cast<unsigned long>(ack_.numDeleteAck) > (sizeof(ack_.daVmMsgId) / sizeof(ack_.daVmMsgId[0]))) {
1491         TELEPHONY_LOGE("delect ack length error");
1492         return false;
1493     }
1494     for (uint8_t i = 0; i < ack_.numDeleteAck; i++) {
1495         if (!pdu.ReadBits(v1, BIT8) || !pdu.ReadBits(v2, BIT8)) {
1496             TELEPHONY_LOGE("msgid read error");
1497             return false;
1498         }
1499         ack_.daVmMsgId[i] = v1;
1500         ack_.daVmMsgId[i] = (ack_.daVmMsgId[i] << BIT8) | v2;
1501     }
1502     if (static_cast<unsigned long>(ack_.numPlayAck) > (sizeof(ack_.paVmMsgId) / sizeof(ack_.paVmMsgId[0]))) {
1503         TELEPHONY_LOGE("play ack length error");
1504         return false;
1505     }
1506     for (uint8_t i = 0; i < ack_.numPlayAck; i++) {
1507         if (!pdu.ReadBits(v1, BIT8) || !pdu.ReadBits(v2, BIT8)) {
1508             TELEPHONY_LOGE("msgid read error");
1509             return false;
1510         }
1511         ack_.paVmMsgId[i] = v1;
1512         ack_.paVmMsgId[i] = (ack_.paVmMsgId[i] << BIT8) | v2;
1513     }
1514     pdu.SkipBits();
1515     return true;
1516 }
1517 
1518 } // namespace Telephony
1519 } // namespace OHOS
1520