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