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