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