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 "bluetooth_gatt_server.h"
2095489c19Sopenharmony_ci#include "bluetooth_host.h"
2195489c19Sopenharmony_ci#include "bluetooth_log.h"
2295489c19Sopenharmony_ci#include "bluetooth_utils.h"
2395489c19Sopenharmony_ci#include "bluetooth_host_proxy.h"
2495489c19Sopenharmony_ci#include "bluetooth_gatt_server_proxy.h"
2595489c19Sopenharmony_ci#include "bluetooth_gatt_server_callback_stub.h"
2695489c19Sopenharmony_ci#include "gatt_data.h"
2795489c19Sopenharmony_ci#include "iservice_registry.h"
2895489c19Sopenharmony_ci#include "raw_address.h"
2995489c19Sopenharmony_ci#include "system_ability_definition.h"
3095489c19Sopenharmony_ci#include "bluetooth_profile_manager.h"
3195489c19Sopenharmony_ci
3295489c19Sopenharmony_cinamespace OHOS {
3395489c19Sopenharmony_cinamespace Bluetooth {
3495489c19Sopenharmony_ciconst int EIGHT_BITS = 8;
3595489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_READ = 0x00;
3695489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_WRITE = 0x01;
3795489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_DESCRIPTOR_READ = 0x02;
3895489c19Sopenharmony_ciconstexpr uint8_t REQUEST_TYPE_DESCRIPTOR_WRITE = 0x03;
3995489c19Sopenharmony_ci
4095489c19Sopenharmony_cistruct RequestInformation {
4195489c19Sopenharmony_ci    uint8_t type_;
4295489c19Sopenharmony_ci    bluetooth::GattDevice device_;
4395489c19Sopenharmony_ci    union {
4495489c19Sopenharmony_ci        GattCharacteristic *characteristic_;
4595489c19Sopenharmony_ci        GattDescriptor *descriptor_;
4695489c19Sopenharmony_ci    } context_;
4795489c19Sopenharmony_ci
4895489c19Sopenharmony_ci    RequestInformation(uint8_t type, const bluetooth::GattDevice &device, GattCharacteristic *characteristic)
4995489c19Sopenharmony_ci        : type_(type), device_(device), context_ {
5095489c19Sopenharmony_ci            .characteristic_ = characteristic
5195489c19Sopenharmony_ci        }
5295489c19Sopenharmony_ci    {}
5395489c19Sopenharmony_ci
5495489c19Sopenharmony_ci    RequestInformation(uint8_t type, const bluetooth::GattDevice &device, GattDescriptor *decriptor)
5595489c19Sopenharmony_ci        : type_(type), device_(device), context_ {
5695489c19Sopenharmony_ci            .descriptor_ = decriptor
5795489c19Sopenharmony_ci        }
5895489c19Sopenharmony_ci    {}
5995489c19Sopenharmony_ci
6095489c19Sopenharmony_ci    RequestInformation(uint8_t type, const bluetooth::GattDevice &device) : type_(type), device_(device)
6195489c19Sopenharmony_ci    {}
6295489c19Sopenharmony_ci
6395489c19Sopenharmony_ci    bool operator==(const RequestInformation &rhs) const
6495489c19Sopenharmony_ci    {
6595489c19Sopenharmony_ci        return (device_ == rhs.device_ && type_ == rhs.type_);
6695489c19Sopenharmony_ci    };
6795489c19Sopenharmony_ci
6895489c19Sopenharmony_ci    bool operator<(const RequestInformation &rhs) const
6995489c19Sopenharmony_ci    {
7095489c19Sopenharmony_ci        return (device_ < rhs.device_ && type_ == rhs.type_);
7195489c19Sopenharmony_ci    };
7295489c19Sopenharmony_ci};
7395489c19Sopenharmony_ci
7495489c19Sopenharmony_cistruct GattServer::impl {
7595489c19Sopenharmony_ci    class BluetoothGattServerCallbackStubImpl;
7695489c19Sopenharmony_ci    bool isRegisterSucceeded_ = false;
7795489c19Sopenharmony_ci    std::mutex serviceListMutex_;
7895489c19Sopenharmony_ci    std::mutex requestListMutex_;
7995489c19Sopenharmony_ci    std::list<GattService> gattServices_;
8095489c19Sopenharmony_ci    sptr<BluetoothGattServerCallbackStubImpl> serviceCallback_;
8195489c19Sopenharmony_ci    std::optional<std::reference_wrapper<GattCharacteristic>> FindCharacteristic(uint16_t handle);
8295489c19Sopenharmony_ci    std::optional<std::reference_wrapper<GattDescriptor>> FindDescriptor(uint16_t handle);
8395489c19Sopenharmony_ci    std::set<RequestInformation> requests_;
8495489c19Sopenharmony_ci    std::list<bluetooth::GattDevice> devices_;
8595489c19Sopenharmony_ci    std::shared_ptr<GattServerCallback> callback_;
8695489c19Sopenharmony_ci    int BuildRequestId(uint8_t type, uint8_t transport);
8795489c19Sopenharmony_ci    int RespondCharacteristicRead(
8895489c19Sopenharmony_ci        const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret);
8995489c19Sopenharmony_ci    int RespondCharacteristicWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret);
9095489c19Sopenharmony_ci    int RespondDescriptorRead(
9195489c19Sopenharmony_ci        const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret);
9295489c19Sopenharmony_ci    int RespondDescriptorWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret);
9395489c19Sopenharmony_ci    int applicationId_ = 0;
9495489c19Sopenharmony_ci    std::mutex deviceListMutex_;
9595489c19Sopenharmony_ci    GattService *GetIncludeService(uint16_t handle);
9695489c19Sopenharmony_ci    bluetooth::GattDevice *FindConnectedDevice(const BluetoothRemoteDevice &device);
9795489c19Sopenharmony_ci    GattService BuildService(const BluetoothGattService &service);
9895489c19Sopenharmony_ci    void BuildIncludeService(GattService &svc, const std::vector<bluetooth::Service> &iSvcs);
9995489c19Sopenharmony_ci    impl(std::shared_ptr<GattServerCallback> callback);
10095489c19Sopenharmony_ci    bool Init(std::weak_ptr<GattServer>);
10195489c19Sopenharmony_ci    int32_t profileRegisterId = 0;
10295489c19Sopenharmony_ci};
10395489c19Sopenharmony_ci
10495489c19Sopenharmony_ciclass GattServer::impl::BluetoothGattServerCallbackStubImpl : public BluetoothGattServerCallbackStub {
10595489c19Sopenharmony_cipublic:
10695489c19Sopenharmony_ci    inline std::shared_ptr<GattServer> GetServerSptr(void)
10795489c19Sopenharmony_ci    {
10895489c19Sopenharmony_ci        auto serverSptr = server_.lock();
10995489c19Sopenharmony_ci        if (!serverSptr) {
11095489c19Sopenharmony_ci            HILOGE("server_ is nullptr");
11195489c19Sopenharmony_ci            return nullptr;
11295489c19Sopenharmony_ci        }
11395489c19Sopenharmony_ci        if (!serverSptr->pimpl) {
11495489c19Sopenharmony_ci            HILOGE("impl is nullptr");
11595489c19Sopenharmony_ci            return nullptr;
11695489c19Sopenharmony_ci        }
11795489c19Sopenharmony_ci        return serverSptr;
11895489c19Sopenharmony_ci    }
11995489c19Sopenharmony_ci    void OnCharacteristicReadRequest(
12095489c19Sopenharmony_ci        const BluetoothGattDevice &device, const BluetoothGattCharacteristic &characteristic) override
12195489c19Sopenharmony_ci    {
12295489c19Sopenharmony_ci        HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
12395489c19Sopenharmony_ci            GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_);
12495489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
12595489c19Sopenharmony_ci        if (!serverSptr) {
12695489c19Sopenharmony_ci            return;
12795489c19Sopenharmony_ci        }
12895489c19Sopenharmony_ci
12995489c19Sopenharmony_ci        std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
13095489c19Sopenharmony_ci        auto gattcharacter = serverSptr->pimpl->FindCharacteristic(characteristic.handle_);
13195489c19Sopenharmony_ci        if (gattcharacter.has_value()) {
13295489c19Sopenharmony_ci            {
13395489c19Sopenharmony_ci                std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
13495489c19Sopenharmony_ci                auto ret = serverSptr->pimpl->requests_.emplace(
13595489c19Sopenharmony_ci                    RequestInformation(REQUEST_TYPE_CHARACTERISTICS_READ, device, &gattcharacter.value().get()));
13695489c19Sopenharmony_ci                if (!ret.second) {
13795489c19Sopenharmony_ci                    HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
13895489c19Sopenharmony_ci                        REQUEST_TYPE_CHARACTERISTICS_READ, GET_ENCRYPT_GATT_ADDR(device));
13995489c19Sopenharmony_ci                }
14095489c19Sopenharmony_ci            }
14195489c19Sopenharmony_ci
14295489c19Sopenharmony_ci            if (serverSptr->pimpl->callback_) {
14395489c19Sopenharmony_ci                serverSptr->pimpl->callback_->OnCharacteristicReadRequest(
14495489c19Sopenharmony_ci                    BluetoothRemoteDevice(device.addr_.GetAddress(),
14595489c19Sopenharmony_ci                        (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
14695489c19Sopenharmony_ci                    gattcharacter.value().get(),
14795489c19Sopenharmony_ci                    serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_CHARACTERISTICS_READ, device.transport_));
14895489c19Sopenharmony_ci            }
14995489c19Sopenharmony_ci
15095489c19Sopenharmony_ci            return;
15195489c19Sopenharmony_ci        } else {
15295489c19Sopenharmony_ci            HILOGE("Can not Find Characteristic!");
15395489c19Sopenharmony_ci        }
15495489c19Sopenharmony_ci        return;
15595489c19Sopenharmony_ci    }
15695489c19Sopenharmony_ci
15795489c19Sopenharmony_ci    void OnCharacteristicWriteRequest(const BluetoothGattDevice &device,
15895489c19Sopenharmony_ci        const BluetoothGattCharacteristic &characteristic, bool needRespones) override
15995489c19Sopenharmony_ci    {
16095489c19Sopenharmony_ci        HILOGI("remote device: %{public}s, handle: 0x%{public}04X, length: %{public}zu",
16195489c19Sopenharmony_ci            GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_, characteristic.length_);
16295489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
16395489c19Sopenharmony_ci        if (!serverSptr) {
16495489c19Sopenharmony_ci            return;
16595489c19Sopenharmony_ci        }
16695489c19Sopenharmony_ci
16795489c19Sopenharmony_ci        std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
16895489c19Sopenharmony_ci        auto gattcharacter = serverSptr->pimpl->FindCharacteristic(characteristic.handle_);
16995489c19Sopenharmony_ci        if (gattcharacter.has_value()) {
17095489c19Sopenharmony_ci            gattcharacter.value().get().SetValue(characteristic.value_.get(), characteristic.length_);
17195489c19Sopenharmony_ci            gattcharacter.value().get().SetWriteType(
17295489c19Sopenharmony_ci                needRespones ? GattCharacteristic::WriteType::DEFAULT : GattCharacteristic::WriteType::NO_RESPONSE);
17395489c19Sopenharmony_ci
17495489c19Sopenharmony_ci            if (needRespones) {
17595489c19Sopenharmony_ci                std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
17695489c19Sopenharmony_ci                auto ret = serverSptr->pimpl->requests_.emplace(
17795489c19Sopenharmony_ci                    RequestInformation(REQUEST_TYPE_CHARACTERISTICS_WRITE, device, &gattcharacter.value().get()));
17895489c19Sopenharmony_ci                if (!ret.second) {
17995489c19Sopenharmony_ci                    HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
18095489c19Sopenharmony_ci                        REQUEST_TYPE_CHARACTERISTICS_WRITE, GET_ENCRYPT_GATT_ADDR(device));
18195489c19Sopenharmony_ci                }
18295489c19Sopenharmony_ci            }
18395489c19Sopenharmony_ci
18495489c19Sopenharmony_ci            if (serverSptr->pimpl->callback_) {
18595489c19Sopenharmony_ci                serverSptr->pimpl->callback_->OnCharacteristicWriteRequest(
18695489c19Sopenharmony_ci                    BluetoothRemoteDevice(device.addr_.GetAddress(),
18795489c19Sopenharmony_ci                        (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
18895489c19Sopenharmony_ci                    gattcharacter.value().get(),
18995489c19Sopenharmony_ci                    serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_CHARACTERISTICS_WRITE, device.transport_));
19095489c19Sopenharmony_ci            }
19195489c19Sopenharmony_ci
19295489c19Sopenharmony_ci            return;
19395489c19Sopenharmony_ci        } else {
19495489c19Sopenharmony_ci            HILOGE("Can not Find Characteristic!");
19595489c19Sopenharmony_ci        }
19695489c19Sopenharmony_ci
19795489c19Sopenharmony_ci        return;
19895489c19Sopenharmony_ci    }
19995489c19Sopenharmony_ci
20095489c19Sopenharmony_ci    void OnDescriptorReadRequest(const BluetoothGattDevice &device, const BluetoothGattDescriptor &descriptor) override
20195489c19Sopenharmony_ci    {
20295489c19Sopenharmony_ci        HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
20395489c19Sopenharmony_ci            GET_ENCRYPT_GATT_ADDR(device), descriptor.handle_);
20495489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
20595489c19Sopenharmony_ci        if (!serverSptr) {
20695489c19Sopenharmony_ci            return;
20795489c19Sopenharmony_ci        }
20895489c19Sopenharmony_ci
20995489c19Sopenharmony_ci        std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
21095489c19Sopenharmony_ci        auto gattdesc = serverSptr->pimpl->FindDescriptor(descriptor.handle_);
21195489c19Sopenharmony_ci        if (gattdesc.has_value()) {
21295489c19Sopenharmony_ci            {
21395489c19Sopenharmony_ci                std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
21495489c19Sopenharmony_ci                auto ret = serverSptr->pimpl->requests_.emplace(
21595489c19Sopenharmony_ci                    RequestInformation(REQUEST_TYPE_DESCRIPTOR_READ, device, &gattdesc.value().get()));
21695489c19Sopenharmony_ci                if (!ret.second) {
21795489c19Sopenharmony_ci                    HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
21895489c19Sopenharmony_ci                        REQUEST_TYPE_DESCRIPTOR_READ, GET_ENCRYPT_GATT_ADDR(device));
21995489c19Sopenharmony_ci                }
22095489c19Sopenharmony_ci            }
22195489c19Sopenharmony_ci
22295489c19Sopenharmony_ci            if (serverSptr->pimpl->callback_) {
22395489c19Sopenharmony_ci                serverSptr->pimpl->callback_->OnDescriptorReadRequest(
22495489c19Sopenharmony_ci                    BluetoothRemoteDevice(device.addr_.GetAddress(),
22595489c19Sopenharmony_ci                        (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
22695489c19Sopenharmony_ci                    gattdesc.value().get(),
22795489c19Sopenharmony_ci                    serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_DESCRIPTOR_READ, device.transport_));
22895489c19Sopenharmony_ci            }
22995489c19Sopenharmony_ci
23095489c19Sopenharmony_ci            return;
23195489c19Sopenharmony_ci        } else {
23295489c19Sopenharmony_ci            HILOGE("Can not Find Descriptor!");
23395489c19Sopenharmony_ci        }
23495489c19Sopenharmony_ci
23595489c19Sopenharmony_ci        return;
23695489c19Sopenharmony_ci    }
23795489c19Sopenharmony_ci
23895489c19Sopenharmony_ci    void OnDescriptorWriteRequest(const BluetoothGattDevice &device, const BluetoothGattDescriptor &descriptor) override
23995489c19Sopenharmony_ci    {
24095489c19Sopenharmony_ci        HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
24195489c19Sopenharmony_ci            GET_ENCRYPT_GATT_ADDR(device), descriptor.handle_);
24295489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
24395489c19Sopenharmony_ci        if (!serverSptr) {
24495489c19Sopenharmony_ci            return;
24595489c19Sopenharmony_ci        }
24695489c19Sopenharmony_ci
24795489c19Sopenharmony_ci        std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
24895489c19Sopenharmony_ci        auto gattdesc = serverSptr->pimpl->FindDescriptor(descriptor.handle_);
24995489c19Sopenharmony_ci        if (gattdesc.has_value()) {
25095489c19Sopenharmony_ci            gattdesc.value().get().SetValue(descriptor.value_.get(), descriptor.length_);
25195489c19Sopenharmony_ci
25295489c19Sopenharmony_ci            {
25395489c19Sopenharmony_ci                std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
25495489c19Sopenharmony_ci                auto ret = serverSptr->pimpl->requests_.emplace(
25595489c19Sopenharmony_ci                    RequestInformation(REQUEST_TYPE_DESCRIPTOR_WRITE, device, &gattdesc.value().get()));
25695489c19Sopenharmony_ci                if (!ret.second) {
25795489c19Sopenharmony_ci                    HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
25895489c19Sopenharmony_ci                        REQUEST_TYPE_DESCRIPTOR_WRITE, GET_ENCRYPT_GATT_ADDR(device));
25995489c19Sopenharmony_ci                }
26095489c19Sopenharmony_ci            }
26195489c19Sopenharmony_ci
26295489c19Sopenharmony_ci            if (serverSptr->pimpl->callback_) {
26395489c19Sopenharmony_ci                serverSptr->pimpl->callback_->OnDescriptorWriteRequest(
26495489c19Sopenharmony_ci                    BluetoothRemoteDevice(device.addr_.GetAddress(),
26595489c19Sopenharmony_ci                        (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
26695489c19Sopenharmony_ci                    gattdesc.value().get(),
26795489c19Sopenharmony_ci                    serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_DESCRIPTOR_WRITE, device.transport_));
26895489c19Sopenharmony_ci            }
26995489c19Sopenharmony_ci
27095489c19Sopenharmony_ci            return;
27195489c19Sopenharmony_ci        } else {
27295489c19Sopenharmony_ci            HILOGE("Can not Find Descriptor!");
27395489c19Sopenharmony_ci        }
27495489c19Sopenharmony_ci        return;
27595489c19Sopenharmony_ci    }
27695489c19Sopenharmony_ci
27795489c19Sopenharmony_ci    void OnNotifyConfirm(
27895489c19Sopenharmony_ci        const BluetoothGattDevice &device, const BluetoothGattCharacteristic &characteristic, int result) override
27995489c19Sopenharmony_ci    {
28095489c19Sopenharmony_ci        HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
28195489c19Sopenharmony_ci            GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_);
28295489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
28395489c19Sopenharmony_ci        if (!serverSptr) {
28495489c19Sopenharmony_ci            return;
28595489c19Sopenharmony_ci        }
28695489c19Sopenharmony_ci
28795489c19Sopenharmony_ci        if (serverSptr->pimpl->callback_) {
28895489c19Sopenharmony_ci            serverSptr->pimpl->callback_->OnNotificationCharacteristicChanged(
28995489c19Sopenharmony_ci                BluetoothRemoteDevice(device.addr_.GetAddress(),
29095489c19Sopenharmony_ci                    (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
29195489c19Sopenharmony_ci                result);
29295489c19Sopenharmony_ci        }
29395489c19Sopenharmony_ci        return;
29495489c19Sopenharmony_ci    }
29595489c19Sopenharmony_ci
29695489c19Sopenharmony_ci    void OnConnectionStateChanged(const BluetoothGattDevice &device, int32_t ret, int32_t state) override
29795489c19Sopenharmony_ci    {
29895489c19Sopenharmony_ci        HILOGD("gattServer conn state, remote device: %{public}s, ret: %{public}d, state: %{public}s",
29995489c19Sopenharmony_ci            GET_ENCRYPT_GATT_ADDR(device), ret, GetProfileConnStateName(state).c_str());
30095489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
30195489c19Sopenharmony_ci        if (!serverSptr) {
30295489c19Sopenharmony_ci            return;
30395489c19Sopenharmony_ci        }
30495489c19Sopenharmony_ci
30595489c19Sopenharmony_ci        if (state == static_cast<int>(BTConnectState::CONNECTED)) {
30695489c19Sopenharmony_ci            std::lock_guard<std::mutex> lck(serverSptr->pimpl->deviceListMutex_);
30795489c19Sopenharmony_ci            serverSptr->pimpl->devices_.push_back((bluetooth::GattDevice)device);
30895489c19Sopenharmony_ci        } else if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
30995489c19Sopenharmony_ci            std::lock_guard<std::mutex> lck(serverSptr->pimpl->deviceListMutex_);
31095489c19Sopenharmony_ci            for (auto it = serverSptr->pimpl->devices_.begin(); it != serverSptr->pimpl->devices_.end(); it++) {
31195489c19Sopenharmony_ci                if (*it == (bluetooth::GattDevice)device) {
31295489c19Sopenharmony_ci                    serverSptr->pimpl->devices_.erase(it);
31395489c19Sopenharmony_ci                    break;
31495489c19Sopenharmony_ci                }
31595489c19Sopenharmony_ci            }
31695489c19Sopenharmony_ci        }
31795489c19Sopenharmony_ci
31895489c19Sopenharmony_ci        if (serverSptr->pimpl->callback_) {
31995489c19Sopenharmony_ci            serverSptr->pimpl->callback_->OnConnectionStateUpdate(
32095489c19Sopenharmony_ci                BluetoothRemoteDevice(device.addr_.GetAddress(),
32195489c19Sopenharmony_ci                    (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
32295489c19Sopenharmony_ci                state);
32395489c19Sopenharmony_ci        }
32495489c19Sopenharmony_ci
32595489c19Sopenharmony_ci        return;
32695489c19Sopenharmony_ci    }
32795489c19Sopenharmony_ci
32895489c19Sopenharmony_ci    void OnMtuChanged(const BluetoothGattDevice &device, int32_t mtu) override
32995489c19Sopenharmony_ci    {
33095489c19Sopenharmony_ci        HILOGI("remote device: %{public}s, mtu: %{public}d", GET_ENCRYPT_GATT_ADDR(device), mtu);
33195489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
33295489c19Sopenharmony_ci        if (!serverSptr) {
33395489c19Sopenharmony_ci            return;
33495489c19Sopenharmony_ci        }
33595489c19Sopenharmony_ci
33695489c19Sopenharmony_ci        if (serverSptr->pimpl->callback_) {
33795489c19Sopenharmony_ci            serverSptr->pimpl->callback_->OnMtuUpdate(
33895489c19Sopenharmony_ci                BluetoothRemoteDevice(device.addr_.GetAddress(),
33995489c19Sopenharmony_ci                    (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
34095489c19Sopenharmony_ci                mtu);
34195489c19Sopenharmony_ci        }
34295489c19Sopenharmony_ci
34395489c19Sopenharmony_ci        return;
34495489c19Sopenharmony_ci    }
34595489c19Sopenharmony_ci
34695489c19Sopenharmony_ci    void OnAddService(int32_t ret, const BluetoothGattService &service) override
34795489c19Sopenharmony_ci    {
34895489c19Sopenharmony_ci        HILOGI("enter, ret: %{public}d, handle: %{public}d", ret, service.handle_);
34995489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
35095489c19Sopenharmony_ci        if (!serverSptr) {
35195489c19Sopenharmony_ci            return;
35295489c19Sopenharmony_ci        }
35395489c19Sopenharmony_ci
35495489c19Sopenharmony_ci        GattService *ptr = nullptr;
35595489c19Sopenharmony_ci        if (ret == GattStatus::GATT_SUCCESS) {
35695489c19Sopenharmony_ci            GattService gattSvc = serverSptr->pimpl->BuildService(service);
35795489c19Sopenharmony_ci            serverSptr->pimpl->BuildIncludeService(gattSvc, service.includeServices_);
35895489c19Sopenharmony_ci            {
35995489c19Sopenharmony_ci                std::lock_guard<std::mutex> lck(serverSptr->pimpl->serviceListMutex_);
36095489c19Sopenharmony_ci                auto it = serverSptr->pimpl->gattServices_.emplace(
36195489c19Sopenharmony_ci                    serverSptr->pimpl->gattServices_.end(), std::move(gattSvc));
36295489c19Sopenharmony_ci                ptr = &(*it);
36395489c19Sopenharmony_ci            }
36495489c19Sopenharmony_ci        }
36595489c19Sopenharmony_ci        if (serverSptr->pimpl && serverSptr->pimpl->callback_) {
36695489c19Sopenharmony_ci            serverSptr->pimpl->callback_->OnServiceAdded(ptr, ret);
36795489c19Sopenharmony_ci        }
36895489c19Sopenharmony_ci        return;
36995489c19Sopenharmony_ci    }
37095489c19Sopenharmony_ci
37195489c19Sopenharmony_ci    void OnConnectionParameterChanged(
37295489c19Sopenharmony_ci        const BluetoothGattDevice &device, int32_t interval, int32_t latency, int32_t timeout, int32_t status) override
37395489c19Sopenharmony_ci    {
37495489c19Sopenharmony_ci        HILOGD("remote device: %{public}s, interval: %{public}d, "
37595489c19Sopenharmony_ci            "latency: %{public}d, timeout: %{public}d, status: %{public}d",
37695489c19Sopenharmony_ci            GET_ENCRYPT_GATT_ADDR(device), interval, latency, timeout, status);
37795489c19Sopenharmony_ci        auto serverSptr = GetServerSptr();
37895489c19Sopenharmony_ci        if (!serverSptr) {
37995489c19Sopenharmony_ci            return;
38095489c19Sopenharmony_ci        }
38195489c19Sopenharmony_ci
38295489c19Sopenharmony_ci        if (serverSptr->pimpl->callback_) {
38395489c19Sopenharmony_ci            serverSptr->pimpl->callback_->OnConnectionParameterChanged(
38495489c19Sopenharmony_ci                BluetoothRemoteDevice(device.addr_.GetAddress(),
38595489c19Sopenharmony_ci                    (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
38695489c19Sopenharmony_ci                interval,
38795489c19Sopenharmony_ci                latency,
38895489c19Sopenharmony_ci                timeout,
38995489c19Sopenharmony_ci                status);
39095489c19Sopenharmony_ci        }
39195489c19Sopenharmony_ci
39295489c19Sopenharmony_ci        return;
39395489c19Sopenharmony_ci    }
39495489c19Sopenharmony_ci
39595489c19Sopenharmony_ci    explicit BluetoothGattServerCallbackStubImpl(std::weak_ptr<GattServer> server) : server_(server)
39695489c19Sopenharmony_ci    {
39795489c19Sopenharmony_ci        HILOGD("enter");
39895489c19Sopenharmony_ci    }
39995489c19Sopenharmony_ci    ~BluetoothGattServerCallbackStubImpl() override
40095489c19Sopenharmony_ci    {
40195489c19Sopenharmony_ci        HILOGD("enter");
40295489c19Sopenharmony_ci    }
40395489c19Sopenharmony_ci
40495489c19Sopenharmony_ciprivate:
40595489c19Sopenharmony_ci    std::weak_ptr<GattServer> server_;
40695489c19Sopenharmony_ci};
40795489c19Sopenharmony_ci
40895489c19Sopenharmony_ciGattService GattServer::impl::BuildService(const BluetoothGattService &service)
40995489c19Sopenharmony_ci{
41095489c19Sopenharmony_ci    GattService gattService(UUID::ConvertFrom128Bits(service.uuid_.ConvertTo128Bits()),
41195489c19Sopenharmony_ci        service.handle_,
41295489c19Sopenharmony_ci        service.endHandle_,
41395489c19Sopenharmony_ci        service.isPrimary_ ? GattServiceType::PRIMARY : GattServiceType::SECONDARY);
41495489c19Sopenharmony_ci
41595489c19Sopenharmony_ci    for (auto &character : service.characteristics_) {
41695489c19Sopenharmony_ci        GattCharacteristic gattcharacter(UUID::ConvertFrom128Bits(character.uuid_.ConvertTo128Bits()),
41795489c19Sopenharmony_ci            character.handle_,
41895489c19Sopenharmony_ci            character.permissions_,
41995489c19Sopenharmony_ci            character.properties_);
42095489c19Sopenharmony_ci
42195489c19Sopenharmony_ci        gattcharacter.SetValue(character.value_.get(), character.length_);
42295489c19Sopenharmony_ci
42395489c19Sopenharmony_ci        for (auto &desc : character.descriptors_) {
42495489c19Sopenharmony_ci            GattDescriptor gattDesc(
42595489c19Sopenharmony_ci                UUID::ConvertFrom128Bits(desc.uuid_.ConvertTo128Bits()), desc.handle_, desc.permissions_);
42695489c19Sopenharmony_ci
42795489c19Sopenharmony_ci            gattDesc.SetValue(desc.value_.get(), desc.length_);
42895489c19Sopenharmony_ci            gattcharacter.AddDescriptor(std::move(gattDesc));
42995489c19Sopenharmony_ci        }
43095489c19Sopenharmony_ci
43195489c19Sopenharmony_ci        gattService.AddCharacteristic(std::move(gattcharacter));
43295489c19Sopenharmony_ci    }
43395489c19Sopenharmony_ci
43495489c19Sopenharmony_ci    return gattService;
43595489c19Sopenharmony_ci}
43695489c19Sopenharmony_ci
43795489c19Sopenharmony_civoid GattServer::impl::BuildIncludeService(GattService &svc, const std::vector<bluetooth::Service> &iSvcs)
43895489c19Sopenharmony_ci{
43995489c19Sopenharmony_ci    for (auto &iSvc : iSvcs) {
44095489c19Sopenharmony_ci        GattService *pSvc = GetIncludeService(iSvc.startHandle_);
44195489c19Sopenharmony_ci        if (!pSvc) {
44295489c19Sopenharmony_ci            HILOGE("Can not find include service entity in service ");
44395489c19Sopenharmony_ci            continue;
44495489c19Sopenharmony_ci        }
44595489c19Sopenharmony_ci        svc.AddService(std::ref(*pSvc));
44695489c19Sopenharmony_ci    }
44795489c19Sopenharmony_ci}
44895489c19Sopenharmony_ci
44995489c19Sopenharmony_ciGattService *GattServer::impl::GetIncludeService(uint16_t handle)
45095489c19Sopenharmony_ci{
45195489c19Sopenharmony_ci    for (auto &svc : gattServices_) {
45295489c19Sopenharmony_ci        if (svc.GetHandle() == handle) {
45395489c19Sopenharmony_ci            return &svc;
45495489c19Sopenharmony_ci        }
45595489c19Sopenharmony_ci    }
45695489c19Sopenharmony_ci
45795489c19Sopenharmony_ci    return nullptr;
45895489c19Sopenharmony_ci}
45995489c19Sopenharmony_ci
46095489c19Sopenharmony_ciGattServer::impl::impl(std::shared_ptr<GattServerCallback> callback)
46195489c19Sopenharmony_ci    : isRegisterSucceeded_(false), callback_(callback), applicationId_(0)
46295489c19Sopenharmony_ci{
46395489c19Sopenharmony_ci    HILOGD("enter");
46495489c19Sopenharmony_ci};
46595489c19Sopenharmony_ci
46695489c19Sopenharmony_ciGattServer::GattServer(std::shared_ptr<GattServerCallback> callback)
46795489c19Sopenharmony_ci{
46895489c19Sopenharmony_ci    HILOGI("create GattServer start.");
46995489c19Sopenharmony_ci    pimpl = std::make_unique<GattServer::impl>(callback);
47095489c19Sopenharmony_ci    if (!pimpl) {
47195489c19Sopenharmony_ci        HILOGE("create GattServer failed.");
47295489c19Sopenharmony_ci    }
47395489c19Sopenharmony_ci}
47495489c19Sopenharmony_ci
47595489c19Sopenharmony_cibool GattServer::impl::Init(std::weak_ptr<GattServer> server)
47695489c19Sopenharmony_ci{
47795489c19Sopenharmony_ci    if (profileRegisterId != 0) { //ProxyManager has register callback
47895489c19Sopenharmony_ci        return true;
47995489c19Sopenharmony_ci    }
48095489c19Sopenharmony_ci    serviceCallback_ = new BluetoothGattServerCallbackStubImpl(server);
48195489c19Sopenharmony_ci    profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_GATT_SERVER,
48295489c19Sopenharmony_ci        [this](sptr<IRemoteObject> remote) {
48395489c19Sopenharmony_ci        sptr<IBluetoothGattServer> proxy = iface_cast<IBluetoothGattServer>(remote);
48495489c19Sopenharmony_ci        CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
48595489c19Sopenharmony_ci        int result = proxy->RegisterApplication(serviceCallback_);
48695489c19Sopenharmony_ci        if (result > 0) {
48795489c19Sopenharmony_ci            applicationId_ = result;
48895489c19Sopenharmony_ci            isRegisterSucceeded_ = true;
48995489c19Sopenharmony_ci        } else {
49095489c19Sopenharmony_ci            HILOGE("Can not Register to gatt server service! result = %{public}d", result);
49195489c19Sopenharmony_ci        }
49295489c19Sopenharmony_ci    });
49395489c19Sopenharmony_ci    return true;
49495489c19Sopenharmony_ci}
49595489c19Sopenharmony_ci
49695489c19Sopenharmony_cistd::shared_ptr<GattServer> GattServer::CreateInstance(std::shared_ptr<GattServerCallback> callback)
49795489c19Sopenharmony_ci{
49895489c19Sopenharmony_ci    // The passkey pattern used here.
49995489c19Sopenharmony_ci    auto instance = std::make_shared<GattServer>(PassKey(), callback);
50095489c19Sopenharmony_ci    if (!instance->pimpl) {
50195489c19Sopenharmony_ci        HILOGE("failed: no impl");
50295489c19Sopenharmony_ci        return nullptr;
50395489c19Sopenharmony_ci    }
50495489c19Sopenharmony_ci
50595489c19Sopenharmony_ci    instance->pimpl->Init(instance);
50695489c19Sopenharmony_ci    return instance;
50795489c19Sopenharmony_ci}
50895489c19Sopenharmony_ci
50995489c19Sopenharmony_cistd::optional<std::reference_wrapper<GattCharacteristic>> GattServer::impl::FindCharacteristic(uint16_t handle)
51095489c19Sopenharmony_ci{
51195489c19Sopenharmony_ci    for (auto &svc : gattServices_) {
51295489c19Sopenharmony_ci        for (auto &character : svc.GetCharacteristics()) {
51395489c19Sopenharmony_ci            if (character.GetHandle() == handle) {
51495489c19Sopenharmony_ci                return character;
51595489c19Sopenharmony_ci            }
51695489c19Sopenharmony_ci        }
51795489c19Sopenharmony_ci    }
51895489c19Sopenharmony_ci    return std::nullopt;
51995489c19Sopenharmony_ci}
52095489c19Sopenharmony_cibluetooth::GattDevice *GattServer::impl::FindConnectedDevice(const BluetoothRemoteDevice &device)
52195489c19Sopenharmony_ci{
52295489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(deviceListMutex_);
52395489c19Sopenharmony_ci    for (auto &gattDevice : devices_) {
52495489c19Sopenharmony_ci        if (device.GetDeviceAddr().compare(gattDevice.addr_.GetAddress()) == 0 &&
52595489c19Sopenharmony_ci            (device.GetTransportType() ==
52695489c19Sopenharmony_ci            (gattDevice.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR)) {
52795489c19Sopenharmony_ci            return &gattDevice;
52895489c19Sopenharmony_ci        }
52995489c19Sopenharmony_ci    }
53095489c19Sopenharmony_ci    return nullptr;
53195489c19Sopenharmony_ci}
53295489c19Sopenharmony_cistd::optional<std::reference_wrapper<GattDescriptor>> GattServer::impl::FindDescriptor(uint16_t handle)
53395489c19Sopenharmony_ci{
53495489c19Sopenharmony_ci    for (auto &svc : gattServices_) {
53595489c19Sopenharmony_ci        for (auto &character : svc.GetCharacteristics()) {
53695489c19Sopenharmony_ci            for (auto &desc : character.GetDescriptors()) {
53795489c19Sopenharmony_ci                if (desc.GetHandle() == handle) {
53895489c19Sopenharmony_ci                    return desc;
53995489c19Sopenharmony_ci                }
54095489c19Sopenharmony_ci            }
54195489c19Sopenharmony_ci        }
54295489c19Sopenharmony_ci    }
54395489c19Sopenharmony_ci    return std::nullopt;
54495489c19Sopenharmony_ci}
54595489c19Sopenharmony_ci
54695489c19Sopenharmony_ciint GattServer::impl::BuildRequestId(uint8_t type, uint8_t transport)
54795489c19Sopenharmony_ci{
54895489c19Sopenharmony_ci    int requestId = 0;
54995489c19Sopenharmony_ci
55095489c19Sopenharmony_ci    requestId = type << EIGHT_BITS;
55195489c19Sopenharmony_ci    requestId |= transport;
55295489c19Sopenharmony_ci
55395489c19Sopenharmony_ci    return requestId;
55495489c19Sopenharmony_ci}
55595489c19Sopenharmony_ci
55695489c19Sopenharmony_ciint GattServer::impl::RespondCharacteristicRead(
55795489c19Sopenharmony_ci    const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)
55895489c19Sopenharmony_ci{
55995489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
56095489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
56195489c19Sopenharmony_ci
56295489c19Sopenharmony_ci    if (ret == GattStatus::GATT_SUCCESS) {
56395489c19Sopenharmony_ci        BluetoothGattCharacteristic character(bluetooth::Characteristic(handle, value, length));
56495489c19Sopenharmony_ci
56595489c19Sopenharmony_ci        return proxy->RespondCharacteristicRead(device, &character, ret);
56695489c19Sopenharmony_ci    }
56795489c19Sopenharmony_ci    BluetoothGattCharacteristic character;
56895489c19Sopenharmony_ci    character.handle_ = handle;
56995489c19Sopenharmony_ci    return proxy->RespondCharacteristicRead(device, &character, ret);
57095489c19Sopenharmony_ci}
57195489c19Sopenharmony_ci
57295489c19Sopenharmony_ciint GattServer::impl::RespondCharacteristicWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)
57395489c19Sopenharmony_ci{
57495489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
57595489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
57695489c19Sopenharmony_ci    return proxy->RespondCharacteristicWrite(
57795489c19Sopenharmony_ci        device, (BluetoothGattCharacteristic)bluetooth::Characteristic(handle), ret);
57895489c19Sopenharmony_ci}
57995489c19Sopenharmony_ci
58095489c19Sopenharmony_ciint GattServer::impl::RespondDescriptorRead(
58195489c19Sopenharmony_ci    const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)
58295489c19Sopenharmony_ci{
58395489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
58495489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
58595489c19Sopenharmony_ci    if (ret == GattStatus::GATT_SUCCESS) {
58695489c19Sopenharmony_ci        BluetoothGattDescriptor desc(bluetooth::Descriptor(handle, value, length));
58795489c19Sopenharmony_ci        return proxy->RespondDescriptorRead(device, &desc, ret);
58895489c19Sopenharmony_ci    }
58995489c19Sopenharmony_ci    BluetoothGattDescriptor desc;
59095489c19Sopenharmony_ci    desc.handle_ = handle;
59195489c19Sopenharmony_ci    return proxy->RespondDescriptorRead(device, &desc, ret);
59295489c19Sopenharmony_ci}
59395489c19Sopenharmony_ci
59495489c19Sopenharmony_ciint GattServer::impl::RespondDescriptorWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)
59595489c19Sopenharmony_ci{
59695489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
59795489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
59895489c19Sopenharmony_ci    return proxy->RespondDescriptorWrite(device, (BluetoothGattDescriptor)bluetooth::Descriptor(handle), ret);
59995489c19Sopenharmony_ci}
60095489c19Sopenharmony_ci
60195489c19Sopenharmony_ciint GattServer::AddService(GattService &service)
60295489c19Sopenharmony_ci{
60395489c19Sopenharmony_ci    HILOGD("enter");
60495489c19Sopenharmony_ci    if (!IS_BLE_ENABLED()) {
60595489c19Sopenharmony_ci        HILOGE("bluetooth is off.");
60695489c19Sopenharmony_ci        return BT_ERR_INVALID_STATE;
60795489c19Sopenharmony_ci    }
60895489c19Sopenharmony_ci
60995489c19Sopenharmony_ci    BluetoothGattService svc;
61095489c19Sopenharmony_ci    svc.isPrimary_ = service.IsPrimary();
61195489c19Sopenharmony_ci    svc.uuid_ = bluetooth::Uuid::ConvertFrom128Bits(service.GetUuid().ConvertTo128Bits());
61295489c19Sopenharmony_ci
61395489c19Sopenharmony_ci    for (auto &isvc : service.GetIncludedServices()) {
61495489c19Sopenharmony_ci        svc.includeServices_.push_back(bluetooth::Service(isvc.get().GetHandle()));
61595489c19Sopenharmony_ci    }
61695489c19Sopenharmony_ci
61795489c19Sopenharmony_ci    for (auto &character : service.GetCharacteristics()) {
61895489c19Sopenharmony_ci        size_t length = 0;
61995489c19Sopenharmony_ci        uint8_t *value = character.GetValue(&length).get();
62095489c19Sopenharmony_ci        bluetooth::Characteristic c(bluetooth::Uuid::ConvertFrom128Bits(character.GetUuid().ConvertTo128Bits()),
62195489c19Sopenharmony_ci            character.GetHandle(),
62295489c19Sopenharmony_ci            character.GetProperties(),
62395489c19Sopenharmony_ci            character.GetPermissions(),
62495489c19Sopenharmony_ci            value,
62595489c19Sopenharmony_ci            length);
62695489c19Sopenharmony_ci
62795489c19Sopenharmony_ci        for (auto &desc : character.GetDescriptors()) {
62895489c19Sopenharmony_ci            value = desc.GetValue(&length).get();
62995489c19Sopenharmony_ci            bluetooth::Descriptor d(bluetooth::Uuid::ConvertFrom128Bits(desc.GetUuid().ConvertTo128Bits()),
63095489c19Sopenharmony_ci                desc.GetHandle(),
63195489c19Sopenharmony_ci                desc.GetPermissions(),
63295489c19Sopenharmony_ci                value,
63395489c19Sopenharmony_ci                length);
63495489c19Sopenharmony_ci
63595489c19Sopenharmony_ci            c.descriptors_.push_back(std::move(d));
63695489c19Sopenharmony_ci        }
63795489c19Sopenharmony_ci
63895489c19Sopenharmony_ci        svc.characteristics_.push_back(std::move(c));
63995489c19Sopenharmony_ci    }
64095489c19Sopenharmony_ci    int appId = pimpl->applicationId_;
64195489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
64295489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
64395489c19Sopenharmony_ci    int ret = proxy->AddService(appId, &svc);
64495489c19Sopenharmony_ci    HILOGI("appId = %{public}d, ret = %{public}d.", appId, ret);
64595489c19Sopenharmony_ci    return ret;
64695489c19Sopenharmony_ci}
64795489c19Sopenharmony_ci
64895489c19Sopenharmony_civoid GattServer::ClearServices()
64995489c19Sopenharmony_ci{
65095489c19Sopenharmony_ci    HILOGD("enter");
65195489c19Sopenharmony_ci    if (!IS_BLE_ENABLED()) {
65295489c19Sopenharmony_ci        HILOGE("bluetooth is off.");
65395489c19Sopenharmony_ci        return;
65495489c19Sopenharmony_ci    }
65595489c19Sopenharmony_ci
65695489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
65795489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
65895489c19Sopenharmony_ci
65995489c19Sopenharmony_ci    int appId = pimpl->applicationId_;
66095489c19Sopenharmony_ci    proxy->ClearServices(int(appId));
66195489c19Sopenharmony_ci    pimpl->gattServices_.clear();
66295489c19Sopenharmony_ci}
66395489c19Sopenharmony_ci
66495489c19Sopenharmony_ciint GattServer::Close()
66595489c19Sopenharmony_ci{
66695489c19Sopenharmony_ci    HILOGD("enter");
66795489c19Sopenharmony_ci    if (!IS_BLE_ENABLED()) {
66895489c19Sopenharmony_ci        HILOGE("bluetooth is off.");
66995489c19Sopenharmony_ci        return BT_ERR_INVALID_STATE;
67095489c19Sopenharmony_ci    }
67195489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
67295489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
67395489c19Sopenharmony_ci
67495489c19Sopenharmony_ci    int ret = proxy->DeregisterApplication(pimpl->applicationId_);
67595489c19Sopenharmony_ci    HILOGI("ret: %{public}d", ret);
67695489c19Sopenharmony_ci    if (ret == BT_NO_ERROR) {
67795489c19Sopenharmony_ci        pimpl->isRegisterSucceeded_ = false;
67895489c19Sopenharmony_ci    }
67995489c19Sopenharmony_ci    return ret;
68095489c19Sopenharmony_ci}
68195489c19Sopenharmony_ci
68295489c19Sopenharmony_ciint GattServer::Connect(const BluetoothRemoteDevice &device, bool isDirect)
68395489c19Sopenharmony_ci{
68495489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
68595489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
68695489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
68795489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INTERNAL_ERROR, "Invalid remote device");
68895489c19Sopenharmony_ci
68995489c19Sopenharmony_ci    int appId = pimpl->applicationId_;
69095489c19Sopenharmony_ci    HILOGI("appId: %{public}d, device: %{public}s, isDirect: %{public}d", appId, GET_ENCRYPT_ADDR(device), isDirect);
69195489c19Sopenharmony_ci
69295489c19Sopenharmony_ci    bluetooth::GattDevice gattDevice(bluetooth::RawAddress(device.GetDeviceAddr()), GATT_TRANSPORT_TYPE_LE);
69395489c19Sopenharmony_ci    return proxy->Connect(appId, gattDevice, isDirect);
69495489c19Sopenharmony_ci}
69595489c19Sopenharmony_ci
69695489c19Sopenharmony_ciint GattServer::CancelConnection(const BluetoothRemoteDevice &device)
69795489c19Sopenharmony_ci{
69895489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
69995489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
70095489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
70195489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INTERNAL_ERROR, "Invalid remote device");
70295489c19Sopenharmony_ci
70395489c19Sopenharmony_ci    auto gattDevice = pimpl->FindConnectedDevice(device);
70495489c19Sopenharmony_ci    if (gattDevice == nullptr) {
70595489c19Sopenharmony_ci        HILOGE("gattDevice is nullptr");
70695489c19Sopenharmony_ci        return BT_ERR_INTERNAL_ERROR;
70795489c19Sopenharmony_ci    }
70895489c19Sopenharmony_ci
70995489c19Sopenharmony_ci    int appId = pimpl->applicationId_;
71095489c19Sopenharmony_ci    HILOGI("appId: %{public}d, device: %{public}s", appId, GET_ENCRYPT_ADDR(device));
71195489c19Sopenharmony_ci    return proxy->CancelConnection(appId, *gattDevice);
71295489c19Sopenharmony_ci}
71395489c19Sopenharmony_cistd::optional<std::reference_wrapper<GattService>> GattServer::GetService(const UUID &uuid, bool isPrimary)
71495489c19Sopenharmony_ci{
71595489c19Sopenharmony_ci    HILOGD("enter");
71695489c19Sopenharmony_ci    if (!IS_BLE_ENABLED()) {
71795489c19Sopenharmony_ci        HILOGE("bluetooth is off.");
71895489c19Sopenharmony_ci        return std::nullopt;
71995489c19Sopenharmony_ci    }
72095489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
72195489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::nullopt, "failed: no proxy");
72295489c19Sopenharmony_ci
72395489c19Sopenharmony_ci    std::unique_lock<std::mutex> lock(pimpl->serviceListMutex_);
72495489c19Sopenharmony_ci
72595489c19Sopenharmony_ci    for (auto &svc : pimpl->gattServices_) {
72695489c19Sopenharmony_ci        if (svc.GetUuid().Equals(uuid) && svc.IsPrimary() == isPrimary) {
72795489c19Sopenharmony_ci            HILOGI("Find service, handle: 0x%{public}04X", svc.GetHandle());
72895489c19Sopenharmony_ci            return svc;
72995489c19Sopenharmony_ci        }
73095489c19Sopenharmony_ci    }
73195489c19Sopenharmony_ci
73295489c19Sopenharmony_ci    return std::nullopt;
73395489c19Sopenharmony_ci}
73495489c19Sopenharmony_ci
73595489c19Sopenharmony_cistd::list<GattService> &GattServer::GetServices()
73695489c19Sopenharmony_ci{
73795489c19Sopenharmony_ci    HILOGD("enter");
73895489c19Sopenharmony_ci    if (!IS_BLE_ENABLED()) {
73995489c19Sopenharmony_ci        HILOGE("bluetooth is off.");
74095489c19Sopenharmony_ci        return pimpl->gattServices_;
74195489c19Sopenharmony_ci    }
74295489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
74395489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, pimpl->gattServices_, "failed: no proxy");
74495489c19Sopenharmony_ci
74595489c19Sopenharmony_ci    std::unique_lock<std::mutex> lock(pimpl->serviceListMutex_);
74695489c19Sopenharmony_ci    return pimpl->gattServices_;
74795489c19Sopenharmony_ci}
74895489c19Sopenharmony_ciint GattServer::NotifyCharacteristicChanged(
74995489c19Sopenharmony_ci    const BluetoothRemoteDevice &device, const GattCharacteristic &characteristic, bool confirm)
75095489c19Sopenharmony_ci{
75195489c19Sopenharmony_ci    HILOGI("remote device: %{public}s, handle: 0x%{public}04X, confirm: %{public}d",
75295489c19Sopenharmony_ci        GET_ENCRYPT_ADDR(device), characteristic.GetHandle(), confirm);
75395489c19Sopenharmony_ci    if (!IS_BLE_ENABLED()) {
75495489c19Sopenharmony_ci        HILOGE("bluetooth is off.");
75595489c19Sopenharmony_ci        return BT_ERR_INVALID_STATE;
75695489c19Sopenharmony_ci    }
75795489c19Sopenharmony_ci
75895489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
75995489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
76095489c19Sopenharmony_ci
76195489c19Sopenharmony_ci    if (!device.IsValidBluetoothRemoteDevice()) {
76295489c19Sopenharmony_ci        HILOGE("Invalid remote device");
76395489c19Sopenharmony_ci        return BT_ERR_INTERNAL_ERROR;
76495489c19Sopenharmony_ci    }
76595489c19Sopenharmony_ci    if (pimpl->FindConnectedDevice(device) == nullptr) {
76695489c19Sopenharmony_ci        HILOGE("No connection to device: %{public}s", GET_ENCRYPT_ADDR(device));
76795489c19Sopenharmony_ci        return BT_ERR_INTERNAL_ERROR;
76895489c19Sopenharmony_ci    }
76995489c19Sopenharmony_ci
77095489c19Sopenharmony_ci    size_t length = 0;
77195489c19Sopenharmony_ci    auto &characterValue = characteristic.GetValue(&length);
77295489c19Sopenharmony_ci
77395489c19Sopenharmony_ci    BluetoothGattCharacteristic character(
77495489c19Sopenharmony_ci        bluetooth::Characteristic(characteristic.GetHandle(), characterValue.get(), length));
77595489c19Sopenharmony_ci    std::string address = device.GetDeviceAddr();
77695489c19Sopenharmony_ci    int ret = proxy->NotifyClient(
77795489c19Sopenharmony_ci        bluetooth::GattDevice(bluetooth::RawAddress(address), 0), &character, confirm);
77895489c19Sopenharmony_ci    HILOGI("ret = %{public}d.", ret);
77995489c19Sopenharmony_ci    return ret;
78095489c19Sopenharmony_ci}
78195489c19Sopenharmony_ci
78295489c19Sopenharmony_ciint GattServer::RemoveGattService(const GattService &service)
78395489c19Sopenharmony_ci{
78495489c19Sopenharmony_ci    HILOGD("enter");
78595489c19Sopenharmony_ci    if (!IS_BLE_ENABLED()) {
78695489c19Sopenharmony_ci        HILOGD("bluetooth is off.");
78795489c19Sopenharmony_ci        return BT_ERR_INVALID_STATE;
78895489c19Sopenharmony_ci    }
78995489c19Sopenharmony_ci
79095489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
79195489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
79295489c19Sopenharmony_ci
79395489c19Sopenharmony_ci    int ret = BT_ERR_INVALID_PARAM;
79495489c19Sopenharmony_ci    for (auto sIt = pimpl->gattServices_.begin(); sIt != pimpl->gattServices_.end(); sIt++) {
79595489c19Sopenharmony_ci        if (sIt->GetUuid().Equals(service.GetUuid())) {
79695489c19Sopenharmony_ci            ret = proxy->RemoveService(
79795489c19Sopenharmony_ci                pimpl->applicationId_, (BluetoothGattService)bluetooth::Service(sIt->GetHandle()));
79895489c19Sopenharmony_ci            pimpl->gattServices_.erase(sIt);
79995489c19Sopenharmony_ci            break;
80095489c19Sopenharmony_ci        }
80195489c19Sopenharmony_ci    }
80295489c19Sopenharmony_ci    HILOGI("result = %{public}d.", ret);
80395489c19Sopenharmony_ci    return ret;
80495489c19Sopenharmony_ci}
80595489c19Sopenharmony_ciint GattServer::SendResponse(
80695489c19Sopenharmony_ci    const BluetoothRemoteDevice &device, int requestId, int status, int offset, const uint8_t *value, int length)
80795489c19Sopenharmony_ci{
80895489c19Sopenharmony_ci    HILOGI("remote device: %{public}s, status: %{public}d", GET_ENCRYPT_ADDR(device), status);
80995489c19Sopenharmony_ci    if (!IS_BLE_ENABLED()) {
81095489c19Sopenharmony_ci        HILOGE("bluetooth is off.");
81195489c19Sopenharmony_ci        return BT_ERR_INVALID_STATE;
81295489c19Sopenharmony_ci    }
81395489c19Sopenharmony_ci
81495489c19Sopenharmony_ci    if (!device.IsValidBluetoothRemoteDevice()) {
81595489c19Sopenharmony_ci        HILOGE("pimpl or gatt server proxy is nullptr");
81695489c19Sopenharmony_ci        return BT_ERR_INTERNAL_ERROR;
81795489c19Sopenharmony_ci    }
81895489c19Sopenharmony_ci
81995489c19Sopenharmony_ci    if (pimpl->FindConnectedDevice(device) == nullptr) {
82095489c19Sopenharmony_ci        HILOGE("No connection to device: %{public}s", GET_ENCRYPT_ADDR(device));
82195489c19Sopenharmony_ci        return BT_ERR_INTERNAL_ERROR;
82295489c19Sopenharmony_ci    }
82395489c19Sopenharmony_ci
82495489c19Sopenharmony_ci    int result = BT_ERR_INTERNAL_ERROR;
82595489c19Sopenharmony_ci    uint8_t requestType = requestId >> EIGHT_BITS;
82695489c19Sopenharmony_ci    uint8_t transport = requestId & 0xFF;
82795489c19Sopenharmony_ci    if (transport != GATT_TRANSPORT_TYPE_CLASSIC && transport != GATT_TRANSPORT_TYPE_LE) {
82895489c19Sopenharmony_ci        return result;
82995489c19Sopenharmony_ci    }
83095489c19Sopenharmony_ci    bluetooth::GattDevice gattdevice(bluetooth::RawAddress(device.GetDeviceAddr()), transport);
83195489c19Sopenharmony_ci
83295489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(pimpl->requestListMutex_);
83395489c19Sopenharmony_ci    auto request = pimpl->requests_.find(RequestInformation(requestType, gattdevice));
83495489c19Sopenharmony_ci    if (request != pimpl->requests_.end()) {
83595489c19Sopenharmony_ci        switch (requestType) {
83695489c19Sopenharmony_ci            case REQUEST_TYPE_CHARACTERISTICS_READ:
83795489c19Sopenharmony_ci                result = pimpl->RespondCharacteristicRead(
83895489c19Sopenharmony_ci                    gattdevice, request->context_.characteristic_->GetHandle(), value, length, status);
83995489c19Sopenharmony_ci                break;
84095489c19Sopenharmony_ci            case REQUEST_TYPE_CHARACTERISTICS_WRITE:
84195489c19Sopenharmony_ci                result = pimpl->RespondCharacteristicWrite(
84295489c19Sopenharmony_ci                    gattdevice, request->context_.characteristic_->GetHandle(), status);
84395489c19Sopenharmony_ci                break;
84495489c19Sopenharmony_ci            case REQUEST_TYPE_DESCRIPTOR_READ:
84595489c19Sopenharmony_ci                result = pimpl->RespondDescriptorRead(
84695489c19Sopenharmony_ci                    gattdevice, request->context_.descriptor_->GetHandle(), value, length, status);
84795489c19Sopenharmony_ci                break;
84895489c19Sopenharmony_ci            case REQUEST_TYPE_DESCRIPTOR_WRITE:
84995489c19Sopenharmony_ci                result = pimpl->RespondDescriptorWrite(gattdevice, request->context_.descriptor_->GetHandle(), status);
85095489c19Sopenharmony_ci                break;
85195489c19Sopenharmony_ci            default:
85295489c19Sopenharmony_ci                HILOGE("Error request Id!");
85395489c19Sopenharmony_ci                break;
85495489c19Sopenharmony_ci        }
85595489c19Sopenharmony_ci        if (result == BT_NO_ERROR) {
85695489c19Sopenharmony_ci            pimpl->requests_.erase(request);
85795489c19Sopenharmony_ci        }
85895489c19Sopenharmony_ci    }
85995489c19Sopenharmony_ci    HILOGD("result = %{public}d.", result);
86095489c19Sopenharmony_ci    return result;
86195489c19Sopenharmony_ci}
86295489c19Sopenharmony_ci
86395489c19Sopenharmony_ciGattServer::~GattServer()
86495489c19Sopenharmony_ci{
86595489c19Sopenharmony_ci    HILOGD("enter");
86695489c19Sopenharmony_ci    BluetoothProfileManager::GetInstance().DeregisterFunc(pimpl->profileRegisterId);
86795489c19Sopenharmony_ci    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
86895489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
86995489c19Sopenharmony_ci    if (pimpl->isRegisterSucceeded_) {
87095489c19Sopenharmony_ci        proxy->DeregisterApplication(pimpl->applicationId_);
87195489c19Sopenharmony_ci    }
87295489c19Sopenharmony_ci    HILOGI("end");
87395489c19Sopenharmony_ci}
87495489c19Sopenharmony_ci}  // namespace Bluetooth
87595489c19Sopenharmony_ci}  // namespace OHOS
876