• 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 > 0) {
411         scAddress_ = smsc.address;
412     }
413     if (smscLen >= pdu.length()) {
414         TELEPHONY_LOGE("PduAnalysis pdu is invalid!");
415         return false;
416     }
417 
418     uint8_t tempPdu[TAPI_TEXT_SIZE_MAX + 1] = { 0 };
419     if (sizeof(tempPdu) + smscLen < pdu.length()) {
420         TELEPHONY_LOGE("pdu length exceed maxinum");
421         return false;
422     }
423     if (memcpy_s(tempPdu, sizeof(tempPdu), (pdu.c_str() + smscLen), pdu.length() - smscLen) != EOK) {
424         TELEPHONY_LOGE("PduAnalysis memset_s error!");
425         return false;
426     }
427 
428     auto tpduCodec = std::make_shared<GsmSmsTpduCodec>();
429     if (!tpduCodec->DecodeSmsPdu(tempPdu, pdu.length() - smscLen, smsTpdu_.get())) {
430         TELEPHONY_LOGE("DecodeSmsPdu fail");
431         return false;
432     }
433 
434     bool result = true;
435     switch (smsTpdu_->tpduType) {
436         case SMS_TPDU_DELIVER:
437             AnalysisMsgDeliver(smsTpdu_->data.deliver);
438             break;
439         case SMS_TPDU_STATUS_REP:
440             AnalysisMsgStatusReport(smsTpdu_->data.statusRep);
441             break;
442         case SMS_TPDU_SUBMIT:
443             AnalysisMsgSubmit(smsTpdu_->data.submit);
444             break;
445         default:
446             TELEPHONY_LOGE("tpduType is unknown.");
447             result = false;
448             break;
449     }
450     return result;
451 }
452 
AnalysisMsgDeliver(const SmsDeliver & deliver)453 void GsmSmsMessage::AnalysisMsgDeliver(const SmsDeliver &deliver)
454 {
455     protocolId_ = (int)(deliver.pid);
456     hasReplyPath_ = deliver.bReplyPath;
457     bStatusReportMessage_ = deliver.bStatusReport;
458     bMoreMsg_ = deliver.bMoreMsg;
459     bHeaderInd_ = deliver.bHeaderInd;
460     originatingAddress_ = deliver.originAddress.address;
461     headerCnt_ = deliver.userData.headerCnt;
462     ConvertMsgTimeStamp(deliver.timeStamp);
463     ConvertMessageDcs();
464     ConvertUserData();
465 }
466 
AnalysisMsgStatusReport(const SmsStatusReport & statusRep)467 void GsmSmsMessage::AnalysisMsgStatusReport(const SmsStatusReport &statusRep)
468 {
469     protocolId_ = (int)(statusRep.pid);
470     msgRef_ = statusRep.msgRef;
471     bMoreMsg_ = statusRep.bMoreMsg;
472     bStatusReportMessage_ = statusRep.bStatusReport;
473     bHeaderInd_ = statusRep.bHeaderInd;
474     status_ = statusRep.status;
475     ConvertMsgTimeStamp(statusRep.timeStamp);
476     ConvertMessageDcs();
477     ConvertUserData();
478 }
479 
AnalysisMsgSubmit(const SmsSubmit & submit)480 void GsmSmsMessage::AnalysisMsgSubmit(const SmsSubmit &submit)
481 {
482     protocolId_ = static_cast<int>(submit.pid);
483     hasReplyPath_ = submit.bReplyPath;
484     msgRef_ = submit.msgRef;
485     bStatusReportMessage_ = submit.bStatusReport;
486     bHeaderInd_ = submit.bHeaderInd;
487     ConvertMsgTimeStamp(submit.validityPeriod);
488     ConvertMessageDcs();
489     ConvertUserData();
490 }
491 
ConvertMessageDcs()492 void GsmSmsMessage::ConvertMessageDcs()
493 {
494     if (smsTpdu_ == nullptr) {
495         TELEPHONY_LOGE("GsmSmsMessage::ConvertMessageDcs smsTpdu is null");
496         return;
497     }
498     switch (smsTpdu_->tpduType) {
499         case SMS_TPDU_DELIVER:
500             bCompressed_ = smsTpdu_->data.deliver.dcs.bCompressed;
501             codingScheme_ = smsTpdu_->data.deliver.dcs.codingScheme;
502             codingGroup_ = smsTpdu_->data.deliver.dcs.codingGroup;
503             bIndActive_ = smsTpdu_->data.deliver.dcs.bIndActive;
504             bMwi_ = smsTpdu_->data.deliver.dcs.bMWI;
505             bMwiSense_ = smsTpdu_->data.deliver.dcs.bIndActive; /* Indicates vmail notification set/clear */
506             ConvertMessageClass(smsTpdu_->data.deliver.dcs.msgClass);
507             break;
508         case SMS_TPDU_STATUS_REP:
509             bCompressed_ = smsTpdu_->data.statusRep.dcs.bCompressed;
510             codingScheme_ = smsTpdu_->data.statusRep.dcs.codingScheme;
511             codingGroup_ = smsTpdu_->data.statusRep.dcs.codingGroup;
512             bIndActive_ = smsTpdu_->data.statusRep.dcs.bIndActive;
513             ConvertMessageClass(smsTpdu_->data.statusRep.dcs.msgClass);
514             break;
515         case SMS_TPDU_SUBMIT:
516             bCompressed_ = smsTpdu_->data.submit.dcs.bCompressed;
517             codingScheme_ = smsTpdu_->data.submit.dcs.codingScheme;
518             codingGroup_ = smsTpdu_->data.submit.dcs.codingGroup;
519             bIndActive_ = smsTpdu_->data.submit.dcs.bIndActive;
520             bMwi_ = smsTpdu_->data.submit.dcs.bMWI;
521             bMwiSense_ = smsTpdu_->data.submit.dcs.bIndActive;
522             ConvertMessageClass(smsTpdu_->data.submit.dcs.msgClass);
523             break;
524         default:
525             break;
526     }
527 }
528 
ConvertUserData()529 void GsmSmsMessage::ConvertUserData()
530 {
531     int ret = 0;
532     if (smsTpdu_ == nullptr ||
533         (memset_s(&smsUserData_, sizeof(struct SmsUDPackage), 0x00, sizeof(struct SmsUDPackage)) != EOK)) {
534         TELEPHONY_LOGE("nullptr or memset_s error.");
535         return;
536     }
537 
538     size_t udLen = sizeof(SmsUDPackage);
539     size_t tpduLen = sizeof(SmsTpud);
540     switch (smsTpdu_->tpduType) {
541         case SMS_TPDU_DELIVER:
542             headerDataLen_ = smsTpdu_->data.deliver.userData.length;
543             ret = memcpy_s(&smsUserData_, udLen, &(smsTpdu_->data.deliver.userData), udLen);
544             ret = ret && memcpy_s(&smsWapPushUserData_, tpduLen, &(smsTpdu_->data.deliver.udData), tpduLen);
545             break;
546         case SMS_TPDU_STATUS_REP:
547             headerDataLen_ = smsTpdu_->data.statusRep.userData.length;
548             ret = memcpy_s(&smsUserData_, udLen, &(smsTpdu_->data.statusRep.userData), udLen);
549             break;
550         case SMS_TPDU_SUBMIT:
551             headerDataLen_ = smsTpdu_->data.submit.userData.length;
552             ret = memcpy_s(&smsUserData_, udLen, &(smsTpdu_->data.submit.userData), udLen);
553             break;
554         default:
555             break;
556     }
557     if (ret != EOK) {
558         TELEPHONY_LOGE("memset_s error.");
559         return;
560     }
561     if (smsUserData_.length > 0) {
562         uint8_t buff[MAX_MSG_TEXT_LEN + 1] = { 0 };
563         if (codingScheme_ == DATA_CODING_7BIT) {
564             MsgLangInfo langInfo;
565             langInfo.bSingleShift = false;
566             langInfo.bLockingShift = false;
567             int dataSize = TextCoder::Instance().Gsm7bitToUtf8(
568                 buff, MAX_MSG_TEXT_LEN, reinterpret_cast<uint8_t *>(smsUserData_.data), smsUserData_.length, langInfo);
569             visibleMessageBody_.insert(0, reinterpret_cast<char *>(buff), dataSize);
570         } else if (codingScheme_ == DATA_CODING_UCS2) {
571             int dataSize = TextCoder::Instance().Ucs2ToUtf8(
572                 buff, MAX_MSG_TEXT_LEN, reinterpret_cast<uint8_t *>(smsUserData_.data), smsUserData_.length);
573             visibleMessageBody_.insert(0, reinterpret_cast<char *>(buff), dataSize);
574         } else if (codingScheme_ == DATA_CODING_8BIT) {
575             visibleMessageBody_.insert(0, static_cast<char *>(smsUserData_.data), smsUserData_.length);
576         }
577         rawUserData_.insert(0, static_cast<char *>(smsUserData_.data), smsUserData_.length);
578         rawWapPushUserData_.insert(0, smsWapPushUserData_.ud, smsWapPushUserData_.udl);
579     }
580 }
581 
SetFullText(const std::string & text)582 void GsmSmsMessage::SetFullText(const std::string &text)
583 {
584     fullText_ = text;
585 }
586 
SetDestAddress(const std::string & address)587 void GsmSmsMessage::SetDestAddress(const std::string &address)
588 {
589     destAddress_ = address;
590 }
591 
SetDestPort(uint32_t port)592 void GsmSmsMessage::SetDestPort(uint32_t port)
593 {
594     destPort_ = port;
595 }
596 
GetFullText() const597 std::string GsmSmsMessage::GetFullText() const
598 {
599     return fullText_;
600 }
601 
GetReplyAddress() const602 std::string GsmSmsMessage::GetReplyAddress() const
603 {
604     return replyAddress_;
605 }
606 
GetDestAddress() const607 std::string GsmSmsMessage::GetDestAddress() const
608 {
609     return destAddress_;
610 }
611 
GetDestPort()612 uint16_t GsmSmsMessage::GetDestPort()
613 {
614     std::shared_ptr<SmsAppPortAddr> portAddress = GetPortAddress();
615     if (portAddress == nullptr) {
616         TELEPHONY_LOGE("PortAddress is null!");
617         return DEFAULT_PORT;
618     }
619     destPort_ = static_cast<uint16_t>(portAddress->destPort);
620     return destPort_;
621 }
622 
GetIsSmsText() const623 bool GsmSmsMessage::GetIsSmsText() const
624 {
625     return bSmsText_;
626 }
627 
GetGsm() const628 bool GsmSmsMessage::GetGsm() const
629 {
630     return true;
631 }
632 
GetIsTypeZeroInd() const633 bool GsmSmsMessage::GetIsTypeZeroInd() const
634 {
635     return (GetProtocolId() == 0x40);
636 }
637 
GetIsSIMDataTypeDownload() const638 bool GsmSmsMessage::GetIsSIMDataTypeDownload() const
639 {
640     int protocolId = GetProtocolId();
641     return GetMessageClass() == SMS_SIM_MESSAGE && (protocolId == 0x7f || protocolId == 0x7c);
642 }
643 
ConvertMsgTimeStamp(const struct SmsTimeStamp & times)644 void GsmSmsMessage::ConvertMsgTimeStamp(const struct SmsTimeStamp &times)
645 {
646     if (times.format == SMS_TIME_ABSOLUTE) {
647         scTimestamp_ = SmsCommonUtils::ConvertTime(times.time.absolute);
648     } else {
649         scTimestamp_ = time(nullptr);
650     }
651 }
652 
653 // from 3GPP TS 23.040 V5.1.0 9.2.3.24.2 Special SMS Message Indication
IsSpecialMessage() const654 bool GsmSmsMessage::IsSpecialMessage() const
655 {
656     bool result = false;
657     if (GetIsTypeZeroInd()) {
658         TELEPHONY_LOGI("GsmSmsMessage:: IsTypeZeroInd");
659         result = true;
660     }
661     // 9.2.3.9 TP Protocol Identifier (TP PID)
662     if (GetIsSIMDataTypeDownload()) {
663         TELEPHONY_LOGI("GsmSmsMessage:: GetIsSIMDataTypeDownload");
664         result = true;
665     }
666     if (IsMwiSet() || IsMwiClear()) {
667         TELEPHONY_LOGI("GsmSmsMessage::Mwi Message");
668         result = true;
669     }
670     return result;
671 }
672 
DecodeMessage(uint8_t * decodeData,unsigned int len,DataCodingScheme & codingType,const std::string & msgText,bool & bAbnormal,MSG_LANGUAGE_ID_T & langId)673 int GsmSmsMessage::DecodeMessage(uint8_t *decodeData, unsigned int len, DataCodingScheme &codingType,
674     const std::string &msgText, bool &bAbnormal, MSG_LANGUAGE_ID_T &langId)
675 {
676     int decodeLen = 0;
677     int dataLen = static_cast<int>(msgText.length());
678     const unsigned int maxDecodeLen = len;
679     const uint8_t *pMsgText = reinterpret_cast<const uint8_t *>(msgText.c_str());
680 
681     if (msgText.empty()) {
682         TELEPHONY_LOGE("msgText empty.");
683         return decodeLen;
684     }
685 
686     switch (codingType) {
687         case DATA_CODING_7BIT: {
688             decodeLen = TextCoder::Instance().Utf8ToGsm7bit(
689                 decodeData, maxDecodeLen, const_cast<uint8_t *>(pMsgText), dataLen, langId);
690             break;
691         }
692         case DATA_CODING_8BIT: {
693             if (static_cast<unsigned int>(dataLen) > maxDecodeLen) {
694                 TELEPHONY_LOGE("DecodeMessage data length invalid.");
695                 return decodeLen;
696             }
697             if (memcpy_s(decodeData, maxDecodeLen, pMsgText, dataLen) != EOK) {
698                 TELEPHONY_LOGE("SplitMessage SMS_CHARSET_8BIT memcpy_s error!");
699                 return decodeLen;
700             }
701             decodeLen = dataLen;
702             break;
703         }
704         case DATA_CODING_UCS2: {
705             decodeLen = TextCoder::Instance().Utf8ToUcs2(decodeData, maxDecodeLen, pMsgText, dataLen);
706             break;
707         }
708         case DATA_CODING_AUTO:
709         default: {
710             DataCodingScheme encodeType = DATA_CODING_AUTO;
711             decodeLen = TextCoder::Instance().GsmUtf8ToAuto(decodeData, maxDecodeLen, pMsgText, dataLen, encodeType);
712             codingType = encodeType;
713             break;
714         }
715     }
716     return decodeLen;
717 }
718 } // namespace Telephony
719 } // namespace OHOS
720