/* * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "cdma_sms_common.h" #include "gsm_cb_gsm_codec.h" #include "gsm_cb_umts_codec.h" #include "gsm_pdu_hex_value.h" #include "securec.h" #include "sms_common_utils.h" #include "string_utils.h" #include "telephony_ext_wrapper.h" #include "telephony_log_wrapper.h" #include "text_coder.h" namespace OHOS { namespace Telephony { static constexpr uint8_t SMS_BYTE_BIT = 8; static constexpr uint8_t GSM_CB_HEADER_LEN = 6; static constexpr uint16_t MAX_CB_MSG_LEN = 4200; static constexpr uint8_t MAX_PAGE_PDU_LEN = 82; static constexpr uint8_t CB_FORMAT_3GPP = 1; static constexpr uint16_t OTHER_TYPE = -2; static constexpr uint16_t ETWS_TYPE = 0x1100; static constexpr uint16_t ETWS_TYPE_MASK = 0xFFF8; static constexpr uint16_t CMAS_FIRST_ID = 0x1112; static constexpr uint16_t CMAS_LAST_ID = 0x112F; static constexpr uint16_t EMERGENCY_USER_ALERT = 0x2000; static constexpr uint16_t ETWS_POPUP = 0x1000; static constexpr uint16_t PWS_FIRST_ID = 0x1100; static constexpr uint16_t PWS_LAST_ID = 0x18FF; bool GsmCbCodec::operator==(const GsmCbCodec &codec) const { if (cbHeader_ == nullptr || codec.cbHeader_ == nullptr) { TELEPHONY_LOGE("nullptr error."); return false; } return cbHeader_->serialNum.geoScope == codec.cbHeader_->serialNum.geoScope && cbHeader_->serialNum.msgCode == codec.cbHeader_->serialNum.msgCode && cbHeader_->msgId == codec.cbHeader_->msgId; } std::shared_ptr<GsmCbCodec> GsmCbCodec::CreateCbMessage(const std::string &pdu) { bool result = false; std::shared_ptr<GsmCbCodec> message = std::make_shared<GsmCbCodec>(); if (message == nullptr) { TELEPHONY_LOGE("message is nullptr."); return nullptr; } result = message->PduAnalysis(StringUtils::HexToByteVector(pdu)); return (result ? message : nullptr); } std::shared_ptr<GsmCbCodec> GsmCbCodec::CreateCbMessage(const std::vector<unsigned char> &pdu) { bool result = false; std::shared_ptr<GsmCbCodec> message = std::make_shared<GsmCbCodec>(); if (message == nullptr) { TELEPHONY_LOGE("message is nullptr."); return nullptr; } result = message->PduAnalysis(pdu); return (result ? message : nullptr); } std::shared_ptr<GsmCbCodec::GsmCbMessageHeader> GsmCbCodec::GetCbHeader() const { return cbHeader_; } std::string GsmCbCodec::GetCbMessageRaw() const { return messageRaw_; } void GsmCbCodec::SetCbMessageRaw(std::string &raw) { messageRaw_ = raw; } bool GsmCbCodec::IsSinglePageMsg() const { return cbHeader_ != nullptr && (cbHeader_->totalPages == 1); } /** * refer to 3GPP TS 23.041 V4.1.0 9.1.1 9.1.2 section Protocols and Protocol Architecture * refer to 3GPP TS 23.041 V4.1.0 9.3 Parameters */ bool GsmCbCodec::PduAnalysis(const std::vector<unsigned char> &pdu) { if (!ParamsCheck(pdu)) { TELEPHONY_LOGE("params error."); return false; } auto gsmCodec = std::make_shared<GsmCbGsmCodec>(cbHeader_, cbPduBuffer_, shared_from_this()); auto umtsCodec = std::make_shared<GsmCbUmtsCodec>(cbHeader_, cbPduBuffer_, shared_from_this()); if (gsmCodec == nullptr || umtsCodec == nullptr) { TELEPHONY_LOGE("nullptr error."); return false; } // refer to 3GPP TS 23.041 V4.1.0 9.1.1 9.1.2 section Protocols and Protocol Architecture bool decodeResult = false; if (pdu.size() <= (MAX_PAGE_PDU_LEN + GSM_CB_HEADER_LEN)) { cbHeader_->cbMsgType = GSM_CBS; cbHeader_->cbNetType = GSM_NET_CB; decodeResult = gsmCodec->Decode2gHeader(); } else if (pdu.size() <= MAX_CB_MSG_LEN) { uint8_t oneByte = 0; if (!cbPduBuffer_->PickOneByte(oneByte)) { TELEPHONY_LOGE("get data error."); return false; } cbHeader_->cbMsgType = oneByte; cbHeader_->cbNetType = UMTS_NET_CB; decodeResult = umtsCodec->Decode3gHeader(); } else { TELEPHONY_LOGE("pdu size over max."); return false; } if (!decodeResult || cbPduBuffer_->GetCurPosition() >= pdu.size()) { TELEPHONY_LOGE("CB decode head fail."); return false; } if (cbHeader_->bEtwsMessage && cbHeader_->cbEtwsType == ETWS_PRIMARY) { return gsmCodec->DecodeEtwsMsg(); } if (cbHeader_->cbNetType == GSM_NET_CB) { decodeResult = gsmCodec->Decode2gCbMsg(); } else if (cbHeader_->cbNetType == UMTS_NET_CB) { decodeResult = umtsCodec->Decode3gCbMsg(); } TELEPHONY_LOGI("CB decode result:%{public}d.", decodeResult); return decodeResult; } bool GsmCbCodec::ParamsCheck(const std::vector<unsigned char> &pdu) { if (pdu.size() == 0 && pdu.size() > MAX_CB_MSG_LEN) { TELEPHONY_LOGE("pdu data error."); return false; } cbPduBuffer_ = std::make_shared<GsmCbPduDecodeBuffer>(pdu.size()); cbHeader_ = std::make_shared<GsmCbCodec::GsmCbMessageHeader>(); if (cbPduBuffer_ == nullptr || cbHeader_ == nullptr || cbPduBuffer_->pduBuffer_ == nullptr) { TELEPHONY_LOGE("nullptr error."); return false; } for (size_t index = 0; index < pdu.size() && index < cbPduBuffer_->GetSize(); index++) { cbPduBuffer_->pduBuffer_[index] = static_cast<char>(pdu[index]); } return true; } void GsmCbCodec::GetPduData(std::vector<unsigned char> &dataPdu) { if (cbPduBuffer_ == nullptr) { TELEPHONY_LOGE("nullptr error."); return; } uint32_t current = cbPduBuffer_->GetCurPosition(); uint8_t oneByte = 0; while (cbPduBuffer_->GetCurPosition() < cbPduBuffer_->GetSize()) { if (!cbPduBuffer_->GetOneByte(oneByte)) { TELEPHONY_LOGE("get data error."); } dataPdu.push_back(oneByte); } cbPduBuffer_->SetPointer(current); } void GsmCbCodec::ConvertToUTF8(const std::string &raw, std::string &message) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("ConvertToUTF8 cbHeader null err."); return; } if (cbHeader_->bEtwsMessage && cbHeader_->cbEtwsType == ETWS_PRIMARY) { message.assign(raw); } else { uint16_t codeSize = 0; MsgLangInfo langInfo; uint8_t outBuf[MAX_CB_MSG_LEN + 1] = { 0 }; const uint8_t *src = reinterpret_cast<const uint8_t *>(raw.data()); if (cbHeader_->dcs.codingScheme == DATA_CODING_7BIT) { codeSize = TextCoder::Instance().Gsm7bitToUtf8(outBuf, sizeof(outBuf), src, raw.length(), langInfo); } else if (cbHeader_->dcs.codingScheme == DATA_CODING_UCS2) { codeSize = TextCoder::Instance().Ucs2ToUtf8(outBuf, sizeof(outBuf), src, raw.length()); } else { TELEPHONY_LOGI("CB message data encoding 8bit"); message.assign(raw); return; } if (codeSize >= MAX_CB_MSG_LEN) { TELEPHONY_LOGE("codeSize over size."); return; } outBuf[codeSize] = '\0'; for (uint16_t index = 0; index < codeSize; index++) { message.push_back(static_cast<char>(outBuf[index])); } } } unsigned short GsmCbCodec::EncodeCbSerialNum(const GsmCBMsgSerialNum &snFields) { unsigned short serialNum = ((snFields.geoScope & HEX_VALUE_03) << HEX_VALUE_0E) | ((snFields.msgCode & HEX_VALUE_03FF) << HEX_VALUE_04) | (snFields.updateNum & HEX_VALUE_0F); return serialNum; } uint8_t GsmCbCodec::CMASClass(const uint16_t messageId) const { uint8_t ret = 0; switch (messageId) { case PRESIDENTIAL: case PRESIDENTIAL_SPANISH: ret = CMAS_PRESIDENTIAL; break; case EXTREME_OBSERVED: case EXTREME_OBSERVED_SPANISH: case EXTREME_LIKELY: case EXTREME_LIKELY_SPANISH: ret = CMAS_EXTREME; break; case SEVERE_OBSERVED: case SEVERE_OBSERVED_SPANISH: case SEVERE_LIKELY: case SEVERE_LIKELY_SPANISH: case ALERT_OBSERVED_DEFUALT: case ALERT_OBSERVED_SPANISH: case ALERT_LIKELY: case ALERT_LIKELY_SPANISH: case EXPECTED_OBSERVED: case EXPECTED_OBSERVED_SPANISH: case EXPECTED_LIKELY: case EXPECTED_LIKELY_SPANISH: ret = CMAS_SEVERE; break; case AMBER_ALERT: case AMBER_ALERT_SPANISH: ret = CMAS_AMBER; break; case MONTHLY_ALERT: case MONTHLY_ALERT_SPANISH: ret = CMAS_TEST; break; case EXERCISE_ALERT: case EXERCISE_ALERT_SPANISH: ret = CMAS_EXERCISE; break; case OPERATOR_ALERT: case OPERATOR_ALERT_SPANISH: ret = CMAS_OPERATOR_DEFINED; break; default: break; } return ret; } /** * refer to 3GPP TS 23.038 V4.3.0 6.1.1 section */ void GsmCbCodec::DecodeIos639Dcs(const uint8_t dcsData, const unsigned short iosData, GsmCbMsgDcs &dcs) const { uint8_t dcsLow = (dcsData & HEX_VALUE_0F); switch (dcsLow) { case 0x00: case HEX_VALUE_01: { dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS; dcs.codingScheme = (dcsData & HEX_VALUE_01) ? DATA_CODING_UCS2 : DATA_CODING_7BIT; dcs.langType = CB_LANG_ISO639; uint8_t hight = (iosData >> SMS_BYTE_BIT); uint8_t low = iosData; // refer to 3GPP TS 23.038 V4.3.0 6.1.1 section Control characters if (hight && low) { dcs.iso639Lang[0x00] = hight & HEX_VALUE_7F; dcs.iso639Lang[HEX_VALUE_01] = (hight & HEX_VALUE_80) >> HEX_VALUE_07; dcs.iso639Lang[HEX_VALUE_01] |= (low & HEX_VALUE_3F) << HEX_VALUE_01; dcs.iso639Lang[HEX_VALUE_02] = HEX_VALUE_13; /* CR */ } else { dcs.iso639Lang[0x00] = HEX_VALUE_45; /* E */ dcs.iso639Lang[HEX_VALUE_01] = HEX_VALUE_4E; /* N */ dcs.iso639Lang[HEX_VALUE_02] = HEX_VALUE_13; /* CR */ } break; } default: break; } } /** * refer to 3GPP TS 23.038 V4.3.0 6 section */ void GsmCbCodec::DecodeGeneralDcs(const uint8_t dcsData, GsmCbMsgDcs &dcs) const { dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS; dcs.bCompressed = (dcsData & HEX_VALUE_20) ? true : false; if (dcsData & HEX_VALUE_10) { dcs.classType = (dcsData & HEX_VALUE_03); } uint8_t tmpScheme = (dcsData & HEX_VALUE_0C) >> HEX_VALUE_02; switch (tmpScheme) { case 0x00: dcs.codingScheme = DATA_CODING_7BIT; break; case HEX_VALUE_01: dcs.codingScheme = DATA_CODING_8BIT; break; case HEX_VALUE_02: dcs.codingScheme = DATA_CODING_UCS2; break; default: break; } } /** * refer to 3GPP TS 23.038 V4.3.0 6 section */ void GsmCbCodec::DecodeCbMsgDCS(const uint8_t dcsData, const unsigned short iosData, GsmCbMsgDcs &dcs) const { dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS; dcs.classType = SMS_CLASS_UNKNOWN; dcs.bCompressed = false; dcs.codingScheme = DATA_CODING_7BIT; dcs.langType = CB_MSG_UNSPECIFIED; if (memset_s(dcs.iso639Lang, sizeof(dcs.iso639Lang), 0x00, sizeof(dcs.iso639Lang)) != EOK) { TELEPHONY_LOGE("memset_s error!"); return; } dcs.bUDH = false; dcs.rawData = dcsData; uint8_t codingGroup = (dcsData & HEX_VALUE_F0) >> HEX_VALUE_04; switch (codingGroup) { case 0x00: case HEX_VALUE_02: case HEX_VALUE_03: dcs.codingGroup = SMS_CBMSG_CODGRP_GENERAL_DCS; dcs.langType = dcsData; break; case HEX_VALUE_01: DecodeIos639Dcs(dcsData, iosData, dcs); break; case HEX_VALUE_04: case HEX_VALUE_05: case HEX_VALUE_06: case HEX_VALUE_07: DecodeGeneralDcs(dcsData, dcs); break; case HEX_VALUE_09: dcs.bUDH = true; dcs.classType = dcsData & HEX_VALUE_03; dcs.codingScheme = (dcsData & HEX_VALUE_0C) >> HEX_VALUE_02; break; case HEX_VALUE_0E: dcs.codingGroup = SMS_CBMSG_CODGRP_WAP; break; case HEX_VALUE_0F: dcs.codingGroup = SMS_CBMSG_CODGRP_CLASS_CODING; dcs.codingScheme = (dcsData & HEX_VALUE_04) ? DATA_CODING_8BIT : DATA_CODING_7BIT; dcs.classType = dcsData & HEX_VALUE_03; break; default: TELEPHONY_LOGI("codingGrp: [0x%{public}x]", codingGroup); break; } } int64_t GsmCbCodec::GetRecvTime() const { time_t recvTime = time(NULL); return static_cast<int64_t>(recvTime); } std::string GsmCbCodec::ToString() const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return "GsmCbCodec Header nullptr"; } std::string cbMsgId("msgId:" + std::to_string(cbHeader_->msgId)); std::string cbLangType("\nlangType:" + std::to_string(cbHeader_->langType)); std::string cbIsEtwsMessage("\nisEtws:" + std::to_string(cbHeader_->bEtwsMessage)); std::string cbMsgType("\ncbMsgType:" + std::to_string(cbHeader_->cbMsgType)); std::string cbWarningType("\nwarningType:" + std::to_string(cbHeader_->warningType)); std::string cbSerialNum("\nserialNum: geoScope " + std::to_string(cbHeader_->serialNum.geoScope) + "| updateNum " + std::to_string(cbHeader_->serialNum.updateNum) + "| msgCode " + std::to_string(cbHeader_->serialNum.msgCode)); std::string cbPage( "\ntotal pages: " + std::to_string(cbHeader_->totalPages) + " page:" + std::to_string(cbHeader_->page)); std::string cbRecvTime("\nrecv time: " + std::to_string(cbHeader_->recvTime)); std::string cbDcsRaw("\ndcs: " + std::to_string(cbHeader_->dcs.rawData)); std::string cbMsgBody; ConvertToUTF8(messageRaw_, cbMsgBody); return cbMsgId.append(cbLangType) .append(cbIsEtwsMessage) .append(cbMsgType) .append(cbWarningType) .append(cbSerialNum) .append(cbPage) .append(cbRecvTime) .append(cbDcsRaw) .append("\nbody:") .append(cbMsgBody); } bool GsmCbCodec::GetFormat(int8_t &cbFormat) const { cbFormat = CB_FORMAT_3GPP; return true; } bool GsmCbCodec::GetPriority(int8_t &cbPriority) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } const int8_t normal = 0x00; const int8_t emergency = HEX_VALUE_03; if (cbHeader_->msgId >= PWS_FIRST_ID && cbHeader_->msgId <= PWS_LAST_ID) { cbPriority = emergency; } else { cbPriority = normal; } return true; } bool GsmCbCodec::GetGeoScope(uint8_t &geoScope) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } geoScope = cbHeader_->serialNum.geoScope; return true; } bool GsmCbCodec::GetSerialNum(uint16_t &cbSerial) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } cbSerial = ((cbHeader_->serialNum.geoScope & HEX_VALUE_03) << HEX_VALUE_0E) | ((cbHeader_->serialNum.msgCode & HEX_VALUE_03FF) << HEX_VALUE_04) | (cbHeader_->serialNum.updateNum & HEX_VALUE_0F); return true; } bool GsmCbCodec::GetServiceCategory(uint16_t &cbCategoty) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } cbCategoty = cbHeader_->msgId; return true; } bool GsmCbCodec::GetWarningType(uint16_t &type) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } if (TELEPHONY_EXT_WRAPPER.getCustEtwsType_ != nullptr) { TELEPHONY_LOGI("GetWarningType getCustEtwsType_ not null"); TELEPHONY_EXT_WRAPPER.getCustEtwsType_(cbHeader_->msgId, type); if (type != OTHER_TYPE) { TELEPHONY_LOGI("getCustEtwsType_ type not OTHER_TYPE."); return true; } } type = cbHeader_->msgId - ETWS_TYPE; return true; } bool GsmCbCodec::IsEtwsPrimary(bool &primary) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } primary = (cbHeader_->cbEtwsType == ETWS_PRIMARY); return true; } bool GsmCbCodec::IsEtwsMessage(bool &etws) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } etws = ((cbHeader_->msgId & ETWS_TYPE_MASK) == ETWS_TYPE); if (!etws && TELEPHONY_EXT_WRAPPER.isCustEtwsMessage_ != nullptr) { TELEPHONY_LOGI("IsEtwsMessage isCustEtwsMessage_ not null"); if (TELEPHONY_EXT_WRAPPER.isCustEtwsMessage_(cbHeader_->msgId)) { TELEPHONY_LOGI("isCustEtwsMessage_ is true."); etws = true; } } return true; } bool GsmCbCodec::IsCmasMessage(bool &cmas) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } cmas = ((cbHeader_->msgId >= CMAS_FIRST_ID) && (cbHeader_->msgId <= CMAS_LAST_ID)); return true; } bool GsmCbCodec::IsEtwsEmergencyUserAlert(bool &alert) const { uint16_t serial = 0; if (!GetSerialNum(serial)) { TELEPHONY_LOGE("Get serial num fail."); return false; } alert = ((serial & EMERGENCY_USER_ALERT) != 0); return true; } bool GsmCbCodec::IsEtwsPopupAlert(bool &alert) const { uint16_t serial = 0; if (!GetSerialNum(serial)) { TELEPHONY_LOGE("Get serial num fail."); return false; } alert = ((serial & ETWS_POPUP) != 0); return true; } bool GsmCbCodec::GetCmasSeverity(uint8_t &severity) const { uint16_t msgId = 0; if (!GetMessageId(msgId)) { TELEPHONY_LOGE("Get message id fail."); return false; } switch (static_cast<CmasMsgType>(msgId)) { case CmasMsgType::EXTREME_OBSERVED: case CmasMsgType::EXTREME_OBSERVED_SPANISH: case CmasMsgType::EXTREME_LIKELY: case CmasMsgType::EXTREME_LIKELY_SPANISH: case CmasMsgType::SEVERE_OBSERVED: case CmasMsgType::SEVERE_OBSERVED_SPANISH: case CmasMsgType::SEVERE_LIKELY: case CmasMsgType::SEVERE_LIKELY_SPANISH: severity = static_cast<uint8_t>(SmsCmaeSeverity::EXTREME); break; case CmasMsgType::ALERT_OBSERVED_DEFUALT: case CmasMsgType::ALERT_OBSERVED_SPANISH: case CmasMsgType::ALERT_LIKELY: case CmasMsgType::ALERT_LIKELY_SPANISH: case CmasMsgType::EXPECTED_OBSERVED: case CmasMsgType::EXPECTED_OBSERVED_SPANISH: case CmasMsgType::EXPECTED_LIKELY: case CmasMsgType::EXPECTED_LIKELY_SPANISH: severity = static_cast<uint8_t>(SmsCmaeSeverity::SEVERE); break; default: severity = static_cast<uint8_t>(SmsCmaeSeverity::RESERVED); break; } return true; } bool GsmCbCodec::GetCmasUrgency(uint8_t &urgency) const { uint16_t msgId = 0; if (!GetMessageId(msgId)) { TELEPHONY_LOGE("Get message id fail."); return false; } switch (static_cast<CmasMsgType>(msgId)) { case CmasMsgType::EXTREME_OBSERVED: case CmasMsgType::EXTREME_OBSERVED_SPANISH: case CmasMsgType::EXTREME_LIKELY: case CmasMsgType::EXTREME_LIKELY_SPANISH: case CmasMsgType::ALERT_OBSERVED_DEFUALT: case CmasMsgType::ALERT_OBSERVED_SPANISH: case CmasMsgType::ALERT_LIKELY: case CmasMsgType::ALERT_LIKELY_SPANISH: urgency = static_cast<uint8_t>(SmsCmaeUrgency::IMMEDIATE); break; case CmasMsgType::SEVERE_OBSERVED: case CmasMsgType::SEVERE_OBSERVED_SPANISH: case CmasMsgType::SEVERE_LIKELY: case CmasMsgType::SEVERE_LIKELY_SPANISH: case CmasMsgType::EXPECTED_OBSERVED: case CmasMsgType::EXPECTED_OBSERVED_SPANISH: case CmasMsgType::EXPECTED_LIKELY: case CmasMsgType::EXPECTED_LIKELY_SPANISH: urgency = static_cast<uint8_t>(SmsCmaeUrgency::EXPECTED); break; default: urgency = static_cast<uint8_t>(SmsCmaeUrgency::RESERVED); break; } return true; } bool GsmCbCodec::GetCmasCertainty(uint8_t &certainty) const { uint16_t msgId = 0; if (!GetMessageId(msgId)) { TELEPHONY_LOGE("Get message id fail."); return false; } switch (static_cast<CmasMsgType>(msgId)) { case CmasMsgType::EXTREME_OBSERVED: case CmasMsgType::EXTREME_OBSERVED_SPANISH: case CmasMsgType::SEVERE_OBSERVED: case CmasMsgType::SEVERE_OBSERVED_SPANISH: case CmasMsgType::ALERT_OBSERVED_DEFUALT: case CmasMsgType::ALERT_OBSERVED_SPANISH: case CmasMsgType::EXPECTED_OBSERVED: case CmasMsgType::EXPECTED_OBSERVED_SPANISH: certainty = static_cast<uint8_t>(SmsCmaeCertainty::OBSERVED); break; case CmasMsgType::EXTREME_LIKELY: case CmasMsgType::EXTREME_LIKELY_SPANISH: case CmasMsgType::SEVERE_LIKELY: case CmasMsgType::SEVERE_LIKELY_SPANISH: case CmasMsgType::ALERT_LIKELY: case CmasMsgType::ALERT_LIKELY_SPANISH: case CmasMsgType::EXPECTED_LIKELY: case CmasMsgType::EXPECTED_LIKELY_SPANISH: certainty = static_cast<uint8_t>(SmsCmaeCertainty::LIKELY); break; default: certainty = static_cast<uint8_t>(SmsCmaeCertainty::RESERVED); break; } return true; } bool GsmCbCodec::GetCmasCategory(uint8_t &cmasCategory) const { cmasCategory = static_cast<uint8_t>(SmsCmaeCategory::RESERVED); return true; } bool GsmCbCodec::GetCmasResponseType(uint8_t &cmasRes) const { cmasRes = static_cast<uint8_t>(SmsCmaeResponseType::RESERVED); return true; } bool GsmCbCodec::GetMessageId(uint16_t &msgId) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } msgId = cbHeader_->msgId; return true; } bool GsmCbCodec::GetCmasMessageClass(uint8_t &cmasClass) const { uint16_t cbMsgId = 0; if (!GetMessageId(cbMsgId)) { TELEPHONY_LOGE("get cb id fail."); return false; } cmasClass = CMASClass(cbMsgId); return true; } bool GsmCbCodec::GetMsgType(uint8_t &msgType) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } msgType = cbHeader_->cbMsgType; return true; } bool GsmCbCodec::GetLangType(uint8_t &lan) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } lan = cbHeader_->langType; return true; } bool GsmCbCodec::GetDcs(uint8_t &dcs) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("cbHeader_ is nullptr"); return false; } dcs = cbHeader_->dcs.codingScheme; return true; } bool GsmCbCodec::GetReceiveTime(int64_t &receiveTime) const { if (cbHeader_ == nullptr) { TELEPHONY_LOGE("nullptr error."); return false; } receiveTime = cbHeader_->recvTime; if (receiveTime == 0) { TELEPHONY_LOGI("receiveTime = 0"); time_t recvTime = time(NULL); receiveTime = static_cast<int64_t>(recvTime); } return true; } } // namespace Telephony } // namespace OHOS