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