1 /*
2 * Copyright (C) 2021 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 "telephony_log_wrapper.h"
19
20 namespace OHOS {
21 namespace Telephony {
22 using namespace std;
GetSmscAddr() const23 string SmsBaseMessage::GetSmscAddr() const
24 {
25 return scAddress_;
26 }
27
SetSmscAddr(const string & address)28 void SmsBaseMessage::SetSmscAddr(const string &address)
29 {
30 scAddress_ = address;
31 }
32
GetOriginatingAddress() const33 string SmsBaseMessage::GetOriginatingAddress() const
34 {
35 return originatingAddress_;
36 }
37
GetVisibleOriginatingAddress() const38 string SmsBaseMessage::GetVisibleOriginatingAddress() const
39 {
40 return originatingAddress_;
41 }
42
GetMessageClass() const43 enum SmsMessageClass SmsBaseMessage::GetMessageClass() const
44 {
45 return msgClass_;
46 }
47
GetVisibleMessageBody() const48 string SmsBaseMessage::GetVisibleMessageBody() const
49 {
50 return visibleMessageBody_;
51 }
52
GetRawPdu() const53 std::vector<uint8_t> SmsBaseMessage::GetRawPdu() const
54 {
55 return rawPdu_;
56 }
57
GetRawUserData() const58 std::string SmsBaseMessage::GetRawUserData() const
59 {
60 return rawUserData_;
61 }
62
GetScTimestamp() const63 long SmsBaseMessage::GetScTimestamp() const
64 {
65 return scTimestamp_;
66 }
67
68 // 3GPP TS 23.040 V5.1.0 9.2.3.9 TP Protocol Identifier (TP PID)
IsReplaceMessage()69 bool SmsBaseMessage::IsReplaceMessage()
70 {
71 uint8_t temp = static_cast<uint8_t>(protocolId_);
72 uint8_t tempPid = temp & PID_10_LOW;
73 bReplaceMessage_ = ((temp & PID_87) == PID_7) && (tempPid > 0) && (tempPid < MAX_REPLY_PID);
74 return bReplaceMessage_;
75 }
76
77 // Message Waiting Indication Status storage on the USIM
IsCphsMwi() const78 bool SmsBaseMessage::IsCphsMwi() const
79 {
80 return bCphsMwi_;
81 }
82
83 // 3GPP TS 23.040 V5.1.0 3.2.6 Messages Waiting
IsMwiClear() const84 bool SmsBaseMessage::IsMwiClear() const
85 {
86 return bMwiClear_;
87 }
88
89 // 3GPP TS 23.040 V5.1.0 3.2.6 Messages Waiting
IsMwiSet() const90 bool SmsBaseMessage::IsMwiSet() const
91 {
92 return bMwiSet_;
93 }
94
95 // 3GPP TS 23.040 V5.1.0 3.2.6 Messages Waiting
IsMwiNotStore() const96 bool SmsBaseMessage::IsMwiNotStore() const
97 {
98 return bMwiNotStore_;
99 }
100
GetStatus() const101 int SmsBaseMessage::GetStatus() const
102 {
103 return status_;
104 }
105
IsSmsStatusReportMessage() const106 bool SmsBaseMessage::IsSmsStatusReportMessage() const
107 {
108 return bStatusReportMessage_;
109 }
110
HasReplyPath() const111 bool SmsBaseMessage::HasReplyPath() const
112 {
113 return hasReplyPath_;
114 }
115
GetProtocolId() const116 int SmsBaseMessage::GetProtocolId() const
117 {
118 return protocolId_;
119 }
120
GetConcatMsg()121 std::shared_ptr<SmsConcat> SmsBaseMessage::GetConcatMsg()
122 {
123 smsConcat_ = nullptr;
124 for (int i = 0; i < smsUserData_.headerCnt; i++) {
125 if (smsUserData_.header[i].udhType == SMS_UDH_CONCAT_8BIT) {
126 smsConcat_ = std::make_shared<SmsConcat>();
127 if (smsConcat_ == nullptr) {
128 TELEPHONY_LOGE("smsConcat is nullptr.");
129 break;
130 }
131 smsConcat_->is8Bits = true;
132 smsConcat_->totalSeg = smsUserData_.header[i].udh.concat8bit.totalSeg;
133 smsConcat_->seqNum = smsUserData_.header[i].udh.concat8bit.seqNum;
134 smsConcat_->msgRef = smsUserData_.header[i].udh.concat8bit.msgRef;
135 break;
136 } else if (smsUserData_.header[i].udhType == SMS_UDH_CONCAT_16BIT) {
137 smsConcat_ = std::make_shared<SmsConcat>();
138 if (smsConcat_ == nullptr) {
139 TELEPHONY_LOGE("smsConcat is nullptr.");
140 break;
141 }
142 smsConcat_->is8Bits = false;
143 smsConcat_->totalSeg = smsUserData_.header[i].udh.concat16bit.totalSeg;
144 smsConcat_->seqNum = smsUserData_.header[i].udh.concat16bit.seqNum;
145 smsConcat_->msgRef = smsUserData_.header[i].udh.concat16bit.msgRef;
146 break;
147 }
148 }
149 return smsConcat_;
150 }
151
GetPortAddress()152 std::shared_ptr<SmsAppPortAddr> SmsBaseMessage::GetPortAddress()
153 {
154 portAddress_ = nullptr;
155 for (int i = 0; i < smsUserData_.headerCnt; i++) {
156 if (smsUserData_.header[i].udhType == SMS_UDH_APP_PORT_8BIT) {
157 portAddress_ = std::make_shared<SmsAppPortAddr>();
158 if (portAddress_ == nullptr) {
159 TELEPHONY_LOGE("portAddress_ is nullptr.");
160 break;
161 }
162 portAddress_->is8Bits = true;
163 portAddress_->destPort = smsUserData_.header[i].udh.appPort8bit.destPort;
164 portAddress_->originPort = smsUserData_.header[i].udh.appPort8bit.originPort;
165 break;
166 } else if (smsUserData_.header[i].udhType == SMS_UDH_APP_PORT_16BIT) {
167 portAddress_ = std::make_shared<SmsAppPortAddr>();
168 if (portAddress_ == nullptr) {
169 TELEPHONY_LOGE("portAddress_ is nullptr.");
170 break;
171 }
172 portAddress_->is8Bits = false;
173 portAddress_->destPort = smsUserData_.header[i].udh.appPort16bit.destPort;
174 portAddress_->originPort = smsUserData_.header[i].udh.appPort16bit.originPort;
175 break;
176 }
177 }
178 return portAddress_;
179 }
180
GetSpecialSmsInd()181 std::shared_ptr<SpecialSmsIndication> SmsBaseMessage::GetSpecialSmsInd()
182 {
183 specialSmsInd_ = nullptr;
184 for (int i = 0; i < smsUserData_.headerCnt; i++) {
185 if (smsUserData_.header[i].udhType == SMS_UDH_SPECIAL_SMS) {
186 specialSmsInd_ = std::make_shared<SpecialSmsIndication>();
187 if (specialSmsInd_ == nullptr) {
188 TELEPHONY_LOGE("specialSmsInd_ is nullptr.");
189 break;
190 }
191 specialSmsInd_->bStore = smsUserData_.header[i].udh.specialInd.bStore;
192 specialSmsInd_->msgInd = smsUserData_.header[i].udh.specialInd.msgInd;
193 specialSmsInd_->waitMsgNum = smsUserData_.header[i].udh.specialInd.waitMsgNum;
194 break;
195 }
196 }
197 return specialSmsInd_;
198 }
199
IsConcatMsg()200 bool SmsBaseMessage::IsConcatMsg()
201 {
202 return (GetConcatMsg() == nullptr) ? false : true;
203 }
204
IsWapPushMsg()205 bool SmsBaseMessage::IsWapPushMsg()
206 {
207 std::shared_ptr<SmsAppPortAddr> portAddress = GetPortAddress();
208 if (portAddress != nullptr && !portAddress->is8Bits) {
209 return portAddress->destPort == WAP_PUSH_PORT;
210 }
211 return false;
212 }
213
ConvertMessageClass(enum SmsMessageClass msgClass)214 void SmsBaseMessage::ConvertMessageClass(enum SmsMessageClass msgClass)
215 {
216 switch (msgClass) {
217 case SMS_SIM_MESSAGE:
218 msgClass_ = SmsMessageClass::SMS_SIM_MESSAGE;
219 break;
220 case SMS_INSTANT_MESSAGE:
221 msgClass_ = SmsMessageClass::SMS_INSTANT_MESSAGE;
222 break;
223 case SMS_OPTIONAL_MESSAGE:
224 msgClass_ = SmsMessageClass::SMS_OPTIONAL_MESSAGE;
225 break;
226 case SMS_FORWARD_MESSAGE:
227 msgClass_ = SmsMessageClass::SMS_FORWARD_MESSAGE;
228 break;
229 default:
230 msgClass_ = SmsMessageClass::SMS_CLASS_UNKNOWN;
231 break;
232 }
233 }
234
GetMsgRef()235 int SmsBaseMessage::GetMsgRef()
236 {
237 return msgRef_;
238 }
239
GetSegmentSize(SmsCodingScheme & codingScheme,int dataLen,bool bPortNum,MSG_LANGUAGE_ID_T & langId,int replyAddrLen) const240 int SmsBaseMessage::GetSegmentSize(
241 SmsCodingScheme &codingScheme, int dataLen, bool bPortNum, MSG_LANGUAGE_ID_T &langId, int replyAddrLen) const
242 {
243 const int headerLen = 1;
244 const int concat = 5;
245 const int port = 6;
246 const int lang = 3;
247 const int reply = 2;
248 int headerSize = 0;
249 int segSize = 0;
250 int maxSize = 0;
251 if (codingScheme == SMS_CODING_7BIT || codingScheme == SMS_CODING_ASCII7BIT) {
252 maxSize = MAX_GSM_7BIT_DATA_LEN;
253 } else if (codingScheme == SMS_CODING_8BIT || codingScheme == SMS_CODING_UCS2) {
254 maxSize = MAX_UCS2_DATA_LEN;
255 }
256
257 if (bPortNum == true) {
258 headerSize += port;
259 }
260
261 if (langId != MSG_ID_RESERVED_LANG) {
262 headerSize += lang;
263 }
264
265 if (replyAddrLen > 0) {
266 headerSize += reply;
267 headerSize += replyAddrLen;
268 }
269
270 if (codingScheme == SMS_CODING_7BIT || codingScheme == SMS_CODING_ASCII7BIT) {
271 if ((dataLen + headerSize) > maxSize) {
272 segSize = ((GSM_BEAR_DATA_LEN * BYTE_BITS) - ((headerLen + concat + headerSize) * BYTE_BITS)) /
273 CHARSET_7BIT_BITS;
274 } else {
275 segSize = dataLen;
276 }
277 } else if (codingScheme == SMS_CODING_8BIT || codingScheme == SMS_CODING_UCS2) {
278 if ((dataLen + headerSize) > maxSize) {
279 segSize = GSM_BEAR_DATA_LEN - (headerLen + concat + headerSize);
280 } else {
281 segSize = dataLen;
282 }
283 }
284
285 return segSize;
286 }
287
GetMaxSegmentSize(SmsCodingScheme & codingScheme,int dataLen,bool bPortNum,MSG_LANGUAGE_ID_T & langId,int replyAddrLen) const288 int SmsBaseMessage::GetMaxSegmentSize(
289 SmsCodingScheme &codingScheme, int dataLen, bool bPortNum, MSG_LANGUAGE_ID_T &langId, int replyAddrLen) const
290 {
291 const int headerLen = 1;
292 const int concat = 5;
293 const int port = 6;
294 const int lang = 3;
295 const int reply = 2;
296 int headerSize = 0;
297 int segSize = 0;
298 int maxSize = 0;
299 if (codingScheme == SMS_CODING_7BIT || codingScheme == SMS_CODING_ASCII7BIT) {
300 maxSize = MAX_GSM_7BIT_DATA_LEN;
301 } else if (codingScheme == SMS_CODING_8BIT || codingScheme == SMS_CODING_UCS2) {
302 maxSize = MAX_UCS2_DATA_LEN;
303 }
304 if (bPortNum) {
305 headerSize += port;
306 }
307 if (langId != MSG_ID_RESERVED_LANG) {
308 headerSize += lang;
309 }
310 if (replyAddrLen > 0) {
311 headerSize += reply;
312 headerSize += replyAddrLen;
313 }
314 if (codingScheme == SMS_CODING_7BIT || codingScheme == SMS_CODING_ASCII7BIT) {
315 if ((dataLen + headerSize) > maxSize) {
316 segSize = ((GSM_BEAR_DATA_LEN * BYTE_BITS) - ((headerLen + concat + headerSize) * BYTE_BITS)) /
317 CHARSET_7BIT_BITS;
318 } else {
319 segSize = maxSize - headerSize;
320 }
321 } else if (codingScheme == SMS_CODING_8BIT || codingScheme == SMS_CODING_UCS2) {
322 if ((dataLen + headerSize) > maxSize) {
323 segSize = GSM_BEAR_DATA_LEN - (headerLen + concat + headerSize);
324 } else {
325 segSize = maxSize - headerSize;
326 }
327 }
328 return segSize;
329 }
330
ConvertSpiltToUtf8(SplitInfo & split,const SmsCodingScheme & codingType)331 void SmsBaseMessage::ConvertSpiltToUtf8(SplitInfo &split, const SmsCodingScheme &codingType)
332 {
333 MsgTextConvert *textCvt = MsgTextConvert::Instance();
334 if (textCvt == nullptr || split.encodeData.size() <= 0) {
335 TELEPHONY_LOGE("MsgTextConvert Instance is nullptr");
336 return;
337 }
338
339 int dataSize = 0;
340 unsigned char buff[MAX_MSG_TEXT_LEN + 1] = {0};
341 switch (codingType) {
342 case SMS_CODING_7BIT: {
343 MsgLangInfo langInfo = {
344 0,
345 };
346 langInfo.bSingleShift = false;
347 langInfo.bLockingShift = false;
348 dataSize = textCvt->ConvertGSM7bitToUTF8(
349 buff, MAX_MSG_TEXT_LEN, split.encodeData.data(), split.encodeData.size(), &langInfo);
350 break;
351 }
352 case SMS_CODING_UCS2: {
353 dataSize = textCvt->ConvertUCS2ToUTF8(
354 buff, MAX_MSG_TEXT_LEN, split.encodeData.data(), split.encodeData.size());
355 break;
356 }
357 default: {
358 if (memcpy_s(buff, sizeof(buff), split.encodeData.data(), split.encodeData.size()) != EOK) {
359 TELEPHONY_LOGE("AnalsisDeliverMsg memcpy_s fail.");
360 return;
361 }
362 dataSize = split.encodeData.size();
363 buff[dataSize] = '\0';
364 break;
365 }
366 }
367
368 split.text.insert(0, (char *)buff, dataSize);
369 TELEPHONY_LOGI("split text");
370 }
371
SplitMessage(std::vector<struct SplitInfo> & splitResult,const std::string & text,bool force7BitCode,SmsCodingScheme & codingType)372 void SmsBaseMessage::SplitMessage(std::vector<struct SplitInfo> &splitResult, const std::string &text,
373 bool force7BitCode, SmsCodingScheme &codingType)
374 {
375 std::string msgText(text);
376 unsigned char decodeData[(MAX_GSM_7BIT_DATA_LEN * MAX_SEGMENT_NUM) + 1];
377 if (memset_s(decodeData, sizeof(decodeData), 0x00, sizeof(decodeData)) != EOK) {
378 TELEPHONY_LOGE("SplitMessage memset_s error!");
379 return;
380 }
381
382 int encodeLen = 0;
383 bool bAbnormal = false;
384 MSG_LANGUAGE_ID_T langId = MSG_ID_RESERVED_LANG;
385 codingType = force7BitCode ? SMS_CODING_7BIT : SMS_CODING_AUTO;
386 encodeLen = DecodeMessage(decodeData, codingType, msgText, bAbnormal, langId);
387 if (encodeLen <= 0) {
388 TELEPHONY_LOGE("encodeLen Less than or equal to 0");
389 return;
390 }
391
392 int index = 0;
393 int segSize = 0;
394 int segCount = 0;
395 segSize = GetSegmentSize(codingType, encodeLen, false, langId, MAX_ADD_PARAM_LEN);
396 if (segSize > 0) {
397 segCount = ceil((double)encodeLen / (double)segSize);
398 }
399
400 for (int i = 0; i < segCount; i++) {
401 int userDataLen = 0;
402 struct SplitInfo splitInfo;
403 splitInfo.langId = langId;
404 splitInfo.encodeType = codingType;
405 uint8_t textData[TAPI_TEXT_SIZE_MAX + 1];
406 (void)memset_s(textData, sizeof(textData), 0x00, sizeof(textData));
407 if ((i + 1) == segCount) {
408 userDataLen = encodeLen - (i * segSize);
409 } else {
410 userDataLen = segSize;
411 }
412 splitInfo.encodeData = std::vector<uint8_t>(&decodeData[index], &decodeData[index] + userDataLen);
413 ConvertSpiltToUtf8(splitInfo, codingType);
414 splitResult.push_back(splitInfo);
415 index += segSize;
416 }
417 }
418
GetSmsSegmentsInfo(const std::string & message,bool force7BitCode,LengthInfo & lenInfo)419 bool SmsBaseMessage::GetSmsSegmentsInfo(const std::string &message, bool force7BitCode, LengthInfo &lenInfo)
420 {
421 unsigned char decodeData[(MAX_GSM_7BIT_DATA_LEN * MAX_SEGMENT_NUM) + 1];
422 if (memset_s(decodeData, sizeof(decodeData), 0x00, sizeof(decodeData)) != EOK) {
423 TELEPHONY_LOGE("SplitMessage memset_s error!");
424 return false;
425 }
426 const uint8_t smsEncodingUnkown = 0;
427 const uint8_t smsEncoding7Bit = 1;
428 const uint8_t smsEncoding8Bit = 2;
429 const uint8_t smsEncoding16Bit = 3;
430 int encodeLen = 0;
431 bool bAbnormal = false;
432 MSG_LANGUAGE_ID_T langId = MSG_ID_RESERVED_LANG;
433 SmsCodingScheme codingType = force7BitCode ? SMS_CODING_7BIT : SMS_CODING_AUTO;
434 encodeLen = DecodeMessage(decodeData, codingType, message, bAbnormal, langId);
435 if (encodeLen <= 0) {
436 TELEPHONY_LOGE("encodeLen Less than or equal to 0");
437 return false;
438 }
439 int segSize = GetMaxSegmentSize(codingType, encodeLen, false, langId, MAX_ADD_PARAM_LEN);
440 TELEPHONY_LOGI("segSize = %{public}d", segSize);
441 lenInfo.msgEncodeCount = encodeLen;
442 if (codingType == SMS_CODING_7BIT || codingType == SMS_CODING_ASCII7BIT) {
443 lenInfo.dcs = smsEncoding7Bit;
444 } else if (codingType == SMS_CODING_UCS2) {
445 lenInfo.dcs = smsEncoding16Bit;
446 } else if (codingType == SMS_CODING_8BIT) {
447 lenInfo.dcs = smsEncoding8Bit;
448 } else {
449 lenInfo.dcs = smsEncodingUnkown;
450 }
451 if (lenInfo.dcs == smsEncoding16Bit) {
452 lenInfo.msgEncodeCount = lenInfo.msgEncodeCount / 2;
453 segSize = segSize / 2;
454 }
455 if (segSize != 0) {
456 lenInfo.msgRemainCount = ((segSize - (lenInfo.msgEncodeCount % segSize))) % segSize;
457 lenInfo.msgSegCount = ceil(static_cast<double>(lenInfo.msgEncodeCount) /
458 static_cast<double>(segSize));
459 }
460 return true;
461 }
462
GetIndexOnSim() const463 int32_t SmsBaseMessage::GetIndexOnSim() const
464 {
465 return indexOnSim_;
466 }
467
SetIndexOnSim(int32_t index)468 void SmsBaseMessage::SetIndexOnSim(int32_t index)
469 {
470 indexOnSim_ = index;
471 }
472 } // namespace Telephony
473 } // namespace OHOS
474