/******************************************************************************* * Function Name: GenericEventHandler ******************************************************************************** * Summary: * Event handler function for the BLE stack. All the events by BLE stack * are received by application through this function. For this, CyBle_ProcessEvents() * should be called continuously in main loop. * * Parameters: * event: event value * eventParame: pointer to the location where relevant event data is stored * * Return: * void * *******************************************************************************/ void GenericEventHandler(uint32 event, void * eventParam) { /* Local variables and data structures*/ CYBLE_GATTS_WRITE_REQ_PARAM_T writeReqData; CYBLE_GATTC_WRITE_REQ_T writeADVcounterdata; CYBLE_GAPC_ADV_REPORT_T scan_report; CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T writeCmdData; CYBLE_API_RESULT_T apiResult; CYBLE_GATTC_WRITE_REQ_T writeRGBdata; switch(event) { case CYBLE_EVT_STACK_ON: #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_STACK_ON "); UART_UartPutCRLF(' '); #endif /* At the start of the BLE stack, start advertisement */ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: /* This event is received at every start or stop of peripheral advertisement*/ #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif if((CYBLE_STATE_DISCONNECTED == CyBle_GetState()) && (switch_Role == FALSE)) { /* If the current state of the BLE is Disconnected, then restart advertisement. * Note that the advertisement should only be restarted if the switch flag is not * TRUE. If switch role flag is TRUE, then there is no need to start advertisement * as the GAP role has to be switched*/ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult == CYBLE_ERROR_OK) { #ifdef DEBUG_ENABLED UART_UartPutString("Restart Advertisement "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } } break; case CYBLE_EVT_GAPC_SCAN_START_STOP: /* This event is received at every start or stop of central scanning*/ #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GAPC_SCAN_START_STOP "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif break; case CYBLE_EVT_GATT_CONNECT_IND: /* This event is received at GATT connection with a device. This event * is received for both Client or Server role */ #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GATT_CONNECT_IND "); UART_UartPutCRLF(' '); #endif break; case CYBLE_EVT_GATT_DISCONNECT_IND: /* This event is received at GATT disconnection with a device. This event * is received for both Client or Server role */ #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GATT_DISCONNECT_IND "); UART_UartPutCRLF(' '); #endif break; case CYBLE_EVT_GATTS_WRITE_REQ: /* This event is received at when Server receives a Write request from * connected Client device */ /* Save the associated event parameter in local variable */ writeReqData = *(CYBLE_GATTS_WRITE_REQ_PARAM_T*)eventParam; if(writeReqData.handleValPair.attrHandle == CYBLE_RGB_LED_CONTROL_CHAR_HANDLE) { /* If the Write request is on RGB LED Control Characteristic, then Client is * trying to set a new color to the device. */ if(writeReqData.handleValPair.value.len == RGB_LED_DATA_LEN) { #ifdef DEBUG_ENABLED UART_UartPutString("RGB CYBLE_EVT_GATTS_WRITE_REQ "); UART_UartPutCRLF(' '); #endif /* Extract the four bytes containing the color value and store it */ RGBData[RGB_RED_INDEX] = writeReqData.handleValPair.value.val[0]; RGBData[RGB_GREEN_INDEX] = writeReqData.handleValPair.value.val[1]; RGBData[RGB_BLUE_INDEX] = writeReqData.handleValPair.value.val[2]; RGBData[RGB_INTENSITY_INDEX] = writeReqData.handleValPair.value.val[3]; /* Modify RGB Color my configuring the PrISM components with new density * value*/ UpdateRGBled(RGBData, RGB_LED_DATA_LEN); /* Update the RGB LED Control characteristic in GATT DB to allow * Client to read the latest RGB LED color value set */ CyBle_GattsWriteAttributeValue(&writeReqData.handleValPair,0,&cyBle_connHandle,CYBLE_GATT_DB_LOCALLY_INITIATED); #ifdef ENABLE_ADV_DATA_COUNTER /* Increment the ADV data counter so that scanning Central device knows * if this device has updated RGB LED data or not */ dataADVCounter++; #endif #ifdef DEBUG_ENABLED UART_UartPutString("incremented dataADVCounter value in CYBLE_EVT_GATTS_WRITE_REQ= "); PrintNum(dataADVCounter); UART_UartPutCRLF(' '); #endif /* After receiveing the color value, set the switch role flag to allow the system * to switch role to Central role */ switch_Role = TRUE; #ifdef DEBUG_ENABLED UART_UartPutString("switchRole to Central"); UART_UartPutCRLF(' '); #endif } else { /* Send the error code for invalid attribute length packet */ SendErrorCode(CYBLE_GATT_WRITE_REQ, writeReqData.handleValPair.attrHandle, ERR_INVALID_ATT_LEN); return; } } /* As part of every write request, the server needs to send a write response. Note * that this will be sent only if all the application layer conditions are met on a * write request. Else, an appropriate error code is sent. */ CyBle_GattsWriteRsp(cyBle_connHandle); break; case CYBLE_EVT_GATTS_WRITE_CMD_REQ: /* This event is generated whenever a Client device sends a Write Command (Write * without response) to a connected Server. Save the associated event parameter in * local variable. */ writeCmdData = *(CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T*)eventParam; /* Check if the Write command is for ADV Data counter characteristic */ if(writeCmdData.handleValPair.attrHandle == CYBLE_RGB_DATA_COUNT_CHAR_HANDLE) { /* If the data sent is of one byte, then proceed. */ if(writeCmdData.handleValPair.value.len == 1) { /* Extract and save the set ADV data counter value */ dataADVCounter = *(writeCmdData.handleValPair.value.val); /* This increment is done to balance the ++ done as part of CYBLE_EVT_GATTS_WRITE_REQ */ dataADVCounter--; /* Update the ADV data counter characteristic in GATT DB to allow * Client to read the latest ADV data counter value */ CyBle_GattsWriteAttributeValue(&writeCmdData.handleValPair, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED); #ifdef DEBUG_ENABLED UART_UartPutString("dataADVCounter from CYBLE_EVT_GATTS_WRITE_CMD_REQ = "); PrintNum(dataADVCounter); UART_UartPutCRLF(' '); #endif } /* if(writeCmdData.handleValPair.value.len == 1) */ } break; case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT: /* This event is generated whenever there is a peripheral device found by * while scanning */ if(CYBLE_STATE_CONNECTED != CyBle_GetState()) { /* If we are not connected to any peripheral device, then save the new device * information so to add it to our list */ scan_report = *(CYBLE_GAPC_ADV_REPORT_T*)eventParam; #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT "); UART_UartPutCRLF(' '); #endif #ifdef ENABLE_ADV_DATA_COUNTER /* If ADV DATA COUNTER is enabled, then the central device would check * if the counter in ADV packet of peripheral is less than its own counter * or not. If yes, then it will consider the peripheral as a potential * device to connect to.*/ if(scan_report.eventType == CYBLE_GAPC_CONN_UNDIRECTED_ADV) { /* If the scan report received is of advertising nature and the data * length is as expected... */ if(scan_report.dataLen == new_advData.advDataLen) { /* If the second last value of the advertising data matches the custom * marker, then the peripheral is a node of the network */ if(scan_report.data[scan_report.dataLen-2] == CUSTOM_ADV_DATA_MARKER) { /* If the ADV counter data in Advertising data is less than that of * the value in this scanning device, then the node is a potential node * whose color has to be updated. */ if((scan_report.data[scan_report.dataLen-1] < dataADVCounter) || ((scan_report.data[scan_report.dataLen-1] == 255) && (dataADVCounter == 0))) { /* Potential node found*/ potential_node_found = TRUE; /* Save the advertising peripheral address and type*/ memcpy(potential_node_bdAddr, scan_report.peerBdAddr, 6); potential_node_bdAddrType = scan_report.peerAddrType; #ifdef DEBUG_ENABLED UART_UartPutString("potential_node_found "); UART_UartPutCRLF(' '); #endif } else { /* If the ADV data counter is equal or more than the data counter * in this scanning device, then the node has latest RGB LED data * and does not need to be connected to. Reset the potential node * address */ potential_node_found = FALSE; potential_node_bdAddrType = 0; potential_node_bdAddr[0] = 0x00; potential_node_bdAddr[1] = 0x00; potential_node_bdAddr[2] = 0x00; potential_node_bdAddr[3] = 0x00; potential_node_bdAddr[4] = 0x00; potential_node_bdAddr[5] = 0x00; } } } } #endif /* If the received scan data is part of scan response from a peripheral... */ if(scan_report.eventType == CYBLE_GAPC_SCAN_RSP) { /* If the data lenght of the scan reponse packet is equal to expected * scan response data lenght...*/ if(scan_report.dataLen == SCAN_TAG_DATA_LEN) { #ifdef ENABLE_ADV_DATA_COUNTER /* If a potential node had been found earlier as part of received * advertising data, then compare the address of stored potential * node and received address of the scan response */ if(potential_node_found) { /* Compare the two addresses and type */ if((!memcmp(scan_report.peerBdAddr, potential_node_bdAddr, 6)) && (potential_node_bdAddrType == scan_report.peerAddrType)) { #endif /* If the scan report data matches the expected data (scan_tag), * then it is our desired node */ if(!memcmp(scan_report.data, scan_tag, scan_report.dataLen)) { #ifdef DEBUG_ENABLED UART_UartPutString("Titan Found "); UART_UartPutCRLF(' '); #endif /* Stop existing scan */ CyBle_GapcStopScan(); #ifdef DEBUG_ENABLED UART_UartPutString("Stop Scan called "); UART_UartPutCRLF(' '); #endif /* Save the peripheral BD address and type*/ peripAddr.type = scan_report.peerAddrType; peripAddr.bdAddr[0] = scan_report.peerBdAddr[0]; peripAddr.bdAddr[1] = scan_report.peerBdAddr[1]; peripAddr.bdAddr[2] = scan_report.peerBdAddr[2]; peripAddr.bdAddr[3] = scan_report.peerBdAddr[3]; peripAddr.bdAddr[4] = scan_report.peerBdAddr[4]; peripAddr.bdAddr[5] = scan_report.peerBdAddr[5]; /* Set the flag to allow application to connect to the * peripheral found */ clientConnectToDevice = TRUE; #ifdef ENABLE_ADV_DATA_COUNTER /* Reset the potential node flag*/ potential_node_found = FALSE; #endif } #ifdef ENABLE_ADV_DATA_COUNTER } } #endif } } } break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: /* This event is received whenever the device connect on GAP layer */ if(ble_gap_state == BLE_CENTRAL) { #ifdef ENABLE_CENTRAL_DISCOVERY /* The Device is connected now. Start Attributes discovery process.*/ CyBle_GattcStartDiscovery(cyBle_connHandle); #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GAP_DEVICE_CONNECTED "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif #else /* If this system is currently acting in Central role and has connected * to a peripheral device, then write directly the ADV counter data and * RGB LED control data using attribute handles */ /* Set the device connected flag */ deviceConnected = TRUE; #ifdef DEBUG_ENABLED UART_UartPutString("Directly write RGB using Attr handle "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif /* Write the Data Counter value */ writeADVcounterdata.attrHandle = CYBLE_RGB_DATA_COUNT_CHAR_HANDLE; writeADVcounterdata.value.val = &dataADVCounter; writeADVcounterdata.value.len = 1; CyBle_GattcWriteWithoutResponse(cyBle_connHandle, &writeADVcounterdata); /* Write the RGB LED Value */ writeRGBdata.attrHandle = CYBLE_RGB_LED_CONTROL_CHAR_HANDLE; writeRGBdata.value.val = RGBData; writeRGBdata.value.len = RGB_LED_DATA_LEN; CyBle_GattcWriteCharacteristicValue(cyBle_connHandle, &writeRGBdata); #endif } break; case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE: /* This event is generated whenever the discovery procedure is complete*/ #ifdef ENABLE_CENTRAL_DISCOVERY deviceConnected = TRUE; #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GATTC_DISCOVERY_COMPLETE "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif /* Write the Data Counter value */ writeADVcounterdata.attrHandle = CYBLE_RGB_DATA_COUNT_CHAR_HANDLE; writeADVcounterdata.value.val = &dataADVCounter; writeADVcounterdata.value.len = 1; CyBle_GattcWriteWithoutResponse(cyBle_connHandle, &writeADVcounterdata); /* Write the RGB LED Value */ writeRGBdata.attrHandle = CYBLE_RGB_LED_CONTROL_CHAR_HANDLE; writeRGBdata.value.val = RGBData; writeRGBdata.value.len = RGB_LED_DATA_LEN; CyBle_GattcWriteCharacteristicValue(cyBle_connHandle, &writeRGBdata); #endif break; case CYBLE_EVT_GATTC_WRITE_RSP: /* This event is generated when the Client device receives a response * as part of the Write request sent earlier. This indicates that * the RGB LED data was written successfully */ #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GATTC_WRITE_RSP "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif /* Disconnect the existing connection and restart scanning */ if((cyBle_connHandle.bdHandle != 0)) { CyBle_GapDisconnect(cyBle_connHandle.bdHandle); restartScanning = TRUE; #ifdef DEBUG_ENABLED UART_UartPutString("Disconnect from CYBLE_EVT_GATTC_WRITE_RSP "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* This event is generated when the device disconnects from an * existing connection */ deviceConnected = FALSE; #ifdef DEBUG_ENABLED UART_UartPutString("CYBLE_EVT_GAP_DEVICE_DISCONNECTED "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif if((ble_gap_state == BLE_PERIPHERAL) && (switch_Role != TRUE)) { /* If the current role of this system was Peripheral and the role * is not to be switched, then restart advertisement */ if(CYBLE_STATE_DISCONNECTED == CyBle_GetState()) { CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); #ifdef DEBUG_ENABLED UART_UartPutString("Restart Advertisement "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } } else if((ble_gap_state == BLE_CENTRAL) && (switch_Role != TRUE)) { /* If the current role of this system was Central and the role * is not to be switched, then restart scanning */ if(CYBLE_STATE_DISCONNECTED == CyBle_GetState()) { CyBle_GapcStartScan(CYBLE_SCANNING_FAST); #ifdef DEBUG_ENABLED UART_UartPutString("Restart Scanning "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } } break; default: eventParam = eventParam; break; } }
void CustomEventHandler(uint32 event, void * eventParam) { CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam; switch(event) { case CYBLE_EVT_STACK_ON: case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* Start Advertisement and enter Discoverable mode*/ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: /* Set the BLE state variable to control LED status */ if(CYBLE_STATE_DISCONNECTED == CyBle_GetState()) { /* Start Advertisement and enter Discoverable mode*/ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); } break; case CYBLE_EVT_GATT_CONNECT_IND: /* This flag is used in application to check connection status */ deviceConnected = TRUE; break; case CYBLE_EVT_GATT_DISCONNECT_IND: /* Update deviceConnected flag*/ deviceConnected = FALSE; /* Reset CapSense notification flag to prevent further notifications * being sent to Central device after next connection. */ //sendCapSenseSliderNotifications = FALSE; /* Reset the CCCD value to disable notifications */ //updateNotificationCCCAttribute = TRUE; /* Reset the color coordinates */ RGBledData[RED_INDEX] = 0; RGBledData[GREEN_INDEX] = 0; RGBledData[BLUE_INDEX] = 0; RGBledData[INTENSITY_INDEX] = 0; UpdateRGBled(); break; case CYBLE_EVT_GATTS_WRITE_REQ: /* This event is received when Central device sends a Write command * on an Attribute. * We first get the attribute handle from the event parameter and * then try to match that handle with an attribute in the database. */ wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; /* This condition checks whether the RGB LED characteristic was * written to by matching the attribute handle. * If the attribute handle matches, then the value written to the * attribute is extracted and used to drive RGB LED. */ /* ADD_CODE to extract the attribute handle for the RGB LED * characteristic from the custom service data structure. */ //if(wrReqParam->handleValPair.attrHandle == cyBle_customs[RGB_LED_SERVICE_INDEX].\ // customServiceInfo[RGB_LED_CHAR_INDEX].customServiceCharHandle) if(wrReqParam->handleValPair.attrHandle == cyBle_customs[CYBLE_RGB_LED_SERVICE_SERVICE_INDEX].\ customServiceInfo[CYBLE_RGB_LED_SERVICE_RGB_LED_CHARACTERISTIC_CHAR_INDEX].customServiceCharHandle) { /* ADD_CODE to extract the value of the attribute from * the handle-value pair database. */ RGBledData[RED_INDEX] = wrReqParam->handleValPair.value.val[RED_INDEX]; RGBledData[GREEN_INDEX] = wrReqParam->handleValPair.value.val[GREEN_INDEX]; RGBledData[BLUE_INDEX] = wrReqParam->handleValPair.value.val[BLUE_INDEX]; RGBledData[INTENSITY_INDEX] = wrReqParam->handleValPair.value.val[INTENSITY_INDEX]; /* Update the PrISM components and the attribute for RGB LED read * characteristics */ UpdateRGBled(); //SendVoltageMeasurementNotification(voltageReading); } if(wrReqParam->handleValPair.attrHandle == 0x2A00) { RGBledData[RED_INDEX] = 0; RGBledData[GREEN_INDEX] = 0; RGBledData[BLUE_INDEX] = 0; RGBledData[INTENSITY_INDEX] = 0; /* Update the PrISM components and the attribute for RGB LED read * characteristics */ UpdateRGBled(); } //printf("%d",wrReqParam->handleValPair.attrHandle); /* ADD_CODE to send the response to the write request received. */ CyBle_GattsWriteRsp(cyBle_connHandle); break; case CYBLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ: // Is this in response to a read request? break; default: break; } }