• 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 "gsm_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 
23 namespace OHOS {
24 namespace Telephony {
25 using namespace std;
26 template<typename T>
UniquePtrDeleterOneDimension(T ** (& ptr))27 inline void UniquePtrDeleterOneDimension(T **(&ptr))
28 {
29     if (ptr && *ptr) {
30         delete[] *ptr;
31         *ptr = nullptr;
32     }
33 }
34 
CalcReplyEncodeAddress(const std::string & replyAddress)35 int GsmSmsMessage::CalcReplyEncodeAddress(const std::string &replyAddress)
36 {
37     int ret = 0;
38     int addrLen = 0;
39     char *encodedAddr = nullptr;
40     unique_ptr<char *, void (*)(char **(&))> addressBuf(&encodedAddr, UniquePtrDeleterOneDimension);
41     if (replyAddress.length() > 0) {
42         struct SmsAddress replyAddr = {};
43         replyAddr.ton = SMS_TON_NATIONAL;
44         replyAddr.npi = SMS_NPI_ISDN;
45         ret = memset_s(replyAddr.address, sizeof(replyAddr.address), 0x00, MAX_ADDRESS_LEN + 1);
46         if (ret != EOK) {
47             TELEPHONY_LOGE("CalcReplyEncodeAddress memset_s error!");
48             return addrLen;
49         }
50         ret = memcpy_s(replyAddr.address, sizeof(replyAddr.address), replyAddress.c_str(), MAX_ADDRESS_LEN);
51         if (ret != EOK) {
52             TELEPHONY_LOGE("CalcReplyEncodeAddress memory_s error!");
53             return addrLen;
54         }
55         addrLen = GsmSmsParamCodec::EncodeAddress(&replyAddr, &encodedAddr);
56     }
57     return addrLen;
58 }
59 
SetSmsTpduDestAddress(std::shared_ptr<struct SmsTpdu> & tPdu,const std::string & desAddr)60 int GsmSmsMessage::SetSmsTpduDestAddress(std::shared_ptr<struct SmsTpdu> &tPdu, const std::string &desAddr)
61 {
62     int ret = 0;
63     int addLen = 0;
64     if (tPdu == nullptr) {
65         TELEPHONY_LOGE("TPdu is null.");
66         return addLen;
67     }
68     addLen = desAddr.length();
69     tPdu->data.submit.destAddress.ton = SMS_TON_UNKNOWN;
70     tPdu->data.submit.destAddress.npi = SMS_NPI_ISDN;
71     if (addLen < MAX_ADDRESS_LEN) {
72         ret = memcpy_s(tPdu->data.submit.destAddress.address, sizeof(tPdu->data.submit.destAddress.address),
73             desAddr.c_str(), addLen);
74         if (ret != EOK) {
75             TELEPHONY_LOGE("SetSmsTpduDestAddress memcpy_s error!");
76             return addLen;
77         }
78         tPdu->data.submit.destAddress.address[addLen] = '\0';
79     } else {
80         if (desAddr[0] == '+') {
81             ret = memcpy_s(tPdu->data.submit.destAddress.address, sizeof(tPdu->data.submit.destAddress.address),
82                 desAddr.c_str(), MAX_ADDRESS_LEN);
83         } else {
84             ret = memcpy_s(tPdu->data.submit.destAddress.address, sizeof(tPdu->data.submit.destAddress.address),
85                 desAddr.c_str(), MAX_ADDRESS_LEN - 1);
86         }
87         if (ret != EOK) {
88             TELEPHONY_LOGE("SetSmsTpduDestAddress memcpy_s error!");
89             return addLen;
90         }
91         tPdu->data.submit.destAddress.address[MAX_ADDRESS_LEN] = '\0';
92     }
93     return addLen;
94 }
95 
SetHeaderLang(int index,const SmsCodingScheme codingType,const MSG_LANGUAGE_ID_T langId)96 int GsmSmsMessage::SetHeaderLang(int index, const SmsCodingScheme codingType, const MSG_LANGUAGE_ID_T langId)
97 {
98     int ret = 0;
99     if (smsTpdu_ == nullptr) {
100         TELEPHONY_LOGE("TPdu is null.");
101         return ret;
102     }
103     switch (smsTpdu_->tpduType) {
104         case SMS_TPDU_SUBMIT:
105             if (codingType == SMS_CODING_7BIT && langId != MSG_ID_RESERVED_LANG) {
106                 smsTpdu_->data.submit.userData.header[index].udhType = SMS_UDH_SINGLE_SHIFT;
107                 smsTpdu_->data.submit.userData.header[index].udh.singleShift.langId = langId;
108                 ret++;
109             }
110             break;
111         default:
112             break;
113     }
114     return ret;
115 }
116 
SetHeaderConcat(int index,const SmsConcat & concat)117 int GsmSmsMessage::SetHeaderConcat(int index, const SmsConcat &concat)
118 {
119     int ret = 0;
120     if (smsTpdu_ == nullptr) {
121         TELEPHONY_LOGE("TPdu is null.");
122         return ret;
123     }
124     switch (smsTpdu_->tpduType) {
125         case SMS_TPDU_SUBMIT:
126             if (concat.is8Bits) {
127                 smsTpdu_->data.submit.userData.header[index].udhType = SMS_UDH_CONCAT_8BIT;
128                 smsTpdu_->data.submit.userData.header[index].udh.concat8bit.msgRef = concat.msgRef;
129                 smsTpdu_->data.submit.userData.header[index].udh.concat8bit.totalSeg = concat.totalSeg;
130                 smsTpdu_->data.submit.userData.header[index].udh.concat8bit.seqNum = concat.seqNum;
131             } else {
132                 smsTpdu_->data.submit.userData.header[index].udhType = SMS_UDH_CONCAT_16BIT;
133                 smsTpdu_->data.submit.userData.header[index].udh.concat16bit.msgRef = concat.msgRef;
134                 smsTpdu_->data.submit.userData.header[index].udh.concat16bit.totalSeg = concat.totalSeg;
135                 smsTpdu_->data.submit.userData.header[index].udh.concat16bit.seqNum = concat.seqNum;
136             }
137             ret++;
138             break;
139         default:
140             break;
141     }
142     return ret;
143 }
144 
SetHeaderReply(int index)145 int GsmSmsMessage::SetHeaderReply(int index)
146 {
147     int ret = 0;
148     std::string reply = GetReplyAddress();
149     if (smsTpdu_ == nullptr && reply.length() <= 0) {
150         TELEPHONY_LOGE("TPdu or address is null.");
151         return ret;
152     }
153     switch (smsTpdu_->tpduType) {
154         case SMS_TPDU_SUBMIT: {
155             smsTpdu_->data.submit.bReplyPath = true;
156             smsTpdu_->data.submit.userData.header[index].udhType = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
157             smsTpdu_->data.submit.userData.header[index].udh.alternateAddress.ton = SMS_TON_NATIONAL;
158             smsTpdu_->data.submit.userData.header[index].udh.alternateAddress.npi = SMS_NPI_ISDN;
159             ret = memset_s(smsTpdu_->data.submit.userData.header[index].udh.alternateAddress.address,
160                 sizeof(smsTpdu_->data.submit.userData.header[index].udh.alternateAddress.address), 0x00,
161                 MAX_ADDRESS_LEN + 1);
162             if (ret != EOK) {
163                 TELEPHONY_LOGE("SetHeaderReply memset_s error!");
164                 return ret;
165             }
166             ret = memcpy_s(smsTpdu_->data.submit.userData.header[index].udh.alternateAddress.address,
167                 sizeof(smsTpdu_->data.submit.userData.header[index].udh.alternateAddress.address), reply.c_str(),
168                 reply.length());
169             if (ret != EOK) {
170                 TELEPHONY_LOGE("SetHeaderReply memcpy_s error!");
171                 return ret;
172             }
173             break;
174         }
175         default:
176             break;
177     }
178     return ret;
179 }
180 
CreateDefaultSubmit(bool bStatusReport,const SmsCodingScheme codingScheme)181 void GsmSmsMessage::CreateDefaultSubmit(bool bStatusReport, const SmsCodingScheme codingScheme)
182 {
183     smsTpdu_ = std::make_shared<struct SmsTpdu>();
184     if (smsTpdu_ == nullptr) {
185         TELEPHONY_LOGE("Make tPdu is fail.");
186         return;
187     }
188     smsTpdu_->tpduType = SMS_TPDU_SUBMIT;
189     smsTpdu_->data.submit.bHeaderInd = false;
190     smsTpdu_->data.submit.bRejectDup = false;
191     smsTpdu_->data.submit.bStatusReport = bStatusReport;
192     smsTpdu_->data.submit.bReplyPath = false;
193     smsTpdu_->data.submit.msgRef = 0;
194     smsTpdu_->data.submit.dcs.bCompressed = false;
195     smsTpdu_->data.submit.dcs.msgClass = SmsMessageClass::SMS_CLASS_UNKNOWN;
196     smsTpdu_->data.submit.dcs.codingGroup = SMS_GENERAL_GROUP;
197     smsTpdu_->data.submit.dcs.codingScheme = codingScheme;
198     smsTpdu_->data.submit.pid = SMS_NORMAL_PID;
199     smsTpdu_->data.submit.vpf = SMS_VPF_NOT_PRESENT;
200 }
201 
CreateDefaultSubmitSmsTpdu(const std::string & dest,const std::string & sc,const std::string & text,bool bStatusReport,const SmsCodingScheme codingScheme=SMS_CODING_7BIT)202 std::shared_ptr<struct SmsTpdu> GsmSmsMessage::CreateDefaultSubmitSmsTpdu(const std::string &dest,
203     const std::string &sc, const std::string &text, bool bStatusReport,
204     const SmsCodingScheme codingScheme = SMS_CODING_7BIT)
205 {
206     SetFullText(text);
207     SetSmscAddr(sc);
208     SetDestAddress(dest);
209     CreateDefaultSubmit(bStatusReport, codingScheme);
210     SetSmsTpduDestAddress(smsTpdu_, dest);
211     return smsTpdu_;
212 }
213 
CreateDataSubmitSmsTpdu(const std::string & desAddr,const std::string & scAddr,int32_t port,const uint8_t * data,uint32_t dataLen,uint16_t msgRef8bit,bool bStatusReport)214 std::shared_ptr<struct SmsTpdu> GsmSmsMessage::CreateDataSubmitSmsTpdu(const std::string &desAddr,
215     const std::string &scAddr, int32_t port, const uint8_t *data, uint32_t dataLen, uint16_t msgRef8bit,
216     bool bStatusReport)
217 {
218     SetSmscAddr(scAddr);
219     SetDestAddress(desAddr);
220     CreateDefaultSubmit(bStatusReport, SMS_CODING_7BIT);
221     SetSmsTpduDestAddress(smsTpdu_, desAddr);
222     int endcodeLen = 0;
223     bool bAbnormal = false;
224     MSG_LANGUAGE_ID_T langId = MSG_ID_RESERVED_LANG;
225     SmsCodingScheme pCodingType = SMS_CODING_7BIT;
226     const int bufSize = (MAX_GSM_7BIT_DATA_LEN * MAX_SEGMENT_NUM) + 1;
227     unsigned char encodeData[bufSize];
228     MsgTextConvert *textCvt = MsgTextConvert::Instance();
229     if ((textCvt == nullptr) || (memset_s(encodeData, sizeof(encodeData), 0x00, sizeof(encodeData)) != EOK)) {
230         TELEPHONY_LOGE("failed to initialize!");
231         return nullptr;
232     }
233     const unsigned char *pMsgText = (const unsigned char *)data;
234     unsigned char *pDestText = encodeData;
235     MSG_LANGUAGE_ID_T *pLangId = &langId;
236     bool *pIncludeAbnormalChar = &bAbnormal;
237     std::tuple<unsigned char *, int, unsigned char *, int, MSG_LANGUAGE_ID_T *, bool *> paras (pDestText,
238         bufSize, const_cast<unsigned char *>(pMsgText), (int)dataLen, pLangId, pIncludeAbnormalChar);
239     endcodeLen =
240         textCvt->ConvertUTF8ToGSM7bit(paras);
241     if (smsTpdu_ == nullptr) {
242         TELEPHONY_LOGE("smsTpdu_ is nullptr!");
243         return nullptr;
244     }
245     int headerCnt = 0;
246     if (memset_s(smsTpdu_->data.submit.userData.data, sizeof(smsTpdu_->data.submit.userData.data), 0x00,
247         sizeof(smsTpdu_->data.submit.userData.data)) != EOK) {
248         TELEPHONY_LOGE("memset_s is error!");
249         return nullptr;
250     }
251     if ((unsigned int)endcodeLen > sizeof(smsTpdu_->data.submit.userData.data)) {
252         if (memcpy_s(smsTpdu_->data.submit.userData.data, sizeof(smsTpdu_->data.submit.userData.data), encodeData,
253             sizeof(smsTpdu_->data.submit.userData.data)) != EOK) {
254             TELEPHONY_LOGE("memcpy_s is error!");
255             return nullptr;
256         }
257     } else {
258         if (memcpy_s(smsTpdu_->data.submit.userData.data, sizeof(smsTpdu_->data.submit.userData.data), encodeData,
259             endcodeLen) != EOK) {
260             TELEPHONY_LOGE("memcpy_s is error!");
261             return nullptr;
262         }
263     }
264     smsTpdu_->data.submit.userData.data[endcodeLen] = 0;
265     smsTpdu_->data.submit.msgRef = msgRef8bit;
266     /* Set User Data Header Port Information */
267     smsTpdu_->data.submit.userData.header[headerCnt].udhType = SMS_UDH_APP_PORT_16BIT;
268     smsTpdu_->data.submit.userData.header[headerCnt].udh.appPort16bit.destPort = ((unsigned short)port & 0xFFFF);
269     smsTpdu_->data.submit.userData.header[headerCnt].udh.appPort16bit.originPort = 0;
270     headerCnt++;
271     /* Set User Data Header for Alternate Reply Address */
272     headerCnt += SetHeaderReply(headerCnt);
273     /* Set User Data Header for National Language Single Shift */
274     headerCnt += SetHeaderLang(headerCnt, pCodingType, langId);
275     smsTpdu_->data.submit.userData.headerCnt = headerCnt;
276     return smsTpdu_;
277 }
278 
GetSubmitEncodeInfo(const std::string & sc,bool bMore)279 std::shared_ptr<struct EncodeInfo> GsmSmsMessage::GetSubmitEncodeInfo(const std::string &sc, bool bMore)
280 {
281     int ret = 0;
282     int encodeSmscLen = 0;
283     char tpduBuf[MAX_TPDU_DATA_LEN];
284     unsigned char encodeSmscAddr[MAX_SMSC_LEN];
285     (void)memset_s(encodeSmscAddr, sizeof(encodeSmscAddr), 0x00, sizeof(encodeSmscAddr));
286     (void)memset_s(tpduBuf, sizeof(tpduBuf), 0x00, sizeof(tpduBuf));
287     if ((!sc.empty()) && (sc.length() < MAX_SMSC_LEN)) {
288         struct SmsAddress pAddress;
289         ret = memset_s(&pAddress.address, sizeof(pAddress.address), 0x00, sizeof(pAddress.address));
290         if (ret != EOK) {
291             TELEPHONY_LOGE("GetSubmitEncodeInfo memset_s error!");
292             return nullptr;
293         }
294         ret = memcpy_s(&pAddress.address, sizeof(pAddress.address), sc.data(), sc.length());
295         if (ret != EOK) {
296             TELEPHONY_LOGE("GetSubmitEncodeInfo memcpy_s error!");
297             return nullptr;
298         }
299         pAddress.address[sc.length()] = '\0';
300         if (sc[0] == '+') {
301             pAddress.ton = SMS_TON_INTERNATIONAL;
302         } else {
303             pAddress.ton = SMS_TON_NATIONAL;
304         }
305         pAddress.npi = SMS_NPI_ISDN; /* app cannot set this value */
306         encodeSmscLen = GsmSmsParamCodec::EncodeSMSC(&pAddress, encodeSmscAddr, sizeof(encodeSmscAddr));
307     }
308     std::shared_ptr<struct EncodeInfo> info = std::make_shared<struct EncodeInfo>();
309     int bufLen = GsmSmsTpduCodec::EncodeTpdu(smsTpdu_.get(), tpduBuf, sizeof(tpduBuf));
310     if (bufLen > 0 && info != nullptr) {
311         ret = memcpy_s(info->smcaData_, sizeof(info->smcaData_), encodeSmscAddr, encodeSmscLen);
312         if (ret != EOK) {
313             TELEPHONY_LOGE("GetSubmitEncodeInfo encodeSmscAddr memcpy_s error!");
314             return nullptr;
315         }
316         ret = memcpy_s(info->tpduData_, sizeof(info->tpduData_), tpduBuf, bufLen);
317         if (ret != EOK) {
318             TELEPHONY_LOGE("GetSubmitEncodeInfo memcpy_s error!");
319             return nullptr;
320         }
321         info->smcaLen = encodeSmscLen;
322         info->tpduLen = bufLen;
323         info->isMore_ = bMore;
324     }
325     return info;
326 }
327 
CreateDeliverSmsTpdu()328 std::shared_ptr<struct SmsTpdu> GsmSmsMessage::CreateDeliverSmsTpdu()
329 {
330     smsTpdu_ = std::make_shared<struct SmsTpdu>();
331     if (smsTpdu_ == nullptr) {
332         TELEPHONY_LOGE("Make smsTpdu fail.");
333         return smsTpdu_;
334     }
335     smsTpdu_->tpduType = SMS_TPDU_DELIVER;
336     smsTpdu_->data.deliver.bHeaderInd = false;
337     return smsTpdu_;
338 }
339 
CreateDeliverReportSmsTpdu()340 std::shared_ptr<struct SmsTpdu> GsmSmsMessage::CreateDeliverReportSmsTpdu()
341 {
342     smsTpdu_ = std::make_shared<struct SmsTpdu>();
343     if (smsTpdu_ == nullptr) {
344         TELEPHONY_LOGE("Make smsTpdu fail.");
345         return smsTpdu_;
346     }
347     smsTpdu_->tpduType = SMS_TPDU_DELIVER_REP;
348     smsTpdu_->data.deliverRep.bHeaderInd = false;
349     smsTpdu_->data.deliverRep.paramInd = 0x00;
350     return smsTpdu_;
351 }
352 
CreateStatusReportSmsTpdu()353 std::shared_ptr<struct SmsTpdu> GsmSmsMessage::CreateStatusReportSmsTpdu()
354 {
355     smsTpdu_ = std::make_shared<struct SmsTpdu>();
356     if (smsTpdu_ == nullptr) {
357         TELEPHONY_LOGE("Make smsTpdu fail.");
358         return smsTpdu_;
359     }
360     smsTpdu_->tpduType = SMS_TPDU_STATUS_REP;
361     return smsTpdu_;
362 }
363 
CreateMessage(const std::string & pdu)364 std::shared_ptr<GsmSmsMessage> GsmSmsMessage::CreateMessage(const std::string &pdu)
365 {
366     std::shared_ptr<GsmSmsMessage> message = std::make_shared<GsmSmsMessage>();
367     if (message == nullptr) {
368         TELEPHONY_LOGE("Make message fail.");
369         return message;
370     }
371     message->smsTpdu_ = std::make_shared<struct SmsTpdu>();
372     if (message->smsTpdu_ == nullptr) {
373         TELEPHONY_LOGE("Make smsTpdu fail.");
374         return message;
375     }
376     (void)memset_s(message->smsTpdu_.get(), sizeof(struct SmsTpdu), 0x00, sizeof(struct SmsTpdu));
377     std::string pduData = StringUtils::HexToString(pdu);
378     message->rawPdu_ = StringUtils::HexToByteVector(pdu);
379     if (message->PduAnalysis(pduData)) {
380         return message;
381     }
382     return nullptr;
383 }
384 
PduAnalysis(const string & pdu)385 bool GsmSmsMessage::PduAnalysis(const string &pdu)
386 {
387     bool result = true;
388     if (smsTpdu_ == nullptr || pdu.empty() || pdu.length() > MAX_TPDU_DATA_LEN) {
389         TELEPHONY_LOGE("GsmSmsMessage::PduAnalysis smsTpdu is null");
390         return false;
391     }
392     struct SmsAddress smsc;
393     if (memset_s(&smsc, sizeof(struct SmsAddress), 0x00, sizeof(struct SmsAddress)) != EOK) {
394         TELEPHONY_LOGE("PduAnalysis memset_s error!");
395         return false;
396     }
397     int smscLen = GsmSmsParamCodec::DecodeSMSC((const unsigned char *)pdu.c_str(), pdu.length(), smsc);
398     if (smscLen > 0) {
399         scAddress_ = smsc.address;
400     }
401 
402     if (smscLen >= static_cast<int>(pdu.length())) {
403         TELEPHONY_LOGE("PduAnalysis pdu is invalid!");
404         return false;
405     }
406 
407     unsigned char tempPdu[TAPI_TEXT_SIZE_MAX + 1] = {0};
408     if (memcpy_s(tempPdu, sizeof(tempPdu), (pdu.c_str() + smscLen), (pdu.length() - smscLen)) != EOK) {
409         TELEPHONY_LOGE("PduAnalysis memset_s error!");
410         return false;
411     }
412 
413     int decodeLen = GsmSmsTpduCodec::DecodeTpdu(tempPdu, sizeof(tempPdu), smsTpdu_.get());
414     if (decodeLen <= 0) {
415         TELEPHONY_LOGE("decodeLen <= 0.");
416         return false;
417     }
418     switch (smsTpdu_->tpduType) {
419         case SMS_TPDU_DELIVER:
420             AnalysisMsgDeliver(smsTpdu_->data.deliver);
421             break;
422         case SMS_TPDU_STATUS_REP:
423             AnalysisMsgStatusReport(smsTpdu_->data.statusRep);
424             break;
425         case SMS_TPDU_SUBMIT:
426             AnalysisMsgSubmit(smsTpdu_->data.submit);
427             break;
428         default:
429             TELEPHONY_LOGE("tpduType is unknown.");
430             result = false;
431             break;
432     }
433     return result;
434 }
435 
AnalysisMsgDeliver(const SmsDeliver & deliver)436 void GsmSmsMessage::AnalysisMsgDeliver(const SmsDeliver &deliver)
437 {
438     protocolId_ = (int)(deliver.pid);
439     hasReplyPath_ = deliver.bReplyPath;
440     bStatusReportMessage_ = deliver.bStatusReport;
441     bMoreMsg_ = deliver.bMoreMsg;
442     bHeaderInd_ = deliver.bHeaderInd;
443     originatingAddress_ = deliver.originAddress.address;
444     headerCnt_ = deliver.userData.headerCnt;
445     ConvertMsgTimeStamp(deliver.timeStamp);
446     ConvertMessageDcs();
447     ConvertUserData();
448 }
449 
AnalysisMsgStatusReport(const SmsStatusReport & statusRep)450 void GsmSmsMessage::AnalysisMsgStatusReport(const SmsStatusReport &statusRep)
451 {
452     protocolId_ = (int)(statusRep.pid);
453     msgRef_ = statusRep.msgRef;
454     bMoreMsg_ = statusRep.bMoreMsg;
455     bStatusReportMessage_ = statusRep.bStatusReport;
456     bHeaderInd_ = statusRep.bHeaderInd;
457     status_ = statusRep.status;
458     ConvertMsgTimeStamp(statusRep.timeStamp);
459     ConvertMessageDcs();
460     ConvertUserData();
461 }
462 
AnalysisMsgSubmit(const SmsSubmit & submit)463 void GsmSmsMessage::AnalysisMsgSubmit(const SmsSubmit &submit)
464 {
465     protocolId_ = static_cast<int>(submit.pid);
466     msgRef_ = submit.msgRef;
467     bStatusReportMessage_ = submit.bStatusReport;
468     bHeaderInd_ = submit.bHeaderInd;
469     ConvertMsgTimeStamp(submit.validityPeriod);
470     ConvertMessageDcs();
471     ConvertUserData();
472 }
473 
ConvertMessageDcs()474 void GsmSmsMessage::ConvertMessageDcs()
475 {
476     if (smsTpdu_ == nullptr) {
477         TELEPHONY_LOGE("GsmSmsMessage::ConvertMessageDcs smsTpdu is null");
478         return;
479     }
480     switch (smsTpdu_->tpduType) {
481         case SMS_TPDU_DELIVER:
482             bCompressed_ = smsTpdu_->data.deliver.dcs.bCompressed;
483             codingScheme_ = smsTpdu_->data.deliver.dcs.codingScheme;
484             codingGroup_ = smsTpdu_->data.deliver.dcs.codingGroup;
485             bIndActive_ = smsTpdu_->data.deliver.dcs.bIndActive;
486             bMwi_ = smsTpdu_->data.deliver.dcs.bMWI;
487             bMwiSense_ = smsTpdu_->data.deliver.dcs.bIndActive; /* Indicates vmail notification set/clear */
488             ConvertMessageClass(smsTpdu_->data.deliver.dcs.msgClass);
489             break;
490         case SMS_TPDU_STATUS_REP:
491             bCompressed_ = smsTpdu_->data.statusRep.dcs.bCompressed;
492             codingScheme_ = smsTpdu_->data.statusRep.dcs.codingScheme;
493             codingGroup_ = smsTpdu_->data.statusRep.dcs.codingGroup;
494             bIndActive_ = smsTpdu_->data.statusRep.dcs.bIndActive;
495             ConvertMessageClass(smsTpdu_->data.statusRep.dcs.msgClass);
496             break;
497         case SMS_TPDU_SUBMIT:
498             bCompressed_ = smsTpdu_->data.submit.dcs.bCompressed;
499             codingScheme_ = smsTpdu_->data.submit.dcs.codingScheme;
500             codingGroup_ = smsTpdu_->data.submit.dcs.codingGroup;
501             bIndActive_ = smsTpdu_->data.submit.dcs.bIndActive;
502             bMwi_ = smsTpdu_->data.submit.dcs.bMWI;
503             bMwiSense_ = smsTpdu_->data.submit.dcs.bIndActive;
504             ConvertMessageClass(smsTpdu_->data.submit.dcs.msgClass);
505             break;
506         default:
507             break;
508     }
509 }
510 
ConvertUserData()511 void GsmSmsMessage::ConvertUserData()
512 {
513     int ret = 0;
514     int dataSize = 0;
515     if (smsTpdu_ == nullptr ||
516         (memset_s(&smsUserData_, sizeof(struct SmsUserData), 0x00, sizeof(struct SmsUserData)) != EOK)) {
517         return;
518     }
519     switch (smsTpdu_->tpduType) {
520         case SMS_TPDU_DELIVER:
521             headerDataLen_ = smsTpdu_->data.deliver.userData.length;
522             ret = memcpy_s(&smsUserData_, sizeof(struct SmsUserData), &(smsTpdu_->data.deliver.userData),
523                 sizeof(struct SmsUserData));
524             break;
525         case SMS_TPDU_STATUS_REP:
526             headerDataLen_ = smsTpdu_->data.statusRep.userData.length;
527             ret = memcpy_s(&smsUserData_, sizeof(struct SmsUserData), &(smsTpdu_->data.statusRep.userData),
528                 sizeof(struct SmsUserData));
529             break;
530         case SMS_TPDU_SUBMIT:
531             headerDataLen_ = smsTpdu_->data.submit.userData.length;
532             ret = memcpy_s(
533                 &smsUserData_, sizeof(SmsUserData), &(smsTpdu_->data.submit.userData), sizeof(SmsUserData));
534             break;
535         default:
536             break;
537     }
538     if (ret != EOK) {
539         return;
540     }
541     if (smsUserData_.length > 0) {
542         MsgTextConvert *textCvt = MsgTextConvert::Instance();
543         if (textCvt == nullptr) {
544             return;
545         }
546         unsigned char buff[MAX_MSG_TEXT_LEN + 1] = {0};
547         if (codingScheme_ == SMS_CODING_7BIT) {
548             MsgLangInfo langInfo = {
549                 0,
550             };
551             langInfo.bSingleShift = false;
552             langInfo.bLockingShift = false;
553             dataSize = textCvt->ConvertGSM7bitToUTF8(
554                 buff, MAX_MSG_TEXT_LEN, (unsigned char *)smsUserData_.data, smsUserData_.length, &langInfo);
555         } else if (codingScheme_ == SMS_CODING_UCS2) {
556             dataSize = textCvt->ConvertUCS2ToUTF8(
557                 buff, MAX_MSG_TEXT_LEN, (unsigned char *)smsUserData_.data, smsUserData_.length);
558         }
559         visibleMessageBody_.insert(0, (char *)buff, dataSize);
560         rawUserData_.insert(0, (char *)smsUserData_.data, smsUserData_.length);
561     }
562 }
563 
SetFullText(const std::string & text)564 void GsmSmsMessage::SetFullText(const std::string &text)
565 {
566     fullText_ = text;
567 }
568 
SetDestAddress(const std::string & address)569 void GsmSmsMessage::SetDestAddress(const std::string &address)
570 {
571     destAddress_ = address;
572 }
573 
SetDestPort(uint32_t port)574 void GsmSmsMessage::SetDestPort(uint32_t port)
575 {
576     destPort_ = port;
577 }
578 
GetFullText() const579 std::string GsmSmsMessage::GetFullText() const
580 {
581     return fullText_;
582 }
583 
GetReplyAddress() const584 std::string GsmSmsMessage::GetReplyAddress() const
585 {
586     return replyAddress_;
587 }
588 
GetDestAddress() const589 std::string GsmSmsMessage::GetDestAddress() const
590 {
591     return destAddress_;
592 }
593 
GetDestPort()594 uint16_t GsmSmsMessage::GetDestPort()
595 {
596     std::shared_ptr<SmsAppPortAddr> portAddress = GetPortAddress();
597     if (portAddress == nullptr) {
598         TELEPHONY_LOGE("PortAddress is null!");
599         return DEFAULT_PORT;
600     }
601     destPort_ = static_cast<uint16_t>(portAddress->destPort);
602     return destPort_;
603 }
604 
GetIsSmsText() const605 bool GsmSmsMessage::GetIsSmsText() const
606 {
607     return bSmsText_;
608 }
609 
GetGsm() const610 bool GsmSmsMessage::GetGsm() const
611 {
612     return true;
613 }
614 
GetIsTypeZeroInd() const615 bool GsmSmsMessage::GetIsTypeZeroInd() const
616 {
617     return (GetProtocolId() == 0x40);
618 }
619 
GetIsSIMDataTypeDownload() const620 bool GsmSmsMessage::GetIsSIMDataTypeDownload() const
621 {
622     int protocolId = GetProtocolId();
623     return GetMessageClass() == SMS_SIM_MESSAGE && (protocolId == 0x7f || protocolId == 0x7c);
624 }
625 
ConvertMsgTimeStamp(const struct SmsTimeStamp & times)626 void GsmSmsMessage::ConvertMsgTimeStamp(const struct SmsTimeStamp &times)
627 {
628     if (times.format == SMS_TIME_ABSOLUTE) {
629         scTimestamp_ = SmsCommonUtils::ConvertTime(times.time.absolute);
630     } else {
631         scTimestamp_ = time(nullptr);
632     }
633 }
634 
635 // from 3GPP TS 23.040 V5.1.0 9.2.3.24.2 Special SMS Message Indication
IsSpecialMessage() const636 bool GsmSmsMessage::IsSpecialMessage() const
637 {
638     bool result = false;
639     if (GetIsTypeZeroInd()) {
640         TELEPHONY_LOGI("GsmSmsMessage:: IsTypeZeroInd");
641         result = true;
642     }
643     // 9.2.3.9	TP Protocol Identifier (TP PID)
644     if (GetIsSIMDataTypeDownload()) {
645         TELEPHONY_LOGI("GsmSmsMessage:: GetIsSIMDataTypeDownload");
646         result = true;
647     }
648     if (IsMwiSet() || IsMwiClear()) {
649         TELEPHONY_LOGI("GsmSmsMessage::Mwi Message");
650         result = true;
651     }
652     return result;
653 }
654 
DecodeMessage(unsigned char * decodeData,SmsCodingScheme & codingType,const std::string & msgText,bool & bAbnormal,MSG_LANGUAGE_ID_T & langId)655 int GsmSmsMessage::DecodeMessage(unsigned char *decodeData, SmsCodingScheme &codingType,
656     const std::string &msgText, bool &bAbnormal, MSG_LANGUAGE_ID_T &langId)
657 {
658     int decodeLen = 0;
659     int dataLen = msgText.length();
660     const int maxDecodeLen = (MAX_GSM_7BIT_DATA_LEN * MAX_SEGMENT_NUM) + 1;
661     const unsigned char *pMsgText = (const unsigned char *)msgText.c_str();
662 
663     MsgTextConvert *textCvt = MsgTextConvert::Instance();
664     if (textCvt == nullptr) {
665         TELEPHONY_LOGE("MsgTextConvert Instance is nullptr");
666         return decodeLen;
667     }
668     if (msgText.empty()) {
669         return decodeLen;
670     }
671 
672     switch (codingType) {
673         case SMS_CODING_7BIT: {
674             std::tuple<unsigned char *, int, unsigned char *, int, MSG_LANGUAGE_ID_T *, bool *> paras (
675                 decodeData, maxDecodeLen, const_cast<unsigned char *>(pMsgText), dataLen, &langId, &bAbnormal);
676             decodeLen =
677                 textCvt->ConvertUTF8ToGSM7bit(paras);
678             break;
679         }
680         case SMS_CODING_8BIT: {
681             if (memcpy_s(decodeData, maxDecodeLen, pMsgText, dataLen) != EOK) {
682                 TELEPHONY_LOGE("SplitMessage SMS_CHARSET_8BIT memcpy_s error!");
683                 return decodeLen;
684             }
685             decodeLen = dataLen;
686             break;
687         }
688         case SMS_CODING_UCS2: {
689             decodeLen = textCvt->ConvertUTF8ToUCS2(decodeData, maxDecodeLen, pMsgText, dataLen);
690             break;
691         }
692         case SMS_CODING_AUTO:
693         default: {
694             SmsCodingScheme encodeType = SMS_CODING_AUTO;
695             decodeLen = textCvt->ConvertGsmUTF8ToAuto(decodeData, maxDecodeLen, pMsgText, dataLen, &encodeType);
696             codingType = encodeType;
697             break;
698         }
699     }
700     return decodeLen;
701 }
702 } // namespace Telephony
703 } // namespace OHOS