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