• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "msg_text_convert.h"
19 #include "securec.h"
20 #include "sms_common_utils.h"
21 #include "string_utils.h"
22 #include "telephony_log_wrapper.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 SmsCodingScheme codingScheme)28 std::unique_ptr<SmsTransMsg> CdmaSmsMessage::CreateSubmitTransMsg(const std::string &dest, const std::string &sc,
29     const std::string &text, bool bStatusReport, const SmsCodingScheme codingScheme)
30 {
31     std::unique_ptr<SmsTransMsg> 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.p2pMsg.telesvcMsg.data.submit.userData.encodeType = CovertEncodingType(codingScheme);
41     /* Set Reply option */
42     transMsg->data.p2pMsg.telesvcMsg.data.submit.replyOpt.deliverAckReq = bStatusReport;
43     /* Convert Address values */
44     transMsg->data.p2pMsg.address.digitMode = SMS_DIGIT_4BIT_DTMF;
45     transMsg->data.p2pMsg.address.numberMode = SMS_NUMBER_MODE_NONE_DATANETWORK;
46     transMsg->data.p2pMsg.address.numberPlan = SMS_NPI_UNKNOWN;
47     transMsg->data.p2pMsg.address.addrLen = dest.length();
48     if (strncpy_s(transMsg->data.p2pMsg.address.szData, sizeof(transMsg->data.p2pMsg.address.szData), dest.c_str(),
49             dest.length()) != EOK) {
50         transMsg->data.p2pMsg.address.addrLen = sizeof(transMsg->data.p2pMsg.address.szData) - 1;
51         transMsg->data.p2pMsg.address.szData[transMsg->data.p2pMsg.address.addrLen] = '\0';
52     }
53     if (dest.at(0) == '+') {
54         transMsg->data.p2pMsg.address.digitMode = SMS_DIGIT_8BIT;
55         transMsg->data.p2pMsg.address.numberType = SMS_NUMBER_TYPE_INTERNATIONAL;
56     } else {
57         transMsg->data.p2pMsg.address.numberType = SMS_NUMBER_TYPE_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<SmsTransMsg> 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<SmsTransMsg> 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.p2pMsg.telesvcMsg.data.submit.replyOpt.deliverAckReq = bStatusReport;
77     /* Convert Address values */
78     transMsg->data.p2pMsg.address.digitMode = SMS_DIGIT_4BIT_DTMF;
79     transMsg->data.p2pMsg.address.numberMode = SMS_NUMBER_MODE_NONE_DATANETWORK;
80     transMsg->data.p2pMsg.address.numberPlan = SMS_NPI_UNKNOWN;
81     transMsg->data.p2pMsg.address.addrLen = dest.length();
82     if (dest.length() > SMS_TRANS_ADDRESS_MAX_LEN + 1) {
83         TELEPHONY_LOGE("CreateSubmitTransMsg data length invalid.");
84         return nullptr;
85     }
86     if (strncpy_s(transMsg->data.p2pMsg.address.szData, sizeof(transMsg->data.p2pMsg.address.szData), dest.c_str(),
87             dest.length()) != EOK) {
88         transMsg->data.p2pMsg.address.addrLen = sizeof(transMsg->data.p2pMsg.address.szData) - 1;
89         transMsg->data.p2pMsg.address.szData[transMsg->data.p2pMsg.address.addrLen] = '\0';
90     }
91     if (dest.at(0) == '+') {
92         transMsg->data.p2pMsg.address.digitMode = SMS_DIGIT_8BIT;
93         transMsg->data.p2pMsg.address.numberType = SMS_NUMBER_TYPE_INTERNATIONAL;
94     } else {
95         transMsg->data.p2pMsg.address.numberType = SMS_NUMBER_TYPE_NATIONAL;
96     }
97     return transMsg;
98 }
99 
GreateTransMsg()100 std::unique_ptr<struct SmsTransMsg> CdmaSmsMessage::GreateTransMsg()
101 {
102     std::unique_ptr<SmsTransMsg> transMsg = std::make_unique<SmsTransMsg>();
103     if (transMsg == nullptr) {
104         TELEPHONY_LOGE("CreateMessage message transMsg nullptr");
105         return nullptr;
106     }
107     (void)memset_s(transMsg.get(), sizeof(SmsTransMsg), 0x00, sizeof(SmsTransMsg));
108     transMsg->type = (SmsTransMsgType)SMS_TRANS_P2P_MSG;
109     transMsg->data.p2pMsg.telesvcMsg.type = (SmsMessageType)SMS_TYPE_SUBMIT;
110     /* 1. Set Teleservice ID */
111     transMsg->data.p2pMsg.transTelesvcId = SMS_TRANS_TELESVC_CMT_95;
112     /* 2. Set Service category */
113     transMsg->data.p2pMsg.transSvcCtg = SMS_TRANS_SVC_CTG_UNDEFINED;
114 
115     /* 3. Set Valid period */
116     transMsg->data.p2pMsg.telesvcMsg.data.submit.valPeriod.format = SMS_TIME_RELATIVE;
117     transMsg->data.p2pMsg.telesvcMsg.data.submit.valPeriod.time.relTime.time = SMS_REL_TIME_INDEFINITE;
118     /* 4. Set Priority */
119     transMsg->data.p2pMsg.telesvcMsg.data.submit.priority = SMS_PRIORITY_NORMAL;
120     /* 5. Set Privacy */
121     transMsg->data.p2pMsg.telesvcMsg.data.submit.privacy = SMS_PRIVACY_NOT_RESTRICTED;
122     /* 6. Set Alert priority */
123     transMsg->data.p2pMsg.telesvcMsg.data.submit.alertPriority = SMS_ALERT_MOBILE_DEFAULT;
124     /* 7. Set Language */
125     transMsg->data.p2pMsg.telesvcMsg.data.submit.language = SMS_LAN_UNKNOWN;
126     return transMsg;
127 }
128 
CovertEncodingType(const SmsCodingScheme & codingScheme)129 SmsEncodingType CdmaSmsMessage::CovertEncodingType(const SmsCodingScheme &codingScheme)
130 {
131     SmsEncodingType encodingType = SMS_ENCODE_7BIT_ASCII;
132     switch (codingScheme) {
133         case SMS_CODING_7BIT:
134             encodingType = SMS_ENCODE_GSM7BIT;
135             break;
136         case SMS_CODING_ASCII7BIT:
137             encodingType = SMS_ENCODE_7BIT_ASCII;
138             break;
139         case SMS_CODING_8BIT:
140             encodingType = SMS_ENCODE_OCTET;
141             break;
142         case SMS_CODING_UCS2:
143         default:
144             encodingType = SMS_ENCODE_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 SmsTransMsg>();
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 SmsTransMsg), 0x00, sizeof(struct SmsTransMsg));
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     rawPdu_ = StringUtils::HexToByteVector(pduHex);
178     if (!CdmaSmsPduCodec::CheckInvalidPDU(rawPdu_)) {
179         TELEPHONY_LOGE("PduAnalysis is unInvalid pdu data!");
180         return false;
181     }
182 
183     int decodeLen = 0;
184     std::string pdu = StringUtils::HexToString(pduHex);
185     decodeLen =
186         CdmaSmsPduCodec::DecodeMsg(reinterpret_cast<const unsigned char *>(pdu.c_str()), pdu.length(), *transMsg_);
187     if (decodeLen <= 0) {
188         TELEPHONY_LOGE("Pdu DecodeMsg has failure.");
189         return false;
190     }
191     if (transMsg_->type == SMS_TRANS_BROADCAST_MSG) {
192         if (transMsg_->data.cbMsg.telesvcMsg.data.deliver.cmasData.isWrongRecodeType) {
193             TELEPHONY_LOGE("Invalid CMAS Record Type");
194             return false;
195         }
196         SmsEncodingType encodeType = transMsg_->data.cbMsg.telesvcMsg.data.deliver.cmasData.encodeType;
197         if ((encodeType == SMS_ENCODE_KOREAN) || (encodeType == SMS_ENCODE_GSMDCS)) {
198             TELEPHONY_LOGE("This encode type is not supported [%{public}d]", encodeType);
199             return false;
200         }
201     }
202     switch (transMsg_->type) {
203         case SMS_TRANS_P2P_MSG:
204             AnalysisP2pMsg(transMsg_->data.p2pMsg);
205             break;
206         case SMS_TRANS_BROADCAST_MSG:
207             AnalysisCbMsg(transMsg_->data.cbMsg);
208             break;
209         case SMS_TRANS_ACK_MSG:
210             AnalsisAckMsg(transMsg_->data.ackMsg);
211             break;
212         default:
213             return false;
214     }
215     return true;
216 }
217 
AnalysisP2pMsg(const SmsTransP2PMsg & p2pMsg)218 void CdmaSmsMessage::AnalysisP2pMsg(const SmsTransP2PMsg &p2pMsg)
219 {
220     if (p2pMsg.transTelesvcId == SMS_TRANS_TELESVC_RESERVED) {
221         TELEPHONY_LOGE("this Incoming Message has Unknown Teleservice ID");
222         return;
223     }
224 
225     address_ = std::make_unique<struct SmsTransAddr>();
226     if (address_ == nullptr) {
227         TELEPHONY_LOGE("AnalysisP2pMsg make address == nullptr");
228         return;
229     }
230 
231     if (memcpy_s(address_.get(), sizeof(SmsTransAddr), &p2pMsg.address, sizeof(SmsTransAddr)) != EOK) {
232         TELEPHONY_LOGE("AnalysisP2pMsg address memcpy_s error.");
233         return;
234     }
235 
236     originatingAddress_ = address_->szData;
237     switch (p2pMsg.telesvcMsg.type) {
238         case SmsMessageType::SMS_TYPE_DELIVER:
239             AnalsisDeliverMwi(p2pMsg);
240             AnalsisDeliverMsg(p2pMsg.telesvcMsg.data.deliver);
241             break;
242         case SmsMessageType::SMS_TYPE_DELIVERY_ACK:
243             AnalsisDeliverAck(p2pMsg.telesvcMsg.data.deliveryAck);
244             break;
245         case SmsMessageType::SMS_TYPE_USER_ACK:
246         case SmsMessageType::SMS_TYPE_READ_ACK:
247             break;
248         case SmsMessageType::SMS_TYPE_SUBMIT_REPORT:
249             AnalsisSubmitReport(p2pMsg.telesvcMsg.data.report);
250             break;
251         case SmsMessageType::SMS_TYPE_SUBMIT:
252             AnalsisSubmitMsg(p2pMsg.telesvcMsg.data.submit);
253             break;
254         default:
255             TELEPHONY_LOGI("AnalysisP2pMsg unkown type =%{public}d", p2pMsg.telesvcMsg.type);
256             break;
257     }
258 }
259 
AnalsisDeliverMwi(const SmsTransP2PMsg & p2pMsg)260 void CdmaSmsMessage::AnalsisDeliverMwi(const SmsTransP2PMsg &p2pMsg)
261 {
262     specialSmsInd_ = nullptr;
263     if (p2pMsg.transTelesvcId == SMS_TRANS_TELESVC_VMN_95) {
264         specialSmsInd_ = std::make_shared<SpecialSmsIndication>();
265         if (specialSmsInd_ == nullptr) {
266             TELEPHONY_LOGE("SpecialSmsIndication is null!");
267             return;
268         }
269 
270         specialSmsInd_->msgInd = SMS_VOICE_INDICATOR;
271         if (p2pMsg.telesvcMsg.data.deliver.enhancedVmn.faxIncluded) {
272             specialSmsInd_->msgInd = SMS_FAX_INDICATOR;
273         }
274 
275         if (p2pMsg.telesvcMsg.data.deliver.numMsg < 0) {
276             specialSmsInd_->waitMsgNum = 0;
277             bMwiClear_ = true;
278             bMwiSet_ = false;
279         } else {
280             specialSmsInd_->waitMsgNum = p2pMsg.telesvcMsg.data.deliver.numMsg;
281             bMwiClear_ = false;
282             bMwiSet_ = true;
283         }
284 
285         bMwiNotStore_ = false;
286         if (bMwiSet_ && (p2pMsg.telesvcMsg.data.deliver.userData.userData.length == 0)) {
287             bMwiNotStore_ = true;
288         }
289     }
290 }
291 
AnalsisDeliverMsg(const SmsTeleSvcDeliver & deliver)292 void CdmaSmsMessage::AnalsisDeliverMsg(const SmsTeleSvcDeliver &deliver)
293 {
294     isCmas_ = false;
295     msgClass_ = SMS_CLASS_UNKNOWN;
296     if (deliver.displayMode == SMS_DISPLAY_IMMEDIATE) {
297         msgClass_ = SMS_INSTANT_MESSAGE;
298     }
299 
300     msgRef_ = deliver.msgId.msgId;
301     bHeaderInd_ = deliver.msgId.headerInd;
302     scTimestamp_ = SmsCommonUtils::ConvertTime(deliver.timeStamp);
303     AnalsisUserData(deliver.userData);
304 }
305 
AnalsisDeliverAck(const SmsTeleSvcDeliverAck & deliverAck)306 void CdmaSmsMessage::AnalsisDeliverAck(const SmsTeleSvcDeliverAck &deliverAck)
307 {
308     bStatusReportMessage_ = true;
309     scTimestamp_ = SmsCommonUtils::ConvertTime(deliverAck.timeStamp);
310     AnalsisUserData(deliverAck.userData);
311 }
312 
AnalsisSubmitReport(const SmsTeleSvcDeliverReport & report)313 void CdmaSmsMessage::AnalsisSubmitReport(const SmsTeleSvcDeliverReport &report)
314 {
315     AnalsisUserData(report.userData);
316 }
317 
AnalsisSubmitMsg(const SmsTeleSvcSubmit & submit)318 void CdmaSmsMessage::AnalsisSubmitMsg(const SmsTeleSvcSubmit &submit)
319 {
320     msgRef_ = submit.msgId.msgId;
321     bHeaderInd_ = submit.msgId.headerInd;
322     scTimestamp_ = SmsCommonUtils::ConvertTime(submit.valPeriod.time.absTime);
323     AnalsisUserData(submit.userData);
324 }
325 
AnalsisUserData(const SmsTeleSvcUserData & userData)326 void CdmaSmsMessage::AnalsisUserData(const SmsTeleSvcUserData &userData)
327 {
328     int dataSize = 0;
329     MsgLangInfo langinfo = {
330         0,
331     };
332     AnalsisHeader(userData);
333     MsgTextConvert *textCvt = MsgTextConvert::Instance();
334     if (textCvt == nullptr) {
335         return;
336     }
337     unsigned char buff[MAX_MSG_TEXT_LEN + 1] = { 0 };
338     switch (userData.encodeType) {
339         case SMS_ENCODE_GSM7BIT: {
340             dataSize = textCvt->ConvertGSM7bitToUTF8(
341                 buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData, userData.userData.length, &langinfo);
342             break;
343         }
344         case SMS_ENCODE_KOREAN:
345         case SMS_ENCODE_EUCKR: {
346             dataSize = textCvt->ConvertEUCKRToUTF8(
347                 buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData, userData.userData.length);
348             break;
349         }
350         case SMS_ENCODE_IA5:
351         case SMS_ENCODE_7BIT_ASCII:
352         case SMS_ENCODE_LATIN_HEBREW:
353         case SMS_ENCODE_LATIN:
354         case SMS_ENCODE_OCTET: {
355             if (memcpy_s(buff, sizeof(buff), userData.userData.data, userData.userData.length) != EOK) {
356                 TELEPHONY_LOGE("AnalsisDeliverMsg memcpy_s fail.");
357                 return;
358             }
359             dataSize = userData.userData.length;
360             buff[dataSize] = '\0';
361             break;
362         }
363         case SMS_ENCODE_SHIFT_JIS: {
364             dataSize = textCvt->ConvertSHIFTJISToUTF8(
365                 buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData.data, userData.userData.length);
366             break;
367         }
368         default: {
369             dataSize = textCvt->ConvertUCS2ToUTF8(
370                 buff, MAX_MSG_TEXT_LEN, (unsigned char *)&userData.userData.data, userData.userData.length);
371             break;
372         }
373     }
374     visibleMessageBody_.insert(0, reinterpret_cast<char *>(buff), dataSize);
375     TELEPHONY_LOGI("AnalsisDeliverMsg userData == %{private}s", visibleMessageBody_.c_str());
376 }
377 
AnalsisCMASMsg(const SmsTeleSvcDeliver & deliver)378 void CdmaSmsMessage::AnalsisCMASMsg(const SmsTeleSvcDeliver &deliver)
379 {
380     isCmas_ = true;
381     category_ = deliver.cmasData.category;
382     responseType_ = deliver.cmasData.responseType;
383     severity_ = deliver.cmasData.severity;
384     urgency_ = deliver.cmasData.urgency;
385     certainty_ = deliver.cmasData.certainty;
386     messageClass_ = deliver.cmasData.alertHandle;
387     msgClass_ = SMS_CLASS_UNKNOWN;
388     scTimestamp_ = SmsCommonUtils::ConvertTime(deliver.timeStamp);
389     SmsTeleSvcUserData userData;
390     (void)memset_s(&userData, sizeof(SmsTeleSvcUserData), 0x00, sizeof(SmsTeleSvcUserData));
391     userData.userData.length = deliver.cmasData.dataLen;
392     userData.encodeType = deliver.cmasData.encodeType;
393     if (deliver.cmasData.dataLen > sizeof(userData.userData.data)) {
394         TELEPHONY_LOGE("AnalsisCMASMsg memcpy_s data length invalid.");
395         return;
396     }
397     if (memcpy_s(userData.userData.data, sizeof(userData.userData.data), deliver.cmasData.alertText,
398             deliver.cmasData.dataLen) == EOK) {
399         AnalsisUserData(userData);
400     }
401 }
402 
AnalysisCbMsg(const SmsTransBroadCastMsg & cbMsg)403 void CdmaSmsMessage::AnalysisCbMsg(const SmsTransBroadCastMsg &cbMsg)
404 {
405     serviceCategory_ = cbMsg.transSvcCtg;
406     if (cbMsg.telesvcMsg.type != SmsMessageType::SMS_TYPE_DELIVER) {
407         TELEPHONY_LOGE("No matching type = [%{public}d]", cbMsg.telesvcMsg.type);
408         return;
409     }
410     messageId_ = cbMsg.telesvcMsg.data.deliver.msgId.msgId;
411     priority_ = cbMsg.telesvcMsg.data.deliver.priority;
412     language_ = cbMsg.telesvcMsg.data.deliver.language;
413     TELEPHONY_LOGI("analysisCbMsg transSvcCtg %{public}hu", cbMsg.transSvcCtg);
414     if ((cbMsg.transSvcCtg >= SMS_TRANS_SVC_CTG_CMAS_PRESIDENTIAL) &&
415         (cbMsg.transSvcCtg <= SMS_TRANS_SVC_CTG_CMAS_TEST)) {
416         AnalsisCMASMsg(cbMsg.telesvcMsg.data.deliver);
417     } else {
418         AnalsisDeliverMsg(cbMsg.telesvcMsg.data.deliver);
419     }
420 }
421 
AnalsisAckMsg(const SmsTransAckMsg & ackMsg)422 void CdmaSmsMessage::AnalsisAckMsg(const SmsTransAckMsg &ackMsg)
423 {
424     originatingAddress_ = ackMsg.address.szData;
425 }
426 
AddUserDataHeader(const struct SmsUDH & header)427 bool CdmaSmsMessage::AddUserDataHeader(const struct SmsUDH &header)
428 {
429     if (userHeaders_.size() >= CDMA_MAX_UD_HEADER_NUM) {
430         return false;
431     }
432 
433     userHeaders_.push_back(header);
434     return true;
435 }
436 
AnalsisHeader(const SmsTeleSvcUserData & userData)437 void CdmaSmsMessage::AnalsisHeader(const SmsTeleSvcUserData &userData)
438 {
439     if (memset_s(&smsUserData_, sizeof(SmsUserData), 0x00, sizeof(SmsUserData)) != EOK) {
440         return;
441     }
442     headerDataLen_ = userData.userData.length;
443     if (memcpy_s(&smsUserData_, sizeof(SmsUserData), &(userData.userData), sizeof(SmsUserData)) != EOK) {
444         return;
445     }
446 
447     if (bHeaderInd_ && userData.userData.headerCnt > 0) {
448         userHeaders_.clear();
449         for (int i = 0; i < userData.userData.headerCnt; i++) {
450             userHeaders_.push_back(userData.userData.header[i]);
451         }
452     }
453 }
454 
455 /**
456  * @brief GetTransMsgType
457  * 0x00 is point to point message
458  * 0x01 is broadcast message
459  * 0x02 is ack message
460  * 0x03 is unkown message
461  * @return int
462  */
GetTransMsgType() const463 int CdmaSmsMessage::GetTransMsgType() const
464 {
465     if (transMsg_ == nullptr) {
466         TELEPHONY_LOGE("Trans message type unkown!");
467         return SMS_TRANS_TYPE_RESERVED;
468     }
469 
470     return transMsg_->type;
471 }
472 
473 /**
474  * @brief Get the Trans Tele Service object
475  * 0x1000 IS-91 Extended Protocol Enhanced Services
476  * 0x1001 Wireless Paging Teleservice
477  * 0x1002 Wireless Messaging Teleservice
478  * 0x1003 Voice Mail Notification
479  * 0x1004 Wireless Application Protocol
480  * 0x1005 Wireless Enhanced Messaging Teleservice
481  * 0x1006 Service Category Programming Teleservice
482  * 0x1007 Card Application Toolkit Protocol Teleservice
483  * 0xffff
484  * @return int
485  */
GetTransTeleService() const486 int CdmaSmsMessage::GetTransTeleService() const
487 {
488     if ((transMsg_ == nullptr) || (transMsg_->type != SMS_TRANS_P2P_MSG)) {
489         TELEPHONY_LOGE("Trans Tele Service is error");
490         return SMS_TRANS_TELESVC_RESERVED;
491     }
492 
493     return transMsg_->data.p2pMsg.transTelesvcId;
494 }
495 
GetProtocolId() const496 int CdmaSmsMessage::GetProtocolId() const
497 {
498     return 0;
499 }
500 
IsReplaceMessage()501 bool CdmaSmsMessage::IsReplaceMessage()
502 {
503     return false;
504 }
505 
IsCphsMwi() const506 bool CdmaSmsMessage::IsCphsMwi() const
507 {
508     return false;
509 }
510 
IsWapPushMsg()511 bool CdmaSmsMessage::IsWapPushMsg()
512 {
513     if (transMsg_ == nullptr) {
514         return false;
515     }
516 
517     if (transMsg_->type == SMS_TRANS_P2P_MSG) {
518         return (transMsg_->data.p2pMsg.transTelesvcId == SMS_TRANS_TELESVC_WAP);
519     }
520     return false;
521 }
522 
GetSpecialSmsInd()523 std::shared_ptr<SpecialSmsIndication> CdmaSmsMessage::GetSpecialSmsInd()
524 {
525     return specialSmsInd_;
526 }
527 
IsStatusReport() const528 bool CdmaSmsMessage::IsStatusReport() const
529 {
530     return (transMsg_->data.p2pMsg.telesvcMsg.type == SMS_TYPE_DELIVERY_ACK);
531 }
532 
GetDestPort() const533 int16_t CdmaSmsMessage::GetDestPort() const
534 {
535     return destPort_;
536 }
537 
IsBroadcastMsg() const538 bool CdmaSmsMessage::IsBroadcastMsg() const
539 {
540     return GetTransMsgType() == SMS_TRANS_BROADCAST_MSG;
541 }
542 
DecodeMessage(unsigned char * decodeData,unsigned int len,SmsCodingScheme & codingType,const std::string & msgText,bool & bAbnormal,MSG_LANGUAGE_ID_T & langId)543 int CdmaSmsMessage::DecodeMessage(unsigned char *decodeData, unsigned int len, SmsCodingScheme &codingType,
544     const std::string &msgText, bool &bAbnormal, MSG_LANGUAGE_ID_T &langId)
545 {
546     int decodeLen = 0;
547     int dataLen = static_cast<int>(msgText.length());
548     const unsigned int maxDecodeLen = len;
549     const unsigned char *pMsgText = reinterpret_cast<const unsigned char *>(msgText.c_str());
550 
551     MsgTextConvert *textCvt = MsgTextConvert::Instance();
552     if (textCvt == nullptr) {
553         TELEPHONY_LOGE("MsgTextConvert Instance is nullptr");
554         return decodeLen;
555     }
556     if (msgText.empty()) {
557         TELEPHONY_LOGE("MsgText is empty!");
558         return decodeLen;
559     }
560 
561     switch (codingType) {
562         case SMS_CODING_7BIT: {
563             if (static_cast<unsigned int>(dataLen) > maxDecodeLen) {
564                 TELEPHONY_LOGE("DecodeMessage memcpy_s data length invalid.");
565                 return decodeLen;
566             }
567             if (memcpy_s(decodeData, maxDecodeLen, pMsgText, dataLen) != EOK) {
568                 TELEPHONY_LOGE("SplitMessage SMS_CHARSET_8BIT memcpy_s error!");
569                 return decodeLen;
570             }
571             decodeLen = dataLen;
572             codingType = SMS_CODING_ASCII7BIT;
573             break;
574         }
575         case SMS_CODING_8BIT: {
576             if (memcpy_s(decodeData, maxDecodeLen, pMsgText, dataLen) != EOK) {
577                 TELEPHONY_LOGE("SplitMessage SMS_CHARSET_8BIT memcpy_s error!");
578                 return decodeLen;
579             }
580             decodeLen = dataLen;
581             break;
582         }
583         case SMS_CODING_UCS2: {
584             decodeLen = textCvt->ConvertUTF8ToUCS2(decodeData, maxDecodeLen, pMsgText, dataLen);
585             break;
586         }
587         case SMS_CODING_AUTO:
588         default: {
589             decodeLen = textCvt->ConvertCdmaUTF8ToAuto(decodeData, maxDecodeLen, pMsgText, dataLen, &codingType);
590             break;
591         }
592     }
593     return decodeLen;
594 }
595 
GetCMASCategory() const596 int8_t CdmaSmsMessage::GetCMASCategory() const
597 {
598     return category_;
599 }
600 
GetCMASResponseType() const601 int8_t CdmaSmsMessage::GetCMASResponseType() const
602 {
603     return responseType_;
604 }
605 
GetCMASSeverity() const606 int8_t CdmaSmsMessage::GetCMASSeverity() const
607 {
608     return severity_;
609 }
610 
GetCMASUrgency() const611 int8_t CdmaSmsMessage::GetCMASUrgency() const
612 {
613     return urgency_;
614 }
615 
GetCMASCertainty() const616 int8_t CdmaSmsMessage::GetCMASCertainty() const
617 {
618     return certainty_;
619 }
620 
GetCMASMessageClass() const621 int8_t CdmaSmsMessage::GetCMASMessageClass() const
622 {
623     return messageClass_;
624 }
625 
IsCMAS() const626 bool CdmaSmsMessage::IsCMAS() const
627 {
628     return isCmas_;
629 }
630 
GetMessageId() const631 uint16_t CdmaSmsMessage::GetMessageId() const
632 {
633     return messageId_;
634 }
635 
GetFormat() const636 int8_t CdmaSmsMessage::GetFormat() const
637 {
638     constexpr int8_t FORMAT_3GPP2 = 2;
639     return FORMAT_3GPP2;
640 }
641 
GetLanguage() const642 int8_t CdmaSmsMessage::GetLanguage() const
643 {
644     return language_;
645 }
646 
GetCbInfo() const647 std::string CdmaSmsMessage::GetCbInfo() const
648 {
649     std::string info;
650     info.append("isCmas:")
651         .append(isCmas_ ? "true" : "false")
652         .append("\n")
653         .append("format:")
654         .append(std::to_string(GetFormat()))
655         .append("\n")
656         .append("messageId:")
657         .append(std::to_string(messageId_))
658         .append("\n")
659         .append("serviceCategory:")
660         .append(std::to_string(category_))
661         .append("\n")
662         .append("language:")
663         .append(std::to_string(language_))
664         .append("\n")
665         .append("body:")
666         .append(visibleMessageBody_)
667         .append("\n")
668         .append("priority:")
669         .append(std::to_string(priority_))
670         .append("\n")
671         .append("responseType:")
672         .append(std::to_string(responseType_))
673         .append("\n")
674         .append("severity:")
675         .append(std::to_string(severity_))
676         .append("\n")
677         .append("urgency:")
678         .append(std::to_string(urgency_))
679         .append("\n")
680         .append("certainty:")
681         .append(std::to_string(certainty_))
682         .append("\n")
683         .append("messageClass:")
684         .append(std::to_string(messageClass_))
685         .append("\n")
686         .append("serviceCategory:")
687         .append(std::to_string(serviceCategory_));
688     return info;
689 }
690 
GetPriority() const691 int8_t CdmaSmsMessage::GetPriority() const
692 {
693     return priority_;
694 }
695 
IsEmergencyMsg() const696 bool CdmaSmsMessage::IsEmergencyMsg() const
697 {
698     return priority_ == SMS_PRIORITY_EMERGENCY;
699 }
700 
GetServiceCategoty() const701 uint16_t CdmaSmsMessage::GetServiceCategoty() const
702 {
703     return serviceCategory_;
704 }
705 
GetGeoScope() const706 uint8_t CdmaSmsMessage::GetGeoScope() const
707 {
708     const uint8_t scopePlmnWide = 1;
709     return scopePlmnWide;
710 }
711 
GetReceTime() const712 long CdmaSmsMessage::GetReceTime() const
713 {
714     return scTimestamp_;
715 }
716 } // namespace Telephony
717 } // namespace OHOS
718