• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 namespace OHOS {
25 namespace Telephony {
26 static constexpr uint16_t CDMA_MAX_UD_HEADER_NUM = 7;
27 
CreateSubmitTransMsg(const std::string & dest,const std::string & sc,const std::string & text,bool bStatusReport,const DataCodingScheme codingScheme)28 std::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 
CreateSubmitTransMsg(const std::string & dest,const std::string & sc,int32_t port,const uint8_t * data,uint32_t dataLen,bool bStatusReport)62 std::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 
GreateTransMsg()100 std::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 
CovertEncodingType(const DataCodingScheme & codingScheme)129 SmsEncodingType 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 
CreateMessage(const std::string & pdu)150 std::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 
PduAnalysis(const std::string & pduHex)170 bool 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 
AnalysisP2pMsg(const CdmaP2PMsg & p2pMsg)212 void 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 
AnalsisDeliverMwi(const CdmaP2PMsg & p2pMsg)254 void 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 
AnalsisDeliverMsg(const TeleserviceDeliver & deliver)286 void 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 
AnalsisDeliverAck(const TeleserviceDeliverAck & deliverAck)300 void CdmaSmsMessage::AnalsisDeliverAck(const TeleserviceDeliverAck &deliverAck)
301 {
302     bStatusReportMessage_ = true;
303     scTimestamp_ = SmsCommonUtils::ConvertTime(deliverAck.timeStamp);
304     AnalsisUserData(deliverAck.userData);
305 }
306 
AnalsisSubmitReport(const TeleserviceDeliverReport & report)307 void CdmaSmsMessage::AnalsisSubmitReport(const TeleserviceDeliverReport &report)
308 {
309     AnalsisUserData(report.userData);
310 }
311 
AnalsisSubmitMsg(const TeleserviceSubmit & submit)312 void 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 
AnalsisUserData(const SmsTeleSvcUserData & userData)320 void 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             dataSize = userData.userData.length;
346             if (dataSize >= MAX_MSG_TEXT_LEN + 1 ||
347                 memcpy_s(buff, sizeof(buff), userData.userData.data, dataSize) != EOK) {
348                 TELEPHONY_LOGE("AnalsisDeliverMsg memcpy_s fail.");
349                 return;
350             }
351             buff[dataSize] = '\0';
352             break;
353         }
354         case SmsEncodingType::SHIFT_JIS: {
355             dataSize = TextCoder::Instance().ShiftjisToUtf8(
356                 buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData.data, userData.userData.length);
357             break;
358         }
359         default: {
360             dataSize = TextCoder::Instance().Ucs2ToUtf8(
361                 buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData.data, userData.userData.length);
362             break;
363         }
364     }
365     visibleMessageBody_.insert(0, reinterpret_cast<char *>(buff), dataSize);
366 }
367 
AnalsisCMASMsg(const TeleserviceDeliver & deliver)368 void CdmaSmsMessage::AnalsisCMASMsg(const TeleserviceDeliver &deliver)
369 {
370     isCmas_ = true;
371     category_ = static_cast<int8_t>(deliver.cmasData.category);
372     responseType_ = static_cast<int8_t>(deliver.cmasData.responseType);
373     severity_ = static_cast<int8_t>(deliver.cmasData.severity);
374     urgency_ = static_cast<int8_t>(deliver.cmasData.urgency);
375     certainty_ = static_cast<int8_t>(deliver.cmasData.certainty);
376     messageClass_ = static_cast<int8_t>(deliver.cmasData.alertHandle);
377     msgClass_ = SMS_CLASS_UNKNOWN;
378     scTimestamp_ = SmsCommonUtils::ConvertTime(deliver.timeStamp);
379     SmsTeleSvcUserData userData;
380     (void)memset_s(&userData, sizeof(SmsTeleSvcUserData), 0x00, sizeof(SmsTeleSvcUserData));
381     userData.userData.length = deliver.cmasData.dataLen;
382     userData.encodeType = deliver.cmasData.encodeType;
383     if (deliver.cmasData.dataLen > sizeof(userData.userData.data)) {
384         TELEPHONY_LOGE("AnalsisCMASMsg memcpy_s data length invalid.");
385         return;
386     }
387     if (memcpy_s(userData.userData.data, sizeof(userData.userData.data), deliver.cmasData.alertText,
388             deliver.cmasData.dataLen) == EOK) {
389         AnalsisUserData(userData);
390     }
391 }
392 
AnalysisCbMsg(const CdmaBroadCastMsg & cbMsg)393 void CdmaSmsMessage::AnalysisCbMsg(const CdmaBroadCastMsg &cbMsg)
394 {
395     serviceCategory_ = cbMsg.serviceCtg;
396     if (cbMsg.telesvcMsg.type != TeleserviceMsgType::DELIVER) {
397         TELEPHONY_LOGE("No matching type = [%{public}d]", static_cast<int>(cbMsg.telesvcMsg.type));
398         return;
399     }
400     messageId_ = cbMsg.telesvcMsg.data.deliver.msgId.msgId;
401     priority_ = static_cast<int8_t>(cbMsg.telesvcMsg.data.deliver.priority);
402     language_ = static_cast<uint8_t>(cbMsg.telesvcMsg.data.deliver.language);
403     TELEPHONY_LOGI("analysisCbMsg serviceCtg %{public}hu", cbMsg.serviceCtg);
404     if ((cbMsg.serviceCtg >= static_cast<uint16_t>(SmsServiceCtg::CMAS_PRESIDENTIAL)) &&
405         (cbMsg.serviceCtg <= static_cast<uint16_t>(SmsServiceCtg::CMAS_TEST))) {
406         AnalsisCMASMsg(cbMsg.telesvcMsg.data.deliver);
407     } else {
408         AnalsisDeliverMsg(cbMsg.telesvcMsg.data.deliver);
409     }
410 }
411 
AnalsisAckMsg(const CdmaAckMsg & ackMsg)412 void CdmaSmsMessage::AnalsisAckMsg(const CdmaAckMsg &ackMsg)
413 {
414     originatingAddress_ = ackMsg.address.szData;
415 }
416 
AddUserDataHeader(const struct SmsUDH & header)417 bool CdmaSmsMessage::AddUserDataHeader(const struct SmsUDH &header)
418 {
419     if (userHeaders_.size() >= CDMA_MAX_UD_HEADER_NUM) {
420         return false;
421     }
422 
423     userHeaders_.push_back(header);
424     return true;
425 }
426 
AnalsisHeader(const SmsTeleSvcUserData & userData)427 void CdmaSmsMessage::AnalsisHeader(const SmsTeleSvcUserData &userData)
428 {
429     if (memset_s(&smsUserData_, sizeof(SmsUDPackage), 0x00, sizeof(SmsUDPackage)) != EOK) {
430         return;
431     }
432     headerDataLen_ = userData.userData.length;
433     if (memcpy_s(&smsUserData_, sizeof(SmsUDPackage), &(userData.userData), sizeof(SmsUDPackage)) != EOK) {
434         return;
435     }
436 
437     if (bHeaderInd_ && userData.userData.headerCnt > 0) {
438         userHeaders_.clear();
439         for (int i = 0; i < userData.userData.headerCnt; i++) {
440             userHeaders_.push_back(userData.userData.header[i]);
441         }
442     }
443 }
444 
445 /**
446  * @brief GetTransMsgType
447  * 0x00 is point to point message
448  * 0x01 is broadcast message
449  * 0x02 is ack message
450  * 0x03 is unkown message
451  * @return CdmaTransportMsgType
452  */
GetTransMsgType() const453 CdmaTransportMsgType CdmaSmsMessage::GetTransMsgType() const
454 {
455     if (transMsg_ == nullptr) {
456         TELEPHONY_LOGE("Trans message type unkown!");
457         return CdmaTransportMsgType::RESERVED;
458     }
459 
460     return transMsg_->type;
461 }
462 
463 /**
464  * @brief Get the Trans Tele Service object
465  * 0x1000 IS-91 Extended Protocol Enhanced Services
466  * 0x1001 Wireless Paging Teleservice
467  * 0x1002 Wireless Messaging Teleservice
468  * 0x1003 Voice Mail Notification
469  * 0x1004 Wireless Application Protocol
470  * 0x1005 Wireless Enhanced Messaging Teleservice
471  * 0x1006 Service Category Programming Teleservice
472  * 0x1007 Card Application Toolkit Protocol Teleservice
473  * 0xffff
474  * @return int
475  */
GetTransTeleService() const476 int CdmaSmsMessage::GetTransTeleService() const
477 {
478     if ((transMsg_ == nullptr) || (transMsg_->type != CdmaTransportMsgType::P2P)) {
479         TELEPHONY_LOGE("Trans Tele Service is error");
480         return static_cast<int>(SmsTransTelsvcId::RESERVED);
481     }
482 
483     return transMsg_->data.p2p.teleserviceId;
484 }
485 
GetProtocolId() const486 int CdmaSmsMessage::GetProtocolId() const
487 {
488     return 0;
489 }
490 
IsReplaceMessage()491 bool CdmaSmsMessage::IsReplaceMessage()
492 {
493     return false;
494 }
495 
IsCphsMwi() const496 bool CdmaSmsMessage::IsCphsMwi() const
497 {
498     return false;
499 }
500 
IsWapPushMsg()501 bool CdmaSmsMessage::IsWapPushMsg()
502 {
503     if (transMsg_ == nullptr) {
504         return false;
505     }
506 
507     if (transMsg_->type == CdmaTransportMsgType::P2P) {
508         return (transMsg_->data.p2p.teleserviceId == static_cast<uint16_t>(SmsTransTelsvcId::WAP));
509     }
510     return false;
511 }
512 
GetSpecialSmsInd()513 std::shared_ptr<SpecialSmsIndication> CdmaSmsMessage::GetSpecialSmsInd()
514 {
515     return specialSmsInd_;
516 }
517 
IsStatusReport() const518 bool CdmaSmsMessage::IsStatusReport() const
519 {
520     return (transMsg_->data.p2p.telesvcMsg.type == TeleserviceMsgType::DELIVERY_ACK);
521 }
522 
GetDestPort() const523 int16_t CdmaSmsMessage::GetDestPort() const
524 {
525     return destPort_;
526 }
527 
IsBroadcastMsg() const528 bool CdmaSmsMessage::IsBroadcastMsg() const
529 {
530     return GetTransMsgType() == CdmaTransportMsgType::BROADCAST;
531 }
532 
DecodeMessage(uint8_t * decodeData,unsigned int len,DataCodingScheme & codingType,const std::string & msgText,bool & bAbnormal,MSG_LANGUAGE_ID_T & langId)533 int CdmaSmsMessage::DecodeMessage(uint8_t *decodeData, unsigned int len, DataCodingScheme &codingType,
534     const std::string &msgText, bool &bAbnormal, MSG_LANGUAGE_ID_T &langId)
535 {
536     int decodeLen = 0;
537     int dataLen = static_cast<int>(msgText.length());
538     const unsigned int maxDecodeLen = len;
539     const unsigned char *pMsgText = reinterpret_cast<const unsigned char *>(msgText.c_str());
540 
541     if (msgText.empty()) {
542         TELEPHONY_LOGE("MsgText is empty!");
543         return decodeLen;
544     }
545 
546     switch (codingType) {
547         case DATA_CODING_7BIT: {
548             if (static_cast<unsigned int>(dataLen) > maxDecodeLen) {
549                 TELEPHONY_LOGE("DecodeMessage memcpy_s data length invalid.");
550                 return decodeLen;
551             }
552             if (memcpy_s(decodeData, maxDecodeLen, pMsgText, dataLen) != EOK) {
553                 TELEPHONY_LOGE("SplitMessage SMS_CHARSET_8BIT memcpy_s error!");
554                 return decodeLen;
555             }
556             decodeLen = dataLen;
557             codingType = DATA_CODING_ASCII7BIT;
558             break;
559         }
560         case DATA_CODING_8BIT: {
561             if (memcpy_s(decodeData, maxDecodeLen, pMsgText, dataLen) != EOK) {
562                 TELEPHONY_LOGE("SplitMessage SMS_CHARSET_8BIT memcpy_s error!");
563                 return decodeLen;
564             }
565             decodeLen = dataLen;
566             break;
567         }
568         case DATA_CODING_UCS2: {
569             decodeLen = TextCoder::Instance().Utf8ToUcs2(decodeData, maxDecodeLen, pMsgText, dataLen);
570             break;
571         }
572         case DATA_CODING_AUTO:
573         default: {
574             decodeLen = TextCoder::Instance().CdmaUtf8ToAuto(decodeData, maxDecodeLen, pMsgText, dataLen, codingType);
575             break;
576         }
577     }
578     return decodeLen;
579 }
580 
GetCMASCategory() const581 int8_t CdmaSmsMessage::GetCMASCategory() const
582 {
583     return category_;
584 }
585 
GetCMASResponseType() const586 int8_t CdmaSmsMessage::GetCMASResponseType() const
587 {
588     return responseType_;
589 }
590 
GetCMASSeverity() const591 int8_t CdmaSmsMessage::GetCMASSeverity() const
592 {
593     return severity_;
594 }
595 
GetCMASUrgency() const596 int8_t CdmaSmsMessage::GetCMASUrgency() const
597 {
598     return urgency_;
599 }
600 
GetCMASCertainty() const601 int8_t CdmaSmsMessage::GetCMASCertainty() const
602 {
603     return certainty_;
604 }
605 
GetCMASMessageClass() const606 int8_t CdmaSmsMessage::GetCMASMessageClass() const
607 {
608     return messageClass_;
609 }
610 
IsCMAS() const611 bool CdmaSmsMessage::IsCMAS() const
612 {
613     return isCmas_;
614 }
615 
GetMessageId() const616 uint16_t CdmaSmsMessage::GetMessageId() const
617 {
618     return messageId_;
619 }
620 
GetFormat() const621 int8_t CdmaSmsMessage::GetFormat() const
622 {
623     constexpr int8_t FORMAT_3GPP2 = 2;
624     return FORMAT_3GPP2;
625 }
626 
GetLanguage() const627 int8_t CdmaSmsMessage::GetLanguage() const
628 {
629     return language_;
630 }
631 
GetCbInfo() const632 std::string CdmaSmsMessage::GetCbInfo() const
633 {
634     std::string info;
635     info.append("isCmas:")
636         .append(isCmas_ ? "true" : "false")
637         .append("\n")
638         .append("format:")
639         .append(std::to_string(GetFormat()))
640         .append("\n")
641         .append("messageId:")
642         .append(std::to_string(messageId_))
643         .append("\n")
644         .append("serviceCategory:")
645         .append(std::to_string(category_))
646         .append("\n")
647         .append("language:")
648         .append(std::to_string(language_))
649         .append("\n")
650         .append("body:")
651         .append(visibleMessageBody_)
652         .append("\n")
653         .append("priority:")
654         .append(std::to_string(priority_))
655         .append("\n")
656         .append("responseType:")
657         .append(std::to_string(responseType_))
658         .append("\n")
659         .append("severity:")
660         .append(std::to_string(severity_))
661         .append("\n")
662         .append("urgency:")
663         .append(std::to_string(urgency_))
664         .append("\n")
665         .append("certainty:")
666         .append(std::to_string(certainty_))
667         .append("\n")
668         .append("messageClass:")
669         .append(std::to_string(messageClass_))
670         .append("\n")
671         .append("serviceCategory:")
672         .append(std::to_string(serviceCategory_));
673     return info;
674 }
675 
GetPriority() const676 int8_t CdmaSmsMessage::GetPriority() const
677 {
678     return priority_;
679 }
680 
IsEmergencyMsg() const681 bool CdmaSmsMessage::IsEmergencyMsg() const
682 {
683     return priority_ == static_cast<int8_t>(SmsPriorityIndicator::EMERGENCY);
684 }
685 
GetServiceCategoty() const686 uint16_t CdmaSmsMessage::GetServiceCategoty() const
687 {
688     return serviceCategory_;
689 }
690 
GetGeoScope() const691 uint8_t CdmaSmsMessage::GetGeoScope() const
692 {
693     const uint8_t scopePlmnWide = 1;
694     return scopePlmnWide;
695 }
696 
GetReceTime() const697 int64_t CdmaSmsMessage::GetReceTime() const
698 {
699     return scTimestamp_;
700 }
701 } // namespace Telephony
702 } // namespace OHOS
703