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 ×)
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