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