1/*
2 * Copyright (C) 2021-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_message.h"
17
18#include "securec.h"
19#include "sms_common_utils.h"
20#include "string_utils.h"
21#include "telephony_log_wrapper.h"
22#include "text_coder.h"
23
24namespace OHOS {
25namespace Telephony {
26static constexpr uint16_t CDMA_MAX_UD_HEADER_NUM = 7;
27
28std::unique_ptr<CdmaTransportMsg> CdmaSmsMessage::CreateSubmitTransMsg(const std::string &dest, const std::string &sc,
29    const std::string &text, bool bStatusReport, const DataCodingScheme codingScheme)
30{
31    std::unique_ptr<CdmaTransportMsg> transMsg = GreateTransMsg();
32    if (transMsg == nullptr) {
33        TELEPHONY_LOGE("CreateMessage message transMsg nullptr");
34        return nullptr;
35    }
36    scAddress_ = sc;
37    originatingAddress_ = dest;
38    visibleMessageBody_ = text;
39    bStatusReportMessage_ = bStatusReport;
40    transMsg->data.p2p.telesvcMsg.data.submit.userData.encodeType = CovertEncodingType(codingScheme);
41    /* Set Reply option */
42    transMsg->data.p2p.telesvcMsg.data.submit.replyOpt.dak = bStatusReport;
43    /* Convert Address values */
44    transMsg->data.p2p.address.digitMode = false;
45    transMsg->data.p2p.address.numberMode = false;
46    transMsg->data.p2p.address.numberPlan = SMS_NPI_UNKNOWN;
47    transMsg->data.p2p.address.addrLen = dest.length();
48    if (strncpy_s(transMsg->data.p2p.address.szData, sizeof(transMsg->data.p2p.address.szData), dest.c_str(),
49            dest.length()) != EOK) {
50        transMsg->data.p2p.address.addrLen = sizeof(transMsg->data.p2p.address.szData) - 1;
51        transMsg->data.p2p.address.szData[transMsg->data.p2p.address.addrLen] = '\0';
52    }
53    if (dest.at(0) == '+') {
54        transMsg->data.p2p.address.digitMode = true;
55        transMsg->data.p2p.address.numberType = static_cast<uint8_t>(SmsNumberType::INTERNATIONAL);
56    } else {
57        transMsg->data.p2p.address.numberType = static_cast<uint8_t>(SmsNumberType::NATIONAL);
58    }
59    return transMsg;
60}
61
62std::unique_ptr<CdmaTransportMsg> CdmaSmsMessage::CreateSubmitTransMsg(const std::string &dest, const std::string &sc,
63    int32_t port, const uint8_t *data, uint32_t dataLen, bool bStatusReport)
64{
65    std::unique_ptr<CdmaTransportMsg> transMsg = GreateTransMsg();
66    if (transMsg == nullptr) {
67        TELEPHONY_LOGE("CreateMessage message transMsg nullptr");
68        return nullptr;
69    }
70
71    scAddress_ = sc;
72    destPort_ = static_cast<uint16_t>(port);
73    originatingAddress_ = dest;
74    bStatusReportMessage_ = bStatusReport;
75    /* Set Reply option */
76    transMsg->data.p2p.telesvcMsg.data.submit.replyOpt.dak = bStatusReport;
77    /* Convert Address values */
78    transMsg->data.p2p.address.digitMode = false;
79    transMsg->data.p2p.address.numberMode = false;
80    transMsg->data.p2p.address.numberPlan = SMS_NPI_UNKNOWN;
81    transMsg->data.p2p.address.addrLen = dest.length();
82    if (dest.length() > CDMASMS_ADDRESS_LEN_MAX + 1) {
83        TELEPHONY_LOGE("CreateSubmitTransMsg data length invalid.");
84        return nullptr;
85    }
86    if (strncpy_s(transMsg->data.p2p.address.szData, sizeof(transMsg->data.p2p.address.szData), dest.c_str(),
87            dest.length()) != EOK) {
88        transMsg->data.p2p.address.addrLen = sizeof(transMsg->data.p2p.address.szData) - 1;
89        transMsg->data.p2p.address.szData[transMsg->data.p2p.address.addrLen] = '\0';
90    }
91    if (dest.at(0) == '+') {
92        transMsg->data.p2p.address.digitMode = true;
93        transMsg->data.p2p.address.numberType = static_cast<uint8_t>(SmsNumberType::INTERNATIONAL);
94    } else {
95        transMsg->data.p2p.address.numberType = static_cast<uint8_t>(SmsNumberType::NATIONAL);
96    }
97    return transMsg;
98}
99
100std::unique_ptr<struct CdmaTransportMsg> CdmaSmsMessage::GreateTransMsg()
101{
102    std::unique_ptr<CdmaTransportMsg> transMsg = std::make_unique<CdmaTransportMsg>();
103    if (transMsg == nullptr) {
104        TELEPHONY_LOGE("CreateMessage message transMsg nullptr");
105        return nullptr;
106    }
107    (void)memset_s(transMsg.get(), sizeof(CdmaTransportMsg), 0x00, sizeof(CdmaTransportMsg));
108    transMsg->type = CdmaTransportMsgType::P2P;
109    transMsg->data.p2p.telesvcMsg.type = TeleserviceMsgType::SUBMIT;
110    /* 1. Set Teleservice ID */
111    transMsg->data.p2p.teleserviceId = static_cast<uint16_t>(SmsTransTelsvcId::CMT_95);
112    /* 2. Set Service category */
113    transMsg->data.p2p.serviceCtg = static_cast<uint16_t>(SmsServiceCtg::UNDEFINED);
114
115    /* 3. Set Valid period */
116    transMsg->data.p2p.telesvcMsg.data.submit.valPeriod.format = SMS_TIME_RELATIVE;
117    transMsg->data.p2p.telesvcMsg.data.submit.valPeriod.time.relTime.time = SMS_REL_TIME_INDEFINITE;
118    /* 4. Set Priority */
119    transMsg->data.p2p.telesvcMsg.data.submit.priority = SmsPriorityIndicator::NORMAL;
120    /* 5. Set Privacy */
121    transMsg->data.p2p.telesvcMsg.data.submit.privacy = SmsPrivacyIndicator::NOT_RESTRICTED;
122    /* 6. Set Alert priority */
123    transMsg->data.p2p.telesvcMsg.data.submit.alertPriority = SmsAlertPriority::DEFAULT;
124    /* 7. Set Language */
125    transMsg->data.p2p.telesvcMsg.data.submit.language = SmsLanguageType::UNKNOWN;
126    return transMsg;
127}
128
129SmsEncodingType CdmaSmsMessage::CovertEncodingType(const DataCodingScheme &codingScheme)
130{
131    SmsEncodingType encodingType = SmsEncodingType::ASCII_7BIT;
132    switch (codingScheme) {
133        case DATA_CODING_7BIT:
134            encodingType = SmsEncodingType::GSM7BIT;
135            break;
136        case DATA_CODING_ASCII7BIT:
137            encodingType = SmsEncodingType::ASCII_7BIT;
138            break;
139        case DATA_CODING_8BIT:
140            encodingType = SmsEncodingType::OCTET;
141            break;
142        case DATA_CODING_UCS2:
143        default:
144            encodingType = SmsEncodingType::UNICODE;
145            break;
146    }
147    return encodingType;
148}
149
150std::shared_ptr<CdmaSmsMessage> CdmaSmsMessage::CreateMessage(const std::string &pdu)
151{
152    std::shared_ptr<CdmaSmsMessage> message = std::make_shared<CdmaSmsMessage>();
153    if (message == nullptr) {
154        TELEPHONY_LOGE("CreateMessage message nullptr");
155        return nullptr;
156    }
157    message->transMsg_ = std::make_unique<struct CdmaTransportMsg>();
158    if (message->transMsg_ == nullptr) {
159        TELEPHONY_LOGE("CreateMessage message transMsg_ nullptr");
160        return nullptr;
161    }
162
163    (void)memset_s(message->transMsg_.get(), sizeof(struct CdmaTransportMsg), 0x00, sizeof(struct CdmaTransportMsg));
164    if (message->PduAnalysis(pdu)) {
165        return message;
166    }
167    return nullptr;
168}
169
170bool CdmaSmsMessage::PduAnalysis(const std::string &pduHex)
171{
172    if (transMsg_ == nullptr || pduHex.empty()) {
173        TELEPHONY_LOGE("PduAnalysis is unInvalid param!");
174        return false;
175    }
176
177    std::string pdu = StringUtils::HexToString(pduHex);
178    SmsReadBuffer pduBuffer(pdu);
179    std::unique_ptr<CdmaSmsTransportMessage> transportMessage =
180        CdmaSmsTransportMessage::CreateTransportMessage(*transMsg_, pduBuffer);
181    if (transportMessage == nullptr || transportMessage->IsEmpty() || !transportMessage->Decode(pduBuffer)) {
182        TELEPHONY_LOGE("Pdu DecodeMsg has failure.");
183        return false;
184    }
185    if (transMsg_->type == CdmaTransportMsgType::BROADCAST) {
186        if (transMsg_->data.broadcast.telesvcMsg.data.deliver.cmasData.isWrongRecodeType) {
187            TELEPHONY_LOGE("Invalid CMAS Record Type");
188            return false;
189        }
190        SmsEncodingType encodeType = transMsg_->data.broadcast.telesvcMsg.data.deliver.cmasData.encodeType;
191        if ((encodeType == SmsEncodingType::KOREAN) || (encodeType == SmsEncodingType::GSMDCS)) {
192            TELEPHONY_LOGE("This encode type is not supported [%{public}d]", static_cast<int>(encodeType));
193            return false;
194        }
195    }
196    switch (transMsg_->type) {
197        case CdmaTransportMsgType::P2P:
198            AnalysisP2pMsg(transMsg_->data.p2p);
199            break;
200        case CdmaTransportMsgType::BROADCAST:
201            AnalysisCbMsg(transMsg_->data.broadcast);
202            break;
203        case CdmaTransportMsgType::ACK:
204            AnalsisAckMsg(transMsg_->data.ack);
205            break;
206        default:
207            return false;
208    }
209    return true;
210}
211
212void CdmaSmsMessage::AnalysisP2pMsg(const CdmaP2PMsg &p2pMsg)
213{
214    if (p2pMsg.teleserviceId == static_cast<uint16_t>(SmsTransTelsvcId::RESERVED)) {
215        TELEPHONY_LOGE("this Incoming Message has Unknown Teleservice ID");
216        return;
217    }
218
219    address_ = std::make_unique<struct TransportAddr>();
220    if (address_ == nullptr) {
221        TELEPHONY_LOGE("AnalysisP2pMsg make address == nullptr");
222        return;
223    }
224
225    if (memcpy_s(address_.get(), sizeof(TransportAddr), &p2pMsg.address, sizeof(TransportAddr)) != EOK) {
226        TELEPHONY_LOGE("AnalysisP2pMsg address memcpy_s error.");
227        return;
228    }
229
230    originatingAddress_ = address_->szData;
231    switch (p2pMsg.telesvcMsg.type) {
232        case TeleserviceMsgType::DELIVER:
233            AnalsisDeliverMwi(p2pMsg);
234            AnalsisDeliverMsg(p2pMsg.telesvcMsg.data.deliver);
235            break;
236        case TeleserviceMsgType::DELIVERY_ACK:
237            AnalsisDeliverAck(p2pMsg.telesvcMsg.data.deliveryAck);
238            break;
239        case TeleserviceMsgType::USER_ACK:
240        case TeleserviceMsgType::READ_ACK:
241            break;
242        case TeleserviceMsgType::SUBMIT_REPORT:
243            AnalsisSubmitReport(p2pMsg.telesvcMsg.data.report);
244            break;
245        case TeleserviceMsgType::SUBMIT:
246            AnalsisSubmitMsg(p2pMsg.telesvcMsg.data.submit);
247            break;
248        default:
249            TELEPHONY_LOGI("AnalysisP2pMsg unkown type =%{public}d", static_cast<int>(p2pMsg.telesvcMsg.type));
250            break;
251    }
252}
253
254void CdmaSmsMessage::AnalsisDeliverMwi(const CdmaP2PMsg &p2pMsg)
255{
256    specialSmsInd_ = nullptr;
257    if (p2pMsg.teleserviceId == static_cast<uint16_t>(SmsTransTelsvcId::VMN_95)) {
258        specialSmsInd_ = std::make_shared<SpecialSmsIndication>();
259        if (specialSmsInd_ == nullptr) {
260            TELEPHONY_LOGE("SpecialSmsIndication is null!");
261            return;
262        }
263
264        specialSmsInd_->msgInd = SMS_VOICE_INDICATOR;
265        if (p2pMsg.telesvcMsg.data.deliver.vmn.faxIncluded) {
266            specialSmsInd_->msgInd = SMS_FAX_INDICATOR;
267        }
268
269        if (p2pMsg.telesvcMsg.data.deliver.numMsg < 0) {
270            specialSmsInd_->waitMsgNum = 0;
271            bMwiClear_ = true;
272            bMwiSet_ = false;
273        } else {
274            specialSmsInd_->waitMsgNum = p2pMsg.telesvcMsg.data.deliver.numMsg;
275            bMwiClear_ = false;
276            bMwiSet_ = true;
277        }
278
279        bMwiNotStore_ = false;
280        if (bMwiSet_ && (p2pMsg.telesvcMsg.data.deliver.userData.userData.length == 0)) {
281            bMwiNotStore_ = true;
282        }
283    }
284}
285
286void CdmaSmsMessage::AnalsisDeliverMsg(const TeleserviceDeliver &deliver)
287{
288    isCmas_ = false;
289    msgClass_ = SMS_CLASS_UNKNOWN;
290    if (deliver.displayMode == SmsDisplayMode::IMMEDIATE) {
291        msgClass_ = SMS_INSTANT_MESSAGE;
292    }
293
294    msgRef_ = deliver.msgId.msgId;
295    bHeaderInd_ = deliver.msgId.headerInd;
296    scTimestamp_ = SmsCommonUtils::ConvertTime(deliver.timeStamp);
297    AnalsisUserData(deliver.userData);
298}
299
300void CdmaSmsMessage::AnalsisDeliverAck(const TeleserviceDeliverAck &deliverAck)
301{
302    bStatusReportMessage_ = true;
303    scTimestamp_ = SmsCommonUtils::ConvertTime(deliverAck.timeStamp);
304    AnalsisUserData(deliverAck.userData);
305}
306
307void CdmaSmsMessage::AnalsisSubmitReport(const TeleserviceDeliverReport &report)
308{
309    AnalsisUserData(report.userData);
310}
311
312void CdmaSmsMessage::AnalsisSubmitMsg(const TeleserviceSubmit &submit)
313{
314    msgRef_ = submit.msgId.msgId;
315    bHeaderInd_ = submit.msgId.headerInd;
316    scTimestamp_ = SmsCommonUtils::ConvertTime(submit.valPeriod.time.absTime);
317    AnalsisUserData(submit.userData);
318}
319
320void CdmaSmsMessage::AnalsisUserData(const SmsTeleSvcUserData &userData)
321{
322    int dataSize = 0;
323    MsgLangInfo langinfo = {
324        0,
325    };
326    AnalsisHeader(userData);
327    unsigned char buff[MAX_MSG_TEXT_LEN + 1] = { 0 };
328    switch (userData.encodeType) {
329        case SmsEncodingType::GSM7BIT: {
330            dataSize = TextCoder::Instance().Gsm7bitToUtf8(
331                buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData, userData.userData.length, langinfo);
332            break;
333        }
334        case SmsEncodingType::KOREAN:
335        case SmsEncodingType::EUCKR: {
336            dataSize = TextCoder::Instance().EuckrToUtf8(
337                buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData, userData.userData.length);
338            break;
339        }
340        case SmsEncodingType::IA5:
341        case SmsEncodingType::ASCII_7BIT:
342        case SmsEncodingType::LATIN_HEBREW:
343        case SmsEncodingType::LATIN:
344        case SmsEncodingType::OCTET: {
345            if (memcpy_s(buff, sizeof(buff), userData.userData.data, userData.userData.length) != EOK) {
346                TELEPHONY_LOGE("AnalsisDeliverMsg memcpy_s fail.");
347                return;
348            }
349            dataSize = userData.userData.length;
350            buff[dataSize] = '\0';
351            break;
352        }
353        case SmsEncodingType::SHIFT_JIS: {
354            dataSize = TextCoder::Instance().ShiftjisToUtf8(
355                buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData.data, userData.userData.length);
356            break;
357        }
358        default: {
359            dataSize = TextCoder::Instance().Ucs2ToUtf8(
360                buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData.data, userData.userData.length);
361            break;
362        }
363    }
364    visibleMessageBody_.insert(0, reinterpret_cast<char *>(buff), dataSize);
365}
366
367void CdmaSmsMessage::AnalsisCMASMsg(const TeleserviceDeliver &deliver)
368{
369    isCmas_ = true;
370    category_ = static_cast<int8_t>(deliver.cmasData.category);
371    responseType_ = static_cast<int8_t>(deliver.cmasData.responseType);
372    severity_ = static_cast<int8_t>(deliver.cmasData.severity);
373    urgency_ = static_cast<int8_t>(deliver.cmasData.urgency);
374    certainty_ = static_cast<int8_t>(deliver.cmasData.certainty);
375    messageClass_ = static_cast<int8_t>(deliver.cmasData.alertHandle);
376    msgClass_ = SMS_CLASS_UNKNOWN;
377    scTimestamp_ = SmsCommonUtils::ConvertTime(deliver.timeStamp);
378    SmsTeleSvcUserData userData;
379    (void)memset_s(&userData, sizeof(SmsTeleSvcUserData), 0x00, sizeof(SmsTeleSvcUserData));
380    userData.userData.length = deliver.cmasData.dataLen;
381    userData.encodeType = deliver.cmasData.encodeType;
382    if (deliver.cmasData.dataLen > sizeof(userData.userData.data)) {
383        TELEPHONY_LOGE("AnalsisCMASMsg memcpy_s data length invalid.");
384        return;
385    }
386    if (memcpy_s(userData.userData.data, sizeof(userData.userData.data), deliver.cmasData.alertText,
387            deliver.cmasData.dataLen) == EOK) {
388        AnalsisUserData(userData);
389    }
390}
391
392void CdmaSmsMessage::AnalysisCbMsg(const CdmaBroadCastMsg &cbMsg)
393{
394    serviceCategory_ = cbMsg.serviceCtg;
395    if (cbMsg.telesvcMsg.type != TeleserviceMsgType::DELIVER) {
396        TELEPHONY_LOGE("No matching type = [%{public}d]", static_cast<int>(cbMsg.telesvcMsg.type));
397        return;
398    }
399    messageId_ = cbMsg.telesvcMsg.data.deliver.msgId.msgId;
400    priority_ = static_cast<int8_t>(cbMsg.telesvcMsg.data.deliver.priority);
401    language_ = static_cast<uint8_t>(cbMsg.telesvcMsg.data.deliver.language);
402    TELEPHONY_LOGI("analysisCbMsg serviceCtg %{public}hu", cbMsg.serviceCtg);
403    if ((cbMsg.serviceCtg >= static_cast<uint16_t>(SmsServiceCtg::CMAS_PRESIDENTIAL)) &&
404        (cbMsg.serviceCtg <= static_cast<uint16_t>(SmsServiceCtg::CMAS_TEST))) {
405        AnalsisCMASMsg(cbMsg.telesvcMsg.data.deliver);
406    } else {
407        AnalsisDeliverMsg(cbMsg.telesvcMsg.data.deliver);
408    }
409}
410
411void CdmaSmsMessage::AnalsisAckMsg(const CdmaAckMsg &ackMsg)
412{
413    originatingAddress_ = ackMsg.address.szData;
414}
415
416bool CdmaSmsMessage::AddUserDataHeader(const struct SmsUDH &header)
417{
418    if (userHeaders_.size() >= CDMA_MAX_UD_HEADER_NUM) {
419        return false;
420    }
421
422    userHeaders_.push_back(header);
423    return true;
424}
425
426void CdmaSmsMessage::AnalsisHeader(const SmsTeleSvcUserData &userData)
427{
428    if (memset_s(&smsUserData_, sizeof(SmsUDPackage), 0x00, sizeof(SmsUDPackage)) != EOK) {
429        return;
430    }
431    headerDataLen_ = userData.userData.length;
432    if (memcpy_s(&smsUserData_, sizeof(SmsUDPackage), &(userData.userData), sizeof(SmsUDPackage)) != EOK) {
433        return;
434    }
435
436    if (bHeaderInd_ && userData.userData.headerCnt > 0) {
437        userHeaders_.clear();
438        for (int i = 0; i < userData.userData.headerCnt; i++) {
439            userHeaders_.push_back(userData.userData.header[i]);
440        }
441    }
442}
443
444/**
445 * @brief GetTransMsgType
446 * 0x00 is point to point message
447 * 0x01 is broadcast message
448 * 0x02 is ack message
449 * 0x03 is unkown message
450 * @return CdmaTransportMsgType
451 */
452CdmaTransportMsgType CdmaSmsMessage::GetTransMsgType() const
453{
454    if (transMsg_ == nullptr) {
455        TELEPHONY_LOGE("Trans message type unkown!");
456        return CdmaTransportMsgType::RESERVED;
457    }
458
459    return transMsg_->type;
460}
461
462/**
463 * @brief Get the Trans Tele Service object
464 * 0x1000 IS-91 Extended Protocol Enhanced Services
465 * 0x1001 Wireless Paging Teleservice
466 * 0x1002 Wireless Messaging Teleservice
467 * 0x1003 Voice Mail Notification
468 * 0x1004 Wireless Application Protocol
469 * 0x1005 Wireless Enhanced Messaging Teleservice
470 * 0x1006 Service Category Programming Teleservice
471 * 0x1007 Card Application Toolkit Protocol Teleservice
472 * 0xffff
473 * @return int
474 */
475int CdmaSmsMessage::GetTransTeleService() const
476{
477    if ((transMsg_ == nullptr) || (transMsg_->type != CdmaTransportMsgType::P2P)) {
478        TELEPHONY_LOGE("Trans Tele Service is error");
479        return static_cast<int>(SmsTransTelsvcId::RESERVED);
480    }
481
482    return transMsg_->data.p2p.teleserviceId;
483}
484
485int CdmaSmsMessage::GetProtocolId() const
486{
487    return 0;
488}
489
490bool CdmaSmsMessage::IsReplaceMessage()
491{
492    return false;
493}
494
495bool CdmaSmsMessage::IsCphsMwi() const
496{
497    return false;
498}
499
500bool CdmaSmsMessage::IsWapPushMsg()
501{
502    if (transMsg_ == nullptr) {
503        return false;
504    }
505
506    if (transMsg_->type == CdmaTransportMsgType::P2P) {
507        return (transMsg_->data.p2p.teleserviceId == static_cast<uint16_t>(SmsTransTelsvcId::WAP));
508    }
509    return false;
510}
511
512std::shared_ptr<SpecialSmsIndication> CdmaSmsMessage::GetSpecialSmsInd()
513{
514    return specialSmsInd_;
515}
516
517bool CdmaSmsMessage::IsStatusReport() const
518{
519    return (transMsg_->data.p2p.telesvcMsg.type == TeleserviceMsgType::DELIVERY_ACK);
520}
521
522int16_t CdmaSmsMessage::GetDestPort() const
523{
524    return destPort_;
525}
526
527bool CdmaSmsMessage::IsBroadcastMsg() const
528{
529    return GetTransMsgType() == CdmaTransportMsgType::BROADCAST;
530}
531
532int CdmaSmsMessage::DecodeMessage(uint8_t *decodeData, unsigned int len, DataCodingScheme &codingType,
533    const std::string &msgText, bool &bAbnormal, MSG_LANGUAGE_ID_T &langId)
534{
535    int decodeLen = 0;
536    int dataLen = static_cast<int>(msgText.length());
537    const unsigned int maxDecodeLen = len;
538    const unsigned char *pMsgText = reinterpret_cast<const unsigned char *>(msgText.c_str());
539
540    if (msgText.empty()) {
541        TELEPHONY_LOGE("MsgText is empty!");
542        return decodeLen;
543    }
544
545    switch (codingType) {
546        case DATA_CODING_7BIT: {
547            if (static_cast<unsigned int>(dataLen) > maxDecodeLen) {
548                TELEPHONY_LOGE("DecodeMessage memcpy_s data length invalid.");
549                return decodeLen;
550            }
551            if (memcpy_s(decodeData, maxDecodeLen, pMsgText, dataLen) != EOK) {
552                TELEPHONY_LOGE("SplitMessage SMS_CHARSET_8BIT memcpy_s error!");
553                return decodeLen;
554            }
555            decodeLen = dataLen;
556            codingType = DATA_CODING_ASCII7BIT;
557            break;
558        }
559        case DATA_CODING_8BIT: {
560            if (memcpy_s(decodeData, maxDecodeLen, pMsgText, dataLen) != EOK) {
561                TELEPHONY_LOGE("SplitMessage SMS_CHARSET_8BIT memcpy_s error!");
562                return decodeLen;
563            }
564            decodeLen = dataLen;
565            break;
566        }
567        case DATA_CODING_UCS2: {
568            decodeLen = TextCoder::Instance().Utf8ToUcs2(decodeData, maxDecodeLen, pMsgText, dataLen);
569            break;
570        }
571        case DATA_CODING_AUTO:
572        default: {
573            decodeLen = TextCoder::Instance().CdmaUtf8ToAuto(decodeData, maxDecodeLen, pMsgText, dataLen, codingType);
574            break;
575        }
576    }
577    return decodeLen;
578}
579
580int8_t CdmaSmsMessage::GetCMASCategory() const
581{
582    return category_;
583}
584
585int8_t CdmaSmsMessage::GetCMASResponseType() const
586{
587    return responseType_;
588}
589
590int8_t CdmaSmsMessage::GetCMASSeverity() const
591{
592    return severity_;
593}
594
595int8_t CdmaSmsMessage::GetCMASUrgency() const
596{
597    return urgency_;
598}
599
600int8_t CdmaSmsMessage::GetCMASCertainty() const
601{
602    return certainty_;
603}
604
605int8_t CdmaSmsMessage::GetCMASMessageClass() const
606{
607    return messageClass_;
608}
609
610bool CdmaSmsMessage::IsCMAS() const
611{
612    return isCmas_;
613}
614
615uint16_t CdmaSmsMessage::GetMessageId() const
616{
617    return messageId_;
618}
619
620int8_t CdmaSmsMessage::GetFormat() const
621{
622    constexpr int8_t FORMAT_3GPP2 = 2;
623    return FORMAT_3GPP2;
624}
625
626int8_t CdmaSmsMessage::GetLanguage() const
627{
628    return language_;
629}
630
631std::string CdmaSmsMessage::GetCbInfo() const
632{
633    std::string info;
634    info.append("isCmas:")
635        .append(isCmas_ ? "true" : "false")
636        .append("\n")
637        .append("format:")
638        .append(std::to_string(GetFormat()))
639        .append("\n")
640        .append("messageId:")
641        .append(std::to_string(messageId_))
642        .append("\n")
643        .append("serviceCategory:")
644        .append(std::to_string(category_))
645        .append("\n")
646        .append("language:")
647        .append(std::to_string(language_))
648        .append("\n")
649        .append("body:")
650        .append(visibleMessageBody_)
651        .append("\n")
652        .append("priority:")
653        .append(std::to_string(priority_))
654        .append("\n")
655        .append("responseType:")
656        .append(std::to_string(responseType_))
657        .append("\n")
658        .append("severity:")
659        .append(std::to_string(severity_))
660        .append("\n")
661        .append("urgency:")
662        .append(std::to_string(urgency_))
663        .append("\n")
664        .append("certainty:")
665        .append(std::to_string(certainty_))
666        .append("\n")
667        .append("messageClass:")
668        .append(std::to_string(messageClass_))
669        .append("\n")
670        .append("serviceCategory:")
671        .append(std::to_string(serviceCategory_));
672    return info;
673}
674
675int8_t CdmaSmsMessage::GetPriority() const
676{
677    return priority_;
678}
679
680bool CdmaSmsMessage::IsEmergencyMsg() const
681{
682    return priority_ == static_cast<int8_t>(SmsPriorityIndicator::EMERGENCY);
683}
684
685uint16_t CdmaSmsMessage::GetServiceCategoty() const
686{
687    return serviceCategory_;
688}
689
690uint8_t CdmaSmsMessage::GetGeoScope() const
691{
692    const uint8_t scopePlmnWide = 1;
693    return scopePlmnWide;
694}
695
696int64_t CdmaSmsMessage::GetReceTime() const
697{
698    return scTimestamp_;
699}
700} // namespace Telephony
701} // namespace OHOS
702