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