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 25namespace OHOS { 26namespace Telephony { 27using namespace std; 28constexpr static uint16_t PDU_POS_OFFSET = 1; 29constexpr static uint8_t SMS_TYPE_GSM = 1; 30constexpr static uint8_t SMS_TYPE_CDMA = 2; 31static const std::string WAP_SEQ_NUMBER_TAG = "0003"; 32constexpr static size_t WAP_SEQ_NUMBER_LEN = 10; 33const std::string STR_URI = "datashare:///com.ohos.smsmmsability/sms_mms/sms_subsection"; 34const std::string EXT_URI = "datashare:///com.ohos.smsmmsability"; 35 36std::queue<std::shared_ptr<SmsBaseMessage>> g_smsBaseMessageQueue; 37uint8_t g_reconnectDataShareCount = 0; 38bool g_alreadySendEvent = false; 39 40SmsReceiveHandler::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 49SmsReceiveHandler::~SmsReceiveHandler() {} 50// Function is used to judge if datashare interface is ready 51bool 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 74void 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 91void 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 118void 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 167void 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 185void 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 201void 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 221void 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 233void 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 245void 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 254void 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 268void 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 303bool 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 337void 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 375bool 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 396bool 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