• 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_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         PduAfterDiscardNullBlock(pdu);
142         return gsmCodec->DecodeEtwsMsg();
143     }
144 
145     if (cbHeader_->cbNetType == GSM_NET_CB) {
146         PduAfterDiscardNullBlock(pdu);
147         decodeResult = gsmCodec->Decode2gCbMsg();
148     } else if (cbHeader_->cbNetType == UMTS_NET_CB) {
149         decodeResult = umtsCodec->Decode3gCbMsg();
150     }
151     TELEPHONY_LOGI("CB decode result:%{public}d.", decodeResult);
152     return decodeResult;
153 }
154 
PduAfterDiscardNullBlock(const std::vector<unsigned char> & pdu)155 void GsmCbCodec::PduAfterDiscardNullBlock(const std::vector<unsigned char> &pdu)
156 {
157     if (cbPduBuffer_ == nullptr) {
158         TELEPHONY_LOGE("cbPduBuffer_ nullptr error");
159         return;
160     }
161     if (TELEPHONY_EXT_WRAPPER.getCbsPduLength_ != nullptr) {
162         uint32_t len = TELEPHONY_EXT_WRAPPER.getCbsPduLength_(pdu);
163         cbPduBuffer_ -> SetSize(len);
164     }
165 }
166 
ParamsCheck(const std::vector<unsigned char> & pdu)167 bool GsmCbCodec::ParamsCheck(const std::vector<unsigned char> &pdu)
168 {
169     if (pdu.size() == 0 && pdu.size() > MAX_CB_MSG_LEN) {
170         TELEPHONY_LOGE("pdu data error.");
171         return false;
172     }
173     cbPduBuffer_ = std::make_shared<GsmCbPduDecodeBuffer>(pdu.size());
174     cbHeader_ = std::make_shared<GsmCbCodec::GsmCbMessageHeader>();
175     if (cbPduBuffer_ == nullptr || cbHeader_ == nullptr || cbPduBuffer_->pduBuffer_ == nullptr) {
176         TELEPHONY_LOGE("nullptr error.");
177         return false;
178     }
179     for (size_t index = 0; index < pdu.size() && index < cbPduBuffer_->GetSize(); index++) {
180         cbPduBuffer_->pduBuffer_[index] = static_cast<char>(pdu[index]);
181     }
182     return true;
183 }
184 
GetPduData(std::vector<unsigned char> & dataPdu)185 void GsmCbCodec::GetPduData(std::vector<unsigned char> &dataPdu)
186 {
187     if (cbPduBuffer_ == nullptr) {
188         TELEPHONY_LOGE("nullptr error.");
189         return;
190     }
191 
192     uint32_t current = cbPduBuffer_->GetCurPosition();
193     uint8_t oneByte = 0;
194     while (cbPduBuffer_->GetCurPosition() < cbPduBuffer_->GetSize()) {
195         if (!cbPduBuffer_->GetOneByte(oneByte)) {
196             TELEPHONY_LOGE("get data error.");
197         }
198         dataPdu.push_back(oneByte);
199     }
200     cbPduBuffer_->SetPointer(current);
201 }
202 
ConvertToUTF8(const std::string & raw,std::string & message) const203 void GsmCbCodec::ConvertToUTF8(const std::string &raw, std::string &message) const
204 {
205     if (cbHeader_ == nullptr) {
206         TELEPHONY_LOGE("ConvertToUTF8 cbHeader null err.");
207         return;
208     }
209     if (cbHeader_->bEtwsMessage && cbHeader_->cbEtwsType == ETWS_PRIMARY) {
210         message.assign(raw);
211     } else {
212         uint16_t codeSize = 0;
213         MsgLangInfo langInfo;
214         uint8_t outBuf[MAX_CB_MSG_LEN + 1] = { 0 };
215         const uint8_t *src = reinterpret_cast<const uint8_t *>(raw.data());
216         if (cbHeader_->dcs.codingScheme == DATA_CODING_7BIT) {
217             codeSize = TextCoder::Instance().Gsm7bitToUtf8(outBuf, sizeof(outBuf), src, raw.length(), langInfo);
218         } else if (cbHeader_->dcs.codingScheme == DATA_CODING_UCS2) {
219             codeSize = TextCoder::Instance().Ucs2ToUtf8(outBuf, sizeof(outBuf), src, raw.length());
220         } else {
221             TELEPHONY_LOGI("CB message data encoding 8bit");
222             message.assign(raw);
223             return;
224         }
225         if (codeSize >= MAX_CB_MSG_LEN) {
226             TELEPHONY_LOGE("codeSize over size.");
227             return;
228         }
229         outBuf[codeSize] = '\0';
230         for (uint16_t index = 0; index < codeSize; index++) {
231             message.push_back(static_cast<char>(outBuf[index]));
232         }
233     }
234 }
235 
EncodeCbSerialNum(const GsmCBMsgSerialNum & snFields)236 unsigned short GsmCbCodec::EncodeCbSerialNum(const GsmCBMsgSerialNum &snFields)
237 {
238     unsigned short serialNum = ((snFields.geoScope & HEX_VALUE_03) << HEX_VALUE_0E) |
239                                ((snFields.msgCode & HEX_VALUE_03FF) << HEX_VALUE_04) |
240                                (snFields.updateNum & HEX_VALUE_0F);
241     return serialNum;
242 }
243 
CMASClass(const uint16_t messageId) const244 uint8_t GsmCbCodec::CMASClass(const uint16_t messageId) const
245 {
246     uint8_t ret = 0;
247     switch (messageId) {
248         case PRESIDENTIAL:
249         case PRESIDENTIAL_SPANISH:
250             ret = CMAS_PRESIDENTIAL;
251             break;
252         case EXTREME_OBSERVED:
253         case EXTREME_OBSERVED_SPANISH:
254         case EXTREME_LIKELY:
255         case EXTREME_LIKELY_SPANISH:
256             ret = CMAS_EXTREME;
257             break;
258         case SEVERE_OBSERVED:
259         case SEVERE_OBSERVED_SPANISH:
260         case SEVERE_LIKELY:
261         case SEVERE_LIKELY_SPANISH:
262         case ALERT_OBSERVED_DEFUALT:
263         case ALERT_OBSERVED_SPANISH:
264         case ALERT_LIKELY:
265         case ALERT_LIKELY_SPANISH:
266         case EXPECTED_OBSERVED:
267         case EXPECTED_OBSERVED_SPANISH:
268         case EXPECTED_LIKELY:
269         case EXPECTED_LIKELY_SPANISH:
270             ret = CMAS_SEVERE;
271             break;
272         case AMBER_ALERT:
273         case AMBER_ALERT_SPANISH:
274             ret = CMAS_AMBER;
275             break;
276         case MONTHLY_ALERT:
277         case MONTHLY_ALERT_SPANISH:
278             ret = CMAS_TEST;
279             break;
280         case EXERCISE_ALERT:
281         case EXERCISE_ALERT_SPANISH:
282             ret = CMAS_EXERCISE;
283             break;
284         case OPERATOR_ALERT:
285         case OPERATOR_ALERT_SPANISH:
286             ret = CMAS_OPERATOR_DEFINED;
287             break;
288         default:
289             break;
290     }
291     return ret;
292 }
293 
294 /**
295  *  refer to 3GPP TS 23.038 V4.3.0 6.1.1 section
296  */
DecodeIos639Dcs(const uint8_t dcsData,const unsigned short iosData,GsmCbMsgDcs & dcs) const297 void GsmCbCodec::DecodeIos639Dcs(const uint8_t dcsData, const unsigned short iosData, GsmCbMsgDcs &dcs) const
298 {
299     uint8_t dcsLow = (dcsData & HEX_VALUE_0F);
300     switch (dcsLow) {
301         case 0x00:
302         case HEX_VALUE_01: {
303             dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS;
304             dcs.codingScheme = (dcsData & HEX_VALUE_01) ? DATA_CODING_UCS2 : DATA_CODING_7BIT;
305             dcs.langType = CB_LANG_ISO639;
306             uint8_t hight = (iosData >> SMS_BYTE_BIT);
307             uint8_t low = iosData;
308 
309             // refer to 3GPP TS 23.038 V4.3.0 6.1.1 section Control characters
310             if (hight && low) {
311                 dcs.iso639Lang[0x00] = hight & HEX_VALUE_7F;
312                 dcs.iso639Lang[HEX_VALUE_01] = (hight & HEX_VALUE_80) >> HEX_VALUE_07;
313                 dcs.iso639Lang[HEX_VALUE_01] |= (low & HEX_VALUE_3F) << HEX_VALUE_01;
314                 dcs.iso639Lang[HEX_VALUE_02] = HEX_VALUE_13; /* CR */
315             } else {
316                 dcs.iso639Lang[0x00] = HEX_VALUE_45; /* E */
317                 dcs.iso639Lang[HEX_VALUE_01] = HEX_VALUE_4E; /* N */
318                 dcs.iso639Lang[HEX_VALUE_02] = HEX_VALUE_13; /* CR */
319             }
320             break;
321         }
322         default:
323             break;
324     }
325 }
326 
327 /**
328  *  refer to 3GPP TS 23.038 V4.3.0 6 section
329  */
DecodeGeneralDcs(const uint8_t dcsData,GsmCbMsgDcs & dcs) const330 void GsmCbCodec::DecodeGeneralDcs(const uint8_t dcsData, GsmCbMsgDcs &dcs) const
331 {
332     dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS;
333     dcs.bCompressed = (dcsData & HEX_VALUE_20) ? true : false;
334     if (dcsData & HEX_VALUE_10) {
335         dcs.classType = (dcsData & HEX_VALUE_03);
336     }
337     uint8_t tmpScheme = (dcsData & HEX_VALUE_0C) >> HEX_VALUE_02;
338     switch (tmpScheme) {
339         case 0x00:
340             dcs.codingScheme = DATA_CODING_7BIT;
341             break;
342         case HEX_VALUE_01:
343             dcs.codingScheme = DATA_CODING_8BIT;
344             break;
345         case HEX_VALUE_02:
346             dcs.codingScheme = DATA_CODING_UCS2;
347             break;
348         default:
349             break;
350     }
351 }
352 
353 /**
354  *  refer to 3GPP TS 23.038 V4.3.0 6 section
355  */
DecodeCbMsgDCS(const uint8_t dcsData,const unsigned short iosData,GsmCbMsgDcs & dcs) const356 void GsmCbCodec::DecodeCbMsgDCS(const uint8_t dcsData, const unsigned short iosData, GsmCbMsgDcs &dcs) const
357 {
358     dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS;
359     dcs.classType = SMS_CLASS_UNKNOWN;
360     dcs.bCompressed = false;
361     dcs.codingScheme = DATA_CODING_7BIT;
362     dcs.langType = CB_MSG_UNSPECIFIED;
363     if (memset_s(dcs.iso639Lang, sizeof(dcs.iso639Lang), 0x00, sizeof(dcs.iso639Lang)) != EOK) {
364         TELEPHONY_LOGE("memset_s error!");
365         return;
366     }
367     dcs.bUDH = false;
368     dcs.rawData = dcsData;
369     uint8_t codingGroup = (dcsData & HEX_VALUE_F0) >> HEX_VALUE_04;
370     switch (codingGroup) {
371         case 0x00:
372         case HEX_VALUE_02:
373         case HEX_VALUE_03:
374             dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS;
375             dcs.langType = dcsData;
376             break;
377         case HEX_VALUE_01:
378             DecodeIos639Dcs(dcsData, iosData, dcs);
379             break;
380         case HEX_VALUE_04:
381         case HEX_VALUE_05:
382         case HEX_VALUE_06:
383         case HEX_VALUE_07:
384             DecodeGeneralDcs(dcsData, dcs);
385             break;
386         case HEX_VALUE_09:
387             dcs.bUDH = true;
388             dcs.classType = dcsData & HEX_VALUE_03;
389             dcs.codingScheme = (dcsData & HEX_VALUE_0C) >> HEX_VALUE_02;
390             break;
391         case HEX_VALUE_0E:
392             dcs.codingGroup = SMS_CBMSG_CODGRP_WAP;
393             break;
394         case HEX_VALUE_0F:
395             dcs.codingGroup = SMS_CBMSG_CODGRP_CLASS_CODING;
396             dcs.codingScheme = (dcsData & HEX_VALUE_04) ? DATA_CODING_8BIT : DATA_CODING_7BIT;
397             dcs.classType = dcsData & HEX_VALUE_03;
398             break;
399         default:
400             TELEPHONY_LOGI("codingGrp: [0x%{public}x]", codingGroup);
401             break;
402     }
403 }
404 
GetRecvTime() const405 int64_t GsmCbCodec::GetRecvTime() const
406 {
407     time_t recvTime = time(NULL);
408     return static_cast<int64_t>(recvTime);
409 }
410 
ToString() const411 std::string GsmCbCodec::ToString() const
412 {
413     if (cbHeader_ == nullptr) {
414         TELEPHONY_LOGE("cbHeader_ is nullptr");
415         return "GsmCbCodec Header nullptr";
416     }
417     std::string cbMsgId("msgId:" + std::to_string(cbHeader_->msgId));
418     std::string cbLangType("\nlangType:" + std::to_string(cbHeader_->langType));
419     std::string cbIsEtwsMessage("\nisEtws:" + std::to_string(cbHeader_->bEtwsMessage));
420     std::string cbMsgType("\ncbMsgType:" + std::to_string(cbHeader_->cbMsgType));
421     std::string cbWarningType("\nwarningType:" + std::to_string(cbHeader_->warningType));
422     std::string cbSerialNum("\nserialNum: geoScope " + std::to_string(cbHeader_->serialNum.geoScope) + "| updateNum " +
423                             std::to_string(cbHeader_->serialNum.updateNum) + "| msgCode " +
424                             std::to_string(cbHeader_->serialNum.msgCode));
425     std::string cbPage(
426         "\ntotal pages: " + std::to_string(cbHeader_->totalPages) + " page:" + std::to_string(cbHeader_->page));
427     std::string cbRecvTime("\nrecv time: " + std::to_string(cbHeader_->recvTime));
428     std::string cbDcsRaw("\ndcs: " + std::to_string(cbHeader_->dcs.rawData));
429     std::string cbMsgBody;
430     ConvertToUTF8(messageRaw_, cbMsgBody);
431     return cbMsgId.append(cbLangType)
432         .append(cbIsEtwsMessage)
433         .append(cbMsgType)
434         .append(cbWarningType)
435         .append(cbSerialNum)
436         .append(cbPage)
437         .append(cbRecvTime)
438         .append(cbDcsRaw)
439         .append("\nbody:")
440         .append(cbMsgBody);
441 }
442 
GetFormat(int8_t & cbFormat) const443 bool GsmCbCodec::GetFormat(int8_t &cbFormat) const
444 {
445     cbFormat = CB_FORMAT_3GPP;
446     return true;
447 }
448 
GetPriority(int8_t & cbPriority) const449 bool GsmCbCodec::GetPriority(int8_t &cbPriority) const
450 {
451     if (cbHeader_ == nullptr) {
452         TELEPHONY_LOGE("cbHeader_ is nullptr");
453         return false;
454     }
455     const int8_t normal = 0x00;
456     const int8_t emergency = HEX_VALUE_03;
457     if (cbHeader_->msgId >= PWS_FIRST_ID && cbHeader_->msgId <= PWS_LAST_ID) {
458         cbPriority = emergency;
459     } else {
460         cbPriority = normal;
461     }
462     return true;
463 }
464 
GetGeoScope(uint8_t & geoScope) const465 bool GsmCbCodec::GetGeoScope(uint8_t &geoScope) const
466 {
467     if (cbHeader_ == nullptr) {
468         TELEPHONY_LOGE("cbHeader_ is nullptr");
469         return false;
470     }
471     geoScope = cbHeader_->serialNum.geoScope;
472     return true;
473 }
474 
GetSerialNum(uint16_t & cbSerial) const475 bool GsmCbCodec::GetSerialNum(uint16_t &cbSerial) const
476 {
477     if (cbHeader_ == nullptr) {
478         TELEPHONY_LOGE("cbHeader_ is nullptr");
479         return false;
480     }
481     cbSerial = ((cbHeader_->serialNum.geoScope & HEX_VALUE_03) << HEX_VALUE_0E) |
482                ((cbHeader_->serialNum.msgCode & HEX_VALUE_03FF) << HEX_VALUE_04) |
483                (cbHeader_->serialNum.updateNum & HEX_VALUE_0F);
484     return true;
485 }
486 
GetServiceCategory(uint16_t & cbCategoty) const487 bool GsmCbCodec::GetServiceCategory(uint16_t &cbCategoty) const
488 {
489     if (cbHeader_ == nullptr) {
490         TELEPHONY_LOGE("cbHeader_ is nullptr");
491         return false;
492     }
493     cbCategoty = cbHeader_->msgId;
494     return true;
495 }
496 
GetWarningType(uint16_t & type) const497 bool GsmCbCodec::GetWarningType(uint16_t &type) const
498 {
499     if (cbHeader_ == nullptr) {
500         TELEPHONY_LOGE("cbHeader_ is nullptr");
501         return false;
502     }
503     if (TELEPHONY_EXT_WRAPPER.getCustEtwsType_  != nullptr) {
504         TELEPHONY_LOGI("GetWarningType getCustEtwsType_  not null");
505         TELEPHONY_EXT_WRAPPER.getCustEtwsType_(cbHeader_->msgId, type);
506         if (type != OTHER_TYPE) {
507             TELEPHONY_LOGI("getCustEtwsType_ type not OTHER_TYPE.");
508             return true;
509         }
510     }
511     type = cbHeader_->msgId - ETWS_TYPE;
512     return true;
513 }
514 
IsEtwsPrimary(bool & primary) const515 bool GsmCbCodec::IsEtwsPrimary(bool &primary) const
516 {
517     if (cbHeader_ == nullptr) {
518         TELEPHONY_LOGE("cbHeader_ is nullptr");
519         return false;
520     }
521     primary = (cbHeader_->cbEtwsType == ETWS_PRIMARY);
522     return true;
523 }
524 
IsEtwsMessage(bool & etws) const525 bool GsmCbCodec::IsEtwsMessage(bool &etws) const
526 {
527     if (cbHeader_ == nullptr) {
528         TELEPHONY_LOGE("cbHeader_ is nullptr");
529         return false;
530     }
531     etws = ((cbHeader_->msgId & ETWS_TYPE_MASK) == ETWS_TYPE);
532     if (!etws && TELEPHONY_EXT_WRAPPER.isCustEtwsMessage_  != nullptr) {
533         TELEPHONY_LOGI("IsEtwsMessage isCustEtwsMessage_  not null");
534         if (TELEPHONY_EXT_WRAPPER.isCustEtwsMessage_(cbHeader_->msgId)) {
535             TELEPHONY_LOGI("isCustEtwsMessage_ is true.");
536             etws = true;
537         }
538     }
539     return true;
540 }
541 
IsCmasMessage(bool & cmas) const542 bool GsmCbCodec::IsCmasMessage(bool &cmas) const
543 {
544     if (cbHeader_ == nullptr) {
545         TELEPHONY_LOGE("cbHeader_ is nullptr");
546         return false;
547     }
548     cmas = ((cbHeader_->msgId >= CMAS_FIRST_ID) && (cbHeader_->msgId <= CMAS_LAST_ID));
549     return true;
550 }
551 
IsEtwsEmergencyUserAlert(bool & alert) const552 bool GsmCbCodec::IsEtwsEmergencyUserAlert(bool &alert) const
553 {
554     uint16_t serial = 0;
555     if (!GetSerialNum(serial)) {
556         TELEPHONY_LOGE("Get serial num fail.");
557         return false;
558     }
559     alert = ((serial & EMERGENCY_USER_ALERT) != 0);
560     return true;
561 }
562 
IsEtwsPopupAlert(bool & alert) const563 bool GsmCbCodec::IsEtwsPopupAlert(bool &alert) const
564 {
565     uint16_t serial = 0;
566     if (!GetSerialNum(serial)) {
567         TELEPHONY_LOGE("Get serial num fail.");
568         return false;
569     }
570     alert = ((serial & ETWS_POPUP) != 0);
571     return true;
572 }
573 
GetCmasSeverity(uint8_t & severity) const574 bool GsmCbCodec::GetCmasSeverity(uint8_t &severity) const
575 {
576     uint16_t msgId = 0;
577     if (!GetMessageId(msgId)) {
578         TELEPHONY_LOGE("Get message id fail.");
579         return false;
580     }
581     switch (static_cast<CmasMsgType>(msgId)) {
582         case CmasMsgType::EXTREME_OBSERVED:
583         case CmasMsgType::EXTREME_OBSERVED_SPANISH:
584         case CmasMsgType::EXTREME_LIKELY:
585         case CmasMsgType::EXTREME_LIKELY_SPANISH:
586         case CmasMsgType::SEVERE_OBSERVED:
587         case CmasMsgType::SEVERE_OBSERVED_SPANISH:
588         case CmasMsgType::SEVERE_LIKELY:
589         case CmasMsgType::SEVERE_LIKELY_SPANISH:
590             severity = static_cast<uint8_t>(SmsCmaeSeverity::EXTREME);
591             break;
592         case CmasMsgType::ALERT_OBSERVED_DEFUALT:
593         case CmasMsgType::ALERT_OBSERVED_SPANISH:
594         case CmasMsgType::ALERT_LIKELY:
595         case CmasMsgType::ALERT_LIKELY_SPANISH:
596         case CmasMsgType::EXPECTED_OBSERVED:
597         case CmasMsgType::EXPECTED_OBSERVED_SPANISH:
598         case CmasMsgType::EXPECTED_LIKELY:
599         case CmasMsgType::EXPECTED_LIKELY_SPANISH:
600             severity = static_cast<uint8_t>(SmsCmaeSeverity::SEVERE);
601             break;
602         default:
603             severity = static_cast<uint8_t>(SmsCmaeSeverity::RESERVED);
604             break;
605     }
606     return true;
607 }
608 
GetCmasUrgency(uint8_t & urgency) const609 bool GsmCbCodec::GetCmasUrgency(uint8_t &urgency) const
610 {
611     uint16_t msgId = 0;
612     if (!GetMessageId(msgId)) {
613         TELEPHONY_LOGE("Get message id fail.");
614         return false;
615     }
616     switch (static_cast<CmasMsgType>(msgId)) {
617         case CmasMsgType::EXTREME_OBSERVED:
618         case CmasMsgType::EXTREME_OBSERVED_SPANISH:
619         case CmasMsgType::EXTREME_LIKELY:
620         case CmasMsgType::EXTREME_LIKELY_SPANISH:
621         case CmasMsgType::ALERT_OBSERVED_DEFUALT:
622         case CmasMsgType::ALERT_OBSERVED_SPANISH:
623         case CmasMsgType::ALERT_LIKELY:
624         case CmasMsgType::ALERT_LIKELY_SPANISH:
625             urgency = static_cast<uint8_t>(SmsCmaeUrgency::IMMEDIATE);
626             break;
627         case CmasMsgType::SEVERE_OBSERVED:
628         case CmasMsgType::SEVERE_OBSERVED_SPANISH:
629         case CmasMsgType::SEVERE_LIKELY:
630         case CmasMsgType::SEVERE_LIKELY_SPANISH:
631         case CmasMsgType::EXPECTED_OBSERVED:
632         case CmasMsgType::EXPECTED_OBSERVED_SPANISH:
633         case CmasMsgType::EXPECTED_LIKELY:
634         case CmasMsgType::EXPECTED_LIKELY_SPANISH:
635             urgency = static_cast<uint8_t>(SmsCmaeUrgency::EXPECTED);
636             break;
637         default:
638             urgency = static_cast<uint8_t>(SmsCmaeUrgency::RESERVED);
639             break;
640     }
641     return true;
642 }
643 
GetCmasCertainty(uint8_t & certainty) const644 bool GsmCbCodec::GetCmasCertainty(uint8_t &certainty) const
645 {
646     uint16_t msgId = 0;
647     if (!GetMessageId(msgId)) {
648         TELEPHONY_LOGE("Get message id fail.");
649         return false;
650     }
651     switch (static_cast<CmasMsgType>(msgId)) {
652         case CmasMsgType::EXTREME_OBSERVED:
653         case CmasMsgType::EXTREME_OBSERVED_SPANISH:
654         case CmasMsgType::SEVERE_OBSERVED:
655         case CmasMsgType::SEVERE_OBSERVED_SPANISH:
656         case CmasMsgType::ALERT_OBSERVED_DEFUALT:
657         case CmasMsgType::ALERT_OBSERVED_SPANISH:
658         case CmasMsgType::EXPECTED_OBSERVED:
659         case CmasMsgType::EXPECTED_OBSERVED_SPANISH:
660             certainty = static_cast<uint8_t>(SmsCmaeCertainty::OBSERVED);
661             break;
662         case CmasMsgType::EXTREME_LIKELY:
663         case CmasMsgType::EXTREME_LIKELY_SPANISH:
664         case CmasMsgType::SEVERE_LIKELY:
665         case CmasMsgType::SEVERE_LIKELY_SPANISH:
666         case CmasMsgType::ALERT_LIKELY:
667         case CmasMsgType::ALERT_LIKELY_SPANISH:
668         case CmasMsgType::EXPECTED_LIKELY:
669         case CmasMsgType::EXPECTED_LIKELY_SPANISH:
670             certainty = static_cast<uint8_t>(SmsCmaeCertainty::LIKELY);
671             break;
672         default:
673             certainty = static_cast<uint8_t>(SmsCmaeCertainty::RESERVED);
674             break;
675     }
676     return true;
677 }
678 
GetCmasCategory(uint8_t & cmasCategory) const679 bool GsmCbCodec::GetCmasCategory(uint8_t &cmasCategory) const
680 {
681     cmasCategory = static_cast<uint8_t>(SmsCmaeCategory::RESERVED);
682     return true;
683 }
684 
GetCmasResponseType(uint8_t & cmasRes) const685 bool GsmCbCodec::GetCmasResponseType(uint8_t &cmasRes) const
686 {
687     cmasRes = static_cast<uint8_t>(SmsCmaeResponseType::RESERVED);
688     return true;
689 }
690 
GetMessageId(uint16_t & msgId) const691 bool GsmCbCodec::GetMessageId(uint16_t &msgId) const
692 {
693     if (cbHeader_ == nullptr) {
694         TELEPHONY_LOGE("cbHeader_ is nullptr");
695         return false;
696     }
697     msgId = cbHeader_->msgId;
698     return true;
699 }
700 
GetCmasMessageClass(uint8_t & cmasClass) const701 bool GsmCbCodec::GetCmasMessageClass(uint8_t &cmasClass) const
702 {
703     uint16_t cbMsgId = 0;
704     if (!GetMessageId(cbMsgId)) {
705         TELEPHONY_LOGE("get cb id fail.");
706         return false;
707     }
708     cmasClass = CMASClass(cbMsgId);
709     return true;
710 }
711 
GetMsgType(uint8_t & msgType) const712 bool GsmCbCodec::GetMsgType(uint8_t &msgType) const
713 {
714     if (cbHeader_ == nullptr) {
715         TELEPHONY_LOGE("cbHeader_ is nullptr");
716         return false;
717     }
718     msgType = cbHeader_->cbMsgType;
719     return true;
720 }
721 
GetLangType(uint8_t & lan) const722 bool GsmCbCodec::GetLangType(uint8_t &lan) const
723 {
724     if (cbHeader_ == nullptr) {
725         TELEPHONY_LOGE("cbHeader_ is nullptr");
726         return false;
727     }
728     lan = cbHeader_->langType;
729     return true;
730 }
731 
GetDcs(uint8_t & dcs) const732 bool GsmCbCodec::GetDcs(uint8_t &dcs) const
733 {
734     if (cbHeader_ == nullptr) {
735         TELEPHONY_LOGE("cbHeader_ is nullptr");
736         return false;
737     }
738     dcs = cbHeader_->dcs.codingScheme;
739     return true;
740 }
741 
GetReceiveTime(int64_t & receiveTime) const742 bool GsmCbCodec::GetReceiveTime(int64_t &receiveTime) const
743 {
744     if (cbHeader_ == nullptr) {
745         TELEPHONY_LOGE("nullptr error.");
746         return false;
747     }
748     receiveTime = cbHeader_->recvTime;
749     if (receiveTime == 0) {
750         TELEPHONY_LOGI("receiveTime = 0");
751         time_t recvTime = time(NULL);
752         receiveTime = static_cast<int64_t>(recvTime);
753     }
754     return true;
755 }
756 } // namespace Telephony
757 } // namespace OHOS