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 27namespace OHOS { 28namespace Telephony { 29static constexpr uint8_t SMS_BYTE_BIT = 8; 30static constexpr uint8_t GSM_CB_HEADER_LEN = 6; 31static constexpr uint16_t MAX_CB_MSG_LEN = 4200; 32static constexpr uint8_t MAX_PAGE_PDU_LEN = 82; 33static constexpr uint8_t CB_FORMAT_3GPP = 1; 34static constexpr uint16_t OTHER_TYPE = -2; 35static constexpr uint16_t ETWS_TYPE = 0x1100; 36static constexpr uint16_t ETWS_TYPE_MASK = 0xFFF8; 37static constexpr uint16_t CMAS_FIRST_ID = 0x1112; 38static constexpr uint16_t CMAS_LAST_ID = 0x112F; 39static constexpr uint16_t EMERGENCY_USER_ALERT = 0x2000; 40static constexpr uint16_t ETWS_POPUP = 0x1000; 41static constexpr uint16_t PWS_FIRST_ID = 0x1100; 42static constexpr uint16_t PWS_LAST_ID = 0x18FF; 43 44bool 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 55std::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 67std::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 79std::shared_ptr<GsmCbCodec::GsmCbMessageHeader> GsmCbCodec::GetCbHeader() const 80{ 81 return cbHeader_; 82} 83 84std::string GsmCbCodec::GetCbMessageRaw() const 85{ 86 return messageRaw_; 87} 88 89void GsmCbCodec::SetCbMessageRaw(std::string &raw) 90{ 91 messageRaw_ = raw; 92} 93 94bool 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 */ 103bool 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 153bool 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 171void 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 189void 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 222unsigned 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 230uint8_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 */ 283void 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 */ 316void 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 */ 342void 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 391int64_t GsmCbCodec::GetRecvTime() const 392{ 393 time_t recvTime = time(NULL); 394 return static_cast<int64_t>(recvTime); 395} 396 397std::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 429bool GsmCbCodec::GetFormat(int8_t &cbFormat) const 430{ 431 cbFormat = CB_FORMAT_3GPP; 432 return true; 433} 434 435bool 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 451bool 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 461bool 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 473bool 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 483bool 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 501bool 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 511bool 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 528bool 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 538bool 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 549bool 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 560bool 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 595bool 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 630bool 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 665bool GsmCbCodec::GetCmasCategory(uint8_t &cmasCategory) const 666{ 667 cmasCategory = static_cast<uint8_t>(SmsCmaeCategory::RESERVED); 668 return true; 669} 670 671bool GsmCbCodec::GetCmasResponseType(uint8_t &cmasRes) const 672{ 673 cmasRes = static_cast<uint8_t>(SmsCmaeResponseType::RESERVED); 674 return true; 675} 676 677bool 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 687bool 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 698bool 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 708bool 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 718bool 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 728bool 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