• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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