• 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_receive_handler.h"
17 #include "gsm_sms_message.h"
18 #include "radio_event.h"
19 #include "sms_common.h"
20 #include "sms_hisysevent.h"
21 #include "sms_persist_helper.h"
22 #include "sms_policy_utils.h"
23 #include "telephony_log_wrapper.h"
24 #include "iservice_registry.h"
25 #include <queue>
26 
27 namespace OHOS {
28 namespace Telephony {
29 using namespace std;
30 constexpr static uint16_t PDU_POS_OFFSET = 1;
31 constexpr static uint8_t SMS_TYPE_GSM = 1;
32 constexpr static uint8_t SMS_TYPE_CDMA = 2;
33 static const std::string WAP_SEQ_NUMBER_TAG = "0003";
34 constexpr static size_t WAP_SEQ_NUMBER_LEN = 10;
35 const std::string STR_URI = "datashare:///com.ohos.smsmmsability/sms_mms/sms_subsection";
36 const std::string EXT_URI = "datashare:///com.ohos.smsmmsability";
37 
38 std::queue<std::shared_ptr<SmsBaseMessage>> g_smsBaseMessageQueue;
39 
SmsReceiveHandler(int32_t slotId)40 SmsReceiveHandler::SmsReceiveHandler(int32_t slotId) : TelEventHandler("SmsReceiveHandler"), slotId_(slotId)
41 {
42     smsWapPushHandler_ = std::make_unique<SmsWapPushHandler>(slotId);
43     if (smsWapPushHandler_ == nullptr) {
44         TELEPHONY_LOGE("make sms wapPush Hander error.");
45     }
46     CreateRunningLockInner();
47 }
48 
~SmsReceiveHandler()49 SmsReceiveHandler::~SmsReceiveHandler() {}
50 // Function is used to judge if datashare interface is ready
IsDataShareReady()51 bool SmsReceiveHandler::IsDataShareReady()
52 {
53     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
54     if (saManager == nullptr) {
55         TELEPHONY_LOGE("Get system ability mgr failed.");
56         return false;
57     }
58     auto remoteObj = saManager->GetSystemAbility(TELEPHONY_SMS_MMS_SYS_ABILITY_ID);
59     if (remoteObj == nullptr) {
60         TELEPHONY_LOGE("Getsystemability service failed.");
61         return false;
62     }
63     std::lock_guard<std::mutex> lock(datashareMutex_);
64     std::pair<int, std::shared_ptr<DataShare::DataShareHelper>> ret =
65         DataShare::DataShareHelper::Create(remoteObj, STR_URI, EXT_URI);
66     TELEPHONY_LOGI("create data_share helper, ret=%{public}d", ret.first);
67     if (ret.first == E_OK) {
68         ret.second->Release();
69         return true;
70     }
71     return false;
72 }
73 
HandleMessageQueue()74 void SmsReceiveHandler::HandleMessageQueue()
75 {
76     uint8_t queueLength = g_smsBaseMessageQueue.size();
77     // send un-operate message to the remain receive procedure.
78     for (uint8_t i = 0; i < queueLength; i++) {
79         HandleRemainDataShare(g_smsBaseMessageQueue.front());
80         g_smsBaseMessageQueue.pop();
81         TELEPHONY_LOGI("operated a sms and there are %{public}zu sms wait to be operated",
82             g_smsBaseMessageQueue.size());
83     }
84     // give app 20s power lock time to handle receive.
85     this->SendEvent(DELAY_RELEASE_RUNNING_LOCK_EVENT_ID, DELAY_REDUCE_RUNNING_LOCK_SMS_QUEUE_TIMEOUT_MS);
86     reconnectDataShareCount_ = 0;
87     // set the flag of datashare is not ready to false.
88     alreadySendEvent_ = false;
89 }
90 
HandleReconnectEvent()91 void SmsReceiveHandler::HandleReconnectEvent()
92 {
93     if (IsDataShareReady()) {
94         std::lock_guard<std::mutex> lock(queueMutex_);
95         HandleMessageQueue();
96     } else {
97         reconnectDataShareCount_++;
98         // if retry times over 20(the datashare is not ready in 100s), stop try.
99         if (reconnectDataShareCount_ >= RECONNECT_MAX_COUNT) {
100             TELEPHONY_LOGI("Over the max reconnect count:20 and there are %{public}zu sms have not been operated",
101                 g_smsBaseMessageQueue.size());
102             reconnectDataShareCount_ = 0;
103             alreadySendEvent_ = false;
104             ReleaseRunningLock();
105         } else {
106             TELEPHONY_LOGI("Send event %{public}u times", reconnectDataShareCount_);
107             /*
108              *applylock can only hold power lock 60s, so reapply lock every 5s to ensure have entire 60s to
109              *operate sms when datashare is ready('reduce' to release and 'apply' to rehold)
110              */
111             ReduceRunningLock();
112             ApplyRunningLock();
113             this->SendEvent(RETRY_CONNECT_DATASHARE_EVENT_ID, DELAY_RETRY_CONNECT_DATASHARE_MS);
114         }
115     }
116 }
117 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)118 void SmsReceiveHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
119 {
120     if (event == nullptr) {
121         TELEPHONY_LOGE("SmsReceiveHandler::ProcessEvent event == nullptr");
122         return;
123     }
124 
125     uint32_t eventId = 0;
126     eventId = event->GetInnerEventId();
127     TELEPHONY_LOGI("SmsReceiveHandler::ProcessEvent eventId = %{public}d", eventId);
128     switch (eventId) {
129         case RadioEvent::RADIO_GSM_SMS:
130         case RadioEvent::RADIO_CDMA_SMS: {
131             HandleSmsEvent(event);
132             break;
133         }
134         case RUNNING_LOCK_TIMEOUT_EVENT_ID:
135             HandleRunningLockTimeoutEvent(event);
136             break;
137         case DELAY_RELEASE_RUNNING_LOCK_EVENT_ID:
138             ReduceRunningLock();
139             break;
140         case RETRY_CONNECT_DATASHARE_EVENT_ID: {
141             HandleReconnectEvent();
142             break;
143         }
144         default:
145             TELEPHONY_LOGE("SmsReceiveHandler::ProcessEvent Unknown eventId %{public}d", eventId);
146             break;
147     }
148 }
149 
HandleSmsEvent(const AppExecFwk::InnerEvent::Pointer & event)150 void SmsReceiveHandler::HandleSmsEvent(const AppExecFwk::InnerEvent::Pointer &event)
151 {
152     if (SmsPolicyUtils::IsSmsPolicyDisable()) {
153         TELEPHONY_LOGE("SmsReceiveHandler::ProcessEvent sms policy is disabled");
154         ReplySmsToSmsc(AckIncomeCause::SMS_ACK_RESULT_OK);
155         return;
156     }
157     ApplyRunningLock();
158     std::shared_ptr<SmsBaseMessage> message = TransformMessageInfo(event->GetSharedObject<SmsMessageInfo>());
159     if (!alreadySendEvent_) {
160         if (IsDataShareReady()) {
161             HandleReceivedSms(message);
162             this->SendEvent(DELAY_RELEASE_RUNNING_LOCK_EVENT_ID, DELAY_REDUCE_RUNNING_LOCK_TIMEOUT_MS);
163         } else {
164             HandleReceivedSmsWithoutDataShare(message);
165             this->SendEvent(RETRY_CONNECT_DATASHARE_EVENT_ID, DELAY_RETRY_CONNECT_DATASHARE_MS);
166             alreadySendEvent_ = true;
167         }
168     } else {
169         HandleReceivedSmsWithoutDataShare(message);
170     }
171 }
172 
ApplyRunningLock()173 void SmsReceiveHandler::ApplyRunningLock()
174 {
175 #ifdef ABILITY_POWER_SUPPORT
176     if (smsRunningLock_ == nullptr) {
177         CreateRunningLockInner();
178     }
179     std::lock_guard<std::mutex> lockGuard(mutexRunningLock_);
180     if (smsRunningLock_ != nullptr) {
181         smsRunningLockCount_++;
182         smsLockSerialNum_++;
183         TELEPHONY_LOGI("ApplyRunningLock, try to lock. count: %{public}d, serial: %{public}d",
184             static_cast<int>(smsRunningLockCount_), static_cast<int>(smsLockSerialNum_));
185         smsRunningLock_->Lock(RUNNING_LOCK_DEFAULT_TIMEOUT_MS); // Automatic release after the 60s.
186         this->SendEvent(RUNNING_LOCK_TIMEOUT_EVENT_ID, smsLockSerialNum_, RUNNING_LOCK_DEFAULT_TIMEOUT_MS);
187     }
188 #endif
189 }
190 
ReduceRunningLock()191 void SmsReceiveHandler::ReduceRunningLock()
192 {
193 #ifdef ABILITY_POWER_SUPPORT
194     std::lock_guard<std::mutex> lockRequest(mutexRunningLock_);
195     TELEPHONY_LOGI("ReduceRunningLock, count:%{public}d", static_cast<int>(smsRunningLockCount_));
196     if (smsRunningLock_ != nullptr) {
197         if (smsRunningLockCount_ > 1) {
198             smsRunningLockCount_--;
199         } else {
200             smsRunningLockCount_ = 0;
201             ReleaseRunningLock();
202         }
203     }
204 #endif
205 }
206 
ReleaseRunningLock()207 void SmsReceiveHandler::ReleaseRunningLock()
208 {
209 #ifdef ABILITY_POWER_SUPPORT
210     if (smsRunningLock_ == nullptr) {
211         TELEPHONY_LOGE("ReleaseRunningLock, smsRunningLock_ is nullptr");
212         return;
213     }
214     TELEPHONY_LOGI("ReleaseRunningLock, try to unlock.");
215     smsRunningLockCount_ = 0;
216     int ret = smsRunningLock_->UnLock();
217     if (ret != PowerMgr::E_GET_POWER_SERVICE_FAILED) {
218         // Call UnLock success, remove event.
219         this->RemoveEvent(RUNNING_LOCK_TIMEOUT_EVENT_ID);
220         return;
221     }
222     TELEPHONY_LOGI("ReleaseRunningLock, no found power service, retry.");
223     this->SendEvent(RUNNING_LOCK_TIMEOUT_EVENT_ID, smsLockSerialNum_, DELAY_RELEASE_RUNNING_LOCK_TIMEOUT_MS);
224 #endif
225 }
226 
CreateRunningLockInner()227 void SmsReceiveHandler::CreateRunningLockInner()
228 {
229 #ifdef ABILITY_POWER_SUPPORT
230     auto &powerMgrClient = PowerMgr::PowerMgrClient::GetInstance();
231     std::lock_guard<std::mutex> lockGuard(mutexRunningLock_);
232     smsRunningLock_ = powerMgrClient.CreateRunningLock("telSmsRunningLock",
233         PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_PHONE);
234     smsRunningLockCount_ = 0;
235     smsLockSerialNum_ = 0;
236 #endif
237 }
238 
HandleRunningLockTimeoutEvent(const AppExecFwk::InnerEvent::Pointer & event)239 void SmsReceiveHandler::HandleRunningLockTimeoutEvent(const AppExecFwk::InnerEvent::Pointer &event)
240 {
241 #ifdef ABILITY_POWER_SUPPORT
242     auto serial = event->GetParam();
243     if (serial == smsLockSerialNum_) {
244         TELEPHONY_LOGE("HandleRunningLockTimeoutEvent, serial:%{public}d, smsLockSerialNum_:%{public}d",
245             static_cast<int>(serial), static_cast<int>(smsLockSerialNum_));
246         ReleaseRunningLock();
247     }
248 #endif
249 }
250 
HandleReceivedSms(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)251 void SmsReceiveHandler::HandleReceivedSms(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
252 {
253     if (smsBaseMessage == nullptr) {
254         TELEPHONY_LOGE("smsBaseMessage is nullptr");
255         return;
256     }
257     ReplySmsToSmsc(HandleSmsByType(smsBaseMessage));
258 }
259 
HandleReceivedSmsWithoutDataShare(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)260 void SmsReceiveHandler::HandleReceivedSmsWithoutDataShare(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
261 {
262     if (smsBaseMessage == nullptr) {
263         TELEPHONY_LOGE("smsBaseMessage is nullptr");
264         return;
265     }
266     int32_t result = ReplySmsToSmsc(HandleAck(smsBaseMessage));
267     if (result) {
268         std::lock_guard lock(queueMutex_);
269         g_smsBaseMessageQueue.push(smsBaseMessage);
270         TELEPHONY_LOGI("Received a new message and pushed it in queue");
271     }
272 }
273 
CombineMessagePart(const std::shared_ptr<SmsReceiveIndexer> & indexer)274 void SmsReceiveHandler::CombineMessagePart(const std::shared_ptr<SmsReceiveIndexer> &indexer)
275 {
276     std::shared_ptr<vector<string>> pdus = make_shared<vector<string>>();
277     if ((indexer == nullptr) || (pdus == nullptr)) {
278         TELEPHONY_LOGE("indexer or pdus is nullptr");
279         return;
280     }
281     auto reliabilityHandler = std::make_shared<SmsReceiveReliabilityHandler>(slotId_);
282     if ((reliabilityHandler == nullptr)) {
283         TELEPHONY_LOGE("reliabilityHandler is nullptr");
284         return;
285     }
286     if (indexer->IsSingleMsg()) {
287         string pdu = StringUtils::StringToHex(indexer->GetPdu());
288         pdus->push_back(pdu);
289     } else {
290         if (!CombineMultiPageMessage(indexer, pdus, reliabilityHandler)) {
291             TELEPHONY_LOGI("The multi-page text didn't all arrive");
292             return;
293         }
294     }
295 
296     if (indexer->GetIsWapPushMsg()) {
297         if (smsWapPushHandler_ != nullptr) {
298             auto rawWapPushUserData = indexer->GetRawWapPushUserData();
299             if (!smsWapPushHandler_->DecodeWapPushPdu(indexer, rawWapPushUserData)) {
300                 SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::WAP_PUSH,
301                     SmsMmsErrorCode::SMS_ERROR_PDU_DECODE_FAIL, "Wap push decode wap push fail");
302             }
303         }
304         return;
305     }
306     reliabilityHandler->SendBroadcast(indexer, pdus);
307 }
308 
CombineMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> & indexer,std::shared_ptr<std::vector<std::string>> pdus,std::shared_ptr<SmsReceiveReliabilityHandler> reliabilityHandler)309 bool SmsReceiveHandler::CombineMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> &indexer,
310     std::shared_ptr<std::vector<std::string>> pdus, std::shared_ptr<SmsReceiveReliabilityHandler> reliabilityHandler)
311 {
312     int msgSeg = static_cast<int>(indexer->GetMsgCount());
313     pdus->assign(msgSeg, "");
314     int8_t notNullPart = msgSeg;
315     std::vector<SmsReceiveIndexer> dbIndexers;
316     DataShare::DataSharePredicates predicates;
317     predicates.EqualTo(SmsSubsection::SENDER_NUMBER, indexer->GetOriginatingAddress())
318         ->And()
319         ->EqualTo(SmsSubsection::SMS_SUBSECTION_ID, std::to_string(indexer->GetMsgRefId()))
320         ->And()
321         ->EqualTo(SmsSubsection::SIZE, std::to_string(indexer->GetMsgCount()));
322     DelayedSingleton<SmsPersistHelper>::GetInstance()->Query(predicates, dbIndexers);
323     int8_t count = 0;
324     for (const auto &v : dbIndexers) {
325         ++count;
326         string pdu = StringUtils::StringToHex(v.GetPdu());
327         if ((v.GetMsgSeqId() - PDU_POS_OFFSET >= msgSeg) || (v.GetMsgSeqId() - PDU_POS_OFFSET < 0)) {
328             reliabilityHandler->DeleteMessageFormDb(indexer->GetMsgRefId());
329             return false;
330         }
331         pdus->at(v.GetMsgSeqId() - PDU_POS_OFFSET) = pdu;
332         if (v.GetPdu().size() == 0) {
333             --notNullPart;
334         }
335     }
336     if ((count != msgSeg) || (pdus->empty()) || (notNullPart != msgSeg)) {
337         return false;
338     }
339     UpdateMultiPageMessage(indexer, pdus);
340     return true;
341 }
342 
UpdateMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> & indexer,std::shared_ptr<std::vector<std::string>> pdus)343 void SmsReceiveHandler::UpdateMultiPageMessage(
344     const std::shared_ptr<SmsReceiveIndexer> &indexer, std::shared_ptr<std::vector<std::string>> pdus)
345 {
346     if ((indexer == nullptr) || (pdus == nullptr) || (pdus->empty())) {
347         TELEPHONY_LOGE("indexer or pdus is null");
348         return;
349     }
350     std::string messagBody;
351     std::string userDataRaw;
352     std::string rawWapPushUserData;
353     for (const auto &pdu : *pdus) {
354         if (pdu.empty()) {
355             continue;
356         }
357         std::shared_ptr<SmsBaseMessage> baseMessage = GsmSmsMessage::CreateMessage(pdu);
358         if (baseMessage == nullptr) {
359             continue;
360         }
361         messagBody.append(baseMessage->GetVisibleMessageBody());
362         userDataRaw.append(baseMessage->GetRawUserData());
363         if (!indexer->GetIsWapPushMsg()) {
364             continue;
365         }
366         auto wapDataHex = StringUtils::StringToHex(baseMessage->GetRawWapPushUserData());
367         if (wapDataHex.substr(0, WAP_SEQ_NUMBER_TAG.size()) == WAP_SEQ_NUMBER_TAG) {
368             rawWapPushUserData.append(StringUtils::HexToString(wapDataHex.substr(WAP_SEQ_NUMBER_LEN)));
369         } else {
370             rawWapPushUserData.append(StringUtils::HexToString(wapDataHex));
371         }
372     }
373 
374     indexer->SetVisibleMessageBody(messagBody);
375     indexer->SetRawUserData(userDataRaw);
376     if (indexer->GetIsWapPushMsg()) {
377         indexer->SetRawWapPushUserData(rawWapPushUserData);
378     }
379 }
380 
IsRepeatedMessagePart(const shared_ptr<SmsReceiveIndexer> & smsIndexer)381 bool SmsReceiveHandler::IsRepeatedMessagePart(const shared_ptr<SmsReceiveIndexer> &smsIndexer)
382 {
383     if (smsIndexer != nullptr) {
384         std::vector<SmsReceiveIndexer> dbIndexers;
385         DataShare::DataSharePredicates predicates;
386         predicates.EqualTo(SmsSubsection::SENDER_NUMBER, smsIndexer->GetOriginatingAddress())
387             ->And()
388             ->EqualTo(SmsSubsection::SMS_SUBSECTION_ID, std::to_string(smsIndexer->GetMsgRefId()))
389             ->And()
390             ->EqualTo(SmsSubsection::SIZE, std::to_string(smsIndexer->GetMsgCount()));
391         DelayedSingleton<SmsPersistHelper>::GetInstance()->Query(predicates, dbIndexers);
392 
393         for (const auto &it : dbIndexers) {
394             if (it.GetMsgSeqId() == smsIndexer->GetMsgSeqId()) {
395                 return true;
396             }
397         }
398     }
399     return false;
400 }
401 
AddMsgToDB(const std::shared_ptr<SmsReceiveIndexer> indexer)402 bool SmsReceiveHandler::AddMsgToDB(const std::shared_ptr<SmsReceiveIndexer> indexer)
403 {
404     if (indexer == nullptr) {
405         TELEPHONY_LOGE("indexer is nullptr.");
406         return false;
407     }
408 
409     DataShare::DataShareValuesBucket bucket;
410     bucket.Put(SmsSubsection::SLOT_ID, std::to_string(slotId_));
411     bucket.Put(SmsSubsection::RECEIVER_NUMBER, indexer->GetOriginatingAddress());
412     bucket.Put(SmsSubsection::SENDER_NUMBER, indexer->GetOriginatingAddress());
413     bucket.Put(SmsSubsection::START_TIME, std::to_string(indexer->GetTimestamp()));
414     bucket.Put(SmsSubsection::END_TIME, std::to_string(indexer->GetTimestamp()));
415     bucket.Put(SmsSubsection::REW_PUD, StringUtils::StringToHex(indexer->GetPdu()));
416 
417     bucket.Put(SmsSubsection::FORMAT, indexer->GetIsCdma() ? SMS_TYPE_CDMA : SMS_TYPE_GSM);
418     bucket.Put(SmsSubsection::DEST_PORT, indexer->GetDestPort());
419     bucket.Put(SmsSubsection::SMS_SUBSECTION_ID, indexer->GetMsgRefId());
420     bucket.Put(SmsSubsection::SIZE, indexer->GetMsgCount());
421     bucket.Put(SmsSubsection::SUBSECTION_INDEX, indexer->GetMsgSeqId());
422     uint16_t dataBaseId = 0;
423     bool ret = DelayedSingleton<SmsPersistHelper>::GetInstance()->Insert(bucket, dataBaseId);
424     indexer->SetDataBaseId(dataBaseId);
425     if (!ret) {
426         SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
427             SmsMmsErrorCode::SMS_ERROR_ADD_TO_DATABASE_FAIL, "add msg to database error");
428     }
429     return ret;
430 }
431 } // namespace Telephony
432 } // namespace OHOS