/*
 * Copyright (C) 2024-2026 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bluetooth_gatt_server_impl.h"

#import "BluetoothPeripheralManager.h"
#import "BluetoothUntils.h"
#include "bluetooth_gatt_characteristic.h"
#include "bluetooth_log.h"
#include "securec.h"

using Propertie = OHOS::Bluetooth::GattCharacteristic::Propertie;
using namespace OHOS::bluetooth;

const uint16_t MIN_SERVICE_HANDLE = 1;
const uint16_t MAX_SERVICE_HANDLE = 65535;
const uint16_t CHARACTERISTIC_READ = 0;
const uint16_t CHARACTERISTIC_WRITE = 1;

namespace OHOS {
namespace Bluetooth {
const std::string CLIENT_CHARACTERISTIC_CONFIGURATION_UUID = "00002902-0000-1000-8000-00805F9B34FB";

static const OHOS::bluetooth::Descriptor* GetClientCharacteristicConfigurationDescriptor(
    const OHOS::bluetooth::Characteristic& characteristic)
{
    for (const auto& descriptor : characteristic.descriptors_) {
        if (descriptor.uuid_.ToString() == CLIENT_CHARACTERISTIC_CONFIGURATION_UUID) {
            return &descriptor;
        }
    }
    return nullptr;
}

static bool AssignGattDescriptor(const OHOS::bluetooth::Descriptor& sourceDescriptor, int length,
    const uint8_t* bytesValue, BluetoothGattDescriptor& descriptor)
{
    descriptor.handle_ = sourceDescriptor.handle_;
    descriptor.permissions_ = sourceDescriptor.permissions_;
    descriptor.uuid_ = sourceDescriptor.uuid_;
    descriptor.length_ = static_cast<size_t>(length);
    descriptor.value_ = std::make_unique<uint8_t[]>(descriptor.length_);
    if (memcpy_s(descriptor.value_.get(), descriptor.length_, bytesValue, descriptor.length_) != EOK) {
        descriptor.value_.reset(nullptr);
        descriptor.length_ = 0;
        return false;
    }
    return true;
}

BluetoothGattServerImpl::BluetoothGattServerImpl()
{
    appId_ = 0;
}

bool BluetoothGattServerImpl::CalculateAndAssignHandle(const int applicationId, BluetoothGattService& service)
{
    uint16_t count = 1;
    std::pair<uint16_t, uint16_t> handlePair(0, 0);
    count += service.includeServices_.size();
    count += service.characteristics_.size() * 0x2;
    for (auto& ccc : service.characteristics_) {
        count += ccc.descriptors_.size();
    }
    for (auto item = gattServiceHandleMap_[applicationId].begin(); item != gattServiceHandleMap_[applicationId].end();
         item++) {
        auto availableLength = item->second - item->first + 1;
        if (availableLength >= count) {
            handlePair = std::pair<uint16_t, uint16_t>(item->first, item->first + count - 1);
            if (handlePair.second < item->second) {
                gattServiceHandleMap_[applicationId].insert(
                    item, std::pair<uint16_t, uint16_t>(handlePair.second + 1, item->second));
            }
            gattServiceHandleMap_[applicationId].erase(item);
            break;
        }
    }
    service.handle_ = handlePair.first;
    service.endHandle_ = handlePair.second;
    if (handlePair == std::pair<uint16_t, uint16_t>(0, 0)) {
        return false;
    }
    uint32_t currentHandle = handlePair.first + 1;
    for (auto& includeService : service.includeServices_) {
        includeService.handle_ = currentHandle++;
    }
    for (auto& charactor : service.characteristics_) {
        charactor.handle_ = currentHandle++;
        charactor.valueHandle_ = currentHandle++;
        for (auto& descriptor : charactor.descriptors_) {
            descriptor.handle_ = currentHandle++;
        }
        charactor.endHandle_ = currentHandle - 1;
    }
    gattServiceMap_.insert({ service.handle_, service });
    gattServiceAppIdMap_.insert({ service.handle_, applicationId });
    return true;
}

void BluetoothGattServerImpl::ReleaseHandle(const int applicationId, const BluetoothGattService& service)
{
    if (gattServiceHandleMap_[applicationId].empty()) {
        gattServiceHandleMap_[applicationId].emplace_front(service.handle_, service.endHandle_);
        return;
    }
    auto item = gattServiceHandleMap_[applicationId].begin();
    while (item != gattServiceHandleMap_[applicationId].end()) {
        auto currentNode = item;
        auto nextNode = ++item;
        if (currentNode->first > service.endHandle_) {
            if (currentNode->first == service.endHandle_ + 1) {
                gattServiceHandleMap_[applicationId].emplace(currentNode, service.handle_, currentNode->second);
                gattServiceHandleMap_[applicationId].erase(currentNode);
            } else {
                gattServiceHandleMap_[applicationId].emplace(currentNode, service.handle_, service.endHandle_);
            }
            break;
        }
        if (nextNode == gattServiceHandleMap_[applicationId].end()) {
            if (service.handle_ == currentNode->second + 1) {
                gattServiceHandleMap_[applicationId].emplace(currentNode, currentNode->first, service.endHandle_);
                gattServiceHandleMap_[applicationId].erase(currentNode);
            } else {
                gattServiceHandleMap_[applicationId].emplace(nextNode, service.handle_, service.endHandle_);
            }
            break;
        } else {
            if (service.handle_ > nextNode->second) {
                continue;
            }
            if (service.handle_ == currentNode->second + 1 && service.endHandle_ + 1 != nextNode->first) {
                gattServiceHandleMap_[applicationId].emplace(currentNode, currentNode->first, service.endHandle_);
                gattServiceHandleMap_[applicationId].erase(currentNode);
            } else if (service.handle_ != currentNode->second + 1 && service.endHandle_ + 1 == nextNode->first) {
                gattServiceHandleMap_[applicationId].emplace(nextNode, service.handle_, nextNode->second);
                gattServiceHandleMap_[applicationId].erase(nextNode);
            } else if (service.handle_ == currentNode->second + 1 && service.endHandle_ + 1 == nextNode->first) {
                gattServiceHandleMap_[applicationId].emplace(nextNode, currentNode->first, nextNode->second);
                gattServiceHandleMap_[applicationId].erase(currentNode);
                gattServiceHandleMap_[applicationId].erase(nextNode);
            } else {
                gattServiceHandleMap_[applicationId].emplace(nextNode, service.handle_, service.endHandle_);
            }
            break;
        }
    }
}

CBMutableCharacteristic* createCharacter(BluetoothGattCharacteristic& cvc)
{
    CBCharacteristicProperties properties = (CBCharacteristicProperties)cvc.properties_;
    CBAttributePermissions permissions = 0;
    if (cvc.permissions_ & static_cast<int>(GattPermission::READABLE)) {
        permissions |= CBAttributePermissionsReadable;
    }
    if (cvc.permissions_ & static_cast<int>(GattPermission::WRITEABLE)) {
        permissions |= CBAttributePermissionsWriteable;
    }
    NSString* strUUID = [NSString stringWithFormat:@"%s", cvc.uuid_.ToString().c_str()];
    CBUUID* characterUUID = [CBUUID UUIDWithString:strUUID];
    uint8_t* rawData = cvc.value_.get();
    size_t dataSize = cvc.length_;
    NSData* characterData = [NSData dataWithBytes:rawData length:dataSize];
    CBMutableCharacteristic* character = nil;
    if (properties & CBCharacteristicPropertyNotify || properties & CBCharacteristicPropertyIndicate) {
        character = [[CBMutableCharacteristic alloc] initWithType:characterUUID
                                                       properties:properties
                                                            value:nil
                                                      permissions:permissions];
    } else {
        character = [[CBMutableCharacteristic alloc] initWithType:characterUUID
                                                       properties:properties
                                                            value:characterData
                                                      permissions:permissions];
    }
    NSMutableArray* arrDescriptor = [NSMutableArray array];
    for (OHOS::bluetooth::Descriptor descriptor : cvc.descriptors_) {
        NSString* strDid = [NSString stringWithFormat:@"%s", descriptor.uuid_.ToString().c_str()];
        strDid = [BluetoothUntils GetSystemStringUUIDKey:strDid];
        if ([strDid isEqualToString:CBUUIDClientCharacteristicConfigurationString]) {
            continue;
        }
        CBUUID* descriptorUUID = [CBUUID UUIDWithString:strDid];
        uint8_t* descriptorValue = descriptor.value_.get();
        size_t descriptorLength = descriptor.length_;
        NSData* descriptorsData = [NSData dataWithBytes:descriptorValue length:descriptorLength];
        id value = [BluetoothUntils GetValueWithData:descriptorsData uuid:strDid];
        CBMutableDescriptor* descriptor_ios = [[CBMutableDescriptor alloc] initWithType:descriptorUUID value:value];
        [arrDescriptor addObject:descriptor_ios];
    }
    character.descriptors = arrDescriptor;
    return character;
}

CBMutableService* CreateServices(BluetoothGattService gattService)
{
    NSString* strServiceUUID = [NSString stringWithFormat:@"%s", gattService.uuid_.ToString().c_str()];
    CBUUID* serviceUUID = [CBUUID UUIDWithString:strServiceUUID];
    CBMutableService* mutableService = [[CBMutableService alloc] initWithType:serviceUUID
                                                                      primary:gattService.isPrimary_];
    NSMutableArray* arrCharacter = [NSMutableArray array];
    for (OHOS::bluetooth::Characteristic cvc : gattService.characteristics_) {
        BluetoothGattCharacteristic gattCharacter(cvc);
        CBMutableCharacteristic* character = createCharacter(gattCharacter);
        [arrCharacter addObject:character];
    }

    [mutableService setCharacteristics:arrCharacter];
    return mutableService;
}

int BluetoothGattServerImpl::AddService(int32_t appId, BluetoothGattService* services)
{
    BluetoothGattService gattService = BluetoothGattService(*services);
    CalculateAndAssignHandle(appId, gattService);
    CBMutableService* service = CreateServices(gattService);
    BluetoothPeripheralManager* peripheralManager = [BluetoothPeripheralManager sharedInstance];
    [peripheralManager addService:service
                            appId:appId
                            block:^(int ret) {
                              if (serviceCallBack_) {
                                  serviceCallBack_->OnAddService(ret, gattService);
                              }
                            }];
    return BT_NO_ERROR;
}

int BluetoothGattServerImpl::ClearServices(int appId)
{
    return BT_NO_ERROR;
}

int BluetoothGattServerImpl::RegisterApplication(const sptr<IBluetoothGattServerCallback>& callback)
{
    std::lock_guard<std::mutex> lock(gattServerMutex_);
    serviceCallBack_ = callback;
    BluetoothPeripheralManager* peripheralManager = [BluetoothPeripheralManager sharedInstance];
    peripheralManager.connectDeviceBlock = ^(int state, NSString* _Nonnull deviceId) {
      if (serviceCallBack_) {
          BluetoothGattDevice gattDevice;
          gattDevice.addr_ = OHOS::bluetooth::RawAddress(deviceId.UTF8String);
          gattDevice.transport_ = GATT_TRANSPORT_TYPE_LE;
          switch (state) {
              case CBPeripheralStateConnected:
                  serviceCallBack_->OnConnectionStateChanged(
                      gattDevice, BT_NO_ERROR, static_cast<int>(BTConnectState::CONNECTED),
                      static_cast<int>(GattDisconnectReason::CONN_UNKNOWN), "");
                  break;
              default:
                  serviceCallBack_->OnConnectionStateChanged(
                      gattDevice, BT_NO_ERROR, static_cast<int>(BTConnectState::DISCONNECTED),
                      static_cast<int>(GattDisconnectReason::CONN_UNKNOWN), "");
                  break;
          }
      }
    };
    GattCharacteristicReadBlock();
    GattCharacteristicWriteBlock();
    GattCharacteristicNotifyBlock();
    GattDescriptorWriteBlock();
    int appId = [[BluetoothPeripheralManager sharedInstance] getAppId];
    gattServiceHandleMap_[appId].emplace_front(std::make_pair(MIN_SERVICE_HANDLE, MAX_SERVICE_HANDLE));
    return appId;
}

int BluetoothGattServerImpl::DeregisterApplication(int appId)
{
    std::lock_guard<std::mutex> lock(gattServerMutex_);
    NSString* strAppId = [NSString stringWithFormat:@"%d", appId];
    [[BluetoothPeripheralManager sharedInstance] closePeripheral:strAppId];
    auto item = gattServiceHandleMap_.find(appId);
    if (item != gattServiceHandleMap_.end()) {
        gattServiceHandleMap_.erase(item);
    }
    for (auto serviceItem = gattServiceAppIdMap_.begin(); serviceItem != gattServiceAppIdMap_.end();) {
        if (serviceItem->second == appId) {
            gattServiceMap_.erase(serviceItem->first);
            serviceItem = gattServiceAppIdMap_.erase(serviceItem);
        } else {
            ++serviceItem;
        }
    }
    return BT_NO_ERROR;
}

int BluetoothGattServerImpl::Connect(int appId, const BluetoothGattDevice& device, bool isDirect)
{
    return BT_NO_ERROR;
}

int BluetoothGattServerImpl::CancelConnection(int appId, const BluetoothGattDevice& device)
{
    return BT_NO_ERROR;
}

CBMutableCharacteristic* GetCurrentCharacteristic(uint16_t currentHandle, BluetoothGattService gattService)
{
    CBMutableCharacteristic* character = nil;
    for (OHOS::bluetooth::Characteristic cvc : gattService.characteristics_) {
        BluetoothGattCharacteristic gattCharacter(cvc);
        if (cvc.handle_ == currentHandle) {
            character = createCharacter(gattCharacter);
            break;
        }
    }
    return character;
}

int BluetoothGattServerImpl::NotifyClient(
    const BluetoothGattDevice& device, BluetoothGattCharacteristic* characteristic, bool needConfirm)
{
    if (characteristic == nullptr) {
        HILOGE("characteristic is null");
        return BT_ERR_INTERNAL_ERROR;
    }
    CBMutableService* service = nil;
    CBMutableCharacteristic* character = nil;
    int32_t notifyAppId = 0;
    for (auto item = gattServiceMap_.rbegin(); item != gattServiceMap_.rend(); ++item) {
        uint16_t serviceHandle = item->first;
        if (serviceHandle < characteristic->handle_) {
            service = CreateServices(item->second);
            character = GetCurrentCharacteristic(characteristic->handle_, item->second);
            auto appIdItem = gattServiceAppIdMap_.find(serviceHandle);
            if (appIdItem != gattServiceAppIdMap_.end()) {
                notifyAppId = appIdItem->second;
            }
            break;
        }
    }
    if (!service || !character || notifyAppId == 0) {
        return BT_ERR_INTERNAL_ERROR;
    }
    BOOL supportNotify = ((character.properties & CBCharacteristicPropertyNotify) != 0) ||
        ((character.properties & CBCharacteristicPropertyNotifyEncryptionRequired) != 0);
    BOOL supportIndicate = ((character.properties & CBCharacteristicPropertyIndicate) != 0) ||
        ((character.properties & CBCharacteristicPropertyIndicateEncryptionRequired) != 0);
    if (needConfirm && !supportIndicate) {
        return BT_ERR_API_NOT_SUPPORT;
    }
    if (!needConfirm && !supportNotify) {
        return BT_ERR_API_NOT_SUPPORT;
    }
    uint8_t* rawData = characteristic->value_.get();
    size_t dataSize = characteristic->length_;
    if (rawData == nullptr && dataSize > 0) {
        return BT_ERR_INTERNAL_ERROR;
    }
    character.value = dataSize == 0 ? [NSData data] : [NSData dataWithBytes:rawData length:dataSize];
    NSString* strDeviceId = [NSString stringWithFormat:@"%s", device.addr_.GetAddress().c_str()];
    BluetoothPeripheralManager* bpm = [BluetoothPeripheralManager sharedInstance];
    int ret = [bpm notifyCharacteristicChanged:strDeviceId
                                         appId:notifyAppId
                                   serviceUUID:service.UUID.UUIDString
                          notifyCharacteristic:character];
    if (ret == BT_NO_ERROR && serviceCallBack_ != nullptr) {
        BluetoothGattDevice gattDevice = device;
        serviceCallBack_->OnNotifyConfirm(gattDevice, *characteristic, BT_NO_ERROR);
    }
    return ret;
}

int BluetoothGattServerImpl::RemoveService(int32_t appId, const BluetoothGattService& services)
{
    ReleaseHandle(appId, services);
    CBMutableService* service = nil;
    for (auto item = gattServiceMap_.begin(); item != gattServiceMap_.end(); ++item) {
        uint16_t serviceHandle = item->first;
        if (serviceHandle == services.handle_) {
            service = CreateServices(item->second);
            gattServiceMap_.erase(serviceHandle);
            gattServiceAppIdMap_.erase(serviceHandle);
            break;
        }
    }
    BluetoothPeripheralManager* peripheralManager = [BluetoothPeripheralManager sharedInstance];
    return [peripheralManager removeService:service.UUID.UUIDString appId:appId];
}

int BluetoothGattServerImpl::RespondCharacteristic(
    const uint16_t type, const BluetoothGattDevice& device, const BluetoothGattCharacteristic& gattCharacter,
    int32_t ret)
{
    uint16_t characterHandle = gattCharacter.handle_;
    CBMutableService* service = nil;
    CBMutableCharacteristic* character = nil;
    int32_t respondAppId = 0;
    for (auto item = gattServiceMap_.rbegin(); item != gattServiceMap_.rend(); ++item) {
        uint16_t serviceHandle = item->first;
        if (serviceHandle < characterHandle) {
            service = CreateServices(item->second);
            character = GetCurrentCharacteristic(characterHandle, item->second);
            auto appIdItem = gattServiceAppIdMap_.find(serviceHandle);
            if (appIdItem != gattServiceAppIdMap_.end()) {
                respondAppId = appIdItem->second;
            }
            break;
        }
    }
    if (!service || !character || respondAppId == 0) {
        HILOGE("service character is null");
        return BT_ERR_INTERNAL_ERROR;
    }
    NSString* strDeviceId = [NSString stringWithFormat:@"%s", device.addr_.GetAddress().c_str()];
    BluetoothPeripheralManager* bpm = [BluetoothPeripheralManager sharedInstance];
    int result;
    if (type == CHARACTERISTIC_READ) {
        uint8_t* rawData = gattCharacter.value_.get();
        size_t dataSize = gattCharacter.length_;
        NSData* characterData = [NSData dataWithBytes:rawData length:dataSize];
        result = [bpm sendRespondReadWithDeviceId:strDeviceId
                                             appId:respondAppId
                                      serviceUUID:service.UUID.UUIDString
                                    characterUUID:character.UUID.UUIDString
                                             data:characterData
                                           status:ret];
    } else {
        result = [bpm sendRespondWriteWithDeviceId:strDeviceId
                                              appId:respondAppId
                                       serviceUUID:service.UUID.UUIDString
                                     characterUUID:character.UUID.UUIDString
                                            status:ret];
    }
    return result;
}

int BluetoothGattServerImpl::RespondCharacteristicRead(
    const BluetoothGattDevice& device, BluetoothGattCharacteristic* characteristic, int32_t ret)
{
    BluetoothGattCharacteristic gattCharacteristic = BluetoothGattCharacteristic(*characteristic);
    return RespondCharacteristic(CHARACTERISTIC_READ, device, gattCharacteristic, ret);
}

int BluetoothGattServerImpl::RespondCharacteristicWrite(
    const BluetoothGattDevice& device, const BluetoothGattCharacteristic& characteristic, int32_t ret)
{
    BluetoothGattCharacteristic gattCharacteristic = BluetoothGattCharacteristic(characteristic);
    return RespondCharacteristic(CHARACTERISTIC_WRITE, device, gattCharacteristic, ret);
}

int BluetoothGattServerImpl::RespondDescriptorRead(
    const BluetoothGattDevice& device, BluetoothGattDescriptor* descriptor, int32_t ret)
{
    return BT_NO_ERROR;
}

int BluetoothGattServerImpl::RespondDescriptorWrite(
    const BluetoothGattDevice& device, const BluetoothGattDescriptor& descriptor, int32_t ret)
{
    return BT_NO_ERROR;
}

int BluetoothGattServerImpl::GetConnectedState(const std::string& deviceId, int& state)
{
    return BT_NO_ERROR;
}

int BluetoothGattServerImpl::SetPhy(int32_t appId, const std::string &deviceId,
    int32_t txPhy, int32_t rxPhy, int32_t phyOptions)
{
    return BT_NO_ERROR;
}

int BluetoothGattServerImpl::ReadPhy(int32_t appId, const std::string &deviceId)
{
    return BT_NO_ERROR;
}

int32_t BluetoothGattServerImpl::GetGattServerAppId()
{
    appId_ += 1;
    return appId_;
}

void BluetoothGattServerImpl::GetGattCharacteristic(std::string serviceUUID, std::string charaUUID, int length,
    const uint8_t* bytesValue, BluetoothGattCharacteristic& character)
{
    for (auto item = gattServiceMap_.begin(); item != gattServiceMap_.end(); ++item) {
        BluetoothGattService gattService = item->second;
        if (serviceUUID != gattService.uuid_.ToString()) {
            continue;
        }
        for (OHOS::bluetooth::Characteristic cvc : gattService.characteristics_) {
            if (charaUUID != cvc.uuid_.ToString()) {
                continue;
            }
            character.length_ = cvc.length_;
            character.uuid_ = cvc.uuid_;
            character.handle_ = cvc.handle_;
            character.properties_ = cvc.properties_;
            character.permissions_ = cvc.permissions_;
            character.SetValue(bytesValue, length);
            for (auto& desc : cvc.descriptors_) {
                character.descriptors_.push_back(desc);
            }
            break;
        }
    }
}

bool BluetoothGattServerImpl::GetGattDescriptor(std::string serviceUUID, std::string charaUUID, int length,
    const uint8_t* bytesValue, BluetoothGattDescriptor& descriptor)
{
    for (auto item = gattServiceMap_.begin(); item != gattServiceMap_.end(); ++item) {
        const BluetoothGattService& gattService = item->second;
        if (serviceUUID != gattService.uuid_.ToString()) {
            continue;
        }
        for (const auto& cvc : gattService.characteristics_) {
            if (charaUUID != cvc.uuid_.ToString()) {
                continue;
            }
            const auto* cccdDescriptor = GetClientCharacteristicConfigurationDescriptor(cvc);
            if (cccdDescriptor == nullptr) {
                continue;
            }
            return AssignGattDescriptor(*cccdDescriptor, length, bytesValue, descriptor);
        }
    }
    return false;
}

void BluetoothGattServerImpl::GattCharacteristicWriteBlock()
{
    BluetoothPeripheralManager* peripheralManager = [BluetoothPeripheralManager sharedInstance];
    peripheralManager.characterWriteBlock =
        ^(NSString* _Nonnull deviceId, CBMutableCharacteristic* _Nonnull characteristic) {
          if (serviceCallBack_ == nullptr) {
              return;
          }
          NSUInteger length = [characteristic.value length];
          const uint8_t* bytesValue = (const uint8_t*)[characteristic.value bytes];
          std::string serviceUuid = characteristic.service.UUID.UUIDString.UTF8String;
          std::string characterUuid = characteristic.UUID.UUIDString.UTF8String;
          BluetoothGattCharacteristic gattCharacteristic;
          GetGattCharacteristic(serviceUuid, characterUuid, length, bytesValue, gattCharacteristic);

          bool needRespones = characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse ? false : true;
          BluetoothGattDevice gattDevice;
          gattDevice.addr_ = OHOS::bluetooth::RawAddress(deviceId.UTF8String);
          gattDevice.transport_ = GATT_TRANSPORT_TYPE_LE;
          serviceCallBack_->OnCharacteristicWriteRequest(gattDevice, gattCharacteristic, needRespones);
        };
}

void BluetoothGattServerImpl::GattCharacteristicReadBlock()
{
    BluetoothPeripheralManager* peripheralManager = [BluetoothPeripheralManager sharedInstance];
    peripheralManager.characterReadBlock =
        ^(NSString* _Nonnull deviceId, CBMutableCharacteristic* _Nonnull characteristic) {
          if (serviceCallBack_ == nullptr) {
              return;
          }
          NSUInteger length = [characteristic.value length];
          const uint8_t* bytesValue = (const uint8_t*)[characteristic.value bytes];
          std::string serviceUuid = characteristic.service.UUID.UUIDString.UTF8String;
          std::string characterUuid = characteristic.UUID.UUIDString.UTF8String;
          BluetoothGattCharacteristic gattCharacteristic;
          GetGattCharacteristic(serviceUuid, characterUuid, length, bytesValue, gattCharacteristic);
          BluetoothGattDevice gattDevice;
          gattDevice.addr_ = OHOS::bluetooth::RawAddress(deviceId.UTF8String);
          gattDevice.transport_ = GATT_TRANSPORT_TYPE_LE;
          serviceCallBack_->OnCharacteristicReadRequest(gattDevice, gattCharacteristic);
        };
}

void BluetoothGattServerImpl::GattDescriptorWriteBlock()
{
    BluetoothPeripheralManager* peripheralManager = [BluetoothPeripheralManager sharedInstance];
    peripheralManager.descriptorWriteBlock =
        ^(NSString* _Nonnull deviceId, CBCharacteristic* _Nonnull characteristic, NSData* _Nonnull value) {
          if (serviceCallBack_ == nullptr) {
              return;
          }
          NSUInteger length = [value length];
          const uint8_t* bytesValue = (const uint8_t*)[value bytes];
          std::string serviceUuid = characteristic.service.UUID.UUIDString.UTF8String;
          std::string characterUuid = characteristic.UUID.UUIDString.UTF8String;
          BluetoothGattDescriptor gattDescriptor;
          if (!GetGattDescriptor(serviceUuid, characterUuid, static_cast<int>(length), bytesValue, gattDescriptor)) {
              return;
          }
          BluetoothGattDevice gattDevice;
          gattDevice.addr_ = OHOS::bluetooth::RawAddress(deviceId.UTF8String);
          gattDevice.transport_ = GATT_TRANSPORT_TYPE_LE;
          serviceCallBack_->OnDescriptorWriteRequest(gattDevice, gattDescriptor);
        };
}

void BluetoothGattServerImpl::GattCharacteristicNotifyBlock()
{
    BluetoothPeripheralManager* peripheralManager = [BluetoothPeripheralManager sharedInstance];
    peripheralManager.characterNotifyBlock =
        ^(NSString* _Nonnull deviceId, CBCharacteristic* _Nonnull characteristic, int state) {
          if (serviceCallBack_ == nullptr) {
              return;
          }
          NSUInteger length = [characteristic.value length];
          const uint8_t* bytesValue = (const uint8_t*)[characteristic.value bytes];
          std::string serviceUuid = characteristic.service.UUID.UUIDString.UTF8String;
          std::string characterUuid = characteristic.UUID.UUIDString.UTF8String;
          BluetoothGattCharacteristic gattCharacteristic;
          GetGattCharacteristic(serviceUuid, characterUuid, length, bytesValue, gattCharacteristic);

          BluetoothGattDevice gattDevice;
          gattDevice.addr_ = OHOS::bluetooth::RawAddress(deviceId.UTF8String);
          gattDevice.transport_ = GATT_TRANSPORT_TYPE_LE;
          serviceCallBack_->OnNotifyConfirm(gattDevice, gattCharacteristic, BT_NO_ERROR);
        };
}
} // namespace Bluetooth
} // namespace OHOS