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