/* * Copyright (C) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "dbinder_service.h" #include #include "securec.h" #include "string_ex.h" #include "ipc_skeleton.h" #include "ipc_thread_skeleton.h" #include "dbinder_error_code.h" #include "dbinder_log.h" #include "dbinder_remote_listener.h" #include "dbinder_sa_death_recipient.h" #include "dbinder_service_stub.h" #include "ffrt.h" #include "dsoftbus_interface.h" namespace OHOS { static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC_DBINDER_SER, "DbinderService" }; sptr DBinderService::instance_ = nullptr; bool DBinderService::mainThreadCreated_ = false; std::mutex DBinderService::instanceMutex_; std::shared_ptr DBinderService::remoteListener_ = nullptr; constexpr unsigned int BINDER_MASK = 0xffff; // DBinderServiceStub's reference count in a MakeRemoteBinder call. constexpr int DBINDER_STUB_REF_COUNT = 2; DBinderService::DBinderService() { DBINDER_LOGI(LOG_LABEL, "create dbinder service"); } DBinderService::~DBinderService() { StopRemoteListener(); DBinderStubRegisted_.clear(); mapDBinderStubRegisters_.clear(); mapRemoteBinderObjects_.clear(); threadLockInfo_.clear(); proxyObject_.clear(); sessionObject_.clear(); noticeProxy_.clear(); deathRecipients_.clear(); loadSaReply_.clear(); dbinderCallback_ = nullptr; DBINDER_LOGI(LOG_LABEL, "dbinder service died"); } std::string DBinderService::GetLocalDeviceID() { std::string pkgName = "DBinderService"; std::string networkId; if (DBinderSoftbusClient::GetInstance().GetLocalNodeDeviceId( pkgName.c_str(), networkId) != SOFTBUS_CLIENT_SUCCESS) { DBINDER_LOGE(LOG_LABEL, "Get local node device id failed"); } return networkId; } bool DBinderService::StartDBinderService(std::shared_ptr &callbackImpl) { if (mainThreadCreated_) { return ReStartRemoteListener(); } bool result = StartRemoteListener(); if (!result) { return false; } mainThreadCreated_ = true; dbinderCallback_ = callbackImpl; return true; } bool DBinderService::StartRemoteListener() { if (remoteListener_ != nullptr) { DBINDER_LOGI(LOG_LABEL, "remote listener started"); return true; } remoteListener_ = std::make_shared(); if (remoteListener_ == nullptr) { DBINDER_LOGE(LOG_LABEL, "failed to create remote listener"); return false; } if (remoteListener_->StartListener() != true) { StopRemoteListener(); return false; } DBINDER_LOGI(LOG_LABEL, "start remote listener ok"); return true; } bool DBinderService::ReStartRemoteListener() { if (remoteListener_ == nullptr) { DBINDER_LOGE(LOG_LABEL, "restart remote listener got null"); return false; } if (remoteListener_->StartListener() != true) { DBINDER_LOGE(LOG_LABEL, "restart dbinder server failed"); StopRemoteListener(); return false; } return true; } void DBinderService::StopRemoteListener() { if (remoteListener_ != nullptr) { remoteListener_->StopListener(); remoteListener_ = nullptr; } } std::shared_ptr DBinderService::GetRemoteListener() { if (remoteListener_ == nullptr && !StartRemoteListener()) { return nullptr; } return remoteListener_; } sptr DBinderService::GetInstance() { if (instance_ == nullptr) { std::lock_guard lockGuard(instanceMutex_); if (instance_ == nullptr) { sptr temp = new DBinderService(); instance_ = temp; } } return instance_; } uint32_t DBinderService::GetSeqNumber() { std::lock_guard lockGuard(instanceMutex_); if (seqNumber_ == std::numeric_limits::max()) { seqNumber_ = 0; } seqNumber_++; return seqNumber_; } bool DBinderService::IsDeviceIdIllegal(const std::string &deviceID) { if (deviceID.empty() || deviceID.length() > DEVICEID_LENGTH) { return true; } return false; } binder_uintptr_t DBinderService::AddStubByTag(binder_uintptr_t stub) { std::lock_guard lockGuard(handleEntryMutex_); // the same stub needs add stubNum to mapDBinderStubRegisters_, the previous corresponding stubNum will be returned. for (auto iter = mapDBinderStubRegisters_.begin(); iter != mapDBinderStubRegisters_.end(); iter++) { if (iter->second == stub) { return iter->first; } } binder_uintptr_t stubTag = stubTagNum_++; auto result = mapDBinderStubRegisters_.insert( std::pair(stubTag, stub)); if (result.second) { return stubTag; } else { return 0; } } binder_uintptr_t DBinderService::QueryStubPtr(binder_uintptr_t stubTag) { std::lock_guard lockGuard(handleEntryMutex_); auto iter = mapDBinderStubRegisters_.find(stubTag); if (iter != mapDBinderStubRegisters_.end()) { return iter->second; } return 0; } bool DBinderService::CheckBinderObject(const sptr &stub, binder_uintptr_t stubPtr) { if (stub == nullptr) { return false; } if (reinterpret_cast(stub.GetRefPtr()) == stubPtr) { DBINDER_LOGI(LOG_LABEL, "found registered stub"); return true; } return false; } bool DBinderService::HasDBinderStub(binder_uintptr_t stubPtr) { auto checkStub = [&stubPtr, this](const sptr &stub) { return CheckBinderObject(stub, stubPtr); }; std::lock_guard lockGuard(handleEntryMutex_); auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub); if (it != DBinderStubRegisted_.end()) { return true; } return false; } bool DBinderService::IsSameStubObject(const sptr &stub, const std::u16string &service, const std::string &device) { if (stub == nullptr) { return false; } const std::string serviceStr8 = Str16ToStr8(service); if (IsSameTextStr(stub->GetServiceName(), serviceStr8) && IsSameTextStr(stub->GetDeviceID(), device)) { DBINDER_LOGI(LOG_LABEL, "found registered service, name:%{public}s device:%{public}s", serviceStr8.c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str()); return true; } return false; } sptr DBinderService::FindDBinderStub(const std::u16string &service, const std::string &device) { auto checkStub = [&service, &device, this](const sptr &stub) { return IsSameStubObject(stub, service, device); }; std::lock_guard lockGuard(handleEntryMutex_); auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub); if (it == DBinderStubRegisted_.end()) { DBINDER_LOGW(LOG_LABEL, "not found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str()); return nullptr; } DBINDER_LOGD(LOG_LABEL, "found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str()); return (*it); } bool DBinderService::DeleteDBinderStub(const std::u16string &service, const std::string &device) { auto checkStub = [&service, &device, this](const sptr &stub) { return IsSameStubObject(stub, service, device); }; std::lock_guard lockGuard(handleEntryMutex_); auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub); if (it == DBinderStubRegisted_.end()) { DBINDER_LOGW(LOG_LABEL, "not found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str()); return false; } for (auto mapIt = mapDBinderStubRegisters_.begin(); mapIt != mapDBinderStubRegisters_.end();) { if (mapIt->second == reinterpret_cast((*it).GetRefPtr())) { mapIt = mapDBinderStubRegisters_.erase(mapIt); } else { ++mapIt; } } DBinderStubRegisted_.erase(it); DBINDER_LOGI(LOG_LABEL, "succ, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str()); return true; } sptr DBinderService::FindOrNewDBinderStub(const std::u16string &service, const std::string &device, binder_uintptr_t binderObject) { auto checkStub = [&service, &device, this](const sptr &stub) { return IsSameStubObject(stub, service, device); }; std::lock_guard lockGuard(handleEntryMutex_); const std::string serviceStr8 = Str16ToStr8(service); auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub); if (it != DBinderStubRegisted_.end()) { DBINDER_LOGD(LOG_LABEL, "found, service:%{public}s device:%{public}s", serviceStr8.c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str()); return (*it); } sptr dBinderServiceStub = new DBinderServiceStub(serviceStr8, device, binderObject); DBinderStubRegisted_.push_back(dBinderServiceStub); DBINDER_LOGD(LOG_LABEL, "create, service:%{public}s device:%{public}s", serviceStr8.c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str()); return dBinderServiceStub; } sptr DBinderService::MakeRemoteBinder(const std::u16string &serviceName, const std::string &deviceID, int32_t binderObject, uint32_t pid, uint32_t uid) { if (IsDeviceIdIllegal(deviceID) || serviceName.length() == 0) { DBINDER_LOGE(LOG_LABEL, "para is wrong, device length:%{public}zu, service length:%{public}zu", deviceID.length(), serviceName.length()); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__); return nullptr; } const std::string serviceNameStr8 = Str16ToStr8(serviceName); DBINDER_LOGI(LOG_LABEL, "service:%{public}s device:%{public}s", serviceNameStr8.c_str(), DBinderService::ConvertToSecureDeviceID(deviceID).c_str()); DfxReportDeviceEvent(DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::IPC_RESULT_IDLE, DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), __FUNCTION__); sptr dBinderServiceStub = FindOrNewDBinderStub(serviceName, deviceID, static_cast(binderObject)); if (dBinderServiceStub == nullptr) { DBINDER_LOGE(LOG_LABEL, "FindOrNewDBinderStub fail, service:%{public}s", serviceNameStr8.c_str()); return nullptr; } /* if not found dBinderServiceStub, should send msg to toDeviceID * to invoker socket thread and add authentication info for create softbus session */ int retryTimes = 0; int32_t ret = -1; do { ret = InvokerRemoteDBinder(dBinderServiceStub, GetSeqNumber(), pid, uid); retryTimes++; } while (ret == WAIT_REPLY_TIMEOUT && (retryTimes < RETRY_TIMES)); if (ret != DBINDER_OK) { DBINDER_LOGE(LOG_LABEL, "fail to invoke service, service:%{public}s device:%{public}s " "DBinderServiceStub refcount:%{public}d", serviceNameStr8.c_str(), DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), dBinderServiceStub->GetSptrRefCount()); if (dBinderServiceStub->GetSptrRefCount() <= DBINDER_STUB_REF_COUNT) { /* invoke fail, delete dbinder stub info */ (void)DeleteDBinderStub(serviceName, deviceID); (void)DetachSessionObject(reinterpret_cast(dBinderServiceStub.GetRefPtr())); } return nullptr; } return dBinderServiceStub; } bool DBinderService::CheckDeviceIDsInvalid(const std::string &deviceID, const std::string &localDevID) { if (IsDeviceIdIllegal(deviceID) || IsDeviceIdIllegal(localDevID)) { DBINDER_LOGE(LOG_LABEL, "wrong device id length, remote:%{public}zu local:%{public}zu", deviceID.length(), localDevID.length()); return true; } return false; } bool DBinderService::CopyDeviceIDsToMessage(std::shared_ptr message, const std::string &localDevID, const std::string &deviceID) { if (memcpy_s(message->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH, localDevID.data(), localDevID.length()) != 0 || memcpy_s(message->deviceIdInfo.toDeviceId, DEVICEID_LENGTH, deviceID.data(), deviceID.length()) != 0) { DBINDER_LOGE(LOG_LABEL, "fail to copy memory, service:%{public}" PRIu64" seq:%{public}u", message->stubIndex, message->seqNumber); return false; } message->deviceIdInfo.fromDeviceId[localDevID.length()] = '\0'; message->deviceIdInfo.toDeviceId[deviceID.length()] = '\0'; return true; } std::shared_ptr DBinderService::CreateMessage(const sptr &stub, uint32_t seqNumber, uint32_t pid, uint32_t uid) { auto message = std::make_shared(); if (message == nullptr) { DBINDER_LOGE(LOG_LABEL, "new DHandleEntryTxRx fail"); return nullptr; } message->head.len = sizeof(DHandleEntryTxRx); message->head.version = RPC_TOKENID_SUPPORT_VERSION; message->dBinderCode = MESSAGE_AS_INVOKER; message->transType = GetRemoteTransType(); message->fromPort = 0; message->toPort = 0; message->stubIndex = static_cast(std::atoi(stub->GetServiceName().c_str())); message->seqNumber = seqNumber; message->binderObject = stub->GetBinderObject(); message->stub = AddStubByTag(reinterpret_cast(stub.GetRefPtr())); message->deviceIdInfo.tokenId = IPCSkeleton::GetCallingTokenID(); message->pid = pid; message->uid = uid; return message; } bool DBinderService::SendEntryToRemote(const sptr stub, uint32_t seqNumber, uint32_t pid, uint32_t uid) { const std::string deviceID = stub->GetDeviceID(); const std::string localDevID = GetLocalDeviceID(); if (CheckDeviceIDsInvalid(deviceID, localDevID)) { DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__); return false; } auto message = CreateMessage(stub, seqNumber, pid, uid); if (message == nullptr) { return false; } if (!CopyDeviceIDsToMessage(message, localDevID, deviceID)) { DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__); return false; } DBINDER_LOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u seq:%{public}u stub:%{public}llu" " tokenId:%{public}u", message->pid, message->uid, message->seqNumber, (message->stub & BINDER_MASK), message->deviceIdInfo.tokenId); std::shared_ptr remoteListener = GetRemoteListener(); if (remoteListener == nullptr) { DBINDER_LOGE(LOG_LABEL, "remoteListener is null, service:%{public}" PRIu64 " seq:%{public}u", message->stubIndex, message->seqNumber); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_REMOTE_LISTENER_FAIL, __FUNCTION__); return false; } bool result = remoteListener->SendDataToRemote(deviceID, message.get()); if (result != true) { DBINDER_LOGE(LOG_LABEL, "SendDataToRemote failed, service:%{public}" PRIu64" seq:%{public}u", message->stubIndex, message->seqNumber); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_SEND_DATA_TO_REMOTE_FAIL, __FUNCTION__); return false; } return true; } int32_t DBinderService::InvokerRemoteDBinder(const sptr stub, uint32_t seqNumber, uint32_t pid, uint32_t uid) { if (stub == nullptr) { DBINDER_LOGE(LOG_LABEL, "stub is nullptr"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__); return STUB_INVALID; } bool result = SendEntryToRemote(stub, seqNumber, pid, uid); if (!result) { DBINDER_LOGE(LOG_LABEL, "SendEntryToRemote fail, seq:%{public}u", seqNumber); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_SEND_ENTRY_TO_REMOTE_FAIL, __FUNCTION__); return SEND_MESSAGE_FAILED; } /* pend to wait reply */ std::shared_ptr threadLockInfo = std::make_shared(); result = AttachThreadLockInfo(seqNumber, stub->GetDeviceID(), threadLockInfo); if (result != true) { DBINDER_LOGE(LOG_LABEL, "AttachThreadLockInfo fail, seq:%{public}u", seqNumber); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ATTACH_THREADLOCK_FAIL, __FUNCTION__); return MAKE_THREADLOCK_FAILED; } std::unique_lock lock(threadLockInfo->mutex); if (threadLockInfo->condition.wait_for(lock, std::chrono::seconds(WAIT_FOR_REPLY_MAX_SEC), [&threadLockInfo] { return threadLockInfo->ready; }) == false) { DBINDER_LOGE(LOG_LABEL, "get remote data timeout or ssession is closed, seq:%{public}u", seqNumber); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_WAIT_REPLY_TIMEOUT, __FUNCTION__); DetachThreadLockInfo(seqNumber); threadLockInfo->ready = false; return WAIT_REPLY_TIMEOUT; } /* if can not find session, means invoke failed or nothing in OnRemoteReplyMessage() */ auto session = QuerySessionObject(reinterpret_cast(stub.GetRefPtr())); if (session == nullptr) { DBINDER_LOGE(LOG_LABEL, "client find session is null, seq:%{public}u", seqNumber); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_QUERY_REPLY_SESSION_FAIL, __FUNCTION__); return QUERY_REPLY_SESSION_FAILED; } return DBINDER_OK; } bool DBinderService::CheckSystemAbilityId(int32_t systemAbilityId) { return systemAbilityId >= FIRST_SYS_ABILITY_ID && systemAbilityId <= LAST_SYS_ABILITY_ID; } uint16_t DBinderService::AllocFreeSocketPort() { /* alloc port by system */ return 0; } bool DBinderService::IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId, std::shared_ptr loadSaItem) { if (static_cast(loadSaItem->stubIndex) == systemAbilityId && loadSaItem->deviceIdInfo.fromDeviceId == srcNetworkId) { DBINDER_LOGI(LOG_LABEL, "match succeed"); return true; } return false; } std::shared_ptr DBinderService::PopLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId) { auto checkSaItem = [srcNetworkId, systemAbilityId, this](std::shared_ptr loadSaItem) { return IsSameLoadSaItem(srcNetworkId, systemAbilityId, loadSaItem); }; std::lock_guard lockGuard(loadSaMutex_); auto it = std::find_if(loadSaReply_.begin(), loadSaReply_.end(), checkSaItem); if (it == loadSaReply_.end()) { DBINDER_LOGI(LOG_LABEL, "no msg for saId:%{public}d, deviceId:%{public}s", systemAbilityId, DBinderService::ConvertToSecureDeviceID(srcNetworkId).c_str()); return nullptr; } std::shared_ptr replymsg = (*it); it = loadSaReply_.erase(it); return replymsg; } void DBinderService::LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId, const sptr& remoteObject) { while (true) { std::shared_ptr replyMessage = PopLoadSaItem(srcNetworkId, systemAbilityId); if (replyMessage == nullptr) { break; } if (remoteObject == nullptr) { SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_FOUND, replyMessage); DBINDER_LOGE(LOG_LABEL, "GetSystemAbility from samgr error, saId:%{public}d", systemAbilityId); continue; } binder_uintptr_t binderObject = replyMessage->binderObject; IPCObjectProxy *saProxy = reinterpret_cast(remoteObject.GetRefPtr()); if (QueryProxyObject(binderObject) == nullptr) { /* When the stub object dies, you need to delete the corresponding busName information */ sptr death(new DbinderSaDeathRecipient(binderObject)); if (!saProxy->AddDeathRecipient(death)) { SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_FOUND, replyMessage); DBINDER_LOGE(LOG_LABEL, "fail to add death recipient"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ADD_DEATH_RECIPIENT_FAIL, __FUNCTION__); continue; } if (!AttachProxyObject(remoteObject, binderObject)) { DBINDER_LOGW(LOG_LABEL, "attach proxy object is already existed"); } } std::string deviceId = replyMessage->deviceIdInfo.fromDeviceId; if (replyMessage->transType != IRemoteObject::DATABUS_TYPE) { SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_INVOKE_FAILED, replyMessage); DBINDER_LOGE(LOG_LABEL, "Invalid Message Type"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__); } else { // peer device rpc version == 1, not support thokenId and message->deviceIdInfo.tokenId is random value uint32_t tokenId = (replyMessage->head.version < RPC_TOKENID_SUPPORT_VERSION) ? 0 : replyMessage->deviceIdInfo.tokenId; uint32_t result = OnRemoteInvokerDataBusMessage(saProxy, replyMessage, deviceId, replyMessage->pid, replyMessage->uid, tokenId); if (result != 0) { SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, result, replyMessage); continue; } SendReplyMessageToRemote(MESSAGE_AS_REPLY, 0, replyMessage); } } DBINDER_LOGI(LOG_LABEL, "LoadSystemAbility complete"); } void DBinderService::SendReplyMessageToRemote(uint32_t dBinderCode, uint32_t reason, std::shared_ptr replyMessage) { std::shared_ptr remoteListener = GetRemoteListener(); if (remoteListener == nullptr) { DBINDER_LOGE(LOG_LABEL, "remoteListener is null"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_REMOTE_LISTENER_FAIL, __FUNCTION__); return; } replyMessage->dBinderCode = dBinderCode; if (dBinderCode == MESSAGE_AS_REMOTE_ERROR) { replyMessage->transType = reason; // reuse transType send back error code } if (!remoteListener->SendDataReply(replyMessage->deviceIdInfo.fromDeviceId, replyMessage.get())) { DBINDER_LOGE(LOG_LABEL, "fail to send data from server DBS to client DBS"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_SEND_DATA_REPLAY_FAIL, __FUNCTION__); } } bool DBinderService::CheckAndAmendSaId(std::shared_ptr message) { bool ret = true; int32_t stubIndex = static_cast(message->stubIndex); int32_t binderObject = static_cast(message->binderObject); bool stubIndexVaild = CheckSystemAbilityId(stubIndex); bool binderObjectVaild = CheckSystemAbilityId(binderObject); if (stubIndexVaild && binderObjectVaild) { if (stubIndex != binderObject) { DBINDER_LOGW(LOG_LABEL, "stubIndex(%{public}d) != binderObject(%{public}d), update said:%{public}d", stubIndex, binderObject, stubIndex); message->binderObject = message->stubIndex; } } else if (stubIndexVaild && !binderObjectVaild) { DBINDER_LOGI(LOG_LABEL, "update said, replace binderObject:%{public}d with stubIndex:%{public}d", binderObject, stubIndex); message->binderObject = message->stubIndex; } else if (!stubIndexVaild && binderObjectVaild) { DBINDER_LOGI(LOG_LABEL, "update said, replace stubIndex:%{public}d with binderObject:%{public}d", stubIndex, binderObject); message->stubIndex = message->binderObject; } else { DBINDER_LOGE(LOG_LABEL, "invalid said, stubIndex:%{public}d binderObject:%{public}d", stubIndex, binderObject); ret = false; } return ret; } bool DBinderService::OnRemoteInvokerMessage(std::shared_ptr message) { if (!CheckAndAmendSaId(message)) { DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_INVALID_SAID, __FUNCTION__); SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SAID_INVALID_ERR, message); return false; } DBINDER_LOGI(LOG_LABEL, "invoke business service:%{public}d seq:%{public}u stub:%{public}llu tokenId:%{public}u", static_cast(message->stubIndex), message->seqNumber, (message->stub & BINDER_MASK), message->deviceIdInfo.tokenId); if (!dbinderCallback_->IsDistributedSystemAbility(message->binderObject)) { DBINDER_LOGE(LOG_LABEL, "SA:%{public}llu not have distributed capability.", message->binderObject); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_NOT_DISTEIBUTED_SA, __FUNCTION__); SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_DISTRUBUTED_ERR, message); return false; } std::shared_ptr replyMessage = message; { std::lock_guard lockGuard(loadSaMutex_); loadSaReply_.push_back(replyMessage); } bool isSaAvailable = dbinderCallback_->LoadSystemAbilityFromRemote(replyMessage->deviceIdInfo.fromDeviceId, static_cast(replyMessage->stubIndex)); if (!isSaAvailable) { DBINDER_LOGE(LOG_LABEL, "fail to call the system ability:%{public}d", static_cast(replyMessage->stubIndex)); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_CALL_SYSTEM_ABILITY_FAIL, __FUNCTION__); PopLoadSaItem(replyMessage->deviceIdInfo.fromDeviceId, static_cast(replyMessage->stubIndex)); SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_AVAILABLE, replyMessage); return false; } return true; } std::string DBinderService::GetDatabusNameByProxy(IPCObjectProxy *proxy) { if (proxy == nullptr) { DBINDER_LOGE(LOG_LABEL, "proxy can not be null"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__); return ""; } std::string sessionName = proxy->GetSessionName(); if (sessionName.empty()) { DBINDER_LOGE(LOG_LABEL, "grand session name failed"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GRT_SESSION_NAME_FAIL, __FUNCTION__); return ""; } DBINDER_LOGD(LOG_LABEL, "succ, handle:%{public}d sessionName:%{public}s", proxy->GetHandle(), sessionName.c_str()); return sessionName; } std::string DBinderService::CreateDatabusName(int uid, int pid) { std::string sessionName = "DBinder" + std::to_string(uid) + std::string("_") + std::to_string(pid); if (DBinderSoftbusClient::GetInstance().DBinderGrantPermission(uid, pid, sessionName) != ERR_NONE) { DBINDER_LOGE(LOG_LABEL, "fail to Grant Permission softbus name"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GRANT_PERMISSION_FAIL, __FUNCTION__); return ""; } return sessionName; } bool DBinderService::CheckDeviceIdIllegal(const std::string &remoteDeviceId) { if (IsDeviceIdIllegal(remoteDeviceId)) { DBINDER_LOGE(LOG_LABEL, "remote device id is error"); return true; } return false; } bool DBinderService::CheckSessionNameIsEmpty(const std::string &sessionName) { if (sessionName.empty()) { DBINDER_LOGE(LOG_LABEL, "get bus name fail"); return true; } return false; } bool DBinderService::CheckInvokeListenThreadIllegal(IPCObjectProxy *proxy, MessageParcel &data, MessageParcel &reply) { int err = proxy->InvokeListenThread(data, reply); if (err != ERR_NONE) { DBINDER_LOGE(LOG_LABEL, "start service listen error:%{public}d handle:%{public}d", err, proxy->GetHandle()); return true; } return false; } bool DBinderService::CheckStubIndexAndSessionNameIllegal(uint64_t stubIndex, const std::string &serverSessionName, const std::string &deviceId, IPCObjectProxy *proxy) { if (stubIndex == 0 || serverSessionName.empty() || serverSessionName.length() > SERVICENAME_LENGTH) { DBINDER_LOGE(LOG_LABEL, "stubindex:%{public}" PRIu64 " or sessionName:%{public}s is invalid" " handle:%{public}d deviceId:%{public}s", stubIndex, serverSessionName.c_str(), proxy->GetHandle(), DBinderService::ConvertToSecureDeviceID(deviceId).c_str()); return true; } return false; } bool DBinderService::SetReplyMessage(std::shared_ptr replyMessage, uint64_t stubIndex, const std::string &serverSessionName, uint32_t selfTokenId, IPCObjectProxy *proxy) { replyMessage->dBinderCode = MESSAGE_AS_REPLY; if (replyMessage->head.version >= RPC_TOKENID_SUPPORT_VERSION) { replyMessage->dBinderCode = MESSAGE_AS_REPLY_TOKENID; } replyMessage->head.version = RPC_TOKENID_SUPPORT_VERSION; replyMessage->stubIndex = stubIndex; replyMessage->serviceNameLength = serverSessionName.length(); replyMessage->deviceIdInfo.tokenId = selfTokenId; if (memcpy_s(replyMessage->serviceName, SERVICENAME_LENGTH, serverSessionName.data(), replyMessage->serviceNameLength) != 0) { DBINDER_LOGE(LOG_LABEL, "memcpy serviceName fail, handle:%{public}d", proxy->GetHandle()); return false; } replyMessage->serviceName[replyMessage->serviceNameLength] = '\0'; return true; } uint32_t DBinderService::OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, std::shared_ptr replyMessage, std::string &remoteDeviceId, int pid, int uid, uint32_t tokenId) { if (CheckDeviceIdIllegal(remoteDeviceId)) { DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__); return DEVICEID_INVALID; } std::string sessionName = GetDatabusNameByProxy(proxy); if (CheckSessionNameIsEmpty(sessionName)) { DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_BUS_NAME_FAIL, __FUNCTION__); return SESSION_NAME_NOT_FOUND; } MessageParcel data; MessageParcel reply; if (!data.WriteUint16(IRemoteObject::DATABUS_TYPE) || !data.WriteString(GetLocalDeviceID()) || !data.WriteUint32(pid) || !data.WriteUint32(uid) || !data.WriteString(remoteDeviceId) || !data.WriteString(sessionName) || !data.WriteUint32(tokenId)) { DBINDER_LOGE(LOG_LABEL, "write to parcel fail, handle:%{public}d", proxy->GetHandle()); DfxReportFailHandleEvent(DbinderErrorCode::RPC_DRIVER, proxy->GetHandle(), RADAR_WRITE_PARCEL_FAIL, __FUNCTION__); return WRITE_PARCEL_FAILED; } if (CheckInvokeListenThreadIllegal(proxy, data, reply)) { DfxReportFailHandleEvent(DbinderErrorCode::RPC_DRIVER, proxy->GetHandle(), RADAR_INVOKE_STUB_THREAD_FAIL, __FUNCTION__); return INVOKE_STUB_THREAD_FAILED; } uint64_t stubIndex = reply.ReadUint64(); std::string serverSessionName = reply.ReadString(); std::string deviceId = reply.ReadString(); uint32_t selfTokenId = reply.ReadUint32(); if (CheckStubIndexAndSessionNameIllegal(stubIndex, serverSessionName, deviceId, proxy)) { DfxReportFailHandleEvent(DbinderErrorCode::RPC_DRIVER, proxy->GetHandle(), RADAR_SESSION_NAME_INVALID, __FUNCTION__); return SESSION_NAME_INVALID; } if (!SetReplyMessage(replyMessage, stubIndex, serverSessionName, selfTokenId, proxy)) { DfxReportFailHandleEvent(DbinderErrorCode::RPC_DRIVER, proxy->GetHandle(), RADAR_ERR_MEMCPY_DATA, __FUNCTION__); return SESSION_NAME_INVALID; } return 0; } std::u16string DBinderService::GetRegisterService(binder_uintptr_t binderObject) { std::shared_lock lockGuard(remoteBinderMutex_); for (auto it = mapRemoteBinderObjects_.begin(); it != mapRemoteBinderObjects_.end(); it++) { if (it->second == binderObject) { DBINDER_LOGI(LOG_LABEL, "get service:%{public}s", Str16ToStr8(it->first).c_str()); return it->first; } } return std::u16string(); } bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, sptr binderObject) { if (serviceName.length() == 0 || binderObject == nullptr) { DBINDER_LOGE(LOG_LABEL, "serviceName length:%{public}zu", serviceName.length()); return false; } DBINDER_LOGI(LOG_LABEL, "service name:%{public}s", Str16ToStr8(serviceName).c_str()); binder_uintptr_t binder = (binder_uintptr_t)binderObject.GetRefPtr(); return RegisterRemoteProxyInner(serviceName, binder); } bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId) { if (serviceName.length() == 0 || systemAbilityId <= 0) { DBINDER_LOGE(LOG_LABEL, "serviceName length:%{public}zu", serviceName.length()); return false; } DBINDER_LOGI(LOG_LABEL, "service name:%{public}s saId:%{public}d", Str16ToStr8(serviceName).c_str(), systemAbilityId); binder_uintptr_t binder = (binder_uintptr_t)systemAbilityId; return RegisterRemoteProxyInner(serviceName, binder); } bool DBinderService::RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder) { std::unique_lock lockGuard(remoteBinderMutex_); // clear historical remnants, Don't care if it succeeds (void)mapRemoteBinderObjects_.erase(serviceName); auto result = mapRemoteBinderObjects_.insert(std::pair(serviceName, binder)); return result.second; } void DBinderService::AddAsynMessageTask(std::shared_ptr message) { auto task = [this, message] { this->OnRemoteMessageTask(message); }; ffrt::submit(task); } bool DBinderService::OnRemoteMessageTask(std::shared_ptr message) { if (message == nullptr) { DBINDER_LOGE(LOG_LABEL, "message is null"); return false; } bool result = false; switch (message->dBinderCode) { case MESSAGE_AS_INVOKER: { result = OnRemoteInvokerMessage(message); break; } case MESSAGE_AS_REPLY: case MESSAGE_AS_REPLY_TOKENID: { result = OnRemoteReplyMessage(message); break; } case MESSAGE_AS_REMOTE_ERROR: { result = OnRemoteErrorMessage(message); break; } default: { DBINDER_LOGE(LOG_LABEL, "DbinderCode:%{public}u is not support", message->dBinderCode); result = false; break; } } return result; } bool DBinderService::ProcessOnSessionClosed(const std::string &networkId) { std::lock_guard lock(threadLockMutex_); for (auto it = threadLockInfo_.begin(); it != threadLockInfo_.end();) { if (it->second->networkId != networkId) { it++; continue; } std::unique_lock lock(it->second->mutex); it->second->ready = false; it->second->condition.notify_all(); it = threadLockInfo_.erase(it); } return true; } bool DBinderService::OnRemoteErrorMessage(std::shared_ptr replyMessage) { DfxReportEvent(DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::IPC_RESULT_IDLE, __FUNCTION__); DBINDER_LOGI(LOG_LABEL, "invoke remote stubIndex:%{public}d fail, error:%{public}u seq:%{public}u", static_cast(replyMessage->stubIndex), replyMessage->transType, replyMessage->seqNumber); WakeupThreadByStub(replyMessage->seqNumber); DetachThreadLockInfo(replyMessage->seqNumber); return true; } bool DBinderService::OnRemoteReplyMessage(std::shared_ptr replyMessage) { DBINDER_LOGI(LOG_LABEL, "invoker remote stubIndex:%{public}d succ, seq:%{public}u stub:%{public}llu " "tokenId:%{public}u dBinderCode:%{public}u", static_cast(replyMessage->stubIndex), replyMessage->seqNumber, (replyMessage->stub & BINDER_MASK), replyMessage->deviceIdInfo.tokenId, replyMessage->dBinderCode); MakeSessionByReplyMessage(replyMessage); WakeupThreadByStub(replyMessage->seqNumber); DetachThreadLockInfo(replyMessage->seqNumber); return true; } bool DBinderService::IsSameSession(std::shared_ptr oldSession, std::shared_ptr newSession) { if ((oldSession->stubIndex != newSession->stubIndex) || (oldSession->toPort != newSession->toPort) || (oldSession->fromPort != newSession->fromPort) || (oldSession->type != newSession->type) || (oldSession->serviceName != newSession->serviceName)) { return false; } if (strncmp(oldSession->deviceIdInfo.fromDeviceId, newSession->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH) != 0 || strncmp(oldSession->deviceIdInfo.toDeviceId, newSession->deviceIdInfo.toDeviceId, DEVICEID_LENGTH) != 0) { return false; } return true; } bool DBinderService::IsInvalidStub(std::shared_ptr replyMessage) { if (HasDBinderStub(QueryStubPtr(replyMessage->stub)) == false) { DBINDER_LOGE(LOG_LABEL, "invalid stub object"); return true; } return false; } bool DBinderService::CopyDeviceIdInfo(std::shared_ptr &session, std::shared_ptr replyMessage) { if (memcpy_s(&session->deviceIdInfo, sizeof(struct DeviceIdInfo), &replyMessage->deviceIdInfo, sizeof(struct DeviceIdInfo)) != 0) { DBINDER_LOGE(LOG_LABEL, "fail to copy memory"); return false; } return true; } void DBinderService::InitializeSession(std::shared_ptr &session, std::shared_ptr replyMessage) { session->seqNumber = replyMessage->seqNumber; session->socketFd = 0; session->stubIndex = replyMessage->stubIndex; session->toPort = replyMessage->toPort; session->fromPort = replyMessage->fromPort; session->type = replyMessage->transType; session->serviceName = replyMessage->serviceName; } void DBinderService::MakeSessionByReplyMessage(std::shared_ptr replyMessage) { if (IsInvalidStub(replyMessage)) { DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_STUB_INVALID, __FUNCTION__); return; } std::shared_ptr session = std::make_shared(); if (session == nullptr) { DBINDER_LOGE(LOG_LABEL, "new SessionInfo fail"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_IPC_NEW_SESSION_FAIL, __FUNCTION__); return; } if (!CopyDeviceIdInfo(session, replyMessage)) { DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__); return; } // remote device NOT support tokenId, clear random value if (replyMessage->dBinderCode == MESSAGE_AS_REPLY) { session->deviceIdInfo.tokenId = 0; } DBINDER_LOGI(LOG_LABEL, "stubIndex:%{public}d tokenId:%{public}u", static_cast(replyMessage->stubIndex), session->deviceIdInfo.tokenId); InitializeSession(session, replyMessage); if (session->stubIndex == 0) { DBINDER_LOGE(LOG_LABEL, "get stubIndex == 0, it is invalid"); return; } // check whether need to update session std::shared_ptr oldSession = QuerySessionObject(QueryStubPtr(replyMessage->stub)); if (oldSession != nullptr) { if (IsSameSession(oldSession, session) == true) { DBINDER_LOGI(LOG_LABEL, "invoker remote session already, do nothing"); return; } // ignore seqNumber overflow here, greater seqNumber means later request if (oldSession->seqNumber < session->seqNumber) { // remote old session if (!DetachSessionObject(QueryStubPtr(replyMessage->stub))) { DBINDER_LOGE(LOG_LABEL, "failed to detach session object"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_DETACH_SESSION_FAIL, __FUNCTION__); } } else { // do nothing, use old session, discard session got this time // in this case, old session is requested later, but it comes back earlier } } if (!AttachSessionObject(session, QueryStubPtr(replyMessage->stub))) { DBINDER_LOGE(LOG_LABEL, "attach SessionInfo fail"); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ATTACH_SESSION_FAIL, __FUNCTION__); return; } } void DBinderService::WakeupThreadByStub(uint32_t seqNumber) { std::shared_ptr threadLockInfo = QueryThreadLockInfo(seqNumber); if (threadLockInfo == nullptr) { DBINDER_LOGE(LOG_LABEL, "threadLockInfo is not exist"); return; } /* Wake up the client processing thread */ std::unique_lock lock(threadLockInfo->mutex); threadLockInfo->ready = true; threadLockInfo->condition.notify_all(); } void DBinderService::DetachThreadLockInfo(uint32_t seqNumber) { std::lock_guard lock(threadLockMutex_); threadLockInfo_.erase(seqNumber); } bool DBinderService::AttachThreadLockInfo(uint32_t seqNumber, const std::string &networkId, std::shared_ptr object) { std::lock_guard lock(threadLockMutex_); object->networkId = networkId; auto result = threadLockInfo_.insert(std::pair>(seqNumber, object)); return result.second; } std::shared_ptr DBinderService::QueryThreadLockInfo(uint32_t seqNumber) { std::lock_guard lock(threadLockMutex_); auto it = threadLockInfo_.find(seqNumber); if (it != threadLockInfo_.end()) { return it->second; } return nullptr; } bool DBinderService::DetachProxyObject(binder_uintptr_t binderObject) { std::unique_lock lock(proxyMutex_); return (proxyObject_.erase(binderObject) > 0); } bool DBinderService::AttachProxyObject(sptr object, binder_uintptr_t binderObject) { std::unique_lock lock(proxyMutex_); auto result = proxyObject_.insert(std::pair>(binderObject, object)); return result.second; } sptr DBinderService::QueryProxyObject(binder_uintptr_t binderObject) { std::shared_lock lock(proxyMutex_); auto it = proxyObject_.find(binderObject); if (it != proxyObject_.end()) { return it->second; } return nullptr; } bool DBinderService::DetachSessionObject(binder_uintptr_t stub) { std::unique_lock lock(sessionMutex_); return (sessionObject_.erase(stub) > 0); } bool DBinderService::AttachSessionObject(std::shared_ptr object, binder_uintptr_t stub) { std::unique_lock lock(sessionMutex_); auto ret = sessionObject_.insert(std::pair>(stub, object)); return ret.second; } std::shared_ptr DBinderService::QuerySessionObject(binder_uintptr_t stub) { std::shared_lock lock(sessionMutex_); auto it = sessionObject_.find(stub); if (it != sessionObject_.end()) { return it->second; } return nullptr; } bool DBinderService::DetachDeathRecipient(sptr object) { std::unique_lock lockGuard(deathRecipientMutex_); return (deathRecipients_.erase(object) > 0); } bool DBinderService::AttachDeathRecipient(sptr object, sptr deathRecipient) { std::unique_lock lockGuard(deathRecipientMutex_); auto ret = deathRecipients_.insert( std::pair, sptr>(object, deathRecipient)); return ret.second; } sptr DBinderService::QueryDeathRecipient(sptr object) { std::shared_lock lockGuard(deathRecipientMutex_); auto it = deathRecipients_.find(object); if (it != deathRecipients_.end()) { return it->second; } return nullptr; } bool DBinderService::DetachCallbackProxy(sptr object) { std::lock_guard lockGuard(callbackProxyMutex_); return (noticeProxy_.erase(object) > 0); } bool DBinderService::AttachCallbackProxy(sptr object, DBinderServiceStub *dbStub) { std::lock_guard lockGuard(callbackProxyMutex_); auto result = noticeProxy_.insert(std::pair, DBinderServiceStub *>(object, dbStub)); return result.second; } bool DBinderService::NoticeCallbackProxy(sptr dbStub) { DBINDER_LOGI(LOG_LABEL, "service:%{public}s devicId:%{public}s", dbStub->GetServiceName().c_str(), DBinderService::ConvertToSecureDeviceID(dbStub->GetDeviceID()).c_str()); bool status = true; const binder_uintptr_t binderObject = reinterpret_cast(dbStub.GetRefPtr()); if (!DetachSessionObject(binderObject)) { DBINDER_LOGE(LOG_LABEL, "fail to detach session object"); status = false; } if (!DeleteDBinderStub(Str8ToStr16(dbStub->GetServiceName()), dbStub->GetDeviceID())) { DBINDER_LOGE(LOG_LABEL, "fail to delete DBinder stub"); status = false; } ProcessCallbackProxy(dbStub); return status; } void DBinderService::ProcessCallbackProxy(sptr dbStub) { std::lock_guard lockGuard(callbackProxyMutex_); for (auto it = noticeProxy_.begin(); it != noticeProxy_.end();) { if (it->second == dbStub.GetRefPtr()) { IPCObjectProxy *callbackProxy = reinterpret_cast((it->first).GetRefPtr()); int status = callbackProxy->NoticeServiceDie(); if (status != ERR_NONE) { DBINDER_LOGE(LOG_LABEL, "fail to notice service:%{public}s die, handle:%{public}d", dbStub->GetServiceName().c_str(), callbackProxy->GetHandle()); // do nothing, Continue to clear subsequent data } sptr death = QueryDeathRecipient((it->first)); if (death != nullptr) { // Continue to clear subsequent data callbackProxy->RemoveDeathRecipient(death); } if (!DetachDeathRecipient((it->first))) { DBINDER_LOGE(LOG_LABEL, "detaching death recipient is failed, service:%{public}s handle:%{public}d", dbStub->GetServiceName().c_str(), callbackProxy->GetHandle()); } it = noticeProxy_.erase(it); } else { it++; } } } int32_t DBinderService::NoticeServiceDieInner(const std::u16string &serviceName, const std::string &deviceID) { if (serviceName.empty() || IsDeviceIdIllegal(deviceID)) { DBINDER_LOGE(LOG_LABEL, "service name length:%{public}zu, deviceID length:%{public}zu", serviceName.length(), deviceID.length()); return DBINDER_SERVICE_INVALID_DATA_ERR; } DBINDER_LOGI(LOG_LABEL, "service:%{public}s deviceId:%{public}s", Str16ToStr8(serviceName).c_str(), DBinderService::ConvertToSecureDeviceID(deviceID).c_str()); sptr dbStub = FindDBinderStub(serviceName, deviceID); if (dbStub == nullptr) { DBINDER_LOGE(LOG_LABEL, "find null stub, do not need notice death"); return ERR_NONE; } if (!NoticeCallbackProxy(dbStub)) { DBINDER_LOGE(LOG_LABEL, "find null proxy"); return DBINDER_SERVICE_NOTICE_DIE_ERR; } return ERR_NONE; } int32_t DBinderService::NoticeServiceDie(const std::u16string &serviceName, const std::string &deviceID) { if (IsDeviceIdIllegal(deviceID)) { DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__); } else { DfxReportDeviceEvent(DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::IPC_RESULT_IDLE, DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), __FUNCTION__); } std::lock_guard lockGuard(deathNotificationMutex_); return NoticeServiceDieInner(serviceName, deviceID); } int32_t DBinderService::NoticeDeviceDie(const std::string &deviceID) { if (IsDeviceIdIllegal(deviceID)) { DBINDER_LOGE(LOG_LABEL, "deviceID length:%{public}zu", deviceID.length()); DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__); return DBINDER_SERVICE_INVALID_DATA_ERR; } DBINDER_LOGI(LOG_LABEL, "remote device:%{public}s is dead", DBinderService::ConvertToSecureDeviceID(deviceID).c_str()); DfxReportDeviceEvent(DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::IPC_RESULT_IDLE, DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), __FUNCTION__); if (remoteListener_ == nullptr) { DBINDER_LOGE(LOG_LABEL, "remote listener is null"); return DBINDER_SERVICE_NOTICE_DIE_ERR; } if (!remoteListener_->ShutdownSocket(deviceID)) { DBINDER_LOGE(LOG_LABEL, "Shutdown fail"); // do nothing } std::list serviceNames = FindServicesByDeviceID(deviceID); if (serviceNames.empty()) { DBINDER_LOGE(LOG_LABEL, "the device does not have any registered service"); return ERR_NONE; } int status = ERR_NONE; std::lock_guard lockGuard(deathNotificationMutex_); for (auto it = serviceNames.begin(); it != serviceNames.end(); it++) { status += NoticeServiceDieInner((*it), deviceID); } return status; } std::list DBinderService::FindServicesByDeviceID(const std::string &deviceID) { std::lock_guard lockGuard(handleEntryMutex_); std::list serviceNames; for (auto it = DBinderStubRegisted_.begin(); it != DBinderStubRegisted_.end(); it++) { if ((*it)->GetDeviceID() == deviceID) { serviceNames.push_back(Str8ToStr16((*it)->GetServiceName())); } } DBINDER_LOGI(LOG_LABEL, "deviceId:%{public}s, service size:%{public}zu", DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), serviceNames.size()); return serviceNames; } uint32_t DBinderService::GetRemoteTransType() { return IRemoteObject::DATABUS_TYPE; } std::string DBinderService::ConvertToSecureDeviceID(const std::string &str) { size_t len = str.size(); if (len <= ENCRYPT_LENGTH) { return "****"; } return str.substr(0, ENCRYPT_LENGTH) + "****" + str.substr(len - ENCRYPT_LENGTH); } } // namespace OHOS