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