/* * Copyright (C) 2021-2022 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 #include #include #include "bluetooth_gatt_client_server.h" #include "bluetooth_hitrace.h" #include "bluetooth_errorcode.h" #include "bluetooth_log.h" #include "hisysevent.h" #include "interface_adapter_ble.h" #include "interface_adapter_classic.h" #include "interface_adapter_manager.h" #include "interface_profile_gatt_client.h" #include "interface_profile_manager.h" #include "bluetooth_utils_server.h" #include "string_ex.h" #include "system_ability_definition.h" #include "ipc_skeleton.h" #include "permission_utils.h" using namespace OHOS::bluetooth; namespace OHOS { namespace Bluetooth { struct BluetoothGattClientServer::impl { class GattClientCallbackImpl; class SystemStateObserver; IProfileGattClient *clientService_; std::unique_ptr systemStateObserver_; std::list> callbacks_; std::mutex registerMutex_; impl(); ~impl(); IProfileGattClient *GetServicePtr() { if (IProfileManager::GetInstance() == nullptr) { return nullptr; } return static_cast( IProfileManager::GetInstance()->GetProfileService(PROFILE_NAME_GATT_CLIENT)); } }; class BluetoothGattClientServer::impl::SystemStateObserver : public ISystemStateObserver { public: SystemStateObserver(BluetoothGattClientServer::impl *impl) : impl_(impl){}; ~SystemStateObserver() override = default; void OnSystemStateChange(const BTSystemState state) override { std::lock_guard lck(impl_->registerMutex_); switch (state) { case BTSystemState::ON: impl_->clientService_ = impl_->GetServicePtr(); break; case BTSystemState::OFF: impl_->clientService_ = nullptr; break; default: break; } } private: BluetoothGattClientServer::impl *impl_; }; class BluetoothGattClientServer::impl::GattClientCallbackImpl : public IGattClientCallback { public: void OnConnectionStateChanged(int state, int newState) override { HILOGI("curState(%{public}d) -> newState(%{public}d)", state, newState); if (PermissionUtils::VerifyUseBluetoothPermission(tokenId_) == PERMISSION_DENIED) { HILOGE("check permission failed, tokenId: %{public}u", tokenId_); return; } int32_t pid = IPCSkeleton::GetCallingPid(); int32_t uid = IPCSkeleton::GetCallingUid(); if (state == static_cast(BTConnectState::CONNECTED) || state == static_cast(BTConnectState::DISCONNECTED)) { HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BT_SERVICE, "GATT_CLIENT_CONN_STATE", OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "PID", pid, "UID", uid, "STATE", state); } callback_->OnConnectionStateChanged(state, newState); } void OnCharacteristicChanged(const Characteristic &characteristic) override { HILOGI("enter"); if (PermissionUtils::VerifyUseBluetoothPermission(tokenId_) == PERMISSION_DENIED) { HILOGE("check permission failed, tokenId: %{public}u", tokenId_); return; } callback_->OnCharacteristicChanged((BluetoothGattCharacteristic)characteristic); } void OnCharacteristicRead(int ret, const Characteristic &characteristic) override { HILOGI("ret: %{public}d", ret); callback_->OnCharacteristicRead(ret, (BluetoothGattCharacteristic)characteristic); } void OnCharacteristicWrite(int ret, const Characteristic &characteristic) override { HILOGI("ret: %{public}d", ret); callback_->OnCharacteristicWrite(ret, (BluetoothGattCharacteristic)characteristic); } void OnDescriptorRead(int ret, const Descriptor &descriptor) override { HILOGI("ret: %{public}d", ret); callback_->OnDescriptorRead(ret, (BluetoothGattDescriptor)descriptor); } void OnDescriptorWrite(int ret, const Descriptor &descriptor) override { HILOGI("ret: %{public}d", ret); callback_->OnDescriptorWrite(ret, (BluetoothGattDescriptor)descriptor); } void OnMtuChanged(int state, int mtu) override { HILOGI("state: %{public}d, mtu: %{public}d", state, mtu); callback_->OnMtuChanged(state, mtu); } void OnReadRemoteRssiValue(const RawAddress &addr, int rssi, int status) override { return; } void OnServicesDiscovered(int status) override { HILOGI("status: %{public}d", status); callback_->OnServicesDiscovered(status); } void OnConnectionParameterChanged(int interval, int latency, int timeout, int status) override { HILOGI("interval: %{public}d, latency: %{public}d, timeout: %{public}d, status: %{public}d", interval, latency, timeout, status); callback_->OnConnectionParameterChanged(interval, latency, timeout, status); } void OnServicesChanged(const std::vector &services) override { HILOGI("enter"); std::vector result; int num = services.size(); for (int i = 0; i < num; i++) { result.push_back((BluetoothGattService)services[i]); } callback_->OnServicesChanged(result); } sptr GetCallback() { return callback_; } void SetAppId(int appId) { applicationId_ = appId; } int GetAppId() { return applicationId_; } GattClientCallbackImpl(const sptr &callback, BluetoothGattClientServer &owner); ~GattClientCallbackImpl() { if (!callback_->AsObject()->RemoveDeathRecipient(deathRecipient_)) { HILOGE("Failed to unlink death recipient to callback"); } callback_ = nullptr; deathRecipient_ = nullptr; }; private: class CallbackDeathRecipient : public IRemoteObject::DeathRecipient { public: CallbackDeathRecipient(const sptr &callback, BluetoothGattClientServer &owner); sptr GetCallback() const { return callback_; }; void OnRemoteDied(const wptr &remote) override; private: sptr callback_; BluetoothGattClientServer &owner_; }; sptr callback_; sptr deathRecipient_; int applicationId_; uint32_t tokenId_; }; BluetoothGattClientServer::impl::GattClientCallbackImpl::GattClientCallbackImpl( const sptr &callback, BluetoothGattClientServer &owner) : callback_(callback), deathRecipient_(new CallbackDeathRecipient(callback, owner)) { if (!callback_->AsObject()->AddDeathRecipient(deathRecipient_)) { HILOGE("Failed to link death recipient to callback"); } tokenId_ = IPCSkeleton::GetCallingTokenID(); } BluetoothGattClientServer::impl::GattClientCallbackImpl::CallbackDeathRecipient::CallbackDeathRecipient( const sptr &callback, BluetoothGattClientServer &owner) : callback_(callback), owner_(owner) {} void BluetoothGattClientServer::impl::GattClientCallbackImpl::CallbackDeathRecipient::OnRemoteDied( const wptr &remote) { HILOGI("enter"); if (owner_.pimpl == nullptr || owner_.pimpl->clientService_ == nullptr) { HILOGE("gattClientServerImpl clientService_ is not support."); return; } std::lock_guard lck(owner_.pimpl->registerMutex_); for (auto it = owner_.pimpl->callbacks_.begin(); it != owner_.pimpl->callbacks_.end(); ++it) { if ((*it)->GetCallback()->AsObject() == remote) { HILOGI("callback is found from callbacks"); sptr dr = (*it)->deathRecipient_; if (!dr->GetCallback()->AsObject()->RemoveDeathRecipient(dr)) { HILOGE("Failed to unlink death recipient from callback"); } HILOGI("App id is %{public}d", (*it)->GetAppId()); owner_.pimpl->clientService_->Disconnect((*it)->GetAppId()); owner_.pimpl->clientService_->DeregisterApplication((*it)->GetAppId()); owner_.pimpl->callbacks_.erase(it); return; } } HILOGE("No callback erased from callbacks"); } BluetoothGattClientServer::impl::impl() : clientService_(nullptr), systemStateObserver_(new SystemStateObserver(this)) { IAdapterManager::GetInstance()->RegisterSystemStateObserver(*systemStateObserver_); } BluetoothGattClientServer::impl::~impl() { IAdapterManager::GetInstance()->DeregisterSystemStateObserver(*systemStateObserver_); } BluetoothGattClientServer::BluetoothGattClientServer() : pimpl(new impl()) { HILOGI("enter"); } BluetoothGattClientServer::~BluetoothGattClientServer() {} int BluetoothGattClientServer::RegisterApplication( const sptr &callback, const BluetoothRawAddress &addr, int32_t transport) { int appId = 0; int ret = RegisterApplication(callback, addr, transport, appId); return (ret == NO_ERROR) ? appId : ret; } int BluetoothGattClientServer::RegisterApplication( const sptr &callback, const BluetoothRawAddress &addr, int32_t transport, int &appId) { HILOGI("address: %{public}s, transport: %{public}d", GetEncryptAddr(addr.GetAddress()).c_str(), transport); std::lock_guard lck(pimpl->registerMutex_); pimpl->clientService_ = pimpl->GetServicePtr(); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } auto it = pimpl->callbacks_.emplace( pimpl->callbacks_.begin(), std::make_unique(callback, *this)); appId = pimpl->clientService_->RegisterSharedApplication(*it->get(), (RawAddress)addr, transport); if (appId >= 0) { HILOGI("appId: %{public}d", appId); (*it)->SetAppId(appId); HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BT_SERVICE, "GATT_APP_REGISTER", OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "register", "SIDE", "client", "ADDRESS", GetEncryptAddr(addr.GetAddress()), "PID", OHOS::IPCSkeleton::GetCallingPid(), "UID", OHOS::IPCSkeleton::GetCallingUid(), "APPID", appId); } else { HILOGE("RegisterSharedApplication failed, appId: %{public}d", appId); pimpl->callbacks_.erase(it); } return NO_ERROR; } int BluetoothGattClientServer::DeregisterApplication(int32_t appId) { HILOGI("appId: %{public}d", appId); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return REQUEST_NOT_SUPPORT; } std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return bluetooth::GattStatus::REQUEST_NOT_SUPPORT; } HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BT_SERVICE, "GATT_APP_REGISTER", OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "ACTION", "deregister", "SIDE", "client", "ADDRESS", "empty", "PID", OHOS::IPCSkeleton::GetCallingPid(), "UID", OHOS::IPCSkeleton::GetCallingUid(), "APPID", appId); auto it = std::find_if(pimpl->callbacks_.begin(), pimpl->callbacks_.end(), [appId](const std::unique_ptr &p) { return p->GetAppId() == appId; }); if (it == pimpl->callbacks_.end()) { HILOGE("Unknown appId: %{public}d", appId); return INVALID_PARAMETER; } int ret = pimpl->clientService_->DeregisterApplication(appId); pimpl->callbacks_.erase(it); return ret; } int BluetoothGattClientServer::Connect(int32_t appId, bool autoConnect) { HILOGI("appId: %{public}d, autoConnect: %{public}d", appId, autoConnect); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return BT_ERR_PERMISSION_FAILED; } std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } OHOS::Bluetooth::BluetoothHiTrace::BluetoothStartAsyncTrace("GATT_CLIENT_CONNECT", 1); int result = pimpl->clientService_->Connect(appId, autoConnect); OHOS::Bluetooth::BluetoothHiTrace::BluetoothFinishAsyncTrace("GATT_CLIENT_CONNECT", 1); return result; } int BluetoothGattClientServer::Disconnect(int32_t appId) { HILOGI("appId: %{public}d", appId); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return BT_ERR_PERMISSION_FAILED; } std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } return pimpl->clientService_->Disconnect(appId); } int BluetoothGattClientServer::DiscoveryServices(int32_t appId) { HILOGI("appId: %{public}d", appId); std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } return pimpl->clientService_->DiscoveryServices(appId); } int BluetoothGattClientServer::ReadCharacteristic(int32_t appId, const BluetoothGattCharacteristic &characteristic) { HILOGI("appId: %{public}d", appId); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return BT_ERR_PERMISSION_FAILED; } std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } return pimpl->clientService_->ReadCharacteristic(appId, (Characteristic)characteristic); } int BluetoothGattClientServer::WriteCharacteristic( int32_t appId, BluetoothGattCharacteristic *characteristic, bool withoutRespond) { HILOGI("appId: %{public}d, withoutRespond: %{public}d", appId, withoutRespond); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return BT_ERR_PERMISSION_FAILED; } Characteristic character(characteristic->handle_); character.length_ = characteristic->length_; character.value_ = std::move(characteristic->value_); characteristic->length_ = 0; std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } return pimpl->clientService_->WriteCharacteristic(appId, character, withoutRespond); } int BluetoothGattClientServer::SignedWriteCharacteristic(int32_t appId, BluetoothGattCharacteristic *characteristic) { HILOGI("appId: %{public}d", appId); Characteristic character(characteristic->handle_); character.length_ = characteristic->length_; character.value_ = std::move(characteristic->value_); characteristic->length_ = 0; std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return bluetooth::GattStatus::REQUEST_NOT_SUPPORT; } return pimpl->clientService_->SignedWriteCharacteristic(appId, character); } int BluetoothGattClientServer::ReadDescriptor(int32_t appId, const BluetoothGattDescriptor &descriptor) { HILOGI("appId: %{public}d", appId); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return BT_ERR_PERMISSION_FAILED; } std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } return pimpl->clientService_->ReadDescriptor(appId, (Descriptor)descriptor); } int BluetoothGattClientServer::WriteDescriptor(int32_t appId, BluetoothGattDescriptor *descriptor) { HILOGI("appId: %{public}d", appId); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return BT_ERR_PERMISSION_FAILED; } Descriptor desc(descriptor->handle_); desc.length_ = descriptor->length_; desc.value_ = std::move(descriptor->value_); descriptor->length_ = 0; std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } return pimpl->clientService_->WriteDescriptor(appId, desc); } int BluetoothGattClientServer::RequestExchangeMtu(int32_t appId, int32_t mtu) { HILOGI("appId: %{public}d, mtu: %{public}d", appId, mtu); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return BT_ERR_PERMISSION_FAILED; } std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } return pimpl->clientService_->RequestExchangeMtu(appId, mtu); } void BluetoothGattClientServer::GetAllDevice(::std::vector &device) { HILOGI("enter"); std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return; } for (auto &dev : pimpl->clientService_->GetAllDevice()) { device.push_back(dev); } } int BluetoothGattClientServer::RequestConnectionPriority(int32_t appId, int32_t connPriority) { HILOGI("appId: %{public}d, connPriority: %{public}d", appId, connPriority); std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return 0; } return pimpl->clientService_->RequestConnectionPriority(appId, connPriority); } int BluetoothGattClientServer::GetServices(int32_t appId, ::std::vector &service) { HILOGI("appId: %{public}d", appId); if (PermissionUtils::VerifyUseBluetoothPermission() == PERMISSION_DENIED) { HILOGE("check permission failed"); return RET_NO_SUPPORT; } std::lock_guard lck(pimpl->registerMutex_); if (pimpl->clientService_ == nullptr) { HILOGE("request not support."); return BT_ERR_INTERNAL_ERROR; } for (auto &svc : pimpl->clientService_->GetServices(appId)) { service.push_back(svc); } return NO_ERROR; } int BluetoothGattClientServer::RequestFastestConn(const BluetoothRawAddress &addr) { HILOGI("NOT SUPPORT NOW"); return NO_ERROR; } int BluetoothGattClientServer::ReadRemoteRssiValue(int32_t appId) { HILOGI("NOT SUPPORT NOW"); return NO_ERROR; } int BluetoothGattClientServer::RequestNotification(int32_t appId, uint16_t characterHandle, bool enable) { HILOGI("NOT SUPPORT NOW"); return NO_ERROR; } } // namespace Bluetooth } // namespace OHOS