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