1 /*
2 * Copyright (C) 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_receive_reliability_handler.h"
17
18 #include "common_event.h"
19 #include "common_event_manager.h"
20 #include "common_event_support.h"
21 #include "gsm_sms_message.h"
22 #include "parameter.h"
23 #include "radio_event.h"
24 #include "sms_broadcast_subscriber_receiver.h"
25 #include "sms_hisysevent.h"
26 #include "sms_persist_helper.h"
27 #include "telephony_common_utils.h"
28 #include "telephony_log_wrapper.h"
29 #include "telephony_permission.h"
30 #include "want.h"
31
32 namespace OHOS {
33 namespace Telephony {
34 using namespace std;
35 using namespace EventFwk;
36 static constexpr uint16_t PDU_POS_OFFSET = 1;
37 static constexpr uint16_t PDU_START_POS = 0;
38 static constexpr uint16_t SMS_INVALID_PAGE_COUNT = 0;
39 static constexpr uint16_t SMS_SINGLE_PAGE_COUNT = 1;
40 static constexpr uint16_t SMS_PAGE_INITIAL = 1;
41 static constexpr uint16_t SMS_PAGE_INCREMENT = 1;
42 static constexpr int16_t WAP_PUSH_PORT = 2948;
43 static constexpr int16_t SMS_TEXT_PORT = -1;
44 static constexpr int32_t TEXT_MSG_RECEIVE_CODE = 0;
45 static constexpr int32_t DATA_MSG_RECEIVE_CODE = 1;
46 static constexpr int64_t ONE_DAY_TOTAL_SECONDS = 86400;
47 static constexpr uint16_t MAX_TPDU_DATA_LEN = 255;
48 static constexpr int32_t EXPIRE_DAYS_PARA_SIZE = 128;
49 static constexpr const char *SMS_EXPIRE_DAYS = "const.telephony.sms.expire.days";
50 static constexpr const char *DEFAULT_EXPIRE_DAYS = "7";
51 static constexpr const char *SMS_PAGE_COUNT_INVALID = "0";
52 static constexpr const char *SMS_BROADCAST_SLOTID_KEY = "slotId";
53 static constexpr const char *SMS_BROADCAST_PDU_KEY = "pdus";
54 static constexpr const char *SMS_BROADCAST_SMS_TYPE_KEY = "isCdma";
55 static constexpr const char *SMS_BROADCAST_SMS_TEXT_TYPE_KEY = "TEXT_SMS_RECEIVE";
56 static constexpr const char *SMS_BROADCAST_SMS_DATA_TYPE_KEY = "DATA_SMS_RECEIVE";
57 static constexpr const char *SMS_BROADCAST_SMS_PORT_KEY = "port";
58
SmsReceiveReliabilityHandler(int32_t slotId)59 SmsReceiveReliabilityHandler::SmsReceiveReliabilityHandler(int32_t slotId) : slotId_(slotId)
60 {
61 smsWapPushHandler_ = std::make_unique<SmsWapPushHandler>(slotId);
62 if (smsWapPushHandler_ == nullptr) {
63 TELEPHONY_LOGE("make sms wapPush Hander error.");
64 }
65 }
66
~SmsReceiveReliabilityHandler()67 SmsReceiveReliabilityHandler::~SmsReceiveReliabilityHandler() {}
68
DeleteExpireSmsFromDB()69 bool SmsReceiveReliabilityHandler::DeleteExpireSmsFromDB()
70 {
71 DataShare::DataSharePredicates predicates;
72 std::time_t timep;
73 int64_t currentTime = time(&timep);
74
75 std::string smsExpire = GetSmsExpire();
76 if (!IsValidDecValue(smsExpire)) {
77 TELEPHONY_LOGE("system property telephony.sms.expire.days not decimal");
78 smsExpire = DEFAULT_EXPIRE_DAYS;
79 }
80 int64_t validityDuration = std::stoi(smsExpire) * ONE_DAY_TOTAL_SECONDS;
81 int64_t deadlineTime = currentTime - validityDuration;
82 if (deadlineTime <= 0) {
83 TELEPHONY_LOGE("deadlineTime is negative");
84 return false;
85 }
86
87 predicates.EqualTo(SmsSubsection::SLOT_ID, std::to_string(slotId_))
88 ->BeginWrap()
89 ->LessThan(SmsSubsection::START_TIME, std::to_string(deadlineTime))
90 ->Or()
91 ->EqualTo(SmsSubsection::REW_PUD, "")
92 ->Or()
93 ->LessThan(SmsSubsection::SIZE, SMS_PAGE_COUNT_INVALID)
94 ->EndWrap();
95 return DelayedSingleton<SmsPersistHelper>::GetInstance()->Delete(predicates);
96 }
97
GetSmsExpire()98 std::string SmsReceiveReliabilityHandler::GetSmsExpire()
99 {
100 char smsExpireDays[EXPIRE_DAYS_PARA_SIZE] = { 0 };
101 GetParameter(SMS_EXPIRE_DAYS, DEFAULT_EXPIRE_DAYS, smsExpireDays, EXPIRE_DAYS_PARA_SIZE);
102 return smsExpireDays;
103 }
104
RemoveBlockedSms(std::vector<SmsReceiveIndexer> & dbIndexers)105 void SmsReceiveReliabilityHandler::RemoveBlockedSms(std::vector<SmsReceiveIndexer> &dbIndexers)
106 {
107 DataShare::DataSharePredicates predicates;
108 predicates.EqualTo(SmsSubsection::SLOT_ID, std::to_string(slotId_));
109 DelayedSingleton<SmsPersistHelper>::GetInstance()->Query(predicates, dbIndexers);
110
111 for (auto smsPage = dbIndexers.begin(); smsPage != dbIndexers.end();) {
112 if (CheckBlockedPhoneNumber(smsPage->GetOriginatingAddress())) {
113 TELEPHONY_LOGI("indexer display address is block");
114 smsPage = dbIndexers.erase(smsPage);
115 } else if (smsPage->GetPdu().size() == 0 || smsPage->GetPdu().size() > MAX_TPDU_DATA_LEN) {
116 smsPage = dbIndexers.erase(smsPage);
117 } else {
118 smsPage++;
119 }
120 }
121 }
122
CheckUnReceiveWapPush(std::vector<SmsReceiveIndexer> & dbIndexers)123 void SmsReceiveReliabilityHandler::CheckUnReceiveWapPush(std::vector<SmsReceiveIndexer> &dbIndexers)
124 {
125 for (auto place = dbIndexers.begin(); place != dbIndexers.end();) {
126 std::shared_ptr<vector<string>> userDataRaws = make_shared<vector<string>>();
127 userDataRaws->assign(MAX_SEGMENT_NUM, "");
128 if (place->GetDestPort() != WAP_PUSH_PORT) {
129 place++;
130 continue;
131 }
132 if (place->GetMsgCount() == SMS_SINGLE_PAGE_COUNT) {
133 GetWapPushUserDataSinglePage(*place, userDataRaws);
134 } else {
135 int32_t smsPagesCount = SMS_PAGE_INITIAL;
136 int32_t pos = static_cast<int32_t>(std::distance(dbIndexers.begin(), place));
137 GetWapPushUserDataMultipage(smsPagesCount, dbIndexers, pos, userDataRaws);
138 if (place->GetMsgCount() != smsPagesCount) {
139 place = dbIndexers.erase(place);
140 continue;
141 }
142 }
143
144 if (!userDataRaws->at(PDU_START_POS).empty()) {
145 ReadyDecodeWapPushUserData(*place, userDataRaws);
146 }
147 place = dbIndexers.erase(place);
148 }
149 }
150
GetWapPushUserDataSinglePage(SmsReceiveIndexer & indexer,std::shared_ptr<vector<string>> userDataRaws)151 void SmsReceiveReliabilityHandler::GetWapPushUserDataSinglePage(
152 SmsReceiveIndexer &indexer, std::shared_ptr<vector<string>> userDataRaws)
153 {
154 string pdu = StringUtils::StringToHex(indexer.GetPdu());
155 std::shared_ptr<SmsBaseMessage> baseMessage = GsmSmsMessage::CreateMessage(pdu);
156 if (baseMessage == nullptr) {
157 TELEPHONY_LOGE("baseMessage nullptr");
158 return;
159 }
160 userDataRaws->at(PDU_START_POS) = baseMessage->GetRawUserData();
161 }
162
GetWapPushUserDataMultipage(int32_t & smsPagesCount,std::vector<SmsReceiveIndexer> & dbIndexers,int32_t place,std::shared_ptr<vector<string>> userDataRaws)163 void SmsReceiveReliabilityHandler::GetWapPushUserDataMultipage(int32_t &smsPagesCount,
164 std::vector<SmsReceiveIndexer> &dbIndexers, int32_t place, std::shared_ptr<vector<string>> userDataRaws)
165 {
166 if (place < 0 || place >= static_cast<int32_t>(dbIndexers.size())) {
167 TELEPHONY_LOGE("place invalid");
168 return;
169 }
170 string pdu = StringUtils::StringToHex(dbIndexers[place].GetPdu());
171 std::shared_ptr<SmsBaseMessage> baseMessage = GsmSmsMessage::CreateMessage(pdu);
172 if (baseMessage == nullptr) {
173 TELEPHONY_LOGE("baseMessage nullptr");
174 return;
175 }
176 if (dbIndexers[place].GetMsgSeqId() < PDU_POS_OFFSET || dbIndexers[place].GetMsgSeqId() > MAX_SEGMENT_NUM) {
177 TELEPHONY_LOGE("seqId invalid");
178 return;
179 }
180 userDataRaws->at(dbIndexers[place].GetMsgSeqId() - PDU_POS_OFFSET) = baseMessage->GetRawUserData();
181
182 for (auto locate = dbIndexers.begin() + place + SMS_PAGE_INCREMENT; locate != dbIndexers.end();) {
183 if (dbIndexers[place].GetMsgRefId() != locate->GetMsgRefId()) {
184 locate++;
185 continue;
186 }
187 if (locate->GetPdu().size() > 0) {
188 smsPagesCount++;
189 }
190 pdu = StringUtils::StringToHex(locate->GetPdu());
191 baseMessage = GsmSmsMessage::CreateMessage(pdu);
192 if (baseMessage == nullptr) {
193 TELEPHONY_LOGE("baseMessage nullptr");
194 locate = dbIndexers.erase(locate);
195 return;
196 }
197 if (locate->GetMsgSeqId() < PDU_POS_OFFSET || locate->GetMsgSeqId() > MAX_SEGMENT_NUM) {
198 TELEPHONY_LOGE("seqId invalid");
199 locate = dbIndexers.erase(locate);
200 return;
201 }
202 userDataRaws->at(locate->GetMsgSeqId() - PDU_POS_OFFSET) = baseMessage->GetRawUserData();
203 locate = dbIndexers.erase(locate);
204 }
205 }
206
ReadyDecodeWapPushUserData(SmsReceiveIndexer & indexerObj,std::shared_ptr<vector<string>> userDataRaws)207 void SmsReceiveReliabilityHandler::ReadyDecodeWapPushUserData(
208 SmsReceiveIndexer &indexerObj, std::shared_ptr<vector<string>> userDataRaws)
209 {
210 string userDataWapPush;
211 for (auto userDataRaw : *userDataRaws) {
212 userDataWapPush.append(userDataRaw);
213 }
214 shared_ptr<SmsReceiveIndexer> indexer = std::make_shared<SmsReceiveIndexer>(indexerObj.GetPdu(),
215 indexerObj.GetTimestamp(), indexerObj.GetDestPort(), indexerObj.GetIsCdma(), indexerObj.GetOriginatingAddress(),
216 indexerObj.GetVisibleAddress(), indexerObj.GetMsgRefId(), indexerObj.GetMsgSeqId(), indexerObj.GetMsgCount(),
217 false, StringUtils::StringToHex(indexerObj.GetPdu()));
218 indexer->SetDataBaseId(indexerObj.GetDataBaseId());
219
220 if (smsWapPushHandler_ == nullptr) {
221 TELEPHONY_LOGI("smsWapPushHandler_ nullptr");
222 return;
223 }
224 if (!smsWapPushHandler_->DecodeWapPushPdu(indexer, userDataWapPush)) {
225 SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::WAP_PUSH,
226 SmsMmsErrorCode::SMS_ERROR_PDU_DECODE_FAIL, "Wap push decode wap push fail");
227 }
228 }
229
SmsReceiveReliabilityProcessing()230 void SmsReceiveReliabilityHandler::SmsReceiveReliabilityProcessing()
231 {
232 std::vector<SmsReceiveIndexer> dbIndexers;
233 RemoveBlockedSms(dbIndexers);
234
235 CheckUnReceiveWapPush(dbIndexers);
236
237 for (auto position = dbIndexers.begin(); position != dbIndexers.end();) {
238 std::shared_ptr<vector<string>> pdus = make_shared<vector<string>>();
239 if (position->GetMsgCount() == SMS_INVALID_PAGE_COUNT) {
240 position++;
241 continue;
242 } else if (position->GetMsgCount() == SMS_SINGLE_PAGE_COUNT) {
243 pdus->push_back(StringUtils::StringToHex(position->GetPdu()));
244 } else {
245 int32_t smsPagesCount = SMS_PAGE_INITIAL;
246 int32_t pos = static_cast<int32_t>(std::distance(dbIndexers.begin(), position));
247 GetSmsUserDataMultipage(smsPagesCount, dbIndexers, pos, pdus);
248 if (position->GetMsgCount() != smsPagesCount) {
249 position = dbIndexers.erase(position);
250 continue;
251 }
252 }
253 if (!pdus->at(PDU_START_POS).empty()) {
254 ReadySendSmsBroadcast(*position, pdus);
255 }
256 position = dbIndexers.erase(position);
257 }
258 }
259
GetSmsUserDataMultipage(int32_t & smsPagesCount,std::vector<SmsReceiveIndexer> & dbIndexers,int32_t position,std::shared_ptr<std::vector<std::string>> pdus)260 void SmsReceiveReliabilityHandler::GetSmsUserDataMultipage(int32_t &smsPagesCount,
261 std::vector<SmsReceiveIndexer> &dbIndexers, int32_t position, std::shared_ptr<std::vector<std::string>> pdus)
262 {
263 if (position < 0 || position >= static_cast<int32_t>(dbIndexers.size())) {
264 TELEPHONY_LOGE("position over max");
265 return;
266 }
267 pdus->assign(MAX_SEGMENT_NUM, "");
268 if (dbIndexers[position].GetMsgSeqId() < PDU_POS_OFFSET || dbIndexers[position].GetMsgSeqId() > MAX_SEGMENT_NUM) {
269 TELEPHONY_LOGE("seqId invalid");
270 return;
271 }
272 pdus->at(dbIndexers[position].GetMsgSeqId() - PDU_POS_OFFSET) =
273 StringUtils::StringToHex(dbIndexers[position].GetPdu());
274 for (auto locate = dbIndexers.begin() + position + SMS_PAGE_INCREMENT; locate != dbIndexers.end();) {
275 if (dbIndexers[position].GetMsgRefId() != locate->GetMsgRefId()) {
276 locate++;
277 continue;
278 }
279 if (locate->GetMsgSeqId() < PDU_POS_OFFSET || locate->GetMsgSeqId() > MAX_SEGMENT_NUM) {
280 TELEPHONY_LOGE("seqId invalid");
281 locate = dbIndexers.erase(locate);
282 return;
283 }
284 pdus->at(locate->GetMsgSeqId() - PDU_POS_OFFSET) = StringUtils::StringToHex(locate->GetPdu());
285 locate = dbIndexers.erase(locate);
286 smsPagesCount++;
287 }
288 }
289
ReadySendSmsBroadcast(SmsReceiveIndexer & indexerObj,std::shared_ptr<vector<string>> pdus)290 void SmsReceiveReliabilityHandler::ReadySendSmsBroadcast(
291 SmsReceiveIndexer &indexerObj, std::shared_ptr<vector<string>> pdus)
292 {
293 shared_ptr<SmsReceiveIndexer> indexer = std::make_shared<SmsReceiveIndexer>(indexerObj.GetPdu(),
294 indexerObj.GetTimestamp(), indexerObj.GetDestPort(), indexerObj.GetIsCdma(), indexerObj.GetOriginatingAddress(),
295 indexerObj.GetVisibleAddress(), indexerObj.GetMsgRefId(), indexerObj.GetMsgSeqId(), indexerObj.GetMsgCount(),
296 false, StringUtils::StringToHex(indexerObj.GetPdu()));
297 indexer->SetDataBaseId(indexerObj.GetDataBaseId());
298 SendBroadcast(indexer, pdus);
299 }
300
DeleteMessageFormDb(const uint16_t refId,const uint16_t dataBaseId)301 void SmsReceiveReliabilityHandler::DeleteMessageFormDb(const uint16_t refId, const uint16_t dataBaseId)
302 {
303 if (refId == 0 && dataBaseId == 0) {
304 TELEPHONY_LOGE("DeleteMessageFormDb fail by refId error");
305 return;
306 }
307 if (refId == 0) {
308 DataShare::DataSharePredicates predicates;
309 predicates.EqualTo(SmsSubsection::ID, std::to_string(dataBaseId));
310 DelayedSingleton<SmsPersistHelper>::GetInstance()->Delete(predicates);
311 } else {
312 DataShare::DataSharePredicates predicates;
313 predicates.EqualTo(SmsSubsection::SMS_SUBSECTION_ID, std::to_string(refId));
314 DelayedSingleton<SmsPersistHelper>::GetInstance()->Delete(predicates);
315 }
316 }
317
SendBroadcast(const std::shared_ptr<SmsReceiveIndexer> indexer,const shared_ptr<vector<string>> pdus)318 void SmsReceiveReliabilityHandler::SendBroadcast(
319 const std::shared_ptr<SmsReceiveIndexer> indexer, const shared_ptr<vector<string>> pdus)
320 {
321 if (indexer == nullptr || pdus == nullptr) {
322 TELEPHONY_LOGE("indexer or pdus is nullptr");
323 return;
324 }
325 std::vector<std::string> newPdus;
326 for (const auto &it : *pdus) {
327 if (!it.empty()) {
328 newPdus.emplace_back(it);
329 }
330 }
331
332 Want want;
333 want.SetAction(CommonEventSupport::COMMON_EVENT_SMS_RECEIVE_COMPLETED);
334 want.SetParam(SMS_BROADCAST_SLOTID_KEY, static_cast<int>(slotId_));
335 want.SetParam(SMS_BROADCAST_PDU_KEY, newPdus);
336 want.SetParam(SMS_BROADCAST_SMS_TYPE_KEY, indexer->GetIsCdma());
337 CommonEventData data;
338 data.SetWant(want);
339 if (indexer->GetIsText() || indexer->GetDestPort() == SMS_TEXT_PORT) {
340 data.SetData(SMS_BROADCAST_SMS_TEXT_TYPE_KEY);
341 data.SetCode(TEXT_MSG_RECEIVE_CODE);
342 } else {
343 data.SetData(SMS_BROADCAST_SMS_DATA_TYPE_KEY);
344 data.SetCode(DATA_MSG_RECEIVE_CODE);
345 want.SetParam(SMS_BROADCAST_SMS_PORT_KEY, static_cast<short>(indexer->GetDestPort()));
346 }
347 CommonEventPublishInfo publishInfo;
348 publishInfo.SetOrdered(true);
349 std::vector<std::string> smsPermissions;
350 smsPermissions.emplace_back(Permission::RECEIVE_MESSAGES);
351 publishInfo.SetSubscriberPermissions(smsPermissions);
352
353 MatchingSkills smsSkills;
354 smsSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SMS_RECEIVE_COMPLETED);
355 CommonEventSubscribeInfo smsSubscriberInfo(smsSkills);
356 smsSubscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
357 auto smsReceiver = std::make_shared<SmsBroadcastSubscriberReceiver>(
358 smsSubscriberInfo, shared_from_this(), indexer->GetMsgRefId(), indexer->GetDataBaseId());
359 bool cbResult = CommonEventManager::PublishCommonEvent(data, publishInfo, smsReceiver);
360 HiSysEventCBResult(cbResult);
361 }
362
HiSysEventCBResult(bool publishResult)363 void SmsReceiveReliabilityHandler::HiSysEventCBResult(bool publishResult)
364 {
365 if (!publishResult) {
366 TELEPHONY_LOGE("SendBroadcast PublishBroadcastEvent result fail");
367 SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
368 SmsMmsErrorCode::SMS_ERROR_PUBLISH_COMMON_EVENT_FAIL, "publish short message broadcast event fail");
369 return;
370 }
371 DelayedSingleton<SmsHiSysEvent>::GetInstance()->SetSmsBroadcastStartTime();
372 }
373
CheckBlockedPhoneNumber(std::string originatingAddress)374 bool SmsReceiveReliabilityHandler::CheckBlockedPhoneNumber(std::string originatingAddress)
375 {
376 return DelayedSingleton<SmsPersistHelper>::GetInstance()->QueryBlockPhoneNumber(originatingAddress);
377 }
378
CheckSmsCapable()379 bool SmsReceiveReliabilityHandler::CheckSmsCapable()
380 {
381 auto helperPtr = DelayedSingleton<SmsPersistHelper>::GetInstance();
382 if (helperPtr == nullptr) {
383 return true;
384 }
385 return helperPtr->QueryParamBoolean(SmsPersistHelper::SMS_CAPABLE_PARAM_KEY, true);
386 }
387 } // namespace Telephony
388 } // namespace OHOS