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_common.h"
17 #include "gsm_cb_gsm_codec.h"
18 #include "gsm_cb_umts_codec.h"
19 #include "gsm_pdu_hex_value.h"
20 #include "securec.h"
21 #include "sms_common_utils.h"
22 #include "string_utils.h"
23 #include "telephony_ext_wrapper.h"
24 #include "telephony_log_wrapper.h"
25 #include "text_coder.h"
26 
27 namespace OHOS {
28 namespace Telephony {
29 static constexpr uint8_t SMS_BYTE_BIT = 8;
30 static constexpr uint8_t GSM_CB_HEADER_LEN = 6;
31 static constexpr uint16_t MAX_CB_MSG_LEN = 4200;
32 static constexpr uint8_t MAX_PAGE_PDU_LEN = 82;
33 static constexpr uint8_t CB_FORMAT_3GPP = 1;
34 static constexpr uint16_t OTHER_TYPE = -2;
35 static constexpr uint16_t ETWS_TYPE = 0x1100;
36 static constexpr uint16_t ETWS_TYPE_MASK = 0xFFF8;
37 static constexpr uint16_t CMAS_FIRST_ID = 0x1112;
38 static constexpr uint16_t CMAS_LAST_ID = 0x112F;
39 static constexpr uint16_t EMERGENCY_USER_ALERT = 0x2000;
40 static constexpr uint16_t ETWS_POPUP = 0x1000;
41 static constexpr uint16_t PWS_FIRST_ID = 0x1100;
42 static constexpr uint16_t PWS_LAST_ID = 0x18FF;
43 
operator ==(const GsmCbCodec & codec) const44 bool GsmCbCodec::operator==(const GsmCbCodec &codec) const
45 {
46     if (cbHeader_ == nullptr || codec.cbHeader_ == nullptr) {
47         TELEPHONY_LOGE("nullptr error.");
48         return false;
49     }
50     return cbHeader_->serialNum.geoScope == codec.cbHeader_->serialNum.geoScope &&
51            cbHeader_->serialNum.msgCode == codec.cbHeader_->serialNum.msgCode &&
52            cbHeader_->msgId == codec.cbHeader_->msgId;
53 }
54 
CreateCbMessage(const std::string & pdu)55 std::shared_ptr<GsmCbCodec> GsmCbCodec::CreateCbMessage(const std::string &pdu)
56 {
57     bool result = false;
58     std::shared_ptr<GsmCbCodec> message = std::make_shared<GsmCbCodec>();
59     if (message == nullptr) {
60         TELEPHONY_LOGE("message is nullptr.");
61         return nullptr;
62     }
63     result = message->PduAnalysis(StringUtils::HexToByteVector(pdu));
64     return (result ? message : nullptr);
65 }
66 
CreateCbMessage(const std::vector<unsigned char> & pdu)67 std::shared_ptr<GsmCbCodec> GsmCbCodec::CreateCbMessage(const std::vector<unsigned char> &pdu)
68 {
69     bool result = false;
70     std::shared_ptr<GsmCbCodec> message = std::make_shared<GsmCbCodec>();
71     if (message == nullptr) {
72         TELEPHONY_LOGE("message is nullptr.");
73         return nullptr;
74     }
75     result = message->PduAnalysis(pdu);
76     return (result ? message : nullptr);
77 }
78 
GetCbHeader() const79 std::shared_ptr<GsmCbCodec::GsmCbMessageHeader> GsmCbCodec::GetCbHeader() const
80 {
81     return cbHeader_;
82 }
83 
GetCbMessageRaw() const84 std::string GsmCbCodec::GetCbMessageRaw() const
85 {
86     return messageRaw_;
87 }
88 
SetCbMessageRaw(std::string & raw)89 void GsmCbCodec::SetCbMessageRaw(std::string &raw)
90 {
91     messageRaw_ = raw;
92 }
93 
IsSinglePageMsg() const94 bool GsmCbCodec::IsSinglePageMsg() const
95 {
96     return cbHeader_ != nullptr && (cbHeader_->totalPages == 1);
97 }
98 
99 /**
100  * refer to 3GPP TS 23.041 V4.1.0 9.1.1 9.1.2 section Protocols and Protocol Architecture
101  * refer to 3GPP TS 23.041 V4.1.0 9.3 Parameters
102  */
PduAnalysis(const std::vector<unsigned char> & pdu)103 bool GsmCbCodec::PduAnalysis(const std::vector<unsigned char> &pdu)
104 {
105     if (!ParamsCheck(pdu)) {
106         TELEPHONY_LOGE("params error.");
107         return false;
108     }
109     auto gsmCodec = std::make_shared<GsmCbGsmCodec>(cbHeader_, cbPduBuffer_, shared_from_this());
110     auto umtsCodec = std::make_shared<GsmCbUmtsCodec>(cbHeader_, cbPduBuffer_, shared_from_this());
111     if (gsmCodec == nullptr || umtsCodec == nullptr) {
112         TELEPHONY_LOGE("nullptr error.");
113         return false;
114     }
115 
116     // refer to 3GPP TS 23.041 V4.1.0 9.1.1 9.1.2 section Protocols and Protocol Architecture
117     bool decodeResult = false;
118     if (pdu.size() <= (MAX_PAGE_PDU_LEN + GSM_CB_HEADER_LEN)) {
119         cbHeader_->cbMsgType = GSM_CBS;
120         cbHeader_->cbNetType = GSM_NET_CB;
121         decodeResult = gsmCodec->Decode2gHeader();
122     } else if (pdu.size() <= MAX_CB_MSG_LEN) {
123         uint8_t oneByte = 0;
124         if (!cbPduBuffer_->PickOneByte(oneByte)) {
125             TELEPHONY_LOGE("get data error.");
126             return false;
127         }
128         cbHeader_->cbMsgType = oneByte;
129         cbHeader_->cbNetType = UMTS_NET_CB;
130         decodeResult = umtsCodec->Decode3gHeader();
131     } else {
132         TELEPHONY_LOGE("pdu size over max.");
133         return false;
134     }
135 
136     if (!decodeResult || cbPduBuffer_->GetCurPosition() >= pdu.size()) {
137         TELEPHONY_LOGE("CB decode head fail.");
138         return false;
139     }
140     if (cbHeader_->bEtwsMessage && cbHeader_->cbEtwsType == ETWS_PRIMARY) {
141         return gsmCodec->DecodeEtwsMsg();
142     }
143 
144     if (cbHeader_->cbNetType == GSM_NET_CB) {
145         decodeResult = gsmCodec->Decode2gCbMsg();
146     } else if (cbHeader_->cbNetType == UMTS_NET_CB) {
147         decodeResult = umtsCodec->Decode3gCbMsg();
148     }
149     TELEPHONY_LOGI("CB decode result:%{public}d.", decodeResult);
150     return decodeResult;
151 }
152 
ParamsCheck(const std::vector<unsigned char> & pdu)153 bool GsmCbCodec::ParamsCheck(const std::vector<unsigned char> &pdu)
154 {
155     if (pdu.size() == 0 && pdu.size() > MAX_CB_MSG_LEN) {
156         TELEPHONY_LOGE("pdu data error.");
157         return false;
158     }
159     cbPduBuffer_ = std::make_shared<GsmCbPduDecodeBuffer>(pdu.size());
160     cbHeader_ = std::make_shared<GsmCbCodec::GsmCbMessageHeader>();
161     if (cbPduBuffer_ == nullptr || cbHeader_ == nullptr || cbPduBuffer_->pduBuffer_ == nullptr) {
162         TELEPHONY_LOGE("nullptr error.");
163         return false;
164     }
165     for (size_t index = 0; index < pdu.size() && index < cbPduBuffer_->GetSize(); index++) {
166         cbPduBuffer_->pduBuffer_[index] = static_cast<char>(pdu[index]);
167     }
168     return true;
169 }
170 
GetPduData(std::vector<unsigned char> & dataPdu)171 void GsmCbCodec::GetPduData(std::vector<unsigned char> &dataPdu)
172 {
173     if (cbPduBuffer_ == nullptr) {
174         TELEPHONY_LOGE("nullptr error.");
175         return;
176     }
177 
178     uint32_t current = cbPduBuffer_->GetCurPosition();
179     uint8_t oneByte = 0;
180     while (cbPduBuffer_->GetCurPosition() < cbPduBuffer_->GetSize()) {
181         if (!cbPduBuffer_->GetOneByte(oneByte)) {
182             TELEPHONY_LOGE("get data error.");
183         }
184         dataPdu.push_back(oneByte);
185     }
186     cbPduBuffer_->SetPointer(current);
187 }
188 
ConvertToUTF8(const std::string & raw,std::string & message) const189 void GsmCbCodec::ConvertToUTF8(const std::string &raw, std::string &message) const
190 {
191     if (cbHeader_ == nullptr) {
192         TELEPHONY_LOGE("ConvertToUTF8 cbHeader null err.");
193         return;
194     }
195     if (cbHeader_->bEtwsMessage && cbHeader_->cbEtwsType == ETWS_PRIMARY) {
196         message.assign(raw);
197     } else {
198         uint16_t codeSize = 0;
199         MsgLangInfo langInfo;
200         uint8_t outBuf[MAX_CB_MSG_LEN + 1] = { 0 };
201         const uint8_t *src = reinterpret_cast<const uint8_t *>(raw.data());
202         if (cbHeader_->dcs.codingScheme == DATA_CODING_7BIT) {
203             codeSize = TextCoder::Instance().Gsm7bitToUtf8(outBuf, sizeof(outBuf), src, raw.length(), langInfo);
204         } else if (cbHeader_->dcs.codingScheme == DATA_CODING_UCS2) {
205             codeSize = TextCoder::Instance().Ucs2ToUtf8(outBuf, sizeof(outBuf), src, raw.length());
206         } else {
207             TELEPHONY_LOGI("CB message data encoding 8bit");
208             message.assign(raw);
209             return;
210         }
211         if (codeSize >= MAX_CB_MSG_LEN) {
212             TELEPHONY_LOGE("codeSize over size.");
213             return;
214         }
215         outBuf[codeSize] = '\0';
216         for (uint16_t index = 0; index < codeSize; index++) {
217             message.push_back(static_cast<char>(outBuf[index]));
218         }
219     }
220 }
221 
EncodeCbSerialNum(const GsmCBMsgSerialNum & snFields)222 unsigned short GsmCbCodec::EncodeCbSerialNum(const GsmCBMsgSerialNum &snFields)
223 {
224     unsigned short serialNum = ((snFields.geoScope & HEX_VALUE_03) << HEX_VALUE_0E) |
225                                ((snFields.msgCode & HEX_VALUE_03FF) << HEX_VALUE_04) |
226                                (snFields.updateNum & HEX_VALUE_0F);
227     return serialNum;
228 }
229 
CMASClass(const uint16_t messageId) const230 uint8_t GsmCbCodec::CMASClass(const uint16_t messageId) const
231 {
232     uint8_t ret = 0;
233     switch (messageId) {
234         case PRESIDENTIAL:
235         case PRESIDENTIAL_SPANISH:
236             ret = CMAS_PRESIDENTIAL;
237             break;
238         case EXTREME_OBSERVED:
239         case EXTREME_OBSERVED_SPANISH:
240         case EXTREME_LIKELY:
241         case EXTREME_LIKELY_SPANISH:
242             ret = CMAS_EXTREME;
243             break;
244         case SEVERE_OBSERVED:
245         case SEVERE_OBSERVED_SPANISH:
246         case SEVERE_LIKELY:
247         case SEVERE_LIKELY_SPANISH:
248         case ALERT_OBSERVED_DEFUALT:
249         case ALERT_OBSERVED_SPANISH:
250         case ALERT_LIKELY:
251         case ALERT_LIKELY_SPANISH:
252         case EXPECTED_OBSERVED:
253         case EXPECTED_OBSERVED_SPANISH:
254         case EXPECTED_LIKELY:
255         case EXPECTED_LIKELY_SPANISH:
256             ret = CMAS_SEVERE;
257             break;
258         case AMBER_ALERT:
259         case AMBER_ALERT_SPANISH:
260             ret = CMAS_AMBER;
261             break;
262         case MONTHLY_ALERT:
263         case MONTHLY_ALERT_SPANISH:
264             ret = CMAS_TEST;
265             break;
266         case EXERCISE_ALERT:
267         case EXERCISE_ALERT_SPANISH:
268             ret = CMAS_EXERCISE;
269             break;
270         case OPERATOR_ALERT:
271         case OPERATOR_ALERT_SPANISH:
272             ret = CMAS_OPERATOR_DEFINED;
273             break;
274         default:
275             break;
276     }
277     return ret;
278 }
279 
280 /**
281  *  refer to 3GPP TS 23.038 V4.3.0 6.1.1 section
282  */
DecodeIos639Dcs(const uint8_t dcsData,const unsigned short iosData,GsmCbMsgDcs & dcs) const283 void GsmCbCodec::DecodeIos639Dcs(const uint8_t dcsData, const unsigned short iosData, GsmCbMsgDcs &dcs) const
284 {
285     uint8_t dcsLow = (dcsData & HEX_VALUE_0F);
286     switch (dcsLow) {
287         case 0x00:
288         case HEX_VALUE_01: {
289             dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS;
290             dcs.codingScheme = (dcsData & HEX_VALUE_01) ? DATA_CODING_UCS2 : DATA_CODING_7BIT;
291             dcs.langType = CB_LANG_ISO639;
292             uint8_t hight = (iosData >> SMS_BYTE_BIT);
293             uint8_t low = iosData;
294 
295             // refer to 3GPP TS 23.038 V4.3.0 6.1.1 section Control characters
296             if (hight && low) {
297                 dcs.iso639Lang[0x00] = hight & HEX_VALUE_7F;
298                 dcs.iso639Lang[HEX_VALUE_01] = (hight & HEX_VALUE_80) >> HEX_VALUE_07;
299                 dcs.iso639Lang[HEX_VALUE_01] |= (low & HEX_VALUE_3F) << HEX_VALUE_01;
300                 dcs.iso639Lang[HEX_VALUE_02] = HEX_VALUE_13; /* CR */
301             } else {
302                 dcs.iso639Lang[0x00] = HEX_VALUE_45; /* E */
303                 dcs.iso639Lang[HEX_VALUE_01] = HEX_VALUE_4E; /* N */
304                 dcs.iso639Lang[HEX_VALUE_02] = HEX_VALUE_13; /* CR */
305             }
306             break;
307         }
308         default:
309             break;
310     }
311 }
312 
313 /**
314  *  refer to 3GPP TS 23.038 V4.3.0 6 section
315  */
DecodeGeneralDcs(const uint8_t dcsData,GsmCbMsgDcs & dcs) const316 void GsmCbCodec::DecodeGeneralDcs(const uint8_t dcsData, GsmCbMsgDcs &dcs) const
317 {
318     dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS;
319     dcs.bCompressed = (dcsData & HEX_VALUE_20) ? true : false;
320     if (dcsData & HEX_VALUE_10) {
321         dcs.classType = (dcsData & HEX_VALUE_03);
322     }
323     uint8_t tmpScheme = (dcsData & HEX_VALUE_0C) >> HEX_VALUE_02;
324     switch (tmpScheme) {
325         case 0x00:
326             dcs.codingScheme = DATA_CODING_7BIT;
327             break;
328         case HEX_VALUE_01:
329             dcs.codingScheme = DATA_CODING_8BIT;
330             break;
331         case HEX_VALUE_02:
332             dcs.codingScheme = DATA_CODING_UCS2;
333             break;
334         default:
335             break;
336     }
337 }
338 
339 /**
340  *  refer to 3GPP TS 23.038 V4.3.0 6 section
341  */
DecodeCbMsgDCS(const uint8_t dcsData,const unsigned short iosData,GsmCbMsgDcs & dcs) const342 void GsmCbCodec::DecodeCbMsgDCS(const uint8_t dcsData, const unsigned short iosData, GsmCbMsgDcs &dcs) const
343 {
344     dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS;
345     dcs.classType = SMS_CLASS_UNKNOWN;
346     dcs.bCompressed = false;
347     dcs.codingScheme = DATA_CODING_7BIT;
348     dcs.langType = CB_MSG_UNSPECIFIED;
349     if (memset_s(dcs.iso639Lang, sizeof(dcs.iso639Lang), 0x00, sizeof(dcs.iso639Lang)) != EOK) {
350         TELEPHONY_LOGE("memset_s error!");
351         return;
352     }
353     dcs.bUDH = false;
354     dcs.rawData = dcsData;
355     uint8_t codingGroup = (dcsData & HEX_VALUE_F0) >> HEX_VALUE_04;
356     switch (codingGroup) {
357         case 0x00:
358         case HEX_VALUE_02:
359         case HEX_VALUE_03:
360             dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS;
361             dcs.langType = dcsData;
362             break;
363         case HEX_VALUE_01:
364             DecodeIos639Dcs(dcsData, iosData, dcs);
365             break;
366         case HEX_VALUE_04:
367         case HEX_VALUE_05:
368         case HEX_VALUE_06:
369         case HEX_VALUE_07:
370             DecodeGeneralDcs(dcsData, dcs);
371             break;
372         case HEX_VALUE_09:
373             dcs.bUDH = true;
374             dcs.classType = dcsData & HEX_VALUE_03;
375             dcs.codingScheme = (dcsData & HEX_VALUE_0C) >> HEX_VALUE_02;
376             break;
377         case HEX_VALUE_0E:
378             dcs.codingGroup = SMS_CBMSG_CODGRP_WAP;
379             break;
380         case HEX_VALUE_0F:
381             dcs.codingGroup = SMS_CBMSG_CODGRP_CLASS_CODING;
382             dcs.codingScheme = (dcsData & HEX_VALUE_04) ? DATA_CODING_8BIT : DATA_CODING_7BIT;
383             dcs.classType = dcsData & HEX_VALUE_03;
384             break;
385         default:
386             TELEPHONY_LOGI("codingGrp: [0x%{public}x]", codingGroup);
387             break;
388     }
389 }
390 
GetRecvTime() const391 int64_t GsmCbCodec::GetRecvTime() const
392 {
393     time_t recvTime = time(NULL);
394     return static_cast<int64_t>(recvTime);
395 }
396 
ToString() const397 std::string GsmCbCodec::ToString() const
398 {
399     if (cbHeader_ == nullptr) {
400         TELEPHONY_LOGE("cbHeader_ is nullptr");
401         return "GsmCbCodec Header nullptr";
402     }
403     std::string cbMsgId("msgId:" + std::to_string(cbHeader_->msgId));
404     std::string cbLangType("\nlangType:" + std::to_string(cbHeader_->langType));
405     std::string cbIsEtwsMessage("\nisEtws:" + std::to_string(cbHeader_->bEtwsMessage));
406     std::string cbMsgType("\ncbMsgType:" + std::to_string(cbHeader_->cbMsgType));
407     std::string cbWarningType("\nwarningType:" + std::to_string(cbHeader_->warningType));
408     std::string cbSerialNum("\nserialNum: geoScope " + std::to_string(cbHeader_->serialNum.geoScope) + "| updateNum " +
409                             std::to_string(cbHeader_->serialNum.updateNum) + "| msgCode " +
410                             std::to_string(cbHeader_->serialNum.msgCode));
411     std::string cbPage(
412         "\ntotal pages: " + std::to_string(cbHeader_->totalPages) + " page:" + std::to_string(cbHeader_->page));
413     std::string cbRecvTime("\nrecv time: " + std::to_string(cbHeader_->recvTime));
414     std::string cbDcsRaw("\ndcs: " + std::to_string(cbHeader_->dcs.rawData));
415     std::string cbMsgBody;
416     ConvertToUTF8(messageRaw_, cbMsgBody);
417     return cbMsgId.append(cbLangType)
418         .append(cbIsEtwsMessage)
419         .append(cbMsgType)
420         .append(cbWarningType)
421         .append(cbSerialNum)
422         .append(cbPage)
423         .append(cbRecvTime)
424         .append(cbDcsRaw)
425         .append("\nbody:")
426         .append(cbMsgBody);
427 }
428 
GetFormat(int8_t & cbFormat) const429 bool GsmCbCodec::GetFormat(int8_t &cbFormat) const
430 {
431     cbFormat = CB_FORMAT_3GPP;
432     return true;
433 }
434 
GetPriority(int8_t & cbPriority) const435 bool GsmCbCodec::GetPriority(int8_t &cbPriority) const
436 {
437     if (cbHeader_ == nullptr) {
438         TELEPHONY_LOGE("cbHeader_ is nullptr");
439         return false;
440     }
441     const int8_t normal = 0x00;
442     const int8_t emergency = HEX_VALUE_03;
443     if (cbHeader_->msgId >= PWS_FIRST_ID && cbHeader_->msgId <= PWS_LAST_ID) {
444         cbPriority = emergency;
445     } else {
446         cbPriority = normal;
447     }
448     return true;
449 }
450 
GetGeoScope(uint8_t & geoScope) const451 bool GsmCbCodec::GetGeoScope(uint8_t &geoScope) const
452 {
453     if (cbHeader_ == nullptr) {
454         TELEPHONY_LOGE("cbHeader_ is nullptr");
455         return false;
456     }
457     geoScope = cbHeader_->serialNum.geoScope;
458     return true;
459 }
460 
GetSerialNum(uint16_t & cbSerial) const461 bool GsmCbCodec::GetSerialNum(uint16_t &cbSerial) const
462 {
463     if (cbHeader_ == nullptr) {
464         TELEPHONY_LOGE("cbHeader_ is nullptr");
465         return false;
466     }
467     cbSerial = ((cbHeader_->serialNum.geoScope & HEX_VALUE_03) << HEX_VALUE_0E) |
468                ((cbHeader_->serialNum.msgCode & HEX_VALUE_03FF) << HEX_VALUE_04) |
469                (cbHeader_->serialNum.updateNum & HEX_VALUE_0F);
470     return true;
471 }
472 
GetServiceCategory(uint16_t & cbCategoty) const473 bool GsmCbCodec::GetServiceCategory(uint16_t &cbCategoty) const
474 {
475     if (cbHeader_ == nullptr) {
476         TELEPHONY_LOGE("cbHeader_ is nullptr");
477         return false;
478     }
479     cbCategoty = cbHeader_->msgId;
480     return true;
481 }
482 
GetWarningType(uint16_t & type) const483 bool GsmCbCodec::GetWarningType(uint16_t &type) const
484 {
485     if (cbHeader_ == nullptr) {
486         TELEPHONY_LOGE("cbHeader_ is nullptr");
487         return false;
488     }
489     if (TELEPHONY_EXT_WRAPPER.getCustEtwsType_  != nullptr) {
490         TELEPHONY_LOGI("GetWarningType getCustEtwsType_  not null");
491         TELEPHONY_EXT_WRAPPER.getCustEtwsType_(cbHeader_->msgId, type);
492         if (type != OTHER_TYPE) {
493             TELEPHONY_LOGI("getCustEtwsType_ type not OTHER_TYPE.");
494             return true;
495         }
496     }
497     type = cbHeader_->msgId - ETWS_TYPE;
498     return true;
499 }
500 
IsEtwsPrimary(bool & primary) const501 bool GsmCbCodec::IsEtwsPrimary(bool &primary) const
502 {
503     if (cbHeader_ == nullptr) {
504         TELEPHONY_LOGE("cbHeader_ is nullptr");
505         return false;
506     }
507     primary = (cbHeader_->cbEtwsType == ETWS_PRIMARY);
508     return true;
509 }
510 
IsEtwsMessage(bool & etws) const511 bool GsmCbCodec::IsEtwsMessage(bool &etws) const
512 {
513     if (cbHeader_ == nullptr) {
514         TELEPHONY_LOGE("cbHeader_ is nullptr");
515         return false;
516     }
517     etws = ((cbHeader_->msgId & ETWS_TYPE_MASK) == ETWS_TYPE);
518     if (!etws && TELEPHONY_EXT_WRAPPER.isCustEtwsMessage_  != nullptr) {
519         TELEPHONY_LOGI("IsEtwsMessage isCustEtwsMessage_  not null");
520         if (TELEPHONY_EXT_WRAPPER.isCustEtwsMessage_(cbHeader_->msgId)) {
521             TELEPHONY_LOGI("isCustEtwsMessage_ is true.");
522             etws = true;
523         }
524     }
525     return true;
526 }
527 
IsCmasMessage(bool & cmas) const528 bool GsmCbCodec::IsCmasMessage(bool &cmas) const
529 {
530     if (cbHeader_ == nullptr) {
531         TELEPHONY_LOGE("cbHeader_ is nullptr");
532         return false;
533     }
534     cmas = ((cbHeader_->msgId >= CMAS_FIRST_ID) && (cbHeader_->msgId <= CMAS_LAST_ID));
535     return true;
536 }
537 
IsEtwsEmergencyUserAlert(bool & alert) const538 bool GsmCbCodec::IsEtwsEmergencyUserAlert(bool &alert) const
539 {
540     uint16_t serial = 0;
541     if (!GetSerialNum(serial)) {
542         TELEPHONY_LOGE("Get serial num fail.");
543         return false;
544     }
545     alert = ((serial & EMERGENCY_USER_ALERT) != 0);
546     return true;
547 }
548 
IsEtwsPopupAlert(bool & alert) const549 bool GsmCbCodec::IsEtwsPopupAlert(bool &alert) const
550 {
551     uint16_t serial = 0;
552     if (!GetSerialNum(serial)) {
553         TELEPHONY_LOGE("Get serial num fail.");
554         return false;
555     }
556     alert = ((serial & ETWS_POPUP) != 0);
557     return true;
558 }
559 
GetCmasSeverity(uint8_t & severity) const560 bool GsmCbCodec::GetCmasSeverity(uint8_t &severity) const
561 {
562     uint16_t msgId = 0;
563     if (!GetMessageId(msgId)) {
564         TELEPHONY_LOGE("Get message id fail.");
565         return false;
566     }
567     switch (static_cast<CmasMsgType>(msgId)) {
568         case CmasMsgType::EXTREME_OBSERVED:
569         case CmasMsgType::EXTREME_OBSERVED_SPANISH:
570         case CmasMsgType::EXTREME_LIKELY:
571         case CmasMsgType::EXTREME_LIKELY_SPANISH:
572         case CmasMsgType::SEVERE_OBSERVED:
573         case CmasMsgType::SEVERE_OBSERVED_SPANISH:
574         case CmasMsgType::SEVERE_LIKELY:
575         case CmasMsgType::SEVERE_LIKELY_SPANISH:
576             severity = static_cast<uint8_t>(SmsCmaeSeverity::EXTREME);
577             break;
578         case CmasMsgType::ALERT_OBSERVED_DEFUALT:
579         case CmasMsgType::ALERT_OBSERVED_SPANISH:
580         case CmasMsgType::ALERT_LIKELY:
581         case CmasMsgType::ALERT_LIKELY_SPANISH:
582         case CmasMsgType::EXPECTED_OBSERVED:
583         case CmasMsgType::EXPECTED_OBSERVED_SPANISH:
584         case CmasMsgType::EXPECTED_LIKELY:
585         case CmasMsgType::EXPECTED_LIKELY_SPANISH:
586             severity = static_cast<uint8_t>(SmsCmaeSeverity::SEVERE);
587             break;
588         default:
589             severity = static_cast<uint8_t>(SmsCmaeSeverity::RESERVED);
590             break;
591     }
592     return true;
593 }
594 
GetCmasUrgency(uint8_t & urgency) const595 bool GsmCbCodec::GetCmasUrgency(uint8_t &urgency) const
596 {
597     uint16_t msgId = 0;
598     if (!GetMessageId(msgId)) {
599         TELEPHONY_LOGE("Get message id fail.");
600         return false;
601     }
602     switch (static_cast<CmasMsgType>(msgId)) {
603         case CmasMsgType::EXTREME_OBSERVED:
604         case CmasMsgType::EXTREME_OBSERVED_SPANISH:
605         case CmasMsgType::EXTREME_LIKELY:
606         case CmasMsgType::EXTREME_LIKELY_SPANISH:
607         case CmasMsgType::ALERT_OBSERVED_DEFUALT:
608         case CmasMsgType::ALERT_OBSERVED_SPANISH:
609         case CmasMsgType::ALERT_LIKELY:
610         case CmasMsgType::ALERT_LIKELY_SPANISH:
611             urgency = static_cast<uint8_t>(SmsCmaeUrgency::IMMEDIATE);
612             break;
613         case CmasMsgType::SEVERE_OBSERVED:
614         case CmasMsgType::SEVERE_OBSERVED_SPANISH:
615         case CmasMsgType::SEVERE_LIKELY:
616         case CmasMsgType::SEVERE_LIKELY_SPANISH:
617         case CmasMsgType::EXPECTED_OBSERVED:
618         case CmasMsgType::EXPECTED_OBSERVED_SPANISH:
619         case CmasMsgType::EXPECTED_LIKELY:
620         case CmasMsgType::EXPECTED_LIKELY_SPANISH:
621             urgency = static_cast<uint8_t>(SmsCmaeUrgency::EXPECTED);
622             break;
623         default:
624             urgency = static_cast<uint8_t>(SmsCmaeUrgency::RESERVED);
625             break;
626     }
627     return true;
628 }
629 
GetCmasCertainty(uint8_t & certainty) const630 bool GsmCbCodec::GetCmasCertainty(uint8_t &certainty) const
631 {
632     uint16_t msgId = 0;
633     if (!GetMessageId(msgId)) {
634         TELEPHONY_LOGE("Get message id fail.");
635         return false;
636     }
637     switch (static_cast<CmasMsgType>(msgId)) {
638         case CmasMsgType::EXTREME_OBSERVED:
639         case CmasMsgType::EXTREME_OBSERVED_SPANISH:
640         case CmasMsgType::SEVERE_OBSERVED:
641         case CmasMsgType::SEVERE_OBSERVED_SPANISH:
642         case CmasMsgType::ALERT_OBSERVED_DEFUALT:
643         case CmasMsgType::ALERT_OBSERVED_SPANISH:
644         case CmasMsgType::EXPECTED_OBSERVED:
645         case CmasMsgType::EXPECTED_OBSERVED_SPANISH:
646             certainty = static_cast<uint8_t>(SmsCmaeCertainty::OBSERVED);
647             break;
648         case CmasMsgType::EXTREME_LIKELY:
649         case CmasMsgType::EXTREME_LIKELY_SPANISH:
650         case CmasMsgType::SEVERE_LIKELY:
651         case CmasMsgType::SEVERE_LIKELY_SPANISH:
652         case CmasMsgType::ALERT_LIKELY:
653         case CmasMsgType::ALERT_LIKELY_SPANISH:
654         case CmasMsgType::EXPECTED_LIKELY:
655         case CmasMsgType::EXPECTED_LIKELY_SPANISH:
656             certainty = static_cast<uint8_t>(SmsCmaeCertainty::LIKELY);
657             break;
658         default:
659             certainty = static_cast<uint8_t>(SmsCmaeCertainty::RESERVED);
660             break;
661     }
662     return true;
663 }
664 
GetCmasCategory(uint8_t & cmasCategory) const665 bool GsmCbCodec::GetCmasCategory(uint8_t &cmasCategory) const
666 {
667     cmasCategory = static_cast<uint8_t>(SmsCmaeCategory::RESERVED);
668     return true;
669 }
670 
GetCmasResponseType(uint8_t & cmasRes) const671 bool GsmCbCodec::GetCmasResponseType(uint8_t &cmasRes) const
672 {
673     cmasRes = static_cast<uint8_t>(SmsCmaeResponseType::RESERVED);
674     return true;
675 }
676 
GetMessageId(uint16_t & msgId) const677 bool GsmCbCodec::GetMessageId(uint16_t &msgId) const
678 {
679     if (cbHeader_ == nullptr) {
680         TELEPHONY_LOGE("cbHeader_ is nullptr");
681         return false;
682     }
683     msgId = cbHeader_->msgId;
684     return true;
685 }
686 
GetCmasMessageClass(uint8_t & cmasClass) const687 bool GsmCbCodec::GetCmasMessageClass(uint8_t &cmasClass) const
688 {
689     uint16_t cbMsgId = 0;
690     if (!GetMessageId(cbMsgId)) {
691         TELEPHONY_LOGE("get cb id fail.");
692         return false;
693     }
694     cmasClass = CMASClass(cbMsgId);
695     return true;
696 }
697 
GetMsgType(uint8_t & msgType) const698 bool GsmCbCodec::GetMsgType(uint8_t &msgType) const
699 {
700     if (cbHeader_ == nullptr) {
701         TELEPHONY_LOGE("cbHeader_ is nullptr");
702         return false;
703     }
704     msgType = cbHeader_->cbMsgType;
705     return true;
706 }
707 
GetLangType(uint8_t & lan) const708 bool GsmCbCodec::GetLangType(uint8_t &lan) const
709 {
710     if (cbHeader_ == nullptr) {
711         TELEPHONY_LOGE("cbHeader_ is nullptr");
712         return false;
713     }
714     lan = cbHeader_->langType;
715     return true;
716 }
717 
GetDcs(uint8_t & dcs) const718 bool GsmCbCodec::GetDcs(uint8_t &dcs) const
719 {
720     if (cbHeader_ == nullptr) {
721         TELEPHONY_LOGE("cbHeader_ is nullptr");
722         return false;
723     }
724     dcs = cbHeader_->dcs.codingScheme;
725     return true;
726 }
727 
GetReceiveTime(int64_t & receiveTime) const728 bool GsmCbCodec::GetReceiveTime(int64_t &receiveTime) const
729 {
730     if (cbHeader_ == nullptr) {
731         TELEPHONY_LOGE("nullptr error.");
732         return false;
733     }
734     receiveTime = cbHeader_->recvTime;
735     if (receiveTime == 0) {
736         TELEPHONY_LOGI("receiveTime = 0");
737         time_t recvTime = time(NULL);
738         receiveTime = static_cast<int64_t>(recvTime);
739     }
740     return true;
741 }
742 } // namespace Telephony
743 } // namespace OHOS