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