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_hisysevent.h"
20 #include "sms_persist_helper.h"
21 #include "telephony_log_wrapper.h"
22 #include "iservice_registry.h"
23 #include <queue>
24 
25 namespace OHOS {
26 namespace Telephony {
27 using namespace std;
28 constexpr static uint16_t PDU_POS_OFFSET = 1;
29 constexpr static uint8_t SMS_TYPE_GSM = 1;
30 constexpr static uint8_t SMS_TYPE_CDMA = 2;
31 static const std::string WAP_SEQ_NUMBER_TAG = "0003";
32 constexpr static size_t WAP_SEQ_NUMBER_LEN = 10;
33 const std::string STR_URI = "datashare:///com.ohos.smsmmsability/sms_mms/sms_subsection";
34 const std::string EXT_URI = "datashare:///com.ohos.smsmmsability";
35 
36 std::queue<std::shared_ptr<SmsBaseMessage>> g_smsBaseMessageQueue;
37 uint8_t g_reconnectDataShareCount = 0;
38 bool g_alreadySendEvent = false;
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     g_reconnectDataShareCount = 0;
87     // set the flag of datashare is not ready to false.
88     g_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         g_reconnectDataShareCount++;
98         // if retry times over 20(the datashare is not ready in 100s), stop try.
99         if (g_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             g_reconnectDataShareCount = 0;
103             g_alreadySendEvent = false;
104             ReleaseRunningLock();
105         } else {
106             TELEPHONY_LOGI("Send event %{public}u times", g_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             ApplyRunningLock();
132             std::shared_ptr<SmsBaseMessage> message = nullptr;
133             message = TransformMessageInfo(event->GetSharedObject<SmsMessageInfo>());
134             if (message != nullptr) {
135                 TELEPHONY_LOGI("[raw pdu] =%{private}s", StringUtils::StringToHex(message->GetRawPdu()).c_str());
136             }
137             if (!g_alreadySendEvent) {
138                 if (IsDataShareReady()) {
139                     HandleReceivedSms(message);
140                     this->SendEvent(DELAY_RELEASE_RUNNING_LOCK_EVENT_ID, DELAY_REDUCE_RUNNING_LOCK_TIMEOUT_MS);
141                 } else {
142                     HandleReceivedSmsWithoutDataShare(message);
143                     this->SendEvent(RETRY_CONNECT_DATASHARE_EVENT_ID, DELAY_RETRY_CONNECT_DATASHARE_MS);
144                     g_alreadySendEvent = true;
145                 }
146             } else {
147                 HandleReceivedSmsWithoutDataShare(message);
148             }
149             break;
150         }
151         case RUNNING_LOCK_TIMEOUT_EVENT_ID:
152             HandleRunningLockTimeoutEvent(event);
153             break;
154         case DELAY_RELEASE_RUNNING_LOCK_EVENT_ID:
155             ReduceRunningLock();
156             break;
157         case RETRY_CONNECT_DATASHARE_EVENT_ID: {
158             HandleReconnectEvent();
159             break;
160         }
161         default:
162             TELEPHONY_LOGE("SmsReceiveHandler::ProcessEvent Unknown eventId %{public}d", eventId);
163             break;
164     }
165 }
166 
ApplyRunningLock()167 void SmsReceiveHandler::ApplyRunningLock()
168 {
169 #ifdef ABILITY_POWER_SUPPORT
170     if (smsRunningLock_ == nullptr) {
171         CreateRunningLockInner();
172     }
173     std::lock_guard<std::mutex> lockGuard(mutexRunningLock_);
174     if (smsRunningLock_ != nullptr) {
175         smsRunningLockCount_++;
176         smsLockSerialNum_++;
177         TELEPHONY_LOGI("ApplyRunningLock, try to lock. count: %{public}d, serial: %{public}d",
178             static_cast<int>(smsRunningLockCount_), static_cast<int>(smsLockSerialNum_));
179         smsRunningLock_->Lock(RUNNING_LOCK_DEFAULT_TIMEOUT_MS); // Automatic release after the 60s.
180         this->SendEvent(RUNNING_LOCK_TIMEOUT_EVENT_ID, smsLockSerialNum_, RUNNING_LOCK_DEFAULT_TIMEOUT_MS);
181     }
182 #endif
183 }
184 
ReduceRunningLock()185 void SmsReceiveHandler::ReduceRunningLock()
186 {
187 #ifdef ABILITY_POWER_SUPPORT
188     std::lock_guard<std::mutex> lockRequest(mutexRunningLock_);
189     TELEPHONY_LOGI("ReduceRunningLock, count:%{public}d", static_cast<int>(smsRunningLockCount_));
190     if (smsRunningLock_ != nullptr) {
191         if (smsRunningLockCount_ > 1) {
192             smsRunningLockCount_--;
193         } else {
194             smsRunningLockCount_ = 0;
195             ReleaseRunningLock();
196         }
197     }
198 #endif
199 }
200 
ReleaseRunningLock()201 void SmsReceiveHandler::ReleaseRunningLock()
202 {
203 #ifdef ABILITY_POWER_SUPPORT
204     if (smsRunningLock_ == nullptr) {
205         TELEPHONY_LOGE("ReleaseRunningLock, smsRunningLock_ is nullptr");
206         return;
207     }
208     TELEPHONY_LOGI("ReleaseRunningLock, try to unlock.");
209     smsRunningLockCount_ = 0;
210     int ret = smsRunningLock_->UnLock();
211     if (ret != PowerMgr::E_GET_POWER_SERVICE_FAILED) {
212         // Call UnLock success, remove event.
213         this->RemoveEvent(RUNNING_LOCK_TIMEOUT_EVENT_ID);
214         return;
215     }
216     TELEPHONY_LOGI("ReleaseRunningLock, no found power service, retry.");
217     this->SendEvent(RUNNING_LOCK_TIMEOUT_EVENT_ID, smsLockSerialNum_, DELAY_RELEASE_RUNNING_LOCK_TIMEOUT_MS);
218 #endif
219 }
220 
CreateRunningLockInner()221 void SmsReceiveHandler::CreateRunningLockInner()
222 {
223 #ifdef ABILITY_POWER_SUPPORT
224     auto &powerMgrClient = PowerMgr::PowerMgrClient::GetInstance();
225     std::lock_guard<std::mutex> lockGuard(mutexRunningLock_);
226     smsRunningLock_ = powerMgrClient.CreateRunningLock("telSmsRunningLock",
227         PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_PHONE);
228     smsRunningLockCount_ = 0;
229     smsLockSerialNum_ = 0;
230 #endif
231 }
232 
HandleRunningLockTimeoutEvent(const AppExecFwk::InnerEvent::Pointer & event)233 void SmsReceiveHandler::HandleRunningLockTimeoutEvent(const AppExecFwk::InnerEvent::Pointer &event)
234 {
235 #ifdef ABILITY_POWER_SUPPORT
236     auto serial = event->GetParam();
237     if (serial == smsLockSerialNum_) {
238         TELEPHONY_LOGE("HandleRunningLockTimeoutEvent, serial:%{public}d, smsLockSerialNum_:%{public}d",
239             static_cast<int>(serial), static_cast<int>(smsLockSerialNum_));
240         ReleaseRunningLock();
241     }
242 #endif
243 }
244 
HandleReceivedSms(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)245 void SmsReceiveHandler::HandleReceivedSms(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
246 {
247     if (smsBaseMessage == nullptr) {
248         TELEPHONY_LOGE("smsBaseMessage is nullptr");
249         return;
250     }
251     ReplySmsToSmsc(HandleSmsByType(smsBaseMessage));
252 }
253 
HandleReceivedSmsWithoutDataShare(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)254 void SmsReceiveHandler::HandleReceivedSmsWithoutDataShare(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
255 {
256     if (smsBaseMessage == nullptr) {
257         TELEPHONY_LOGE("smsBaseMessage is nullptr");
258         return;
259     }
260     int32_t result = ReplySmsToSmsc(HandleAck(smsBaseMessage));
261     if (result) {
262         std::lock_guard lock(queueMutex_);
263         g_smsBaseMessageQueue.push(smsBaseMessage);
264         TELEPHONY_LOGI("Received a new message and pushed it in queue");
265     }
266 }
267 
CombineMessagePart(const std::shared_ptr<SmsReceiveIndexer> & indexer)268 void SmsReceiveHandler::CombineMessagePart(const std::shared_ptr<SmsReceiveIndexer> &indexer)
269 {
270     std::shared_ptr<vector<string>> pdus = make_shared<vector<string>>();
271     if ((indexer == nullptr) || (pdus == nullptr)) {
272         TELEPHONY_LOGE("indexer or pdus is nullptr");
273         return;
274     }
275     auto reliabilityHandler = std::make_shared<SmsReceiveReliabilityHandler>(slotId_);
276     if ((reliabilityHandler == nullptr)) {
277         TELEPHONY_LOGE("reliabilityHandler is nullptr");
278         return;
279     }
280     if (indexer->IsSingleMsg()) {
281         string pdu = StringUtils::StringToHex(indexer->GetPdu());
282         pdus->push_back(pdu);
283     } else {
284         if (!CombineMultiPageMessage(indexer, pdus, reliabilityHandler)) {
285             TELEPHONY_LOGI("The multi-page text didn't all arrive");
286             return;
287         }
288     }
289 
290     if (indexer->GetIsWapPushMsg()) {
291         if (smsWapPushHandler_ != nullptr) {
292             auto rawWapPushUserData = indexer->GetRawWapPushUserData();
293             if (!smsWapPushHandler_->DecodeWapPushPdu(indexer, rawWapPushUserData)) {
294                 SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::WAP_PUSH,
295                     SmsMmsErrorCode::SMS_ERROR_PDU_DECODE_FAIL, "Wap push decode wap push fail");
296             }
297         }
298         return;
299     }
300     reliabilityHandler->SendBroadcast(indexer, pdus);
301 }
302 
CombineMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> & indexer,std::shared_ptr<std::vector<std::string>> pdus,std::shared_ptr<SmsReceiveReliabilityHandler> reliabilityHandler)303 bool SmsReceiveHandler::CombineMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> &indexer,
304     std::shared_ptr<std::vector<std::string>> pdus, std::shared_ptr<SmsReceiveReliabilityHandler> reliabilityHandler)
305 {
306     pdus->assign(MAX_SEGMENT_NUM, "");
307     int msgSeg = static_cast<int>(indexer->GetMsgCount());
308     int8_t notNullPart = msgSeg;
309     std::vector<SmsReceiveIndexer> dbIndexers;
310     DataShare::DataSharePredicates predicates;
311     predicates.EqualTo(SmsSubsection::SENDER_NUMBER, indexer->GetOriginatingAddress())
312         ->And()
313         ->EqualTo(SmsSubsection::SMS_SUBSECTION_ID, std::to_string(indexer->GetMsgRefId()))
314         ->And()
315         ->EqualTo(SmsSubsection::SIZE, std::to_string(indexer->GetMsgCount()));
316     DelayedSingleton<SmsPersistHelper>::GetInstance()->Query(predicates, dbIndexers);
317     int8_t count = 0;
318     for (const auto &v : dbIndexers) {
319         ++count;
320         string pdu = StringUtils::StringToHex(v.GetPdu());
321         if ((v.GetMsgSeqId() - PDU_POS_OFFSET >= MAX_SEGMENT_NUM) || (v.GetMsgSeqId() - PDU_POS_OFFSET < 0)) {
322             reliabilityHandler->DeleteMessageFormDb(indexer->GetMsgRefId());
323             return false;
324         }
325         pdus->at(v.GetMsgSeqId() - PDU_POS_OFFSET) = pdu;
326         if (v.GetPdu().size() == 0) {
327             --notNullPart;
328         }
329     }
330     if ((count != msgSeg) || (pdus->empty()) || (notNullPart != msgSeg)) {
331         return false;
332     }
333     UpdateMultiPageMessage(indexer, pdus);
334     return true;
335 }
336 
UpdateMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> & indexer,std::shared_ptr<std::vector<std::string>> pdus)337 void SmsReceiveHandler::UpdateMultiPageMessage(
338     const std::shared_ptr<SmsReceiveIndexer> &indexer, std::shared_ptr<std::vector<std::string>> pdus)
339 {
340     if ((indexer == nullptr) || (pdus == nullptr) || (pdus->empty())) {
341         TELEPHONY_LOGE("indexer or pdus is null");
342         return;
343     }
344     std::string messagBody;
345     std::string userDataRaw;
346     std::string rawWapPushUserData;
347     for (const auto &pdu : *pdus) {
348         if (pdu.empty()) {
349             continue;
350         }
351         std::shared_ptr<SmsBaseMessage> baseMessage = GsmSmsMessage::CreateMessage(pdu);
352         if (baseMessage == nullptr) {
353             continue;
354         }
355         messagBody.append(baseMessage->GetVisibleMessageBody());
356         userDataRaw.append(baseMessage->GetRawUserData());
357         if (!indexer->GetIsWapPushMsg()) {
358             continue;
359         }
360         auto wapDataHex = StringUtils::StringToHex(baseMessage->GetRawWapPushUserData());
361         if (wapDataHex.substr(0, WAP_SEQ_NUMBER_TAG.size()) == WAP_SEQ_NUMBER_TAG) {
362             rawWapPushUserData.append(StringUtils::HexToString(wapDataHex.substr(WAP_SEQ_NUMBER_LEN)));
363         } else {
364             rawWapPushUserData.append(StringUtils::HexToString(wapDataHex));
365         }
366     }
367 
368     indexer->SetVisibleMessageBody(messagBody);
369     indexer->SetRawUserData(userDataRaw);
370     if (indexer->GetIsWapPushMsg()) {
371         indexer->SetRawWapPushUserData(rawWapPushUserData);
372     }
373 }
374 
IsRepeatedMessagePart(const shared_ptr<SmsReceiveIndexer> & smsIndexer)375 bool SmsReceiveHandler::IsRepeatedMessagePart(const shared_ptr<SmsReceiveIndexer> &smsIndexer)
376 {
377     if (smsIndexer != nullptr) {
378         std::vector<SmsReceiveIndexer> dbIndexers;
379         DataShare::DataSharePredicates predicates;
380         predicates.EqualTo(SmsSubsection::SENDER_NUMBER, smsIndexer->GetOriginatingAddress())
381             ->And()
382             ->EqualTo(SmsSubsection::SMS_SUBSECTION_ID, std::to_string(smsIndexer->GetMsgRefId()))
383             ->And()
384             ->EqualTo(SmsSubsection::SIZE, std::to_string(smsIndexer->GetMsgCount()));
385         DelayedSingleton<SmsPersistHelper>::GetInstance()->Query(predicates, dbIndexers);
386 
387         for (const auto &it : dbIndexers) {
388             if (it.GetMsgSeqId() == smsIndexer->GetMsgSeqId()) {
389                 return true;
390             }
391         }
392     }
393     return false;
394 }
395 
AddMsgToDB(const std::shared_ptr<SmsReceiveIndexer> indexer)396 bool SmsReceiveHandler::AddMsgToDB(const std::shared_ptr<SmsReceiveIndexer> indexer)
397 {
398     if (indexer == nullptr) {
399         TELEPHONY_LOGE("indexer is nullptr.");
400         return false;
401     }
402 
403     DataShare::DataShareValuesBucket bucket;
404     bucket.Put(SmsSubsection::SLOT_ID, std::to_string(slotId_));
405     bucket.Put(SmsSubsection::RECEIVER_NUMBER, indexer->GetOriginatingAddress());
406     bucket.Put(SmsSubsection::SENDER_NUMBER, indexer->GetOriginatingAddress());
407     bucket.Put(SmsSubsection::START_TIME, std::to_string(indexer->GetTimestamp()));
408     bucket.Put(SmsSubsection::END_TIME, std::to_string(indexer->GetTimestamp()));
409     bucket.Put(SmsSubsection::REW_PUD, StringUtils::StringToHex(indexer->GetPdu()));
410 
411     bucket.Put(SmsSubsection::FORMAT, indexer->GetIsCdma() ? SMS_TYPE_CDMA : SMS_TYPE_GSM);
412     bucket.Put(SmsSubsection::DEST_PORT, indexer->GetDestPort());
413     bucket.Put(SmsSubsection::SMS_SUBSECTION_ID, indexer->GetMsgRefId());
414     bucket.Put(SmsSubsection::SIZE, indexer->GetMsgCount());
415     bucket.Put(SmsSubsection::SUBSECTION_INDEX, indexer->GetMsgSeqId());
416     uint16_t dataBaseId = 0;
417     bool ret = DelayedSingleton<SmsPersistHelper>::GetInstance()->Insert(bucket, dataBaseId);
418     indexer->SetDataBaseId(dataBaseId);
419     if (!ret) {
420         SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
421             SmsMmsErrorCode::SMS_ERROR_ADD_TO_DATABASE_FAIL, "add msg to database error");
422     }
423     return ret;
424 }
425 } // namespace Telephony
426 } // namespace OHOS