/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *
 *    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.
 */

/**
 *    @file
 *          Provides an implementation of the BLEManager singleton object
 *          for the Telink platform.
 */
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>

#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE

#include <ble/BleUUID.h>
#include <ble/CHIPBleServiceData.h>
#include <platform/internal/BLEManager.h>

#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>

/*Includes for ieee802154 switchings */
#define DT_DRV_COMPAT telink_b91_zb
#include <drivers/ieee802154/b91.h>
#include <net/ieee802154_radio.h>

/* Telink headers */
#include "drivers.h"
#include "ext_driver/ext_misc.h"
#include "stack/ble/ble.h"
#include "tl_common.h"
#include "types.h"

using namespace ::chip;
using namespace ::chip::Ble;
using namespace ::chip::System;

namespace chip {
namespace DeviceLayer {
namespace Internal {

namespace {

typedef enum
{
    ATT_H_START = 0,

    /* GAP service */
    GenericAccess_PS_H,            // UUID: 2800, VALUE: uuid 1800
    GenericAccess_DeviceName_CD_H, // UUID: 2803, VALUE: Prop: Read | Notify
    GenericAccess_DeviceName_DP_H, // UUID: 2A00, VALUE: device name
    GenericAccess_Appearance_CD_H, // UUID: 2803, VALUE: Prop: Read
    GenericAccess_Appearance_DP_H, // UUID: 2A01, VALUE: appearance
    CONN_PARAM_CD_H,               // UUID: 2803, VALUE: Prop: Read
    CONN_PARAM_DP_H,               // UUID: 2A04, VALUE: connParameter

    /* GATT service */
    GenericAttribute_PS_H,                 // UUID: 2800, VALUE: uuid 1801
    GenericAttribute_ServiceChanged_CD_H,  // UUID: 2803, VALUE: Prop: Indicate
    GenericAttribute_ServiceChanged_DP_H,  // UUID: 2A05, VALUE: service change
    GenericAttribute_ServiceChanged_CCB_H, // UUID: 2902, VALUE: serviceChangeCCC

    /* Matter service */
    Matter_PS_H,
    Matter_RX_CD_H,
    Matter_RX_DP_H,
    Matter_TX_CD_H,
    Matter_TX_DP_H,
    Matter_TX_CCC_H,

    ATT_END_H,

} ATT_HANDLE;

typedef struct
{
    /** Minimum value for the connection event (interval. 0x0006 - 0x0C80 * 1.25 ms) */
    u16 intervalMin;
    /** Maximum value for the connection event (interval. 0x0006 - 0x0C80 * 1.25 ms) */
    u16 intervalMax;
    /** Number of LL latency connection events (0x0000 - 0x03e8) */
    u16 latency;
    /** Connection Timeout (0x000A - 0x0C80 * 10 ms) */
    u16 timeout;
} gap_periConnectParams_t;

#define CHIP_MAC_LEN 6
#define CHIP_MTU_SIZE 244
#define CHIP_MAX_ADV_DATA_LEN 31
#define CHIP_MAX_RESPONSE_DATA_LEN 31
#define CHIP_SHORT_UUID_LEN 2

#define CHIP_ADE_DATA_LEN_FLAGS 0x02
#define CHIP_ADV_DATA_TYPE_FLAGS 0x01
#define CHIP_ADV_DATA_FLAGS 0x06
#define CHIP_ADV_DATA_TYPE_UUID 0x03
#define CHIP_ADV_DATA_TYPE_NAME 0x09
#define CHIP_ADV_DATA_TYPE_SERVICE_DATA 0x16
#define CHIP_ADV_SERVICE_DATA_LEN (sizeof(ChipBLEDeviceIdentificationInfo) + CHIP_SHORT_UUID_LEN + 1)

#define CHIP_BLE_TX_FIFO_SIZE 48
#define CHIP_BLE_TX_FIFO_NUM 33
#define CHIP_BLE_RX_FIFO_SIZE 48
#define CHIP_BLE_RX_FIFO_NUM 8

#define CHIP_BLE_THREAD_STACK_SIZE 2048
#define CHIP_BLE_THREAD_PRIORITY 2

#define CHIP_BLE_DISCONNECT_REASON 8

#define CHIP_RF_PACKET_HEADER_SIZE 3

#define STIMER_IRQ_NUM 1
#define RF_IRQ_NUM 15

#define CHIP_RX_CHAR_UUID 0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18
#define CHIP_TX_CHAR_UUID 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18

const ChipBleUUID chipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
                                                 0x9D, 0x11 } };

const ChipBleUUID chipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
                                                 0x9D, 0x12 } };

static const uint8_t matterServiceUUID[CHIP_SHORT_UUID_LEN] = { 0xF6, 0xFF }; // service UUID

} // unnamed namespace

BLEManagerImpl BLEManagerImpl::sInstance;

void rf_irq_handler(const void * paramiter)
{
    irq_blt_sdk_handler();
}

void stimer_irq_handler(const void * paramiter)
{
    irq_blt_sdk_handler();
}

void BLEManagerImpl::BleEntry(void *, void *, void *)
{
    while (true)
    {
        blt_sdk_main_loop();

        k_msleep(10);
    }
}

/* Thread for running BLE main loop */
K_THREAD_DEFINE(chipBleThread, CHIP_BLE_THREAD_STACK_SIZE, BLEManagerImpl::BleEntry, NULL, NULL, NULL, CHIP_BLE_THREAD_PRIORITY, 0,
                0);

CHIP_ERROR BLEManagerImpl::_Init()
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    ThreadConnectivityReady = false;

    /* Initialize the CHIP BleLayer. */
    err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer());
    SuccessOrExit(err);

    /* Set number of connections to zero */
    mNumConnections = 0;

    /* Unsubscribe all connections */
    memset(mSubscribedConns, 0, sizeof(mSubscribedConns));

    /* Enable CHIP over BLE service */
    mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;

    /* Suspend BLE Task */
    k_thread_suspend(chipBleThread);

exit:
    return err;
}

int BLEManagerImpl::RxWriteCallback(uint16_t connHandle, void * p)
{
    rf_packet_att_t * packet = (rf_packet_att_t *) p;
    size_t dataLen           = packet->l2capLen - CHIP_RF_PACKET_HEADER_SIZE;
    ChipDeviceEvent event;

    PacketBufferHandle packetBuf = PacketBufferHandle::NewWithData(packet->dat, dataLen);

    // If successful...
    if (packetBuf.IsNull())
    {
        ChipLogError(DeviceLayer, "Failed to allocate buffer");

        return 0;
    }

    // Arrange to post a CHIPoBLERXWriteEvent event to the CHIP queue.
    event.Type                                = DeviceEventType::kPlatformTelinkBleRXWrite;
    event.Platform.BleRXWriteEvent.connHandle = connHandle;
    event.Platform.BleRXWriteEvent.Data       = std::move(packetBuf).UnsafeRelease();

    PlatformMgr().PostEventOrDie(&event);

    return 0;
}

void BLEManagerImpl::ConnectCallback(uint8_t bleEvent, uint8_t * data, int len)
{
    ChipDeviceEvent event;
    ble_sts_t status = BLE_SUCCESS;

    event.Type                             = DeviceEventType::kPlatformTelinkBleConnected;
    event.Platform.BleConnEvent.connHandle = BLS_CONN_HANDLE;
    event.Platform.BleConnEvent.HciResult  = BLE_SUCCESS;

    PlatformMgr().PostEventOrDie(&event);
}

void BLEManagerImpl::DisconnectCallback(uint8_t bleEvent, uint8_t * data, int len)
{
    ChipDeviceEvent event;

    event.Type                             = DeviceEventType::kPlatformTelinkBleDisconnected;
    event.Platform.BleConnEvent.connHandle = BLS_CONN_HANDLE;
    event.Platform.BleConnEvent.HciResult  = *data; // Reason of disconnection stored in first data byte

    PlatformMgr().PostEventOrDie(&event);
}

int BLEManagerImpl::TxCccWriteCallback(uint16_t connHandle, void * p)
{
    ChipDeviceEvent event;
    rf_packet_att_t * packet = (rf_packet_att_t *) p;
    int dataLen              = packet->rf_len - CHIP_RF_PACKET_HEADER_SIZE;
    uint16_t value           = *((uint16_t *) packet->dat);

    event.Type                                 = DeviceEventType::kPlatformTelinkBleCCCWrite;
    event.Platform.BleCCCWriteEvent.connHandle = connHandle;
    event.Platform.BleCCCWriteEvent.Value      = value;

    PlatformMgr().PostEventOrDie(&event);

    return 0;
}

int BLEManagerImpl::GapEventHandler(uint32_t gapEvent, uint8_t * data, int size)
{
    ChipDeviceEvent event;

    if ((gapEvent & 0xFF) == GAP_EVT_GATT_HANDLE_VLAUE_CONFIRM)
    {
        /* Send TX complete event if everything is fine */
        event.Type                                   = DeviceEventType::kPlatformTelinkBleTXComplete;
        event.Platform.BleTXCompleteEvent.connHandle = BLS_CONN_HANDLE;

        PlatformMgr().PostEventOrDie(&event);
    }

    return 0;
}

CHIP_ERROR BLEManagerImpl::_InitStack(void)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    uint8_t macPublic[CHIP_MAC_LEN]       = { 0 };
    uint8_t macRandomStatic[CHIP_MAC_LEN] = { 0 };
    int ret                               = 0;

    if (ConnectivityMgr().IsThreadProvisioned())
    {
        ChipLogProgress(DeviceLayer, "Thread Provisioned. Ignore");

        return CHIP_ERROR_INCORRECT_STATE;
    }

    /* Reset Radio */
    rf_radio_reset();

    /* Reset DMA */
    rf_reset_dma();

    /* Init Radio driver */
    ble_radio_init();

    /* Generate MAC address if it does not exist or read it from flash if it is exist already */
    blc_initMacAddress(CFG_ADR_MAC_1M_FLASH, macPublic, macRandomStatic);

    /* Init interrupts and DMA for BLE module ??? */
    blc_ll_initBasicMCU();

    /* Setup MAC Address */
    blc_ll_initStandby_module(macPublic);

    /* Init advertisement */
    blc_ll_initAdvertising_module();

    /* Init slave role */
    blc_ll_initSlaveRole_module();

    /* Init connection mode */
    blc_ll_initConnection_module();

    /* Init GAP */
    err = _InitGap();
    SuccessOrExit(err);

    /* Resetup stimer interrupt to handle BLE stack */
    ret = irq_connect_dynamic(STIMER_IRQ_NUM, 2, stimer_irq_handler, NULL, 0);
    ChipLogDetail(DeviceLayer, "Stimer IRQ assigned vector %d", ret);

    /* Resetup rf interrupt to handle BLE stack */
    ret = irq_connect_dynamic(RF_IRQ_NUM, 2, rf_irq_handler, NULL, 0);
    ChipLogDetail(DeviceLayer, "RF IRQ assigned vector %d", ret);

exit:

    return err;
}

CHIP_ERROR BLEManagerImpl::_InitGap(void)
{
    ble_sts_t status = BLE_SUCCESS;
    /* Fifo buffers */
    static u8 txFifoBuff[CHIP_BLE_TX_FIFO_SIZE * CHIP_BLE_TX_FIFO_NUM] = { 0 };
    static u8 rxFifoBuff[CHIP_BLE_RX_FIFO_SIZE * CHIP_BLE_RX_FIFO_NUM] = { 0 };

    status = blc_ll_initAclConnTxFifo(txFifoBuff, CHIP_BLE_TX_FIFO_SIZE, CHIP_BLE_TX_FIFO_NUM);
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to init BLE TX FIFO. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    status = blc_ll_initAclConnRxFifo(rxFifoBuff, CHIP_BLE_RX_FIFO_SIZE, CHIP_BLE_RX_FIFO_NUM);
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to init BLE RX FIFO. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    status = blc_controller_check_appBufferInitialization();
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Buffer initialization check failed. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    /* Init GAP */
    blc_gap_peripheral_init();

    /* Set up GATT Services */
    _InitGatt();

    /* L2CAP Initialization */
    blc_l2cap_register_handler((void *) blc_l2cap_packet_receive);

    /* Setup connect/terminate callbacks */
    bls_app_registerEventCallback(BLT_EV_FLAG_CONNECT, BLEManagerImpl::ConnectCallback);
    bls_app_registerEventCallback(BLT_EV_FLAG_TERMINATE, BLEManagerImpl::DisconnectCallback);

    /* Add GAP event handler to handle indication send */
    blc_gap_registerHostEventHandler(BLEManagerImpl::GapEventHandler);
    blc_gap_setEventMask(GAP_EVT_MASK_GATT_HANDLE_VLAUE_CONFIRM);

    /* Set MTU */
    status = blc_att_setRxMtuSize(CHIP_MTU_SIZE);
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to set MTU size. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    return CHIP_NO_ERROR;
}

void BLEManagerImpl::_InitGatt(void)
{
    /* UUIDs */
    static const u16 primaryServiceUUID     = GATT_UUID_PRIMARY_SERVICE;
    static const u16 gapServiceUUID         = SERVICE_UUID_GENERIC_ACCESS;
    static const u16 characterUUID          = GATT_UUID_CHARACTER;
    static const u16 devNameUUID            = GATT_UUID_DEVICE_NAME;
    static const u16 gattServiceUUID        = SERVICE_UUID_GENERIC_ATTRIBUTE;
    static const u16 serviceChangeUUID      = GATT_UUID_SERVICE_CHANGE;
    static const u16 clientCharacterCfgUUID = GATT_UUID_CLIENT_CHAR_CFG;
    static const u16 devServiceUUID         = SERVICE_UUID_DEVICE_INFORMATION;
    static const u16 appearanceUUID         = GATT_UUID_APPEARANCE;
    static const u16 periConnParamUUID      = GATT_UUID_PERI_CONN_PARAM;
    static const u8 MatterRxCharUUID[]      = WRAPPING_BRACES(CHIP_RX_CHAR_UUID);
    static const u8 MatterTxCharUUID[]      = WRAPPING_BRACES(CHIP_TX_CHAR_UUID);

    /* Characteristics */
    static const u8 devNameCharVal[] = { CHAR_PROP_READ | CHAR_PROP_NOTIFY, U16_LO(GenericAccess_DeviceName_DP_H),
                                         U16_HI(GenericAccess_DeviceName_DP_H), U16_LO(GATT_UUID_DEVICE_NAME),
                                         U16_HI(GATT_UUID_DEVICE_NAME) };

    static const u8 appearanceCharVal[] = { CHAR_PROP_READ, U16_LO(GenericAccess_Appearance_DP_H),
                                            U16_HI(GenericAccess_Appearance_DP_H), U16_LO(GATT_UUID_APPEARANCE),
                                            U16_HI(GATT_UUID_APPEARANCE) };

    static const u8 periConnParamCharVal[] = { CHAR_PROP_READ, U16_LO(CONN_PARAM_DP_H), U16_HI(CONN_PARAM_DP_H),
                                               U16_LO(GATT_UUID_PERI_CONN_PARAM), U16_HI(GATT_UUID_PERI_CONN_PARAM) };

    static const u8 serviceChangeCharVal[] = { CHAR_PROP_INDICATE, U16_LO(GenericAttribute_ServiceChanged_DP_H),
                                               U16_HI(GenericAttribute_ServiceChanged_DP_H), U16_LO(GATT_UUID_SERVICE_CHANGE),
                                               U16_HI(GATT_UUID_SERVICE_CHANGE) };

    static const u8 MatterRxCharVal[] = { CHAR_PROP_WRITE | CHAR_PROP_WRITE_WITHOUT_RSP, U16_LO(Matter_RX_DP_H),
                                          U16_HI(Matter_RX_DP_H), CHIP_RX_CHAR_UUID };

    static const u8 MatterTxCharVal[] = { CHAR_PROP_INDICATE, U16_LO(Matter_TX_DP_H), U16_HI(Matter_TX_DP_H), CHIP_TX_CHAR_UUID };

    /* Values */
    static const u16 appearance                             = GAP_APPEARE_UNKNOWN;
    static const gap_periConnectParams_t periConnParameters = { 8, 11, 0, 1000 };
    static u16 serviceChangeVal[2]                          = { 0 };
    static u8 serviceChangeCCC[2]                           = { 0 };
    static u8 matterTxCCC[2]                                = { 0 };

    static const attribute_t gattTable[] = {
        /* Total number of attributes */
        { ATT_END_H - 1, 0, 0, 0, 0, 0 },

        /* 0001 - 0007  GAP service */
        { 7, ATT_PERMISSIONS_READ, 2, 2, (u8 *) (&primaryServiceUUID), (u8 *) (&gapServiceUUID), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(devNameCharVal), (u8 *) (&characterUUID), (u8 *) (devNameCharVal), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, (u32) kMaxDeviceNameLength, (u8 *) (&devNameUUID), (u8 *) (mDeviceName), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(appearanceCharVal), (u8 *) (&characterUUID), (u8 *) (appearanceCharVal), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(appearance), (u8 *) (&appearanceUUID), (u8 *) (&appearance), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(periConnParamCharVal), (u8 *) (&characterUUID), (u8 *) (periConnParamCharVal), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(periConnParameters), (u8 *) (&periConnParamUUID), (u8 *) (&periConnParameters), 0 },

        /* 0008 - 000b GATT */
        { 4, ATT_PERMISSIONS_READ, 2, 2, (u8 *) (&primaryServiceUUID), (u8 *) (&gattServiceUUID), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(serviceChangeCharVal), (u8 *) (&characterUUID), (u8 *) (serviceChangeCharVal), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(serviceChangeVal), (u8 *) (&serviceChangeUUID), (u8 *) (&serviceChangeVal), 0 },
        { 0, ATT_PERMISSIONS_RDWR, 2, sizeof(serviceChangeCCC), (u8 *) (&clientCharacterCfgUUID), (u8 *) (serviceChangeCCC), 0 },

        /* 000c - 0011 Matter service */
        { 6, ATT_PERMISSIONS_READ, 2, 2, (u8 *) (&primaryServiceUUID), (u8 *) (&matterServiceUUID), 0 },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(MatterRxCharVal), (u8 *) (&characterUUID), (u8 *) (MatterRxCharVal), 0 },
        { 0, ATT_PERMISSIONS_RDWR, 16, sizeof(mRxDataBuff), (u8 *) (&MatterRxCharUUID), mRxDataBuff, RxWriteCallback, NULL },
        { 0, ATT_PERMISSIONS_READ, 2, sizeof(MatterTxCharVal), (u8 *) (&characterUUID), (u8 *) (MatterTxCharVal), 0 },
        { 0, ATT_PERMISSIONS_RDWR, 16, sizeof(mTxDataBuff), (u8 *) (&MatterTxCharUUID), mTxDataBuff, 0 },
        { 0, ATT_PERMISSIONS_RDWR, 2, sizeof(matterTxCCC), (u8 *) (&clientCharacterCfgUUID), (u8 *) (matterTxCCC),
          TxCccWriteCallback, NULL }
    };

    bls_att_setAttributeTable((u8 *) gattTable);
}

CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
{
    ble_sts_t status   = BLE_SUCCESS;
    CHIP_ERROR err     = CHIP_NO_ERROR;
    uint8_t index      = 0;
    uint8_t devNameLen = 0;
    ChipBLEDeviceIdentificationInfo deviceIdInfo;
    u8 adv[CHIP_MAX_ADV_DATA_LEN]       = { 0 };
    u8 srsp[CHIP_MAX_RESPONSE_DATA_LEN] = { 0 };

    ChipLogProgress(DeviceLayer, "BLEManagerImpl::ConfigureAdvertisingData");

    /* Get BLE device identification info */
    err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo);
    SuccessOrExit(err);

    /* Check device name */
    if (!mFlags.Has(Flags::kDeviceNameSet))
    {
        err = _SetDeviceName("TelinkMatter");
        SuccessOrExit(err);
    }

    /* Fulfill BLE advertisement data */
    /* Set flags */
    adv[index++] = CHIP_ADE_DATA_LEN_FLAGS;
    adv[index++] = CHIP_ADV_DATA_TYPE_FLAGS;
    adv[index++] = CHIP_ADV_DATA_FLAGS;

    /* Set Service Data */
    adv[index++] = CHIP_ADV_SERVICE_DATA_LEN;
    adv[index++] = CHIP_ADV_DATA_TYPE_SERVICE_DATA;
    adv[index++] = matterServiceUUID[0];
    adv[index++] = matterServiceUUID[1];
    memcpy(&adv[index], (void *) &deviceIdInfo, sizeof(deviceIdInfo));
    index += sizeof(deviceIdInfo);

    /* Set device name */
    devNameLen   = strlen(mDeviceName);
    adv[index++] = devNameLen + 1;
    adv[index++] = CHIP_ADV_DATA_TYPE_NAME;
    memcpy(&adv[index], mDeviceName, devNameLen);
    index += devNameLen;

    /* Set advetisment data */
    status = bls_ll_setAdvData(adv, index);
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to set BLE advertisement data. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    index         = 0;
    srsp[index++] = CHIP_SHORT_UUID_LEN + 1;
    srsp[index++] = CHIP_ADV_DATA_TYPE_UUID;
    srsp[index++] = matterServiceUUID[0];
    srsp[index++] = matterServiceUUID[1];

    /* Set scan response data */
    status = bls_ll_setScanRspData(srsp, sizeof(srsp));
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to set BLE scan response data. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

exit:
    return err;
}

CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    if (val)
    {
        err = StartAdvertising();
    }
    else
    {
        err = StopAdvertising();
    }

    return err;
}

CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
{
    CHIP_ERROR err   = CHIP_NO_ERROR;
    ble_sts_t status = BLE_SUCCESS;

    /* At first run always select fast advertising, on the next attempt slow down interval. */
    u16 intervalMin = mFlags.Has(Flags::kFastAdvertisingEnabled) ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN
                                                                 : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN;
    u16 intervalMax = mFlags.Has(Flags::kFastAdvertisingEnabled) ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX
                                                                 : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;

    if (ConnectivityMgr().IsThreadProvisioned())
    {
        ChipLogProgress(DeviceLayer, "Thread provisioned. Start advertisement not possible");

        return CHIP_ERROR_INCORRECT_STATE;
    }

    /* Block IEEE802154 */
    /* @todo: move to RadioSwitch module*/
    const struct device * radio_dev = device_get_binding(CONFIG_NET_CONFIG_IEEE802154_DEV_NAME);
    __ASSERT(radio_dev != NULL, "Fail to get radio device");
    b91_ieee802154_deinit(radio_dev);

    /* It is time to init BLE stack */
    err = _InitStack();
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "Fail to init BLE stack");

        return err;
    }

    /* Configure CHIP BLE advertisement data */
    err = ConfigureAdvertisingData();
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "Fail to config BLE advertisement data");

        return err;
    }

    /* Setup advertisement parameters */
    status = bls_ll_setAdvParam(intervalMin, intervalMax, ADV_TYPE_CONNECTABLE_UNDIRECTED, OWN_ADDRESS_PUBLIC, 0, NULL,
                                BLT_ENABLE_ADV_ALL, ADV_FP_NONE);
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to set BLE advertisement parameters. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    /* Enable advertisement */
    status = bls_ll_setAdvEnable(BLC_ADV_ENABLE);
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to start BLE advertisement. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    mFlags.Set(Flags::kAdvertising);

    /* Start BLE Task */
    k_thread_resume(chipBleThread);

    return err;
}

CHIP_ERROR BLEManagerImpl::StopAdvertising(void)
{
    ble_sts_t status = BLE_SUCCESS;

    if (ConnectivityMgr().IsThreadProvisioned())
    {
        ChipLogProgress(DeviceLayer, "Thread provisioned. Advertisement already stopped at this stage");

        return CHIP_NO_ERROR;
    }

    /* Disable advertisement */
    status = bls_ll_setAdvEnable(BLC_ADV_DISABLE);
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to stop BLE advertisement. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    mFlags.Clear(Flags::kAdvertising);

    return CHIP_NO_ERROR;
}

/// @todo: implementation
CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode)
{
    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize)
{
    if (strlen(mDeviceName) >= bufSize)
    {
        return CHIP_ERROR_BUFFER_TOO_SMALL;
    }
    strcpy(buf, mDeviceName);

    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * devName)
{

    if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported)
    {
        ChipLogError(DeviceLayer, "Unsupported");

        return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
    }

    if (devName == NULL && devName[0] == 0)
    {
        ChipLogError(DeviceLayer, "Invalid name");

        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    if (strlen(devName) >= kMaxDeviceNameLength)
    {
        ChipLogError(DeviceLayer, "BLE device name is to long");

        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    strcpy(mDeviceName, devName);
    mFlags.Set(Flags::kDeviceNameSet);

    ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", devName);

    return CHIP_NO_ERROR;
}

void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    switch (event->Type)
    {
    case DeviceEventType::kPlatformTelinkBleConnected:
        err = HandleGAPConnect(event);
        break;

    case DeviceEventType::kPlatformTelinkBleDisconnected:
        err = HandleGAPDisconnect(event);
        break;

    case DeviceEventType::kPlatformTelinkBleDisconnectRequest:
        err = HandleDisconnectRequest(event);
        break;

    case DeviceEventType::kPlatformTelinkBleRXWrite:
        err = HandleRXCharWrite(event);
        break;

    case DeviceEventType::kPlatformTelinkBleCCCWrite:
        err = HandleTXCharCCCDWrite(event);
        break;

    case DeviceEventType::kPlatformTelinkBleTXComplete:
        err = HandleTXCharComplete(event);
        break;

    case DeviceEventType::kThreadStateChange:
        err = HandleThreadStateChange(event);
        break;

    case DeviceEventType::kCHIPoBLEConnectionClosed:
        err = HandleBleConnectionClosed(event);
        break;

    case DeviceEventType::kOperationalNetworkEnabled:
        err = HandleOperationalNetworkEnabled(event);
        break;

    default:
        ChipLogDetail(DeviceLayer, "Event: Unknown (0x%04x)", event->Type);
    }

    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "Fail to handle 0x%04x event. Error: %s", event->Type, ErrorStr(err));
    }
}

bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
{
    return false;
}

bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
{
    return false;
}

bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId)
{
    return false;
}

uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const
{
    return blc_att_getEffectiveMtuSize(conId);
}

bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
                                    PacketBufferHandle pBuf)
{
    ble_sts_t status = BLE_SUCCESS;

    do
    {
        if (status != BLE_SUCCESS)
        {
            k_msleep(1);
        }
        status = blc_gatt_pushHandleValueIndicate(conId, Matter_TX_DP_H, pBuf->Start(), pBuf->DataLength());
    } while (status == GATT_ERR_DATA_PENDING_DUE_TO_SERVICE_DISCOVERY_BUSY);
    if (status != BLE_SUCCESS)
    {
        ChipLogError(DeviceLayer, "Fail to send indication. Error %d", status);

        return false;
    }

    return true;
}

bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
                                      PacketBufferHandle pBuf)
{
    ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported");
    return false;
}

bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
                                     PacketBufferHandle pBuf)
{
    ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported");
    return false;
}

bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext,
                                      const ChipBleUUID * svcId, const ChipBleUUID * charId)
{
    ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported");
    return false;
}

/* @todo: move to RadioSwitch module */
void BLEManagerImpl::SwitchToIeee802154(void)
{
    int result = 0;

    ChipLogProgress(DeviceLayer, "BLEManagerImpl::Switch to IEEE802154");

    /* Stop BLE */
    StopAdvertising();

    /* Stop BLE task */
    k_thread_suspend(chipBleThread);

    /* Reset Radio */
    rf_radio_reset();

    /* Reset DMA */
    rf_reset_dma();

    const struct device * radio_dev = device_get_binding(CONFIG_NET_CONFIG_IEEE802154_DEV_NAME);
    __ASSERT(radio_dev != NULL, "Fail to get radio device");

    /* Init IEEE802154 */
    result = b91_ieee802154_init(radio_dev);
    __ASSERT(result == 0, "Fail to init IEEE802154 radio. Error: %d", result);
}

void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) {}

uint16_t BLEManagerImpl::_NumConnections(void)
{
    return mNumConnections;
}

/// @todo implement multicinnection subscription
CHIP_ERROR BLEManagerImpl::SetSubscribed(uint16_t conId)
{

    mSubscribedConns[0] = true;

    return CHIP_NO_ERROR;
}

/// @todo implement multicinnection subscription
bool BLEManagerImpl::UnsetSubscribed(uint16_t conId)
{

    mSubscribedConns[0] = false;

    return true;
}

/// @todo implement multicinnection subscription
bool BLEManagerImpl::IsSubscribed(uint16_t conId)
{
    return mSubscribedConns[0];
}

CHIP_ERROR BLEManagerImpl::HandleGAPConnect(const ChipDeviceEvent * event)
{
    const BleConnEventType * connEvent = &event->Platform.BleConnEvent;

    /* Increase number of connections */
    mNumConnections++;

    ChipLogProgress(DeviceLayer, "BLE connection established (ConnId: 0x%02x)", connEvent->connHandle);
    ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", NumConnections(), kMaxConnections);

    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event)
{
    const BleConnEventType * connEvent = &event->Platform.BleConnEvent;
    ChipDeviceEvent disconnectEvent;

    /* Decrease number of connections */
    mNumConnections--;

    ChipLogProgress(DeviceLayer, "BLE GAP connection terminated (reason 0x%02x)", connEvent->HciResult);
    ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", NumConnections(), kMaxConnections);

    /* Unsubscribe */
    if (UnsetSubscribed(connEvent->connHandle))
    {
        HandleUnsubscribeReceived(connEvent->connHandle, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
    }

    /* Send Connection close event */
    disconnectEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed;
    ReturnErrorOnFailure(PlatformMgr().PostEvent(&disconnectEvent));

    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::HandleDisconnectRequest(const ChipDeviceEvent * event)
{
    ble_sts_t status = BLE_SUCCESS;
    uint16_t handle  = event->Platform.BleConnEvent.connHandle;
    uint8_t reason   = event->Platform.BleConnEvent.HciResult;

    ChipLogDetail(DeviceLayer, "HandleDisconnectRequest");

    /* Trigger disconnect. DisconnectCallback call occures on completion */
    status = blc_ll_disconnect(handle, reason);
    if (status != BLE_SUCCESS && status != LL_ERR_CONNECTION_NOT_ESTABLISH)
    {
        ChipLogError(DeviceLayer, "Fail to disconnect. Error %d", status);

        return CHIP_ERROR_INCORRECT_STATE;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::HandleOperationalNetworkEnabled(const ChipDeviceEvent * event)
{
    ChipDeviceEvent disconnectEvent;

    ChipLogDetail(DeviceLayer, "HandleOperationalNetworkEnabled");

    disconnectEvent.Type                             = DeviceEventType::kPlatformTelinkBleDisconnectRequest;
    disconnectEvent.Platform.BleConnEvent.connHandle = BLS_CONN_HANDLE;
    disconnectEvent.Platform.BleConnEvent.HciResult  = CHIP_BLE_DISCONNECT_REASON;
    ReturnErrorOnFailure(PlatformMgr().PostEvent(&disconnectEvent));

    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::HandleThreadStateChange(const ChipDeviceEvent * event)
{
    CHIP_ERROR error = CHIP_NO_ERROR;

    ChipLogDetail(DeviceLayer, "HandleThreadStateChange");

    if (event->Type == DeviceEventType::kThreadStateChange && event->ThreadStateChange.RoleChanged)
    {
        ChipDeviceEvent attachEvent;
        attachEvent.Type                            = DeviceEventType::kThreadConnectivityChange;
        attachEvent.ThreadConnectivityChange.Result = kConnectivity_Established;

        error = PlatformMgr().PostEvent(&attachEvent);
        VerifyOrExit(error == CHIP_NO_ERROR,
                     ChipLogError(DeviceLayer, "Failed to post Thread connectivity change: %" CHIP_ERROR_FORMAT, error.Format()));

        ChipLogDetail(DeviceLayer, "Thread Connectivity Ready");
        ThreadConnectivityReady = true;
    }

exit:
    return error;
}

CHIP_ERROR BLEManagerImpl::HandleBleConnectionClosed(const ChipDeviceEvent * event)
{
    /* It is time to swich to IEEE802154 radio if it is provisioned */
    if (ThreadConnectivityReady)
    {
        SwitchToIeee802154();
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::HandleRXCharWrite(const ChipDeviceEvent * event)
{
    const BleRXWriteEventType * writeEvent = &event->Platform.BleRXWriteEvent;

    ChipLogDetail(DeviceLayer, "Write request received for CHIPoBLE RX (ConnId 0x%02x)", writeEvent->connHandle);

    HandleWriteReceived(writeEvent->connHandle, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX,
                        PacketBufferHandle::Adopt(writeEvent->Data));

    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::HandleTXCharComplete(const ChipDeviceEvent * event)
{
    const BleTXCompleteEventType * completeEvent = &event->Platform.BleTXCompleteEvent;

    ChipLogDetail(DeviceLayer, "Notification for CHIPoBLE TX done (ConnId 0x%02x)", completeEvent->connHandle);

    // Signal the BLE Layer that the outstanding notification is complete.
    HandleIndicationConfirmation(completeEvent->connHandle, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);

    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerImpl::HandleTXCharCCCDWrite(const ChipDeviceEvent * event)
{
    const BleCCCWriteEventType * writeEvent = &event->Platform.BleCCCWriteEvent;

    ChipLogDetail(DeviceLayer, "ConnId: 0x%02x, New CCCD value: 0x%04x", writeEvent->connHandle, writeEvent->Value);

    /* If the client has requested to enable notifications and if it is not yet subscribed */
    if (writeEvent->Value != 0 && SetSubscribed(writeEvent->connHandle) == CHIP_NO_ERROR)
    {
        /* Alert the BLE layer that CHIPoBLE "subscribe" has been received and increment the bt_conn reference counter. */
        HandleSubscribeReceived(writeEvent->connHandle, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);

        ChipLogProgress(DeviceLayer, "CHIPoBLE connection established (ConnId: 0x%02x, GATT MTU: %d)", writeEvent->connHandle,
                        GetMTU(writeEvent->connHandle));

        /* Post a CHIPoBLEConnectionEstablished event to the DeviceLayer and the application. */
        {
            ChipDeviceEvent conEstEvent;
            conEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
            ReturnErrorOnFailure(PlatformMgr().PostEvent(&conEstEvent));
        }
    }
    else
    {
        if (UnsetSubscribed(writeEvent->connHandle))
        {
            HandleUnsubscribeReceived(writeEvent->connHandle, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
        }
    }

    return CHIP_NO_ERROR;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip

#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
