/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2020 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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 K32W platforms.
 */

/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <platform/CommissionableDataProvider.h>

#include <crypto/CHIPCryptoPAL.h>

#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE

#include <ble/Ble.h>

#include "board.h"
#include "gatt_db_app_interface.h"
#include "gatt_db_handles.h"
#include "stdio.h"
#include "timers.h"

#if defined(CPU_JN518X) && defined(chip_with_low_power) && (chip_with_low_power == 1)
#include "PWR_Configuration.h"
#endif

#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
#include <platform/DeviceInstanceInfoProvider.h>
#include <setup_payload/AdditionalDataPayloadGenerator.h>
#endif

/*******************************************************************************
 * Local data types
 *******************************************************************************/
extern "C" bool_t Ble_ConfigureHostStackConfig(void);

#if defined(chip_with_low_power) && (chip_with_low_power == 1)
extern "C" void PWR_DisallowDeviceToSleep(void);
extern "C" void PWR_AllowDeviceToSleep(void);
#endif

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

namespace chip {
namespace DeviceLayer {
namespace Internal {

namespace {
/*******************************************************************************
 * Macros & Constants definitions
 *******************************************************************************/
/* Timeout of BLE commands */
#define CHIP_BLE_KW_EVNT_TIMEOUT 1000 / portTICK_PERIOD_MS

/** BLE advertisement state changed */
#define CHIP_BLE_KW_EVNT_ADV_CHANGED 0x0001
/** BLE advertisement command failed */
#define CHIP_BLE_KW_EVNT_ADV_FAILED 0x0002
/** BLE advertisement setup failed */
#define CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED 0x0004
/** BLE advertisement parameters setup complete */
#define CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE 0x0008
/** BLE advertisement data setup complete */
#define CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE 0x0010
/** BLE random address set */
#define CHIP_BLE_KW_EVNT_RND_ADDR_SET 0x0020
/** BLE Initialization complete */
#define CHIP_BLE_KW_EVNT_INIT_COMPLETE 0x0040
/** BLE Received a handle value confirmation from the client */
#define CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED 0x0080
/** BLE send indication failed */
#define CHIP_BLE_KW_EVNT_INDICATION_FAILED 0x0100
/** TX Power Level Set */
#define CHIP_BLE_KW_EVNT_POWER_LEVEL_SET 0x0200
/** Maximal time of connection without activity */
#define CHIP_BLE_KW_CONN_TIMEOUT 60000
/** Maximum number of pending BLE events */
#define CHIP_BLE_EVENT_QUEUE_MAX_ENTRIES 10

#define LOOP_EV_BLE (0x08)

/* controller task configuration */
#define CONTROLLER_TASK_PRIORITY (6U)
#define CONTROLLER_TASK_STACK_SIZE (gControllerTaskStackSize_c / sizeof(StackType_t))

/* host task configuration */
#define HOST_TASK_PRIORITY (4U)
#define HOST_TASK_STACK_SIZE (gHost_TaskStackSize_c / sizeof(StackType_t))

/* advertising configuration */
#define BLEKW_ADV_MAX_NO (2)
#define BLEKW_SCAN_RSP_MAX_NO (2)
#define BLEKW_MAX_ADV_DATA_LEN (31)
#define CHIP_ADV_SHORT_UUID_LEN (2)

/* FreeRTOS sw timer */
TimerHandle_t sbleAdvTimeoutTimer;

/* Queue used to synchronize asynchronous messages from the KW BLE tasks */
QueueHandle_t sBleEventQueue;

/* Used to manage asynchronous events from BLE Stack: e.g.: GAP setup finished */
EventGroupHandle_t sEventGroup;

TimerHandle_t connectionTimeout;

const uint8_t ShortUUID_CHIPoBLEService[]  = { 0xF6, 0xFF };
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 } };

#if defined(chip_with_low_power) && (chip_with_low_power == 1)
static bool bleAppStopInProgress;
#endif

BLEManagerCommon * sImplInstance = nullptr;

} // namespace

CHIP_ERROR BLEManagerCommon::_Init()
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    EventBits_t eventBits;
    uint16_t attChipRxHandle[1] = { (uint16_t) value_chipoble_rx };

#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
    uint16_t attChipC3Handle[1] = { (uint16_t) value_chipoble_c3 };
#endif

    mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;

    // Check if BLE stack is initialized
    VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);

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

    /* Initialization of message wait events -
     * used for receiving BLE Stack events */
    sEventGroup = xEventGroupCreate();
    VerifyOrExit(sEventGroup != NULL, err = CHIP_ERROR_INCORRECT_STATE);

    /* Prepare callback input queue.*/
    sBleEventQueue = xQueueCreate(CHIP_BLE_EVENT_QUEUE_MAX_ENTRIES, sizeof(blekw_msg_t *));
    VerifyOrExit(sBleEventQueue != NULL, err = CHIP_ERROR_INCORRECT_STATE);

    /* Create the connection timeout timer. */
    connectionTimeout =
        xTimerCreate("bleTimeoutTmr", pdMS_TO_TICKS(CHIP_BLE_KW_CONN_TIMEOUT), pdFALSE, (void *) 0, blekw_connection_timeout_cb);
    VerifyOrExit(connectionTimeout != NULL, err = CHIP_ERROR_INCORRECT_STATE);

    sImplInstance = GetImplInstance();

    /* BLE platform code initialization */
    SuccessOrExit(err = InitHostController(&blekw_generic_cb));

    /* Register the GATT server callback */
    VerifyOrExit(GattServer_RegisterCallback(blekw_gatt_server_cb) == gBleSuccess_c, err = CHIP_ERROR_INCORRECT_STATE);

    /* Wait until BLE Stack is ready */
    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_INIT_COMPLETE, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT);
    VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_INIT_COMPLETE, err = CHIP_ERROR_INCORRECT_STATE);

#if BLE_HIGH_TX_POWER
    /* Set Adv Power */
    Gap_SetTxPowerLevel(gAdvertisingPowerLeveldBm_c, gTxPowerAdvChannel_c);
    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT);
    VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, err = CHIP_ERROR_INCORRECT_STATE);

    /* Set Connect Power */
    Gap_SetTxPowerLevel(gConnectPowerLeveldBm_c, gTxPowerConnChannel_c);
    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT);
    VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, err = CHIP_ERROR_INCORRECT_STATE);
#endif

#if defined(CPU_JN518X) && defined(chip_with_low_power) && (chip_with_low_power == 1)
    PWR_ChangeDeepSleepMode(cPWR_PowerDown_RamRet);
#endif

    GattServer_RegisterHandlesForWriteNotifications(1, attChipRxHandle);
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
    VerifyOrExit(GattServer_RegisterHandlesForReadNotifications(1, attChipC3Handle) == gBleSuccess_c,
                 err = CHIP_ERROR_INCORRECT_STATE);
#endif

    mFlags.Set(Flags::kK32WBLEStackInitialized);
    mFlags.Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? true : false);
    mFlags.Set(Flags::kFastAdvertisingEnabled);

    // Create FreeRTOS sw timer for BLE timeouts and interval change.
    sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer",       // Just a text name, not used by the RTOS kernel
                                       pdMS_TO_TICKS(100),  // == default timer period (mS)
                                       false,               // no timer reload (==one-shot)
                                       (void *) this,       // init timer id = ble obj context
                                       BleAdvTimeoutHandler // timer callback handler
    );
    VerifyOrExit(sbleAdvTimeoutTimer != NULL, err = CHIP_ERROR_INCORRECT_STATE);

exit:
    return err;
}

uint16_t BLEManagerCommon::_NumConnections(void)
{
    return static_cast<uint16_t>(mDeviceConnected == true);
}

bool BLEManagerCommon::_IsAdvertisingEnabled(void)
{
    return mFlags.Has(Flags::kAdvertisingEnabled);
}

bool BLEManagerCommon::_IsAdvertising(void)
{
    return mFlags.Has(Flags::kAdvertising);
}

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

    VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);

    if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
    {
        mFlags.Set(Flags::kAdvertisingEnabled, val);
        PlatformMgr().ScheduleWork(DriveBLEState, 0);
    }

exit:
    return err;
}

CHIP_ERROR BLEManagerCommon::_SetAdvertisingMode(BLEAdvertisingMode mode)
{
    switch (mode)
    {
    case BLEAdvertisingMode::kFastAdvertising:
        mFlags.Set(Flags::kFastAdvertisingEnabled);
        break;
    case BLEAdvertisingMode::kSlowAdvertising: {
        // We are in FreeRTOS timer service context, which is a default daemon task and has
        // the highest priority. Stop advertising should be scheduled to run from Matter task.
        mFlags.Clear(Flags::kFastAdvertisingEnabled);
        PlatformMgr().ScheduleWork(StopAdvertisingPriorToSwitchingMode, 0);
        break;
    }
    default:
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    mFlags.Set(Flags::kRestartAdvertising);
    PlatformMgr().ScheduleWork(DriveBLEState, 0);
    return CHIP_NO_ERROR;
}

CHIP_ERROR BLEManagerCommon::_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 BLEManagerCommon::_SetDeviceName(const char * deviceName)
{
    if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported)
    {
        return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
    }
    if (deviceName != NULL && deviceName[0] != 0)
    {
        if (strlen(deviceName) >= kMaxDeviceNameLength)
        {
            return CHIP_ERROR_INVALID_ARGUMENT;
        }
        memset(mDeviceName, 0, kMaxDeviceNameLength);
        strcpy(mDeviceName, deviceName);
        mFlags.Set(Flags::kDeviceNameSet);
        ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", deviceName);
    }
    else
    {
        mDeviceName[0] = 0;
        mFlags.Clear(Flags::kDeviceNameSet);
    }

    return CHIP_NO_ERROR;
}

void BLEManagerCommon::_OnPlatformEvent(const ChipDeviceEvent * event)
{
    switch (event->Type)
    {
    case DeviceEventType::kCHIPoBLESubscribe:
        ChipDeviceEvent connEstEvent;

        HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
        connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
        PlatformMgr().PostEventOrDie(&connEstEvent);
        break;

    case DeviceEventType::kCHIPoBLEUnsubscribe:
        HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
        break;

    case DeviceEventType::kCHIPoBLEWriteReceived:
        HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX,
                            PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data));
        break;

    case DeviceEventType::kCHIPoBLEConnectionError:
        HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason);
        break;

    case DeviceEventType::kCHIPoBLEIndicateConfirm:
        HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
        break;

    default:
        break;
    }
}

bool BLEManagerCommon::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
{
    ChipLogProgress(DeviceLayer, "BLEManagerCommon::SubscribeCharacteristic() not supported");
    return false;
}

bool BLEManagerCommon::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
{
    ChipLogProgress(DeviceLayer, "BLEManagerCommon::UnsubscribeCharacteristic() not supported");
    return false;
}

bool BLEManagerCommon::CloseConnection(BLE_CONNECTION_OBJECT conId)
{
    return blekw_stop_connection_internal(conId);
}

uint16_t BLEManagerCommon::GetMTU(BLE_CONNECTION_OBJECT conId) const
{
    uint16_t tempMtu = 0;
    (void) Gatt_GetMtu(conId, &tempMtu);

    return tempMtu;
}

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

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

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

void BLEManagerCommon::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId)
{
    BLEMgrImpl().CloseConnection(conId);
}

bool BLEManagerCommon::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
                                      PacketBufferHandle data)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    uint16_t cId   = (UUIDsMatch(&ChipUUID_CHIPoBLEChar_TX, charId) ? value_chipoble_tx : 0);
    ChipDeviceEvent event;

    if (cId != 0)
    {
        if (blekw_send_event(conId, cId, data->Start(), data->DataLength()) != BLE_OK)
        {
            err = CHIP_ERROR_SENDING_BLOCKED;
        }
        else
        {
            event.Type                          = DeviceEventType::kCHIPoBLEIndicateConfirm;
            event.CHIPoBLEIndicateConfirm.ConId = conId;
            err                                 = PlatformMgr().PostEvent(&event);
        }

        if (err != CHIP_NO_ERROR)
        {
            ChipLogError(DeviceLayer, "BLEManagerCommon::SendIndication() failed: %s", ErrorStr(err));
            return false;
        }
        return true;
    }
    return false;
}

BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_send_event(int8_t connection_handle, uint16_t handle, uint8_t * data,
                                                               uint32_t len)
{
    EventBits_t eventBits;

#if CHIP_DEVICE_CHIP0BLE_DEBUG
    ChipLogProgress(DeviceLayer, "Trying to send event.");
#endif

    if (connection_handle < 0 || handle <= 0)
    {
        ChipLogProgress(DeviceLayer, "BLE Event - Bad Handle");
        return BLE_E_FAIL;
    }

    if (len > 0 && data == NULL)
    {
        ChipLogProgress(DeviceLayer, "BLE Event - Invalid Data");
        return BLE_E_FAIL;
    }

    /************* Send the indication *************/
    xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED);

    if (GattServer_SendInstantValueIndication(connection_handle, handle, len, data) != gBleSuccess_c)
    {
        ChipLogProgress(DeviceLayer, "BLE Event - Can't sent indication");
        return BLE_E_FAIL;
    }

    /* Wait until BLE Stack is ready */
    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED, pdTRUE,
                                    pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT);

    if (eventBits & CHIP_BLE_KW_EVNT_INDICATION_FAILED)
    {
        ChipLogProgress(DeviceLayer, "BLE Event - Sent Failed");
        return BLE_E_FAIL;
    }

#if CHIP_DEVICE_CHIP0BLE_DEBUG
    ChipLogProgress(DeviceLayer, "BLE Event - Sent :-) ");
#endif

    return BLE_OK;
}
/*******************************************************************************
 * Private functions
 *******************************************************************************/

BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_start_advertising(gapAdvertisingParameters_t * adv_params,
                                                                      gapAdvertisingData_t * adv, gapScanResponseData_t * scnrsp)
{
    EventBits_t eventBits;

    /************* Set the advertising parameters *************/
    xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE);

    /* Set the advertising parameters */
    if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c)
    {
        vTaskDelay(1);

        /* Retry, just to make sure before giving up and sending an error. */
        if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c)
        {
            return BLE_E_SET_ADV_PARAMS;
        }
    }

    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE,
                                    pdTRUE, pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT);

    if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE))
    {
        return BLE_E_ADV_PARAMS_FAILED;
    }

    /************* Set the advertising data *************/
    xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE);

    /* Set the advertising data */
    if (Gap_SetAdvertisingData(adv, scnrsp) != gBleSuccess_c)
    {
        return BLE_E_SET_ADV_DATA;
    }

    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE,
                                    pdTRUE, pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT);

    if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE))
    {
        return BLE_E_ADV_SETUP_FAILED;
    }

    /************* Start the advertising *************/
    xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED);

    if (gBleSuccess_c != Gap_CreateRandomDeviceAddress(NULL, NULL))
    {
        return BLE_E_SET_ADV_PARAMS;
    }

    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_RND_ADDR_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT);

    if (!(eventBits & CHIP_BLE_KW_EVNT_RND_ADDR_SET))
    {
        return BLE_E_ADV_PARAMS_FAILED;
    }

    /* Start the advertising */
    if (Gap_StartAdvertising(blekw_gap_advertising_cb, blekw_gap_connection_cb) != gBleSuccess_c)
    {
        return BLE_E_START_ADV;
    }

#if defined(chip_with_low_power) && (chip_with_low_power == 1)
    PWR_DisallowDeviceToSleep();
#endif

    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED, pdTRUE, pdFALSE,
                                    CHIP_BLE_KW_EVNT_TIMEOUT);
    if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_CHANGED))
    {
#if defined(chip_with_low_power) && (chip_with_low_power == 1)
        PWR_AllowDeviceToSleep();
#endif
        return BLE_E_START_ADV_FAILED;
    }

#if defined(chip_with_low_power) && (chip_with_low_power == 1)
    PWR_AllowDeviceToSleep();
#endif

    return BLE_OK;
}

BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_stop_advertising(void)
{
    EventBits_t eventBits;
    bleResult_t res;

    xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED);

    /* Stop the advertising data */
    res = Gap_StopAdvertising();
    if (res != gBleSuccess_c)
    {
        ChipLogProgress(DeviceLayer, "Failed to stop advertising %d", res);
        return BLE_E_STOP;
    }

    eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED, pdTRUE, pdFALSE,
                                    CHIP_BLE_KW_EVNT_TIMEOUT);

    if (eventBits & CHIP_BLE_KW_EVNT_ADV_FAILED)
    {
        ChipLogProgress(DeviceLayer, "Stop advertising flat out failed.");
        return BLE_E_ADV_FAILED;
    }
    else if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_CHANGED))
    {
        ChipLogProgress(DeviceLayer, "Stop advertising event timeout.");
        return BLE_E_ADV_CHANGED;
    }

    return BLE_OK;
}

CHIP_ERROR BLEManagerCommon::ConfigureAdvertisingData(void)
{
    ble_err_t err;
    CHIP_ERROR chipErr;
    uint16_t discriminator;
    uint16_t advInterval                                  = 0;
    gapAdvertisingData_t adv                              = { 0 };
    gapAdStructure_t adv_data[BLEKW_ADV_MAX_NO]           = { { 0 } };
    gapAdStructure_t scan_rsp_data[BLEKW_SCAN_RSP_MAX_NO] = { { 0 } };
    uint8_t advPayload[BLEKW_MAX_ADV_DATA_LEN]            = { 0 };
    gapScanResponseData_t scanRsp                         = { 0 };
    gapAdvertisingParameters_t adv_params                 = { 0 };
    uint8_t chipAdvDataFlags                              = (gLeGeneralDiscoverableMode_c | gBrEdrNotSupported_c);
    uint8_t chipOverBleService[2];
    ChipBLEDeviceIdentificationInfo mDeviceIdInfo = { 0 };
    uint8_t mDeviceIdInfoLength                   = 0;

    chipErr = GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator);
    if (chipErr != CHIP_NO_ERROR)
    {
        return chipErr;
    }

    if (!mFlags.Has(Flags::kDeviceNameSet))
    {
        memset(mDeviceName, 0, kMaxDeviceNameLength);
        snprintf(mDeviceName, kMaxDeviceNameLength, "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator);
    }

    /**************** Prepare advertising data *******************************************/
    adv.cNumAdStructures = BLEKW_ADV_MAX_NO;

    chipErr = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo);
    SuccessOrExit(chipErr);
    mDeviceIdInfoLength = sizeof(mDeviceIdInfo);

    if ((mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1) > BLEKW_MAX_ADV_DATA_LEN)
    {
        return CHIP_ERROR_INCORRECT_STATE;
    }

    adv_data[0].length = 0x02;
    adv_data[0].adType = gAdFlags_c;
    adv_data[0].aData  = (uint8_t *) (&chipAdvDataFlags);

    adv_data[1].length = static_cast<uint8_t>(mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1);
    adv_data[1].adType = gAdServiceData16bit_c;
    memcpy(advPayload, ShortUUID_CHIPoBLEService, CHIP_ADV_SHORT_UUID_LEN);
    memcpy(&advPayload[CHIP_ADV_SHORT_UUID_LEN], (void *) &mDeviceIdInfo, mDeviceIdInfoLength);
    adv_data[1].aData = advPayload;

    adv.aAdStructures = adv_data;

#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
    ReturnErrorOnFailure(EncodeAdditionalDataTlv());
#endif

    /**************** Prepare scan response data *******************************************/
    scanRsp.cNumAdStructures = BLEKW_SCAN_RSP_MAX_NO;

    scan_rsp_data[0].length = static_cast<uint8_t>(strlen(mDeviceName) + 1);
    scan_rsp_data[0].adType = gAdCompleteLocalName_c;
    scan_rsp_data[0].aData  = (uint8_t *) mDeviceName;

    scan_rsp_data[1].length = sizeof(chipOverBleService) + 1;
    scan_rsp_data[1].adType = gAdComplete16bitServiceList_c;
    chipOverBleService[0]   = ShortUUID_CHIPoBLEService[0];
    chipOverBleService[1]   = ShortUUID_CHIPoBLEService[1];
    scan_rsp_data[1].aData  = (uint8_t *) chipOverBleService;

    scanRsp.aAdStructures = scan_rsp_data;

    /**************** Prepare advertising parameters *************************************/
    if (mFlags.Has(Flags::kFastAdvertisingEnabled))
    {
        advInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX;
    }
    else
    {
        advInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
    }
    advInterval = (uint16_t) (advInterval * 0.625F);

    adv_params.minInterval = adv_params.maxInterval = advInterval;
    adv_params.advertisingType                      = gAdvConnectableUndirected_c;
    adv_params.ownAddressType                       = gBleAddrTypeRandom_c;
    adv_params.peerAddressType                      = gBleAddrTypePublic_c;
    memset(adv_params.peerAddress, 0, gcBleDeviceAddressSize_c);
    adv_params.channelMap   = (gapAdvertisingChannelMapFlags_t) (gAdvChanMapFlag37_c | gAdvChanMapFlag38_c | gAdvChanMapFlag39_c);
    adv_params.filterPolicy = gProcessAll_c;

    err = blekw_start_advertising(&adv_params, &adv, &scanRsp);
    if (err == BLE_OK)
    {
        ChipLogProgress(DeviceLayer, "Started Advertising at %d ms", advInterval);
    }
    else
    {
        ChipLogProgress(DeviceLayer, "Advertising error 0x%x!", err);
        mFlags.Clear(Flags::kAdvertising);
        return CHIP_ERROR_INCORRECT_STATE;
    }

exit:
    return chipErr;
}

#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
CHIP_ERROR BLEManagerCommon::EncodeAdditionalDataTlv()
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    BitFlags<AdditionalDataFields> dataFields;
    AdditionalDataPayloadGeneratorParams params;

#if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
    uint8_t rotatingDeviceIdUniqueId[ConfigurationManager::kRotatingDeviceIDUniqueIDLength] = {};
    MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);

    err = DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan);
    SuccessOrExit(err);
    err = ConfigurationMgr().GetLifetimeCounter(params.rotatingDeviceIdLifetimeCounter);
    SuccessOrExit(err);
    params.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan;
    dataFields.Set(AdditionalDataFields::RotatingDeviceId);
#endif /* CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) */
    err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(params, sImplInstance->c3AdditionalDataBufferHandle,
                                                                         dataFields);

exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data (%s)", __func__);
    }

    return err;
}

void BLEManagerCommon::HandleC3ReadRequest(blekw_msg_t * msg)
{
    bleResult_t result;
    blekw_att_read_data_t * att_rd_data = (blekw_att_read_data_t *) msg->data.data;
    deviceId_t deviceId                 = att_rd_data->device_id;
    uint16_t handle                     = att_rd_data->handle;
    uint16_t length                     = sImplInstance->c3AdditionalDataBufferHandle->DataLength();
    const uint8_t * data                = (const uint8_t *) sImplInstance->c3AdditionalDataBufferHandle->Start();

    result = GattDb_WriteAttribute(handle, length, data);
    if (result != gBleSuccess_c)
    {
        ChipLogError(DeviceLayer, "Failed to write C3 characteristic: %d", result);
    }

    result = GattServer_SendAttributeReadStatus(deviceId, handle, gAttErrCodeNoError_c);
    if (result != gBleSuccess_c)
    {
        ChipLogError(DeviceLayer, "Failed to send response to C3 read request: %d", result);
    }
}
#endif /* CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING */

CHIP_ERROR BLEManagerCommon::StartAdvertising(void)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    mFlags.Set(Flags::kAdvertising);
    mFlags.Clear(Flags::kRestartAdvertising);

    if (mFlags.Has(Flags::kFastAdvertisingEnabled))
    {
        StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT);
    }

    err = ConfigureAdvertisingData();

    if (err == CHIP_NO_ERROR)
    /* schedule NFC emulation stop */
    {
        ChipDeviceEvent advChange;
        advChange.Type                             = DeviceEventType::kCHIPoBLEAdvertisingChange;
        advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started;
        err                                        = PlatformMgr().PostEvent(&advChange);
    }

    return err;
}

CHIP_ERROR BLEManagerCommon::StopAdvertising(void)
{
    CHIP_ERROR error = CHIP_NO_ERROR;

    if (mFlags.Has(Flags::kAdvertising))
    {
        mFlags.Clear(Flags::kAdvertising);
        mFlags.Clear(Flags::kRestartAdvertising);

        if (!mDeviceConnected)
        {
            ble_err_t err = blekw_stop_advertising();
            VerifyOrReturnError(err == BLE_OK, CHIP_ERROR_INCORRECT_STATE);
            CancelBleAdvTimeoutTimer();
        }

#if CONFIG_CHIP_NFC_COMMISSIONING
        /* schedule NFC emulation stop */
        ChipDeviceEvent advChange;
        advChange.Type                             = DeviceEventType::kCHIPoBLEAdvertisingChange;
        advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped;
        error                                      = PlatformMgr().PostEvent(&advChange);
#endif
    }

    return error;
}

void BLEManagerCommon::DriveBLEState(void)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    // Check if BLE stack is initialized
    VerifyOrExit(mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);

    // Start advertising if needed...
    if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled))
    {
        // Start/re-start advertising if not already started, or if there is a pending change
        // to the advertising configuration.
        if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kRestartAdvertising))
        {
            err = StartAdvertising();
            SuccessOrExit(err);
        }
    }
    // Otherwise, stop advertising if it is enabled.
    else if (mFlags.Has(Flags::kAdvertising))
    {
        err = StopAdvertising();
        SuccessOrExit(err);
        // Reset to fast advertising mode only if SetBLEAdvertisingEnabled(false) was called (usually from app).
        mFlags.Set(Flags::kFastAdvertisingEnabled);
    }

exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err));
        mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
    }
}

void BLEManagerCommon::DriveBLEState(intptr_t arg)
{
    sImplInstance->DriveBLEState();
}

void BLEManagerCommon::StopAdvertisingPriorToSwitchingMode(intptr_t arg)
{
    if (CHIP_NO_ERROR != sImplInstance->StopAdvertising())
    {
        ChipLogProgress(DeviceLayer, "Failed to stop advertising");
    }
}

void BLEManagerCommon::DoBleProcessing(void)
{
    blekw_msg_t * msg = NULL;

    while ((xQueueReceive(sBleEventQueue, &msg, 0) == pdTRUE) && msg)
    {
        if (msg->type == BLE_KW_MSG_ERROR)
        {
            if (msg->data.u8 == BLE_KW_MSG_2M_UPGRADE_ERROR)
            {
                ChipLogProgress(DeviceLayer,
                                "Warning. BLE is using 1Mbps. Couldn't upgrade to 2Mbps, "
                                "maybe the peer is missing 2Mbps support.");
            }
            else
            {
                ChipLogProgress(DeviceLayer, "BLE Error: %d.\n", msg->data.u8);
            }
        }
        else if (msg->type == BLE_KW_MSG_CONNECTED)
        {
            sImplInstance->HandleConnectEvent(msg);
        }
        else if (msg->type == BLE_KW_MSG_DISCONNECTED)
        {
            sImplInstance->HandleConnectionCloseEvent(msg);
        }
        else if (msg->type == BLE_KW_MSG_MTU_CHANGED)
        {
            blekw_start_connection_timeout();
            ChipLogProgress(DeviceLayer, "BLE MTU size has been changed to %d.", msg->data.u16);
        }
        else if (msg->type == BLE_KW_MSG_ATT_WRITTEN || msg->type == BLE_KW_MSG_ATT_LONG_WRITTEN ||
                 msg->type == BLE_KW_MSG_ATT_CCCD_WRITTEN)
        {
            sImplInstance->HandleWriteEvent(msg);
        }
        else if (msg->type == BLE_KW_MSG_ATT_READ)
        {
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
            blekw_att_read_data_t * att_rd_data = (blekw_att_read_data_t *) msg->data.data;
            if (value_chipoble_c3 == att_rd_data->handle)
                sImplInstance->HandleC3ReadRequest(msg);
#endif
        }
        else if (msg->type == BLE_KW_MSG_FORCE_DISCONNECT)
        {
            sImplInstance->HandleForceDisconnect();
        }

        /* Free the message from the queue */
        free(msg);
        msg = NULL;
    }
}

void BLEManagerCommon::RegisterAppCallbacks(BLECallbackDelegate::GapGenericCallback gapCallback,
                                            BLECallbackDelegate::GattServerCallback gattCallback)
{
    callbackDelegate.gapCallback  = gapCallback;
    callbackDelegate.gattCallback = gattCallback;
}

void BLEManagerCommon::HandleConnectEvent(blekw_msg_t * msg)
{
    uint8_t deviceId = msg->data.u8;
    ChipLogProgress(DeviceLayer, "BLE is connected with device: %d.\n", deviceId);

#if gClkUseFro32K && defined(chip_with_low_power) && (chip_with_low_power == 1)
    PWR_DisallowDeviceToSleep();
#endif

    mDeviceId        = deviceId;
    mDeviceConnected = true;

    blekw_start_connection_timeout();
    PlatformMgr().ScheduleWork(DriveBLEState, 0);
}

void BLEManagerCommon::HandleConnectionCloseEvent(blekw_msg_t * msg)
{
    uint8_t deviceId = msg->data.u8;
    ChipLogProgress(DeviceLayer, "BLE is disconnected with device: %d.\n", deviceId);

#if gClkUseFro32K && defined(chip_with_low_power) && (chip_with_low_power == 1)
    PWR_AllowDeviceToSleep();
#endif

    mDeviceConnected = false;

    ChipDeviceEvent event;
    event.Type                           = DeviceEventType::kCHIPoBLEConnectionClosed;
    event.CHIPoBLEConnectionError.ConId  = deviceId;
    event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED;

    CancelBleAdvTimeoutTimer();

    PlatformMgr().PostEventOrDie(&event);
    mFlags.Set(Flags::kRestartAdvertising);
    mFlags.Set(Flags::kFastAdvertisingEnabled);
    PlatformMgr().ScheduleWork(DriveBLEState, 0);
}

void BLEManagerCommon::HandleWriteEvent(blekw_msg_t * msg)
{
    blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
    attErrorCode_t status                  = gAttErrCodeNoError_c;

#if CHIP_DEVICE_CHIP0BLE_DEBUG
    ChipLogProgress(DeviceLayer, "Attribute write request(device: %d,handle: %d).", att_wr_data->device_id, att_wr_data->handle);
#endif

    blekw_start_connection_timeout();

    if (value_chipoble_rx == att_wr_data->handle)
    {
        sImplInstance->HandleRXCharWrite(msg);
    }
    else if (cccd_chipoble_tx == att_wr_data->handle)
    {
        sImplInstance->HandleTXCharCCCDWrite(msg);
    }

    /* TODO: do we need to send the status also for CCCD_WRITTEN? */
    if (msg->type != BLE_KW_MSG_ATT_CCCD_WRITTEN)
    {
        bleResult_t res = GattServer_SendAttributeWrittenStatus(att_wr_data->device_id, att_wr_data->handle, status);

        if (res != gBleSuccess_c)
        {
            ChipLogProgress(DeviceLayer, "GattServer_SendAttributeWrittenStatus returned %d", res);
        }
    }
}

void BLEManagerCommon::HandleTXCharCCCDWrite(blekw_msg_t * msg)
{
    CHIP_ERROR err                         = CHIP_NO_ERROR;
    blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;
    ChipDeviceEvent event;

    VerifyOrExit(att_wr_data->length != 0, err = CHIP_ERROR_INCORRECT_STATE);
    VerifyOrExit(att_wr_data->data != nullptr, err = CHIP_ERROR_INCORRECT_STATE);

#if CHIP_DEVICE_CHIP0BLE_DEBUG
    ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", *att_wr_data->data ? "subscribe" : "unsubscribe");
#endif

    if (*att_wr_data->data)
    {
        if (!mDeviceSubscribed)
        {
            mDeviceSubscribed             = true;
            event.Type                    = DeviceEventType::kCHIPoBLESubscribe;
            event.CHIPoBLESubscribe.ConId = att_wr_data->device_id;
            err                           = PlatformMgr().PostEvent(&event);
        }
    }
    else
    {
        mDeviceSubscribed             = false;
        event.Type                    = DeviceEventType::kCHIPoBLEUnsubscribe;
        event.CHIPoBLESubscribe.ConId = att_wr_data->device_id;
        err                           = PlatformMgr().PostEvent(&event);
    }

exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err));
    }
}

void BLEManagerCommon::HandleRXCharWrite(blekw_msg_t * msg)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    System::PacketBufferHandle buf;
    blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data;

    VerifyOrExit(att_wr_data->length != 0, err = CHIP_ERROR_INCORRECT_STATE);
    VerifyOrExit(att_wr_data->data != nullptr, err = CHIP_ERROR_INCORRECT_STATE);

    // Copy the data to a PacketBuffer.
    buf = System::PacketBufferHandle::NewWithData(att_wr_data->data, att_wr_data->length);
    VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY);

#if CHIP_DEVICE_CHIP0BLE_DEBUG
    ChipLogDetail(DeviceLayer,
                  "Write request/command received for"
                  "CHIPoBLE RX characteristic (con %u, len %u)",
                  att_wr_data->device_id, buf->DataLength());
#endif

    // Post an event to the CHIP queue to deliver the data into the CHIP stack.
    {
        ChipDeviceEvent event;
        event.Type                        = DeviceEventType::kCHIPoBLEWriteReceived;
        event.CHIPoBLEWriteReceived.ConId = att_wr_data->device_id;
        event.CHIPoBLEWriteReceived.Data  = std::move(buf).UnsafeRelease();
        err                               = PlatformMgr().PostEvent(&event);
    }
exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err));
    }
}

void BLEManagerCommon::HandleForceDisconnect()
{
    ChipLogProgress(DeviceLayer, "BLE connection timeout: Forcing disconnection.");

    /* Set the advertising parameters */
    if (Gap_Disconnect(mDeviceId) != gBleSuccess_c)
    {
        ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
    }
}

/*******************************************************************************
 * BLE stack callbacks
 *******************************************************************************/
void BLEManagerCommon::blekw_generic_cb(gapGenericEvent_t * pGenericEvent)
{
    /* Call BLE Conn Manager */
    BleConnManager_GenericEvent(pGenericEvent);

    if (sImplInstance && sImplInstance->callbackDelegate.gapCallback)
    {
        sImplInstance->callbackDelegate.gapCallback(pGenericEvent);
    }

    switch (pGenericEvent->eventType)
    {
    case gInternalError_c:
        /* Notify the CHIP that the BLE hardware report fail */
        ChipLogProgress(DeviceLayer, "BLE Internal Error: Code 0x%04X, Source 0x%08X, HCI OpCode %d.\n",
                        pGenericEvent->eventData.internalError.errorCode, pGenericEvent->eventData.internalError.errorSource,
                        pGenericEvent->eventData.internalError.hciCommandOpcode);
        if ((gHciUnsupportedRemoteFeature_c == pGenericEvent->eventData.internalError.errorCode) &&
            (gLeSetPhy_c == pGenericEvent->eventData.internalError.errorSource))
        {
            (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_KW_MSG_2M_UPGRADE_ERROR);
        }
        else
        {
            (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_ERROR);
        }
        break;

    case gAdvertisingSetupFailed_c:
        xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED);
        break;

    case gAdvertisingParametersSetupComplete_c:
        xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE);
        break;

    case gAdvertisingDataSetupComplete_c:
        xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE);
        break;

    case gRandomAddressReady_c:
        Gap_SetRandomAddress(pGenericEvent->eventData.addrReady.aAddress);
        break;

    case gRandomAddressSet_c:
        xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_RND_ADDR_SET);
        break;

#if BLE_HIGH_TX_POWER
    case gTxPowerLevelSetComplete_c:
        if (gBleSuccess_c == pGenericEvent->eventData.txPowerLevelSetStatus)
        {
            xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET);
        }
        break;
#endif

    case gInitializationComplete_c:
        /* Common GAP configuration */
        BleConnManager_GapCommonConfig();

        /* Set the local synchronization event */
        xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INIT_COMPLETE);
        break;
    default:
        break;
    }
}

void BLEManagerCommon::blekw_gap_advertising_cb(gapAdvertisingEvent_t * pAdvertisingEvent)
{
    if (pAdvertisingEvent->eventType == gAdvertisingStateChanged_c)
    {
        /* Set the local synchronization event */
        xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED);
    }
    else
    {
        /* The advertisement start failed */
        ChipLogProgress(DeviceLayer, "Advertising failed: event=%d reason=0x%04X\n", pAdvertisingEvent->eventType,
                        pAdvertisingEvent->eventData.failReason);

        /* Set the local synchronization event */
        xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_FAILED);
    }
}

void BLEManagerCommon::blekw_gap_connection_cb(deviceId_t deviceId, gapConnectionEvent_t * pConnectionEvent)
{
    /* Call BLE Conn Manager */
    BleConnManager_GapPeripheralEvent(deviceId, pConnectionEvent);

    if (pConnectionEvent->eventType == gConnEvtConnected_c)
    {
#if CHIP_DEVICE_K32W1
#if defined(chip_with_low_power) && (chip_with_low_power == 1)
        /* Disallow must be called here for K32W1, otherwise an assert will be reached.
         * Disclaimer: this is a workaround until a better cross platform solution is found. */
        PWR_DisallowDeviceToSleep();
#endif
#endif

#if CHIP_DEVICE_CONFIG_BLE_SET_PHY_2M_REQ
        ChipLogProgress(DeviceLayer, "BLE K32W: Trying to set the PHY to 2M");

        (void) Gap_LeSetPhy(FALSE, deviceId, 0, gConnPhyUpdateReqTxPhySettings_c, gConnPhyUpdateReqRxPhySettings_c,
                            (uint16_t) gConnPhyUpdateReqPhyOptions_c);
#endif

        /* Notify App Task that the BLE is connected now */
        (void) blekw_msg_add_u8(BLE_KW_MSG_CONNECTED, (uint8_t) deviceId);
#if defined(chip_with_low_power) && (chip_with_low_power == 1)
        PWR_AllowDeviceToSleep();
#endif
    }
    else if (pConnectionEvent->eventType == gConnEvtDisconnected_c)
    {
        blekw_stop_connection_timeout();

        /* Notify App Task that the BLE is disconnected now */
        (void) blekw_msg_add_u8(BLE_KW_MSG_DISCONNECTED, (uint8_t) deviceId);

#if defined(chip_with_low_power) && (chip_with_low_power == 1)
        if (bleAppStopInProgress == TRUE)
        {
            bleAppStopInProgress = FALSE;
            PWR_AllowDeviceToSleep();
        }
#endif
    }
    else if (pConnectionEvent->eventType == gConnEvtPairingRequest_c)
    {
        /* Reject request for pairing */
        Gap_RejectPairing(deviceId, gPairingNotSupported_c);
    }
    else if (pConnectionEvent->eventType == gConnEvtAuthenticationRejected_c)
    {
        ChipLogProgress(DeviceLayer, "BLE Authentication rejected (reason:%d).\n",
                        pConnectionEvent->eventData.authenticationRejectedEvent.rejectReason);
    }
}

void BLEManagerCommon::blekw_connection_timeout_cb(TimerHandle_t timer)
{
    (void) blekw_msg_add_u8(BLE_KW_MSG_FORCE_DISCONNECT, 0);
}

void BLEManagerCommon::blekw_start_connection_timeout(void)
{
    xTimerReset(connectionTimeout, 0);
}

void BLEManagerCommon::blekw_stop_connection_timeout(void)
{
    ChipLogProgress(DeviceLayer, "Stopped connectionTimeout timer.");
    xTimerStop(connectionTimeout, 0);
}

void BLEManagerCommon::blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent)
{
    if (sImplInstance && sImplInstance->callbackDelegate.gattCallback)
    {
        sImplInstance->callbackDelegate.gattCallback(deviceId, pServerEvent);
    }

    switch (pServerEvent->eventType)
    {
    case gEvtMtuChanged_c: {
        uint16_t tempMtu = 0;

        (void) Gatt_GetMtu(deviceId, &tempMtu);
        blekw_msg_add_u16(BLE_KW_MSG_MTU_CHANGED, tempMtu);
        break;
    }

    case gEvtAttributeWritten_c:
        blekw_msg_add_att_written(BLE_KW_MSG_ATT_WRITTEN, deviceId, pServerEvent->eventData.attributeWrittenEvent.handle,
                                  pServerEvent->eventData.attributeWrittenEvent.aValue,
                                  pServerEvent->eventData.attributeWrittenEvent.cValueLength);
        break;

    case gEvtLongCharacteristicWritten_c:
        blekw_msg_add_att_written(BLE_KW_MSG_ATT_LONG_WRITTEN, deviceId, pServerEvent->eventData.longCharWrittenEvent.handle,
                                  pServerEvent->eventData.longCharWrittenEvent.aValue,
                                  pServerEvent->eventData.longCharWrittenEvent.cValueLength);
        break;

    case gEvtAttributeRead_c:
        blekw_msg_add_att_read(BLE_KW_MSG_ATT_READ, deviceId, pServerEvent->eventData.attributeReadEvent.handle);
        break;

    case gEvtCharacteristicCccdWritten_c: {
        uint16_t cccd_val = pServerEvent->eventData.charCccdWrittenEvent.newCccd;

        blekw_msg_add_att_written(BLE_KW_MSG_ATT_CCCD_WRITTEN, deviceId, pServerEvent->eventData.charCccdWrittenEvent.handle,
                                  (uint8_t *) &cccd_val, 2);
        break;
    }

    case gEvtHandleValueConfirmation_c:
        /* Set the local synchronization event */
        xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED);
        break;

    case gEvtError_c:
        if (pServerEvent->eventData.procedureError.procedureType == gSendIndication_c)
        {
            /* Set the local synchronization event */
            xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_FAILED);
        }
        else
        {
            ChipLogProgress(DeviceLayer, "BLE Gatt Server Error: Code 0x%04X, Source %d.\n",
                            pServerEvent->eventData.procedureError.error, pServerEvent->eventData.procedureError.procedureType);

            /* Notify CHIP BLE App Task that the BLE hardware report fail */
            (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_GATT_ERROR);
        }
        break;

    default:
        break;
    }
}
/*******************************************************************************
 * Add to message queue functions
 *******************************************************************************/
CHIP_ERROR BLEManagerCommon::blekw_msg_add_att_written(blekw_msg_type_t type, uint8_t device_id, uint16_t handle, uint8_t * data,
                                                       uint16_t length)
{
    CHIP_ERROR err    = CHIP_NO_ERROR;
    blekw_msg_t * msg = NULL;
    blekw_att_written_data_t * att_wr_data;

    /* Allocate a buffer with enough space to store the packet */
    msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t) + sizeof(blekw_att_written_data_t) + length);
    VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY);

    msg->type              = type;
    msg->length            = sizeof(blekw_att_written_data_t) + length;
    att_wr_data            = (blekw_att_written_data_t *) msg->data.data;
    att_wr_data->device_id = device_id;
    att_wr_data->handle    = handle;
    att_wr_data->length    = length;
    FLib_MemCpy(att_wr_data->data, data, length);

    VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY);
    otTaskletsSignalPending(NULL);

exit:
    return err;
}

CHIP_ERROR BLEManagerCommon::blekw_msg_add_att_read(blekw_msg_type_t type, uint8_t device_id, uint16_t handle)
{
    CHIP_ERROR err    = CHIP_NO_ERROR;
    blekw_msg_t * msg = NULL;
    blekw_att_read_data_t * att_rd_data;

    /* Allocate a buffer with enough space to store the packet */
    msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t) + sizeof(blekw_att_read_data_t));
    VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY);

    msg->type              = type;
    msg->length            = sizeof(blekw_att_read_data_t);
    att_rd_data            = (blekw_att_read_data_t *) msg->data.data;
    att_rd_data->device_id = device_id;
    att_rd_data->handle    = handle;

    VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY);
    otTaskletsSignalPending(NULL);

exit:
    return err;
}

CHIP_ERROR BLEManagerCommon::blekw_msg_add_u8(blekw_msg_type_t type, uint8_t data)
{
    CHIP_ERROR err    = CHIP_NO_ERROR;
    blekw_msg_t * msg = NULL;

    /* Allocate a buffer with enough space to store the packet */
    msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t));
    VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY);

    msg->type    = type;
    msg->length  = 0;
    msg->data.u8 = data;

    VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY);
    otTaskletsSignalPending(NULL);

exit:
    return err;
}

CHIP_ERROR BLEManagerCommon::blekw_msg_add_u16(blekw_msg_type_t type, uint16_t data)
{
    CHIP_ERROR err    = CHIP_NO_ERROR;
    blekw_msg_t * msg = NULL;

    /* Allocate a buffer with enough space to store the packet */
    msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t));
    VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY);

    msg->type     = type;
    msg->length   = 0;
    msg->data.u16 = data;

    VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY);
    otTaskletsSignalPending(NULL);

exit:
    return err;
}

void BLEManagerCommon::BleAdvTimeoutHandler(TimerHandle_t xTimer)
{
    if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled))
    {
        ChipLogDetail(DeviceLayer, "Start slow advertisement");
        BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising);
    }
}

void BLEManagerCommon::CancelBleAdvTimeoutTimer(void)
{
    if (xTimerStop(sbleAdvTimeoutTimer, 0) == pdFAIL)
    {
        ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer");
    }
}

void BLEManagerCommon::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs)
{
    if (xTimerIsTimerActive(sbleAdvTimeoutTimer))
    {
        CancelBleAdvTimeoutTimer();
    }

    // timer is not active, change its period to required value (== restart).
    // FreeRTOS- Block for a maximum of 100 ticks if the change period command
    // cannot immediately be sent to the timer command queue.
    if (xTimerChangePeriod(sbleAdvTimeoutTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS)
    {
        ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer");
    }
}

bool BLEManagerCommon::blekw_stop_connection_internal(BLE_CONNECTION_OBJECT conId)
{
    ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId);

    if (Gap_Disconnect(conId) != gBleSuccess_c)
    {
        ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
        return false;
    }
#if defined(chip_with_low_power) && (chip_with_low_power == 1)
    else
    {
        bleAppStopInProgress = TRUE;
        PWR_DisallowDeviceToSleep();
    }
#endif

    return true;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
