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