1 /***************************************************************************//**
2 * \file cy_ble_event_handler.c
3 * \version 3.60
4 *
5 * \brief
6 *  This file contains the source code for the event Handler State Machine
7 *  of the PSoC 6 BLE Middleware.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright 2017-2021, Cypress Semiconductor Corporation.  All rights reserved.
12 * You may use this file only in accordance with the license, terms, conditions,
13 * disclaimers, and limitations in the end user license agreement accompanying
14 * the software package with which this file was provided.
15 *******************************************************************************/
16 
17 #include "cy_ble_event_handler.h"
18 #include "cy_ble_hal_pvt.h"
19 
20 #if defined(CY_IP_MXBLESS)
21 
22 /*******************************************************************************
23 * Global Variables
24 *******************************************************************************/
25 
26 /* Indicates if event is processed by registered services */
27 volatile uint8_t cy_ble_eventHandlerFlag;
28 
29 /* Busy status. Updated from CY_BLE_EVT_STACK_BUSY_STATUS event */
30 // volatile uint8_t cy_ble_busyStatus[CY_BLE_MAX_SUPPORTED_CONN_COUNT];
31 
32 /* The pointers to the callback functions */
33 cy_ble_app_ev_cb_t Cy_BLE_ServerEventHandlerCallback = NULL;
34 cy_ble_app_ev_cb_t Cy_BLE_ClientEventHandlerCallback = NULL;
35 
36 /* Pointer to the BLE device address in SROM */
37 cy_stc_ble_bd_addr_t *cy_ble_sflashDeviceAddress = (cy_stc_ble_bd_addr_t *) SFLASH_BLE_DEVICE_ADDRESS;
38 
39 
40 #if CY_BLE_LIB_HOST_CORE
41 
42 /*******************************************************************************
43 * Private Function Prototypes
44 *******************************************************************************/
45 
46 /* event Handler functions */
47 static void Cy_BLE_TimeOutEventHandler(const cy_stc_ble_timeout_param_t *eventParam);
48 static void Cy_BLE_SendWriteResponse(const cy_stc_ble_gatts_write_cmd_req_param_t *eventParam,
49                                      cy_en_ble_gatt_err_code_t gattErr);
50 
51 static void Cy_BLE_ReadByGroupEventHandler(cy_stc_ble_gattc_read_by_grp_rsp_param_t *eventParam);
52 static void Cy_BLE_ReadByTypeEventHandler(cy_stc_ble_gattc_read_by_type_rsp_param_t *eventParam);
53 static void Cy_BLE_FindInfoEventHandler(cy_stc_ble_gattc_find_info_rsp_param_t *eventParam);
54 static void Cy_BLE_NextCharDiscovery(cy_stc_ble_conn_handle_t connHandle, uint8_t incrementIndex);
55 static void Cy_BLE_NextCharDscrDiscovery(cy_stc_ble_conn_handle_t connHandle, uint8_t incrementIndex);
56 static void Cy_BLE_LongProcedureEndEventHandler(cy_stc_ble_conn_handle_t connHandle);
57 static void Cy_BLE_ErrorResponseEventHandler(const cy_stc_ble_gatt_err_param_t *eventParam);
58 static void Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler(cy_stc_ble_disc_char_info_t *discCharInfo);
59 
60 
61 /******************************************************************************
62 * Function Name: Cy_BLE_RegisterServiceEventHandler
63 ***************************************************************************//**
64 *
65 *  Registration service event Handler
66 *
67 *  \param  eventHandlerFunc: The pointer to the callback procedure.
68 *
69 *  \return
70 *  \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
71 *  failed. The following are possible error codes.
72 *
73 *   Error Codes                           | Description
74 *   ------------                          | -----------
75 *   CY_BLE_SUCCESS                        | The function completed successfully.
76 *   CY_BLE_ERROR_INVALID_PARAMETER        | On specifying NULL as input parameter.
77 *   CY_BLE_ERROR_MEMORY_ALLOCATION_FAILED | Buffer overflow in the registration callback.
78 *
79 ******************************************************************************/
Cy_BLE_RegisterServiceEventHandler(cy_ble_event_handle_t eventHandlerFunc)80 cy_en_ble_api_result_t Cy_BLE_RegisterServiceEventHandler(cy_ble_event_handle_t eventHandlerFunc)
81 {
82     cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
83     bool existFlag = false;
84 
85     if(eventHandlerFunc == NULL)
86     {
87         apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
88     }
89     else
90     {
91         /* Check whether eventHandlerFunc has been already registered */
92         uint32_t idx;
93         for(idx = 0u; (idx < cy_ble_configPtr->context->eventHandlerPool->count) && (existFlag == false); idx++)
94         {
95             if(cy_ble_configPtr->context->eventHandlerPool->serviceEventHandler[idx] == eventHandlerFunc)
96             {
97                 existFlag = true;
98             }
99         }
100     }
101 
102     /* Register eventHandlerFunc callback */
103     if((apiResult == CY_BLE_SUCCESS) && (existFlag == false))
104     {
105         if(cy_ble_configPtr->context->eventHandlerPool->count <
106                cy_ble_configPtr->context->eventHandlerPool->maxServCount)
107         {
108             cy_ble_configPtr->context->eventHandlerPool->
109                      serviceEventHandler[cy_ble_configPtr->context->eventHandlerPool->count] = eventHandlerFunc;
110             cy_ble_configPtr->context->eventHandlerPool->count += 1u;
111         }
112         else
113         {
114             apiResult = CY_BLE_ERROR_MEMORY_ALLOCATION_FAILED;
115         }
116     }
117 
118     return(apiResult);
119 }
120 
121 
122 /******************************************************************************
123 * Function Name: Cy_BLE_InvokeServiceEventHandler
124 ***************************************************************************//**
125 *
126 *  Invoke registered service event handlers.
127 *
128 *  \param eventCode:   The event code.
129 *  \param eventParam:  The event parameters.
130 *
131 *  \return
132 *   A return value of type cy_en_ble_gatt_err_code_t.
133 *
134 ******************************************************************************/
Cy_BLE_InvokeServiceEventHandler(uint32_t eventCode,void * eventParam)135 cy_en_ble_gatt_err_code_t Cy_BLE_InvokeServiceEventHandler(uint32_t eventCode,
136                                                            void *eventParam)
137 {
138     uint32_t idx;
139     cy_en_ble_gatt_err_code_t gattErr = CY_BLE_GATT_ERR_NONE;
140 
141     for(idx = 0u; ( (idx < cy_ble_configPtr->context->eventHandlerPool->count) &&
142                     ((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u) ) ; idx++)
143     {
144         gattErr = cy_ble_configPtr->context->eventHandlerPool->
145                                     serviceEventHandler[idx](eventCode, eventParam);
146     }
147 
148     return(gattErr);
149 }
150 
151 
152 /******************************************************************************
153 * Function Name: Cy_BLE_SendWriteResponse
154 ***************************************************************************//**
155 *
156 *  Sends the Write Response to Write Request when event was handled by service.
157 *
158 *  \param eventParam - The event parameter.
159 *  \param gattErr - The error code.
160 *
161 ******************************************************************************/
Cy_BLE_SendWriteResponse(const cy_stc_ble_gatts_write_cmd_req_param_t * eventParam,cy_en_ble_gatt_err_code_t gattErr)162 static void Cy_BLE_SendWriteResponse(const cy_stc_ble_gatts_write_cmd_req_param_t *eventParam,
163                                      cy_en_ble_gatt_err_code_t gattErr)
164 {
165     cy_stc_ble_gatt_err_param_t err_param;
166     err_param.errInfo.opCode     = CY_BLE_GATT_WRITE_REQ;
167     err_param.errInfo.attrHandle = eventParam->handleValPair.attrHandle;
168     err_param.connHandle         = eventParam->connHandle;
169 
170     /* Send response when event was handled by the service */
171     if((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) == 0u)
172     {
173         if(gattErr != CY_BLE_GATT_ERR_NONE)
174         {
175             /* Send an Error Response */
176             err_param.errInfo.errorCode  = gattErr;
177             (void)Cy_BLE_GATTS_ErrorRsp(&err_param);
178         }
179         else
180         {
181             /* Send an Write Response */
182             (void)Cy_BLE_GATTS_WriteRsp(eventParam->connHandle);
183         }
184     }
185 }
186 
187 
188 /******************************************************************************
189 * Function Name: Cy_BLE_TimeOutEventHandler
190 ***************************************************************************//**
191 *
192 *  Handles a #CY_BLE_EVT_TIMEOUT event from the BLE Stack.
193 *
194 *  \param eventParam: The pointer to a structure of type cy_stc_ble_timeout_param_t.
195 *
196 ******************************************************************************/
Cy_BLE_TimeOutEventHandler(const cy_stc_ble_timeout_param_t * eventParam)197 static void Cy_BLE_TimeOutEventHandler(const cy_stc_ble_timeout_param_t *eventParam)
198 {
199     if((eventParam->reasonCode == CY_BLE_GATT_RSP_TO) &&
200        ((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u) )
201     {
202         uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->CY_BLE_HANDLE.connHandle);
203 
204         if((discIdx < cy_ble_configPtr->params->maxClientCount) &&
205            (cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u))
206         {
207             switch(Cy_BLE_GetConnectionState(eventParam->CY_BLE_HANDLE.connHandle))
208             {
209                 case CY_BLE_CONN_STATE_CLIENT_SRVC_DISCOVERING:
210                     Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_SRVC_DISCOVERY_FAILED,
211                                         (cy_stc_ble_conn_handle_t*)&eventParam->CY_BLE_HANDLE.connHandle);
212                     break;
213 
214                 case CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING:
215                     Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_INCL_DISCOVERY_FAILED,
216                                         (cy_stc_ble_conn_handle_t*)&eventParam->CY_BLE_HANDLE.connHandle);
217                     break;
218 
219                 case CY_BLE_CONN_STATE_CLIENT_CHAR_DISCOVERING:
220                     Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_CHAR_DISCOVERY_FAILED,
221                                         (cy_stc_ble_conn_handle_t*)&eventParam->CY_BLE_HANDLE.connHandle);
222                     break;
223 
224                 case CY_BLE_CONN_STATE_CLIENT_DESCR_DISCOVERING:
225                     Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_DESCR_DISCOVERY_FAILED,
226                                         (cy_stc_ble_conn_handle_t*)&eventParam->CY_BLE_HANDLE.connHandle);
227                     break;
228 
229                 default:        /* Other states should not be set in Auto discovery mode */
230                     break;
231             }
232             cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
233             Cy_BLE_SetConnectionState(eventParam->CY_BLE_HANDLE.connHandle, CY_BLE_CONN_STATE_CONNECTED);
234         }
235     }
236 
237     if((cy_ble_configPtr->params->gapRole & CY_BLE_GAP_CENTRAL) != 0u)
238     {
239         /* Connection procedure timeout */
240         if((eventParam->reasonCode == CY_BLE_GENERIC_APP_TO) &&
241            (cy_ble_connectingTimeout.timerHandle == eventParam->timerHandle) &&
242            (Cy_BLE_GetState() == CY_BLE_STATE_CONNECTING))
243         {
244             (void)Cy_BLE_GAPC_CancelDeviceConnection();
245         }
246     }
247 }
248 
249 
250 /******************************************************************************
251 * Function Name: Cy_BLE_IsDeviceAddressValid
252 ***************************************************************************//**
253 *
254 *  This function verifies that the device address is valid (not equal zero)
255 *
256 *  \param deviceAddress: The pointer to the BD address of
257 *                        type #cy_stc_ble_bd_addr_t.
258 *
259 *  \return
260 *   A non-zero value when a device address is valid
261 *
262 ******************************************************************************/
Cy_BLE_IsDeviceAddressValid(const cy_stc_ble_bd_addr_t * deviceAddress)263 uint8_t Cy_BLE_IsDeviceAddressValid(const cy_stc_ble_bd_addr_t *deviceAddress)
264 {
265     uint8_t addressValid = 0u;
266     uint32_t i;
267 
268     if(deviceAddress->type == CY_BLE_GAP_ADDR_TYPE_PUBLIC)
269     {
270         for(i = 0u; i < CY_BLE_GAP_BD_ADDR_SIZE; i++)
271         {
272             if(deviceAddress->bdAddr[i] != 0u)
273             {
274                 addressValid = 1u;
275                 break;
276             }
277         }
278     }
279 
280     return(addressValid);
281 }
282 
283 
284 /******************************************************************************
285 * Function Name: Cy_BLE_EventHandler
286 ***************************************************************************//**
287 *
288 *  Handles events from the BLE Stack.
289 *
290 *  \param event:   The event code.
291 *  \param evParam: The event parameters.
292 *
293 ******************************************************************************/
Cy_BLE_EventHandler(cy_en_ble_event_t event,void * evParam)294 void Cy_BLE_EventHandler(cy_en_ble_event_t event, void *evParam)
295 {
296     /* Internal status of commands execution */
297     static volatile uint32_t cy_ble_cmdStatus;
298 
299     cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
300 
301     /* Common Profile event handling */
302     switch(event)
303     {
304         /**********************************************************
305          * General events
306          ************************************************************/
307 
308         case CY_BLE_EVT_HCI_PKT_RCVD:
309         {
310             cy_stc_ble_hci_tx_packet_info_t *HciPktParams = (cy_stc_ble_hci_tx_packet_info_t*)evParam;
311             Cy_BLE_HAL_MappingSoftHciHostReceiveControllerPkt(HciPktParams);
312 
313             /* Clear the CY_BLE_CALLBACK flag not to provide a handled event to the application */
314             cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
315         }
316         break;
317 
318         case CY_BLE_EVT_STACK_ON:
319 
320             /* Initializes internal state variables */
321             cy_ble_scanningIntervalType = CY_BLE_SCANNING_FAST;
322             cy_ble_advertisingIntervalType = CY_BLE_ADVERTISING_FAST;
323             (void)memset((uint8_t*)&cy_ble_busyStatus, 0, sizeof(cy_ble_busyStatus));
324             (void)memset(&cy_ble_connState, 0, sizeof(cy_ble_connState));
325             cy_ble_cmdStatus = 0u;
326 
327             /* Set a device address  */
328             if(Cy_BLE_IsDeviceAddressValid(cy_ble_sflashDeviceAddress) != 0u)
329             {
330                 (void)Cy_BLE_GAP_SetBdAddress(cy_ble_sflashDeviceAddress);
331 
332                 if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
333                 {
334                     Cy_BLE_ChangeAdDeviceAddress(cy_ble_sflashDeviceAddress, 0u);
335                     Cy_BLE_ChangeAdDeviceAddress(cy_ble_sflashDeviceAddress, 1u);
336                 }
337             }
338             else
339             {
340                 if(cy_ble_configPtr->params->siliconDeviceAddressEn)
341                 {
342                     uint32_t bdAddrLoc;
343                     bdAddrLoc = ((uint32_t)SFLASH_DIE_X & (uint32_t)CY_BLE_SFLASH_DIE_X_MASK) |
344                                 ((uint32_t)(((uint32_t)SFLASH_DIE_Y) & ((uint32_t)CY_BLE_SFLASH_DIE_Y_MASK)) <<
345                                     CY_BLE_SFLASH_DIE_X_BITS) |
346                                 ((uint32_t)(((uint32_t)SFLASH_DIE_WAFER) & ((uint32_t)CY_BLE_SFLASH_DIE_WAFER_MASK)) <<
347                                     CY_BLE_SFLASH_DIE_XY_BITS) |
348                                 ((uint32_t)(((uint32_t)SFLASH_DIE_LOT(0)) & ((uint32_t)CY_BLE_SFLASH_DIE_LOT_MASK)) <<
349                                     CY_BLE_SFLASH_DIE_XYWAFER_BITS);
350 
351                     cy_ble_configPtr->deviceAddress->bdAddr[0] = (uint8_t)bdAddrLoc;
352                     cy_ble_configPtr->deviceAddress->bdAddr[1] = (uint8_t)(bdAddrLoc >> 8u);
353                     cy_ble_configPtr->deviceAddress->bdAddr[2] = (uint8_t)(bdAddrLoc >> 16u);
354                 }
355                 (void)Cy_BLE_GAP_SetBdAddress(cy_ble_configPtr->deviceAddress);
356 
357                 if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
358                 {
359                     Cy_BLE_ChangeAdDeviceAddress(cy_ble_configPtr->deviceAddress, 0u);
360                     Cy_BLE_ChangeAdDeviceAddress(cy_ble_configPtr->deviceAddress, 1u);
361                 }
362             }
363 
364             /* Set the device IO Capability  */
365             (void)Cy_BLE_GAP_SetIoCap((cy_en_ble_gap_iocap_t*)&cy_ble_configPtr->params->securityIoCapability);
366 
367             /* Enable all 4.1 events and configured 4.2 events */
368             {
369                 uint8_t leMask[CY_BLE_LE_MASK_LENGTH] = {CY_LO8(CY_BLE_LE_MASK),
370                                                          CY_HI8(CY_BLE_LE_MASK), 0u, 0u, 0u, 0u, 0u, 0u };
371                 (void)Cy_BLE_SetLeEventMask(leMask);
372             }
373 
374             /* Update BLE state  */
375             Cy_BLE_SetState(CY_BLE_STATE_ON);
376         break;
377 
378         case CY_BLE_EVT_SOFT_RESET_COMPLETE:
379         case CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE:
380 
381             /* Update BLE / Adv. / Scan states  */
382             Cy_BLE_SetState(CY_BLE_STATE_STOPPED);
383 
384             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
385             {
386                 Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
387             }
388 
389             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_CENTRAL | CY_BLE_GAP_OBSERVER)) != 0u)
390             {
391                 Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_STOPPED);
392             }
393 
394             /* Clean pair status */
395             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
396             {
397                 (void)memset((uint8_t*)cy_ble_pairStatus, 0, sizeof(cy_ble_pairStatus));
398             }
399 
400             #if defined(COMPONENT_BLESS_HOST_IPC)
401             /* Adding a delay of 10ms to ensure that the controller is completely
402              * shut-down before generating the event to the application.
403              * Refer to CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE event documentation. */
404             Cy_SysLib_Delay(10u);
405             #endif /* defined(COMPONENT_BLESS_HOST_IPC) */
406 
407             if ( event == CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE)
408             {
409                 /* Unregister BLE SysPm callback for deep sleep/sleep */
410                 if (Cy_BLE_UnregisterPmCallbacksPtr != NULL)
411                 {
412                     Cy_BLE_UnregisterPmCallbacksPtr();
413                 }
414             }
415         break;
416 
417         case CY_BLE_EVT_LE_SET_EVENT_MASK_COMPLETE:
418             if((cy_ble_cmdStatus & CY_BLE_STATUS_SET_TX_PWR_LVL) == 0u)
419             {
420                 cy_stc_ble_tx_pwr_lvl_info_t bleSsPowerLevel;
421 
422                 /* Set the Tx Power Level for advertising channel */
423                 bleSsPowerLevel.blePwrLevel = cy_ble_configPtr->params->txPowerLevelAdv;
424                 bleSsPowerLevel.pwrConfigParam.bleSsChId = CY_BLE_LL_ADV_CH_TYPE;
425                 bleSsPowerLevel.pwrConfigParam.bdHandle = 0x0u;
426                 (void)Cy_BLE_SetTxPowerLevel(&bleSsPowerLevel);
427 
428                 /* Set the Tx Power Level for connection channel */
429                 bleSsPowerLevel.blePwrLevel = cy_ble_configPtr->params->txPowerLevelConn;
430                 bleSsPowerLevel.pwrConfigParam.bleSsChId = CY_BLE_LL_CONN_CH_TYPE;
431                 bleSsPowerLevel.pwrConfigParam.bdHandle = 0xFFu; /* Set the tx power level value for all connection handles.*/
432                 (void)Cy_BLE_SetTxPowerLevel(&bleSsPowerLevel);
433 
434                 /* Set flag that executed Cy_BLE_SetTxPowerLevel during BLE start-up  */
435                 cy_ble_cmdStatus |= CY_BLE_STATUS_SET_TX_PWR_LVL;
436             }
437         break;
438 
439         case CY_BLE_EVT_TIMEOUT:
440             /* Internal Timeout Handling */
441             Cy_BLE_TimeOutEventHandler((cy_stc_ble_timeout_param_t*)evParam);
442 
443             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
444             {
445                 (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
446             }
447         break;
448 
449         case CY_BLE_EVT_STACK_BUSY_STATUS:
450             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
451             {
452                 cy_ble_busyStatus[Cy_BLE_GetConnHandleByBdHandle(((cy_stc_ble_l2cap_state_info_t*)evParam)->bdHandle).attId] =
453                    ((cy_stc_ble_l2cap_state_info_t*)evParam)->flowState;
454             }
455         break;
456 
457         case CY_BLE_EVT_MEMORY_REQUEST:
458         {
459             cy_stc_ble_memory_request_t *memReq = (cy_stc_ble_memory_request_t*)evParam;
460 
461             if( (!cy_ble_configPtr->params->gattPrepareWriteExtBuffEn) &&
462                 (memReq->request == CY_BLE_PREPARED_WRITE_REQUEST) )
463             {
464                 /* Stack requests to provide memory to process a remote request */
465                 if(memReq->allocFree == CY_BLE_ALLOC_MEMORY)
466                 {
467                     static cy_stc_ble_prepare_write_request_memory_t gPrepWriteReqMem;
468 
469                     /* Prepare write buffer locates at the end of memoryHeap */
470                     uint16_t bufferAddr = cy_ble_configPtr->stackParam->totalHeapSz;
471 
472                     /* Configure and return a statically allocated buffer at the end of the cy_ble_stackMemoryRam buffer */
473                     gPrepWriteReqMem.prepareWriteQueueSize = cy_ble_configPtr->params->gattPrepareWriteQueueSize;
474                     gPrepWriteReqMem.totalAttrValueLength  = cy_ble_configPtr->params->totalAttrValueLength;
475                     gPrepWriteReqMem.queueBuffer           = &cy_ble_configPtr->stackParam->memoryHeapPtr[bufferAddr];
476                     memReq->configMemory = &gPrepWriteReqMem;
477                 }
478 
479                 /* Clear the CY_BLE_CALLBACK flag not to provide a handled event to the application */
480                 cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
481             }
482         }
483         break;
484 
485         /**********************************************************
486          * GAP events
487          ************************************************************/
488 
489         case CY_BLE_EVT_GAP_AUTH_COMPLETE:
490             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
491             {
492                 cy_stc_ble_conn_handle_t connectedHandle;
493                 connectedHandle = Cy_BLE_GetConnHandleByBdHandle(((cy_stc_ble_gap_auth_info_t*)evParam)->bdHandle);
494 
495                 if(cy_ble_configPtr->params->isBondingReq == CY_BLE_BONDING_YES)
496                 {
497                     cy_ble_peerBonding[connectedHandle.attId] = ((cy_stc_ble_gap_auth_info_t*)evParam)->bonding;
498                 }
499 
500                 if(((cy_stc_ble_gap_auth_info_t *)evParam)->authErr == CY_BLE_GAP_AUTH_ERROR_NONE)
501                 {
502                     cy_ble_pairStatus[connectedHandle.attId] = true;
503                 }
504             }
505         break;
506 
507         case CY_BLE_EVT_GAP_CONNECTION_UPDATE_COMPLETE:
508             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
509             {
510                 (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
511             }
512         break;
513 
514         case CY_BLE_EVT_GAP_ENHANCE_CONN_COMPLETE:
515         case CY_BLE_EVT_GAP_DEVICE_CONNECTED:
516             {
517                 uint8_t cmdStatus;
518                 uint8_t deviceDdHandle = 0u;
519                 uint8_t deviceRole = 0u;
520 
521                 if((cy_ble_configPtr->stackParam->featureMask & CY_BLE_PRIVACY_1_2_FEATURE_MASK) != 0u)
522                 {
523                     cmdStatus = ((cy_stc_ble_gap_enhance_conn_complete_param_t *) evParam)->status;
524                     if(cmdStatus == CY_BLE_HCI_SUCCESS)
525                     {
526                         deviceDdHandle = ((cy_stc_ble_gap_enhance_conn_complete_param_t *) evParam)->bdHandle;
527                         deviceRole = ((cy_stc_ble_gap_enhance_conn_complete_param_t *) evParam)->role;
528                     }
529                 }
530                 else
531                 {
532                     cmdStatus = ((cy_stc_ble_gap_connected_param_t *) evParam)->status;
533                     if(cmdStatus == CY_BLE_HCI_SUCCESS)
534                     {
535                         deviceDdHandle = ((cy_stc_ble_gap_connected_param_t *) evParam)->bdHandle;
536                         deviceRole = ((cy_stc_ble_gap_connected_param_t *) evParam)->role;
537                     }
538                 }
539 
540                 if(cmdStatus == CY_BLE_HCI_SUCCESS)
541                 {
542                     /* Advertising is automatically stopped if a Slave is connected,
543                        so update the adv state to CY_BLE_ADV_STATE_STOPPED  */
544                     if( ((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u) &&
545                         (deviceRole == CY_BLE_GAP_LL_ROLE_SLAVE) )
546                     {
547                         Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
548                     }
549 
550                     /* Stop Timer in central mode (if timer was started) */
551                     if(((cy_ble_configPtr->params->gapRole & CY_BLE_GAP_CENTRAL) != 0u) &&
552                         (cy_ble_connectingTimeout.timeout != 0u))
553                     {
554                         (void)Cy_BLE_StopTimer(&cy_ble_connectingTimeout);
555                     }
556 
557                     /* Store information about role of device connected (Master/Slave)*/
558                     if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
559                     {
560                         cy_stc_ble_conn_handle_t tconnHandle = Cy_BLE_GetConnHandleByBdHandle(deviceDdHandle);
561                         if( tconnHandle.attId != CY_BLE_INVALID_CONN_HANDLE_VALUE)
562                         {
563                             cy_ble_devConnRole[tconnHandle.attId] = deviceRole;
564                         }
565                     }
566                 }
567                 Cy_BLE_SetState(CY_BLE_STATE_ON);
568             }
569         break;
570 
571         case CY_BLE_EVT_GAP_DEVICE_DISCONNECTED:
572             Cy_BLE_SetState(CY_BLE_STATE_ON);
573         break;
574 
575         case CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
576             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_BROADCASTER | CY_BLE_GAP_PERIPHERAL)) ==
577                     (CY_BLE_GAP_BROADCASTER | CY_BLE_GAP_PERIPHERAL))
578             {
579                 (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
580             }
581 
582             if((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u)
583             {
584                 /* After Cy_BLE_GAPP_StartAdvertisement, the first event indicates that advertising has started */
585                 if(Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_ADV_INITIATED)
586                 {
587                     Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_ADVERTISING);
588                 }
589                 /* When the application initiated a stop advertisement */
590                 else if(Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_STOP_INITIATED)
591                 {
592                     Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
593                 }
594                 /* The following event indicates that advertising has been stopped */
595                 else if(Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_ADVERTISING)
596                 {
597                     Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
598 
599                     /* Enable slow advertising, if need */
600                     if((cy_ble_configPtr->gappAdvParams[cy_ble_advIndex].slowAdvEnable != 0u) &&
601                        (cy_ble_configPtr->gappAdvParams[cy_ble_advIndex].fastAdvTimeOut != 0u) &&
602                        (cy_ble_advertisingIntervalType == CY_BLE_ADVERTISING_FAST))
603                     {
604                         if(Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_SLOW, cy_ble_advIndex) == CY_BLE_SUCCESS)
605                         {
606                             Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_ADV_INITIATED);
607                         }
608                     }
609                 }
610                 else
611                 {
612                     /* Empty else */
613                 }
614             }
615         break;
616 
617         case CY_BLE_EVT_GAPC_SCAN_START_STOP:
618             if((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u)
619             {
620                 (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
621             }
622 
623             if((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u)
624             {
625                 /* After Cy_BLE_GAPC_StartScan, the first event indicates that scanning has been started */
626                 if(Cy_BLE_GetScanState() == CY_BLE_SCAN_STATE_SCAN_INITIATED)
627                 {
628                     Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_SCANNING);
629                 }
630                 /* When the application initiated stop scanning */
631                 else if(Cy_BLE_GetScanState() == CY_BLE_SCAN_STATE_STOP_INITIATED)
632                 {
633                     Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_STOPPED);
634                 }
635                 /* The following event indicates that scanning has been stopped by BLE Stack */
636                 else if(Cy_BLE_GetScanState() == CY_BLE_SCAN_STATE_SCANNING)
637                 {
638                     Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_STOPPED);
639                     if((cy_ble_configPtr->gapcScanParams[cy_ble_scanIndex].slowScanEnabled != 0u) &&
640                        (cy_ble_configPtr->gapcScanParams[cy_ble_scanIndex].fastScanTimeOut != 0u) &&
641                        (cy_ble_scanningIntervalType == CY_BLE_SCANNING_FAST))
642                     {
643                         if(Cy_BLE_GAPC_StartScan(CY_BLE_SCANNING_SLOW, cy_ble_scanIndex) == CY_BLE_SUCCESS)
644                         {
645                             Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_SCAN_INITIATED);
646                         }
647                     }
648                 }
649                 else
650                 {
651                     /* Empty else */
652                 }
653             }
654         break;
655 
656 
657         /**********************************************************
658          * L2AP events
659          ************************************************************/
660         case CY_BLE_EVT_L2CAP_CONN_PARAM_UPDATE_RSP:
661             if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL)) != 0u)
662             {
663                 (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
664             }
665          break;
666 
667 
668         /**********************************************************
669          * GATT events
670          ************************************************************/
671         case CY_BLE_EVT_GATT_CONNECT_IND:
672             {
673                 cy_stc_ble_conn_handle_t *locConnHandle = (cy_stc_ble_conn_handle_t*)evParam;
674 
675                 /* If connected to the same device which is already discovered */
676                 if( ((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u) &&
677                     (Cy_BLE_GetConnectionState(*locConnHandle) == CY_BLE_CONN_STATE_CLIENT_DISCONNECTED_DISCOVERED) &&
678                     (locConnHandle->bdHandle == cy_ble_connHandle[locConnHandle->attId].bdHandle))
679                 {   /* Set a discovered state */
680                     Cy_BLE_SetConnectionState(*(cy_stc_ble_conn_handle_t*)evParam, CY_BLE_CONN_STATE_CLIENT_DISCOVERED);
681                 }
682                 else    /* Connected to a new device */
683                 {
684                     /* Clear the discovery index for the client role */
685                     if( (cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u)
686                     {
687                         (void)Cy_BLE_GATTC_RemoveConnHandle(*(cy_stc_ble_conn_handle_t*)evParam);
688                     }
689                     Cy_BLE_SetConnectionState(*locConnHandle, CY_BLE_CONN_STATE_CONNECTED);
690                     cy_ble_connHandle[locConnHandle->attId] = *locConnHandle;
691                 }
692                 cy_ble_busyStatus[locConnHandle->attId] = CY_BLE_STACK_STATE_FREE;
693 
694                 if( ((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_SERVER) != 0u) &&
695                     (cy_ble_configPtr->params->isBondingReq == CY_BLE_BONDING_YES) &&
696                     (cy_ble_configPtr->flashStorage->cccdCount != 0u) )
697                 {
698                     /* Initialize the CCCD values in the RAM when bonding is enabled */
699                     uint32_t cccdBlockSize = cy_ble_configPtr->flashStorage->cccdCount + CY_BLE_CCCD_CRC_BYTE;
700                     uint32_t cccdBlockOffsetRam = locConnHandle->attId * cccdBlockSize;
701                     uint32_t cccdBlockCrcOffset = cccdBlockSize - CY_BLE_CCCD_CRC_BYTE;
702                     uint8_t calcCrc;
703 
704                     (void)memcpy(&cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam],
705                                  &cy_ble_configPtr->flashStorage->cccdFlashPtr[locConnHandle->bdHandle * cccdBlockSize],
706                                  cccdBlockSize);
707 
708                     /* Check CRC for CCCD data */
709                     calcCrc = Cy_BLE_HAL_CalcCRC8(&cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam],
710                                                   cy_ble_configPtr->flashStorage->cccdCount);
711 
712                     if(cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam  + cccdBlockCrcOffset] != calcCrc)
713                     {
714 
715                         /* Inform that the CRC for CCCD is wrong */
716                         Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTS_EVT_CCCD_CORRUPT, NULL);
717 
718                         /* Clean the CCCD buffer in the RAM */
719                         (void)memset(&cy_ble_configPtr->flashStorage->cccdRamPtr[locConnHandle->attId * cccdBlockSize],
720                                       0, cccdBlockSize);
721                     }
722                 }
723                 (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
724             }
725         break;
726 
727         case CY_BLE_EVT_GATT_DISCONNECT_IND:
728             {
729                 cy_stc_ble_conn_handle_t *locConnHandle = (cy_stc_ble_conn_handle_t*)evParam;
730 
731                 if( ((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u) &&
732                     (Cy_BLE_GetConnectionState(*locConnHandle) == CY_BLE_CONN_STATE_CLIENT_DISCOVERED) &&
733                     (cy_ble_configPtr->params->isBondingReq == CY_BLE_BONDING_YES) )
734                 {
735                     Cy_BLE_SetConnectionState(*(cy_stc_ble_conn_handle_t*)evParam,
736                                               CY_BLE_CONN_STATE_CLIENT_DISCONNECTED_DISCOVERED);
737                 }
738                 else
739                 {
740                     Cy_BLE_SetConnectionState(*(cy_stc_ble_conn_handle_t*)evParam, CY_BLE_CONN_STATE_DISCONNECTED);
741 
742                     if((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u)
743                     {
744                         (void)Cy_BLE_GATTC_RemoveConnHandle(*(cy_stc_ble_conn_handle_t*)evParam);
745                     }
746                 }
747 
748                 if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_CENTRAL )) != 0u)
749                 {
750                     cy_ble_pairStatus[(*(cy_stc_ble_conn_handle_t *)evParam).attId] = false;
751                 }
752                 (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
753             }
754         break;
755 
756         case CY_BLE_EVT_GATTS_XCNHG_MTU_REQ:
757         {
758             cy_stc_ble_gatt_xchg_mtu_param_t mtuParam;
759             mtuParam.connHandle = ((cy_stc_ble_gatt_xchg_mtu_param_t*)evParam)->connHandle;
760             mtuParam.mtu = cy_ble_configPtr->params->mtuSize ;
761 
762             (void)Cy_BLE_GATTS_ExchangeMtuRsp(&mtuParam);
763         }
764         break;
765 
766         case CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT:
767             (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
768         break;
769 
770         case CY_BLE_EVT_PENDING_FLASH_WRITE:
771             cy_ble_pendingFlashWrite |= CY_BLE_PENDING_STACK_FLASH_WRITE_BIT;
772         break;
773 
774         default:
775             break;
776     }
777 
778     /* Handling GATT server events */
779     if(((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u) && (Cy_BLE_ServerEventHandlerCallback != NULL))
780     {
781         Cy_BLE_ServerEventHandlerCallback(event, evParam);
782     }
783 
784     /* Handling GATT client events */
785     if(((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u) && (Cy_BLE_ClientEventHandlerCallback != NULL))
786     {
787         Cy_BLE_ClientEventHandlerCallback(event, evParam);
788     }
789 
790     /* Call Cy_BLE_ApplCallback if event was not processed */
791     if((cy_ble_eventHandlerFlag & (CY_BLE_CALLBACK | CY_BLE_ENABLE_ALL_EVENTS)) != 0u)
792     {
793         cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
794         Cy_BLE_ApplCallback((uint32_t)event, evParam);
795     }
796 }
797 
798 
799 /******************************************************************************
800 * Function Name: Cy_BLE_ServerEventHandler
801 ***************************************************************************//**
802 *
803 *  Handles server events from the BLE Stack.
804 *
805 *  \param event:   The event code.
806 *  \param evParam: The event parameters.
807 *
808 ******************************************************************************/
Cy_BLE_ServerEventHandler(cy_en_ble_event_t event,void * evParam)809 void Cy_BLE_ServerEventHandler(cy_en_ble_event_t event, void *evParam)
810 {
811     /* Common Profile event handling */
812     switch(event)
813     {
814         case CY_BLE_EVT_GATTS_WRITE_REQ:
815         {
816             cy_en_ble_gatt_err_code_t gattErr;
817             cy_ble_gatt_db_attr_handle_t attrHandle;
818 
819             /* Process GATT service */
820             gattErr = Cy_BLE_GATTS_WriteEventHandler((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam);
821 
822             /* Process all registered service */
823             if(gattErr == CY_BLE_GATT_ERR_NONE)
824             {
825                 gattErr = Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
826             }
827             Cy_BLE_SendWriteResponse((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam, gattErr);
828 
829             /* Call Cy_BLE_ApplCallback if event was not processed */
830             if((cy_ble_eventHandlerFlag & (CY_BLE_CALLBACK | CY_BLE_ENABLE_ALL_EVENTS)) != 0u)
831             {
832                 Cy_BLE_ApplCallback((uint32_t)event, evParam);
833             }
834 
835             /* Send Error response if unknown attr handle */
836             attrHandle = ((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam)->handleValPair.attrHandle;
837             if( ((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u) &&
838                 ((attrHandle > cy_ble_configPtr->params->gattDbIndexCount) || (attrHandle == 0u)))
839             {
840                 /* Processing unknown attr handle (send an Error Response) */
841                 cy_stc_ble_gatt_err_param_t err_param;
842                 err_param.errInfo.opCode     = CY_BLE_GATT_WRITE_REQ;
843                 err_param.errInfo.attrHandle = ((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam)->handleValPair.attrHandle;
844                 err_param.connHandle         = ((cy_stc_ble_gatts_write_cmd_req_param_t*)evParam)->connHandle;
845                 err_param.errInfo.errorCode  = CY_BLE_GATT_ERR_INVALID_HANDLE;
846 
847                 (void)Cy_BLE_GATTS_ErrorRsp(&err_param);
848             }
849 
850             /* Indicate that request was handled */
851             cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
852         }
853         break;
854 
855         case CY_BLE_EVT_GATTS_WRITE_CMD_REQ:
856         case CY_BLE_EVT_GATTS_PREP_WRITE_REQ:
857         case CY_BLE_EVT_GATTS_EXEC_WRITE_REQ:
858         case CY_BLE_EVT_GATTS_HANDLE_VALUE_CNF:
859             (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
860             break;
861 
862         case CY_BLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ:
863             if(cy_ble_configPtr->flashStorage->cccdCount != 0u)
864             {
865                 (void)Cy_BLE_GATTS_ReadAttributeValueCCCDReqHandler((cy_stc_ble_gatts_char_val_read_req_t*)evParam);
866             }
867             (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
868             break;
869 
870         default:
871             break;
872     }
873 }
874 
875 
876 /******************************************************************************
877 * Function Name: Cy_BLE_ClientEventHandler
878 ***************************************************************************//**
879 *
880 *  Handles client events from the BLE Stack.
881 *
882 *  \param event:   The event code.
883 *  \param evParam: The event parameters.
884 *
885 ******************************************************************************/
Cy_BLE_ClientEventHandler(cy_en_ble_event_t event,void * evParam)886 void Cy_BLE_ClientEventHandler(cy_en_ble_event_t event, void *evParam)
887 {
888     /* Common Profile event handling */
889     switch(event)
890     {
891         case CY_BLE_EVT_GATTC_READ_BY_GROUP_TYPE_RSP:
892             Cy_BLE_ReadByGroupEventHandler((cy_stc_ble_gattc_read_by_grp_rsp_param_t*)evParam);
893             break;
894 
895         case CY_BLE_EVT_GATTC_READ_BY_TYPE_RSP:
896             Cy_BLE_ReadByTypeEventHandler((cy_stc_ble_gattc_read_by_type_rsp_param_t*)evParam);
897             break;
898 
899         case CY_BLE_EVT_GATTC_READ_BLOB_RSP:
900             (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
901             break;
902 
903         case CY_BLE_EVT_GATTC_LONG_PROCEDURE_END:
904             Cy_BLE_LongProcedureEndEventHandler(((cy_stc_ble_gattc_long_procedure_end_param_t*)evParam)->connHandle);
905             break;
906 
907         case CY_BLE_EVT_GATTC_FIND_INFO_RSP:
908             Cy_BLE_FindInfoEventHandler((cy_stc_ble_gattc_find_info_rsp_param_t*)evParam);
909             break;
910 
911         case CY_BLE_EVT_GATTC_ERROR_RSP:
912             Cy_BLE_ErrorResponseEventHandler((cy_stc_ble_gatt_err_param_t*)evParam);
913             (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
914             break;
915 
916         case CY_BLE_EVT_GATTC_HANDLE_VALUE_IND:
917             Cy_BLE_GATTC_IndicationEventHandler((cy_stc_ble_gattc_handle_value_ind_param_t*)evParam);
918             (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
919 
920             /* Respond with a Handle Value Confirmation when request handled */
921             if((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) == 0u)
922             {
923                 cy_stc_ble_gattc_confirmation_req_t confirmationParam;
924                 confirmationParam.connHandle = ((cy_stc_ble_gattc_handle_value_ind_param_t*)evParam)->connHandle;
925 
926                 (void)Cy_BLE_GATTC_Confirmation(&confirmationParam);
927             }
928             break;
929 
930         case CY_BLE_EVT_GATTC_HANDLE_VALUE_NTF:
931         case CY_BLE_EVT_GATTC_READ_RSP:
932         case CY_BLE_EVT_GATTC_READ_MULTI_RSP:
933         case CY_BLE_EVT_GATTC_WRITE_RSP:
934         case CY_BLE_EVT_GATTC_EXEC_WRITE_RSP:
935             (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)event, (void*)evParam);
936             break;
937 
938         case CY_BLE_EVT_GATTC_STOP_CMD_COMPLETE:
939             {
940                 cy_stc_ble_conn_handle_t locConnHandle = *(cy_stc_ble_conn_handle_t *)evParam;
941                 uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(locConnHandle);
942 
943                 if( (Cy_BLE_GetConnectionState(locConnHandle) == CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING) &&
944                     (discIdx < cy_ble_configPtr->params->maxClientCount) &&
945                     (cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u) )
946                 {
947                     cy_stc_ble_gattc_read_req_t readReqParam;
948                     /* Fill Read Request parameters */
949                     readReqParam.attrHandle =
950                         cy_ble_configPtr->context->discovery[discIdx].inclInfo.inclHandleRange.startHandle;
951                     readReqParam.connHandle = locConnHandle;
952 
953                     /* Get the included service UUID when the included service uses a 128-bit
954                      * UUID, a Read Request is used. The Attribute Handle for the Read Request is
955                      * the Attribute Handle of the included service.
956                      */
957 
958                     if(Cy_BLE_GATTC_ReadCharacteristicValue(&readReqParam) != CY_BLE_SUCCESS)
959                     {
960                         Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_INCL_DISCOVERY_FAILED, &locConnHandle);
961                         cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
962                     }
963 
964                     cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
965                 }
966             }
967             break;
968 
969         default:
970             break;
971     }
972 }
973 
974 
975 /******************************************************************************
976 * Function Name: Cy_BLE_ReadByGroupEventHandler
977 ***************************************************************************//**
978 *
979 *  Handles a Read By Group Response event during an automatic server discovery
980 *  process.
981 *
982 *  \param eventParam: The event parameters for a Read By Group Response.
983 *
984 ******************************************************************************/
Cy_BLE_ReadByGroupEventHandler(cy_stc_ble_gattc_read_by_grp_rsp_param_t * eventParam)985 static void Cy_BLE_ReadByGroupEventHandler(cy_stc_ble_gattc_read_by_grp_rsp_param_t *eventParam)
986 {
987     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->connHandle);
988 
989     if( (Cy_BLE_GetConnectionState(eventParam->connHandle) == CY_BLE_CONN_STATE_CLIENT_SRVC_DISCOVERING) &&
990         (discIdx < cy_ble_configPtr->params->maxClientCount) &&
991         (cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u) )
992     {
993         uint16_t locDataLength = eventParam->attrData.length;
994         uint16_t attrLength;
995 
996         if((locDataLength == CY_BLE_DISC_SRVC_INFO_LEN) || (locDataLength == CY_BLE_DISC_SRVC_INFO_128_LEN))
997         {
998             cy_stc_ble_disc_srv_info_t locDiscServInfo = { .connHandle = eventParam->connHandle };
999             uint32_t fFlag;
1000             uint32_t j;
1001             uint32_t i;
1002 
1003             attrLength = eventParam->attrData.attrLen;
1004 
1005             for(i = 0u; i < attrLength; i += locDataLength)
1006             {
1007                 cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
1008 
1009                 locDiscServInfo.srvcInfo = (cy_stc_ble_disc_srvc128_info_t*)(eventParam->attrData.attrValue + i);
1010                 fFlag = 0u;
1011 
1012 
1013                 if((locDiscServInfo.srvcInfo->range.startHandle >=
1014                     cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) &&
1015                    (locDiscServInfo.srvcInfo->range.startHandle <=
1016                     cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.endHandle))
1017                 {
1018                     /* Received a 16-bit service UUID */
1019                     if(locDataLength == CY_BLE_DISC_SRVC_INFO_LEN)
1020                     {
1021                         uint32_t discServiNum = cy_ble_configPtr->context->discServiCount;
1022 
1023                         locDiscServInfo.uuidFormat = CY_BLE_GATT_16_BIT_UUID_FORMAT;
1024                         for(j = 0u; (j < discServiNum) && (fFlag == 0u); j++)
1025                         {
1026                             locDiscServInfo.uuidFormat = CY_BLE_GATT_16_BIT_UUID_FORMAT;
1027                             if(cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].uuid ==
1028                                 locDiscServInfo.srvcInfo->uuid.uuid16)
1029                             {
1030                                 if(cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].range.startHandle ==
1031                                     CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE)
1032                                 {
1033                                     cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].range =
1034                                       locDiscServInfo.srvcInfo->range;
1035                                     fFlag = 1u;
1036                                 }
1037                                 else    /* Duplication of service */
1038                                 {
1039                                     /* For multiple service support next service has the same UUID */
1040                                     if((j >= (discServiNum - 1u)) ||
1041                                        (cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j + 1u].uuid !=
1042                                           locDiscServInfo.srvcInfo->uuid.uuid16))
1043                                     {
1044                                         Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_SRVC_DUPLICATION, &locDiscServInfo);
1045                                         fFlag = 1u;
1046                                     }
1047                                 }
1048                             }
1049                         }
1050                     }
1051                     else  /* Received a 128-bit service UUID */
1052                     {
1053                         locDiscServInfo.uuidFormat = CY_BLE_GATT_128_BIT_UUID_FORMAT;
1054 
1055                         /* Loop thru all registered services and invoke CY_BLE_EVT_GATTC_DISC_CHAR event */
1056                         (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_SERVICE,
1057                                                                (void*)&locDiscServInfo);
1058                     }
1059                 }
1060 
1061                 /* Generate event CY_BLE_EVT_GATTC_DISC_SKIPPED_SERVICE, if the incoming service was not processed */
1062                 if((fFlag == 0u) && ((cy_ble_eventHandlerFlag & CY_BLE_CALLBACK) != 0u))
1063                 {
1064                     /* Inform application that we discovered the service which is not defined in GATT database */
1065                     Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_DISC_SKIPPED_SERVICE, &locDiscServInfo);
1066                 }
1067 
1068             }
1069             cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1070         }
1071         else
1072         {
1073             Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_SRVC_DISCOVERY_FAILED, &eventParam->connHandle);
1074         }
1075     }
1076 }
1077 
1078 
1079 /******************************************************************************
1080 * Function Name: Cy_BLE_NextInclDiscovery
1081 ***************************************************************************//**
1082 *
1083 *  Looks for the included services in the current service (pointed by
1084 *   cy_ble_disCount). If the current service handle range is invalid (any of start
1085 *   or end handle is invalid), then increments the cy_ble_disCount and check
1086 *   the next service range and does so until a valid range is caught or the end of
1087 *   the service set is reached.
1088 *
1089 *  \param connHandle:     The connection handle.
1090 *  \param incrementIndex: A non-zero value indicates that the service index should be
1091 *                         incremented.
1092 *
1093 ******************************************************************************/
Cy_BLE_NextInclDiscovery(cy_stc_ble_conn_handle_t connHandle,uint8_t incrementIndex)1094 void Cy_BLE_NextInclDiscovery(cy_stc_ble_conn_handle_t connHandle,
1095                               uint8_t incrementIndex)
1096 {
1097     uint32_t locServCount;
1098     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(connHandle);
1099     uint32_t discServiNum = cy_ble_configPtr->context->discServiCount;
1100 
1101     if(incrementIndex != CY_BLE_DISCOVERY_INIT)
1102     {
1103         cy_ble_configPtr->context->discovery[discIdx].servCount++;
1104     }
1105     else
1106     {
1107         cy_ble_configPtr->context->discovery[discIdx].servCount = 0u;
1108         cy_ble_configPtr->context->discovery[discIdx].inclInfo.inclDefHandle = 0u;
1109     }
1110 
1111     locServCount = cy_ble_configPtr->context->discovery[discIdx].servCount;
1112 
1113     /* Skip not existing services and services out of the discovery range */
1114     while( (cy_ble_configPtr->context->discovery[discIdx].servCount < discServiNum) &&
1115            ((cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range.startHandle <
1116              cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) ||
1117             (cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range.startHandle >
1118              cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.endHandle)) )
1119     {
1120         cy_ble_configPtr->context->discovery[discIdx].servCount++;
1121         locServCount = cy_ble_configPtr->context->discovery[discIdx].servCount;
1122     }
1123 
1124     if(cy_ble_configPtr->context->discovery[discIdx].servCount < discServiNum)
1125     {
1126         cy_stc_ble_gattc_read_by_type_req_t requestParam;
1127 
1128         /* Fill Read by type request parameters */
1129         requestParam.range = cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range;
1130         requestParam.connHandle = connHandle;
1131 
1132         if(Cy_BLE_GATTC_FindIncludedServices(&requestParam) != CY_BLE_SUCCESS)
1133         {
1134             Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_INCL_DISCOVERY_FAILED, &connHandle);
1135             cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
1136         }
1137     }
1138     else /* An included service discovery procedure is done, start a characteristic discovery procedure */
1139     {
1140         if((cy_ble_eventHandlerFlag & CY_BLE_ENABLE_ALL_EVENTS) != 0u)
1141         {
1142             Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_INCL_DISCOVERY_COMPLETE, &connHandle);
1143         }
1144         Cy_BLE_SetConnectionState(connHandle, CY_BLE_CONN_STATE_CLIENT_CHAR_DISCOVERING);
1145         Cy_BLE_NextCharDiscovery(connHandle, CY_BLE_DISCOVERY_INIT);
1146     }
1147 }
1148 
1149 
1150 /******************************************************************************
1151 * Function Name: Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler
1152 ***************************************************************************//**
1153 *
1154 *  This function is called on receiving a #CY_BLE_EVT_GATTC_READ_BY_TYPE_RSP
1155 *  event. Based on the service UUID, an appropriate data structure is populated
1156 *  using the data received as part of the callback.
1157 *
1158 *  \param discCharInfo:  The pointer to the characteristic information structure.
1159 *
1160 ******************************************************************************/
Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler(cy_stc_ble_disc_char_info_t * discCharInfo)1161 static void Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler(cy_stc_ble_disc_char_info_t *discCharInfo)
1162 {
1163     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(discCharInfo->connHandle);
1164 
1165     if((discCharInfo->uuidFormat == CY_BLE_GATT_16_BIT_UUID_FORMAT) &&
1166        (cy_ble_configPtr->context->discovery[discIdx].servCount == cy_ble_gapcConfigPtr->serviceDiscIdx))
1167     {
1168         switch(discCharInfo->uuid.uuid16)
1169         {
1170             case CY_BLE_UUID_CHAR_DEVICE_NAME:
1171                 CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].deviceNameCharHandle,
1172                                             discCharInfo);
1173                 break;
1174 
1175             case CY_BLE_UUID_CHAR_APPEARANCE:
1176                 CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].appearanceCharHandle,
1177                                             discCharInfo);
1178                 break;
1179 
1180             case CY_BLE_UUID_CHAR_PERIPH_PRIVCY_FLAG:
1181                 CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].periphPrivacyCharHandle,
1182                                             discCharInfo);
1183                 break;
1184 
1185             case CY_BLE_UUID_CHAR_RECONNECTION_ADDR:
1186                 CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].reconnAddrCharHandle,
1187                                             discCharInfo);
1188                 break;
1189 
1190             case CY_BLE_UUID_CHAR_PRFRRD_CNXN_PARAM:
1191                 CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].prefConnParamCharHandle,
1192                                             discCharInfo);
1193                 break;
1194 
1195             case CY_BLE_UUID_CHAR_CENTRAL_ADDRESS_RESOLUTION:
1196                 CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].centralAddrResolutionCharHandle,
1197                                             discCharInfo);
1198                 break;
1199 
1200             case CY_BLE_UUID_CHAR_RESOLVABLE_PRIVATE_ADDR_ONLY:
1201                 CY_BLE_GapcCheckCharHandle(cy_ble_gapcConfigPtr->attrInfo[discIdx].resolvablePrivateAddressOnly, discCharInfo);
1202                 break;
1203 
1204             default:
1205                 break;
1206         }
1207 
1208         /* Indicate that request was handled */
1209         cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1210     }
1211 }
1212 
1213 
1214 /******************************************************************************
1215 * Function Name: Cy_BLE_ReadByTypeEventHandler
1216 ***************************************************************************//**
1217 *
1218 *  Handles a Read By Type Response event during an automatic server discovery
1219 *  process.
1220 *
1221 *  \param eventParam: The event parameters for a Read By Type Response.
1222 *
1223 ******************************************************************************/
Cy_BLE_ReadByTypeEventHandler(cy_stc_ble_gattc_read_by_type_rsp_param_t * eventParam)1224 static void Cy_BLE_ReadByTypeEventHandler(cy_stc_ble_gattc_read_by_type_rsp_param_t *eventParam)
1225 {
1226     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->connHandle);
1227     uint32_t i;
1228     uint32_t j;
1229 
1230     if((discIdx < cy_ble_configPtr->params->maxClientCount) &&
1231        (cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u))
1232     {
1233         /* Count of service information pieces in this mtu */
1234         uint32_t locDataLength = (uint32_t)eventParam->attrData.length;
1235         uint32_t attrLength = (uint32_t)eventParam->attrData.attrLen;
1236         uint8_t *attrVal = eventParam->attrData.attrValue;
1237 
1238         if(Cy_BLE_GetConnectionState(eventParam->connHandle) == CY_BLE_CONN_STATE_CLIENT_CHAR_DISCOVERING)
1239         {
1240             cy_stc_ble_disc_char_info_t locDiscCharInfo;
1241 
1242             locDiscCharInfo.connHandle = eventParam->connHandle;
1243 
1244             for(i = 0u; i < attrLength; i += locDataLength)
1245             {
1246                 cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
1247 
1248                 /* Get Handle for characteristic declaration */
1249                 locDiscCharInfo.charDeclHandle = Cy_BLE_Get16ByPtr(attrVal);
1250                 attrVal += sizeof(locDiscCharInfo.charDeclHandle);
1251 
1252                 /* Get Properties for value */
1253                 locDiscCharInfo.properties = *attrVal;
1254                 attrVal += sizeof(locDiscCharInfo.properties);
1255 
1256                 /* Get Handle to server database attribute value entry */
1257                 locDiscCharInfo.valueHandle = Cy_BLE_Get16ByPtr(attrVal);
1258                 attrVal += sizeof(locDiscCharInfo.valueHandle);
1259 
1260                 /* Get Characteristic UUID (128/16 bit) */
1261                 if(locDataLength == CY_BLE_DISC_CHAR_INFO_128_LEN)
1262                 {
1263                     locDiscCharInfo.uuidFormat = CY_BLE_GATT_128_BIT_UUID_FORMAT;
1264                     (void)memcpy(&locDiscCharInfo.uuid.uuid128, attrVal, CY_BLE_GATT_128_BIT_UUID_SIZE);
1265                     attrVal += CY_BLE_GATT_128_BIT_UUID_SIZE;
1266                 }
1267                 else if(locDataLength == CY_BLE_DISC_CHAR_INFO_LEN)
1268                 {
1269                     locDiscCharInfo.uuidFormat = CY_BLE_GATT_16_BIT_UUID_FORMAT;
1270                     locDiscCharInfo.uuid.uuid16 = Cy_BLE_Get16ByPtr(attrVal);
1271                     attrVal += CY_BLE_GATT_16_BIT_UUID_SIZE;
1272                 }
1273                 else
1274                 {
1275                     /* Unsupported data length value */
1276                 }
1277 
1278                 if((locDataLength == CY_BLE_DISC_CHAR_INFO_128_LEN) || (locDataLength == CY_BLE_DISC_CHAR_INFO_LEN))
1279                 {
1280                     /* Process common services: GAP and GATT */
1281                     Cy_BLE_GAPC_DiscoverCharacteristicsEventHandler(&locDiscCharInfo);
1282                     Cy_BLE_GATTC_DiscoverCharacteristicsEventHandler(&locDiscCharInfo);
1283 
1284                     /* Loop thru all registered services and invoke CY_BLE_EVT_GATTC_DISC_CHAR event */
1285                     (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_CHAR, (void*)&locDiscCharInfo);
1286                 }
1287             }
1288             /* The sub-procedure is complete when an Error Response is received and the
1289              *  Error Code is set to the Attribute Not Found; or the Read By Type Response has an
1290              *  Attribute Handle equal to the Ending Handle of the request - in this case
1291              *  a CY_BLE_EVT_GATTC_LONG_PROCEDURE_END event is generated by the BLE Stack. */
1292             cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1293         }
1294         else if(Cy_BLE_GetConnectionState(eventParam->connHandle) == CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING)
1295         {
1296             bool exitFlag = false;
1297             cy_stc_ble_disc_incl_info_t locDiscInclInfo;
1298             locDiscInclInfo.connHandle = eventParam->connHandle;
1299 
1300             for(i = 0u; (i < attrLength) && (exitFlag == false); i += locDataLength)
1301             {
1302                 cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
1303 
1304                 locDiscInclInfo.inclDefHandle = Cy_BLE_Get16ByPtr(attrVal);
1305                 attrVal += sizeof(locDiscInclInfo.inclDefHandle);
1306 
1307                 locDiscInclInfo.inclHandleRange.startHandle = Cy_BLE_Get16ByPtr(attrVal);
1308                 attrVal += sizeof(locDiscInclInfo.inclHandleRange.startHandle);
1309 
1310                 locDiscInclInfo.inclHandleRange.endHandle = Cy_BLE_Get16ByPtr(attrVal);
1311                 attrVal += sizeof(locDiscInclInfo.inclHandleRange.endHandle);
1312 
1313                 if(locDataLength == CY_BLE_DISC_INCL_INFO_128_LEN)
1314                 {
1315                     cy_stc_ble_gattc_stop_cmd_param_t stopCmdParam;
1316 
1317                     stopCmdParam.connHandle = eventParam->connHandle;
1318                     locDiscInclInfo.uuidFormat = CY_BLE_GATT_128_BIT_UUID_FORMAT;
1319 
1320                     /* Stop ongoing GATT operation */
1321                     (void)Cy_BLE_GATTC_StopCmd(&stopCmdParam);
1322 
1323                     /* Save handle to support a read response from device */
1324                     cy_ble_configPtr->context->discovery[discIdx].inclInfo = locDiscInclInfo;
1325 
1326                     exitFlag = true;
1327                 }
1328                 else if(locDataLength == CY_BLE_DISC_INCL_INFO_LEN)
1329                 {
1330                     uint32_t discServiNum = cy_ble_configPtr->context->discServiCount;
1331                     locDiscInclInfo.uuidFormat = CY_BLE_GATT_16_BIT_UUID_FORMAT;
1332                     locDiscInclInfo.uuid.uuid16 = Cy_BLE_Get16ByPtr(attrVal);
1333                     attrVal += CY_BLE_GATT_16_BIT_UUID_SIZE;
1334 
1335                     /* Store the range of the included service in the list of services for discovery */
1336                     for(j = 0u; j < discServiNum; j++)
1337                     {
1338                         if( (cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].uuid ==
1339                                 locDiscInclInfo.uuid.uuid16) &&
1340                             (cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].range.startHandle ==
1341                                 CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE))
1342                             {
1343                                 cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + j].range =
1344                                     locDiscInclInfo.inclHandleRange;
1345                                 break;
1346                             }
1347                     }
1348                 }
1349                 else
1350                 {
1351                     /* Unsupported data length value */
1352                 }
1353 
1354                 /* Loop thru all registered services and invoke CY_BLE_EVT_GATTC_DISC_INCL event */
1355                 (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_INCL, (void*)&locDiscInclInfo);
1356             }
1357             cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1358         }
1359         else
1360         {
1361             /* Unhandled state value */
1362         }
1363     }
1364 }
1365 
1366 
1367 /******************************************************************************
1368 * Function Name: Cy_BLE_NextCharDiscovery
1369 ***************************************************************************//**
1370 *
1371 *  Looks for a characteristic handle range for the current service (pointed by
1372 *   cy_ble_disCount). If the current range is invalid (any of start or end
1373 *   handles is invalid), then increments the cy_ble_disCount and check
1374 *   the next service range and does so until a valid range is caught or the end
1375 *   of the service set is reached.
1376 *
1377 *  \param connHandle:     The connection handle.
1378 *  \param incrementIndex: A non-zero value indicates that the characteristic index
1379 *                         should be incremented.
1380 *
1381 ******************************************************************************/
Cy_BLE_NextCharDiscovery(cy_stc_ble_conn_handle_t connHandle,uint8_t incrementIndex)1382 static void Cy_BLE_NextCharDiscovery(cy_stc_ble_conn_handle_t connHandle,
1383                               uint8_t incrementIndex)
1384 {
1385     uint32_t locServCount;
1386     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(connHandle);
1387     uint32_t discServiNum = cy_ble_configPtr->context->discServiCount;
1388 
1389     if(incrementIndex != CY_BLE_DISCOVERY_INIT)
1390     {
1391         cy_ble_configPtr->context->discovery[discIdx].servCount++;
1392     }
1393     else
1394     {
1395         cy_ble_configPtr->context->discovery[discIdx].servCount = 0u;
1396     }
1397 
1398     locServCount = cy_ble_configPtr->context->discovery[discIdx].servCount;
1399 
1400     /* Skip not existing services and services out of the discovery range */
1401     while((cy_ble_configPtr->context->discovery[discIdx].servCount < discServiNum) &&
1402           ((cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range.startHandle <
1403             cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) ||
1404            (cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range.startHandle >
1405             cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.endHandle)))
1406     {
1407         ++cy_ble_configPtr->context->discovery[discIdx].servCount;
1408         locServCount = cy_ble_configPtr->context->discovery[discIdx].servCount;
1409     }
1410 
1411     if(cy_ble_configPtr->context->discovery[discIdx].servCount < discServiNum)
1412     {
1413         cy_stc_ble_gattc_read_by_type_req_t reqParam =
1414         {
1415             .connHandle = connHandle,
1416             .range      = cy_ble_configPtr->context->serverInfo[(discIdx * discServiNum) + locServCount].range
1417         };
1418 
1419         if(Cy_BLE_GATTC_DiscoverCharacteristics(&reqParam) != CY_BLE_SUCCESS)
1420         {
1421             Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_CHAR_DISCOVERY_FAILED, &connHandle);
1422             cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
1423         }
1424     }
1425     else /* A Characteristic discovery procedure is done, start a descriptor discovery procedure */
1426     {
1427         if((cy_ble_eventHandlerFlag & CY_BLE_ENABLE_ALL_EVENTS) != 0u)
1428         {
1429             Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_CHAR_DISCOVERY_COMPLETE, &connHandle);
1430         }
1431         Cy_BLE_SetConnectionState(connHandle, CY_BLE_CONN_STATE_CLIENT_DESCR_DISCOVERING);
1432         Cy_BLE_NextCharDscrDiscovery(connHandle, CY_BLE_DISCOVERY_INIT);
1433     }
1434 }
1435 
1436 
1437 /******************************************************************************
1438 * Function Name: Cy_BLE_FindInfoEventHandler
1439 ***************************************************************************//**
1440 *
1441 *  Handles a Find Info Response event during an automatic server discovery
1442 *  process.
1443 *
1444 *  \param eventParam:  The event parameters for a Find Info Response.
1445 *
1446 ******************************************************************************/
Cy_BLE_FindInfoEventHandler(cy_stc_ble_gattc_find_info_rsp_param_t * eventParam)1447 static void Cy_BLE_FindInfoEventHandler(cy_stc_ble_gattc_find_info_rsp_param_t *eventParam)
1448 {
1449     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->connHandle);
1450 
1451     /* Discovery descriptor information */
1452     cy_stc_ble_disc_descr_info_t locDiscDescrInfo;
1453 
1454     locDiscDescrInfo.descrHandle = CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE;
1455 
1456     if((Cy_BLE_GetConnectionState(eventParam->connHandle) == CY_BLE_CONN_STATE_CLIENT_DESCR_DISCOVERING) &&
1457        (discIdx < cy_ble_configPtr->params->maxClientCount) &&
1458        (cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u))
1459     {
1460         uint32_t attrLength = eventParam->handleValueList.byteCount;    /* Number of elements on list in bytes */
1461         uint32_t locDataLength;
1462         uint32_t i;
1463         uint8_t *attrVal;
1464 
1465         locDiscDescrInfo.uuidFormat = eventParam->uuidFormat;
1466         locDiscDescrInfo.connHandle = eventParam->connHandle;
1467 
1468         if(locDiscDescrInfo.uuidFormat == CY_BLE_GATT_16_BIT_UUID_FORMAT)
1469         {
1470             locDataLength = CY_BLE_DB_ATTR_HANDLE_LEN + CY_BLE_GATT_16_BIT_UUID_SIZE;
1471         }
1472         else
1473         {
1474             locDataLength = CY_BLE_DB_ATTR_HANDLE_LEN + CY_BLE_GATT_128_BIT_UUID_SIZE;
1475         }
1476         attrVal = eventParam->handleValueList.list;
1477 
1478         for(i = 0u; i < attrLength; i += locDataLength)
1479         {
1480             cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
1481 
1482             locDiscDescrInfo.descrHandle = Cy_BLE_Get16ByPtr(attrVal);
1483             attrVal += CY_BLE_DB_ATTR_HANDLE_LEN;
1484 
1485 
1486             if(locDiscDescrInfo.uuidFormat == CY_BLE_GATT_128_BIT_UUID_FORMAT)
1487             {
1488                 (void)memcpy(&locDiscDescrInfo.uuid.uuid128, attrVal, CY_BLE_GATT_128_BIT_UUID_SIZE);
1489                 attrVal += CY_BLE_GATT_128_BIT_UUID_SIZE;
1490             }
1491             else
1492             {
1493                 locDiscDescrInfo.uuid.uuid16 = Cy_BLE_Get16ByPtr(attrVal);
1494                 attrVal += CY_BLE_GATT_16_BIT_UUID_SIZE;
1495             }
1496 
1497             /* Process common services: GATT */
1498             Cy_BLE_GATTC_DiscoverCharDescriptorsEventHandler(&locDiscDescrInfo);
1499 
1500             /* Loop thru all registered services and invoke CY_BLE_EVT_GATTC_DISC_CHAR event */
1501             (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_DESCR, (void*)&locDiscDescrInfo);
1502         }
1503 
1504         /* The sub-procedure is complete when an Error Response is received and the
1505          * Error Code is set to the Attribute Not Found or the Find Information Response has
1506          * an Attribute Handle that is equal to the Ending Handle of the request in this
1507          * case a CY_BLE_EVT_GATTC_LONG_PROCEDURE_END event is generated by the BLE Stack. */
1508 
1509         cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1510     }
1511 }
1512 
1513 
1514 /******************************************************************************
1515 * Function Name: Cy_BLE_NextCharDscrDiscovery
1516 ***************************************************************************//**
1517 *
1518 *  Looks for a handle range for the current descriptor (pointed by
1519 *   cy_ble_discovery[discIdx].servCount). If the current range is invalid (any of start or end
1520 *   handles is invalid), then increments the cy_ble_discovery[discIdx].servCount and check
1521 *   the next descriptor range and does so until a valid range is caught or the
1522 *   end of the descriptor set is reached.
1523 *
1524 *  \param connHandle:     The connection handle.
1525 *  \param incrementIndex: A non-zero value indicates that the characteristic index should be
1526 *                         incremented.
1527 *
1528 ******************************************************************************/
Cy_BLE_NextCharDscrDiscovery(cy_stc_ble_conn_handle_t connHandle,uint8_t incrementIndex)1529 static void Cy_BLE_NextCharDscrDiscovery(cy_stc_ble_conn_handle_t connHandle,
1530                                   uint8_t incrementIndex)
1531 {
1532     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(connHandle);
1533     cy_stc_ble_disc_range_info_t charRangeInfo = { .connHandle = connHandle, .srviIncIdx = incrementIndex };
1534 
1535     do
1536     {
1537         cy_ble_eventHandlerFlag |= CY_BLE_CALLBACK;
1538         charRangeInfo.range.startHandle = CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE;
1539         charRangeInfo.range.endHandle = CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE;
1540 
1541         if(incrementIndex == CY_BLE_DISCOVERY_INIT)
1542         {
1543             cy_ble_configPtr->context->discovery[discIdx].servCount = 0u;
1544             cy_ble_configPtr->context->discovery[discIdx].charCount = 0u;
1545             incrementIndex = CY_BLE_DISCOVERY_CONTINUE;
1546 
1547         }
1548 
1549         /* Get a possible range of the common service: GATT */
1550         Cy_BLE_GATTC_GetCharRange(&charRangeInfo);
1551 
1552         /* Loop thru all registered services and get a possible range of the characteristic descriptor */
1553         (void)Cy_BLE_InvokeServiceEventHandler((uint32_t)CY_BLE_EVT_GATTC_DISC_DESCR_GET_RANGE, (void*)&charRangeInfo);
1554 
1555         if((charRangeInfo.range.startHandle == CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE) ||
1556            (charRangeInfo.range.endHandle == CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE))
1557         {
1558             cy_ble_configPtr->context->discovery[discIdx].servCount++;
1559             cy_ble_configPtr->context->discovery[discIdx].charCount = 0u;
1560             charRangeInfo.srviIncIdx = CY_BLE_DISCOVERY_INIT;
1561         }
1562         else
1563         {
1564             charRangeInfo.srviIncIdx = CY_BLE_DISCOVERY_CONTINUE;
1565         }
1566 
1567         /* Skip not existing characteristics and characteristics out of discovery range */
1568     }
1569     while( ((charRangeInfo.range.startHandle <= cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) ||
1570             (charRangeInfo.range.startHandle > cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.endHandle) ||
1571             (charRangeInfo.range.endHandle < cy_ble_configPtr->context->discovery[discIdx].gattcDiscoveryRange.startHandle) ||
1572            (charRangeInfo.range.startHandle > charRangeInfo.range.endHandle)) &&
1573            (cy_ble_configPtr->context->discovery[discIdx].servCount < cy_ble_configPtr->context->discServiCount) );
1574 
1575     if(cy_ble_configPtr->context->discovery[discIdx].servCount < cy_ble_configPtr->context->discServiCount)
1576     {
1577         cy_stc_ble_gattc_find_info_req_t reqParam;
1578 
1579         /* Fill Error Response parameters */
1580         reqParam.connHandle = connHandle;
1581         reqParam.range      = charRangeInfo.range;
1582 
1583         if(Cy_BLE_GATTC_DiscoverCharacteristicDescriptors(&reqParam) != CY_BLE_SUCCESS)
1584         {
1585             Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_DESCR_DISCOVERY_FAILED, &connHandle);
1586             cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
1587         }
1588     }
1589     else /* Discovery done */
1590     {
1591         Cy_BLE_SetConnectionState(connHandle, CY_BLE_CONN_STATE_CLIENT_DISCOVERED);
1592         Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_DISCOVERY_COMPLETE, &connHandle);
1593         cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag = 0u;
1594     }
1595 }
1596 
1597 
1598 /******************************************************************************
1599 * Function Name: Cy_BLE_LongProcedureEndEventHandler
1600 ***************************************************************************//**
1601 *
1602 *  Handles a Long Procedure End event during an automatic server discovery
1603 *  process.
1604 *
1605 *  \param connHandle:  The connection handle.
1606 *
1607 ******************************************************************************/
Cy_BLE_LongProcedureEndEventHandler(cy_stc_ble_conn_handle_t connHandle)1608 static void Cy_BLE_LongProcedureEndEventHandler(cy_stc_ble_conn_handle_t connHandle)
1609 {
1610     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(connHandle);
1611 
1612     if((discIdx < cy_ble_configPtr->params->maxClientCount) &&
1613        (cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u))
1614     {
1615         cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1616 
1617         switch(Cy_BLE_GetConnectionState(connHandle))
1618         {
1619             case CY_BLE_CONN_STATE_CLIENT_SRVC_DISCOVERING:
1620                 if((cy_ble_eventHandlerFlag & CY_BLE_ENABLE_ALL_EVENTS) != 0u)
1621                 {
1622                     Cy_BLE_ApplCallback((uint32_t)CY_BLE_EVT_GATTC_SRVC_DISCOVERY_COMPLETE, &connHandle);
1623                 }
1624                 Cy_BLE_SetConnectionState(connHandle, CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING);
1625                 Cy_BLE_NextInclDiscovery(connHandle, CY_BLE_DISCOVERY_INIT);
1626                 /* Do not propagate this event to the application level during an automatic discovery procedure */
1627                 cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1628                 break;
1629 
1630             case CY_BLE_CONN_STATE_CLIENT_INCL_DISCOVERING:
1631                 Cy_BLE_NextInclDiscovery(connHandle, CY_BLE_DISCOVERY_CONTINUE);
1632                 cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1633                 break;
1634 
1635             case CY_BLE_CONN_STATE_CLIENT_CHAR_DISCOVERING:
1636                 Cy_BLE_NextCharDiscovery(connHandle, CY_BLE_DISCOVERY_CONTINUE);
1637                 cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1638                 break;
1639 
1640             case CY_BLE_CONN_STATE_CLIENT_DESCR_DISCOVERING:
1641                 Cy_BLE_NextCharDscrDiscovery(connHandle, CY_BLE_DISCOVERY_CONTINUE);
1642                 cy_ble_eventHandlerFlag &= (uint8_t) ~CY_BLE_CALLBACK;
1643                 break;
1644 
1645             default:
1646                 break;
1647         }
1648     }
1649 }
1650 
1651 
1652 /******************************************************************************
1653 * Function Name: Cy_BLE_ErrorResponseEventHandler
1654 ***************************************************************************//**
1655 *
1656 *  Handles an Error Response event during an automatic server discovery
1657 *  process.
1658 *
1659 *  \param eventParam:  The event parameters for an Error Response.
1660 *
1661 ******************************************************************************/
Cy_BLE_ErrorResponseEventHandler(const cy_stc_ble_gatt_err_param_t * eventParam)1662 static void Cy_BLE_ErrorResponseEventHandler(const cy_stc_ble_gatt_err_param_t *eventParam)
1663 {
1664     uint32_t discIdx = Cy_BLE_GetDiscoveryIdx(eventParam->connHandle);
1665 
1666     if( (discIdx < cy_ble_configPtr->params->maxClientCount) &&
1667         (cy_ble_configPtr->context->discovery[discIdx].autoDiscoveryFlag != 0u) &&
1668         (eventParam->errInfo.errorCode == CY_BLE_GATT_ERR_ATTRIBUTE_NOT_FOUND) )
1669     {
1670         Cy_BLE_LongProcedureEndEventHandler(eventParam->connHandle);
1671     }
1672 }
1673 
1674 #endif /* CY_BLE_LIB_HOST_CORE */
1675 #endif /* CY_IP_MXBLESS */
1676 
1677 
1678 /* [] END OF FILE */
1679