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