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