/******************************************************************************* * Function Name: IasEventHandler ******************************************************************************** * * Summary: * This is an event callback function to receive events from the BLE Component, * which are specific to Immediate Alert Service. * * Parameters: * uint8 event: Write Command event from the CYBLE component. * void* eventParams: A structure instance of CYBLE_GATT_HANDLE_VALUE_PAIR_T * type. * * Return: * None * *******************************************************************************/ void MIDIEventHandler(uint32 event, void *eventParam) { CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam; CYBLE_GATT_HANDLE_VALUE_PAIR_T midiNotificationCccdHandle; uint8 midiCccdUpdate = 0x01; switch(event) { case CYBLE_EVT_GATTS_WRITE_REQ: /* This event is received when iOS device sends a Write command on an Attribute */ wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; /* When this event is triggered, the peripheral has received a write command on the custom characteristic */ /* Check if command is for correct attribute and update the flag for sending Notifications */ if(CYBLE_MIDI_SERVICE_MIDI_IO_CHARATERISTIC_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE == wrReqParam->handleValPair.attrHandle) { /* Extract the Write value sent by the Client for CapSense Slider CCCD */ enableMidi = wrReqParam->handleValPair.value.val[CYBLE_MIDI_SERVICE_MIDI_IO_CHARATERISTIC_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX]; /* Update CCCD handle with notification status data*/ midiNotificationCccdHandle.attrHandle = CYBLE_MIDI_SERVICE_MIDI_IO_CHARATERISTIC_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE; midiNotificationCccdHandle.value.val = &midiCccdUpdate; midiNotificationCccdHandle.value.len = sizeof(midiCccdUpdate); /* Report data to BLE component for sending data when read by Central device */ CyBle_GattsWriteAttributeValue(&midiNotificationCccdHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED); } CyBle_GattsWriteRsp(cyBle_connHandle); break; case CYBLE_EVT_GATTS_WRITE_CMD_REQ: ServiceMidiOutData(); break; } }
void AppCallBack(uint32 event, void *eventParam) { uint8 i; CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam; switch (event) { case CYBLE_EVT_STACK_ON: /* start advertising */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult == CYBLE_ERROR_OK) { #ifdef LED_INDICATION ADV_LED_ON(); #endif /* LED_INDICATION */ } break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: sendNotifications = 0; #ifdef ENABLE_I2C_ONLY_WHEN_CONNECTED /* Stop I2C Slave operation */ I2C_Stop(); #endif #ifdef LED_INDICATION /* Indicate disconnect event to user */ DISCON_LED_ON(); CyDelay(3000); #endif /* LED_INDICATION */ /* start advertising */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult == CYBLE_ERROR_OK) { #ifdef LED_INDICATION ADV_LED_ON(); #endif /* LED_INDICATION */ } break; case CYBLE_EVT_GATT_CONNECT_IND: #ifdef LED_INDICATION CONNECT_LED_ON(); #endif /* LED_INDICATION */ #ifdef ENABLE_I2C_ONLY_WHEN_CONNECTED /* Start I2C Slave operation */ I2C_Start(); /* Initialize I2C write buffer */ I2C_I2CSlaveInitWriteBuf((uint8 *) wrBuf, I2C_WRITE_BUFFER_SIZE); /* Initialize I2C read buffer */ I2C_I2CSlaveInitReadBuf((uint8 *) rdBuf, I2C_READ_BUFFER_SIZE); #endif break; /* Client may do Write Value or Write Value without Response. Handle both */ case CYBLE_EVT_GATTS_WRITE_REQ: case CYBLE_EVT_GATTS_WRITE_CMD_REQ: wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; /* Handling Notification Enable */ if(wrReqParam->handleValPair.attrHandle == CYBLE_I2C_READ_I2C_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { CYBLE_GATT_HANDLE_VALUE_PAIR_T I2CNotificationCCDHandle; uint8 I2CCCDValue[2]; /* Extract CCCD Notification enable flag */ sendNotifications = wrReqParam->handleValPair.value.val[0]; /* Write the present I2C notification status to the local variable */ I2CCCDValue[0] = sendNotifications; I2CCCDValue[1] = 0x00; /* Update CCCD handle with notification status data*/ I2CNotificationCCDHandle.attrHandle = CYBLE_I2C_READ_I2C_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE; I2CNotificationCCDHandle.value.val = I2CCCDValue; I2CNotificationCCDHandle.value.len = 2; /* Report data to BLE component for sending data when read by Central device */ CyBle_GattsWriteAttributeValue(&I2CNotificationCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED); } /* Handling Write data from Client */ else if(wrReqParam->handleValPair.attrHandle == CYBLE_I2C_WRITE_I2C_WRITE_DATA_CHAR_HANDLE) { /* Turn off I2C interrupt before updating read registers */ I2C_DisableInt(); /*The data received from I2C client is extracted */ for(i=0;i<(wrReqParam->handleValPair.value.len);i++) rdBuf[i] = wrReqParam->handleValPair.value.val[i]; /* Turn on I2C interrupt after updating read registers */ I2C_EnableInt(); } if (event == CYBLE_EVT_GATTS_WRITE_REQ) { CyBle_GattsWriteRsp(cyBle_connHandle); } break; default: break; } }
void AppCallBack(uint32 event, void *eventParam) { CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam; switch (event) { case CYBLE_EVT_STACK_ON: /* start advertising */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult == CYBLE_ERROR_OK) { #ifdef LED_INDICATION ADV_LED_ON(); #endif /* LED_INDICATION */ } break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: sendNotifications = 0; #ifdef ENABLE_SPI_ONLY_WHEN_CONNECTED /* Stop SPI Slave operation */ SPI_Stop(); #endif #ifdef LED_INDICATION /* Indicate disconnect event to user */ DISCON_LED_ON(); CyDelay(3000); #endif /* LED_INDICATION */ /* start advertising */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult == CYBLE_ERROR_OK) { #ifdef LED_INDICATION ADV_LED_ON(); #endif /* LED_INDICATION */ } break; case CYBLE_EVT_GATT_CONNECT_IND: #ifdef LED_INDICATION CONNECT_LED_ON(); #endif /* LED_INDICATION */ #ifdef ENABLE_SPI_ONLY_WHEN_CONNECTED /* Start SPI Slave operation */ SPI_Start(); #endif break; /* Client may do Write Value or Write Value without Response. Handle both */ case CYBLE_EVT_GATTS_WRITE_REQ: case CYBLE_EVT_GATTS_WRITE_CMD_REQ: wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; /* Handling Notification Enable */ if(wrReqParam->handleValPair.attrHandle == CYBLE_SPI_READ_SPI_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { CYBLE_GATT_HANDLE_VALUE_PAIR_T SPINotificationCCDHandle; uint8 SPICCDValue[2]; /* Extract CCCD Notification enable flag */ sendNotifications = wrReqParam->handleValPair.value.val[0]; /* Write the present SPI notification status to the local variable */ SPICCDValue[0] = sendNotifications; SPICCDValue[1] = 0x00; /* Update CCCD handle with notification status data*/ SPINotificationCCDHandle.attrHandle = CYBLE_SPI_READ_SPI_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE; SPINotificationCCDHandle.value.val = SPICCDValue; SPINotificationCCDHandle.value.len = 2; /* Report data to BLE component for sending data when read by Central device */ CyBle_GattsWriteAttributeValue(&SPINotificationCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED); } /* Handling Write data from Client */ else if(wrReqParam->handleValPair.attrHandle == CYBLE_SPI_WRITE_SPI_WRITE_DATA_CHAR_HANDLE) { while(SPI_SpiIsBusBusy()) { } SPI_SpiUartClearTxBuffer(); SPI_SpiUartPutArray(wrReqParam->handleValPair.value.val,wrReqParam->handleValPair.value.len); } if (event == CYBLE_EVT_GATTS_WRITE_REQ) { CyBle_GattsWriteRsp(cyBle_connHandle); } break; default: break; } }
/******************************************************************************* * Function Name: AppCallBack() ******************************************************************************** * * Summary: * This is an event callback function to receive events from the BLE Component. * *******************************************************************************/ void AppCallBack(uint32 event, void* eventParam) { CYBLE_API_RESULT_T apiResult; CYBLE_GAP_BD_ADDR_T localAddr; CYBLE_GAP_AUTH_INFO_T *authInfo; uint8 i; switch (event) { /********************************************************** * General Events ***********************************************************/ case CYBLE_EVT_STACK_ON: /* This event is received when the component is Started */ /* Enter into discoverable mode so that remote can search it. */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { DBG_PRINTF("StartAdvertisement API Error: %d \r\n", apiResult); } DBG_PRINTF("Bluetooth On, StartAdvertisement with addr: "); localAddr.type = 0u; CyBle_GetDeviceAddress(&localAddr); for(i = CYBLE_GAP_BD_ADDR_SIZE; i > 0u; i--) { DBG_PRINTF("%2.2x", localAddr.bdAddr[i-1]); } DBG_PRINTF("\r\n"); break; case CYBLE_EVT_TIMEOUT: break; case CYBLE_EVT_HARDWARE_ERROR: /* This event indicates that some internal HW error has occurred. */ DBG_PRINTF("CYBLE_EVT_HARDWARE_ERROR \r\n"); break; /* This event will be triggered by host stack if BLE stack is busy or not busy. * Parameter corresponding to this event will be the state of BLE stack. * BLE stack busy = CYBLE_STACK_STATE_BUSY, * BLE stack not busy = CYBLE_STACK_STATE_FREE */ case CYBLE_EVT_STACK_BUSY_STATUS: DBG_PRINTF("CYBLE_EVT_STACK_BUSY_STATUS: %x\r\n", *(uint8 *)eventParam); break; case CYBLE_EVT_HCI_STATUS: DBG_PRINTF("CYBLE_EVT_HCI_STATUS: %x \r\n", *(uint8 *)eventParam); break; /********************************************************** * GAP Events ***********************************************************/ case CYBLE_EVT_GAP_AUTH_REQ: DBG_PRINTF("CYBLE_EVT_AUTH_REQ: security=%x, bonding=%x, ekeySize=%x, err=%x \r\n", (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).security, (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).bonding, (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).ekeySize, (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).authErr); break; case CYBLE_EVT_GAP_PASSKEY_ENTRY_REQUEST: DBG_PRINTF("CYBLE_EVT_PASSKEY_ENTRY_REQUEST press 'p' to enter passkey \r\n"); break; case CYBLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST: DBG_PRINTF("CYBLE_EVT_PASSKEY_DISPLAY_REQUEST %6.6ld \r\n", *(uint32 *)eventParam); break; case CYBLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT: DBG_PRINTF("CYBLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT \r\n"); break; case CYBLE_EVT_GAP_AUTH_COMPLETE: authInfo = (CYBLE_GAP_AUTH_INFO_T *)eventParam; (void)authInfo; DBG_PRINTF("AUTH_COMPLETE: security:%x, bonding:%x, ekeySize:%x, authErr %x \r\n", authInfo->security, authInfo->bonding, authInfo->ekeySize, authInfo->authErr); break; case CYBLE_EVT_GAP_AUTH_FAILED: DBG_PRINTF("CYBLE_EVT_AUTH_FAILED: %x \r\n", *(uint8 *)eventParam); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: DBG_PRINTF("CYBLE_EVT_ADVERTISING, state: %x \r\n", CyBle_GetState()); if(CYBLE_STATE_DISCONNECTED == CyBle_GetState()) { /* Fast and slow advertising period complete, go to low power * mode (Hibernate mode) and wait for an external * user event to wake up the device again */ DBG_PRINTF("Hibernate \r\n"); LED_BLU_Write(LED_OFF); LED_RED_Write(LED_ON); LED_GRN_Write(LED_OFF); SW2_ClearInterrupt(); Wakeup_Interrupt_ClearPending(); Wakeup_Interrupt_Start(); #if (DEBUG_UART_ENABLED == ENABLED) /* Wait until debug info is sent */ while((UART_DEB_SpiUartGetTxBufferSize() + UART_DEB_GET_TX_FIFO_SR_VALID) != 0); #endif /* (DEBUG_UART_ENABLED == ENABLED) */ CySysPmHibernate(); } break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: DBG_PRINTF("CYBLE_EVT_GAP_DEVICE_CONNECTED \r\n"); LED_BLU_Write(LED_OFF); break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: DBG_PRINTF("CYBLE_EVT_GAP_DEVICE_DISCONNECTED\r\n"); apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { DBG_PRINTF("StartAdvertisement API Error: %d \r\n", apiResult); } break; case CYBLE_EVT_GATTS_XCNHG_MTU_REQ: { uint16 mtu; CyBle_GattGetMtuSize(&mtu); DBG_PRINTF("CYBLE_EVT_GATTS_XCNHG_MTU_REQ, final mtu= %d \r\n", mtu); } break; case CYBLE_EVT_GATTS_WRITE_REQ: DBG_PRINTF("CYBLE_EVT_GATT_WRITE_REQ: %x = ",((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.attrHandle); ShowValue(&((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value); (void)CyBle_GattsWriteRsp(((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->connHandle); break; case CYBLE_EVT_GAP_ENCRYPT_CHANGE: DBG_PRINTF("CYBLE_EVT_GAP_ENCRYPT_CHANGE: %x \r\n", *(uint8 *)eventParam); break; case CYBLE_EVT_GAPC_CONNECTION_UPDATE_COMPLETE: DBG_PRINTF("CYBLE_EVT_CONNECTION_UPDATE_COMPLETE: %x \r\n", *(uint8 *)eventParam); break; /********************************************************** * GATT Events ***********************************************************/ case CYBLE_EVT_GATT_CONNECT_IND: DBG_PRINTF("CYBLE_EVT_GATT_CONNECT_IND: %x, %x \r\n", cyBle_connHandle.attId, cyBle_connHandle.bdHandle); /* Register service specific callback functions */ HidsInit(); BasInit(); ScpsInit(); break; case CYBLE_EVT_GATT_DISCONNECT_IND: DBG_PRINTF("CYBLE_EVT_GATT_DISCONNECT_IND \r\n"); break; case CYBLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ: /* Triggered on server side when client sends read request and when * characteristic has CYBLE_GATT_DB_ATTR_CHAR_VAL_RD_EVENT property set. * This event could be ignored by application unless it need to response * by error response which needs to be set in gattErrorCode field of * event parameter. */ DBG_PRINTF("CYBLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ: handle: %x \r\n", ((CYBLE_GATTS_CHAR_VAL_READ_REQ_T *)eventParam)->attrHandle); break; /********************************************************** * Other Events ***********************************************************/ case CYBLE_EVT_PENDING_FLASH_WRITE: /* Inform application that flash write is pending. Stack internal data * structures are modified and require to be stored in Flash using * CyBle_StoreBondingData() */ DBG_PRINTF("CYBLE_EVT_PENDING_FLASH_WRITE\r\n"); break; default: DBG_PRINTF("OTHER event: %lx \r\n", event); break; } }
/******************************************************************************* * 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; } }
/***************************************************************************** * Function Name: EventHandler() ****************************************************************************** * Summary: * Handles the events generated by stack and take necessary actions when * event is received. * * Parameters: * eventCode - the event code * *event_params - the event parameters * * Return: * None. * * Note: * *****************************************************************************/ void EventHandler(uint32 eventCode, void *eventParam) { // Local variable to store the data received as part of the Write request // events. CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam; // Log all the events. eventCodesLog[pointer++] = eventCode; switch(eventCode) { ////////////////////////////////////////////////////////////////////// // General events ////////////////////////////////////////////////////////////////////// // This event is received when the module is started. case CYBLE_EVT_STACK_ON: // eventCode == 0x01 #if LOWPOWERMODE_ENABLED // Get the configured clock parameters for BLE subsystem. CyBle_GetBleClockCfgParam(&clockConfig); // Set the device sleep-clock accuracy (SCA) based on the // tuned ppm of the WCO. clockConfig.bleLlSca = CYBLE_LL_SCA_000_TO_020_PPM; // Set the clock parameter of BLESS with updated values. CyBle_SetBleClockCfgParam(&clockConfig); #endif // Start fast advertisement _BLE_restartAdvertisement = TRUE; break; // This event is received when there is a timeout and application // needs to handle the event. Timeout reason is defined by // CYBLE_TO_REASON_CODE_T. case CYBLE_EVT_TIMEOUT: // eventCode == 0x02 // If triggered by the advertisement timeout. if( *(CYBLE_TO_REASON_CODE_T *)eventParam == CYBLE_GAP_ADV_MODE_TO ) { } break; // This event is generated when the internal stack buffer is full // and no more data can be accepted or the stack has buffer available // and can accept data. This event is used by application to prevent // pushing lot of data to stack. case CYBLE_EVT_STACK_BUSY_STATUS: // eventCode == 0x05 // Extract the present stack status. _BLE_busyStatus = *(uint8*)eventParam; break; ////////////////////////////////////////////////////////////////////// // GAP events ////////////////////////////////////////////////////////////////////// // This event is received by Peripheral and Central devices. When it is // received by Peripheral, peripheral needs to Call CyBle_GappAuthReqReply() // to reply to authentication request from Central. case CYBLE_EVT_GAP_AUTH_REQ: // eventCode == 0x21 // Reply to the authentification request. CyBle_GappAuthReqReply(connectionHandle.bdHandle, &cyBle_authInfo); break; // Authentication process failed between two devices. The return value // of type CYBLE_GAP_AUTH_FAILED_REASON_T indicates the reason for failure. case CYBLE_EVT_GAP_AUTH_FAILED: // eventCode == 0x25 break; // If the current BLE state is Disconnected, then the Advertisement // Start_Stop event implies that advertisement has stopped. case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: // eventCode == 0x26 // Restart fast advertisement if(CyBle_GetState() != CYBLE_STATE_ADVERTISING) _BLE_restartAdvertisement = TRUE; break; // This event is generated at the GAP Peripheral end after // connection is completed with peer Centra device. case CYBLE_EVT_GAP_DEVICE_CONNECTED: // eventCode == 0x27 break; // Disconnected from remote device or failed to establish // connection. Parameter returned with the event contains pointer to // the reason for disconnection. case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: // eventCode == 0x28 break; // This event is generated at the GAP Central and the Peripheral end // after connection parameter update is requested from the host to // the controller. Event parameter is a pointer to a structure of type // CYBLE_GAP_CONN_PARAM_UPDATED_IN_CONTROLLER_T. case CYBLE_EVT_GAP_CONNECTION_UPDATE_COMPLETE: // eventCode == 0x2A break; ////////////////////////////////////////////////////////////////////// // GATT events ////////////////////////////////////////////////////////////////////// // This event is received when device is connected at GATT level. case CYBLE_EVT_GATT_CONNECT_IND: // eventCode == 0x41 // Update attribute handle on GATT Connection. connectionHandle = *(CYBLE_CONN_HANDLE_T *)eventParam; // Set the connection status flag. _BLE_deviceConnected = TRUE; // Set all the flags for the current connection. updateSensorsCCCDreq = TRUE; updateControlValuesReq = TRUE; _BLE_UpdateCCCD(); _BLE_UpdateControl(); _BLE_writeStatusFlags(); break; // This event is received when device is disconnected at GATT level. case CYBLE_EVT_GATT_DISCONNECT_IND: // eventCode == 0x42 // Reset the connection status flag. _BLE_deviceConnected = FALSE; // Reset the connection status flag. _BLE_resetNeeded = TRUE; break; // 'MTU Exchange Request' received from GATT client device. // Event parameter contains the MTU size of type CYBLE_GATT_XCHG_MTU_PARAM_T. case CYBLE_EVT_GATTS_XCNHG_MTU_REQ: // eventCode == 0x43 // Establish the MTU that is going to be used during communication. negotiatedMtu = (((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu < CYBLE_GATT_MTU) ? ((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu : CYBLE_GATT_MTU; break; // This event is received when Central device sends a Write command // on an Attribute. case CYBLE_EVT_GATTS_WRITE_REQ: // eventCode == 0x4C wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; // The peripheral has received a write command on the Sensors // Characteristic CCCD. if(CYBLE_CAPSENSE_SENSORS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE == wrReqParam->handleValPair.attrHandle) { // Extract the Write value sent by the Client CCCD. if( wrReqParam->handleValPair.value.val[CYBLE_CAPSENSE_SENSORS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX] & CCCD_NTF_BIT_MASK ) sendDataNotifications = TRUE; else sendDataNotifications = FALSE; if( wrReqParam->handleValPair.value.val[CYBLE_CAPSENSE_SENSORS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX] & CCCD_IND_BIT_MASK ) sendDataIndications = TRUE; else sendDataIndications = FALSE; // Set flag to allow CCCD to be updated. updateSensorsCCCDreq = TRUE; } // The peripheral has received a write command on the Control // Characteristic. else if(CYBLE_CAPSENSE_CONTROL_CHAR_HANDLE == wrReqParam->handleValPair.attrHandle) { // Update 'acquireData' flag: // FALSE only if 'Status_Acquiring' is TRUE; // TRUE only if 'Status_Ready' is also TRUE. if ( Status_Acquiring && !wrReqParam->handleValPair.value.val[CONTROL_ACQUIRE_DATA_BYTE_MASK] ) _BLE_acquireData = FALSE; else if ( Status_Ready && wrReqParam->handleValPair.value.val[CONTROL_ACQUIRE_DATA_BYTE_MASK] ) _BLE_acquireData = TRUE; // Update 'sendData' flag: // FALSE only if 'Status_NoMoreData' is TRUE; // TRUE only if 'Status_DataAcquired' is also TRUE. if ( !wrReqParam->handleValPair.value.val[CONTROL_SEND_DATA_BYTE_MASK] && Status_NoMoreData ) _BLE_sendData = FALSE; else if ( wrReqParam->handleValPair.value.val[CONTROL_SEND_DATA_BYTE_MASK] && Status_DataAcquired ) _BLE_sendData = TRUE; // Update 'sendDataSyncronously' flag: // FALSE only if 'Status_Acquiring' OR 'Status_Ready' is TRUE; // TRUE only if 'Status_Ready' is also TRUE. if ( (Status_Acquiring || Status_Ready) && !wrReqParam->handleValPair.value.val[CONTROL_SEND_DATA_SYNCHRONOUSLY_BYTE_MASK] ) _BLE_sendDataSynchronously = FALSE; else if ( Status_Ready && wrReqParam->handleValPair.value.val[CONTROL_SEND_DATA_SYNCHRONOUSLY_BYTE_MASK] ) _BLE_sendDataSynchronously = TRUE; // Set the flag to allow the control values to be updated. updateControlValuesReq = TRUE; } // The peripheral has received a write command on the Status // Characteristic CCCD. else if(CYBLE_CAPSENSE_STATUS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE == wrReqParam->handleValPair.attrHandle) { // Extract the Write value sent by the Client CCCD. if( wrReqParam->handleValPair.value.val[CYBLE_CAPSENSE_STATUS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX] & CCCD_NTF_BIT_MASK ) sendStatusNotifications = TRUE; else sendStatusNotifications = FALSE; if( wrReqParam->handleValPair.value.val[CYBLE_CAPSENSE_STATUS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX] & CCCD_IND_BIT_MASK ) sendStatusIndications = TRUE; else sendStatusIndications = FALSE; // Set flag to allow CCCD to be updated. updateStatusCCCDreq = TRUE; } // Update control flags _BLE_sendStatus = sendStatusNotifications | sendStatusIndications; // Send the response to the write request received. CyBle_GattsWriteRsp(connectionHandle); break; // Confirmation to indication response from client device. Event // parameter is a pointer to a structure of type CYBLE_CONN_HANDLE_T. case CYBLE_EVT_GATTS_HANDLE_VALUE_CNF: // eventCode == 0x54 break; // Event parameters for characteristic read value access event // generated by BLE Stack upon an access of Characteristic value read // for the characteristic definition which has // CYBLE_GATT_DB_ATTR_CHAR_VAL_RD_EVENT property set. case CYBLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ: // eventCode == 0x57 // Make sure all the flags are updated. _BLE_writeStatusFlags(); break; default: break; } }
/******************************************************************************* * Function Name: AppCallBack ******************************************************************************** * * Summary: * This is an event callback function to receive events from the CYBLE Component. * * Parameters: * uint8 event: Event from the CYBLE component. * void* eventParams: A structure instance for corresponding event type. The * list of event structure is described in the component * datasheet. * * Return: * None * *******************************************************************************/ void AppCallBack(uint32 event, void* eventParam) { CYBLE_API_RESULT_T apiResult; CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam; switch (event) { /********************************************************** * General Events ***********************************************************/ case CYBLE_EVT_STACK_ON: /* This event is received when component is Started */ /* Enter into discoverable mode so that remote can search it. */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { //ShowError(); } printf("CYBLE_EVT_STACK_ON\n"); break; case CYBLE_EVT_TIMEOUT: printf("CYBLE_EVT_TIMEOUT\n"); break; case CYBLE_EVT_HARDWARE_ERROR: /* This event indicates that some internal HW error has occurred. */ //ShowError(); break; /********************************************************** * GAP Events ***********************************************************/ case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: printf("CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP\n"); if(CYBLE_STATE_DISCONNECTED == CyBle_GetState()) { /* Fast and slow advertising period complete, go to low power * mode (Hibernate mode) and wait for an external * user event to wake up the device again */ // Advertising_LED_Write(LED_OFF); // Disconnect_LED_Write(LED_ON); // SW2_ClearInterrupt(); // Wakeup_Interrupt_ClearPending(); // Wakeup_Interrupt_Start(); CySysPmHibernate(); } break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: printf("CYBLE_EVT_GAP_DEVICE_CONNECTED\n"); // Disconnect_LED_Write(LED_OFF); // Advertising_LED_Write(LED_OFF); break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* Put the device to discoverable mode so that remote can search it. */ printf("CYBLE_EVT_GAP_DEVICE_DISCONNECTED\n"); apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { //ShowError(); } break; case CYBLE_EVT_GAPC_CONNECTION_UPDATE_COMPLETE: break; /********************************************************** * GATT Events ***********************************************************/ case CYBLE_EVT_GATT_CONNECT_IND: printf("CYBLE_EVT_GATT_CONNECT_IND\n"); break; case CYBLE_EVT_GATT_DISCONNECT_IND: printf("CYBLE_EVT_GATT_DISCONNECT_IND\n"); // Reset the rotation notification _rotationCCCDValue[0] = 0; _voltageCCCDValue[0] = 0; _drawCCCDValue[0] = 0; break; case CYBLE_EVT_GATTS_WRITE_REQ: printf("CYBLE_EVT_GATTS_WRITE_REQ\n"); wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; /* Write request for time/date */ if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_TIME_CHAR_HANDLE) { /* only update the value and write the response if the requested write is allowed */ if(CYBLE_GATT_ERR_NONE == CyBle_GattsWriteAttributeValue(&wrReqParam->handleValPair, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED)) { uint64_t datetime = wrReqParam->handleValPair.value.val[0]; datetime <<= 8; datetime |= wrReqParam->handleValPair.value.val[1]; datetime <<= 8; datetime |= wrReqParam->handleValPair.value.val[2]; datetime <<= 8; datetime |= wrReqParam->handleValPair.value.val[3]; printf("Date time EPOCH: %08x\n", (unsigned int)(datetime >> 32)); printf("Date time EPOCH: %08x\n", (unsigned int)datetime); RTC_SetUnixTime(datetime); } } /* Write request for time/date */ if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_FILTERGAIN_CHAR_HANDLE) { /* only update the value and write the response if the requested write is allowed */ if(CYBLE_GATT_ERR_NONE == CyBle_GattsWriteAttributeValue(&wrReqParam->handleValPair, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED)) { _rotationFilterGain = wrReqParam->handleValPair.value.val[0]; _rotationFilterGain <<= 8; _rotationFilterGain |= wrReqParam->handleValPair.value.val[1]; _rotationFilterGain <<= 8; _rotationFilterGain |= wrReqParam->handleValPair.value.val[2]; _rotationFilterGain <<= 8; _rotationFilterGain |= wrReqParam->handleValPair.value.val[3]; } } if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_DRAWOFFSET_CHAR_HANDLE) { /* only update the value and write the response if the requested write is allowed */ if(CYBLE_GATT_ERR_NONE == CyBle_GattsWriteAttributeValue(&wrReqParam->handleValPair, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED)) { _drawOffset = wrReqParam->handleValPair.value.val[0]; _drawOffset <<= 8; _drawOffset |= wrReqParam->handleValPair.value.val[1]; } } if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_ROTATIONSPEED_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { /* only update the value and write the response if the requested write is allowed */ if(wrReqParam->handleValPair.value.val[CYBLE_POVDISPLAY_ROTATIONSPEED_CHARACTERISTIC_USER_DESCRIPTION_DESC_INDEX] == 1) { _rotationCCCDValue[0] = 1; } else { _rotationCCCDValue[0] = 0; } /* Update CCCD handle with notification status data*/ _rotationNotificationCCCDHandle.attrHandle = CYBLE_POVDISPLAY_ROTATIONSPEED_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE; _rotationNotificationCCCDHandle.value.val = _rotationCCCDValue; _rotationNotificationCCCDHandle.value.len = 2; /* Report data to BLE component for sending data when read by Central device */ CyBle_GattsWriteAttributeValue(&_rotationNotificationCCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED); } if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_VOLTAGE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { /* only update the value and write the response if the requested write is allowed */ if(wrReqParam->handleValPair.value.val[CYBLE_POVDISPLAY_VOLTAGE_CHARACTERISTIC_USER_DESCRIPTION_DESC_INDEX] == 1) { _voltageCCCDValue[0] = 1; } else { _voltageCCCDValue[0] = 0; } /* Update CCCD handle with notification status data*/ _voltageNotificationCCCDHandle.attrHandle = CYBLE_POVDISPLAY_VOLTAGE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE; _voltageNotificationCCCDHandle.value.val = _voltageCCCDValue; _voltageNotificationCCCDHandle.value.len = 2; /* Report data to BLE component for sending data when read by Central device */ CyBle_GattsWriteAttributeValue(&_voltageNotificationCCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED); } if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_DRAWTIME_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { /* only update the value and write the response if the requested write is allowed */ if(wrReqParam->handleValPair.value.val[CYBLE_POVDISPLAY_DRAWTIME_CHARACTERISTIC_USER_DESCRIPTION_DESC_INDEX] == 1) { _drawCCCDValue[0] = 1; } else { _drawCCCDValue[0] = 0; } /* Update CCCD handle with notification status data*/ _drawNotificationCCCDHandle.attrHandle = CYBLE_POVDISPLAY_DRAWTIME_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE; _drawNotificationCCCDHandle.value.val = _drawCCCDValue; _drawNotificationCCCDHandle.value.len = 2; /* Report data to BLE component for sending data when read by Central device */ CyBle_GattsWriteAttributeValue(&_drawNotificationCCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED); } CyBle_GattsWriteRsp(cyBle_connHandle); break; /********************************************************** * Other Events ***********************************************************/ case CYBLE_EVT_STACK_BUSY_STATUS: /* This event is generated when the internal stack buffer is full and no more * data can be accepted or the stack has buffer available and can accept data. * This event is used by application to prevent pushing lot of data to stack. */ /* Extract the present stack status */ _busyStatus = * (uint8*)eventParam; break; default: break; }
/******************************************************************************* * Function Name: ProcessWriteReq ******************************************************************************** * * Summary: * Process all GATT level write requests and responds with appropriate status * * Parameters: * CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T: GATT write command request prameter * * Return: * None * *******************************************************************************/ void ProcessWriteReq(CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T writeCmdReq) { bool value_val; uint8 status = LOCKED, key_buf[LOCK_CODE_LENGTH]; uint16 beaconPeriod = 0; CYBLE_GATT_HANDLE_VALUE_PAIR_T valuePairT; /* Reset error send flag */ errorSent = false; /* Retrieve the LOCK status from the GATT DB */ valuePairT.attrHandle = CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE; valuePairT.value.val = (uint8 *)&value_val; valuePairT.value.len = sizeof(bool); CyBle_GattsReadAttributeValue( &valuePairT, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED ); /* Check the LOCK status */ if(valuePairT.value.val[0] == UNLOCKED) { /*URL Data*/ if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE) { /* First byte should be scheme prefix and length should be less than * or equal to MAX_URL_LENGTH */ if( (writeCmdReq.handleValPair.value.len <= MAX_URL_LENGTH) && (writeCmdReq.handleValPair.value.val[0] < URL_PREFIX_MAX) ) { uint8 TempURL[MAX_URL_LENGTH]; memset(TempURL, 0, MAX_URL_LENGTH); memcpy( TempURL, writeCmdReq.handleValPair.value.val, writeCmdReq.handleValPair.value.len ); if( CYBLE_GATT_ERR_NONE == WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ) ) { /* Update the length as per the new URL data */ URLLength = writeCmdReq.handleValPair.value.len; cyBle_attValuesLen[16].actualLength = URLLength; /* Update the URL data */ memcpy(CurrentURL, TempURL, MAX_URL_LENGTH); } } else if (writeCmdReq.handleValPair.value.len > MAX_URL_LENGTH) { /* Invalid length. Send error response */ SendErrorResponse ( CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN ); } } /* Lock Characteristic */ else if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE) { if(writeCmdReq.handleValPair.value.len == LOCK_CODE_LENGTH) { WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); /* Update the LOCK characteristic */ status = LOCKED; WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE, sizeof(bool), &status, CYBLE_GATT_DB_LOCALLY_INITIATED ); } else { /* Invalid length. Send error response */ SendErrorResponse(CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN); } } /* Advertised Tx power level */ else if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE) { if (writeCmdReq.handleValPair.value.len == MAX_NUM_PWR_LVL) { WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); if (writeCmdReq.handleValPair.value.len == MAX_NUM_PWR_LVL) { /* Update Tx Power levels */ memcpy ( currentTxPowerLevels, writeCmdReq.handleValPair.value.val, MAX_NUM_PWR_LVL ); } else { SendErrorResponse ( CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN ); } } else { /* Invalid length. Send error response */ SendErrorResponse ( CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN ); } } /* Tx Power Mode */ else if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE) { if(writeCmdReq.handleValPair.value.val[0] <= 0x03) { WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); currentTxmode = writeCmdReq.handleValPair.value.val[0]; UpdateTxPower(currentTxmode); } else /* Invalid value. Write not permitted. */ { SendErrorResponse ( CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE, CYBLE_GATT_ERR_WRITE_NOT_PERMITTED ); } } /* Beacon Period */ else if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE) { beaconPeriod = CyBle_Get16ByPtr(writeCmdReq.handleValPair.value.val); /* Disable URL FRAMES */ if(beaconPeriod == 0) { eddystoneImplenmentation = EDDYSTONE_UID; WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); } /* Values in valid range */ else if((beaconPeriod >= MIN_BEACON_PERIOD) && (beaconPeriod <= MAX_BEACON_PERIOD)) { WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); CurrentAdvPeriod = beaconPeriod / 0.625; eddystoneImplenmentation = EDDYSTONE_URL; } else { uint16 temp = MIN_BEACON_PERIOD; /* Values not supportes. Write default values */ WriteAttributeValue( CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE, sizeof(temp), (uint8 *)&temp, CYBLE_GATT_DB_PEER_INITIATED); CurrentAdvPeriod = CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN; eddystoneImplenmentation = EDDYSTONE_URL; } } /* Reset the Configurations to default */ else if((writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_RESET_CHAR_HANDLE) && (writeCmdReq.handleValPair.value.val[0] != 0)) { ResetGattDb(); } } else if(valuePairT.value.val[0] == LOCKED) { if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE) { /* Accesing the lock in LOCKED state */ SendErrorResponse(writeCmdReq.handleValPair.attrHandle, CYBLE_GATT_ERR_INSUFFICIENT_AUTHORIZATION); } } if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_UNLOCK_CHAR_HANDLE) { if(writeCmdReq.handleValPair.value.len == LOCK_CODE_LENGTH) { if(valuePairT.value.val[0] == LOCKED) { int compareResult; valuePairT.attrHandle = CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE; valuePairT.value.val = key_buf; valuePairT.value.len = sizeof(LOCK); CyBle_GattsReadAttributeValue(&valuePairT, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED); compareResult = memcmp ( valuePairT.value.val, writeCmdReq.handleValPair.value.val, LOCK_CODE_LENGTH ); if(compareResult == 0) { status = UNLOCKED; /* Update the LOCK STATE */ WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE, sizeof(bool), &status, CYBLE_GATT_DB_LOCALLY_INITIATED ); /* Reset the LOCK */ WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE, sizeof(LOCK), (uint8 *)LOCK, CYBLE_GATT_DB_LOCALLY_INITIATED ); } else /* LOCK not matched */ { SendErrorResponse(writeCmdReq.handleValPair.attrHandle, CYBLE_GATT_ERR_INSUFFICIENT_AUTHORIZATION); } } } else /* Invalid length */ { SendErrorResponse(writeCmdReq.handleValPair.attrHandle, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN); } } if (errorSent == false) { CyBle_GattsWriteRsp(cyBle_connHandle); } }
/******************************************************************************* * Function Name: AppCallBack() ******************************************************************************** * * Summary: * This finction handles events that are generated by BLE stack. * * Parameters: * None * * Return: * None * *******************************************************************************/ void AppCallBack(uint32 event, void* eventParam) { CYBLE_API_RESULT_T apiResult; uint32 i = 0u; switch (event) { /********************************************************** * General Events ***********************************************************/ case CYBLE_EVT_STACK_ON: /* This event received when component is Started */ /* Enter in to discoverable mode so that remote can search it. */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { } break; case CYBLE_EVT_HARDWARE_ERROR: /* This event indicates that some internal HW error has occurred. */ DBG_PRINTF("CYBLE_EVT_HARDWARE_ERROR\r\n"); break; /********************************************************** * GAP Events ***********************************************************/ case CYBLE_EVT_GAP_AUTH_REQ: DBG_PRINTF("EVT_AUTH_REQ: security=%x, bonding=%x, ekeySize=%x, err=%x \r\n", (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).security, (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).bonding, (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).ekeySize, (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).authErr); break; case CYBLE_EVT_GAP_PASSKEY_ENTRY_REQUEST: DBG_PRINTF("EVT_PASSKEY_ENTRY_REQUEST press 'p' to enter passkey \r\n"); break; case CYBLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST: DBG_PRINTF("EVT_PASSKEY_DISPLAY_REQUEST %6.6ld \r\n", *(uint32 *)eventParam); break; case CYBLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT: DBG_PRINTF("EVT_GAP_KEYINFO_EXCHNGE_CMPLT \r\n"); break; case CYBLE_EVT_GAP_AUTH_COMPLETE: DBG_PRINTF("AUTH_COMPLETE"); break; case CYBLE_EVT_GAP_AUTH_FAILED: DBG_PRINTF("EVT_AUTH_FAILED: %x \r\n", *(uint8 *)eventParam); break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: DBG_PRINTF("EVT_GAP_DEVICE_CONNECTED: %d \r\n", connHandle.bdHandle); LED_WRITE_MACRO(LED_OFF); break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: DBG_PRINTF("EVT_GAP_DEVICE_DISCONNECTED\r\n"); apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { DBG_PRINTF("StartAdvertisement API Error: %d \r\n", apiResult); } break; case CYBLE_EVT_GAP_ENCRYPT_CHANGE: DBG_PRINTF("EVT_GAP_ENCRYPT_CHANGE: %x \r\n", *(uint8 *)eventParam); break; case CYBLE_EVT_GAPC_CONNECTION_UPDATE_COMPLETE: DBG_PRINTF("EVT_CONNECTION_UPDATE_COMPLETE: %x \r\n", *(uint8 *)eventParam); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: if(CYBLE_STATE_DISCONNECTED == CyBle_GetState()) { /* Fast and slow advertising period complete, go to low power * mode (Hibernate mode) and wait for an external * user event to wake up the device again */ DBG_PRINTF("Entering low power mode...\r\n"); Bootloading_LED_Write(LED_ON); Advertising_LED_1_Write(LED_ON); Advertising_LED_2_Write(LED_ON); Bootloader_Service_Activation_ClearInterrupt(); Wakeup_Interrupt_ClearPending(); Wakeup_Interrupt_Start(); CySysPmHibernate(); } break; /********************************************************** * GATT Events ***********************************************************/ case CYBLE_EVT_GATTS_WRITE_REQ: DBG_PRINTF("EVT_GATT_WRITE_REQ: %x = ",((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.attrHandle); for(i = 0; i < ((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value.len; i++) { DBG_PRINTF("%2.2x ", ((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value.val[i]); } DBG_PRINTF("\r\n"); CyBle_GattsWriteAttributeValue(&((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair, 0u, \ &((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->connHandle, CYBLE_GATT_DB_PEER_INITIATED); (void)CyBle_GattsWriteRsp(((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->connHandle); break; case CYBLE_EVT_GATT_CONNECT_IND: connHandle = *(CYBLE_CONN_HANDLE_T *)eventParam; break; case CYBLE_EVT_GATT_DISCONNECT_IND: connHandle.bdHandle = 0; break; case CYBLE_EVT_GATTS_WRITE_CMD_REQ: /* Pass packet to bootloader emulator */ packetRXSize = ((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value.len; memcpy(&packetRX[0], ((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value.val, packetRXSize); packetRXFlag = 1u; break; case CYBLE_EVT_GATTS_PREP_WRITE_REQ: (void)CyBle_GattsPrepWriteReqSupport(CYBLE_GATTS_PREP_WRITE_NOT_SUPPORT); break; case CYBLE_EVT_HCI_STATUS: DBG_PRINTF("CYBLE_EVT_HCI_STATUS\r\n"); default: break; } }
void StackEventHandler(uint32 event, void *eventParam) { switch (event) { //====================================================== // Mandatory events to be handled //====================================================== case CYBLE_EVT_STACK_ON: // Disable CCCD notification initializeCounterCccDescriptor(); // Start BLE advertisement for 30 seconds CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); // Initialize descriptor initializeRgbDescriptor(); break; //====================================================== // GAP Events //====================================================== case CYBLE_EVT_GAP_DEVICE_CONNECTED: // BLE link is established break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: // Disable CCCD notification initializeCounterCccDescriptor(); // Start BLE advertisement for 30 seconds CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; //====================================================== // GATT Events //====================================================== case CYBLE_EVT_GATT_CONNECT_IND: // This event is received when device is connected // over GATT level // Update attribute handle on GATT Connection connectionHandle = *(CYBLE_CONN_HANDLE_T *)eventParam; // This flag is used in application // to check connection status deviceConnected = 1; break; case CYBLE_EVT_GATT_DISCONNECT_IND: // This event is received when device is disconnected // Update deviceConnected flag deviceConnected = 0; break; case CYBLE_EVT_GATTS_WRITE_REQ: // This event is received when Central device sends { CYBLE_GATTS_WRITE_REQ_PARAM_T *writeReqParam; // a Write command on an Attribute writeReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; // When this event is triggered, the peripheral has // received a write command on the custom characteristic // Check if the returned handle is matching to // Counter CCCD Write Attribute if (writeReqParam->handleValPair.attrHandle == COUNTER_CCC_HANDLE ) { queueCounterCccDescriptor( &(writeReqParam->handleValPair.value) ); } // Check if the returned handle is matching to // RGB Control Write Attribute if (writeReqParam->handleValPair.attrHandle == RGB_CHAR_HANDLE ) { queueRgbDescriptor( &(writeReqParam->handleValPair.value) ); } // Send the response to the write request received. CyBle_GattsWriteRsp(connectionHandle); } break; default: break; } }
/************************************************************************************************************************* * Function Name: CustomEventHandler ************************************************************************************************************************** * Summary: This is a call back event function to handle various events from BLE stack. * * Parameters: * Event - Event returned * EventParameter - Link to value of the event returned * * Return: * void * *************************************************************************************************************************/ void CustomEventHandler(uint32 Event, void *EventParameter) { switch(Event) { /********************************************************** * General Events ***********************************************************/ case CYBLE_EVT_STACK_ON: //This event is received when the BLE component is started StartAdvertisement = TRUE; //Set the advertisement flag break; case CYBLE_EVT_STACK_BUSY_STATUS: //This event is generated when the internal stack buffer is full and no more data can be accepted or the stack has buffer available and can accept data BLEStackStatus = *(uint8*)EventParameter; //Extract the BLE stack status break; /********************************************************** * GAP Events ***********************************************************/ case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: //This event is received when the device starts or stops advertising if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { StartAdvertisement = TRUE; //Set the advertisement flag } break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: //This event is received when the device is disconnected StartAdvertisement = TRUE; //Set the advertisement flag break; /********************************************************** * GATT Events ***********************************************************/ case CYBLE_EVT_GATT_CONNECT_IND: //This event is received when the device is connected over GATT level ConnectionHandle = *(CYBLE_CONN_HANDLE_T *)EventParameter; //Update the attribute handle on GATT connection DeviceConnected = TRUE; //Set device connection status flag ChangePowerPinDriveMode = FALSE; //Clear change power pin drive mode flag break; case CYBLE_EVT_GATT_DISCONNECT_IND: //This event is received when device is disconnected DeviceConnected = FALSE; //Clear device connection status flag TemperatureNotificationEnabled = FALSE; //Clear the temperature notification flag PressureNotificationEnabled = FALSE; //Clear the pressure notification flag AltitudeNotificationEnabled = FALSE; //Clear the altitude notification flag UpdateTemperatureNotificationAttribute = TRUE; //Clear the update temperature notification flag UpdatePressureNotificationAttribute = TRUE; //Clear the update pressure notification flag UpdateAltitudeNotificationAttribute = TRUE; //Clear the update altitude notification flag /* Clear temperature notification data */ TemperatureNotificationData[0x03] = TemperatureNotificationData[0x02] = TemperatureNotificationData[0x01] = TemperatureNotificationData[0x00] = ZERO; /* Clear pressure notification data */ PressureNotificationData[0x03] = PressureNotificationData[0x02] = PressureNotificationData[0x01] = PressureNotificationData[0x00] = ZERO; /* Clear altitude notification data */ AltitudeNotificationData[0x03] = AltitudeNotificationData[0x02] = AltitudeNotificationData[0x01] = AltitudeNotificationData[0x00] = ZERO; LastTemperatureData = ZERO; //Clear last stored temperature notification data LastPressureData = ZERO; //Clear last stored pressure notification data LastAltitudeData = ZERO; //Clear last stored altitude notification data ChangePowerPinDriveMode = TRUE; //Set change power pin drive mode flag ConnectionParametersUpdateRequired = TRUE; //Set the Connection Parameters Update flag UpdateNotificationCCCDAttribute(); //Update the CCCD writing by the Central device break; case CYBLE_EVT_GATTS_WRITE_REQ: //When this event is triggered, the peripheral has received a write command on the custom characteristic /* Extract the write value from the event parameter */ WriteRequestedParameter = (CYBLE_GATTS_WRITE_REQ_PARAM_T *)EventParameter; /* Check if command is for notification attribute and update the flag for sending notifications */ if(WriteRequestedParameter->handleValPair.attrHandle == CYBLE_BMP180_TEMPERATURE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { /* Set temperature notification flag so that application can start sending notifications */ TemperatureNotificationEnabled = WriteRequestedParameter->handleValPair.value.val[CYBLE_BMP180_TEMPERATURE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX]; UpdateTemperatureNotificationAttribute = TRUE; //Set flag to allow CCCD to be updated for next read operation } /* Check if command is for notification attribute and update the flag for sending notifications */ if(WriteRequestedParameter->handleValPair.attrHandle == CYBLE_BMP180_PRESSURE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { /* Set pressure notification flag so that application can start sending notifications */ PressureNotificationEnabled = WriteRequestedParameter->handleValPair.value.val[CYBLE_BMP180_PRESSURE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX]; UpdatePressureNotificationAttribute = TRUE; //Set flag to allow CCCD to be updated for next read operation } /* Check if command is for notification attribute and update the flag for sending notifications */ if(WriteRequestedParameter->handleValPair.attrHandle == CYBLE_BMP180_ALTITUDE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { /* Set altitude notification flag so that application can start sending notifications */ AltitudeNotificationEnabled = WriteRequestedParameter->handleValPair.value.val[CYBLE_BMP180_ALTITUDE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX]; UpdateAltitudeNotificationAttribute = TRUE; //Set flag to allow CCCD to be updated for next read operation } /* Send response to the write command received */ CyBle_GattsWriteRsp(ConnectionHandle); break; /********************************************************** * L2CAP Events ***********************************************************/ case CYBLE_EVT_L2CAP_CONN_PARAM_UPDATE_RSP: //This event is generated when the L2CAP connection parameter update response received ConnectionParametersUpdateRequired = FALSE; //Clear the Connection Parameters Update flag break; default: break; } }