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