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