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