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 23namespace OHOS { 24namespace Telephony { 25using namespace std; 26static constexpr uint16_t DEFAULT_PORT = -1; 27static constexpr uint8_t MAX_GSM_7BIT_DATA_LEN = 160; 28static constexpr uint8_t MAX_SMSC_LEN = 20; 29static constexpr uint16_t MAX_TPDU_DATA_LEN = 255; 30static constexpr uint16_t TAPI_TEXT_SIZE_MAX = 520; 31 32uint8_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 55int 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 91int 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 112int 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 140int 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 184void 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 205std::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 217std::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 265std::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 300std::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 337std::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 349std::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 362std::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 373std::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 394bool 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 430bool 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 451void 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 465void 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 478void 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 490void 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 527void 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 563void 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 591void GsmSmsMessage::SetFullText(const std::string &text) 592{ 593 fullText_ = text; 594} 595 596void GsmSmsMessage::SetDestAddress(const std::string &address) 597{ 598 destAddress_ = address; 599} 600 601void GsmSmsMessage::SetDestPort(uint32_t port) 602{ 603 destPort_ = port; 604} 605 606std::string GsmSmsMessage::GetFullText() const 607{ 608 return fullText_; 609} 610 611std::string GsmSmsMessage::GetReplyAddress() const 612{ 613 return replyAddress_; 614} 615 616std::string GsmSmsMessage::GetDestAddress() const 617{ 618 return destAddress_; 619} 620 621uint16_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 632bool GsmSmsMessage::GetIsSmsText() const 633{ 634 return bSmsText_; 635} 636 637bool GsmSmsMessage::GetGsm() const 638{ 639 return true; 640} 641 642bool GsmSmsMessage::GetIsTypeZeroInd() const 643{ 644 return (GetProtocolId() == 0x40); 645} 646 647bool GsmSmsMessage::GetIsSIMDataTypeDownload() const 648{ 649 int protocolId = GetProtocolId(); 650 return GetMessageClass() == SMS_SIM_MESSAGE && (protocolId == 0x7f || protocolId == 0x7c); 651} 652 653void 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 663bool 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 682void GsmSmsMessage::SetSmsCodingNationalType(SmsCodingNationalType smsCodingNationalType) 683{ 684 smsCodingNationalType_ = smsCodingNationalType; 685} 686 687int 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