195489c19Sopenharmony_ci/* 295489c19Sopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd. 395489c19Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 495489c19Sopenharmony_ci * you may not use this file except in compliance with the License. 595489c19Sopenharmony_ci * You may obtain a copy of the License at 695489c19Sopenharmony_ci * 795489c19Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 895489c19Sopenharmony_ci * 995489c19Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1095489c19Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1195489c19Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1295489c19Sopenharmony_ci * See the License for the specific language governing permissions and 1395489c19Sopenharmony_ci * limitations under the License. 1495489c19Sopenharmony_ci */ 1595489c19Sopenharmony_ci 1695489c19Sopenharmony_ci#include <condition_variable> 1795489c19Sopenharmony_ci#include <memory> 1895489c19Sopenharmony_ci#include <set> 1995489c19Sopenharmony_ci#include <thread> 2095489c19Sopenharmony_ci#include "bluetooth_def.h" 2195489c19Sopenharmony_ci#include "bluetooth_gatt_client.h" 2295489c19Sopenharmony_ci#include "bluetooth_gatt_client_proxy.h" 2395489c19Sopenharmony_ci#include "bluetooth_gatt_client_callback_stub.h" 2495489c19Sopenharmony_ci#include "bluetooth_host.h" 2595489c19Sopenharmony_ci#include "bluetooth_host_proxy.h" 2695489c19Sopenharmony_ci#include "bluetooth_log.h" 2795489c19Sopenharmony_ci#include "bluetooth_utils.h" 2895489c19Sopenharmony_ci#include "gatt_data.h" 2995489c19Sopenharmony_ci#include "i_bluetooth_gatt_client.h" 3095489c19Sopenharmony_ci#include "iservice_registry.h" 3195489c19Sopenharmony_ci#include "raw_address.h" 3295489c19Sopenharmony_ci#include "system_ability_definition.h" 3395489c19Sopenharmony_ci#include "bluetooth_profile_manager.h" 3495489c19Sopenharmony_ci 3595489c19Sopenharmony_cinamespace OHOS { 3695489c19Sopenharmony_cinamespace Bluetooth { 3795489c19Sopenharmony_ci#define WPTR_GATT_CBACK(cbWptr, func, ...) \ 3895489c19Sopenharmony_cido { \ 3995489c19Sopenharmony_ci auto cbSptr = (cbWptr).lock(); \ 4095489c19Sopenharmony_ci if (cbSptr) { \ 4195489c19Sopenharmony_ci cbSptr->func(__VA_ARGS__); \ 4295489c19Sopenharmony_ci } else { \ 4395489c19Sopenharmony_ci HILOGE(#cbWptr ": callback is nullptr"); \ 4495489c19Sopenharmony_ci } \ 4595489c19Sopenharmony_ci} while (0) 4695489c19Sopenharmony_ci 4795489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_READ = 0x00; 4895489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_WRITE = 0x01; 4995489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_DESCRIPTOR_READ = 0x02; 5095489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_DESCRIPTOR_WRITE = 0x03; 5195489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS = 0x04; 5295489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_READ_REMOTE_RSSI_VALUE = 0x05; 5395489c19Sopenharmony_ci 5495489c19Sopenharmony_ciconstexpr const int WAIT_TIMEOUT = 10; // 10s 5595489c19Sopenharmony_cistd::mutex g_gattClientProxyMutex; 5695489c19Sopenharmony_cistruct DiscoverInfomation { 5795489c19Sopenharmony_ci struct Characteristics { 5895489c19Sopenharmony_ci bool isDiscoverDescCompleted_; 5995489c19Sopenharmony_ci Characteristics() : isDiscoverDescCompleted_(false) 6095489c19Sopenharmony_ci {} 6195489c19Sopenharmony_ci }; 6295489c19Sopenharmony_ci 6395489c19Sopenharmony_ci struct Service { 6495489c19Sopenharmony_ci bool isDiscoverCompleted_; 6595489c19Sopenharmony_ci bool isDiscoverCharacteristicCompleted_; 6695489c19Sopenharmony_ci bool isDiscoverIncludeSvcCompleted_; 6795489c19Sopenharmony_ci uint16_t endHandle_; 6895489c19Sopenharmony_ci std::map<uint16_t, Characteristics> characteristics_; 6995489c19Sopenharmony_ci Service(uint16_t endHandle) 7095489c19Sopenharmony_ci : isDiscoverCompleted_(false), 7195489c19Sopenharmony_ci isDiscoverCharacteristicCompleted_(false), 7295489c19Sopenharmony_ci isDiscoverIncludeSvcCompleted_(false), 7395489c19Sopenharmony_ci endHandle_(endHandle) 7495489c19Sopenharmony_ci {} 7595489c19Sopenharmony_ci }; 7695489c19Sopenharmony_ci bool isDiscovering_; 7795489c19Sopenharmony_ci bool needNotify_; 7895489c19Sopenharmony_ci std::mutex mutex_; 7995489c19Sopenharmony_ci std::condition_variable condition_; 8095489c19Sopenharmony_ci std::map<uint16_t, Service> service_; 8195489c19Sopenharmony_ci DiscoverInfomation() : isDiscovering_(false), needNotify_(false) 8295489c19Sopenharmony_ci {} 8395489c19Sopenharmony_ci}; 8495489c19Sopenharmony_ci 8595489c19Sopenharmony_cistruct RequestInformation { 8695489c19Sopenharmony_ci bool doing_; 8795489c19Sopenharmony_ci uint8_t type_ = 0; 8895489c19Sopenharmony_ci std::mutex mutex_; 8995489c19Sopenharmony_ci RequestInformation() : doing_(false) 9095489c19Sopenharmony_ci {} 9195489c19Sopenharmony_ci}; 9295489c19Sopenharmony_ci 9395489c19Sopenharmony_cistruct GattClient::impl { 9495489c19Sopenharmony_ci class BluetoothGattClientCallbackStubImpl; 9595489c19Sopenharmony_ci 9695489c19Sopenharmony_ci bool isGetServiceYet_; 9795489c19Sopenharmony_ci bool isRegisterSucceeded_; 9895489c19Sopenharmony_ci std::weak_ptr<GattClientCallback> callback_; 9995489c19Sopenharmony_ci int applicationId_; 10095489c19Sopenharmony_ci int connectionState_; 10195489c19Sopenharmony_ci BluetoothRemoteDevice device_; 10295489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy; 10395489c19Sopenharmony_ci sptr<BluetoothGattClientCallbackStubImpl> clientCallback_; 10495489c19Sopenharmony_ci std::vector<GattService> gattServices_; 10595489c19Sopenharmony_ci std::mutex gattServicesMutex_; 10695489c19Sopenharmony_ci std::mutex connStateMutex_; 10795489c19Sopenharmony_ci RequestInformation requestInformation_; 10895489c19Sopenharmony_ci DiscoverInfomation discoverInformation_; 10995489c19Sopenharmony_ci int32_t profileRegisterId = 0; 11095489c19Sopenharmony_ci 11195489c19Sopenharmony_ci explicit impl(const BluetoothRemoteDevice &device); 11295489c19Sopenharmony_ci ~impl(); 11395489c19Sopenharmony_ci 11495489c19Sopenharmony_ci bool Init(std::weak_ptr<GattClient> client); 11595489c19Sopenharmony_ci 11695489c19Sopenharmony_ci int DiscoverStart(); 11795489c19Sopenharmony_ci void DiscoverComplete(int state); 11895489c19Sopenharmony_ci void BuildServiceList(const std::vector<BluetoothGattService> &src); 11995489c19Sopenharmony_ci GattService *FindService(uint16_t handle); 12095489c19Sopenharmony_ci void GetServices(); 12195489c19Sopenharmony_ci void CleanConnectionInfo(); 12295489c19Sopenharmony_ci bool GetCharacteristicByHandle(uint16_t handle, GattCharacteristic &outCharac); 12395489c19Sopenharmony_ci bool GetDescriptorByHandle(uint16_t handle, GattDescriptor &outDesc); 12495489c19Sopenharmony_ci}; 12595489c19Sopenharmony_ci 12695489c19Sopenharmony_ciclass GattClient::impl::BluetoothGattClientCallbackStubImpl : public BluetoothGattClientCallbackStub { 12795489c19Sopenharmony_cipublic: 12895489c19Sopenharmony_ci void OnServicesChanged(std::vector<BluetoothGattService> &service) override 12995489c19Sopenharmony_ci { 13095489c19Sopenharmony_ci HILOGI("enter"); 13195489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 13295489c19Sopenharmony_ci if (!clientSptr) { 13395489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 13495489c19Sopenharmony_ci return; 13595489c19Sopenharmony_ci } 13695489c19Sopenharmony_ci clientSptr->pimpl->DiscoverStart(); 13795489c19Sopenharmony_ci } 13895489c19Sopenharmony_ci 13995489c19Sopenharmony_ci void OnConnectionStateChanged(int32_t state, int32_t newState) override 14095489c19Sopenharmony_ci { 14195489c19Sopenharmony_ci HILOGD("gattClient conn state, status: %{public}d, newState: %{public}s", 14295489c19Sopenharmony_ci state, GetProfileConnStateName(newState).c_str()); 14395489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 14495489c19Sopenharmony_ci if (!clientSptr) { 14595489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 14695489c19Sopenharmony_ci return; 14795489c19Sopenharmony_ci } 14895489c19Sopenharmony_ci if (newState == static_cast<int>(BTConnectState::DISCONNECTED)) { 14995489c19Sopenharmony_ci clientSptr->pimpl->CleanConnectionInfo(); 15095489c19Sopenharmony_ci } 15195489c19Sopenharmony_ci 15295489c19Sopenharmony_ci { 15395489c19Sopenharmony_ci std::lock_guard<std::mutex> lck(clientSptr->pimpl->connStateMutex_); 15495489c19Sopenharmony_ci clientSptr->pimpl->connectionState_ = newState; 15595489c19Sopenharmony_ci } 15695489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnConnectionStateChanged, newState, state); 15795489c19Sopenharmony_ci } 15895489c19Sopenharmony_ci 15995489c19Sopenharmony_ci void OnCharacteristicChanged(const BluetoothGattCharacteristic &characteristic) override 16095489c19Sopenharmony_ci { 16195489c19Sopenharmony_ci HILOGD("recv notification, length:%{public}zu", characteristic.length_); 16295489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 16395489c19Sopenharmony_ci if (!clientSptr) { 16495489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 16595489c19Sopenharmony_ci return; 16695489c19Sopenharmony_ci } 16795489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(clientSptr->pimpl->gattServicesMutex_); 16895489c19Sopenharmony_ci for (auto &svc : clientSptr->pimpl->gattServices_) { 16995489c19Sopenharmony_ci for (auto &character : svc.GetCharacteristics()) { 17095489c19Sopenharmony_ci if (character.GetHandle() == characteristic.handle_) { 17195489c19Sopenharmony_ci character.SetValue(characteristic.value_.get(), characteristic.length_); 17295489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnCharacteristicChanged, character); 17395489c19Sopenharmony_ci return; 17495489c19Sopenharmony_ci } 17595489c19Sopenharmony_ci } 17695489c19Sopenharmony_ci } 17795489c19Sopenharmony_ci HILOGE("recv notification failed, characteristic is not exist."); 17895489c19Sopenharmony_ci } 17995489c19Sopenharmony_ci 18095489c19Sopenharmony_ci void OnCharacteristicRead(int32_t ret, const BluetoothGattCharacteristic &characteristic) override 18195489c19Sopenharmony_ci { 18295489c19Sopenharmony_ci HILOGI("ret:%{public}d, length:%{public}zu", ret, characteristic.length_); 18395489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 18495489c19Sopenharmony_ci if (!clientSptr) { 18595489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 18695489c19Sopenharmony_ci return; 18795489c19Sopenharmony_ci } 18895489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_); 18995489c19Sopenharmony_ci clientSptr->pimpl->requestInformation_.doing_ = false; 19095489c19Sopenharmony_ci GattCharacteristic charac(UUID(), 0, 0); 19195489c19Sopenharmony_ci bool isExist = clientSptr->pimpl->GetCharacteristicByHandle(characteristic.handle_, charac); 19295489c19Sopenharmony_ci if (!isExist) { 19395489c19Sopenharmony_ci HILOGE("no expected characteristic handle:%{public}d type:%{public}d", 19495489c19Sopenharmony_ci characteristic.handle_, clientSptr->pimpl->requestInformation_.type_); 19595489c19Sopenharmony_ci ret = BT_ERR_INTERNAL_ERROR; 19695489c19Sopenharmony_ci } 19795489c19Sopenharmony_ci if (clientSptr->pimpl->requestInformation_.type_ != REQUEST_TYPE_CHARACTERISTICS_READ) { 19895489c19Sopenharmony_ci HILOGE("Unexpected call!"); 19995489c19Sopenharmony_ci return; 20095489c19Sopenharmony_ci } 20195489c19Sopenharmony_ci if (ret == GattStatus::GATT_SUCCESS) { 20295489c19Sopenharmony_ci charac.SetValue(characteristic.value_.get(), characteristic.length_); 20395489c19Sopenharmony_ci } 20495489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnCharacteristicReadResult, charac, ret); 20595489c19Sopenharmony_ci } 20695489c19Sopenharmony_ci 20795489c19Sopenharmony_ci void OnCharacteristicWrite(int32_t ret, const BluetoothGattCharacteristic &characteristic) override 20895489c19Sopenharmony_ci { 20995489c19Sopenharmony_ci HILOGI("ret:%{public}d, length:%{public}zu", ret, characteristic.length_); 21095489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 21195489c19Sopenharmony_ci if (!clientSptr) { 21295489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 21395489c19Sopenharmony_ci return; 21495489c19Sopenharmony_ci } 21595489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_); 21695489c19Sopenharmony_ci clientSptr->pimpl->requestInformation_.doing_ = false; 21795489c19Sopenharmony_ci GattCharacteristic charac(UUID(), 0, 0); 21895489c19Sopenharmony_ci bool isExist = clientSptr->pimpl->GetCharacteristicByHandle(characteristic.handle_, charac); 21995489c19Sopenharmony_ci if (!isExist) { 22095489c19Sopenharmony_ci HILOGE("no expected characteristic handle:%{public}d type:%{public}d", 22195489c19Sopenharmony_ci characteristic.handle_, clientSptr->pimpl->requestInformation_.type_); 22295489c19Sopenharmony_ci ret = BT_ERR_INTERNAL_ERROR; 22395489c19Sopenharmony_ci } 22495489c19Sopenharmony_ci if (clientSptr->pimpl->requestInformation_.type_ != REQUEST_TYPE_CHARACTERISTICS_WRITE) { 22595489c19Sopenharmony_ci HILOGE("Unexpected call!"); 22695489c19Sopenharmony_ci return; 22795489c19Sopenharmony_ci } 22895489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnCharacteristicWriteResult, charac, ret); 22995489c19Sopenharmony_ci } 23095489c19Sopenharmony_ci 23195489c19Sopenharmony_ci void OnDescriptorRead(int32_t ret, const BluetoothGattDescriptor &descriptor) override 23295489c19Sopenharmony_ci { 23395489c19Sopenharmony_ci HILOGI("ret:%{public}d, length:%{public}zu", ret, descriptor.length_); 23495489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 23595489c19Sopenharmony_ci if (!clientSptr) { 23695489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 23795489c19Sopenharmony_ci return; 23895489c19Sopenharmony_ci } 23995489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_); 24095489c19Sopenharmony_ci clientSptr->pimpl->requestInformation_.doing_ = false; 24195489c19Sopenharmony_ci GattDescriptor desc(UUID(), 0); 24295489c19Sopenharmony_ci bool isExist = clientSptr->pimpl->GetDescriptorByHandle(descriptor.handle_, desc); 24395489c19Sopenharmony_ci if (!isExist) { 24495489c19Sopenharmony_ci HILOGE("no expected descriptor handle:%{public}d type:%{public}d", 24595489c19Sopenharmony_ci descriptor.handle_, clientSptr->pimpl->requestInformation_.type_); 24695489c19Sopenharmony_ci ret = BT_ERR_INTERNAL_ERROR; 24795489c19Sopenharmony_ci } 24895489c19Sopenharmony_ci if (clientSptr->pimpl->requestInformation_.type_ != REQUEST_TYPE_DESCRIPTOR_READ) { 24995489c19Sopenharmony_ci HILOGE("Unexpected call!"); 25095489c19Sopenharmony_ci return; 25195489c19Sopenharmony_ci } 25295489c19Sopenharmony_ci if (ret == GattStatus::GATT_SUCCESS) { 25395489c19Sopenharmony_ci desc.SetValue(descriptor.value_.get(), descriptor.length_); 25495489c19Sopenharmony_ci } 25595489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnDescriptorReadResult, desc, ret); 25695489c19Sopenharmony_ci } 25795489c19Sopenharmony_ci 25895489c19Sopenharmony_ci void OnDescriptorWrite(int32_t ret, const BluetoothGattDescriptor &descriptor) override 25995489c19Sopenharmony_ci { 26095489c19Sopenharmony_ci HILOGD("ret:%{public}d, length:%{public}zu", ret, descriptor.length_); 26195489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 26295489c19Sopenharmony_ci if (!clientSptr) { 26395489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 26495489c19Sopenharmony_ci return; 26595489c19Sopenharmony_ci } 26695489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_); 26795489c19Sopenharmony_ci clientSptr->pimpl->requestInformation_.doing_ = false; 26895489c19Sopenharmony_ci GattDescriptor desc(UUID(), 0); 26995489c19Sopenharmony_ci bool isExist = clientSptr->pimpl->GetDescriptorByHandle(descriptor.handle_, desc); 27095489c19Sopenharmony_ci if (!isExist) { 27195489c19Sopenharmony_ci HILOGE("no expected descriptor handle:%{public}d type:%{public}d", 27295489c19Sopenharmony_ci descriptor.handle_, clientSptr->pimpl->requestInformation_.type_); 27395489c19Sopenharmony_ci ret = BT_ERR_INTERNAL_ERROR; 27495489c19Sopenharmony_ci } 27595489c19Sopenharmony_ci if (clientSptr->pimpl->requestInformation_.type_ == REQUEST_TYPE_DESCRIPTOR_WRITE) { 27695489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnDescriptorWriteResult, desc, ret); 27795489c19Sopenharmony_ci } else if (clientSptr->pimpl->requestInformation_.type_ == REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS) { 27895489c19Sopenharmony_ci GattCharacteristic charac(UUID(), 0, 0); 27995489c19Sopenharmony_ci if (isExist && desc.GetCharacteristic() != nullptr) { 28095489c19Sopenharmony_ci charac = *desc.GetCharacteristic(); 28195489c19Sopenharmony_ci } 28295489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnSetNotifyCharacteristic, charac, ret); 28395489c19Sopenharmony_ci } else { 28495489c19Sopenharmony_ci HILOGE("Unexpected call!"); 28595489c19Sopenharmony_ci return; 28695489c19Sopenharmony_ci } 28795489c19Sopenharmony_ci } 28895489c19Sopenharmony_ci 28995489c19Sopenharmony_ci void OnMtuChanged(int32_t state, int32_t mtu) override 29095489c19Sopenharmony_ci { 29195489c19Sopenharmony_ci HILOGI("state: %{public}d, mtu: %{public}d", state, mtu); 29295489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 29395489c19Sopenharmony_ci if (!clientSptr) { 29495489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 29595489c19Sopenharmony_ci return; 29695489c19Sopenharmony_ci } 29795489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnMtuUpdate, mtu, state); 29895489c19Sopenharmony_ci } 29995489c19Sopenharmony_ci 30095489c19Sopenharmony_ci void OnServicesDiscovered(int32_t status) override 30195489c19Sopenharmony_ci { 30295489c19Sopenharmony_ci HILOGI("status: %{public}d", status); 30395489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 30495489c19Sopenharmony_ci if (!clientSptr) { 30595489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 30695489c19Sopenharmony_ci return; 30795489c19Sopenharmony_ci } 30895489c19Sopenharmony_ci clientSptr->pimpl->DiscoverComplete(status); 30995489c19Sopenharmony_ci } 31095489c19Sopenharmony_ci 31195489c19Sopenharmony_ci void OnConnectionParameterChanged(int32_t interval, int32_t latency, int32_t timeout, int32_t status) override 31295489c19Sopenharmony_ci { 31395489c19Sopenharmony_ci HILOGD("interval: %{public}d, latency: %{public}d, timeout: %{public}d, status: %{public}d", 31495489c19Sopenharmony_ci interval, latency, timeout, status); 31595489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 31695489c19Sopenharmony_ci if (!clientSptr) { 31795489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 31895489c19Sopenharmony_ci return; 31995489c19Sopenharmony_ci } 32095489c19Sopenharmony_ci 32195489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnConnectionParameterChanged, interval, latency, timeout, status); 32295489c19Sopenharmony_ci } 32395489c19Sopenharmony_ci 32495489c19Sopenharmony_ci void OnReadRemoteRssiValue(const bluetooth::RawAddress &addr, int32_t rssi, int32_t status) override 32595489c19Sopenharmony_ci { 32695489c19Sopenharmony_ci HILOGI("rssi: %{public}d, status: %{public}d", rssi, status); 32795489c19Sopenharmony_ci std::shared_ptr<GattClient> clientSptr = (client_).lock(); 32895489c19Sopenharmony_ci if (!clientSptr) { 32995489c19Sopenharmony_ci HILOGE("callback client is nullptr"); 33095489c19Sopenharmony_ci return; 33195489c19Sopenharmony_ci } 33295489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_); 33395489c19Sopenharmony_ci clientSptr->pimpl->requestInformation_.doing_ = false; 33495489c19Sopenharmony_ci if (clientSptr->pimpl->requestInformation_.type_ != REQUEST_TYPE_READ_REMOTE_RSSI_VALUE) { 33595489c19Sopenharmony_ci HILOGE("Unexpected call!"); 33695489c19Sopenharmony_ci } 33795489c19Sopenharmony_ci WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnReadRemoteRssiValueResult, rssi, status); 33895489c19Sopenharmony_ci } 33995489c19Sopenharmony_ci 34095489c19Sopenharmony_ci explicit BluetoothGattClientCallbackStubImpl(std::weak_ptr<GattClient> client) : client_(client) 34195489c19Sopenharmony_ci {} 34295489c19Sopenharmony_ci ~BluetoothGattClientCallbackStubImpl() override 34395489c19Sopenharmony_ci {} 34495489c19Sopenharmony_ci 34595489c19Sopenharmony_ciprivate: 34695489c19Sopenharmony_ci std::weak_ptr<GattClient> client_; 34795489c19Sopenharmony_ci}; 34895489c19Sopenharmony_ci 34995489c19Sopenharmony_cibool GattClient::impl::Init(std::weak_ptr<GattClient> client) 35095489c19Sopenharmony_ci{ 35195489c19Sopenharmony_ci if (clientCallback_ != nullptr) { 35295489c19Sopenharmony_ci return true; 35395489c19Sopenharmony_ci } 35495489c19Sopenharmony_ci clientCallback_ = new BluetoothGattClientCallbackStubImpl(client); 35595489c19Sopenharmony_ci return true; 35695489c19Sopenharmony_ci} 35795489c19Sopenharmony_ci 35895489c19Sopenharmony_ciGattClient::impl::impl(const BluetoothRemoteDevice &device) 35995489c19Sopenharmony_ci : isGetServiceYet_(false), 36095489c19Sopenharmony_ci isRegisterSucceeded_(false), 36195489c19Sopenharmony_ci applicationId_(0), 36295489c19Sopenharmony_ci connectionState_(static_cast<int>(BTConnectState::DISCONNECTED)), 36395489c19Sopenharmony_ci device_(device) 36495489c19Sopenharmony_ci{ 36595489c19Sopenharmony_ci auto bluetoothTurnOffFunc = [this]() { 36695489c19Sopenharmony_ci applicationId_ = 0; 36795489c19Sopenharmony_ci isRegisterSucceeded_ = false; 36895489c19Sopenharmony_ci }; 36995489c19Sopenharmony_ci ProfileFunctions profileFunctions = { 37095489c19Sopenharmony_ci .bluetoothLoadedfunc = nullptr, 37195489c19Sopenharmony_ci .bleTurnOnFunc = nullptr, 37295489c19Sopenharmony_ci .bluetoothTurnOffFunc = bluetoothTurnOffFunc, 37395489c19Sopenharmony_ci }; 37495489c19Sopenharmony_ci profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc( 37595489c19Sopenharmony_ci PROFILE_GATT_CLIENT, profileFunctions); 37695489c19Sopenharmony_ci} 37795489c19Sopenharmony_ci 37895489c19Sopenharmony_ciGattClient::impl::~impl() 37995489c19Sopenharmony_ci{ 38095489c19Sopenharmony_ci HILOGI("GattClient ~impl"); 38195489c19Sopenharmony_ci BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId); 38295489c19Sopenharmony_ci} 38395489c19Sopenharmony_ci 38495489c19Sopenharmony_ciint GattClient::impl::DiscoverStart() 38595489c19Sopenharmony_ci{ 38695489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 38795489c19Sopenharmony_ci HILOGE("bluetooth is off."); 38895489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 38995489c19Sopenharmony_ci } 39095489c19Sopenharmony_ci 39195489c19Sopenharmony_ci { 39295489c19Sopenharmony_ci std::unique_lock<std::mutex> lock(discoverInformation_.mutex_); 39395489c19Sopenharmony_ci while (discoverInformation_.isDiscovering_) { 39495489c19Sopenharmony_ci auto ret = discoverInformation_.condition_.wait_for(lock, std::chrono::seconds(WAIT_TIMEOUT)); 39595489c19Sopenharmony_ci if (ret == std::cv_status::timeout) { 39695489c19Sopenharmony_ci HILOGE("timeout"); 39795489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 39895489c19Sopenharmony_ci } 39995489c19Sopenharmony_ci } 40095489c19Sopenharmony_ci discoverInformation_.isDiscovering_ = true; 40195489c19Sopenharmony_ci } 40295489c19Sopenharmony_ci 40395489c19Sopenharmony_ci if (!isRegisterSucceeded_) { 40495489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 40595489c19Sopenharmony_ci } 40695489c19Sopenharmony_ci int result = BT_ERR_INTERNAL_ERROR; 40795489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 40895489c19Sopenharmony_ci if (!proxy) { 40995489c19Sopenharmony_ci HILOGE("proxy is null"); 41095489c19Sopenharmony_ci } else { 41195489c19Sopenharmony_ci result = proxy->DiscoveryServices(applicationId_); 41295489c19Sopenharmony_ci if (result != BT_NO_ERROR) { 41395489c19Sopenharmony_ci DiscoverComplete(BT_ERR_INTERNAL_ERROR); 41495489c19Sopenharmony_ci } 41595489c19Sopenharmony_ci } 41695489c19Sopenharmony_ci return result; 41795489c19Sopenharmony_ci} 41895489c19Sopenharmony_ci 41995489c19Sopenharmony_civoid GattClient::impl::DiscoverComplete(int state) 42095489c19Sopenharmony_ci{ 42195489c19Sopenharmony_ci bool ret = false; 42295489c19Sopenharmony_ci { 42395489c19Sopenharmony_ci std::unique_lock<std::mutex> lock(discoverInformation_.mutex_); 42495489c19Sopenharmony_ci if (discoverInformation_.isDiscovering_) { 42595489c19Sopenharmony_ci discoverInformation_.isDiscovering_ = false; 42695489c19Sopenharmony_ci isGetServiceYet_ = false; 42795489c19Sopenharmony_ci discoverInformation_.condition_.notify_all(); 42895489c19Sopenharmony_ci ret = true; 42995489c19Sopenharmony_ci } 43095489c19Sopenharmony_ci } 43195489c19Sopenharmony_ci if (ret) { 43295489c19Sopenharmony_ci std::shared_ptr<GattClientCallback> clientSptr = (callback_).lock(); 43395489c19Sopenharmony_ci clientSptr->OnServicesDiscovered(state); 43495489c19Sopenharmony_ci } 43595489c19Sopenharmony_ci} 43695489c19Sopenharmony_ci 43795489c19Sopenharmony_civoid GattClient::impl::BuildServiceList(const std::vector<BluetoothGattService> &src) 43895489c19Sopenharmony_ci{ 43995489c19Sopenharmony_ci HILOGI("enter"); 44095489c19Sopenharmony_ci for (auto &svc : src) { 44195489c19Sopenharmony_ci GattService svcTmp(UUID::ConvertFrom128Bits(svc.uuid_.ConvertTo128Bits()), 44295489c19Sopenharmony_ci svc.handle_, 44395489c19Sopenharmony_ci svc.endHandle_, 44495489c19Sopenharmony_ci svc.isPrimary_ ? GattServiceType::PRIMARY : GattServiceType::SECONDARY); 44595489c19Sopenharmony_ci for (auto &character : svc.characteristics_) { 44695489c19Sopenharmony_ci GattCharacteristic characterTmp(UUID::ConvertFrom128Bits(character.uuid_.ConvertTo128Bits()), 44795489c19Sopenharmony_ci character.handle_, 44895489c19Sopenharmony_ci character.permissions_, 44995489c19Sopenharmony_ci character.properties_); 45095489c19Sopenharmony_ci for (auto &desc : character.descriptors_) { 45195489c19Sopenharmony_ci characterTmp.AddDescriptor(GattDescriptor( 45295489c19Sopenharmony_ci UUID::ConvertFrom128Bits(desc.uuid_.ConvertTo128Bits()), desc.handle_, desc.permissions_)); 45395489c19Sopenharmony_ci } 45495489c19Sopenharmony_ci svcTmp.AddCharacteristic(std::move(characterTmp)); 45595489c19Sopenharmony_ci } 45695489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(gattServicesMutex_); 45795489c19Sopenharmony_ci gattServices_.emplace_back(std::move(svcTmp)); 45895489c19Sopenharmony_ci } 45995489c19Sopenharmony_ci for (auto &svc : src) { 46095489c19Sopenharmony_ci GattService *ptr = FindService(svc.handle_); 46195489c19Sopenharmony_ci if (ptr == NULL) { 46295489c19Sopenharmony_ci return; 46395489c19Sopenharmony_ci } 46495489c19Sopenharmony_ci for (auto &isvc : svc.includeServices_) { 46595489c19Sopenharmony_ci GattService *iptr = FindService(isvc.startHandle_); 46695489c19Sopenharmony_ci if (iptr == nullptr) { 46795489c19Sopenharmony_ci return; 46895489c19Sopenharmony_ci } 46995489c19Sopenharmony_ci ptr->AddService(*iptr); 47095489c19Sopenharmony_ci } 47195489c19Sopenharmony_ci } 47295489c19Sopenharmony_ci} 47395489c19Sopenharmony_ci 47495489c19Sopenharmony_ciGattService *GattClient::impl::FindService(uint16_t handle) 47595489c19Sopenharmony_ci{ 47695489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(gattServicesMutex_); 47795489c19Sopenharmony_ci for (auto &item : gattServices_) { 47895489c19Sopenharmony_ci if (item.GetHandle() == handle) { 47995489c19Sopenharmony_ci return &item; 48095489c19Sopenharmony_ci } 48195489c19Sopenharmony_ci } 48295489c19Sopenharmony_ci return nullptr; 48395489c19Sopenharmony_ci} 48495489c19Sopenharmony_ci 48595489c19Sopenharmony_civoid GattClient::impl::GetServices() 48695489c19Sopenharmony_ci{ 48795489c19Sopenharmony_ci HILOGD("enter"); 48895489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 48995489c19Sopenharmony_ci HILOGE("bluetooth is off."); 49095489c19Sopenharmony_ci return; 49195489c19Sopenharmony_ci } 49295489c19Sopenharmony_ci 49395489c19Sopenharmony_ci std::unique_lock<std::mutex> lock(discoverInformation_.mutex_); 49495489c19Sopenharmony_ci while (discoverInformation_.isDiscovering_) { 49595489c19Sopenharmony_ci auto ret = discoverInformation_.condition_.wait_for(lock, std::chrono::seconds(WAIT_TIMEOUT)); 49695489c19Sopenharmony_ci if (ret == std::cv_status::timeout) { 49795489c19Sopenharmony_ci HILOGE("timeout"); 49895489c19Sopenharmony_ci return; 49995489c19Sopenharmony_ci } 50095489c19Sopenharmony_ci } 50195489c19Sopenharmony_ci if (isGetServiceYet_) { 50295489c19Sopenharmony_ci HILOGD("isGetServiceYet_ is true"); 50395489c19Sopenharmony_ci return; 50495489c19Sopenharmony_ci } 50595489c19Sopenharmony_ci if (!isRegisterSucceeded_) { 50695489c19Sopenharmony_ci HILOGE("isRegisterSucceeded_ is false"); 50795489c19Sopenharmony_ci return; 50895489c19Sopenharmony_ci } 50995489c19Sopenharmony_ci { 51095489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(gattServicesMutex_); 51195489c19Sopenharmony_ci gattServices_.clear(); 51295489c19Sopenharmony_ci } 51395489c19Sopenharmony_ci std::vector<BluetoothGattService> result; 51495489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 51595489c19Sopenharmony_ci if (!proxy) { 51695489c19Sopenharmony_ci HILOGE("proxy is null"); 51795489c19Sopenharmony_ci } else { 51895489c19Sopenharmony_ci proxy->GetServices(applicationId_, result); 51995489c19Sopenharmony_ci BuildServiceList(result); 52095489c19Sopenharmony_ci isGetServiceYet_ = true; 52195489c19Sopenharmony_ci } 52295489c19Sopenharmony_ci} 52395489c19Sopenharmony_ci 52495489c19Sopenharmony_civoid GattClient::impl::CleanConnectionInfo() 52595489c19Sopenharmony_ci{ 52695489c19Sopenharmony_ci DiscoverComplete(GattStatus::GATT_FAILURE); 52795489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(requestInformation_.mutex_); 52895489c19Sopenharmony_ci requestInformation_.doing_ = false; 52995489c19Sopenharmony_ci} 53095489c19Sopenharmony_ci 53195489c19Sopenharmony_cibool GattClient::impl::GetCharacteristicByHandle(uint16_t handle, GattCharacteristic &outCharac) 53295489c19Sopenharmony_ci{ 53395489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(gattServicesMutex_); 53495489c19Sopenharmony_ci for (auto &svc : gattServices_) { 53595489c19Sopenharmony_ci std::vector<GattCharacteristic> &characs = svc.GetCharacteristics(); 53695489c19Sopenharmony_ci for (auto &charac : characs) { 53795489c19Sopenharmony_ci if (handle == charac.GetHandle()) { 53895489c19Sopenharmony_ci outCharac = charac; 53995489c19Sopenharmony_ci return true; 54095489c19Sopenharmony_ci } 54195489c19Sopenharmony_ci } 54295489c19Sopenharmony_ci } 54395489c19Sopenharmony_ci return false; 54495489c19Sopenharmony_ci} 54595489c19Sopenharmony_ci 54695489c19Sopenharmony_cibool GattClient::impl::GetDescriptorByHandle(uint16_t handle, GattDescriptor &outDesc) 54795489c19Sopenharmony_ci{ 54895489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(gattServicesMutex_); 54995489c19Sopenharmony_ci auto getDescriptorFunc = [handle](std::vector<GattCharacteristic> &characs) -> GattDescriptor* { 55095489c19Sopenharmony_ci for (auto &charac : characs) { 55195489c19Sopenharmony_ci std::vector<GattDescriptor> &descs = charac.GetDescriptors(); 55295489c19Sopenharmony_ci for (auto &desc : descs) { 55395489c19Sopenharmony_ci if (handle == desc.GetHandle()) { 55495489c19Sopenharmony_ci return &desc; 55595489c19Sopenharmony_ci } 55695489c19Sopenharmony_ci } 55795489c19Sopenharmony_ci } 55895489c19Sopenharmony_ci return nullptr; 55995489c19Sopenharmony_ci }; 56095489c19Sopenharmony_ci 56195489c19Sopenharmony_ci for (auto &svc : gattServices_) { 56295489c19Sopenharmony_ci GattDescriptor *descPtr = getDescriptorFunc(svc.GetCharacteristics()); 56395489c19Sopenharmony_ci if (descPtr != nullptr) { 56495489c19Sopenharmony_ci outDesc = *descPtr; 56595489c19Sopenharmony_ci return true; 56695489c19Sopenharmony_ci } 56795489c19Sopenharmony_ci } 56895489c19Sopenharmony_ci return false; 56995489c19Sopenharmony_ci} 57095489c19Sopenharmony_ci 57195489c19Sopenharmony_ciGattClient::GattClient(const BluetoothRemoteDevice &device) : pimpl(new GattClient::impl(device)) 57295489c19Sopenharmony_ci{ 57395489c19Sopenharmony_ci HILOGI("enter"); 57495489c19Sopenharmony_ci} 57595489c19Sopenharmony_ci 57695489c19Sopenharmony_cibool GattClient::Init() 57795489c19Sopenharmony_ci{ 57895489c19Sopenharmony_ci HILOGI("GattClient Init"); 57995489c19Sopenharmony_ci return pimpl->Init(weak_from_this()); 58095489c19Sopenharmony_ci} 58195489c19Sopenharmony_ci 58295489c19Sopenharmony_ciGattClient::~GattClient() 58395489c19Sopenharmony_ci{ 58495489c19Sopenharmony_ci HILOGI("~GattClient"); 58595489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 58695489c19Sopenharmony_ci CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 58795489c19Sopenharmony_ci if (pimpl->isRegisterSucceeded_) { 58895489c19Sopenharmony_ci proxy->DeregisterApplication(pimpl->applicationId_); 58995489c19Sopenharmony_ci } 59095489c19Sopenharmony_ci} 59195489c19Sopenharmony_ci 59295489c19Sopenharmony_ciint GattClient::Connect(std::weak_ptr<GattClientCallback> callback, bool isAutoConnect, int transport) 59395489c19Sopenharmony_ci{ 59495489c19Sopenharmony_ci HILOGI("enter, isAutoConnect: %{public}d, transport: %{public}d", isAutoConnect, transport); 59595489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 59695489c19Sopenharmony_ci HILOGE("bluetooth is off."); 59795489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 59895489c19Sopenharmony_ci } 59995489c19Sopenharmony_ci 60095489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 60195489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 60295489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 60395489c19Sopenharmony_ci } 60495489c19Sopenharmony_ci 60595489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->connStateMutex_); 60695489c19Sopenharmony_ci if (pimpl->connectionState_ == static_cast<int>(BTConnectState::CONNECTED)) { 60795489c19Sopenharmony_ci HILOGE("Already connected"); 60895489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 60995489c19Sopenharmony_ci } 61095489c19Sopenharmony_ci HILOGI("isRegisterSucceeded: %{public}d", pimpl->isRegisterSucceeded_); 61195489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 61295489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 61395489c19Sopenharmony_ci if (pimpl->isRegisterSucceeded_) { 61495489c19Sopenharmony_ci return proxy->Connect(pimpl->applicationId_, isAutoConnect); 61595489c19Sopenharmony_ci } 61695489c19Sopenharmony_ci pimpl->callback_ = callback; 61795489c19Sopenharmony_ci if ((transport == GATT_TRANSPORT_TYPE_LE && !IS_BLE_ENABLED()) || 61895489c19Sopenharmony_ci (transport == GATT_TRANSPORT_TYPE_CLASSIC && !IS_BT_ENABLED())) { 61995489c19Sopenharmony_ci HILOGE("Unsupported mode"); 62095489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 62195489c19Sopenharmony_ci } 62295489c19Sopenharmony_ci if (transport == GATT_TRANSPORT_TYPE_CLASSIC && isAutoConnect) { 62395489c19Sopenharmony_ci HILOGE("Unsupported mode"); 62495489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 62595489c19Sopenharmony_ci } 62695489c19Sopenharmony_ci if (!pimpl->device_.IsValidBluetoothRemoteDevice()) { 62795489c19Sopenharmony_ci HILOGE("Invalid remote device"); 62895489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 62995489c19Sopenharmony_ci } 63095489c19Sopenharmony_ci 63195489c19Sopenharmony_ci int appId = 0; 63295489c19Sopenharmony_ci int32_t result = proxy->RegisterApplication( 63395489c19Sopenharmony_ci pimpl->clientCallback_, bluetooth::RawAddress(pimpl->device_.GetDeviceAddr()), transport, appId); 63495489c19Sopenharmony_ci HILOGI("Proxy register application : %{public}d", appId); 63595489c19Sopenharmony_ci if (result != BT_NO_ERROR) { 63695489c19Sopenharmony_ci HILOGE("register application fail"); 63795489c19Sopenharmony_ci return result; 63895489c19Sopenharmony_ci } 63995489c19Sopenharmony_ci if (appId > 0) { 64095489c19Sopenharmony_ci pimpl->applicationId_ = appId; 64195489c19Sopenharmony_ci pimpl->isRegisterSucceeded_ = true; 64295489c19Sopenharmony_ci result = proxy->Connect(pimpl->applicationId_, isAutoConnect); 64395489c19Sopenharmony_ci } 64495489c19Sopenharmony_ci return result; 64595489c19Sopenharmony_ci} 64695489c19Sopenharmony_ci 64795489c19Sopenharmony_ciint GattClient::Disconnect() 64895489c19Sopenharmony_ci{ 64995489c19Sopenharmony_ci HILOGI("enter"); 65095489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 65195489c19Sopenharmony_ci HILOGE("bluetooth is off."); 65295489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 65395489c19Sopenharmony_ci } 65495489c19Sopenharmony_ci 65595489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 65695489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 65795489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 65895489c19Sopenharmony_ci } 65995489c19Sopenharmony_ci 66095489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->connStateMutex_); 66195489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) { 66295489c19Sopenharmony_ci HILOGE("Request not supported"); 66395489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 66495489c19Sopenharmony_ci } 66595489c19Sopenharmony_ci int result = BT_ERR_INTERNAL_ERROR; 66695489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 66795489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 66895489c19Sopenharmony_ci result = proxy->Disconnect(pimpl->applicationId_); 66995489c19Sopenharmony_ci return result; 67095489c19Sopenharmony_ci} 67195489c19Sopenharmony_ci 67295489c19Sopenharmony_ciint GattClient::Close() 67395489c19Sopenharmony_ci{ 67495489c19Sopenharmony_ci HILOGI("enter"); 67595489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 67695489c19Sopenharmony_ci HILOGE("bluetooth is off."); 67795489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 67895489c19Sopenharmony_ci } 67995489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 68095489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 68195489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 68295489c19Sopenharmony_ci } 68395489c19Sopenharmony_ci 68495489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 68595489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 68695489c19Sopenharmony_ci if (pimpl->isRegisterSucceeded_) { 68795489c19Sopenharmony_ci int32_t result = proxy->DeregisterApplication(pimpl->applicationId_); 68895489c19Sopenharmony_ci HILOGI("result: %{public}d", result); 68995489c19Sopenharmony_ci if (result == BT_NO_ERROR) { 69095489c19Sopenharmony_ci pimpl->isRegisterSucceeded_ = false; 69195489c19Sopenharmony_ci } 69295489c19Sopenharmony_ci return result; 69395489c19Sopenharmony_ci } 69495489c19Sopenharmony_ci HILOGI("isRegisterSucceeded_ is false"); 69595489c19Sopenharmony_ci return BT_NO_ERROR; 69695489c19Sopenharmony_ci} 69795489c19Sopenharmony_ci 69895489c19Sopenharmony_ciint GattClient::DiscoverServices() 69995489c19Sopenharmony_ci{ 70095489c19Sopenharmony_ci HILOGI("enter"); 70195489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 70295489c19Sopenharmony_ci HILOGE("bluetooth is off."); 70395489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 70495489c19Sopenharmony_ci } 70595489c19Sopenharmony_ci 70695489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 70795489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 70895489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 70995489c19Sopenharmony_ci } 71095489c19Sopenharmony_ci 71195489c19Sopenharmony_ci std::lock_guard<std::mutex> lck(pimpl->connStateMutex_); 71295489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) { 71395489c19Sopenharmony_ci HILOGE("Request not supported"); 71495489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 71595489c19Sopenharmony_ci } 71695489c19Sopenharmony_ci return pimpl->DiscoverStart(); 71795489c19Sopenharmony_ci} 71895489c19Sopenharmony_ci 71995489c19Sopenharmony_cistd::optional<std::reference_wrapper<GattService>> GattClient::GetService(const UUID &uuid) 72095489c19Sopenharmony_ci{ 72195489c19Sopenharmony_ci HILOGD("enter"); 72295489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 72395489c19Sopenharmony_ci HILOGE("bluetooth is off."); 72495489c19Sopenharmony_ci return std::nullopt; 72595489c19Sopenharmony_ci } 72695489c19Sopenharmony_ci 72795489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 72895489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 72995489c19Sopenharmony_ci return std::nullopt; 73095489c19Sopenharmony_ci } 73195489c19Sopenharmony_ci 73295489c19Sopenharmony_ci pimpl->GetServices(); 73395489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->gattServicesMutex_); 73495489c19Sopenharmony_ci for (auto &svc : pimpl->gattServices_) { 73595489c19Sopenharmony_ci if (svc.GetUuid().Equals(uuid)) { 73695489c19Sopenharmony_ci HILOGD("successful"); 73795489c19Sopenharmony_ci return svc; 73895489c19Sopenharmony_ci } 73995489c19Sopenharmony_ci } 74095489c19Sopenharmony_ci HILOGE("failed"); 74195489c19Sopenharmony_ci return std::nullopt; 74295489c19Sopenharmony_ci} 74395489c19Sopenharmony_ci 74495489c19Sopenharmony_cistd::vector<GattService> &GattClient::GetService() 74595489c19Sopenharmony_ci{ 74695489c19Sopenharmony_ci HILOGI("enter"); 74795489c19Sopenharmony_ci std::vector<GattService> gattServices; 74895489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 74995489c19Sopenharmony_ci HILOGE("bluetooth is off."); 75095489c19Sopenharmony_ci return gattServices; 75195489c19Sopenharmony_ci } 75295489c19Sopenharmony_ci 75395489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 75495489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 75595489c19Sopenharmony_ci return gattServices; 75695489c19Sopenharmony_ci } 75795489c19Sopenharmony_ci 75895489c19Sopenharmony_ci pimpl->GetServices(); 75995489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->gattServicesMutex_); 76095489c19Sopenharmony_ci return pimpl->gattServices_; 76195489c19Sopenharmony_ci} 76295489c19Sopenharmony_ci 76395489c19Sopenharmony_ciint GattClient::ReadCharacteristic(GattCharacteristic &characteristic) 76495489c19Sopenharmony_ci{ 76595489c19Sopenharmony_ci HILOGI("enter"); 76695489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 76795489c19Sopenharmony_ci HILOGE("bluetooth is off."); 76895489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 76995489c19Sopenharmony_ci } 77095489c19Sopenharmony_ci 77195489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 77295489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 77395489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 77495489c19Sopenharmony_ci } 77595489c19Sopenharmony_ci 77695489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->connStateMutex_); 77795489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) { 77895489c19Sopenharmony_ci HILOGE("Request not supported"); 77995489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 78095489c19Sopenharmony_ci } 78195489c19Sopenharmony_ci std::lock_guard<std::mutex> lck(pimpl->requestInformation_.mutex_); 78295489c19Sopenharmony_ci if (pimpl->requestInformation_.doing_) { 78395489c19Sopenharmony_ci HILOGE("Remote device busy"); 78495489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 78595489c19Sopenharmony_ci } 78695489c19Sopenharmony_ci int result = GattStatus::GATT_FAILURE; 78795489c19Sopenharmony_ci HILOGI("applicationId: %{public}d, handle: 0x%{public}04X", pimpl->applicationId_, characteristic.GetHandle()); 78895489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 78995489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 79095489c19Sopenharmony_ci result = proxy->ReadCharacteristic( 79195489c19Sopenharmony_ci pimpl->applicationId_, (BluetoothGattCharacteristic)bluetooth::Characteristic(characteristic.GetHandle())); 79295489c19Sopenharmony_ci HILOGI("result: %{public}d", result); 79395489c19Sopenharmony_ci if (result == BT_NO_ERROR) { 79495489c19Sopenharmony_ci pimpl->requestInformation_.doing_ = true; 79595489c19Sopenharmony_ci pimpl->requestInformation_.type_ = REQUEST_TYPE_CHARACTERISTICS_READ; 79695489c19Sopenharmony_ci } 79795489c19Sopenharmony_ci return result; 79895489c19Sopenharmony_ci} 79995489c19Sopenharmony_ci 80095489c19Sopenharmony_ciint GattClient::ReadDescriptor(GattDescriptor &descriptor) 80195489c19Sopenharmony_ci{ 80295489c19Sopenharmony_ci HILOGI("enter"); 80395489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 80495489c19Sopenharmony_ci HILOGE("bluetooth is off."); 80595489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 80695489c19Sopenharmony_ci } 80795489c19Sopenharmony_ci 80895489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 80995489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 81095489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 81195489c19Sopenharmony_ci } 81295489c19Sopenharmony_ci 81395489c19Sopenharmony_ci std::lock_guard<std::mutex> lck(pimpl->connStateMutex_); 81495489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) { 81595489c19Sopenharmony_ci HILOGE("Request not supported"); 81695489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 81795489c19Sopenharmony_ci } 81895489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_); 81995489c19Sopenharmony_ci if (pimpl->requestInformation_.doing_) { 82095489c19Sopenharmony_ci HILOGE("Remote device busy"); 82195489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 82295489c19Sopenharmony_ci } 82395489c19Sopenharmony_ci int result = BT_ERR_INTERNAL_ERROR; 82495489c19Sopenharmony_ci HILOGI("applicationId: %{public}d, handle: 0x%{public}04X", pimpl->applicationId_, descriptor.GetHandle()); 82595489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 82695489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 82795489c19Sopenharmony_ci result = proxy->ReadDescriptor( 82895489c19Sopenharmony_ci pimpl->applicationId_, (BluetoothGattDescriptor)bluetooth::Descriptor(descriptor.GetHandle())); 82995489c19Sopenharmony_ci HILOGI("result: %{public}d", result); 83095489c19Sopenharmony_ci if (result == BT_NO_ERROR) { 83195489c19Sopenharmony_ci pimpl->requestInformation_.doing_ = true; 83295489c19Sopenharmony_ci pimpl->requestInformation_.type_ = REQUEST_TYPE_DESCRIPTOR_READ; 83395489c19Sopenharmony_ci } 83495489c19Sopenharmony_ci return result; 83595489c19Sopenharmony_ci} 83695489c19Sopenharmony_ci 83795489c19Sopenharmony_ciint GattClient::RequestBleMtuSize(int mtu) 83895489c19Sopenharmony_ci{ 83995489c19Sopenharmony_ci HILOGD("enter"); 84095489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 84195489c19Sopenharmony_ci HILOGE("bluetooth is off."); 84295489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 84395489c19Sopenharmony_ci } 84495489c19Sopenharmony_ci 84595489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 84695489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 84795489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 84895489c19Sopenharmony_ci } 84995489c19Sopenharmony_ci 85095489c19Sopenharmony_ci std::lock_guard<std::mutex> lck(pimpl->connStateMutex_); 85195489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) { 85295489c19Sopenharmony_ci HILOGE("Request not supported"); 85395489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 85495489c19Sopenharmony_ci } 85595489c19Sopenharmony_ci int result = BT_ERR_INTERNAL_ERROR; 85695489c19Sopenharmony_ci HILOGI("applicationId: %{public}d, mtu: %{public}d", pimpl->applicationId_, mtu); 85795489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 85895489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 85995489c19Sopenharmony_ci result = proxy->RequestExchangeMtu(pimpl->applicationId_, mtu); 86095489c19Sopenharmony_ci HILOGI("result: %{public}d", result); 86195489c19Sopenharmony_ci return result; 86295489c19Sopenharmony_ci} 86395489c19Sopenharmony_ci 86495489c19Sopenharmony_ciint GattClient::SetNotifyCharacteristicInner(GattCharacteristic &characteristic, bool enable, 86595489c19Sopenharmony_ci const std::vector<uint8_t> &descriptorValue) 86695489c19Sopenharmony_ci{ 86795489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 86895489c19Sopenharmony_ci HILOGE("bluetooth is off."); 86995489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 87095489c19Sopenharmony_ci } 87195489c19Sopenharmony_ci 87295489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 87395489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 87495489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 87595489c19Sopenharmony_ci } 87695489c19Sopenharmony_ci 87795489c19Sopenharmony_ci std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_); 87895489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) { 87995489c19Sopenharmony_ci HILOGE("Request not supported"); 88095489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 88195489c19Sopenharmony_ci } 88295489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 88395489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 88495489c19Sopenharmony_ci int ret = proxy->RequestNotification(pimpl->applicationId_, characteristic.GetHandle(), enable); 88595489c19Sopenharmony_ci if (ret != BT_NO_ERROR) { 88695489c19Sopenharmony_ci return ret; 88795489c19Sopenharmony_ci } 88895489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_); 88995489c19Sopenharmony_ci if (pimpl->requestInformation_.doing_) { 89095489c19Sopenharmony_ci HILOGI("Remote device busy"); 89195489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 89295489c19Sopenharmony_ci } 89395489c19Sopenharmony_ci auto descriptor = characteristic.GetDescriptor(UUID::FromString("00002902-0000-1000-8000-00805F9B34FB")); 89495489c19Sopenharmony_ci if (descriptor == nullptr) { 89595489c19Sopenharmony_ci HILOGE("descriptor not exist."); 89695489c19Sopenharmony_ci // some devices don't have this descriptor, call back to application 89795489c19Sopenharmony_ci std::thread([this, characteristic]() { 89895489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_); 89995489c19Sopenharmony_ci WPTR_GATT_CBACK(pimpl->callback_, OnSetNotifyCharacteristic, characteristic, 0); 90095489c19Sopenharmony_ci }).detach(); 90195489c19Sopenharmony_ci return BT_NO_ERROR; 90295489c19Sopenharmony_ci } 90395489c19Sopenharmony_ci BluetoothGattDescriptor desc(bluetooth::Descriptor( 90495489c19Sopenharmony_ci descriptor->GetHandle(), descriptorValue.data(), descriptorValue.size())); 90595489c19Sopenharmony_ci int result = GattStatus::GATT_FAILURE; 90695489c19Sopenharmony_ci HILOGD("applicationId: %{public}d", pimpl->applicationId_); 90795489c19Sopenharmony_ci result = proxy->WriteDescriptor(pimpl->applicationId_, &desc); 90895489c19Sopenharmony_ci HILOGD("result: %{public}d", result); 90995489c19Sopenharmony_ci if (result == BT_NO_ERROR) { 91095489c19Sopenharmony_ci pimpl->requestInformation_.type_ = REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS; 91195489c19Sopenharmony_ci pimpl->requestInformation_.doing_ = true; 91295489c19Sopenharmony_ci } 91395489c19Sopenharmony_ci return result; 91495489c19Sopenharmony_ci} 91595489c19Sopenharmony_ci 91695489c19Sopenharmony_ciint GattClient::SetNotifyCharacteristic(GattCharacteristic &characteristic, bool enable) 91795489c19Sopenharmony_ci{ 91895489c19Sopenharmony_ci HILOGI("handle: 0x%{public}04X, enable: %{public}d", characteristic.GetHandle(), enable); 91995489c19Sopenharmony_ci std::vector<uint8_t> enableNotifyValue = {1, 0}; 92095489c19Sopenharmony_ci std::vector<uint8_t> disableValue = {0, 0}; 92195489c19Sopenharmony_ci return SetNotifyCharacteristicInner(characteristic, enable, (enable ? enableNotifyValue : disableValue)); 92295489c19Sopenharmony_ci} 92395489c19Sopenharmony_ci 92495489c19Sopenharmony_ciint GattClient::SetIndicateCharacteristic(GattCharacteristic &characteristic, bool enable) 92595489c19Sopenharmony_ci{ 92695489c19Sopenharmony_ci HILOGI("handle: 0x%{public}04X, enable: %{public}d", characteristic.GetHandle(), enable); 92795489c19Sopenharmony_ci std::vector<uint8_t> enableIndicateValue = {2, 0}; 92895489c19Sopenharmony_ci std::vector<uint8_t> disableValue = {0, 0}; 92995489c19Sopenharmony_ci return SetNotifyCharacteristicInner(characteristic, enable, (enable ? enableIndicateValue : disableValue)); 93095489c19Sopenharmony_ci} 93195489c19Sopenharmony_ci 93295489c19Sopenharmony_ciint GattClient::WriteCharacteristic(GattCharacteristic &characteristic) 93395489c19Sopenharmony_ci{ 93495489c19Sopenharmony_ci size_t length = 0; 93595489c19Sopenharmony_ci const uint8_t *pData = characteristic.GetValue(&length).get(); 93695489c19Sopenharmony_ci std::vector<uint8_t> value(pData, pData + length); 93795489c19Sopenharmony_ci return WriteCharacteristic(characteristic, std::move(value)); 93895489c19Sopenharmony_ci} 93995489c19Sopenharmony_ci 94095489c19Sopenharmony_ciint GattClient::WriteCharacteristic(GattCharacteristic &characteristic, std::vector<uint8_t> value) 94195489c19Sopenharmony_ci{ 94295489c19Sopenharmony_ci HILOGD("enter"); 94395489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 94495489c19Sopenharmony_ci HILOGE("bluetooth is off."); 94595489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 94695489c19Sopenharmony_ci } 94795489c19Sopenharmony_ci 94895489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 94995489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 95095489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 95195489c19Sopenharmony_ci } 95295489c19Sopenharmony_ci 95395489c19Sopenharmony_ci std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_); 95495489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) { 95595489c19Sopenharmony_ci HILOGE("Request not supported"); 95695489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 95795489c19Sopenharmony_ci } 95895489c19Sopenharmony_ci size_t length = value.size(); 95995489c19Sopenharmony_ci HILOGD("length:%{public}zu", length); 96095489c19Sopenharmony_ci if (length == 0) { 96195489c19Sopenharmony_ci HILOGE("Invalid parameters"); 96295489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 96395489c19Sopenharmony_ci } 96495489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_); 96595489c19Sopenharmony_ci if (pimpl->requestInformation_.doing_) { 96695489c19Sopenharmony_ci HILOGE("Remote device busy"); 96795489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 96895489c19Sopenharmony_ci } 96995489c19Sopenharmony_ci BluetoothGattCharacteristic character( 97095489c19Sopenharmony_ci bluetooth::Characteristic(characteristic.GetHandle(), value.data(), length)); 97195489c19Sopenharmony_ci int result = BT_ERR_INTERNAL_ERROR; 97295489c19Sopenharmony_ci bool withoutRespond = true; 97395489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 97495489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 97595489c19Sopenharmony_ci if (characteristic.GetWriteType() == static_cast<int>(GattCharacteristic::WriteType::SIGNED)) { 97695489c19Sopenharmony_ci HILOGI("Signed write"); 97795489c19Sopenharmony_ci result = proxy->SignedWriteCharacteristic(pimpl->applicationId_, &character); 97895489c19Sopenharmony_ci } else { 97995489c19Sopenharmony_ci withoutRespond = ((characteristic.GetWriteType() == 98095489c19Sopenharmony_ci static_cast<int>(GattCharacteristic::WriteType::DEFAULT)) ? false : true); 98195489c19Sopenharmony_ci HILOGD("Write without response:%{public}d", withoutRespond); 98295489c19Sopenharmony_ci pimpl->requestInformation_.type_ = REQUEST_TYPE_CHARACTERISTICS_WRITE; 98395489c19Sopenharmony_ci // if withoutRespond is true, no need wait for callback 98495489c19Sopenharmony_ci pimpl->requestInformation_.doing_ = (!withoutRespond); 98595489c19Sopenharmony_ci result = proxy->WriteCharacteristic(pimpl->applicationId_, &character, withoutRespond); 98695489c19Sopenharmony_ci } 98795489c19Sopenharmony_ci if (result != GattStatus::GATT_SUCCESS) { 98895489c19Sopenharmony_ci HILOGE("Write failed, ret: %{public}d", result); 98995489c19Sopenharmony_ci pimpl->requestInformation_.doing_ = false; 99095489c19Sopenharmony_ci } 99195489c19Sopenharmony_ci return result; 99295489c19Sopenharmony_ci} 99395489c19Sopenharmony_ci 99495489c19Sopenharmony_ciint GattClient::WriteDescriptor(GattDescriptor &descriptor) 99595489c19Sopenharmony_ci{ 99695489c19Sopenharmony_ci HILOGI("enter"); 99795489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 99895489c19Sopenharmony_ci HILOGE("bluetooth is off."); 99995489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 100095489c19Sopenharmony_ci } 100195489c19Sopenharmony_ci 100295489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 100395489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 100495489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 100595489c19Sopenharmony_ci } 100695489c19Sopenharmony_ci 100795489c19Sopenharmony_ci std::lock_guard<std::mutex> lck(pimpl->connStateMutex_); 100895489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) { 100995489c19Sopenharmony_ci HILOGE("Request not supported"); 101095489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 101195489c19Sopenharmony_ci } 101295489c19Sopenharmony_ci size_t length = 0; 101395489c19Sopenharmony_ci auto &characterValue = descriptor.GetValue(&length); 101495489c19Sopenharmony_ci if (characterValue == nullptr || length == 0) { 101595489c19Sopenharmony_ci HILOGE("Invalid parameters"); 101695489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 101795489c19Sopenharmony_ci } 101895489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_); 101995489c19Sopenharmony_ci if (pimpl->requestInformation_.doing_) { 102095489c19Sopenharmony_ci HILOGE("Remote device busy"); 102195489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 102295489c19Sopenharmony_ci } 102395489c19Sopenharmony_ci int result = BT_ERR_INTERNAL_ERROR; 102495489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 102595489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 102695489c19Sopenharmony_ci BluetoothGattDescriptor desc(bluetooth::Descriptor(descriptor.GetHandle(), characterValue.get(), length)); 102795489c19Sopenharmony_ci result = proxy->WriteDescriptor(pimpl->applicationId_, &desc); 102895489c19Sopenharmony_ci HILOGI("result: %{public}d", result); 102995489c19Sopenharmony_ci if (result == BT_NO_ERROR) { 103095489c19Sopenharmony_ci pimpl->requestInformation_.doing_ = true; 103195489c19Sopenharmony_ci pimpl->requestInformation_.type_ = REQUEST_TYPE_DESCRIPTOR_WRITE; 103295489c19Sopenharmony_ci } 103395489c19Sopenharmony_ci return result; 103495489c19Sopenharmony_ci} 103595489c19Sopenharmony_ci 103695489c19Sopenharmony_ciint GattClient::RequestConnectionPriority(int connPriority) 103795489c19Sopenharmony_ci{ 103895489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 103995489c19Sopenharmony_ci HILOGE("bluetooth is off."); 104095489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 104195489c19Sopenharmony_ci } 104295489c19Sopenharmony_ci 104395489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 104495489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 104595489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 104695489c19Sopenharmony_ci } 104795489c19Sopenharmony_ci 104895489c19Sopenharmony_ci std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_); 104995489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) { 105095489c19Sopenharmony_ci HILOGE("Not connected"); 105195489c19Sopenharmony_ci return GattStatus::REQUEST_NOT_SUPPORT; 105295489c19Sopenharmony_ci } 105395489c19Sopenharmony_ci if (connPriority != static_cast<int>(GattConnectionPriority::BALANCED) && 105495489c19Sopenharmony_ci connPriority != static_cast<int>(GattConnectionPriority::HIGH) && 105595489c19Sopenharmony_ci connPriority != static_cast<int>(GattConnectionPriority::LOW_POWER)) { 105695489c19Sopenharmony_ci HILOGE("Invalid parameters"); 105795489c19Sopenharmony_ci return GattStatus::INVALID_PARAMETER; 105895489c19Sopenharmony_ci } 105995489c19Sopenharmony_ci int result = GattStatus::GATT_FAILURE; 106095489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 106195489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 106295489c19Sopenharmony_ci result = proxy->RequestConnectionPriority(pimpl->applicationId_, connPriority); 106395489c19Sopenharmony_ci HILOGI("result: %{public}d", result); 106495489c19Sopenharmony_ci return result; 106595489c19Sopenharmony_ci} 106695489c19Sopenharmony_ci 106795489c19Sopenharmony_ciint GattClient::RequestFastestConn() 106895489c19Sopenharmony_ci{ 106995489c19Sopenharmony_ci HILOGI("enter"); 107095489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 107195489c19Sopenharmony_ci HILOGE("bluetooth is off."); 107295489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 107395489c19Sopenharmony_ci } 107495489c19Sopenharmony_ci 107595489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 107695489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 107795489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 107895489c19Sopenharmony_ci } 107995489c19Sopenharmony_ci 108095489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 108195489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 108295489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->connStateMutex_); 108395489c19Sopenharmony_ci return proxy->RequestFastestConn(bluetooth::RawAddress(pimpl->device_.GetDeviceAddr())); 108495489c19Sopenharmony_ci} 108595489c19Sopenharmony_ciint GattClient::ReadRemoteRssiValue() 108695489c19Sopenharmony_ci{ 108795489c19Sopenharmony_ci HILOGI("enter"); 108895489c19Sopenharmony_ci if (!IS_BLE_ENABLED()) { 108995489c19Sopenharmony_ci HILOGE("bluetooth is off."); 109095489c19Sopenharmony_ci return BT_ERR_INVALID_STATE; 109195489c19Sopenharmony_ci } 109295489c19Sopenharmony_ci 109395489c19Sopenharmony_ci if (pimpl == nullptr || !pimpl->Init(weak_from_this())) { 109495489c19Sopenharmony_ci HILOGE("pimpl or gatt client proxy is nullptr"); 109595489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 109695489c19Sopenharmony_ci } 109795489c19Sopenharmony_ci 109895489c19Sopenharmony_ci std::lock_guard<std::mutex> lock(pimpl->connStateMutex_); 109995489c19Sopenharmony_ci if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) { 110095489c19Sopenharmony_ci HILOGE("Request not supported"); 110195489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 110295489c19Sopenharmony_ci } 110395489c19Sopenharmony_ci std::lock_guard<std::mutex> lck(pimpl->requestInformation_.mutex_); 110495489c19Sopenharmony_ci if (pimpl->requestInformation_.doing_) { 110595489c19Sopenharmony_ci HILOGE("Remote device busy"); 110695489c19Sopenharmony_ci return BT_ERR_INTERNAL_ERROR; 110795489c19Sopenharmony_ci } 110895489c19Sopenharmony_ci int result = GattStatus::GATT_FAILURE; 110995489c19Sopenharmony_ci HILOGI("applicationId: %{public}d", pimpl->applicationId_); 111095489c19Sopenharmony_ci sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT); 111195489c19Sopenharmony_ci CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy"); 111295489c19Sopenharmony_ci result = proxy->ReadRemoteRssiValue(pimpl->applicationId_); 111395489c19Sopenharmony_ci HILOGI("result: %{public}d", result); 111495489c19Sopenharmony_ci if (result == BT_NO_ERROR) { 111595489c19Sopenharmony_ci pimpl->requestInformation_.doing_ = true; 111695489c19Sopenharmony_ci pimpl->requestInformation_.type_ = REQUEST_TYPE_READ_REMOTE_RSSI_VALUE; 111795489c19Sopenharmony_ci } 111895489c19Sopenharmony_ci return result; 111995489c19Sopenharmony_ci} 112095489c19Sopenharmony_ci 112195489c19Sopenharmony_ci} // namespace Bluetooth 112295489c19Sopenharmony_ci} // namespace OHOS