1/*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <condition_variable>
17#include <memory>
18#include <set>
19#include "bluetooth_gatt_server.h"
20#include "bluetooth_host.h"
21#include "bluetooth_log.h"
22#include "bluetooth_utils.h"
23#include "bluetooth_host_proxy.h"
24#include "bluetooth_gatt_server_proxy.h"
25#include "bluetooth_gatt_server_callback_stub.h"
26#include "gatt_data.h"
27#include "iservice_registry.h"
28#include "raw_address.h"
29#include "system_ability_definition.h"
30#include "bluetooth_profile_manager.h"
31
32namespace OHOS {
33namespace Bluetooth {
34const int EIGHT_BITS = 8;
35constexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_READ = 0x00;
36constexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_WRITE = 0x01;
37constexpr uint8_t REQUEST_TYPE_DESCRIPTOR_READ = 0x02;
38constexpr uint8_t REQUEST_TYPE_DESCRIPTOR_WRITE = 0x03;
39
40struct RequestInformation {
41    uint8_t type_;
42    bluetooth::GattDevice device_;
43    union {
44        GattCharacteristic *characteristic_;
45        GattDescriptor *descriptor_;
46    } context_;
47
48    RequestInformation(uint8_t type, const bluetooth::GattDevice &device, GattCharacteristic *characteristic)
49        : type_(type), device_(device), context_ {
50            .characteristic_ = characteristic
51        }
52    {}
53
54    RequestInformation(uint8_t type, const bluetooth::GattDevice &device, GattDescriptor *decriptor)
55        : type_(type), device_(device), context_ {
56            .descriptor_ = decriptor
57        }
58    {}
59
60    RequestInformation(uint8_t type, const bluetooth::GattDevice &device) : type_(type), device_(device)
61    {}
62
63    bool operator==(const RequestInformation &rhs) const
64    {
65        return (device_ == rhs.device_ && type_ == rhs.type_);
66    };
67
68    bool operator<(const RequestInformation &rhs) const
69    {
70        return (device_ < rhs.device_ && type_ == rhs.type_);
71    };
72};
73
74struct GattServer::impl {
75    class BluetoothGattServerCallbackStubImpl;
76    bool isRegisterSucceeded_ = false;
77    std::mutex serviceListMutex_;
78    std::mutex requestListMutex_;
79    std::list<GattService> gattServices_;
80    sptr<BluetoothGattServerCallbackStubImpl> serviceCallback_;
81    std::optional<std::reference_wrapper<GattCharacteristic>> FindCharacteristic(uint16_t handle);
82    std::optional<std::reference_wrapper<GattDescriptor>> FindDescriptor(uint16_t handle);
83    std::set<RequestInformation> requests_;
84    std::list<bluetooth::GattDevice> devices_;
85    std::shared_ptr<GattServerCallback> callback_;
86    int BuildRequestId(uint8_t type, uint8_t transport);
87    int RespondCharacteristicRead(
88        const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret);
89    int RespondCharacteristicWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret);
90    int RespondDescriptorRead(
91        const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret);
92    int RespondDescriptorWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret);
93    int applicationId_ = 0;
94    std::mutex deviceListMutex_;
95    GattService *GetIncludeService(uint16_t handle);
96    bluetooth::GattDevice *FindConnectedDevice(const BluetoothRemoteDevice &device);
97    GattService BuildService(const BluetoothGattService &service);
98    void BuildIncludeService(GattService &svc, const std::vector<bluetooth::Service> &iSvcs);
99    impl(std::shared_ptr<GattServerCallback> callback);
100    bool Init(std::weak_ptr<GattServer>);
101    int32_t profileRegisterId = 0;
102};
103
104class GattServer::impl::BluetoothGattServerCallbackStubImpl : public BluetoothGattServerCallbackStub {
105public:
106    inline std::shared_ptr<GattServer> GetServerSptr(void)
107    {
108        auto serverSptr = server_.lock();
109        if (!serverSptr) {
110            HILOGE("server_ is nullptr");
111            return nullptr;
112        }
113        if (!serverSptr->pimpl) {
114            HILOGE("impl is nullptr");
115            return nullptr;
116        }
117        return serverSptr;
118    }
119    void OnCharacteristicReadRequest(
120        const BluetoothGattDevice &device, const BluetoothGattCharacteristic &characteristic) override
121    {
122        HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
123            GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_);
124        auto serverSptr = GetServerSptr();
125        if (!serverSptr) {
126            return;
127        }
128
129        std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
130        auto gattcharacter = serverSptr->pimpl->FindCharacteristic(characteristic.handle_);
131        if (gattcharacter.has_value()) {
132            {
133                std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
134                auto ret = serverSptr->pimpl->requests_.emplace(
135                    RequestInformation(REQUEST_TYPE_CHARACTERISTICS_READ, device, &gattcharacter.value().get()));
136                if (!ret.second) {
137                    HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
138                        REQUEST_TYPE_CHARACTERISTICS_READ, GET_ENCRYPT_GATT_ADDR(device));
139                }
140            }
141
142            if (serverSptr->pimpl->callback_) {
143                serverSptr->pimpl->callback_->OnCharacteristicReadRequest(
144                    BluetoothRemoteDevice(device.addr_.GetAddress(),
145                        (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
146                    gattcharacter.value().get(),
147                    serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_CHARACTERISTICS_READ, device.transport_));
148            }
149
150            return;
151        } else {
152            HILOGE("Can not Find Characteristic!");
153        }
154        return;
155    }
156
157    void OnCharacteristicWriteRequest(const BluetoothGattDevice &device,
158        const BluetoothGattCharacteristic &characteristic, bool needRespones) override
159    {
160        HILOGI("remote device: %{public}s, handle: 0x%{public}04X, length: %{public}zu",
161            GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_, characteristic.length_);
162        auto serverSptr = GetServerSptr();
163        if (!serverSptr) {
164            return;
165        }
166
167        std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
168        auto gattcharacter = serverSptr->pimpl->FindCharacteristic(characteristic.handle_);
169        if (gattcharacter.has_value()) {
170            gattcharacter.value().get().SetValue(characteristic.value_.get(), characteristic.length_);
171            gattcharacter.value().get().SetWriteType(
172                needRespones ? GattCharacteristic::WriteType::DEFAULT : GattCharacteristic::WriteType::NO_RESPONSE);
173
174            if (needRespones) {
175                std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
176                auto ret = serverSptr->pimpl->requests_.emplace(
177                    RequestInformation(REQUEST_TYPE_CHARACTERISTICS_WRITE, device, &gattcharacter.value().get()));
178                if (!ret.second) {
179                    HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
180                        REQUEST_TYPE_CHARACTERISTICS_WRITE, GET_ENCRYPT_GATT_ADDR(device));
181                }
182            }
183
184            if (serverSptr->pimpl->callback_) {
185                serverSptr->pimpl->callback_->OnCharacteristicWriteRequest(
186                    BluetoothRemoteDevice(device.addr_.GetAddress(),
187                        (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
188                    gattcharacter.value().get(),
189                    serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_CHARACTERISTICS_WRITE, device.transport_));
190            }
191
192            return;
193        } else {
194            HILOGE("Can not Find Characteristic!");
195        }
196
197        return;
198    }
199
200    void OnDescriptorReadRequest(const BluetoothGattDevice &device, const BluetoothGattDescriptor &descriptor) override
201    {
202        HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
203            GET_ENCRYPT_GATT_ADDR(device), descriptor.handle_);
204        auto serverSptr = GetServerSptr();
205        if (!serverSptr) {
206            return;
207        }
208
209        std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
210        auto gattdesc = serverSptr->pimpl->FindDescriptor(descriptor.handle_);
211        if (gattdesc.has_value()) {
212            {
213                std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
214                auto ret = serverSptr->pimpl->requests_.emplace(
215                    RequestInformation(REQUEST_TYPE_DESCRIPTOR_READ, device, &gattdesc.value().get()));
216                if (!ret.second) {
217                    HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
218                        REQUEST_TYPE_DESCRIPTOR_READ, GET_ENCRYPT_GATT_ADDR(device));
219                }
220            }
221
222            if (serverSptr->pimpl->callback_) {
223                serverSptr->pimpl->callback_->OnDescriptorReadRequest(
224                    BluetoothRemoteDevice(device.addr_.GetAddress(),
225                        (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
226                    gattdesc.value().get(),
227                    serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_DESCRIPTOR_READ, device.transport_));
228            }
229
230            return;
231        } else {
232            HILOGE("Can not Find Descriptor!");
233        }
234
235        return;
236    }
237
238    void OnDescriptorWriteRequest(const BluetoothGattDevice &device, const BluetoothGattDescriptor &descriptor) override
239    {
240        HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
241            GET_ENCRYPT_GATT_ADDR(device), descriptor.handle_);
242        auto serverSptr = GetServerSptr();
243        if (!serverSptr) {
244            return;
245        }
246
247        std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
248        auto gattdesc = serverSptr->pimpl->FindDescriptor(descriptor.handle_);
249        if (gattdesc.has_value()) {
250            gattdesc.value().get().SetValue(descriptor.value_.get(), descriptor.length_);
251
252            {
253                std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
254                auto ret = serverSptr->pimpl->requests_.emplace(
255                    RequestInformation(REQUEST_TYPE_DESCRIPTOR_WRITE, device, &gattdesc.value().get()));
256                if (!ret.second) {
257                    HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
258                        REQUEST_TYPE_DESCRIPTOR_WRITE, GET_ENCRYPT_GATT_ADDR(device));
259                }
260            }
261
262            if (serverSptr->pimpl->callback_) {
263                serverSptr->pimpl->callback_->OnDescriptorWriteRequest(
264                    BluetoothRemoteDevice(device.addr_.GetAddress(),
265                        (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
266                    gattdesc.value().get(),
267                    serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_DESCRIPTOR_WRITE, device.transport_));
268            }
269
270            return;
271        } else {
272            HILOGE("Can not Find Descriptor!");
273        }
274        return;
275    }
276
277    void OnNotifyConfirm(
278        const BluetoothGattDevice &device, const BluetoothGattCharacteristic &characteristic, int result) override
279    {
280        HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
281            GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_);
282        auto serverSptr = GetServerSptr();
283        if (!serverSptr) {
284            return;
285        }
286
287        if (serverSptr->pimpl->callback_) {
288            serverSptr->pimpl->callback_->OnNotificationCharacteristicChanged(
289                BluetoothRemoteDevice(device.addr_.GetAddress(),
290                    (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
291                result);
292        }
293        return;
294    }
295
296    void OnConnectionStateChanged(const BluetoothGattDevice &device, int32_t ret, int32_t state) override
297    {
298        HILOGD("gattServer conn state, remote device: %{public}s, ret: %{public}d, state: %{public}s",
299            GET_ENCRYPT_GATT_ADDR(device), ret, GetProfileConnStateName(state).c_str());
300        auto serverSptr = GetServerSptr();
301        if (!serverSptr) {
302            return;
303        }
304
305        if (state == static_cast<int>(BTConnectState::CONNECTED)) {
306            std::lock_guard<std::mutex> lck(serverSptr->pimpl->deviceListMutex_);
307            serverSptr->pimpl->devices_.push_back((bluetooth::GattDevice)device);
308        } else if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
309            std::lock_guard<std::mutex> lck(serverSptr->pimpl->deviceListMutex_);
310            for (auto it = serverSptr->pimpl->devices_.begin(); it != serverSptr->pimpl->devices_.end(); it++) {
311                if (*it == (bluetooth::GattDevice)device) {
312                    serverSptr->pimpl->devices_.erase(it);
313                    break;
314                }
315            }
316        }
317
318        if (serverSptr->pimpl->callback_) {
319            serverSptr->pimpl->callback_->OnConnectionStateUpdate(
320                BluetoothRemoteDevice(device.addr_.GetAddress(),
321                    (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
322                state);
323        }
324
325        return;
326    }
327
328    void OnMtuChanged(const BluetoothGattDevice &device, int32_t mtu) override
329    {
330        HILOGI("remote device: %{public}s, mtu: %{public}d", GET_ENCRYPT_GATT_ADDR(device), mtu);
331        auto serverSptr = GetServerSptr();
332        if (!serverSptr) {
333            return;
334        }
335
336        if (serverSptr->pimpl->callback_) {
337            serverSptr->pimpl->callback_->OnMtuUpdate(
338                BluetoothRemoteDevice(device.addr_.GetAddress(),
339                    (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
340                mtu);
341        }
342
343        return;
344    }
345
346    void OnAddService(int32_t ret, const BluetoothGattService &service) override
347    {
348        HILOGI("enter, ret: %{public}d, handle: %{public}d", ret, service.handle_);
349        auto serverSptr = GetServerSptr();
350        if (!serverSptr) {
351            return;
352        }
353
354        GattService *ptr = nullptr;
355        if (ret == GattStatus::GATT_SUCCESS) {
356            GattService gattSvc = serverSptr->pimpl->BuildService(service);
357            serverSptr->pimpl->BuildIncludeService(gattSvc, service.includeServices_);
358            {
359                std::lock_guard<std::mutex> lck(serverSptr->pimpl->serviceListMutex_);
360                auto it = serverSptr->pimpl->gattServices_.emplace(
361                    serverSptr->pimpl->gattServices_.end(), std::move(gattSvc));
362                ptr = &(*it);
363            }
364        }
365        if (serverSptr->pimpl && serverSptr->pimpl->callback_) {
366            serverSptr->pimpl->callback_->OnServiceAdded(ptr, ret);
367        }
368        return;
369    }
370
371    void OnConnectionParameterChanged(
372        const BluetoothGattDevice &device, int32_t interval, int32_t latency, int32_t timeout, int32_t status) override
373    {
374        HILOGD("remote device: %{public}s, interval: %{public}d, "
375            "latency: %{public}d, timeout: %{public}d, status: %{public}d",
376            GET_ENCRYPT_GATT_ADDR(device), interval, latency, timeout, status);
377        auto serverSptr = GetServerSptr();
378        if (!serverSptr) {
379            return;
380        }
381
382        if (serverSptr->pimpl->callback_) {
383            serverSptr->pimpl->callback_->OnConnectionParameterChanged(
384                BluetoothRemoteDevice(device.addr_.GetAddress(),
385                    (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
386                interval,
387                latency,
388                timeout,
389                status);
390        }
391
392        return;
393    }
394
395    explicit BluetoothGattServerCallbackStubImpl(std::weak_ptr<GattServer> server) : server_(server)
396    {
397        HILOGD("enter");
398    }
399    ~BluetoothGattServerCallbackStubImpl() override
400    {
401        HILOGD("enter");
402    }
403
404private:
405    std::weak_ptr<GattServer> server_;
406};
407
408GattService GattServer::impl::BuildService(const BluetoothGattService &service)
409{
410    GattService gattService(UUID::ConvertFrom128Bits(service.uuid_.ConvertTo128Bits()),
411        service.handle_,
412        service.endHandle_,
413        service.isPrimary_ ? GattServiceType::PRIMARY : GattServiceType::SECONDARY);
414
415    for (auto &character : service.characteristics_) {
416        GattCharacteristic gattcharacter(UUID::ConvertFrom128Bits(character.uuid_.ConvertTo128Bits()),
417            character.handle_,
418            character.permissions_,
419            character.properties_);
420
421        gattcharacter.SetValue(character.value_.get(), character.length_);
422
423        for (auto &desc : character.descriptors_) {
424            GattDescriptor gattDesc(
425                UUID::ConvertFrom128Bits(desc.uuid_.ConvertTo128Bits()), desc.handle_, desc.permissions_);
426
427            gattDesc.SetValue(desc.value_.get(), desc.length_);
428            gattcharacter.AddDescriptor(std::move(gattDesc));
429        }
430
431        gattService.AddCharacteristic(std::move(gattcharacter));
432    }
433
434    return gattService;
435}
436
437void GattServer::impl::BuildIncludeService(GattService &svc, const std::vector<bluetooth::Service> &iSvcs)
438{
439    for (auto &iSvc : iSvcs) {
440        GattService *pSvc = GetIncludeService(iSvc.startHandle_);
441        if (!pSvc) {
442            HILOGE("Can not find include service entity in service ");
443            continue;
444        }
445        svc.AddService(std::ref(*pSvc));
446    }
447}
448
449GattService *GattServer::impl::GetIncludeService(uint16_t handle)
450{
451    for (auto &svc : gattServices_) {
452        if (svc.GetHandle() == handle) {
453            return &svc;
454        }
455    }
456
457    return nullptr;
458}
459
460GattServer::impl::impl(std::shared_ptr<GattServerCallback> callback)
461    : isRegisterSucceeded_(false), callback_(callback), applicationId_(0)
462{
463    HILOGD("enter");
464};
465
466GattServer::GattServer(std::shared_ptr<GattServerCallback> callback)
467{
468    HILOGI("create GattServer start.");
469    pimpl = std::make_unique<GattServer::impl>(callback);
470    if (!pimpl) {
471        HILOGE("create GattServer failed.");
472    }
473}
474
475bool GattServer::impl::Init(std::weak_ptr<GattServer> server)
476{
477    if (profileRegisterId != 0) { //ProxyManager has register callback
478        return true;
479    }
480    serviceCallback_ = new BluetoothGattServerCallbackStubImpl(server);
481    profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_GATT_SERVER,
482        [this](sptr<IRemoteObject> remote) {
483        sptr<IBluetoothGattServer> proxy = iface_cast<IBluetoothGattServer>(remote);
484        CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
485        int result = proxy->RegisterApplication(serviceCallback_);
486        if (result > 0) {
487            applicationId_ = result;
488            isRegisterSucceeded_ = true;
489        } else {
490            HILOGE("Can not Register to gatt server service! result = %{public}d", result);
491        }
492    });
493    return true;
494}
495
496std::shared_ptr<GattServer> GattServer::CreateInstance(std::shared_ptr<GattServerCallback> callback)
497{
498    // The passkey pattern used here.
499    auto instance = std::make_shared<GattServer>(PassKey(), callback);
500    if (!instance->pimpl) {
501        HILOGE("failed: no impl");
502        return nullptr;
503    }
504
505    instance->pimpl->Init(instance);
506    return instance;
507}
508
509std::optional<std::reference_wrapper<GattCharacteristic>> GattServer::impl::FindCharacteristic(uint16_t handle)
510{
511    for (auto &svc : gattServices_) {
512        for (auto &character : svc.GetCharacteristics()) {
513            if (character.GetHandle() == handle) {
514                return character;
515            }
516        }
517    }
518    return std::nullopt;
519}
520bluetooth::GattDevice *GattServer::impl::FindConnectedDevice(const BluetoothRemoteDevice &device)
521{
522    std::lock_guard<std::mutex> lock(deviceListMutex_);
523    for (auto &gattDevice : devices_) {
524        if (device.GetDeviceAddr().compare(gattDevice.addr_.GetAddress()) == 0 &&
525            (device.GetTransportType() ==
526            (gattDevice.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR)) {
527            return &gattDevice;
528        }
529    }
530    return nullptr;
531}
532std::optional<std::reference_wrapper<GattDescriptor>> GattServer::impl::FindDescriptor(uint16_t handle)
533{
534    for (auto &svc : gattServices_) {
535        for (auto &character : svc.GetCharacteristics()) {
536            for (auto &desc : character.GetDescriptors()) {
537                if (desc.GetHandle() == handle) {
538                    return desc;
539                }
540            }
541        }
542    }
543    return std::nullopt;
544}
545
546int GattServer::impl::BuildRequestId(uint8_t type, uint8_t transport)
547{
548    int requestId = 0;
549
550    requestId = type << EIGHT_BITS;
551    requestId |= transport;
552
553    return requestId;
554}
555
556int GattServer::impl::RespondCharacteristicRead(
557    const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)
558{
559    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
560    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
561
562    if (ret == GattStatus::GATT_SUCCESS) {
563        BluetoothGattCharacteristic character(bluetooth::Characteristic(handle, value, length));
564
565        return proxy->RespondCharacteristicRead(device, &character, ret);
566    }
567    BluetoothGattCharacteristic character;
568    character.handle_ = handle;
569    return proxy->RespondCharacteristicRead(device, &character, ret);
570}
571
572int GattServer::impl::RespondCharacteristicWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)
573{
574    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
575    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
576    return proxy->RespondCharacteristicWrite(
577        device, (BluetoothGattCharacteristic)bluetooth::Characteristic(handle), ret);
578}
579
580int GattServer::impl::RespondDescriptorRead(
581    const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)
582{
583    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
584    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
585    if (ret == GattStatus::GATT_SUCCESS) {
586        BluetoothGattDescriptor desc(bluetooth::Descriptor(handle, value, length));
587        return proxy->RespondDescriptorRead(device, &desc, ret);
588    }
589    BluetoothGattDescriptor desc;
590    desc.handle_ = handle;
591    return proxy->RespondDescriptorRead(device, &desc, ret);
592}
593
594int GattServer::impl::RespondDescriptorWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)
595{
596    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
597    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
598    return proxy->RespondDescriptorWrite(device, (BluetoothGattDescriptor)bluetooth::Descriptor(handle), ret);
599}
600
601int GattServer::AddService(GattService &service)
602{
603    HILOGD("enter");
604    if (!IS_BLE_ENABLED()) {
605        HILOGE("bluetooth is off.");
606        return BT_ERR_INVALID_STATE;
607    }
608
609    BluetoothGattService svc;
610    svc.isPrimary_ = service.IsPrimary();
611    svc.uuid_ = bluetooth::Uuid::ConvertFrom128Bits(service.GetUuid().ConvertTo128Bits());
612
613    for (auto &isvc : service.GetIncludedServices()) {
614        svc.includeServices_.push_back(bluetooth::Service(isvc.get().GetHandle()));
615    }
616
617    for (auto &character : service.GetCharacteristics()) {
618        size_t length = 0;
619        uint8_t *value = character.GetValue(&length).get();
620        bluetooth::Characteristic c(bluetooth::Uuid::ConvertFrom128Bits(character.GetUuid().ConvertTo128Bits()),
621            character.GetHandle(),
622            character.GetProperties(),
623            character.GetPermissions(),
624            value,
625            length);
626
627        for (auto &desc : character.GetDescriptors()) {
628            value = desc.GetValue(&length).get();
629            bluetooth::Descriptor d(bluetooth::Uuid::ConvertFrom128Bits(desc.GetUuid().ConvertTo128Bits()),
630                desc.GetHandle(),
631                desc.GetPermissions(),
632                value,
633                length);
634
635            c.descriptors_.push_back(std::move(d));
636        }
637
638        svc.characteristics_.push_back(std::move(c));
639    }
640    int appId = pimpl->applicationId_;
641    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
642    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
643    int ret = proxy->AddService(appId, &svc);
644    HILOGI("appId = %{public}d, ret = %{public}d.", appId, ret);
645    return ret;
646}
647
648void GattServer::ClearServices()
649{
650    HILOGD("enter");
651    if (!IS_BLE_ENABLED()) {
652        HILOGE("bluetooth is off.");
653        return;
654    }
655
656    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
657    CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
658
659    int appId = pimpl->applicationId_;
660    proxy->ClearServices(int(appId));
661    pimpl->gattServices_.clear();
662}
663
664int GattServer::Close()
665{
666    HILOGD("enter");
667    if (!IS_BLE_ENABLED()) {
668        HILOGE("bluetooth is off.");
669        return BT_ERR_INVALID_STATE;
670    }
671    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
672    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
673
674    int ret = proxy->DeregisterApplication(pimpl->applicationId_);
675    HILOGI("ret: %{public}d", ret);
676    if (ret == BT_NO_ERROR) {
677        pimpl->isRegisterSucceeded_ = false;
678    }
679    return ret;
680}
681
682int GattServer::Connect(const BluetoothRemoteDevice &device, bool isDirect)
683{
684    CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
685    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
686    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
687    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INTERNAL_ERROR, "Invalid remote device");
688
689    int appId = pimpl->applicationId_;
690    HILOGI("appId: %{public}d, device: %{public}s, isDirect: %{public}d", appId, GET_ENCRYPT_ADDR(device), isDirect);
691
692    bluetooth::GattDevice gattDevice(bluetooth::RawAddress(device.GetDeviceAddr()), GATT_TRANSPORT_TYPE_LE);
693    return proxy->Connect(appId, gattDevice, isDirect);
694}
695
696int GattServer::CancelConnection(const BluetoothRemoteDevice &device)
697{
698    CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
699    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
700    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
701    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INTERNAL_ERROR, "Invalid remote device");
702
703    auto gattDevice = pimpl->FindConnectedDevice(device);
704    if (gattDevice == nullptr) {
705        HILOGE("gattDevice is nullptr");
706        return BT_ERR_INTERNAL_ERROR;
707    }
708
709    int appId = pimpl->applicationId_;
710    HILOGI("appId: %{public}d, device: %{public}s", appId, GET_ENCRYPT_ADDR(device));
711    return proxy->CancelConnection(appId, *gattDevice);
712}
713std::optional<std::reference_wrapper<GattService>> GattServer::GetService(const UUID &uuid, bool isPrimary)
714{
715    HILOGD("enter");
716    if (!IS_BLE_ENABLED()) {
717        HILOGE("bluetooth is off.");
718        return std::nullopt;
719    }
720    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
721    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::nullopt, "failed: no proxy");
722
723    std::unique_lock<std::mutex> lock(pimpl->serviceListMutex_);
724
725    for (auto &svc : pimpl->gattServices_) {
726        if (svc.GetUuid().Equals(uuid) && svc.IsPrimary() == isPrimary) {
727            HILOGI("Find service, handle: 0x%{public}04X", svc.GetHandle());
728            return svc;
729        }
730    }
731
732    return std::nullopt;
733}
734
735std::list<GattService> &GattServer::GetServices()
736{
737    HILOGD("enter");
738    if (!IS_BLE_ENABLED()) {
739        HILOGE("bluetooth is off.");
740        return pimpl->gattServices_;
741    }
742    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
743    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, pimpl->gattServices_, "failed: no proxy");
744
745    std::unique_lock<std::mutex> lock(pimpl->serviceListMutex_);
746    return pimpl->gattServices_;
747}
748int GattServer::NotifyCharacteristicChanged(
749    const BluetoothRemoteDevice &device, const GattCharacteristic &characteristic, bool confirm)
750{
751    HILOGI("remote device: %{public}s, handle: 0x%{public}04X, confirm: %{public}d",
752        GET_ENCRYPT_ADDR(device), characteristic.GetHandle(), confirm);
753    if (!IS_BLE_ENABLED()) {
754        HILOGE("bluetooth is off.");
755        return BT_ERR_INVALID_STATE;
756    }
757
758    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
759    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
760
761    if (!device.IsValidBluetoothRemoteDevice()) {
762        HILOGE("Invalid remote device");
763        return BT_ERR_INTERNAL_ERROR;
764    }
765    if (pimpl->FindConnectedDevice(device) == nullptr) {
766        HILOGE("No connection to device: %{public}s", GET_ENCRYPT_ADDR(device));
767        return BT_ERR_INTERNAL_ERROR;
768    }
769
770    size_t length = 0;
771    auto &characterValue = characteristic.GetValue(&length);
772
773    BluetoothGattCharacteristic character(
774        bluetooth::Characteristic(characteristic.GetHandle(), characterValue.get(), length));
775    std::string address = device.GetDeviceAddr();
776    int ret = proxy->NotifyClient(
777        bluetooth::GattDevice(bluetooth::RawAddress(address), 0), &character, confirm);
778    HILOGI("ret = %{public}d.", ret);
779    return ret;
780}
781
782int GattServer::RemoveGattService(const GattService &service)
783{
784    HILOGD("enter");
785    if (!IS_BLE_ENABLED()) {
786        HILOGD("bluetooth is off.");
787        return BT_ERR_INVALID_STATE;
788    }
789
790    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
791    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
792
793    int ret = BT_ERR_INVALID_PARAM;
794    for (auto sIt = pimpl->gattServices_.begin(); sIt != pimpl->gattServices_.end(); sIt++) {
795        if (sIt->GetUuid().Equals(service.GetUuid())) {
796            ret = proxy->RemoveService(
797                pimpl->applicationId_, (BluetoothGattService)bluetooth::Service(sIt->GetHandle()));
798            pimpl->gattServices_.erase(sIt);
799            break;
800        }
801    }
802    HILOGI("result = %{public}d.", ret);
803    return ret;
804}
805int GattServer::SendResponse(
806    const BluetoothRemoteDevice &device, int requestId, int status, int offset, const uint8_t *value, int length)
807{
808    HILOGI("remote device: %{public}s, status: %{public}d", GET_ENCRYPT_ADDR(device), status);
809    if (!IS_BLE_ENABLED()) {
810        HILOGE("bluetooth is off.");
811        return BT_ERR_INVALID_STATE;
812    }
813
814    if (!device.IsValidBluetoothRemoteDevice()) {
815        HILOGE("pimpl or gatt server proxy is nullptr");
816        return BT_ERR_INTERNAL_ERROR;
817    }
818
819    if (pimpl->FindConnectedDevice(device) == nullptr) {
820        HILOGE("No connection to device: %{public}s", GET_ENCRYPT_ADDR(device));
821        return BT_ERR_INTERNAL_ERROR;
822    }
823
824    int result = BT_ERR_INTERNAL_ERROR;
825    uint8_t requestType = requestId >> EIGHT_BITS;
826    uint8_t transport = requestId & 0xFF;
827    if (transport != GATT_TRANSPORT_TYPE_CLASSIC && transport != GATT_TRANSPORT_TYPE_LE) {
828        return result;
829    }
830    bluetooth::GattDevice gattdevice(bluetooth::RawAddress(device.GetDeviceAddr()), transport);
831
832    std::lock_guard<std::mutex> lock(pimpl->requestListMutex_);
833    auto request = pimpl->requests_.find(RequestInformation(requestType, gattdevice));
834    if (request != pimpl->requests_.end()) {
835        switch (requestType) {
836            case REQUEST_TYPE_CHARACTERISTICS_READ:
837                result = pimpl->RespondCharacteristicRead(
838                    gattdevice, request->context_.characteristic_->GetHandle(), value, length, status);
839                break;
840            case REQUEST_TYPE_CHARACTERISTICS_WRITE:
841                result = pimpl->RespondCharacteristicWrite(
842                    gattdevice, request->context_.characteristic_->GetHandle(), status);
843                break;
844            case REQUEST_TYPE_DESCRIPTOR_READ:
845                result = pimpl->RespondDescriptorRead(
846                    gattdevice, request->context_.descriptor_->GetHandle(), value, length, status);
847                break;
848            case REQUEST_TYPE_DESCRIPTOR_WRITE:
849                result = pimpl->RespondDescriptorWrite(gattdevice, request->context_.descriptor_->GetHandle(), status);
850                break;
851            default:
852                HILOGE("Error request Id!");
853                break;
854        }
855        if (result == BT_NO_ERROR) {
856            pimpl->requests_.erase(request);
857        }
858    }
859    HILOGD("result = %{public}d.", result);
860    return result;
861}
862
863GattServer::~GattServer()
864{
865    HILOGD("enter");
866    BluetoothProfileManager::GetInstance().DeregisterFunc(pimpl->profileRegisterId);
867    sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
868    CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
869    if (pimpl->isRegisterSucceeded_) {
870        proxy->DeregisterApplication(pimpl->applicationId_);
871    }
872    HILOGI("end");
873}
874}  // namespace Bluetooth
875}  // namespace OHOS
876