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