/* Include Files */ #include "KTag.h" /* Local Definitions and Constants */ #define BLE_TASK_PERIOD_IN_ms 10 #ifdef TRACE_BLE #define TRACE_BLE_STATE_ENTRY(state_name) do {if (State_Changed == true) { COMM_Console_Print_String("[BLE] Entering the ");COMM_Console_Print_String(state_name);COMM_Console_Print_String(" state.\n");}} while (false) #else // TRACE_BLE #define TRACE_BLE_STATE_ENTRY(state_name) #endif // TRACE_BLE /* Public Variables */ /* Variable used to maintain connection information */ cy_stc_ble_conn_handle_t appConnHandle[CY_BLE_CONN_COUNT]; QueueHandle_t COMM_BLE_CommandQueue; TaskHandle_t COMM_BLE_Task_Handle; /* Private Variables */ static const TickType_t BLE_Task_Delay = BLE_TASK_PERIOD_IN_ms / portTICK_PERIOD_MS; static COMM_BLE_StateID_T Current_State = COMM_BLE_DEFAULT; static COMM_BLE_StateID_T Next_State = COMM_BLE_INITIALIZING; static bool State_Changed = false; static TickType_t Time_At_State_Entry_In_Ticks; //! Immediate Alert Service alert level value. volatile uint8_t COMM_BLE_IASAlertLevel = 0; static cy_stc_ble_gapp_disc_data_t Advertising_Data; static cy_stc_ble_gapp_scan_rsp_data_t Scan_Response_Data; static cy_stc_ble_gapp_disc_mode_info_t Advertising_Info = {.advData = &Advertising_Data, .scanRspData = &Scan_Response_Data}; /* Private Function Prototypes */ static void BLE_EventHandler(uint32_t event, void * eventParam); static void IASEventHandler(uint32 event, void * eventParam); static cy_en_ble_api_result_t StartNextAdvertisement(); /* Inline Functions */ static inline uint32_t COMM_BLE_GetTimeInState_in_ms() { uint32_t result = (xTaskGetTickCount() - Time_At_State_Entry_In_Ticks) * portTICK_PERIOD_MS; return result; } /* Public Functions */ //! Initializes the Bluetooth Low Energy communications. void COMM_BLE_Init(void) { COMM_BLE_CommandQueue = xQueueCreate(10, sizeof(COMM_BLE_Command_T)); BLE_InitPacketBuffers(); COMM_BLE_UART_Init(); if (Cy_BLE_Start(BLE_EventHandler) == CY_BLE_SUCCESS) { Cy_BLE_IAS_RegisterAttrCallback(IASEventHandler); } #ifdef TRACE_BLE else { COMM_Console_Print_String("[BLE] Cy_BLE_Start API Error!\n"); } #endif // TRACE_BLE } //! Bluetooth Low Energy communications task: Manages BLE communications, using the PSoC API functions. /*! * */ void COMM_BLE_Task(void * pvParameters) { COMM_BLE_Command_T command; while(true) { Cy_BLE_ProcessEvents(); if (xQueueReceive(COMM_BLE_CommandQueue, &command, BLE_Task_Delay) == pdPASS) { if (Next_State != Current_State) { Current_State = Next_State; Time_At_State_Entry_In_Ticks = xTaskGetTickCount(); State_Changed = true; } else { State_Changed = false; } switch (Current_State) { default: case COMM_BLE_DEFAULT: { TRACE_BLE_STATE_ENTRY("COMM_BLE_DEFAULT"); COMM_BLE_RequestState(COMM_BLE_INITIALIZING); } break; case COMM_BLE_INITIALIZING: { TRACE_BLE_STATE_ENTRY("COMM_BLE_INITIALIZING"); // Wait for the CY_BLE_EVT_STACK_ON event in BLE_EventHandler() to transition to COMM_BLE_IDLE. } break; case COMM_BLE_IDLE: { TRACE_BLE_STATE_ENTRY("COMM_BLE_IDLE"); switch (command.ID) { case COMM_BLE_SCAN_FOR_KTAG_PACKETS: COMM_BLE_RequestState(COMM_BLE_SCANNING_FOR_KTAG_PACKETS); break; case COMM_BLE_SCAN_AND_ADVERTISE: COMM_BLE_RequestState(COMM_BLE_SCANNING_AND_ADVERTISING); break; default: // All other commands are ignored in this state. break; } } break; case COMM_BLE_SCANNING_FOR_KTAG_PACKETS: { TRACE_BLE_STATE_ENTRY("COMM_BLE_SCANNING_FOR_KTAG_PACKETS"); if (State_Changed == true) { // Handle state entry events. cy_en_ble_api_result_t apiResult = Cy_BLE_GAPC_StartScan(CY_BLE_SCANNING_FAST, CY_BLE_OBSERVER_CONFIGURATION_0_INDEX); if(apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPC_StartScan API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } } switch (command.ID) { case COMM_BLE_ADVERTISE_AS_BROADCASTER: COMM_BLE_RequestState(COMM_BLE_ADVERTISING_AS_BROADCASTER); break; case COMM_BLE_SCAN_AND_ADVERTISE: COMM_BLE_RequestState(COMM_BLE_SCANNING_AND_ADVERTISING); break; default: // All other commands are ignored in this state. break; } } break; case COMM_BLE_ADVERTISING_AS_BROADCASTER: { TRACE_BLE_STATE_ENTRY("COMM_BLE_ADVERTISING_AS_BROADCASTER"); if (State_Changed == true) { // Handle state entry events. cy_en_ble_api_result_t apiResult = Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_FAST, CY_BLE_BROADCASTER_CONFIGURATION_0_INDEX); if (apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StartAdvertisement API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } } switch (command.ID) { case COMM_BLE_STOP_ADVERTISING: { cy_en_ble_api_result_t apiResult = Cy_BLE_GAPP_StopAdvertisement(); if (apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StopAdvertisement API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } COMM_BLE_RequestState(COMM_BLE_SCANNING_FOR_KTAG_PACKETS); } break; case COMM_BLE_SCAN_AND_ADVERTISE: COMM_BLE_RequestState(COMM_BLE_SCANNING_AND_ADVERTISING); break; default: // All other commands are ignored in this state. break; } } break; case COMM_BLE_ADVERTISING_AS_PERIPHERAL: { TRACE_BLE_STATE_ENTRY("COMM_BLE_ADVERTISING_AS_PERIPHERAL"); if (State_Changed == true) { // Handle state entry events. cy_en_ble_api_result_t apiResult = Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_FAST, CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX); if (apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StartAdvertisement API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } } } break; case COMM_BLE_SCANNING_AND_ADVERTISING: { TRACE_BLE_STATE_ENTRY("COMM_BLE_SCANNING_AND_ADVERTISING"); if (State_Changed == true) { // Handle state entry events. cy_en_ble_api_result_t apiResult = Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_FAST, CY_BLE_BROADCASTER_CONFIGURATION_0_INDEX); if (apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StartAdvertisement API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } apiResult = Cy_BLE_GAPC_StartScan(CY_BLE_SCANNING_FAST, CY_BLE_OBSERVER_CONFIGURATION_0_INDEX); if(apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPC_StartScan API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } } } break; } COMM_BLE_UART_MaybeSendData(); #ifdef CY_DFU_SDK_VERSION_MAJOR if (COMM_BLE_IASAlertLevel != 0u) { // Disconnect from all the connected devices. for (uint_fast8_t i = 0; i < CY_BLE_CONN_COUNT; i++) { if (Cy_BLE_GetConnectionState(appConnHandle[i]) == CY_BLE_CONN_STATE_CONNECTED) { cy_stc_ble_gap_disconnect_info_t disconnectInfoParam = { .bdHandle = appConnHandle[i].bdHandle, .reason = CY_BLE_HCI_ERROR_OTHER_END_TERMINATED_USER }; /* Initiate disconnection from the peer device*/ if (Cy_BLE_GAP_Disconnect(&disconnectInfoParam) == CY_BLE_SUCCESS) { /* Wait for disconnection event */ while (Cy_BLE_GetConnectionState(appConnHandle[i]) == CY_BLE_CONN_STATE_CONNECTED) { /* Process BLE events */ Cy_BLE_ProcessEvents(); } } } } /* Stop BLE component. */ Cy_BLE_Disable(); Cy_DFU_ExecuteApp(0u); } #endif // CY_DFU_SDK_VERSION_MAJOR } } } SystemKResult_T BLE_GetMyAddress(uint8_t * BD_ADDR) { BD_ADDR[0] = cy_ble_deviceAddress.bdAddr[0]; BD_ADDR[1] = cy_ble_deviceAddress.bdAddr[1]; BD_ADDR[2] = cy_ble_deviceAddress.bdAddr[2]; BD_ADDR[3] = cy_ble_deviceAddress.bdAddr[3]; BD_ADDR[4] = cy_ble_deviceAddress.bdAddr[4]; BD_ADDR[5] = cy_ble_deviceAddress.bdAddr[5]; return SYSTEMK_RESULT_SUCCESS; } SystemKResult_T BLE_ScanAndAdvertise(void) { COMM_BLE_Command_T command = { .ID = COMM_BLE_SCAN_AND_ADVERTISE, .Data = (void *)0x00 }; xQueueSend(COMM_BLE_CommandQueue, &command, 0); return SYSTEMK_RESULT_SUCCESS; } void COMM_BLE_RequestState(COMM_BLE_StateID_T state) { Next_State = state; COMM_BLE_Command_T command = {.ID = COMM_BLE_REQUEST_STATE_CHANGE, .Data = (void *)0x00}; xQueueSend(COMM_BLE_CommandQueue, &command, 0); } SystemKResult_T BLE_SetAdvertisingData(BLE_AdvertisingData_T * data) { SystemKResult_T result = SYSTEMK_RESULT_SUCCESS; if (data->length > BLE_MAX_ADVERTISING_BYTES) { result = SYSTEMK_RESULT_TOO_MANY_DATA; } else if (data->length < BLE_KTAG_PACKET_TOTAL_SIZE) { result = SYSTEMK_RESULT_TOO_FEW_DATA; } else { Advertising_Data.advDataLen = BLE_KTAG_PACKET_TOTAL_SIZE; memcpy(Advertising_Data.advData, data, BLE_KTAG_PACKET_TOTAL_SIZE); cy_en_ble_api_result_t result = Cy_BLE_GAPP_UpdateAdvScanData(&Advertising_Info); if (result != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_UpdateAdvScanData Error: 0x"); COMM_Console_Print_UInt32AsHex(result); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } } return result; } /* Private Functions */ static void BLE_EventHandler(uint32_t event, void * eventParam) { cy_en_ble_api_result_t apiResult; static cy_stc_ble_gap_sec_key_info_t keyInfo = { .localKeysFlag = CY_BLE_GAP_SMP_INIT_ENC_KEY_DIST | CY_BLE_GAP_SMP_INIT_IRK_KEY_DIST | CY_BLE_GAP_SMP_INIT_CSRK_KEY_DIST, .exchangeKeysFlag = CY_BLE_GAP_SMP_INIT_ENC_KEY_DIST | CY_BLE_GAP_SMP_INIT_IRK_KEY_DIST | CY_BLE_GAP_SMP_INIT_CSRK_KEY_DIST | CY_BLE_GAP_SMP_RESP_ENC_KEY_DIST | CY_BLE_GAP_SMP_RESP_IRK_KEY_DIST | CY_BLE_GAP_SMP_RESP_CSRK_KEY_DIST, }; if (COMM_BLE_UART_HandleEvent(event, eventParam) == false) { // For more information, refer to the comments in cy_ble_stack.h, where all // these events are described in more detail. switch (event) { case CY_BLE_EVT_INVALID: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_INVALID\n"); #endif // TRACE_BLE break; // G E N E R I C E V E N T S (0x1000 to 0x1FFF) case CY_BLE_EVT_STACK_ON: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_STACK_ON\n"); #endif // TRACE_BLE COMM_BLE_RequestState(COMM_BLE_IDLE); break; case CY_BLE_EVT_TIMEOUT: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_TIMEOUT: 0x"); COMM_Console_Print_UInt8AsHex(*(uint8_t *)eventParam); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_STACK_BUSY_STATUS: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_STACK_BUSY_STATUS: 0x"); COMM_Console_Print_UInt8AsHex(*(uint8_t *)eventParam); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_MEMORY_REQUEST: case CY_BLE_EVT_PENDING_FLASH_WRITE: case CY_BLE_EVT_FLASH_CORRUPT: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); break; #endif // TRACE_BLE break; // H O S T C O N T R O L I N T E R F A C E E V E N T S (0x2000 to 0x2FFF) case CY_BLE_EVT_HARDWARE_ERROR: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_HARDWARE_ERROR: 0x"); COMM_Console_Print_UInt8AsHex(*(uint8_t *)eventParam); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_WRITE_AUTH_PAYLOAD_TO_COMPLETE: case CY_BLE_EVT_READ_AUTH_PAYLOAD_TO_COMPLETE: case CY_BLE_EVT_GET_CHANNEL_MAP_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_LE_SET_EVENT_MASK_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_SET_DEVICE_ADDR_COMPLETE\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_LE_PING_AUTH_TIMEOUT: case CY_BLE_EVT_SET_DATA_LENGTH_COMPLETE: case CY_BLE_EVT_SET_SUGGESTED_DATA_LENGTH_COMPLETE: case CY_BLE_EVT_GET_DATA_LENGTH_COMPLETE: case CY_BLE_EVT_DATA_LENGTH_CHANGE: case CY_BLE_EVT_GET_PEER_RPA_COMPLETE: case CY_BLE_EVT_GET_LOCAL_RPA_COMPLETE: case CY_BLE_EVT_SET_RPA_TO_COMPLETE: case CY_BLE_EVT_SET_RPA_ENABLE_COMPLETE: case CY_BLE_EVT_SET_HOST_CHANNEL_COMPLETE: case CY_BLE_EVT_ADD_DEVICE_TO_RPA_LIST_COMPLETE: case CY_BLE_EVT_REMOVE_DEVICE_FROM_RPA_LIST_COMPLETE: case CY_BLE_EVT_ADD_DEVICE_TO_WHITE_LIST_COMPLETE: case CY_BLE_EVT_REMOVE_DEVICE_FROM_WHITE_LIST_COMPLETE: case CY_BLE_EVT_GET_PHY_COMPLETE: case CY_BLE_EVT_SET_DEFAULT_PHY_COMPLETE: case CY_BLE_EVT_SET_PHY_COMPLETE: case CY_BLE_EVT_PHY_UPDATE_COMPLETE: case CY_BLE_EVT_SET_PRIVACY_MODE_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; // V E N D O R E V E N T S (0x3000 to 0x3FFF) case CY_BLE_EVT_LL_CNTRL_PROC_PENDING_COMPLETE: case CY_BLE_EVT_SOFT_RESET_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_SET_DEVICE_ADDR_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_SET_DEVICE_ADDR_COMPLETE\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GET_DEVICE_ADDR_COMPLETE: case CY_BLE_EVT_GET_RSSI_COMPLETE: case CY_BLE_EVT_GET_TX_PWR_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_SET_TX_PWR_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_SET_TX_PWR_COMPLETE\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GET_CLK_CONFIG_COMPLETE: case CY_BLE_EVT_SET_CLK_CONFIG_COMPLETE: case CY_BLE_EVT_RANDOM_NUM_GEN_COMPLETE: case CY_BLE_EVT_AES_ENCRYPT_COMPLETE: case CY_BLE_EVT_AES_CCM_ENCRYPT_COMPLETE: case CY_BLE_EVT_AES_CCM_DECRYPT_COMPLETE: case CY_BLE_EVT_SET_SLAVE_LATENCY_MODE_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE\n"); #endif // TRACE_BLE // If desired, wait until console transmit is complete, then call Cy_SysPm_Hibernate(); break; case CY_BLE_EVT_RADIO_TEMPERATURE: case CY_BLE_EVT_RADIO_VOLTAGE_LEVEL: case CY_BLE_EVT_AES_CMAC_GEN_COMPLETE: case CY_BLE_EVT_SET_EVENT_MASK_COMPLETE: case CY_BLE_EVT_SET_CE_LENGTH_COMPLETE: case CY_BLE_EVT_SET_CONN_PRIORITY_COMPLETE: case CY_BLE_EVT_HCI_PKT_RCVD: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; // G E N E R I C A C C E S S P R O F I L E E V E N T S (0x4000 to 0x4FFF) case CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT: { #if (defined TRACE_BLE) && (defined VERBOSE_BLE_TRACE) COMM_Console_Print_String("[BLE] ..SCAN_PROGRESS_RESULT "); #endif // (defined TRACE_BLE) && (defined VERBOSE_BLE_TRACE) BLE_Packet_T * packet = BLE_DecodeKTagPacket((*(cy_stc_ble_gapc_adv_report_param_t *)eventParam).data, (*(cy_stc_ble_gapc_adv_report_param_t *)eventParam).dataLen, (*(cy_stc_ble_gapc_adv_report_param_t *)eventParam).peerBdAddr, (*(cy_stc_ble_gapc_adv_report_param_t *)eventParam).rssi); if (packet != NULL) { #ifdef TRACE_BLE switch (packet->Generic.type) { case BLE_PACKET_TYPE_INSTIGATE_GAME: COMM_Console_Print_String(" KTag 'Instigate Game' packet found!"); break; case BLE_PACKET_TYPE_JOIN_NOW: COMM_Console_Print_String(" KTag 'Join Now' packet found!"); break; case BLE_PACKET_TYPE_TAG: COMM_Console_Print_String(" KTag 'Tag' packet found!"); break; case BLE_PACKET_TYPE_CONSOLE: COMM_Console_Print_String(" KTag 'Console' packet found!"); break; case BLE_PACKET_TYPE_STATUS: COMM_Console_Print_String(" KTag 'Status' packet found!"); break; default: COMM_Console_Print_String(" Unknown KTag packet found!"); break; } COMM_Console_Print_String(" RSSI: "); COMM_Console_Print_Int8(packet->Generic.RSSI); COMM_Console_Print_String("\n"); #endif // TRACE_BLE if (packet->Generic.type == BLE_PACKET_TYPE_CONSOLE) { packet->Console.console_data[BLE_KTAG_PACKET_DATA_SIZE - 1] = COMM_CONSOLE_STRING_TERMINATOR; COMM_Console_Execute_Internal_Command(packet->Console.console_data); } else { KEvent_T packet_received_event = {.ID = KEVENT_BLE_PACKET_RECEIVED, .Data = packet}; Post_KEvent(&packet_received_event); } } #if (defined TRACE_BLE) && (defined VERBOSE_BLE_TRACE) else { COMM_Console_Print_String(" Not a KTag packet!\n"); } #endif // (defined TRACE_BLE) && (defined VERBOSE_BLE_TRACE) } break; case CY_BLE_EVT_GAP_AUTH_REQ: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_AUTH_REQ: bdHandle=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).bdHandle); COMM_Console_Print_String(" security=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).security); COMM_Console_Print_String(" bonding=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).bonding); COMM_Console_Print_String(" ekeySize=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).ekeySize); COMM_Console_Print_String(" authErr=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).authErr); COMM_Console_Print_String("\n"); #endif // TRACE_BLE if(cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX].security == (CY_BLE_GAP_SEC_MODE_1 | CY_BLE_GAP_SEC_LEVEL_1)) { cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX].authErr = CY_BLE_GAP_AUTH_ERROR_PAIRING_NOT_SUPPORTED; } cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX].bdHandle = ((cy_stc_ble_gap_auth_info_t *)eventParam)->bdHandle; /* Pass security information for authentication in reply to an authentication request * from the master device */ apiResult = Cy_BLE_GAPP_AuthReqReply(&cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX]); if(apiResult != CY_BLE_SUCCESS) { Cy_BLE_GAP_RemoveOldestDeviceFromBondedList(); apiResult = Cy_BLE_GAPP_AuthReqReply(&cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX]); if(apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_AuthReqReply API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } } break; case CY_BLE_EVT_GAP_PASSKEY_ENTRY_REQUEST: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_PASSKEY_ENTRY_REQUEST:\n"); COMM_Console_Print_String(" Please enter the passkey displayed on the peer device.\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST: "); COMM_Console_Print_UInt32(*(uint32_t *)eventParam); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAP_AUTH_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_AUTH_COMPLETE: bdHandle=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).bdHandle); COMM_Console_Print_String(" security=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).security); COMM_Console_Print_String(" bonding=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).bonding); COMM_Console_Print_String(" ekeySize=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).ekeySize); COMM_Console_Print_String(" authErr=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).authErr); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAP_AUTH_FAILED: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_AUTH_FAILED: bdHandle=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).bdHandle); COMM_Console_Print_String(" authErr=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_auth_info_t *)eventParam).authErr); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP: state="); COMM_Console_Print_UInt8(Cy_BLE_GetAdvertisementState()); COMM_Console_Print_String("\n"); #endif // TRACE_BLE #if 0 if (Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_STOPPED) { apiResult = StartNextAdvertisement(); if (apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StartAdvertisement API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } } #endif // 0 break; case CY_BLE_EVT_GAP_DEVICE_CONNECTED: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_DEVICE_CONNECTED: connIntv="); COMM_Console_Print_UInt16(((cy_stc_ble_gap_connected_param_t *)eventParam)->connIntv * 5u /4u); COMM_Console_Print_String(" ms\n"); #endif // TRACE_BLE /* Set security keys for new device which is not already bonded */ if(App_IsDeviceInBondList((*(cy_stc_ble_gap_connected_param_t *)eventParam).bdHandle) == 0u) { keyInfo.SecKeyParam.bdHandle = (*(cy_stc_ble_gap_connected_param_t *)eventParam).bdHandle; apiResult = Cy_BLE_GAP_SetSecurityKeys(&keyInfo); if (apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAP_SetSecurityKeys API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } } break; case CY_BLE_EVT_GAP_DEVICE_DISCONNECTED: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_DEVICE_DISCONNECTED: bdHandle=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_disconnect_param_t *)eventParam).bdHandle); COMM_Console_Print_String(" reason=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_disconnect_param_t *)eventParam).reason); COMM_Console_Print_String(" status=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_gap_disconnect_param_t *)eventParam).status); COMM_Console_Print_String("\n"); #endif // TRACE_BLE apiResult = StartNextAdvertisement(); if (apiResult != CY_BLE_SUCCESS) { #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StartAdvertisement API Error: 0x"); COMM_Console_Print_UInt32AsHex(apiResult); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } break; case CY_BLE_EVT_GAP_ENCRYPT_CHANGE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_ENCRYPT_CHANGE: 0x"); COMM_Console_Print_UInt8AsHex(*(uint8_t *)eventParam); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAP_CONNECTION_UPDATE_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAPC_SCAN_START_STOP: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAPC_SCAN_START_STOP\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAP_NUMERIC_COMPARISON_REQUEST: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_NUMERIC_COMPARISON_REQUEST:\n"); COMM_Console_Print_String(" Compare this passkey with the one displayed in your peer device and press 'y' or 'n':\n"); COMM_Console_Print_String(" "); COMM_Console_Print_UInt32(*(uint32_t *)eventParam); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAP_KEYPRESS_NOTIFICATION: case CY_BLE_EVT_GAP_OOB_GENERATED_NOTIFICATION: case CY_BLE_EVT_GAP_ENHANCE_CONN_COMPLETE: case CY_BLE_EVT_GAPC_DIRECT_ADV_REPORT: case CY_BLE_EVT_GAP_SMP_NEGOTIATED_AUTH_INFO: case CY_BLE_EVT_GAP_DEVICE_ADDR_GEN_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAP_KEYS_GEN_COMPLETE: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_KEYS_GEN_COMPLETE\n"); #endif // TRACE_BLE keyInfo.SecKeyParam = (*(cy_stc_ble_gap_sec_key_param_t *)eventParam); Cy_BLE_GAP_SetIdAddress(&cy_ble_deviceAddress); break; case CY_BLE_EVT_GAP_RESOLVE_DEVICE_COMPLETE: case CY_BLE_EVT_GAP_GEN_SET_LOCAL_P256_KEYS_COMPLETE: case CY_BLE_EVT_GAP_CREATE_CONN_CANCEL_COMPLETE: case CY_BLE_EVT_GAP_CONN_ESTB: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GAPP_UPDATE_ADV_SCAN_DATA_COMPLETE: #if (defined TRACE_BLE) && (defined VERBOSE_BLE_TRACE) COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAPP_UPDATE_ADV_SCAN_DATA_COMPLETE: "); COMM_Console_Print_UInt8(*(uint8_t *)eventParam); COMM_Console_Print_String("\n"); #endif // (defined TRACE_BLE) && (defined VERBOSE_BLE_TRACE) break; case CY_BLE_EVT_GAP_ADV_TX: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GAP_ADV_TX\n"); #endif // TRACE_BLE break; // G E N E R I C A T T R I B U T E P R O F I L E E V E N T S (0x5000 to 0x5FFF) case CY_BLE_EVT_GATTC_ERROR_RSP: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GATTC_ERROR_RSP: opCode=0x"); COMM_Console_Print_UInt8AsHex(((cy_stc_ble_gatt_err_param_t*)eventParam)->errInfo.opCode); COMM_Console_Print_String(" errorCode=0x"); COMM_Console_Print_UInt8AsHex(((cy_stc_ble_gatt_err_param_t*)eventParam)->errInfo.errorCode); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; case CY_BLE_EVT_GATT_CONNECT_IND: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GATT_CONNECT_IND: bdHandle=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_conn_handle_t *)eventParam).bdHandle); COMM_Console_Print_String(" attId=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_conn_handle_t *)eventParam).attId); COMM_Console_Print_String("\n"); #endif // TRACE_BLE { cy_stc_ble_conn_handle_t connHandle = *(cy_stc_ble_conn_handle_t*)eventParam; appConnHandle[connHandle.attId] = *(cy_stc_ble_conn_handle_t *)eventParam; } break; case CY_BLE_EVT_GATT_DISCONNECT_IND: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GATT_DISCONNECT_IND: bdHandle=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_conn_handle_t *)eventParam).bdHandle); COMM_Console_Print_String(" attId=0x"); COMM_Console_Print_UInt8AsHex((*(cy_stc_ble_conn_handle_t *)eventParam).attId); COMM_Console_Print_String("\n"); #endif // TRACE_BLE { cy_stc_ble_conn_handle_t connHandle = *(cy_stc_ble_conn_handle_t*)eventParam; appConnHandle[connHandle.attId].attId = connHandle.attId; appConnHandle[connHandle.attId].bdHandle = CY_BLE_INVALID_CONN_HANDLE_VALUE; } break; case CY_BLE_EVT_GATTS_XCNHG_MTU_REQ: { cy_stc_ble_gatt_xchg_mtu_param_t mtu = { .connHandle = ((cy_stc_ble_gatt_xchg_mtu_param_t *)eventParam)->connHandle }; Cy_BLE_GATT_GetMtuSize(&mtu); #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] CY_BLE_EVT_GATTS_XCNHG_MTU_REQ: bdHandle=0x"); COMM_Console_Print_UInt8AsHex(mtu.connHandle.bdHandle); COMM_Console_Print_String(" attId=0x"); COMM_Console_Print_UInt8AsHex(mtu.connHandle.bdHandle); COMM_Console_Print_String(" mtu="); COMM_Console_Print_UInt16(mtu.mtu); COMM_Console_Print_String("\n"); #endif // TRACE_BLE } break; case CY_BLE_EVT_GATTC_XCHNG_MTU_RSP: case CY_BLE_EVT_GATTC_READ_BY_GROUP_TYPE_RSP: case CY_BLE_EVT_GATTC_READ_BY_TYPE_RSP: case CY_BLE_EVT_GATTC_FIND_INFO_RSP: case CY_BLE_EVT_GATTC_FIND_BY_TYPE_VALUE_RSP: case CY_BLE_EVT_GATTC_READ_RSP: case CY_BLE_EVT_GATTC_READ_BLOB_RSP: case CY_BLE_EVT_GATTC_READ_MULTI_RSP: case CY_BLE_EVT_GATTS_WRITE_REQ: case CY_BLE_EVT_GATTC_WRITE_RSP: case CY_BLE_EVT_GATTS_WRITE_CMD_REQ: case CY_BLE_EVT_GATTS_PREP_WRITE_REQ: case CY_BLE_EVT_GATTS_EXEC_WRITE_REQ: case CY_BLE_EVT_GATTC_EXEC_WRITE_RSP: case CY_BLE_EVT_GATTC_HANDLE_VALUE_NTF: case CY_BLE_EVT_GATTC_HANDLE_VALUE_IND: case CY_BLE_EVT_GATTS_HANDLE_VALUE_CNF: case CY_BLE_EVT_GATTS_DATA_SIGNED_CMD_REQ: case CY_BLE_EVT_GATTC_STOP_CMD_COMPLETE: case CY_BLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ: case CY_BLE_EVT_GATTC_LONG_PROCEDURE_END: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt16AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; default: #ifdef TRACE_BLE COMM_Console_Print_String("[BLE] Unhandled event: "); COMM_Console_Print_UInt32AsHex(event); COMM_Console_Print_String("\n"); #endif // TRACE_BLE break; } } } /******************************************************************************* * Function Name: IasEventHandler ******************************************************************************** * * Summary: * This is an event callback function to receive events from the BLE Component, * which are specific to Immediate Alert Service. * * Parameters: * event: Write Command event from the BLE component. * eventParams: A structure instance of CY_BLE_GATT_HANDLE_VALUE_PAIR_T type. * *******************************************************************************/ static void IASEventHandler(uint32 event, void * eventParam) { (void) eventParam; uint8_t alert; /* Alert Level Characteristic write event */ if (event == CY_BLE_EVT_IASS_WRITE_CHAR_CMD) { /* Read the updated Alert Level value from the GATT database */ Cy_BLE_IASS_GetCharacteristicValue(CY_BLE_IAS_ALERT_LEVEL, sizeof(alert), &alert); COMM_BLE_IASAlertLevel = alert; } } static cy_en_ble_api_result_t StartNextAdvertisement() { static uint8_t Current_Advertising_Index = CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX; cy_en_ble_api_result_t apiResult; apiResult = Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_FAST, Current_Advertising_Index); if(apiResult == CY_BLE_SUCCESS) { if (Current_Advertising_Index == CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX) { Current_Advertising_Index = CY_BLE_BROADCASTER_CONFIGURATION_0_INDEX; COMM_Console_Print_String("CY_BLE_BROADCASTER_CONFIGURATION_0_INDEX\n"); } else { Current_Advertising_Index = CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX; COMM_Console_Print_String("CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX\n"); } } return apiResult; }