int main() { CyGlobalIntEnable; CyBle_Start(BleEventHandler); while(connHandle.bdHandle == 0) /* Wait for connection to GATT server */ CyBle_ProcessEvents(); CyBle_GattcStartDiscovery(connHandle); /* Attempt discovery of configured services */ while(ledStateHandle == 0) /* Wait for discovery */ CyBle_ProcessEvents(); writeData = 0x01; /* Turn on LED on Minimal_Peripheral dongle */ writeValue.val = &writeData; writeValue.len = sizeof(writeData); writeValue.actualLen = sizeof(writeData); writeReqParam.value = writeValue; writeReqParam.attrHandle = ledStateHandle; /* Use discovered handle */ CyBle_GattcWriteWithoutResponse(connHandle, &writeReqParam); /* Write to server */ CyBle_ProcessEvents(); return 0; }
/******************************************************************************* * 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; } }
/******************************************************************************* * Function Name: main ******************************************************************************** * * Summary: * Main function. * * Parameters: * None * * Return: * None * *******************************************************************************/ int main() { /* Local variables */ char8 command; int8 intTxPowerLevel; CYBLE_API_RESULT_T apiResult; CYBLE_BLESS_PWR_IN_DB_T txPower; CyGlobalIntEnable; isr_DIS_StartEx(DIS_Interrupt); UART_Start(); CyBle_Start(StackEventHandler); /*Start BLE*/ /* Register the event handler for DIS specific events */ CyBle_DisRegisterAttrCallback(DisEventHandler); /* Register the event handler for TPS specific events */ CyBle_TpsRegisterAttrCallback(TpsServiceAppEventHandler); for(;;) { CyBle_ProcessEvents(); HandleLeds(); /*If SW2 is pressed then start to discover the services of server*/ if(discoverServer==TRUE) { CyBle_GattcStartDiscovery(cyBle_connHandle); discoverServer=FALSE; } command = UART_UartGetChar(); if( command != 0u) {/*Client related functions*/ switch(command) { if(disSupport) { case '1': /*To read the Manufacturer Name */ printf("Manufacturer Name:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_MANUFACTURER_NAME); break; case '2': /*To read the Model number*/ printf("Model Number:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_MODEL_NUMBER); break; case '3': /*To read the serial number*/ printf("Serial Number:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_SERIAL_NUMBER); break; case '4': /*To read hardware Revision*/ printf("Hardware Rev:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_HARDWARE_REV); break; case '5': /*To read Firmware Revision*/ printf("Firmware Rev:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_FIRMWARE_REV); break; case '6': /*To read Software Revision*/ printf("Software Rev:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_SOFTWARE_REV); break; case '7': /*To read System ID*/ printf("System ID:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_SYSTEM_ID); break; case '8': /*To read IEEE 11073 -20601 certifications details*/ printf("IEEE 11073-20601:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_REG_CERT_DATA); break; case '9': /*To read PNP ID*/ printf("PNP ID:"); CyBle_DiscGetCharacteristicValue(cyBle_connHandle,CYBLE_DIS_PNP_ID); break; } else { printf("Client hasn't discovered the services of server or server doesn't support DIS service\r\n"); } /*Server related fucntions*/ /* Decrease Tx power level of BLE radio if button is pressed */ case'd': /* Specify connection channel for reading Tx power level */ txPower.bleSsChId = CYBLE_LL_CONN_CH_TYPE; /* Get current Tx power level */ CyBle_GetTxPowerLevel(&txPower); /* Decrease the Tx power level by one scale */ DecreaseTxPowerLevelValue(&txPower.blePwrLevelInDbm); /* Set the new Tx power level */ apiResult = CyBle_SetTxPowerLevel(&txPower); if(CYBLE_ERROR_OK == apiResult) { /* Convert power level to numeric int8 value */ intTxPowerLevel = ConvertTxPowerlevelToInt8(txPower.blePwrLevelInDbm); (void) CyBle_TpssSetCharacteristicValue(CYBLE_TPS_TX_POWER_LEVEL, CYBLE_TPS_TX_POWER_LEVEL_SIZE, &intTxPowerLevel); /* Display new Tx Power Level value */ printf("Tx power level is set to %d dBm\r\n", intTxPowerLevel); } break; case 'n': /*Send notification to the client about the TX power level*/ CyBle_TpssSendNotification(cyBle_connHandle,CYBLE_TPS_TX_POWER_LEVEL,CYBLE_TPS_TX_POWER_LEVEL_SIZE,&intTxPowerLevel); break; } } } }
/******************************************************************************* * Function Name: ApplicationEventHandler ******************************************************************************** * Summary: * Call back event function to handle various events from BLE stack * * Parameters: * event: event returned * eventParam: link to value of the event parameter returned * * Return: * void * *******************************************************************************/ void ApplicationEventHandler(uint32 event, void *eventparam) { /* 'apiResult' is a variable of type 'CYBLE_API_RESULT_T' (defined in * BLE_StackTypes.h) and is used to store the return value from BLE APIs. */ CYBLE_API_RESULT_T apiResult; /* 'scan_report' is a variable of type 'CYBLE_GAPC_ADV_REPORT_T' (defined in * BLE_StackGap.h) and is used to store report retuned from Scan results. */ CYBLE_GAPC_ADV_REPORT_T scan_report; /* Local variable for Loop */ uint16 i = FALSE; switch(event) { case CYBLE_EVT_STACK_ON: /* Set start scanning flag to allow calling the API in main loop */ restartScanning = TRUE; break; case CYBLE_EVT_GAPC_SCAN_START_STOP: /* Add relevant code here pertaining to Starting/Stopping of Scan*/ if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { ble_state = BLE_DISCONNECTED; if(!peripheralFound) { /* Restart Scanning */ //Status_LED_Write(1); restartScanning = TRUE; } } else { ble_state = BLE_SCANNING; } break; case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT: /* This event is generated whenever there is a device found*/ 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; /* Add the new device to existing list if not done yet, and compare the address with our required address.*/ HandleScanDevices(&scan_report); } /* Update the LED status for BLE scanning mode*/ ble_state = BLE_SCANNING; break; case CYBLE_EVT_GATT_CONNECT_IND: /* When the peripheral device is connected, store the connection handle.*/ connHandle = *(CYBLE_CONN_HANDLE_T *)eventparam; break; case CYBLE_EVT_GATT_DISCONNECT_IND: /* When the peripheral device is disconnected, reset variables*/ break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: /* The Device is connected now. Start Attributes discovery process.*/ apiResult = CyBle_GattcStartDiscovery(connHandle); //HERE HERE HERE HERE if(apiResult != CYBLE_ERROR_OK) { } /* Update the LED status for BLE discovery mode*/ ble_state = BLE_SERVICE_DISCOVERY; break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* Reset all saved peripheral Addresses */ for(i=0;i<addedDevices;i++) { list_of_devices[i].peerBdAddr[0] = FALSE; list_of_devices[i].peerBdAddr[1] = FALSE; list_of_devices[i].peerBdAddr[2] = FALSE; list_of_devices[i].peerBdAddr[3] = FALSE; list_of_devices[i].peerBdAddr[4] = FALSE; list_of_devices[i].peerBdAddr[5] = FALSE; } /* Reset application Flags on BLE Disconnect */ addedDevices = FALSE; peripheralFound = FALSE; deviceConnected = FALSE; iasLevel = FALSE; ble_state = BLE_DISCONNECTED; /* Set the flag for rescanning after wakeup */ restartScanning = TRUE; /* Update LED Status for Disconnection */ //HandleLEDs(ble_state); if(apiResult != CYBLE_ERROR_OK) { } break; case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE: /* This event is generated whenever the discovery procedure is complete*/ /*Set the Device connected flag*/ deviceConnected = TRUE; /* Update the LED status for BLE discovery mode*/ ble_state = BLE_CONNECTED; break; case CYBLE_EVT_GATTC_READ_RSP: /* This event is generated when the server sends a response to a read request*/ readResponse[current_sensor][current_characteristic] = *(CYBLE_GATTC_READ_RSP_PARAM_T *) eventparam; int ii=0; for(ii = 0; ii < readResponse[current_sensor][current_characteristic].value.len; ii++){ sensor_data[current_sensor][current_characteristic].bytes[ii] = *(readResponse[current_sensor][current_characteristic].value.val+ii); } 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; } }