/******************************************************************************* * Function Name: BLE_StackEventHandler ******************************************************************************** * * Summary: * BLE stack generic event handler routine for handling connection, discovery, * security etc. events. * * Parameters: * event - event that triggered this callback * eventParam - parameters for the event. * * Return: * None *******************************************************************************/ void BLE_StackEventHandler(uint32 event, void* eventParam) { CYBLE_API_RESULT_T apiResult; (void) eventParam; switch(event) { case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: break; case CYBLE_EVT_STACK_ON: /* Put the device into discoverable mode so that remote can search it. */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { CYASSERT(0); } break; /* ADD YOUR CODE TO HANDLE OTHER GENERIC BLE STACK EVENTS */ /* All the BLE stack events can be found in BLE_Stack.h (see CYBLE_EVENT_T enum) and BLE_eventHandler.h (see * CYBLE_EVT_T enum ) */ default: break; } }
/******************************************************************************* * Function Name: StartAdvertisement ******************************************************************************** * * Summary: * Initiates the advertisement procedure. * Prints the Device Address. * * Parameters: * None. * * Return: * None. * *******************************************************************************/ void StartAdvertisement(uint8 advType) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK; CYBLE_GAP_BD_ADDR_T localAddr; uint16 i; if(advType == ADV_STATE_GENERAL) { cyBle_discoveryParam.advFilterPolicy = SCAN_ANY_CONNECT_ANY; } else { cyBle_discoveryParam.advFilterPolicy = SCAN_WHITELIST_CONNECT_WHITELIST; } apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { printf("StartAdvertisement API Error: %x \r\n", (int) apiResult); } else { printf("Start Advertisement with addr: "); CyBle_GetDeviceAddress(&localAddr); for(i = CYBLE_GAP_BD_ADDR_SIZE; i > 0u; i--) { printf("%2.2x", localAddr.bdAddr[i-1]); } printf("\r\n"); } }
/******************************************************************************* * Function Name: StackEventHandler ******************************************************************************** * * Summary: * This is an event callback function to receive events from the BLE 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 StackEventHandler(uint32 event, void *eventParam) { switch(event) { /* Mandatory events to be handled by Find Me Target design */ case CYBLE_EVT_STACK_ON: case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* Start BLE advertisement for 30 seconds and update link * status on LEDs */ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); Advertising_LED_Write(LED_ON); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { /* Advertisement event timed out, 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); Hibernate_LED_Write(LED_ON); Wakeup_SW_ClearInterrupt(); Wakeup_Interrupt_ClearPending(); Wakeup_Interrupt_Start(); CySysPmHibernate(); } break; default: break; } }
/* Main loop */ int main() { CYBLE_API_RESULT_T apiResult; CyGlobalIntEnable; Initialization(); for(;;) { /* Delayed start of advertisement */ if(initCounter == 6) { initCounter = 7; WDT_DisableWcoEcoCounters(); apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_CUSTOM); if(apiResult != CYBLE_ERROR_OK) { CYASSERT(0); } } CyBle_ProcessEvents(); /* BLE stack processing state machine interface */ LowPower(); } }
void StartAdvertisment() { apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if (apiResult != CYBLE_ERROR_OK) { printf("CyBle_Start API error: %x \r\n", apiResult); Error_Led_Write(LED_ON); } else { Advertising_Led_Write(LED_ON); } }
/******************************************************************************* * Function Name: main ******************************************************************************** * Summary: * System entrance point. This calls the initializing function and * continuously process BLE and CapSense events. * * Parameters: * void * * Return: * int * *******************************************************************************/ int main() { uint8 lpmSel = DEEPSLEEP; /* This function will initialize the system resources such as BLE and CapSense */ InitializeSystem(); for(;;) { /*Process event callback to handle BLE events. The events generated and * used for this application are inside the 'CustomEventHandler' routine*/ CyBle_ProcessEvents(); /* Updated LED for status during BLE active states */ HandleStatusLED(); if(TRUE == deviceConnected) { /* After the connection, send new connection parameter to the Client device * to run the BLE communication on desired interval. This affects the data rate * and power consumption. High connection interval will have lower data rate but * lower power consumption. Low connection interval will have higher data rate at * expense of higher power. This function is called only once per connection. */ UpdateConnectionParam(); /* When the Client Characteristic Configuration descriptor (CCCD) is written * by Central device for enabling/disabling notifications, then the same * descriptor value has to be explicitly updated in application so that * it reflects the correct value when the descriptor is read */ UpdateNotificationCCCD(); lpmSel = LPMselData; } #ifdef ENABLE_LOW_POWER_MODE /* Put system to Deep sleep, including BLESS, and wakeup on interrupt. * The source of the interrupt can be either BLESS Link Layer in case of * BLE advertisement and connection or by User Button press during BLE * disconnection */ HandleLowPowerMode(lpmSel); #endif if(restartAdvertisement) { /* Reset 'restartAdvertisement' flag*/ restartAdvertisement = FALSE; /* Start Advertisement and enter Discoverable mode*/ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); } } /* End of for(;;) */ }
/******************************************************************************* * Function Name: BLE_AppEventHandler ******************************************************************************** * * Summary: * BLE stack generic event handler routine for handling connection, discovery, * security etc. events. * * Parameters: * event - event that triggered this callback * eventParam - parameters for the event. * * Return: * None *******************************************************************************/ void BLE_AppEventHandler(uint32 event, void* eventParam) { CYBLE_API_RESULT_T apiResult; (void)eventParam; switch (event) { /********************************************************** * General Events ***********************************************************/ case CYBLE_EVT_STACK_ON: /* This event is 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) { CYASSERT(0); } break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { /* On advertisement timeout, restart advertisement */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { CYASSERT(0); } } break; default: break; } }
/* BLE stack event handler */ void BLE_AppEventHandler(uint32 event, void* eventParam) { CYBLE_API_RESULT_T apiResult; switch (event) { /********************************************************** * General Events ***********************************************************/ /* This event is received when component is Started */ case CYBLE_EVT_STACK_ON: /* Start with a regular UID/URL packet */ isRegularAdvScheduled = true; ConfigureAdvPacket(isRegularAdvScheduled); initCounter = 0; WDT_EnableWcoCounter(); /* Enable WDT's WCO counter (counter 0) */ break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: if(CyBle_GetState() != CYBLE_STATE_ADVERTISING) { /* On advertisement timeout, restart advertisement */ #if (IS_EDDYSTONE_TLM_PRESENT) if(true == isRegularAdvScheduled) { /* Configure for TLM packet */ isRegularAdvScheduled = false; } else { /* Configure for regular UID/URL packet */ isRegularAdvScheduled = true; } ConfigureAdvPacket(isRegularAdvScheduled); #endif CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_CUSTOM); } break; default: break; } }
/******************************************************************************* * Function Name: main ******************************************************************************** * Summary: * System entrance point. This calls the initializing function and * continuously process BLE events. * * Parameters: * void * * Return: * int * *******************************************************************************/ int main() { /* This function will initialize the system resources such as BLE and * NEC pulse timer */ InitializeSystem(); for(;;) { /* Process event callback to handle BLE events. The events generated and * used for this application are inside the 'CustomEventHandler' routine */ CyBle_ProcessEvents(); /* Update LED for status during BLE active states */ HandleStatusLED(); if(TRUE == deviceConnected) { /* After the connection, send new connection parameter to the Client device * to run the BLE communication on desired interval. This affects the data rate * and power consumption. High connection interval will have lower data rate but * lower power consumption. Low connection interval will have higher data rate at * expense of higher power. This function is called only once per connection. */ UpdateConnectionParam(); } if(restartAdvertisement) { /* Reset 'restartAdvertisement' flag*/ restartAdvertisement = FALSE; /* Start Advertisement and enter Discoverable mode*/ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); } } /* End of for(;;) */ }
void StackEventHandler(uint32 event,void * eventParam) { /*Local avriables*/ uint8 i; CYBLE_GAP_BD_ADDR_T localAddr; switch(event) { case CYBLE_EVT_STACK_ON: printf("BLE Stack ON: \r\n"); /*Get local device address*/ CyBle_GetDeviceAddress(&localAddr); for(i = CYBLE_GAP_BD_ADDR_SIZE; i > 0u; i--) { printf("%2.2x", localAddr.bdAddr[i-1]); } printf("\r\n"); /*Start to advertise*/ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: if(CyBle_GetState()==CYBLE_STATE_DISCONNECTED) { printf("Advertising stopped\r\n"); } else if(CyBle_GetState()==CYBLE_STATE_ADVERTISING) { printf("Started to Advertise\r\n"); } break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: printf("Device Connected\r\n)"); break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: disSupport=0; CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE: printf("\r\n"); printf("Discovery complete.\r\n"); printf("Discovered services: \r\n"); for(i = 0u; i < CYBLE_SRVI_COUNT; i++) { /*Check for DIS service*/ if(cyBle_serverInfo[i].uuid == CYBLE_UUID_DEVICE_INFO_SERVICE) { if(cyBle_serverInfo[i].range.startHandle < cyBle_serverInfo[i].range.endHandle) { printf("Peer device supports Device Information Service \r\n"); disSupport=1; } else { printf("Peer device doesn't supports Device Information Service \r\n"); } } } printf("\r\n"); break; default: break; } }
/******************************************************************************* * Function Name: StackEventHandler ******************************************************************************** * * Summary: * This is an event callback function to receive events from the BLE 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 StackEventHandler(uint32 event, void *eventParam) { char authFailReasonCode[3]; CYBLE_GAP_AUTH_FAILED_REASON_T *authFailReason; switch(event) { /* Mandatory events to be handled by Find Me Target design */ case CYBLE_EVT_STACK_ON: case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* Start BLE advertisement for 30 seconds and update link * status on LEDs */ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); Advertising_LED_Write(LED_ON); PWM_WriteCompare(LED_NO_ALERT); break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: UART_UartPutString("GAP Device Connected\r\n"); /* BLE link is established */ Advertising_LED_Write(LED_OFF); break; case CYBLE_EVT_TIMEOUT: if(*(uint8 *) eventParam == CYBLE_GAP_ADV_MODE_TO) { /* Advertisement event timed out, 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); Hibernate_LED_Write(LED_ON); PWM_Stop(); Wakeup_SW_ClearInterrupt(); Wakeup_Interrupt_ClearPending(); Wakeup_Interrupt_Start(); CySysPmHibernate(); } break; /********************************************************** * GAP Events ***********************************************************/ case CYBLE_EVT_GAP_AUTH_REQ: UART_UartPutString("Authorization Requested\r\n"); break; case CYBLE_EVT_GAP_AUTH_COMPLETE: UART_UartPutString("Pairing is Successful!\r\n"); break; case CYBLE_EVT_GAP_AUTH_FAILED: authFailReason = ((CYBLE_GAP_AUTH_FAILED_REASON_T *)eventParam); UART_UartPutString("Authentication Failed with Reason Code: "); snprintf(authFailReasonCode, sizeof(authFailReasonCode), "%lu", (uint32)(*authFailReason)); UART_UartPutString(authFailReasonCode); UART_UartPutChar("\r\n"); break; /********************************************************** * GATT Events ***********************************************************/ case CYBLE_EVT_GATT_CONNECT_IND: UART_UartPutString("GATT Connection Indication\r\n"); /* Set OOB data after the connection indication but before the authorization * request is received. */ if(CyBle_GapSetOobData(cyBle_connHandle.bdHandle, CYBLE_GAP_OOB_ENABLE, securityKey, NULL, NULL) != CYBLE_ERROR_OK) { UART_UartPutString("Error in Setting OOB Data\r\n"); } else { UART_UartPutString("OOB Data is Set\r\n"); } break; default: 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: 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: BondingImplementation() ******************************************************************************** * Summary: * Implements bonding of peer BLE device information. * * Parameters: * None * * Return: * None * * Theory: * The function stores the peer BLE device information to flash (called bonding) * when the device is ready. When the user wants to clear the bond information, * it is cleared in this function. * *******************************************************************************/ static void BondingImplementation(void) { uint8 command; CYBLE_GAP_BD_ADDR_T clearAllDevices = {{0,0,0,0,0,0},0}; switch(authState) { case AUTHENTICATION_COMPLETE_BONDING_REQD: /* Store bonding data of the current connection */ while(CYBLE_ERROR_OK != CyBle_StoreBondingData(1)); authState = AUTHENTICATION_BONDING_COMPLETE; UART_UartPutString("Bonding complete. "); break; case AUTHENTICATION_BONDING_COMPLETE: /* See if the user pressed 'R' button to clear the bond list. */ command = UART_UartGetChar(); if(command != 0u) { if((command == 'r') || (command == 'R')) { /* User wants the bond to be removed */ UART_UartPutString("\n\rClear the bond list. "); if(CyBle_GetState() == CYBLE_STATE_CONNECTED) { /* Disconnect */ authState = AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT; CyBle_GapDisconnect(cyBle_connHandle.bdHandle); } else if(CyBle_GetState() == CYBLE_STATE_ADVERTISING) { /* Stop advertisement */ authState = AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT; CyBle_GappStopAdvertisement(); } else { authState = AUTHENTICATION_BONDING_REMOVE_GO_AHEAD; } } } break; case AUTHENTICATION_BONDING_REMOVE_GO_AHEAD: /* Remove all bonded devices in the list */ CyBle_GapRemoveDeviceFromWhiteList(&clearAllDevices); while(CYBLE_ERROR_OK != CyBle_StoreBondingData(1)); UART_UartPutString("Cleared the list of bonded devices. \n\n\r"); authState = AUTHENTICATION_NOT_CONNECTED; /* Start advertisement again */ UART_UartPutString("Advertising. "); CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; default: break; } }
/******************************************************************************* * Function Name: StackEventHandler() ******************************************************************************** * Summary: * Event handler function for the BLE events processing. * * Parameters: * uint32 eventCode: The event to be processed * void * eventParam: Pointer to hold the additional information associated * with an event * * Return: * None * * Theory: * The function is responsible for handling the events generated by the stack. * In addition to handling general events for BLE advertisement, connection, * and disconnection, this function handles the events related to L2CAP CBFC * connection-oriented channel connection and disconnection. * * For details on L2CAP connection-oriented channels, refer to Bluetooth 4.1 * specification, Volume 3, Part A, section 3.4. * * Side Effects: * None * *******************************************************************************/ void StackEventHandler(uint32 eventCode, void * eventParam) { CYBLE_L2CAP_CBFC_CONN_CNF_PARAM_T cbfcResponse; uint8 counter; switch(eventCode) { /* Stack initialized; ready for advertisement */ case CYBLE_EVT_STACK_ON: UART_UartPutString("\n\rAdvertising with Address: "); for(counter = 6; counter > 0; counter--) { UART_UartPutChar(HexToAscii(cyBle_deviceAddress.bdAddr[counter - 1], 1)); UART_UartPutChar(HexToAscii(cyBle_deviceAddress.bdAddr[counter - 1], 0)); UART_UartPutChar(' '); } CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; /* Advertisement timed out; Restart advertisement */ case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); } break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: UART_UartPutString("\n\rConnected. "); break; /* Device disconnected */ case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* The L2CAP channel is disconnected but the PSM is already * registered. Update the state machine. */ channelState = CHANNEL_PSM_REGISTERED; previousDataTransmitted = true; /* Restart advertisement */ UART_UartPutString("\n\n\rDisconnected. "); UART_UartPutString("\n\rAdvertising again. "); UART_UartPutString("Address: "); for(counter = 6; counter > 0; counter--) { UART_UartPutChar(HexToAscii(cyBle_deviceAddress.bdAddr[counter - 1], 1)); UART_UartPutChar(HexToAscii(cyBle_deviceAddress.bdAddr[counter - 1], 0)); UART_UartPutChar(' '); } CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; /* CBFC connection response is received */ case CYBLE_EVT_L2CAP_CBFC_CONN_CNF: cbfcResponse = *(CYBLE_L2CAP_CBFC_CONN_CNF_PARAM_T *)eventParam; /* If the connection request was accepted */ if(cbfcResponse.response == CYBLE_L2CAP_CONNECTION_SUCCESSFUL) { UART_UartPutString("\n\rL2CAP channel connection request accepted. Sending data. "); /* Cache the connection parameters and channel ID */ cbfcPeerParameters = cbfcResponse.connParam; l2capCid = cbfcResponse.lCid; /* Update the state machine to indicate that the channel * is created. */ channelState = CHANNEL_CREATED; } break; /* Peer device requested for CBFC channel disconnection */ case CYBLE_EVT_L2CAP_CBFC_DISCONN_IND: if(*(uint16 *)eventParam == l2capCid) { /* L2CAP channel disconnected but the PSM is still registered */ channelState = CHANNEL_PSM_REGISTERED; previousDataTransmitted = true; } break; /* Invalid credits received from peer device; initiate disconnect */ case CYBLE_EVT_L2CAP_CBFC_TX_CREDIT_IND: if(((CYBLE_L2CAP_CBFC_LOW_TX_CREDIT_PARAM_T *)eventParam)->result != CYBLE_L2CAP_RESULT_SUCCESS) { CyBle_L2capDisconnectReq(l2capCid); channelState = CHANNEL_PSM_REGISTERED; } break; /* Previous data transmission completed */ case CYBLE_EVT_L2CAP_CBFC_DATA_WRITE_IND: previousDataTransmitted = true; break; default: break; } }
/******************************************************************************* * Function Name: main ******************************************************************************** * * Summary: * This is the main entry point for this application. This function initializes all the * components used in the project. It computes the frequency whenever a capture event is * * Parameters: * None * * Return: * None * *******************************************************************************/ int main() { #if(UART_DEBUG_ENABLE) /* Variable to store the loop number */ uint8 loopNo = 0; #endif /* Enable global interrupt mask */ CyGlobalIntEnable; /* Disable ILO as it is not used */ CySysClkIloStop(); /* Initialize components related to BLE communication */ InitializeBLESystem(); /* Initialize components related to frequency counting */ Initialize_Freq_Meas_System(); /* Start UART component if UART debug is enabled */ #if(UART_DEBUG_ENABLE) /* Start UART component and send welcome string to hyper terminal on PC */ UART_Start(); UART_UartPutString("Welcome to Frequency Measurement Using PSoC 4 BLE\n"); UART_PutCRLF(); #endif while(1) { /* Compute frequency once in every PWM interval(2s) */ if(Calculate_Frequency == TRUE) { /* Check if valid capture event is detected */ if((Input_Sig_Ctr_Capture == 1) && (Ref_Clk_Ctr_Capture == 1)) { /* Compute frequency using the latched count value, computed frequency will be stored in ASCII format in a global array */ Compute_Frequency(); #if(UART_DEBUG_ENABLE) /* Print input signal counter value in hexadecimal */ UART_UartPutString("Input Signal Counter Value: "); UART_SendDebugData(Input_Signal_Count); UART_UartPutString(" "); /* Print input signal counter value in ASCII format */ /* Reset the array before storing the ASCII character */ Reset_Array(InputCounter_ASCII, DATA_END); Convert_HextoDec(Input_Signal_Count, InputCounter_ASCII); for(loopNo = 0; loopNo < DATA_END; loopNo++) { UART_UartPutChar(InputCounter_ASCII[DATA_END - loopNo -1]); } UART_PutCRLF(); /* Print reference clock counter value */ UART_UartPutString("Reference Clock Counter Value: "); UART_SendDebugData(Ref_Clock_Count); UART_UartPutString(" "); /* Print input signal counter value in ASCII format */ /* Reset the array before storing the ASCII character */ Reset_Array(RefCounter_ASCII, DATA_END); Convert_HextoDec(Ref_Clock_Count, RefCounter_ASCII); for(loopNo = 0; loopNo < DATA_END; loopNo++) { UART_UartPutChar(RefCounter_ASCII[DATA_END - loopNo -1]); } UART_PutCRLF(); /* Print Input Signal Frequency in decimal format */ UART_UartPutString("Input Frequency: "); for(loopNo = 0; loopNo < DATA_END; loopNo++) { UART_UartPutChar(Input_Frequency[DATA_END - loopNo -1]); } UART_PutCRLF(); #endif /* Reset the capture flag after computing the frequency */ Input_Sig_Ctr_Capture = 0; Ref_Clk_Ctr_Capture = 0; } /* If valid capture event is not registered, set the value of frequency to zero */ else { /* Reset the input_frequency array before storing the frequency value */ Reset_Array(Input_Frequency, DATA_END); /* If no capture event is detected in the 1s interval, set the frequency to zero */ FormatFrequencyData(ZERO_HZ); #if(UART_DEBUG_ENABLE) /* Print Input Signal Frequency in decimal format */ UART_UartPutString("Input Frequency: "); for(loopNo = 0; loopNo < DATA_END; loopNo++) { UART_UartPutChar(Input_Frequency[DATA_END - loopNo -1]); } UART_PutCRLF(); #endif } /* Reset the 2s interval flag for computing the frequency in the next interval */ Calculate_Frequency = 0; /* Send frequency value only if BLE device is connected */ if(TRUE == deviceConnected) { /* Send frequency value when notifications are enabled */ if((startNotification & CCCD_NTF_BIT_MASK)) { /* Send the frequency value to BLE central device by notifications */ SendDataOverFreqCounterNotification(Input_Frequency); } } } /* Function to handle LED status depending on BLE state */ HandleStatusLED(); /* Handle CCCD value update only if BLE device is connected */ if(TRUE == deviceConnected) { /* When the Client Characteristic Configuration descriptor (CCCD) is written * by Central device for enabling/disabling notifications, then the same * descriptor value has to be explicitly updated in application so that * it reflects the correct value when the descriptor is read */ UpdateNotificationCCCD(); } if(restartAdvertisement) { /* Reset 'restartAdvertisement' flag*/ restartAdvertisement = FALSE; /* Start Advertisement and enter Discoverable mode*/ CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); } /*Process Event callback to handle BLE events. The events generated and * used for this application are inside the 'CustomEventHandler' routine*/ CyBle_ProcessEvents(); /* Put CPU to sleep */ CySysPmSleep(); } }
/******************************************************************************* * Function Name: SwitchRole ******************************************************************************** * Summary: * This function switches the role between Central and Peripheral. If device * is connected while switching role, then it is first disconnected. * * Parameters: * void * * Return: * void * *******************************************************************************/ void SwitchRole(void) { CYBLE_API_RESULT_T apiResult; /* if the switch role flag is set... */ if(switch_Role == TRUE) { /* Process pending BLE events */ CyBle_ProcessEvents(); /* If there is an existing connection, then disconnect before switching * role. */ if((cyBle_connHandle.bdHandle != 0)) { /* Disconnect the device and process the event */ CyBle_GapDisconnect(cyBle_connHandle.bdHandle); CyBle_ProcessEvents(); #ifdef DEBUG_ENABLED UART_UartPutString("Peripheral closed connection "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } switch(ble_gap_state) { case BLE_PERIPHERAL: /* If the current role is Peripheral and system is advertising, * then stop advertisement before switching role */ if(CyBle_GetState() == CYBLE_STATE_ADVERTISING) { CyBle_GappStopAdvertisement(); CyBle_ProcessEvents(); #ifdef DEBUG_ENABLED UART_UartPutString("Peripheral Advertisment Stopped "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { /* Switch BLE role by starting scan. This way, the system is set * to Central role */ apiResult = CyBle_GapcStartScan(CYBLE_SCANNING_FAST); if(CYBLE_ERROR_OK == apiResult) { #ifdef DEBUG_ENABLED UART_UartPutString("Start Scan API called "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif /* Record the time at which Central role was started. This will be * used for timeout and switching to Peripheral operation*/ centralStartedTime = WatchDog_CurrentCount(); /* Update the current BLE role to Central */ ble_gap_state = BLE_CENTRAL; /* Reset the switch role flag*/ switch_Role = FALSE; } else { /* If scanning did not start, maintain the current role and retry later */ ble_gap_state = BLE_PERIPHERAL; #ifdef DEBUG_ENABLED UART_UartPutString("Start Scan API failed "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } } /* Process Pending BLE Events */ CyBle_ProcessEvents(); break; case BLE_CENTRAL: /* If the current role is Central and system is scanning, * then stop scanning before switching role */ if(CyBle_GetState() == CYBLE_STATE_SCANNING) { CyBle_GapcStopScan(); CyBle_ProcessEvents(); #ifdef DEBUG_ENABLED UART_UartPutString("Central Scan stopped "); UART_UartPutCRLF(' '); #endif } if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { #ifdef ENABLE_ADV_DATA_COUNTER /* Increment data counter */ new_advData.advData[new_advData.advDataLen - 1] = dataADVCounter; cyBle_discoveryModeInfo.advData = &new_advData; #ifdef DEBUG_ENABLED UART_UartPutString("Updated ADV data = "); PrintNum(dataADVCounter); UART_UartPutCRLF(' '); #endif #endif /* Switch BLE role by starting advertisement. This way, the system is * set to Peripheral role */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult == CYBLE_ERROR_OK) { /* If advertisement started successfully, set the BLE state and * reset the switch role flag*/ ble_gap_state = BLE_PERIPHERAL; clientConnectToDevice = FALSE; switch_Role = FALSE; #ifdef DEBUG_ENABLED UART_UartPutString("Peripheral Advertisment called "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } else { /* If advertisement did not start, maintain the current role and retry later */ ble_gap_state = BLE_CENTRAL; #ifdef DEBUG_ENABLED UART_UartPutString("Start Peripheral Advertisment Failed "); SendBLEStatetoUART(CyBle_GetState()); UART_UartPutCRLF(' '); #endif } } /* Process Pending BLE Events */ CyBle_ProcessEvents(); break; default: break; } } }
void StackEventHandler(uint32 event,void *eventParam) { switch(event) { case CYBLE_EVT_STACK_ON: //Starting Advertisement as soon as Stack is ON apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if (apiResult == CYBLE_ERROR_OK) { printf ("Starting Advertisement\r\n"); } else { printf ("Error Start Adv %d\r\n",apiResult); } break; case CYBLE_EVT_TIMEOUT: if( CYBLE_GAP_ADV_MODE_TO ==*(uint16*) eventParam) { printf ("Advertisement TimedOut\r\n"); apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if (apiResult != CYBLE_ERROR_OK) { printf ("\nRestarting Advertisement\r\n"); } } case CYBLE_EVT_GATT_DISCONNECT_IND: /* Red LED Glows when device is disconnected */ RED_LED_ON (); break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: printf ("Disconnected \r\n"); // Starting Advertisent again when there is disconnection apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if (apiResult != CYBLE_ERROR_OK) { printf ("\nRestarting Advertisement\r\n"); } break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: printf ("\n\r Connection Established \r\n"); //Blue LED glows when device is connected BLUE_LED_ON (); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: // This Event is received when advertisement is started or stopped. if (CyBle_GetState() == CYBLE_STATE_ADVERTISING) { printf("Advertising...\r\n"); //Green LED Indicates that Advertisement is going on. GREEN_LED_ON(); } else { RED_LED_ON(); printf ("Advertisement Stopped \r\n"); if (AddRequest == 1) { AddRequest = 0; // Adding the Device to whitelist apiResult = CyBle_GapAddDeviceToWhiteList(&whitelistdeviceaddress); if(apiResult == CYBLE_ERROR_INVALID_PARAMETER) { printf ("Adding to Whitelist Failed. Invalid parameter \r\n"); } else if (apiResult ==CYBLE_ERROR_INVALID_OPERATION) { printf ("Invalid Operation \r\n"); } else if (apiResult ==CYBLE_ERROR_INSUFFICIENT_RESOURCES) { printf ("Adding to Whitelist Failed. List already full \r\n"); } else if (apiResult ==CYBLE_ERROR_DEVICE_ALREADY_EXISTS) { printf ("Device Already exists \r\n"); } else if (apiResult == CYBLE_ERROR_OK) { //Copying the address to the BackUp Array whitelistdeviceaddressBackup[Index] = whitelistdeviceaddress; Index++; printf ("Device Added to WhiteList\r\n"); printf ("Press A to Add or R to remove a from Whitelist \r\n"); } // Restarting the advertisement apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if (apiResult == CYBLE_ERROR_OK) { printf ("Restarting Advertisement \r\n"); GREEN_LED_ON (); } else { printf ("Error Start Adv %d \r\n",apiResult); } } if (DelRequest == 1) { DelRequest = 0; //Removing the Device from Whitelist apiResult = CyBle_GapRemoveDeviceFromWhiteList (&whitelistdeviceaddressBackup[RemoveIndex]); if (apiResult == CYBLE_ERROR_OK) { uint8 j; for (j = RemoveIndex; j<Index - 1; j++) { whitelistdeviceaddressBackup[j] = whitelistdeviceaddressBackup[j+1]; } Index--; printf ("Device %d Removed from Whitelist\r\n",RemoveIndex + 1); printf ("Press A to Add a Device or R to remove a device\r\n"); } else if (apiResult == CYBLE_ERROR_NO_DEVICE_ENTITY) { printf ("No Such Device Exists. Press A to Add a Device or R to remove\r\n"); } else { printf ("Error: Operation cannot be performed"); printf ("Press A to Add a Device or R to remove\r\n"); } //re-starting Advertisement apiResult = CyBle_GappStartAdvertisement (CYBLE_ADVERTISING_FAST); if (apiResult == CYBLE_ERROR_OK) { printf ("Restarting Advertisement\r\n"); } else { printf ("Restarting Advertisement Failed\r\n"); } } } default: break; } }
/******************************************************************************* * Function Name: BLE_StackEventHandler ******************************************************************************** * * Summary: * BLE stack generic event handler routine for handling connection, discovery, * security etc. events. * * Parameters: * event - event that triggered this callback * eventParam - parameters for the event. * * Return: * None *******************************************************************************/ void BLE_StackEventHandler(uint32 event, void* eventParam) { #if (RESTART_ADV_ON_DISCONNECTION) CYBLE_API_RESULT_T apiResult; #endif /* End of #if (RESTART_ADV_ON_DISCONNECTION) */ CYBLE_GATTC_ERR_RSP_PARAM_T *errorResponse; switch (event) { /********************************************************** * General Events ***********************************************************/ case CYBLE_EVT_STACK_ON: /* This event is received when component is Started */ /* Enter in to discoverable mode so that remote can search it. */ (void) CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); #if(CONSOLE_LOG_ENABLED) printf("Advertising... \r\n\n"); #endif /* End of #if(CONSOLE_LOG_ENABLED) */ break; case CYBLE_EVT_TIMEOUT: #if (BLE_GATT_CLIENT_ENABLE) if(*(uint8 *)eventParam == CYBLE_GATT_RSP_TO && bleStatus == BLE_DISCOVEER_GATT_SERVICES) { /* The peer device didn't respond to service discovery, enable RTC in free run mode if configured */ bleStatus = BLE_TIME_SERVER_ABSENT; #if (RTC_ENABLE) RTC_Start(); #endif /* End of #if (RTC_ENABLE) */ #if DISCONNECT_BLE_AFTER_TIME_SYNC BLE_RequestDisconnection(); #endif /* End of #if DISCONNECT_BLE_AFTER_TIME_SYNC */ } #endif /* End of #if (BLE_GATT_CLIENT_ENABLE) */ break; /********************************************************** * GAP Events ***********************************************************/ case CYBLE_EVT_GAP_AUTH_COMPLETE: /* we initiated the authentication with the iOS device and the authentication is now complete. Proceed * to characteristic value read after this */ bleStatus = BLE_READ_TIME; break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: #if RESTART_ADV_ON_DISCONNECTION BLE_Engine_Reinit(); /* Re-initialize application data structures */ /* Put the device to discoverable mode so that remote can search it. */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult != CYBLE_ERROR_OK) { CYASSERT(0); } #endif /* End of #if RESTART_ADV_ON_DISCONNECTION */ break; /********************************************************** * GATT Events ***********************************************************/ case CYBLE_EVT_GATT_CONNECT_IND: bleStatus = BLE_CONNECTED; break; case CYBLE_EVT_GATT_DISCONNECT_IND: bleStatus = BLE_DISCONNECTED; #if(CONSOLE_LOG_ENABLED) printf("Disconnected!\r\n\n"); #endif break; case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE: if(cyBle_ctsc.currTimeCharacteristics[CYBLE_CTS_CURRENT_TIME].valueHandle == 0x0000) { bleStatus = BLE_TIME_SERVER_ABSENT; #if (RTC_ENABLE)/* If the time server is absent, let the RTC run in free run mode */ RTC_Start(); #endif /* End of #if (RTC_ENABLE) */ #if DISCONNECT_BLE_AFTER_TIME_SYNC BLE_RequestDisconnection(); #endif /* End of #if DISCONNECT_BLE_AFTER_TIME_SYNC */ } else { bleStatus = BLE_READ_TIME; } break; case CYBLE_EVT_GATTC_ERROR_RSP: errorResponse = (CYBLE_GATTC_ERR_RSP_PARAM_T*) eventParam; /* characteristic read requires an authenticated link */ if(errorResponse -> errorCode == CYBLE_GATT_ERR_INSUFFICIENT_AUTHENTICATION) { bleStatus = BLE_INITIATE_AUTHENTICATION; } break; default: 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 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: 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: 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 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: main() ****************************************************************************** * Summary: * Central function which controls the application flow. * * Parameters: * None. * * Return: * None. * * Note: * *****************************************************************************/ int main() { // Init. InitializeSystem(); // Wait for BLE component to finish initialization. while (CyBle_GetState() == CYBLE_STATE_INITIALIZING) { CyBle_ProcessEvents(); } ////////////////////////////////////////////////////////////////////////// // Main Loop ////////////////////////////////////////////////////////////////////////// for(;;) { // Process all the events in the stack. CyBle_ProcessEvents(); #if LOWPOWERMODE_ENABLED // Put the BLESS in deepest sleep possible. CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); #endif ////////////////////////////////////////////////////////////////////// // Device connected ////////////////////////////////////////////////////////////////////// if (_BLE_deviceConnected) { // Update the CapSense CCCD. _BLE_UpdateCCCD(); // Update the Control values. _BLE_UpdateControl(); // If asked by client, send the status flags by notification or // indication. if (_BLE_sendStatus) _BLE_sendStatusFlags(); #if LOWPOWERMODE_ENABLED // Handle the Capsense low power mode. LowPowerMode_Capsense(); #endif // If asked by client, send the content of the vector containing // the CapSense data. if (_BLE_sendData) { SendData(); // Allow DeepSleep between connection intervals. LowPowerMode_System_DeepSleepAllowed = TRUE; } // If asked by client, acquire CapSense data and store it in // the vector. else if (_BLE_acquireData || TEST_USB) { AcquireData(); // Keep system in Active mode during scanning. LowPowerMode_System_DeepSleepAllowed = FALSE; } // If the 'acquireData' request is not present, but the vector // isn't empty, then no more data can be acquired. else if (!_BLE_acquireData && !vectorIsEmpty()) { ReadyToSendData(); // Allow DeepSleep between connection intervals. LowPowerMode_System_DeepSleepAllowed = TRUE; } // If the 'sendData' and 'acquireData' requests are not present, // but the vector is empty, then data has been all sent and // it's ready to acquire new data. else if (!_BLE_sendData && !_BLE_acquireData && vectorIsEmpty()) { ReadyToAcquireData(); // Allow DeepSleep between connection intervals. LowPowerMode_System_DeepSleepAllowed = TRUE; } } else // Allow DeepSleep between advertisement intervals. LowPowerMode_System_DeepSleepAllowed = TRUE; ////////////////////////////////////////////////////////////////////// // Advertisement ////////////////////////////////////////////////////////////////////// // Start advertisement if the flag is set in the BLE event handler. if (_BLE_restartAdvertisement) { // Reset the flag. _BLE_restartAdvertisement = FALSE; // Start advertisement. CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); } ////////////////////////////////////////////////////////////////////// // Reset ////////////////////////////////////////////////////////////////////// // If the client is disconnected, reset everything as the program // would be is first started. if (_BLE_resetNeeded) { // Reset the flag. _BLE_resetNeeded = FALSE; // Reset everything that needs to. ResetSystem(); } ////////////////////////////////////////////////////////////////////// // Low Power Mode (Sleep) ////////////////////////////////////////////////////////////////////// #if LOWPOWERMODE_ENABLED // Put the system in the deepest sleep possible. LowPowerMode_Sleep(); // Reset flag. LowPowerMode_System_DeepSleepAllowed = FALSE; #endif } }
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; } }
/******************************************************************************* * Function Name: StackEventHandler() ******************************************************************************** * Summary: * Event handler for the BLE events processing. * * Parameters: * uint32 eventCode: The event to be processed * void * eventParam: Pointer to hold the additional information associated * with an event * * Return: * None * * Theory: * The function is responsible for handling the events generated by the stack. * It first starts advertisement once the stack is initialized. * Upon advertisement timeout or disconnect events, this function sets a flag * to indicate to the main() function that it should enter Hibernate mode. * * Once the device is connected, this function initiates an authentication * request. It displays a 6-digit passkey on the UART output on a PC and asks * the user to enter this key on the iOS device (NP) side. * Once the authentication is complete, the function starts the discovery * procedure to know whether ANCS service is supported by the peer device. * * When the automated service discovery is complete, the function starts a manual * discovery procedure for the ANCS service (since the BLE component does not * handle discovery of custom services yet - that will be added as part of * Creator 3.2). * * When the automated service discovery is complete and the ANCS service is not * found, the function subscribes to the Service Changed characteristic * indication to know if and when the iOS device adds ANCS support later. * * Once the ANCS service is found and a new GATT Notification comes for any of * the ANCS characteristic, it calls the corresponding function in ANCS.c. * *******************************************************************************/ void StackEventHandler(uint32 eventCode, void * eventParam) { CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T * handleValueNotification; switch(eventCode) { case CYBLE_EVT_STACK_ON: /* Minor change in ADV packet for service solicitation */ cyBle_discoveryData.advData[10] = 0x15; /* Start advertisement after stack is initialized */ UART_UartPutString("\n\rAdvertising."); CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: if(authState != AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT) { if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { UART_UartPutString("\n\rAdvertisement timed out. "); UART_UartPutString("Going to Hibernate mode."); /* Enter hibernate mode upon advertisement timeout */ enterHibernateFlag = true; } } else { UART_UartPutString("\n\rAdvertisement stopped. "); authState = AUTHENTICATION_BONDING_REMOVE_GO_AHEAD; } break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* Enter Hibernate mode upon disconnect * Previous state is erased. */ if(authState != AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT) { UART_UartPutString("\n\rDisconnected. Going to Hibernate mode."); enterHibernateFlag = true; } else { UART_UartPutString("\n\rDisconnected. "); authState = AUTHENTICATION_BONDING_REMOVE_GO_AHEAD; } Ancs_Reset(); break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: UART_UartPutString("\n\rConnected to a peer device."); /* Send authentication request upon connection */ CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo); break; case CYBLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST: UART_UartPutString("\n\rEnter this passkey in your iPhone: "); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 5)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 4)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 3)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 2)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 1)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 0)); break; case CYBLE_EVT_GAP_AUTH_COMPLETE: /* Authentication complete; initiate service discovery procedure */ UART_UartPutString("\n\rAuthentication complete. "); authState = AUTHENTICATION_COMPLETE_BONDING_REQD; CyBle_GattcStartDiscovery(cyBle_connHandle); break; case CYBLE_EVT_GAP_AUTH_FAILED: /* Authentication failed; enter Hibernate mode */ UART_UartPutString("\n\rAuthentication failed. Going to Hibernate mode."); enterHibernateFlag = true; /* Update authentication state so that bond information could be * removed later. */ authState = AUTHENTICATION_BONDING_COMPLETE; break; case CYBLE_EVT_GATTC_INDICATION: /* Server's services changed; restart service discovery */ UART_UartPutString("\n\rService changed indication. Redo service discovery."); Ancs_Reset(); CyBle_GattcStartDiscovery(cyBle_connHandle); break; case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE: /* Automatic discovery does not cover discovery of service snd * characteristics with custom 128-bit UUIDs. This has to be done * manually. The Read by Group response for Service discovery covers * the ANCS custom service. For the ANCS service characteristics, the * Read by Type Request has to be sent by the application. */ if(ANCS_DISC_SERVICE_DISCOVERED == ancsDiscoveryStatus) { CyBle_GattcDiscoverAllCharacteristics(cyBle_connHandle, ancsServiceRange); } else if(ANCS_DISC_NONE_DISCOVERED == ancsDiscoveryStatus) { UART_UartPutString("\n\rANCS service not found. "); /* Service discovery procedure complete; subscribe to the GATT * Service changed indication by writing 0x02 to its CCCD. */ if((serviceChangedCccdWriteStatus == SERVICE_CHANGED_CCCD_WRITE_REQ_NOT_SENT) && (cyBle_gattc.serviceChanged.valueHandle != CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE)) { serviceChangedCccdPacket.value = cccdIndFlagSetStruct; serviceChangedCccdPacket.attrHandle = cyBle_gattc.cccdHandle; CyBle_GattcWriteCharacteristicDescriptors(cyBle_connHandle, &serviceChangedCccdPacket); } /* Internal state machine tracking the CCCD status */ serviceChangedCccdWriteStatus = SERVICE_CHANGED_CCCD_WRITE_REQ_SENT; } else { /* Other conditions need not be handled; they are handled * in the event handler in ANCS.c. */ } break; case CYBLE_EVT_GATTC_READ_BY_GROUP_TYPE_RSP: case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP: case CYBLE_EVT_GATTC_FIND_INFO_RSP: case CYBLE_EVT_GATTC_WRITE_RSP: case CYBLE_EVT_GATTC_ERROR_RSP: /* See if the events are for ANCS */ Ancs_EventHandler(eventCode, eventParam); break; case CYBLE_EVT_GATTC_HANDLE_VALUE_NTF: /* See if the notification packet is for any ANCS characteristic */ handleValueNotification = (CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T *)eventParam; if(handleValueNotification->handleValPair.attrHandle == ancsNotifSourceCharHandle) { /* Notification source characteristic has a new notification */ Ancs_HandleNotifications(handleValueNotification->handleValPair.value.val); } else if(handleValueNotification->handleValPair.attrHandle == ancsDataSourceCharHandle) { /* Data source characteristic has a new notification */ Ancs_HandleData(handleValueNotification->handleValPair.value.val); } else { /* Some other characteristic notification; ignore */ } break; default: break; } }