Skip to content
Permalink
6f0f394fa7
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
1678 lines (1438 sloc) 73.8 KB
/***************************************************************************//**
* \file cy_ble_event_handler.c
* \version 3.60
*
* \brief
* This file contains the source code for the event Handler State Machine
* of the PSoC 6 BLE Middleware.
*
********************************************************************************
* \copyright
* Copyright 2017-2021, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_ble_event_handler.h"
#include "cy_ble_hal_pvt.h"
#if defined(CY_IP_MXBLESS)
/*******************************************************************************
* Global Variables
*******************************************************************************/
/* Indicates if event is processed by registered services */
volatile uint8_t cy_ble_eventHandlerFlag;
/* Busy status. Updated from CY_BLE_EVT_STACK_BUSY_STATUS event */
volatile uint8_t cy_ble_busyStatus[CY_BLE_MAX_SUPPORTED_CONN_COUNT];
/* The pointers to the callback functions */
cy_ble_app_ev_cb_t Cy_BLE_ServerEventHandlerCallback = NULL;
cy_ble_app_ev_cb_t Cy_BLE_ClientEventHandlerCallback = NULL;
/* Pointer to the BLE device address in SROM */
cy_stc_ble_gap_bd_addr_t *cy_ble_sflashDeviceAddress = (cy_stc_ble_gap_bd_addr_t *) CY_BLE_SFLASH_DEVICE_ADDRESS_PTR;
#if CY_BLE_LIB_HOST_CORE
/*******************************************************************************
* Private Function Prototypes
*******************************************************************************/
/* event Handler functions */
static void Cy_BLE_TimeOutEventHandler(const cy_stc_ble_timeout_param_t *eventParam);
static void Cy_BLE_SendWriteResponse(const cy_stc_ble_gatts_write_cmd_req_param_t *eventParam,
cy_en_ble_gatt_err_code_t gattErr);
static void Cy_BLE_ReadByGroupEventHandler(cy_stc_ble_gattc_read_by_grp_rsp_param_t *eventParam);
static void Cy_BLE_ReadByTypeEventHandler(cy_stc_ble_gattc_read_by_type_rsp_param_t *eventParam);
static void Cy_BLE_FindInfoEventHandler(cy_stc_ble_gattc_find_info_rsp_param_t *eventParam);
static void Cy_BLE_NextCharDiscovery(cy_stc_ble_conn_handle_t connHandle, uint8_t incrementIndex);
static void Cy_BLE_NextCharDscrDiscovery(cy_stc_ble_conn_handle_t connHandle, uint8_t incrementIndex);
static void Cy_BLE_LongProcedureEndEventHandler(cy_stc_ble_conn_handle_t connHandle);
static void Cy_BLE_ErrorResponseEventHandler(const cy_stc_ble_gatt_err_param_t *eventParam);
static void Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler(cy_stc_ble_disc_char_info_t *discCharInfo);
/******************************************************************************
* Function Name: Cy_BLE_RegisterServiceEventHandler
***************************************************************************//**
*
* Registration service event Handler
*
* \param eventHandlerFunc: The pointer to the callback procedure.
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
* failed. The following are possible error codes.
*
* Error Codes | Description
* ------------ | -----------
* CY_BLE_SUCCESS | The function completed successfully.
* CY_BLE_ERROR_INVALID_PARAMETER | On specifying NULL as input parameter.
* CY_BLE_ERROR_MEMORY_ALLOCATION_FAILED | Buffer overflow in the registration callback.
*
******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_RegisterServiceEventHandler(cy_ble_event_handle_t eventHandlerFunc)
{
cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
bool existFlag = false;
if(eventHandlerFunc == NULL)
{
apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
}
else
{
/* Check whether eventHandlerFunc has been already registered */
uint32_t idx;
for(idx = 0u; (idx < cy_ble_configPtr->context->eventHandlerPool->count) && (existFlag == false); idx++)
{
if(cy_ble_configPtr->context->eventHandlerPool->serviceEventHandler[idx] == eventHandlerFunc)
{
existFlag = true;
}
}
}
/* Register eventHandlerFunc callback */
if((apiResult == CY_BLE_SUCCESS) && (existFlag == false))
{
if(cy_ble_configPtr->context->eventHandlerPool->count <
cy_ble_configPtr->context->eventHandlerPool->maxServCount)
{
cy_ble_configPtr->context->eventHandlerPool->
serviceEventHandler[cy_ble_configPtr->context->eventHandlerPool->count] = eventHandlerFunc;
cy_ble_configPtr->context->eventHandlerPool->count += 1u;
}
else
{
apiResult = CY_BLE_ERROR_MEMORY_ALLOCATION_FAILED;
}
}
return(apiResult);
}
/******************************************************************************
* Function Name: Cy_BLE_InvokeServiceEventHandler
***************************************************************************//**
*
* Invoke registered service event handlers.
*
* \param eventCode: The event code.
* \param eventParam: The event parameters.
*
* \return
* A return value of type cy_en_ble_gatt_err_code_t.
*
******************************************************************************/
cy_en_ble_gatt_err_code_t Cy_BLE_InvokeServiceEventHandler(uint32_t eventCode,
void *eventParam)
{
uint32_t idx;
cy_en_ble_gatt_err_code_t gattErr = CY_BLE_GATT_ERR_NONE;
for(idx = 0u; ( (idx < cy_ble_configPtr->context->eventHandlerPool->count) &&
((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u) ) ; idx++)
{
gattErr = cy_ble_configPtr->context->eventHandlerPool->
serviceEventHandler[idx](eventCode, eventParam);
}
return(gattErr);
}
/******************************************************************************
* Function Name: Cy_BLE_SendWriteResponse
***************************************************************************//**
*
* Sends the Write Response to Write Request when event was handled by service.
*
* \param eventParam - The event parameter.
* \param gattErr - The error code.
*
******************************************************************************/
static void Cy_BLE_SendWriteResponse(const cy_stc_ble_gatts_write_cmd_req_param_t *eventParam,
cy_en_ble_gatt_err_code_t gattErr)
{
cy_stc_ble_gatt_err_param_t err_param;
err_param.errInfo.opCode = CY_BLE_GATT_WRITE_REQ;
err_param.errInfo.attrHandle = eventParam->handleValPair.attrHandle;
err_param.connHandle = eventParam->connHandle;
/* Send response when event was handled by the service */
if((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) == 0u)
{
if(gattErr != CY_BLE_GATT_ERR_NONE)
{
/* Send an Error Response */
err_param.errInfo.errorCode = gattErr;
(void)Cy_BLE_GATTS_ErrorRsp(&err_param);
}
else
{
/* Send an Write Response */
(void)Cy_BLE_GATTS_WriteRsp(eventParam->connHandle);
}
}
}
/******************************************************************************
* Function Name: Cy_BLE_TimeOutEventHandler
***************************************************************************//**
*
* Handles a #CY_BLE_EVT_TIMEOUT event from the BLE Stack.
*
* \param eventParam: The pointer to a structure of type cy_stc_ble_timeout_param_t.
*
******************************************************************************/
static void Cy_BLE_TimeOutEventHandler(const cy_stc_ble_timeout_param_t *eventParam)
{
if((eventParam->reasonCode == CY_BLE_GATT_RSP_TO) &&
((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u) )
{
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->CY_BLE_HANDLE.connHandle);
if((discIdx < cy_ble_configPtr->params->maxClientCount) &&
(cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u))
{
switch(Cy_BLE_GetConnectionState(eventParam->CY_BLE_HANDLE.connHandle))
{
case CY_BLE_CONN_STATE_CLIENT_SRVC_DISCOVERING:
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_SRVC_DISCOVERY_FAILED,
(cy_stc_ble_conn_handle_t*)&eventParam->CY_BLE_HANDLE.connHandle);
break;
case CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING:
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_INCL_DISCOVERY_FAILED,
(cy_stc_ble_conn_handle_t*)&eventParam->CY_BLE_HANDLE.connHandle);
break;
case CY_BLE_CONN_STATE_CLIENT_CHAR_DISCOVERING:
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_CHAR_DISCOVERY_FAILED,
(cy_stc_ble_conn_handle_t*)&eventParam->CY_BLE_HANDLE.connHandle);
break;
case CY_BLE_CONN_STATE_CLIENT_DESCR_DISCOVERING:
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_DESCR_DISCOVERY_FAILED,
(cy_stc_ble_conn_handle_t*)&eventParam->CY_BLE_HANDLE.connHandle);
break;
default: /* Other states should not be set in Auto discovery mode */
break;
}
cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
Cy_BLE_SetConnectionState(eventParam->CY_BLE_HANDLE.connHandle, CY_BLE_CONN_STATE_CONNECTED);
}
}
if((cy_ble_configPtr->params->gapRole & CY_BLE_GAP_CENTRAL) != 0u)
{
/* Connection procedure timeout */
if((eventParam->reasonCode == CY_BLE_GENERIC_APP_TO) &&
(cy_ble_connectingTimeout.timerHandle == eventParam->timerHandle) &&
(Cy_BLE_GetState() == CY_BLE_STATE_CONNECTING))
{
(void)Cy_BLE_GAPC_CancelDeviceConnection();
}
}
}
/******************************************************************************
* Function Name: Cy_BLE_IsDeviceAddressValid
***************************************************************************//**
*
* This function verifies that the device address is valid (not equal zero)
*
* \param deviceAddress: The pointer to the BD address of
* type #cy_stc_ble_gap_bd_addr_t.
*
* \return
* A non-zero value when a device address is valid
*
******************************************************************************/
uint8_t Cy_BLE_IsDeviceAddressValid(const cy_stc_ble_gap_bd_addr_t *deviceAddress)
{
uint8_t addressValid = 0u;
uint32_t i;
if(deviceAddress->type == CY_BLE_GAP_ADDR_TYPE_PUBLIC)
{
for(i = 0u; i < CY_BLE_GAP_BD_ADDR_SIZE; i++)
{
if(deviceAddress->bdAddr[i] != 0u)
{
addressValid = 1u;
break;
}
}
}
return(addressValid);
}
/******************************************************************************
* Function Name: Cy_BLE_EventHandler
***************************************************************************//**
*
* Handles events from the BLE Stack.
*
* \param event: The event code.
* \param evParam: The event parameters.
*
******************************************************************************/
void Cy_BLE_EventHandler(cy_en_ble_event_t event, void *evParam)
{
/* Internal status of commands execution */
static volatile uint32_t cy_ble_cmdStatus;
cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
/* Common Profile event handling */
switch(event)
{
/**********************************************************
* General events
************************************************************/
case CY_BLE_EVT_HCI_PKT_RCVD:
{
cy_stc_ble_hci_tx_packet_info_t *HciPktParams = (cy_stc_ble_hci_tx_packet_info_t*)evParam;
Cy_BLE_HAL_MappingSoftHciHostReceiveControllerPkt(HciPktParams);
/* Clear the CY_BLE_CALLBACK flag not to provide a handled event to the application */
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
break;
case CY_BLE_EVT_STACK_ON:
/* Initializes internal state variables */
cy_ble_scanningIntervalType = CY_BLE_SCANNING_FAST;
cy_ble_advertisingIntervalType = CY_BLE_ADVERTISING_FAST;
(void)memset((uint8_t*)&cy_ble_busyStatus, 0, sizeof(cy_ble_busyStatus));
(void)memset(&cy_ble_connState, 0, sizeof(cy_ble_connState));
cy_ble_cmdStatus = 0u;
/* Set a device address */
if(Cy_BLE_IsDeviceAddressValid(cy_ble_sflashDeviceAddress) != 0u)
{
(void)Cy_BLE_GAP_SetBdAddress(cy_ble_sflashDeviceAddress);
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
{
Cy_BLE_ChangeAdDeviceAddress(cy_ble_sflashDeviceAddress, 0u);
Cy_BLE_ChangeAdDeviceAddress(cy_ble_sflashDeviceAddress, 1u);
}
}
else
{
if(cy_ble_configPtr->params->siliconDeviceAddressEn)
{
uint32_t bdAddrLoc;
bdAddrLoc = ((uint32_t)SFLASH_DIE_X & (uint32_t)CY_BLE_SFLASH_DIE_X_MASK) |
((uint32_t)(((uint32_t)SFLASH_DIE_Y) & ((uint32_t)CY_BLE_SFLASH_DIE_Y_MASK)) <<
CY_BLE_SFLASH_DIE_X_BITS) |
((uint32_t)(((uint32_t)SFLASH_DIE_WAFER) & ((uint32_t)CY_BLE_SFLASH_DIE_WAFER_MASK)) <<
CY_BLE_SFLASH_DIE_XY_BITS) |
((uint32_t)(((uint32_t)SFLASH_DIE_LOT(0)) & ((uint32_t)CY_BLE_SFLASH_DIE_LOT_MASK)) <<
CY_BLE_SFLASH_DIE_XYWAFER_BITS);
cy_ble_configPtr->deviceAddress->bdAddr[0] = (uint8_t)bdAddrLoc;
cy_ble_configPtr->deviceAddress->bdAddr[1] = (uint8_t)(bdAddrLoc >> 8u);
cy_ble_configPtr->deviceAddress->bdAddr[2] = (uint8_t)(bdAddrLoc >> 16u);
}
(void)Cy_BLE_GAP_SetBdAddress(cy_ble_configPtr->deviceAddress);
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
{
Cy_BLE_ChangeAdDeviceAddress(cy_ble_configPtr->deviceAddress, 0u);
Cy_BLE_ChangeAdDeviceAddress(cy_ble_configPtr->deviceAddress, 1u);
}
}
/* Set the device IO Capability */
(void)Cy_BLE_GAP_SetIoCap((cy_en_ble_gap_iocap_t*)&cy_ble_configPtr->params->securityIoCapability);
/* Enable all 4.1 events and configured 4.2 events */
{
uint8_t leMask[CY_BLE_LE_MASK_LENGTH] = {CY_LO8(CY_BLE_LE_MASK),
CY_HI8(CY_BLE_LE_MASK), 0u, 0u, 0u, 0u, 0u, 0u };
(void)Cy_BLE_SetLeEventMask(leMask);
}
/* Update BLE state */
Cy_BLE_SetState(CY_BLE_STATE_ON);
break;
case CY_BLE_EVT_SOFT_RESET_COMPLETE:
case CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE:
/* Update BLE / Adv. / Scan states */
Cy_BLE_SetState(CY_BLE_STATE_STOPPED);
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
{
Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
}
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_CENTRAL | CY_BLE_GAP_OBSERVER)) != 0u)
{
Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_STOPPED);
}
/* Clean pair status */
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
{
(void)memset((uint8_t*)cy_ble_pairStatus, 0, sizeof(cy_ble_pairStatus));
}
#if defined(COMPONENT_BLESS_HOST_IPC)
/* Adding a delay of 10ms to ensure that the controller is completely
* shut-down before generating the event to the application.
* Refer to CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE event documentation. */
Cy_SysLib_Delay(10u);
#endif /* defined(COMPONENT_BLESS_HOST_IPC) */
if ( event == CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE)
{
/* Unregister BLE SysPm callback for deep sleep/sleep */
if (Cy_BLE_UnregisterPmCallbacksPtr != NULL)
{
Cy_BLE_UnregisterPmCallbacksPtr();
}
}
break;
case CY_BLE_EVT_LE_SET_EVENT_MASK_COMPLETE:
if((cy_ble_cmdStatus & CY_BLE_STATUS_SET_TX_PWR_LVL) == 0u)
{
cy_stc_ble_tx_pwr_lvl_info_t bleSsPowerLevel;
/* Set the Tx Power Level for advertising channel */
bleSsPowerLevel.blePwrLevel = cy_ble_configPtr->params->txPowerLevelAdv;
bleSsPowerLevel.pwrConfigParam.bleSsChId = CY_BLE_LL_ADV_CH_TYPE;
bleSsPowerLevel.pwrConfigParam.bdHandle = 0x0u;
(void)Cy_BLE_SetTxPowerLevel(&bleSsPowerLevel);
/* Set the Tx Power Level for connection channel */
bleSsPowerLevel.blePwrLevel = cy_ble_configPtr->params->txPowerLevelConn;
bleSsPowerLevel.pwrConfigParam.bleSsChId = CY_BLE_LL_CONN_CH_TYPE;
bleSsPowerLevel.pwrConfigParam.bdHandle = 0xFFu; /* Set the tx power level value for all connection handles.*/
(void)Cy_BLE_SetTxPowerLevel(&bleSsPowerLevel);
/* Set flag that executed Cy_BLE_SetTxPowerLevel during BLE start-up */
cy_ble_cmdStatus |= CY_BLE_STATUS_SET_TX_PWR_LVL;
}
break;
case CY_BLE_EVT_TIMEOUT:
/* Internal Timeout Handling */
Cy_BLE_TimeOutEventHandler((cy_stc_ble_timeout_param_t*)evParam);
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
{
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
}
break;
case CY_BLE_EVT_STACK_BUSY_STATUS:
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
{
cy_ble_busyStatus[Cy_BLE_GetConnHandleByBdHandle(((cy_stc_ble_l2cap_state_info_t*)evParam)->bdHandle).attId] =
((cy_stc_ble_l2cap_state_info_t*)evParam)->flowState;
}
break;
case CY_BLE_EVT_MEMORY_REQUEST:
{
cy_stc_ble_memory_request_t *memReq = (cy_stc_ble_memory_request_t*)evParam;
if( (!cy_ble_configPtr->params->gattPrepareWriteExtBuffEn) &&
(memReq->request == CY_BLE_PREPARED_WRITE_REQUEST) )
{
/* Stack requests to provide memory to process a remote request */
if(memReq->allocFree == CY_BLE_ALLOC_MEMORY)
{
static cy_stc_ble_prepare_write_request_memory_t gPrepWriteReqMem;
/* Prepare write buffer locates at the end of memoryHeap */
uint16_t bufferAddr = cy_ble_configPtr->stackParam->totalHeapSz;
/* Configure and return a statically allocated buffer at the end of the cy_ble_stackMemoryRam buffer */
gPrepWriteReqMem.prepareWriteQueueSize = cy_ble_configPtr->params->gattPrepareWriteQueueSize;
gPrepWriteReqMem.totalAttrValueLength = cy_ble_configPtr->params->totalAttrValueLength;
gPrepWriteReqMem.queueBuffer = &cy_ble_configPtr->stackParam->memoryHeapPtr[bufferAddr];
memReq->configMemory = &gPrepWriteReqMem;
}
/* Clear the CY_BLE_CALLBACK flag not to provide a handled event to the application */
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
}
break;
/**********************************************************
* GAP events
************************************************************/
case CY_BLE_EVT_GAP_AUTH_COMPLETE:
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
{
cy_stc_ble_conn_handle_t connectedHandle;
connectedHandle = Cy_BLE_GetConnHandleByBdHandle(((cy_stc_ble_gap_auth_info_t*)evParam)->bdHandle);
if(cy_ble_configPtr->params->isBondingReq == CY_BLE_BONDING_YES)
{
cy_ble_peerBonding[connectedHandle.attId] = ((cy_stc_ble_gap_auth_info_t*)evParam)->bonding;
}
if(((cy_stc_ble_gap_auth_info_t *)evParam)->authErr == CY_BLE_GAP_AUTH_ERROR_NONE)
{
cy_ble_pairStatus[connectedHandle.attId] = true;
}
}
break;
case CY_BLE_EVT_GAP_CONNECTION_UPDATE_COMPLETE:
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
{
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
}
break;
case CY_BLE_EVT_GAP_ENHANCE_CONN_COMPLETE:
case CY_BLE_EVT_GAP_DEVICE_CONNECTED:
{
uint8_t cmdStatus;
uint8_t deviceDdHandle = 0u;
uint8_t deviceRole = 0u;
if((cy_ble_configPtr->stackParam->featureMask & CY_BLE_PRIVACY_1_2_FEATURE_MASK) != 0u)
{
cmdStatus = ((cy_stc_ble_gap_enhance_conn_complete_param_t *) evParam)->status;
if(cmdStatus == CY_BLE_HCI_SUCCESS)
{
deviceDdHandle = ((cy_stc_ble_gap_enhance_conn_complete_param_t *) evParam)->bdHandle;
deviceRole = ((cy_stc_ble_gap_enhance_conn_complete_param_t *) evParam)->role;
}
}
else
{
cmdStatus = ((cy_stc_ble_gap_connected_param_t *) evParam)->status;
if(cmdStatus == CY_BLE_HCI_SUCCESS)
{
deviceDdHandle = ((cy_stc_ble_gap_connected_param_t *) evParam)->bdHandle;
deviceRole = ((cy_stc_ble_gap_connected_param_t *) evParam)->role;
}
}
if(cmdStatus == CY_BLE_HCI_SUCCESS)
{
/* Advertising is automatically stopped if a Slave is connected,
so update the adv state to CY_BLE_ADV_STATE_STOPPED */
if( ((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u) &&
(deviceRole == CY_BLE_GAP_LL_ROLE_SLAVE) )
{
Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
}
/* Stop Timer in central mode (if timer was started) */
if(((cy_ble_configPtr->params->gapRole & CY_BLE_GAP_CENTRAL) != 0u) &&
(cy_ble_connectingTimeout.timeout != 0u))
{
(void)Cy_BLE_StopTimer(&cy_ble_connectingTimeout);
}
/* Store information about role of device connected (Master/Slave)*/
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
{
cy_stc_ble_conn_handle_t tconnHandle = Cy_BLE_GetConnHandleByBdHandle(deviceDdHandle);
if( tconnHandle.attId != CY_BLE_INVALID_CONN_HANDLE_VALUE)
{
cy_ble_devConnRole[tconnHandle.attId] = deviceRole;
}
}
}
Cy_BLE_SetState(CY_BLE_STATE_ON);
}
break;
case CY_BLE_EVT_GAP_DEVICE_DISCONNECTED:
Cy_BLE_SetState(CY_BLE_STATE_ON);
break;
case CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_BROADCASTER | CY_BLE_GAP_PERIPHERAL)) ==
(CY_BLE_GAP_BROADCASTER | CY_BLE_GAP_PERIPHERAL))
{
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
}
if((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u)
{
/* After Cy_BLE_GAPP_StartAdvertisement, the first event indicates that advertising has started */
if(Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_ADV_INITIATED)
{
Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_ADVERTISING);
}
/* When the application initiated a stop advertisement */
else if(Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_STOP_INITIATED)
{
Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
}
/* The following event indicates that advertising has been stopped */
else if(Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_ADVERTISING)
{
Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
/* Enable slow advertising, if need */
if((cy_ble_configPtr->gappAdvParams[cy_ble_advIndex].slowAdvEnable != 0u) &&
(cy_ble_configPtr->gappAdvParams[cy_ble_advIndex].fastAdvTimeOut != 0u) &&
(cy_ble_advertisingIntervalType == CY_BLE_ADVERTISING_FAST))
{
if(Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_SLOW, cy_ble_advIndex) == CY_BLE_SUCCESS)
{
Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_ADV_INITIATED);
}
}
}
else
{
/* Empty else */
}
}
break;
case CY_BLE_EVT_GAPC_SCAN_START_STOP:
if((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u)
{
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
}
if((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u)
{
/* After Cy_BLE_GAPC_StartScan, the first event indicates that scanning has been started */
if(Cy_BLE_GetScanState() == CY_BLE_SCAN_STATE_SCAN_INITIATED)
{
Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_SCANNING);
}
/* When the application initiated stop scanning */
else if(Cy_BLE_GetScanState() == CY_BLE_SCAN_STATE_STOP_INITIATED)
{
Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_STOPPED);
}
/* The following event indicates that scanning has been stopped by BLE Stack */
else if(Cy_BLE_GetScanState() == CY_BLE_SCAN_STATE_SCANNING)
{
Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_STOPPED);
if((cy_ble_configPtr->gapcScanParams[cy_ble_scanIndex].slowScanEnabled != 0u) &&
(cy_ble_configPtr->gapcScanParams[cy_ble_scanIndex].fastScanTimeOut != 0u) &&
(cy_ble_scanningIntervalType == CY_BLE_SCANNING_FAST))
{
if(Cy_BLE_GAPC_StartScan(CY_BLE_SCANNING_SLOW, cy_ble_scanIndex) == CY_BLE_SUCCESS)
{
Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_SCAN_INITIATED);
}
}
}
else
{
/* Empty else */
}
}
break;
/**********************************************************
* L2AP events
************************************************************/
case CY_BLE_EVT_L2CAP_CONN_PARAM_UPDATE_RSP:
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
{
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
}
break;
/**********************************************************
* GATT events
************************************************************/
case CY_BLE_EVT_GATT_CONNECT_IND:
{
cy_stc_ble_conn_handle_t *locConnHandle = (cy_stc_ble_conn_handle_t*)evParam;
/* If connected to the same device which is already discovered */
if( ((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u) &&
(Cy_BLE_GetConnectionState(*locConnHandle) == CY_BLE_CONN_STATE_CLIENT_DISCONNECTED_DISCOVERED) &&
(locConnHandle->bdHandle == cy_ble_connHandle[locConnHandle->attId].bdHandle))
{ /* Set a discovered state */
Cy_BLE_SetConnectionState(*(cy_stc_ble_conn_handle_t*)evParam, CY_BLE_CONN_STATE_CLIENT_DISCOVERED);
}
else /* Connected to a new device */
{
/* Clear the discovery index for the client role */
if( (cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u)
{
(void)Cy_BLE_GATTC_RemoveConnHandle(*(cy_stc_ble_conn_handle_t*)evParam);
}
Cy_BLE_SetConnectionState(*locConnHandle, CY_BLE_CONN_STATE_CONNECTED);
cy_ble_connHandle[locConnHandle->attId] = *locConnHandle;
}
cy_ble_busyStatus[locConnHandle->attId] = CY_BLE_STACK_STATE_FREE;
if( ((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_SERVER) != 0u) &&
(cy_ble_configPtr->params->isBondingReq == CY_BLE_BONDING_YES) &&
(cy_ble_configPtr->flashStorage->cccdCount != 0u) )
{
/* Initialize the CCCD values in the RAM when bonding is enabled */
uint32_t cccdBlockSize = cy_ble_configPtr->flashStorage->cccdCount + CY_BLE_CCCD_CRC_BYTE;
uint32_t cccdBlockOffsetRam = locConnHandle->attId * cccdBlockSize;
uint32_t cccdBlockCrcOffset = cccdBlockSize - CY_BLE_CCCD_CRC_BYTE;
uint8_t calcCrc;
(void)memcpy(&cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam],
&cy_ble_configPtr->flashStorage->cccdFlashPtr[locConnHandle->bdHandle * cccdBlockSize],
cccdBlockSize);
/* Check CRC for CCCD data */
calcCrc = Cy_BLE_HAL_CalcCRC8(&cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam],
cy_ble_configPtr->flashStorage->cccdCount);
if(cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam + cccdBlockCrcOffset] != calcCrc)
{
/* Inform that the CRC for CCCD is wrong */
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTS_EVT_CCCD_CORRUPT, NULL);
/* Clean the CCCD buffer in the RAM */
(void)memset(&cy_ble_configPtr->flashStorage->cccdRamPtr[locConnHandle->attId * cccdBlockSize],
0, cccdBlockSize);
}
}
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
}
break;
case CY_BLE_EVT_GATT_DISCONNECT_IND:
{
cy_stc_ble_conn_handle_t *locConnHandle = (cy_stc_ble_conn_handle_t*)evParam;
if( ((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u) &&
(Cy_BLE_GetConnectionState(*locConnHandle) == CY_BLE_CONN_STATE_CLIENT_DISCOVERED) &&
(cy_ble_configPtr->params->isBondingReq == CY_BLE_BONDING_YES) )
{
Cy_BLE_SetConnectionState(*(cy_stc_ble_conn_handle_t*)evParam,
CY_BLE_CONN_STATE_CLIENT_DISCONNECTED_DISCOVERED);
}
else
{
Cy_BLE_SetConnectionState(*(cy_stc_ble_conn_handle_t*)evParam, CY_BLE_CONN_STATE_DISCONNECTED);
if((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u)
{
(void)Cy_BLE_GATTC_RemoveConnHandle(*(cy_stc_ble_conn_handle_t*)evParam);
}
}
if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL )) != 0u)
{
cy_ble_pairStatus[(*(cy_stc_ble_conn_handle_t *)evParam).attId] = false;
}
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
}
break;
case CY_BLE_EVT_GATTS_XCNHG_MTU_REQ:
{
cy_stc_ble_gatt_xchg_mtu_param_t mtuParam;
mtuParam.connHandle = ((cy_stc_ble_gatt_xchg_mtu_param_t*)evParam)->connHandle;
mtuParam.mtu = cy_ble_configPtr->params->mtuSize ;
(void)Cy_BLE_GATTS_ExchangeMtuRsp(&mtuParam);
}
break;
case CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT:
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
break;
case CY_BLE_EVT_PENDING_FLASH_WRITE:
cy_ble_pendingFlashWrite |= CY_BLE_PENDING_STACK_FLASH_WRITE_BIT;
break;
default:
break;
}
/* Handling GATT server events */
if(((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u) && (Cy_BLE_ServerEventHandlerCallback != NULL))
{
Cy_BLE_ServerEventHandlerCallback(event, evParam);
}
/* Handling GATT client events */
if(((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u) && (Cy_BLE_ClientEventHandlerCallback != NULL))
{
Cy_BLE_ClientEventHandlerCallback(event, evParam);
}
/* Call Cy_BLE_ApplCallback if event was not processed */
if((cy_ble_eventHandlerFlag & (CY_BLE_CALLBACK | CY_BLE_ENABLE_ALL_EVENTS)) != 0u)
{
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
Cy_BLE_ApplCallback((uint32_t)event, evParam);
}
}
/******************************************************************************
* Function Name: Cy_BLE_ServerEventHandler
***************************************************************************//**
*
* Handles server events from the BLE Stack.
*
* \param event: The event code.
* \param evParam: The event parameters.
*
******************************************************************************/
void Cy_BLE_ServerEventHandler(cy_en_ble_event_t event, void *evParam)
{
/* Common Profile event handling */
switch(event)
{
case CY_BLE_EVT_GATTS_WRITE_REQ:
{
cy_en_ble_gatt_err_code_t gattErr;
cy_ble_gatt_db_attr_handle_t attrHandle;
/* Process GATT service */
gattErr = Cy_BLE_GATTS_WriteEventHandler((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam);
/* Process all registered service */
if(gattErr == CY_BLE_GATT_ERR_NONE)
{
gattErr = Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
}
Cy_BLE_SendWriteResponse((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam, gattErr);
/* Call Cy_BLE_ApplCallback if event was not processed */
if((cy_ble_eventHandlerFlag & (CY_BLE_CALLBACK | CY_BLE_ENABLE_ALL_EVENTS)) != 0u)
{
Cy_BLE_ApplCallback((uint32_t)event, evParam);
}
/* Send Error response if unknown attr handle */
attrHandle = ((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam)->handleValPair.attrHandle;
if( ((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u) &&
((attrHandle > cy_ble_configPtr->params->gattDbIndexCount) || (attrHandle == 0u)))
{
/* Processing unknown attr handle (send an Error Response) */
cy_stc_ble_gatt_err_param_t err_param;
err_param.errInfo.opCode = CY_BLE_GATT_WRITE_REQ;
err_param.errInfo.attrHandle = ((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam)->handleValPair.attrHandle;
err_param.connHandle = ((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam)->connHandle;
err_param.errInfo.errorCode = CY_BLE_GATT_ERR_INVALID_HANDLE;
(void)Cy_BLE_GATTS_ErrorRsp(&err_param);
}
/* Indicate that request was handled */
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
break;
case CY_BLE_EVT_GATTS_WRITE_CMD_REQ:
case CY_BLE_EVT_GATTS_PREP_WRITE_REQ:
case CY_BLE_EVT_GATTS_EXEC_WRITE_REQ:
case CY_BLE_EVT_GATTS_HANDLE_VALUE_CNF:
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
break;
case CY_BLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ:
if(cy_ble_configPtr->flashStorage->cccdCount != 0u)
{
(void)Cy_BLE_GATTS_ReadAttributeValueCCCDReqHandler((cy_stc_ble_gatts_char_val_read_req_t*)evParam);
}
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
break;
default:
break;
}
}
/******************************************************************************
* Function Name: Cy_BLE_ClientEventHandler
***************************************************************************//**
*
* Handles client events from the BLE Stack.
*
* \param event: The event code.
* \param evParam: The event parameters.
*
******************************************************************************/
void Cy_BLE_ClientEventHandler(cy_en_ble_event_t event, void *evParam)
{
/* Common Profile event handling */
switch(event)
{
case CY_BLE_EVT_GATTC_READ_BY_GROUP_TYPE_RSP:
Cy_BLE_ReadByGroupEventHandler((cy_stc_ble_gattc_read_by_grp_rsp_param_t*)evParam);
break;
case CY_BLE_EVT_GATTC_READ_BY_TYPE_RSP:
Cy_BLE_ReadByTypeEventHandler((cy_stc_ble_gattc_read_by_type_rsp_param_t*)evParam);
break;
case CY_BLE_EVT_GATTC_READ_BLOB_RSP:
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
break;
case CY_BLE_EVT_GATTC_LONG_PROCEDURE_END:
Cy_BLE_LongProcedureEndEventHandler(((cy_stc_ble_gattc_long_procedure_end_param_t*)evParam)->connHandle);
break;
case CY_BLE_EVT_GATTC_FIND_INFO_RSP:
Cy_BLE_FindInfoEventHandler((cy_stc_ble_gattc_find_info_rsp_param_t*)evParam);
break;
case CY_BLE_EVT_GATTC_ERROR_RSP:
Cy_BLE_ErrorResponseEventHandler((cy_stc_ble_gatt_err_param_t*)evParam);
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
break;
case CY_BLE_EVT_GATTC_HANDLE_VALUE_IND:
Cy_BLE_GATTC_IndicationEventHandler((cy_stc_ble_gattc_handle_value_ind_param_t*)evParam);
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
/* Respond with a Handle Value Confirmation when request handled */
if((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) == 0u)
{
cy_stc_ble_gattc_confirmation_req_t confirmationParam;
confirmationParam.connHandle = ((cy_stc_ble_gattc_handle_value_ind_param_t*)evParam)->connHandle;
(void)Cy_BLE_GATTC_Confirmation(&confirmationParam);
}
break;
case CY_BLE_EVT_GATTC_HANDLE_VALUE_NTF:
case CY_BLE_EVT_GATTC_READ_RSP:
case CY_BLE_EVT_GATTC_READ_MULTI_RSP:
case CY_BLE_EVT_GATTC_WRITE_RSP:
case CY_BLE_EVT_GATTC_EXEC_WRITE_RSP:
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
break;
case CY_BLE_EVT_GATTC_STOP_CMD_COMPLETE:
{
cy_stc_ble_conn_handle_t locConnHandle = *(cy_stc_ble_conn_handle_t *)evParam;
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(locConnHandle);
if( (Cy_BLE_GetConnectionState(locConnHandle) == CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING) &&
(discIdx < cy_ble_configPtr->params->maxClientCount) &&
(cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u) )
{
cy_stc_ble_gattc_read_req_t readReqParam;
/* Fill Read Request parameters */
readReqParam.attrHandle =
cy_ble_configPtr->context->discovery[discIdx].inclInfo.inclHandleRange.startHandle;
readReqParam.connHandle = locConnHandle;
/* Get the included service UUID when the included service uses a 128-bit
* UUID, a Read Request is used. The Attribute Handle for the Read Request is
* the Attribute Handle of the included service.
*/
if(Cy_BLE_GATTC_ReadCharacteristicValue(&readReqParam) != CY_BLE_SUCCESS)
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_INCL_DISCOVERY_FAILED, &locConnHandle);
cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
}
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
}
break;
default:
break;
}
}
/******************************************************************************
* Function Name: Cy_BLE_ReadByGroupEventHandler
***************************************************************************//**
*
* Handles a Read By Group Response event during an automatic server discovery
* process.
*
* \param eventParam: The event parameters for a Read By Group Response.
*
******************************************************************************/
static void Cy_BLE_ReadByGroupEventHandler(cy_stc_ble_gattc_read_by_grp_rsp_param_t *eventParam)
{
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->connHandle);
if( (Cy_BLE_GetConnectionState(eventParam->connHandle) == CY_BLE_CONN_STATE_CLIENT_SRVC_DISCOVERING) &&
(discIdx < cy_ble_configPtr->params->maxClientCount) &&
(cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u) )
{
uint16_t locDataLength = eventParam->attrData.length;
uint16_t attrLength;
if((locDataLength == CY_BLE_DISC_SRVC_INFO_LEN) || (locDataLength == CY_BLE_DISC_SRVC_INFO_128_LEN))
{
cy_stc_ble_disc_srv_info_t locDiscServInfo = { .connHandle = eventParam->connHandle };
uint32_t fFlag;
uint32_t j;
uint32_t i;
attrLength = eventParam->attrData.attrLen;
for(i = 0u; i < attrLength; i += locDataLength)
{
cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
locDiscServInfo.srvcInfo = (cy_stc_ble_disc_srvc128_info_t*)(eventParam->attrData.attrValue + i);
fFlag = 0u;
if((locDiscServInfo.srvcInfo->range.startHandle >=
cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) &&
(locDiscServInfo.srvcInfo->range.startHandle <=
cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.endHandle))
{
/* Received a 16-bit service UUID */
if(locDataLength == CY_BLE_DISC_SRVC_INFO_LEN)
{
uint32_t discServiNum = cy_ble_configPtr->context->discServiCount;
locDiscServInfo.uuidFormat = CY_BLE_GATT_16_BIT_UUID_FORMAT;
for(j = 0u; (j < discServiNum) && (fFlag == 0u); j++)
{
locDiscServInfo.uuidFormat = CY_BLE_GATT_16_BIT_UUID_FORMAT;
if(cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].uuid ==
locDiscServInfo.srvcInfo->uuid.uuid16)
{
if(cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].range.startHandle ==
CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE)
{
cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].range =
locDiscServInfo.srvcInfo->range;
fFlag = 1u;
}
else /* Duplication of service */
{
/* For multiple service support next service has the same UUID */
if((j >= (discServiNum - 1u)) ||
(cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j + 1u].uuid !=
locDiscServInfo.srvcInfo->uuid.uuid16))
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_SRVC_DUPLICATION, &locDiscServInfo);
fFlag = 1u;
}
}
}
}
}
else /* Received a 128-bit service UUID */
{
locDiscServInfo.uuidFormat = CY_BLE_GATT_128_BIT_UUID_FORMAT;
/* Loop thru all registered services and invoke CY_BLE_EVT_GATTC_DISC_CHAR event */
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_SERVICE,
(void*)&locDiscServInfo);
}
}
/* Generate event CY_BLE_EVT_GATTC_DISC_SKIPPED_SERVICE, if the incoming service was not processed */
if((fFlag == 0u) && ((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u))
{
/* Inform application that we discovered the service which is not defined in GATT database */
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_DISC_SKIPPED_SERVICE, &locDiscServInfo);
}
}
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
else
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_SRVC_DISCOVERY_FAILED, &eventParam->connHandle);
}
}
}
/******************************************************************************
* Function Name: Cy_BLE_NextInclDiscovery
***************************************************************************//**
*
* Looks for the included services in the current service (pointed by
* cy_ble_disCount). If the current service handle range is invalid (any of start
* or end handle is invalid), then increments the cy_ble_disCount and check
* the next service range and does so until a valid range is caught or the end of
* the service set is reached.
*
* \param connHandle: The connection handle.
* \param incrementIndex: A non-zero value indicates that the service index should be
* incremented.
*
******************************************************************************/
void Cy_BLE_NextInclDiscovery(cy_stc_ble_conn_handle_t connHandle,
uint8_t incrementIndex)
{
uint32_t locServCount;
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(connHandle);
uint32_t discServiNum = cy_ble_configPtr->context->discServiCount;
if(incrementIndex != CY_BLE_DISCOVERY_INIT)
{
cy_ble_configPtr->context->discovery[discIdx].servCount++;
}
else
{
cy_ble_configPtr->context->discovery[discIdx].servCount = 0u;
cy_ble_configPtr->context->discovery[discIdx].inclInfo.inclDefHandle = 0u;
}
locServCount = cy_ble_configPtr->context->discovery[discIdx].servCount;
/* Skip not existing services and services out of the discovery range */
while( (cy_ble_configPtr->context->discovery[discIdx].servCount < discServiNum) &&
((cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range.startHandle <
cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) ||
(cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range.startHandle >
cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.endHandle)) )
{
cy_ble_configPtr->context->discovery[discIdx].servCount++;
locServCount = cy_ble_configPtr->context->discovery[discIdx].servCount;
}
if(cy_ble_configPtr->context->discovery[discIdx].servCount < discServiNum)
{
cy_stc_ble_gattc_read_by_type_req_t requestParam;
/* Fill Read by type request parameters */
requestParam.range = cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range;
requestParam.connHandle = connHandle;
if(Cy_BLE_GATTC_FindIncludedServices(&requestParam) != CY_BLE_SUCCESS)
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_INCL_DISCOVERY_FAILED, &connHandle);
cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
}
}
else /* An included service discovery procedure is done, start a characteristic discovery procedure */
{
if((cy_ble_eventHandlerFlag & CY_BLE_ENABLE_ALL_EVENTS) != 0u)
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_INCL_DISCOVERY_COMPLETE, &connHandle);
}
Cy_BLE_SetConnectionState(connHandle, CY_BLE_CONN_STATE_CLIENT_CHAR_DISCOVERING);
Cy_BLE_NextCharDiscovery(connHandle, CY_BLE_DISCOVERY_INIT);
}
}
/******************************************************************************
* Function Name: Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler
***************************************************************************//**
*
* This function is called on receiving a #CY_BLE_EVT_GATTC_READ_BY_TYPE_RSP
* event. Based on the service UUID, an appropriate data structure is populated
* using the data received as part of the callback.
*
* \param discCharInfo: The pointer to the characteristic information structure.
*
******************************************************************************/
static void Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler(cy_stc_ble_disc_char_info_t *discCharInfo)
{
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(discCharInfo->connHandle);
if((discCharInfo->uuidFormat == CY_BLE_GATT_16_BIT_UUID_FORMAT) &&
(cy_ble_configPtr->context->discovery[discIdx].servCount == cy_ble_gapcConfigPtr->serviceDiscIdx))
{
switch(discCharInfo->uuid.uuid16)
{
case CY_BLE_UUID_CHAR_DEVICE_NAME:
CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].deviceNameCharHandle,
discCharInfo);
break;
case CY_BLE_UUID_CHAR_APPEARANCE:
CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].appearanceCharHandle,
discCharInfo);
break;
case CY_BLE_UUID_CHAR_PERIPH_PRIVCY_FLAG:
CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].periphPrivacyCharHandle,
discCharInfo);
break;
case CY_BLE_UUID_CHAR_RECONNECTION_ADDR:
CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].reconnAddrCharHandle,
discCharInfo);
break;
case CY_BLE_UUID_CHAR_PRFRRD_CNXN_PARAM:
CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].prefConnParamCharHandle,
discCharInfo);
break;
case CY_BLE_UUID_CHAR_CENTRAL_ADDRESS_RESOLUTION:
CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].centralAddrResolutionCharHandle,
discCharInfo);
break;
case CY_BLE_UUID_CHAR_RESOLVABLE_PRIVATE_ADDR_ONLY:
CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].resolvablePrivateAddressOnly, discCharInfo);
break;
default:
break;
}
/* Indicate that request was handled */
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
}
/******************************************************************************
* Function Name: Cy_BLE_ReadByTypeEventHandler
***************************************************************************//**
*
* Handles a Read By Type Response event during an automatic server discovery
* process.
*
* \param eventParam: The event parameters for a Read By Type Response.
*
******************************************************************************/
static void Cy_BLE_ReadByTypeEventHandler(cy_stc_ble_gattc_read_by_type_rsp_param_t *eventParam)
{
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->connHandle);
uint32_t i;
uint32_t j;
if((discIdx < cy_ble_configPtr->params->maxClientCount) &&
(cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u))
{
/* Count of service information pieces in this mtu */
uint32_t locDataLength = (uint32_t)eventParam->attrData.length;
uint32_t attrLength = (uint32_t)eventParam->attrData.attrLen;
uint8_t *attrVal = eventParam->attrData.attrValue;
if(Cy_BLE_GetConnectionState(eventParam->connHandle) == CY_BLE_CONN_STATE_CLIENT_CHAR_DISCOVERING)
{
cy_stc_ble_disc_char_info_t locDiscCharInfo;
locDiscCharInfo.connHandle = eventParam->connHandle;
for(i = 0u; i < attrLength; i += locDataLength)
{
cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
/* Get Handle for characteristic declaration */
locDiscCharInfo.charDeclHandle = Cy_BLE_Get16ByPtr(attrVal);
attrVal += sizeof(locDiscCharInfo.charDeclHandle);
/* Get Properties for value */
locDiscCharInfo.properties = *attrVal;
attrVal += sizeof(locDiscCharInfo.properties);
/* Get Handle to server database attribute value entry */
locDiscCharInfo.valueHandle = Cy_BLE_Get16ByPtr(attrVal);
attrVal += sizeof(locDiscCharInfo.valueHandle);
/* Get Characteristic UUID (128/16 bit) */
if(locDataLength == CY_BLE_DISC_CHAR_INFO_128_LEN)
{
locDiscCharInfo.uuidFormat = CY_BLE_GATT_128_BIT_UUID_FORMAT;
(void)memcpy(&locDiscCharInfo.uuid.uuid128, attrVal, CY_BLE_GATT_128_BIT_UUID_SIZE);
attrVal += CY_BLE_GATT_128_BIT_UUID_SIZE;
}
else if(locDataLength == CY_BLE_DISC_CHAR_INFO_LEN)
{
locDiscCharInfo.uuidFormat = CY_BLE_GATT_16_BIT_UUID_FORMAT;
locDiscCharInfo.uuid.uuid16 = Cy_BLE_Get16ByPtr(attrVal);
attrVal += CY_BLE_GATT_16_BIT_UUID_SIZE;
}
else
{
/* Unsupported data length value */
}
if((locDataLength == CY_BLE_DISC_CHAR_INFO_128_LEN) || (locDataLength == CY_BLE_DISC_CHAR_INFO_LEN))
{
/* Process common services: GAP and GATT */
Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler(&locDiscCharInfo);
Cy_BLE_GATTC_DiscoverCharacteristicsEventHandler(&locDiscCharInfo);
/* Loop thru all registered services and invoke CY_BLE_EVT_GATTC_DISC_CHAR event */
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_CHAR, (void*)&locDiscCharInfo);
}
}
/* The sub-procedure is complete when an Error Response is received and the
* Error Code is set to the Attribute Not Found; or the Read By Type Response has an
* Attribute Handle equal to the Ending Handle of the request - in this case
* a CY_BLE_EVT_GATTC_LONG_PROCEDURE_END event is generated by the BLE Stack. */
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
else if(Cy_BLE_GetConnectionState(eventParam->connHandle) == CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING)
{
bool exitFlag = false;
cy_stc_ble_disc_incl_info_t locDiscInclInfo;
locDiscInclInfo.connHandle = eventParam->connHandle;
for(i = 0u; (i < attrLength) && (exitFlag == false); i += locDataLength)
{
cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
locDiscInclInfo.inclDefHandle = Cy_BLE_Get16ByPtr(attrVal);
attrVal += sizeof(locDiscInclInfo.inclDefHandle);
locDiscInclInfo.inclHandleRange.startHandle = Cy_BLE_Get16ByPtr(attrVal);
attrVal += sizeof(locDiscInclInfo.inclHandleRange.startHandle);
locDiscInclInfo.inclHandleRange.endHandle = Cy_BLE_Get16ByPtr(attrVal);
attrVal += sizeof(locDiscInclInfo.inclHandleRange.endHandle);
if(locDataLength == CY_BLE_DISC_INCL_INFO_128_LEN)
{
cy_stc_ble_gattc_stop_cmd_param_t stopCmdParam;
stopCmdParam.connHandle = eventParam->connHandle;
locDiscInclInfo.uuidFormat = CY_BLE_GATT_128_BIT_UUID_FORMAT;
/* Stop ongoing GATT operation */
(void)Cy_BLE_GATTC_StopCmd(&stopCmdParam);
/* Save handle to support a read response from device */
cy_ble_configPtr->context->discovery[discIdx].inclInfo = locDiscInclInfo;
exitFlag = true;
}
else if(locDataLength == CY_BLE_DISC_INCL_INFO_LEN)
{
uint32_t discServiNum = cy_ble_configPtr->context->discServiCount;
locDiscInclInfo.uuidFormat = CY_BLE_GATT_16_BIT_UUID_FORMAT;
locDiscInclInfo.uuid.uuid16 = Cy_BLE_Get16ByPtr(attrVal);
attrVal += CY_BLE_GATT_16_BIT_UUID_SIZE;
/* Store the range of the included service in the list of services for discovery */
for(j = 0u; j < discServiNum; j++)
{
if( (cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].uuid ==
locDiscInclInfo.uuid.uuid16) &&
(cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].range.startHandle ==
CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE))
{
cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].range =
locDiscInclInfo.inclHandleRange;
break;
}
}
}
else
{
/* Unsupported data length value */
}
/* Loop thru all registered services and invoke CY_BLE_EVT_GATTC_DISC_INCL event */
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_INCL, (void*)&locDiscInclInfo);
}
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
else
{
/* Unhandled state value */
}
}
}
/******************************************************************************
* Function Name: Cy_BLE_NextCharDiscovery
***************************************************************************//**
*
* Looks for a characteristic handle range for the current service (pointed by
* cy_ble_disCount). If the current range is invalid (any of start or end
* handles is invalid), then increments the cy_ble_disCount and check
* the next service range and does so until a valid range is caught or the end
* of the service set is reached.
*
* \param connHandle: The connection handle.
* \param incrementIndex: A non-zero value indicates that the characteristic index
* should be incremented.
*
******************************************************************************/
static void Cy_BLE_NextCharDiscovery(cy_stc_ble_conn_handle_t connHandle,
uint8_t incrementIndex)
{
uint32_t locServCount;
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(connHandle);
uint32_t discServiNum = cy_ble_configPtr->context->discServiCount;
if(incrementIndex != CY_BLE_DISCOVERY_INIT)
{
cy_ble_configPtr->context->discovery[discIdx].servCount++;
}
else
{
cy_ble_configPtr->context->discovery[discIdx].servCount = 0u;
}
locServCount = cy_ble_configPtr->context->discovery[discIdx].servCount;
/* Skip not existing services and services out of the discovery range */
while((cy_ble_configPtr->context->discovery[discIdx].servCount < discServiNum) &&
((cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range.startHandle <
cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) ||
(cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range.startHandle >
cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.endHandle)))
{
++cy_ble_configPtr->context->discovery[discIdx].servCount;
locServCount = cy_ble_configPtr->context->discovery[discIdx].servCount;
}
if(cy_ble_configPtr->context->discovery[discIdx].servCount < discServiNum)
{
cy_stc_ble_gattc_read_by_type_req_t reqParam =
{
.connHandle = connHandle,
.range = cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range
};
if(Cy_BLE_GATTC_DiscoverCharacteristics(&reqParam) != CY_BLE_SUCCESS)
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_CHAR_DISCOVERY_FAILED, &connHandle);
cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
}
}
else /* A Characteristic discovery procedure is done, start a descriptor discovery procedure */
{
if((cy_ble_eventHandlerFlag & CY_BLE_ENABLE_ALL_EVENTS) != 0u)
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_CHAR_DISCOVERY_COMPLETE, &connHandle);
}
Cy_BLE_SetConnectionState(connHandle, CY_BLE_CONN_STATE_CLIENT_DESCR_DISCOVERING);
Cy_BLE_NextCharDscrDiscovery(connHandle, CY_BLE_DISCOVERY_INIT);
}
}
/******************************************************************************
* Function Name: Cy_BLE_FindInfoEventHandler
***************************************************************************//**
*
* Handles a Find Info Response event during an automatic server discovery
* process.
*
* \param eventParam: The event parameters for a Find Info Response.
*
******************************************************************************/
static void Cy_BLE_FindInfoEventHandler(cy_stc_ble_gattc_find_info_rsp_param_t *eventParam)
{
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->connHandle);
/* Discovery descriptor information */
cy_stc_ble_disc_descr_info_t locDiscDescrInfo;
locDiscDescrInfo.descrHandle = CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE;
if((Cy_BLE_GetConnectionState(eventParam->connHandle) == CY_BLE_CONN_STATE_CLIENT_DESCR_DISCOVERING) &&
(discIdx < cy_ble_configPtr->params->maxClientCount) &&
(cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u))
{
uint32_t attrLength = eventParam->handleValueList.byteCount; /* Number of elements on list in bytes */
uint32_t locDataLength;
uint32_t i;
uint8_t *attrVal;
locDiscDescrInfo.uuidFormat = eventParam->uuidFormat;
locDiscDescrInfo.connHandle = eventParam->connHandle;
if(locDiscDescrInfo.uuidFormat == CY_BLE_GATT_16_BIT_UUID_FORMAT)
{
locDataLength = CY_BLE_DB_ATTR_HANDLE_LEN + CY_BLE_GATT_16_BIT_UUID_SIZE;
}
else
{
locDataLength = CY_BLE_DB_ATTR_HANDLE_LEN + CY_BLE_GATT_128_BIT_UUID_SIZE;
}
attrVal = eventParam->handleValueList.list;
for(i = 0u; i < attrLength; i += locDataLength)
{
cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
locDiscDescrInfo.descrHandle = Cy_BLE_Get16ByPtr(attrVal);
attrVal += CY_BLE_DB_ATTR_HANDLE_LEN;
if(locDiscDescrInfo.uuidFormat == CY_BLE_GATT_128_BIT_UUID_FORMAT)
{
(void)memcpy(&locDiscDescrInfo.uuid.uuid128, attrVal, CY_BLE_GATT_128_BIT_UUID_SIZE);
attrVal += CY_BLE_GATT_128_BIT_UUID_SIZE;
}
else
{
locDiscDescrInfo.uuid.uuid16 = Cy_BLE_Get16ByPtr(attrVal);
attrVal += CY_BLE_GATT_16_BIT_UUID_SIZE;
}
/* Process common services: GATT */
Cy_BLE_GATTC_DiscoverCharDescriptorsEventHandler(&locDiscDescrInfo);
/* Loop thru all registered services and invoke CY_BLE_EVT_GATTC_DISC_CHAR event */
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_DESCR, (void*)&locDiscDescrInfo);
}
/* The sub-procedure is complete when an Error Response is received and the
* Error Code is set to the Attribute Not Found or the Find Information Response has
* an Attribute Handle that is equal to the Ending Handle of the request in this
* case a CY_BLE_EVT_GATTC_LONG_PROCEDURE_END event is generated by the BLE Stack. */
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
}
}
/******************************************************************************
* Function Name: Cy_BLE_NextCharDscrDiscovery
***************************************************************************//**
*
* Looks for a handle range for the current descriptor (pointed by
* cy_ble_discovery[discIdx].servCount). If the current range is invalid (any of start or end
* handles is invalid), then increments the cy_ble_discovery[discIdx].servCount and check
* the next descriptor range and does so until a valid range is caught or the
* end of the descriptor set is reached.
*
* \param connHandle: The connection handle.
* \param incrementIndex: A non-zero value indicates that the characteristic index should be
* incremented.
*
******************************************************************************/
static void Cy_BLE_NextCharDscrDiscovery(cy_stc_ble_conn_handle_t connHandle,
uint8_t incrementIndex)
{
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(connHandle);
cy_stc_ble_disc_range_info_t charRangeInfo = { .connHandle = connHandle, .srviIncIdx = incrementIndex };
do
{
cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
charRangeInfo.range.startHandle = CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE;
charRangeInfo.range.endHandle = CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE;
if(incrementIndex == CY_BLE_DISCOVERY_INIT)
{
cy_ble_configPtr->context->discovery[discIdx].servCount = 0u;
cy_ble_configPtr->context->discovery[discIdx].charCount = 0u;
incrementIndex = CY_BLE_DISCOVERY_CONTINUE;
}
/* Get a possible range of the common service: GATT */
Cy_BLE_GATTC_GetCharRange(&charRangeInfo);
/* Loop thru all registered services and get a possible range of the characteristic descriptor */
(void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_DESCR_GET_RANGE, (void*)&charRangeInfo);
if((charRangeInfo.range.startHandle == CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE) ||
(charRangeInfo.range.endHandle == CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE))
{
cy_ble_configPtr->context->discovery[discIdx].servCount++;
cy_ble_configPtr->context->discovery[discIdx].charCount = 0u;
charRangeInfo.srviIncIdx = CY_BLE_DISCOVERY_INIT;
}
else
{
charRangeInfo.srviIncIdx = CY_BLE_DISCOVERY_CONTINUE;
}
/* Skip not existing characteristics and characteristics out of discovery range */
}
while( ((charRangeInfo.range.startHandle <= cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) ||
(charRangeInfo.range.startHandle > cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.endHandle) ||
(charRangeInfo.range.endHandle < cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) ||
(charRangeInfo.range.startHandle > charRangeInfo.range.endHandle)) &&
(cy_ble_configPtr->context->discovery[discIdx].servCount < cy_ble_configPtr->context->discServiCount) );
if(cy_ble_configPtr->context->discovery[discIdx].servCount < cy_ble_configPtr->context->discServiCount)
{
cy_stc_ble_gattc_find_info_req_t reqParam;
/* Fill Error Response parameters */
reqParam.connHandle = connHandle;
reqParam.range = charRangeInfo.range;
if(Cy_BLE_GATTC_DiscoverCharacteristicDescriptors(&reqParam) != CY_BLE_SUCCESS)
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_DESCR_DISCOVERY_FAILED, &connHandle);
cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
}
}
else /* Discovery done */
{
Cy_BLE_SetConnectionState(connHandle, CY_BLE_CONN_STATE_CLIENT_DISCOVERED);
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_DISCOVERY_COMPLETE, &connHandle);
cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
}
}
/******************************************************************************
* Function Name: Cy_BLE_LongProcedureEndEventHandler
***************************************************************************//**
*
* Handles a Long Procedure End event during an automatic server discovery
* process.
*
* \param connHandle: The connection handle.
*
******************************************************************************/
static void Cy_BLE_LongProcedureEndEventHandler(cy_stc_ble_conn_handle_t connHandle)
{
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(connHandle);
if((discIdx < cy_ble_configPtr->params->maxClientCount) &&
(cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u))
{
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
switch(Cy_BLE_GetConnectionState(connHandle))
{
case CY_BLE_CONN_STATE_CLIENT_SRVC_DISCOVERING:
if((cy_ble_eventHandlerFlag & CY_BLE_ENABLE_ALL_EVENTS) != 0u)
{
Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_SRVC_DISCOVERY_COMPLETE, &connHandle);
}
Cy_BLE_SetConnectionState(connHandle, CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING);
Cy_BLE_NextInclDiscovery(connHandle, CY_BLE_DISCOVERY_INIT);
/* Do not propagate this event to the application level during an automatic discovery procedure */
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
break;
case CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING:
Cy_BLE_NextInclDiscovery(connHandle, CY_BLE_DISCOVERY_CONTINUE);
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
break;
case CY_BLE_CONN_STATE_CLIENT_CHAR_DISCOVERING:
Cy_BLE_NextCharDiscovery(connHandle, CY_BLE_DISCOVERY_CONTINUE);
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
break;
case CY_BLE_CONN_STATE_CLIENT_DESCR_DISCOVERING:
Cy_BLE_NextCharDscrDiscovery(connHandle, CY_BLE_DISCOVERY_CONTINUE);
cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
break;
default:
break;
}
}
}
/******************************************************************************
* Function Name: Cy_BLE_ErrorResponseEventHandler
***************************************************************************//**
*
* Handles an Error Response event during an automatic server discovery
* process.
*
* \param eventParam: The event parameters for an Error Response.
*
******************************************************************************/
static void Cy_BLE_ErrorResponseEventHandler(const cy_stc_ble_gatt_err_param_t *eventParam)
{
uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->connHandle);
if( (discIdx < cy_ble_configPtr->params->maxClientCount) &&
(cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u) &&
(eventParam->errInfo.errorCode == CY_BLE_GATT_ERR_ATTRIBUTE_NOT_FOUND) )
{
Cy_BLE_LongProcedureEndEventHandler(eventParam->connHandle);
}
}
#endif /* CY_BLE_LIB_HOST_CORE */
#endif /* CY_IP_MXBLESS */
/* [] END OF FILE */