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