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