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 "sms_base_message.h" 17 18#include "securec.h" 19#include "sms_mms_errors.h" 20#include "sms_service_manager_client.h" 21#include "telephony_errors.h" 22#include "telephony_log_wrapper.h" 23#include "text_coder.h" 24#include "unicode/brkiter.h" 25#include "unicode/rbbi.h" 26#include "unicode/unistr.h" 27#include "unicode/ucnv.h" 28 29namespace OHOS { 30namespace Telephony { 31using namespace std; 32static constexpr uint8_t PID_87 = 0xc0; 33static constexpr uint8_t PID_7 = 0x40; 34static constexpr uint8_t PID_10_LOW = 0x3f; 35static constexpr int16_t WAP_PUSH_PORT = 2948; 36static constexpr uint8_t MAX_GSM_7BIT_DATA_LEN = 160; 37static constexpr uint8_t MAX_UCS2_DATA_LEN = 140; 38static constexpr uint8_t BYTE_BITS = 8; 39static constexpr uint8_t MAX_ADD_PARAM_LEN = 12; 40static constexpr uint8_t GSM_BEAR_DATA_LEN = 140; 41static constexpr uint8_t CHARSET_7BIT_BITS = 7; 42static constexpr uint16_t TAPI_TEXT_SIZE_MAX = 520; 43const std::string CT_SMSC = "10659401"; 44 45string SmsBaseMessage::GetSmscAddr() const 46{ 47 return scAddress_; 48} 49 50void SmsBaseMessage::SetSmscAddr(const string &address) 51{ 52 scAddress_ = address; 53} 54 55string SmsBaseMessage::GetOriginatingAddress() const 56{ 57 return originatingAddress_; 58} 59 60string SmsBaseMessage::GetVisibleOriginatingAddress() const 61{ 62 return originatingAddress_; 63} 64 65enum SmsMessageClass SmsBaseMessage::GetMessageClass() const 66{ 67 return msgClass_; 68} 69 70string SmsBaseMessage::GetVisibleMessageBody() const 71{ 72 return visibleMessageBody_; 73} 74 75std::vector<uint8_t> SmsBaseMessage::GetRawPdu() const 76{ 77 return rawPdu_; 78} 79 80std::string SmsBaseMessage::GetRawUserData() const 81{ 82 return rawUserData_; 83} 84 85std::string SmsBaseMessage::GetRawWapPushUserData() const 86{ 87 return rawWapPushUserData_; 88} 89 90int64_t SmsBaseMessage::GetScTimestamp() const 91{ 92 return scTimestamp_; 93} 94 95// 3GPP TS 23.040 V5.1.0 9.2.3.9 TP Protocol Identifier (TP PID) 96bool SmsBaseMessage::IsReplaceMessage() 97{ 98 uint8_t temp = static_cast<uint8_t>(protocolId_); 99 uint8_t tempPid = temp & PID_10_LOW; 100 bReplaceMessage_ = ((temp & PID_87) == PID_7) && (tempPid > 0) && (tempPid < MAX_REPLY_PID); 101 return bReplaceMessage_; 102} 103 104// Message Waiting Indication Status storage on the USIM 105bool SmsBaseMessage::IsCphsMwi() const 106{ 107 return bCphsMwi_; 108} 109 110// 3GPP TS 23.040 V5.1.0 3.2.6 Messages Waiting 111bool SmsBaseMessage::IsMwiClear() const 112{ 113 return bMwiClear_; 114} 115 116// 3GPP TS 23.040 V5.1.0 3.2.6 Messages Waiting 117bool SmsBaseMessage::IsMwiSet() const 118{ 119 return bMwiSet_; 120} 121 122// 3GPP TS 23.040 V5.1.0 3.2.6 Messages Waiting 123bool SmsBaseMessage::IsMwiNotStore() const 124{ 125 return bMwiNotStore_; 126} 127 128int SmsBaseMessage::GetStatus() const 129{ 130 return status_; 131} 132 133bool SmsBaseMessage::IsSmsStatusReportMessage() const 134{ 135 return bStatusReportMessage_; 136} 137 138bool SmsBaseMessage::HasReplyPath() const 139{ 140 return hasReplyPath_; 141} 142 143int SmsBaseMessage::GetProtocolId() const 144{ 145 return protocolId_; 146} 147 148std::shared_ptr<SmsConcat> SmsBaseMessage::GetConcatMsg() 149{ 150 smsConcat_ = nullptr; 151 for (int i = 0; i < smsUserData_.headerCnt; i++) { 152 if (smsUserData_.header[i].udhType == UDH_CONCAT_8BIT) { 153 smsConcat_ = std::make_shared<SmsConcat>(); 154 if (smsConcat_ == nullptr) { 155 TELEPHONY_LOGE("smsConcat is nullptr."); 156 break; 157 } 158 smsConcat_->is8Bits = true; 159 smsConcat_->totalSeg = smsUserData_.header[i].udh.concat8bit.totalSeg; 160 smsConcat_->seqNum = smsUserData_.header[i].udh.concat8bit.seqNum; 161 smsConcat_->msgRef = smsUserData_.header[i].udh.concat8bit.msgRef; 162 break; 163 } else if (smsUserData_.header[i].udhType == UDH_CONCAT_16BIT) { 164 smsConcat_ = std::make_shared<SmsConcat>(); 165 if (smsConcat_ == nullptr) { 166 TELEPHONY_LOGE("smsConcat is nullptr."); 167 break; 168 } 169 smsConcat_->is8Bits = false; 170 smsConcat_->totalSeg = smsUserData_.header[i].udh.concat16bit.totalSeg; 171 smsConcat_->seqNum = smsUserData_.header[i].udh.concat16bit.seqNum; 172 smsConcat_->msgRef = smsUserData_.header[i].udh.concat16bit.msgRef; 173 break; 174 } 175 } 176 return smsConcat_; 177} 178 179std::shared_ptr<SmsAppPortAddr> SmsBaseMessage::GetPortAddress() 180{ 181 portAddress_ = nullptr; 182 for (int i = 0; i < smsUserData_.headerCnt; i++) { 183 if (smsUserData_.header[i].udhType == UDH_APP_PORT_8BIT) { 184 portAddress_ = std::make_shared<SmsAppPortAddr>(); 185 if (portAddress_ == nullptr) { 186 TELEPHONY_LOGE("portAddress_ is nullptr."); 187 break; 188 } 189 portAddress_->is8Bits = true; 190 portAddress_->destPort = smsUserData_.header[i].udh.appPort8bit.destPort; 191 portAddress_->originPort = smsUserData_.header[i].udh.appPort8bit.originPort; 192 break; 193 } else if (smsUserData_.header[i].udhType == UDH_APP_PORT_16BIT) { 194 portAddress_ = std::make_shared<SmsAppPortAddr>(); 195 if (portAddress_ == nullptr) { 196 TELEPHONY_LOGE("portAddress_ is nullptr."); 197 break; 198 } 199 portAddress_->is8Bits = false; 200 portAddress_->destPort = smsUserData_.header[i].udh.appPort16bit.destPort; 201 portAddress_->originPort = smsUserData_.header[i].udh.appPort16bit.originPort; 202 break; 203 } 204 } 205 return portAddress_; 206} 207 208std::shared_ptr<SpecialSmsIndication> SmsBaseMessage::GetSpecialSmsInd() 209{ 210 specialSmsInd_ = nullptr; 211 for (int i = 0; i < smsUserData_.headerCnt; i++) { 212 if (smsUserData_.header[i].udhType == UDH_SPECIAL_SMS) { 213 specialSmsInd_ = std::make_shared<SpecialSmsIndication>(); 214 if (specialSmsInd_ == nullptr) { 215 TELEPHONY_LOGE("specialSmsInd_ is nullptr."); 216 break; 217 } 218 specialSmsInd_->bStore = smsUserData_.header[i].udh.specialInd.bStore; 219 specialSmsInd_->msgInd = smsUserData_.header[i].udh.specialInd.msgInd; 220 specialSmsInd_->waitMsgNum = smsUserData_.header[i].udh.specialInd.waitMsgNum; 221 break; 222 } 223 } 224 return specialSmsInd_; 225} 226 227bool SmsBaseMessage::IsConcatMsg() 228{ 229 return (GetConcatMsg() == nullptr) ? false : true; 230} 231 232bool SmsBaseMessage::IsWapPushMsg() 233{ 234 std::shared_ptr<SmsAppPortAddr> portAddress = GetPortAddress(); 235 if (portAddress != nullptr && !portAddress->is8Bits) { 236 return portAddress->destPort == WAP_PUSH_PORT; 237 } 238 return false; 239} 240 241void SmsBaseMessage::ConvertMessageClass(enum SmsMessageClass msgClass) 242{ 243 switch (msgClass) { 244 case SMS_SIM_MESSAGE: 245 msgClass_ = SmsMessageClass::SMS_SIM_MESSAGE; 246 break; 247 case SMS_INSTANT_MESSAGE: 248 msgClass_ = SmsMessageClass::SMS_INSTANT_MESSAGE; 249 break; 250 case SMS_OPTIONAL_MESSAGE: 251 msgClass_ = SmsMessageClass::SMS_OPTIONAL_MESSAGE; 252 break; 253 case SMS_FORWARD_MESSAGE: 254 msgClass_ = SmsMessageClass::SMS_FORWARD_MESSAGE; 255 break; 256 default: 257 msgClass_ = SmsMessageClass::SMS_CLASS_UNKNOWN; 258 break; 259 } 260} 261 262int SmsBaseMessage::GetMsgRef() 263{ 264 return msgRef_; 265} 266 267int SmsBaseMessage::GetSegmentSize( 268 DataCodingScheme &codingScheme, int dataLen, bool bPortNum, MSG_LANGUAGE_ID_T &langId) const 269{ 270 const int multiSegSms7BitLength = 153; 271 const int multiSegSmsUcs2Length = 134; 272 const int port = 6; 273 const int lang = 3; 274 int headerSize = 0; 275 int segSize = 0; 276 int maxSize = 0; 277 if (codingScheme == DATA_CODING_7BIT || codingScheme == DATA_CODING_ASCII7BIT) { 278 maxSize = MAX_GSM_7BIT_DATA_LEN; 279 } else if (codingScheme == DATA_CODING_8BIT || codingScheme == DATA_CODING_UCS2) { 280 maxSize = MAX_UCS2_DATA_LEN; 281 } 282 283 if (bPortNum == true) { 284 headerSize += port; 285 } 286 287 if (langId != MSG_ID_RESERVED_LANG) { 288 headerSize += lang; 289 } 290 291 if (codingScheme == DATA_CODING_7BIT || codingScheme == DATA_CODING_ASCII7BIT) { 292 if ((dataLen + headerSize) > maxSize) { 293 segSize = multiSegSms7BitLength; 294 } else { 295 segSize = dataLen; 296 } 297 } else if (codingScheme == DATA_CODING_8BIT || codingScheme == DATA_CODING_UCS2) { 298 if ((dataLen + headerSize) > maxSize) { 299 segSize = multiSegSmsUcs2Length; 300 } else { 301 segSize = dataLen; 302 } 303 } 304 305 return segSize; 306} 307 308int SmsBaseMessage::GetMaxSegmentSize( 309 DataCodingScheme &codingScheme, int dataLen, bool bPortNum, MSG_LANGUAGE_ID_T &langId, int replyAddrLen) const 310{ 311 const int headerLen = 1; 312 const int concat = 5; 313 const int port = 6; 314 const int lang = 3; 315 const int reply = 2; 316 int headerSize = 0; 317 int segSize = 0; 318 int maxSize = 0; 319 if (codingScheme == DATA_CODING_7BIT || codingScheme == DATA_CODING_ASCII7BIT) { 320 maxSize = MAX_GSM_7BIT_DATA_LEN; 321 } else if (codingScheme == DATA_CODING_8BIT || codingScheme == DATA_CODING_UCS2) { 322 maxSize = MAX_UCS2_DATA_LEN; 323 } 324 if (bPortNum) { 325 headerSize += port; 326 } 327 if (langId != MSG_ID_RESERVED_LANG) { 328 headerSize += lang; 329 } 330 if (replyAddrLen > 0) { 331 headerSize += reply; 332 headerSize += replyAddrLen; 333 } 334 if (codingScheme == DATA_CODING_7BIT || codingScheme == DATA_CODING_ASCII7BIT) { 335 if ((dataLen + headerSize) > maxSize) { 336 segSize = 337 ((GSM_BEAR_DATA_LEN * BYTE_BITS) - ((headerLen + concat + headerSize) * BYTE_BITS)) / CHARSET_7BIT_BITS; 338 } else { 339 segSize = maxSize - headerSize; 340 } 341 } else if (codingScheme == DATA_CODING_8BIT || codingScheme == DATA_CODING_UCS2) { 342 if ((dataLen + headerSize) > maxSize) { 343 segSize = GSM_BEAR_DATA_LEN - (headerLen + concat + headerSize); 344 } else { 345 segSize = maxSize - headerSize; 346 } 347 } 348 return segSize; 349} 350 351void SmsBaseMessage::ConvertSpiltToUtf8(SplitInfo &split, const DataCodingScheme &codingType) 352{ 353 if (split.encodeData.size() <= 0) { 354 TELEPHONY_LOGE("data is null"); 355 return; 356 } 357 358 int dataSize = 0; 359 uint8_t buff[MAX_MSG_TEXT_LEN + 1] = { 0 }; 360 switch (codingType) { 361 case DATA_CODING_7BIT: { 362 MsgLangInfo langInfo = { 363 0, 364 }; 365 langInfo.bSingleShift = false; 366 langInfo.bLockingShift = false; 367 dataSize = TextCoder::Instance().Gsm7bitToUtf8( 368 buff, MAX_MSG_TEXT_LEN, split.encodeData.data(), split.encodeData.size(), langInfo); 369 break; 370 } 371 case DATA_CODING_UCS2: { 372 dataSize = TextCoder::Instance().Ucs2ToUtf8( 373 buff, MAX_MSG_TEXT_LEN, split.encodeData.data(), split.encodeData.size()); 374 break; 375 } 376 default: { 377 if (split.encodeData.size() > sizeof(buff)) { 378 TELEPHONY_LOGE("AnalsisDeliverMsg data length invalid."); 379 return; 380 } 381 if (memcpy_s(buff, sizeof(buff), split.encodeData.data(), split.encodeData.size()) != EOK) { 382 TELEPHONY_LOGE("AnalsisDeliverMsg memcpy_s fail."); 383 return; 384 } 385 dataSize = static_cast<int>(split.encodeData.size()); 386 buff[dataSize] = '\0'; 387 break; 388 } 389 } 390 391 split.text.insert(0, reinterpret_cast<char *>(buff), dataSize); 392 TELEPHONY_LOGI("split text"); 393} 394void SmsBaseMessage::SplitMessageUcs2(std::vector<struct SplitInfo> &splitResult, const uint8_t* decodeData, 395 int32_t encodeLen, int32_t segSize, DataCodingScheme &codingType) 396{ 397 // this 3 para divide 2 because breakiterator class is init by a uint16_t pointer. 398 int32_t utf16Multiples = 2; 399 int32_t dataSize = encodeLen / utf16Multiples; 400 int32_t segSizeHalf = segSize / utf16Multiples; 401 int32_t index = 0; 402 int32_t oneByte = 1; 403 int32_t bits = 8; 404 MSG_LANGUAGE_ID_T langId = MSG_ID_RESERVED_LANG; 405 /* 406 * decodeData is uint8_t array, in order to init breakiterator class, need a uint16_t array. sample:[0xa0,0xa1, 407 * 0xa2,0xa3] become [0xa1a2,0xa3a4] 408 */ 409 uint16_t decodeData16Bit[dataSize]; 410 for (int i = 0; i < dataSize; i++) { 411 decodeData16Bit[i] = (decodeData[i * utf16Multiples] << bits) | decodeData[i * utf16Multiples + oneByte]; 412 } 413 /* 414 * init breakiterator class. attention: createCharacterInstance is a factory method, in fact breakiterator is 415 * a pure abstract class, this fuction creat a object of subclass rulebasedbreakiterator. 416 */ 417 icu::UnicodeString fullData(decodeData16Bit, dataSize); 418 UErrorCode status = U_ZERO_ERROR; 419 icu::BreakIterator* fullDataIter = icu::BreakIterator::createCharacterInstance(NULL, status); 420 if (U_FAILURE(status)) { 421 TELEPHONY_LOGE("Failed to create break iterator"); 422 return; 423 } 424 // let breakiterator object point data need to operate 425 fullDataIter->setText(fullData); 426 // let iterator point zero element 427 fullDataIter->first(); 428 // operation of segment except the last one, such as a pdu is devide to 3 segment, 1 and 2 are operated under. 429 while ((dataSize - index) > segSizeHalf) { 430 // init struct to store data 431 struct SplitInfo splitInfo; 432 splitInfo.langId = langId; 433 splitInfo.encodeType = codingType; 434 /* 435 * judge if the end of this segment is boundary, if it is boundary, store number of segsize data in struct 436 * and move the index agter this boundary to be the head of next segment 437 * if it is not boundary, use previous function or next function(set the para to -1)to find the previous 438 * boundary before end of segment 439 */ 440 if (fullDataIter->isBoundary(index + segSizeHalf)) { 441 splitInfo.encodeData = std::vector<uint8_t>(&decodeData[index * utf16Multiples], 442 &decodeData[index * utf16Multiples] + segSize); 443 index += segSizeHalf; 444 } else { 445 splitInfo.encodeData = std::vector<uint8_t>(&decodeData[index * utf16Multiples], 446 &decodeData[index * utf16Multiples] + (fullDataIter->previous() - index) * utf16Multiples); 447 index = fullDataIter->current(); 448 } 449 ConvertSpiltToUtf8(splitInfo, codingType); 450 splitResult.push_back(splitInfo); 451 fullDataIter->first(); 452 } 453 // operation of last segment 454 struct SplitInfo splitInfo; 455 splitInfo.langId = langId; 456 splitInfo.encodeType = codingType; 457 splitInfo.encodeData = std::vector<uint8_t>(&decodeData[index * utf16Multiples], 458 &decodeData[index * utf16Multiples] + (dataSize - index) * utf16Multiples); 459 ConvertSpiltToUtf8(splitInfo, codingType); 460 splitResult.push_back(splitInfo); 461} 462 463void SmsBaseMessage::SplitMessage(std::vector<struct SplitInfo> &splitResult, const std::string &text, 464 bool force7BitCode, DataCodingScheme &codingType, bool bPortNum, const std::string &desAddr) 465{ 466 std::string msgText(text); 467 // init destination array of pdu data 468 uint8_t decodeData[(MAX_GSM_7BIT_DATA_LEN * MAX_SEGMENT_NUM) + 1]; 469 if (memset_s(decodeData, sizeof(decodeData), 0x00, sizeof(decodeData)) != EOK) { 470 TELEPHONY_LOGE("SplitMessage memset_s error!"); 471 return; 472 } 473 int encodeLen = 0; 474 bool bAbnormal = false; 475 MSG_LANGUAGE_ID_T langId = MSG_ID_RESERVED_LANG; 476 codingType = force7BitCode ? DATA_CODING_7BIT : DATA_CODING_AUTO; 477 if (CT_SMSC.compare(desAddr) == 0) { 478 codingType = DATA_CODING_8BIT; 479 } 480 /* 481 * src is utf-8 code, DecodeMessage function aim to trans the src to dest unicode method depend on above operation 482 * encodeLen means the data length agter trans(although the dest unicode method is ucs2 or utf16, the length is the 483 * count of uint8_t) such as utf8 is 0x41, trans utf16 is 0x00,0x41, the length is 2 484 * after DecodeMessage function, the codingType will become DATA_CODING_UCS2 although before is DATA_CODING_AUTO 485 */ 486 encodeLen = DecodeMessage(decodeData, sizeof(decodeData), codingType, msgText, bAbnormal, langId); 487 if (encodeLen <= 0) { 488 TELEPHONY_LOGE("encodeLen Less than or equal to 0"); 489 return; 490 } 491 int segSize = 0; 492 int segCount = 0; 493 // get segment length mainly according to codingType. 494 segSize = GetSegmentSize(codingType, encodeLen, bPortNum, langId); 495 if (segSize > 0) { 496 segCount = ceil((double)encodeLen / (double)segSize); 497 } 498 /* 499 * under code is a special condition: the length of pdu data is over segSize conculated above and codingType is 500 * utf16(although the codingType displayed is ucs2). because in this condition a emoji(takeover 4 bytes in utf16) 501 * may be cut in 2 parts(first 2 byte in segment1 and last 2 in segment 2), under code will avoid this situation. 502 */ 503 if (codingType == DATA_CODING_UCS2 && segCount > 1) { 504 SplitMessageUcs2(splitResult, decodeData, encodeLen, segSize, codingType); 505 } else { 506 int32_t index = 0; 507 for (int i = 0; i < segCount; i++) { 508 int userDataLen = 0; 509 struct SplitInfo splitInfo; 510 splitInfo.langId = langId; 511 splitInfo.encodeType = codingType; 512 uint8_t textData[TAPI_TEXT_SIZE_MAX + 1]; 513 (void)memset_s(textData, sizeof(textData), 0x00, sizeof(textData)); 514 if ((i + 1) == segCount) { 515 userDataLen = encodeLen - (i * segSize); 516 } else { 517 userDataLen = segSize; 518 } 519 splitInfo.encodeData = std::vector<uint8_t>(&decodeData[index], &decodeData[index] + userDataLen); 520 ConvertSpiltToUtf8(splitInfo, codingType); 521 splitResult.push_back(splitInfo); 522 index += segSize; 523 } 524 } 525} 526 527int32_t SmsBaseMessage::GetSmsSegmentsInfo(const std::string &message, bool force7BitCode, LengthInfo &lenInfo) 528{ 529 uint8_t decodeData[(MAX_GSM_7BIT_DATA_LEN * MAX_SEGMENT_NUM) + 1]; 530 if (memset_s(decodeData, sizeof(decodeData), 0x00, sizeof(decodeData)) != EOK) { 531 TELEPHONY_LOGE("SplitMessage memset_s error!"); 532 return TELEPHONY_ERR_MEMSET_FAIL; 533 } 534 const uint8_t smsEncodingUnkown = 0; 535 const uint8_t smsEncoding7Bit = 1; 536 const uint8_t smsEncoding8Bit = 2; 537 const uint8_t smsEncoding16Bit = 3; 538 int encodeLen = 0; 539 bool bAbnormal = false; 540 MSG_LANGUAGE_ID_T langId = MSG_ID_RESERVED_LANG; 541 DataCodingScheme codingType = force7BitCode ? DATA_CODING_7BIT : DATA_CODING_AUTO; 542 encodeLen = DecodeMessage(decodeData, sizeof(decodeData), codingType, message, bAbnormal, langId); 543 if (encodeLen <= 0) { 544 TELEPHONY_LOGE("encodeLen Less than or equal to 0"); 545 return SMS_MMS_DECODE_DATA_EMPTY; 546 } 547 int segSize = GetMaxSegmentSize(codingType, encodeLen, false, langId, MAX_ADD_PARAM_LEN); 548 TELEPHONY_LOGI("segSize = %{public}d", segSize); 549 lenInfo.msgEncodeCount = static_cast<uint16_t>(encodeLen); 550 if (codingType == DATA_CODING_7BIT || codingType == DATA_CODING_ASCII7BIT) { 551 lenInfo.dcs = smsEncoding7Bit; 552 } else if (codingType == DATA_CODING_UCS2) { 553 lenInfo.dcs = smsEncoding16Bit; 554 } else if (codingType == DATA_CODING_8BIT) { 555 lenInfo.dcs = smsEncoding8Bit; 556 } else { 557 lenInfo.dcs = smsEncodingUnkown; 558 } 559 if (lenInfo.dcs == smsEncoding16Bit) { 560 lenInfo.msgEncodeCount = lenInfo.msgEncodeCount / 2; 561 segSize = segSize / 2; 562 } 563 if (segSize != 0) { 564 lenInfo.msgRemainCount = static_cast<uint8_t>(((segSize - (lenInfo.msgEncodeCount % segSize))) % segSize); 565 lenInfo.msgSegCount = ceil(static_cast<double>(lenInfo.msgEncodeCount) / static_cast<double>(segSize)); 566 } 567 return TELEPHONY_ERR_SUCCESS; 568} 569 570int32_t SmsBaseMessage::GetIndexOnSim() const 571{ 572 return indexOnSim_; 573} 574 575void SmsBaseMessage::SetIndexOnSim(int32_t index) 576{ 577 indexOnSim_ = index; 578} 579} // namespace Telephony 580} // namespace OHOS 581