/* USER CODE BEGIN Header */ /** ****************************************************************************** * File Name : App/p2p_client_app.c * Description : P2P Client Application ****************************************************************************** * @attention * *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license * SLA0044, the "License"; You may not use this file except in compliance with * the License. You may obtain a copy of the License at: * www.st.com/SLA0044 * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include #include "main.h" #include "app_common.h" #include "dbg_trace.h" #include "ble.h" #include "p2p_client_app.h" #include "stm32_seq.h" #include "app_ble.h" /* USER CODE BEGIN Includes */ #include "commands.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ typedef enum { P2P_START_TIMER_EVT, P2P_STOP_TIMER_EVT, P2P_NOTIFICATION_INFO_RECEIVED_EVT, } P2P_Client_Opcode_Notification_evt_t; typedef struct { uint8_t * pPayload; uint8_t Length; }P2P_Client_Data_t; typedef struct { P2P_Client_Opcode_Notification_evt_t P2P_Client_Evt_Opcode; P2P_Client_Data_t DataTransfered; }P2P_Client_App_Notification_evt_t; typedef struct { /** * state of the P2P Client * state machine */ APP_BLE_ConnStatus_t state; /** * connection handle */ uint16_t connHandle; /** * handle of the P2P service */ uint16_t P2PServiceHandle; /** * end handle of the P2P service */ uint16_t P2PServiceEndHandle; /** * handle of the Tx characteristic - Write To Server * */ uint16_t P2PWriteToServerCharHdle; /** * handle of the client configuration * descriptor of Tx characteristic */ uint16_t P2PWriteToServerDescHandle; /** * handle of the Rx characteristic - Notification From Server * */ uint16_t P2PNotificationCharHdle; /** * handle of the client configuration * descriptor of Rx characteristic */ uint16_t P2PNotificationDescHandle; }P2P_ClientContext_t; /* USER CODE BEGIN PTD */ typedef struct{ uint8_t Device_Led_Selection; uint8_t Led1; }P2P_LedCharValue_t; typedef struct{ uint8_t Device_Button_Selection; uint8_t Button1; }P2P_ButtonCharValue_t; typedef struct { uint8_t Notification_Status; /* used to chek if P2P Server is enabled to Notify */ P2P_LedCharValue_t LedControl; P2P_ButtonCharValue_t ButtonStatus; uint16_t ConnectionHandle; } P2P_Client_App_Context_t; /* USER CODE END PTD */ /* Private defines ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macros -------------------------------------------------------------*/ #define UNPACK_2_BYTE_PARAMETER(ptr) \ (uint16_t)((uint16_t)(*((uint8_t *)ptr))) | \ (uint16_t)((((uint16_t)(*((uint8_t *)ptr + 1))) << 8)) /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /** * START of Section BLE_APP_CONTEXT */ PLACE_IN_SECTION("BLE_APP_CONTEXT") static P2P_ClientContext_t aP2PClientContext[BLE_CFG_CLT_MAX_NBR_CB]; /** * END of Section BLE_APP_CONTEXT */ /* USER CODE BEGIN PV */ PLACE_IN_SECTION("BLE_APP_CONTEXT") static P2P_Client_App_Context_t P2P_Client_App_Context; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ static void Gatt_Notification(P2P_Client_App_Notification_evt_t *pNotification); static SVCCTL_EvtAckStatus_t Event_Handler(void *Event); /* USER CODE BEGIN PFP */ static tBleStatus Write_Char(uint16_t UUID, uint8_t Service_Instance, uint8_t *pPayload); static void Button_Trigger_Received( void ); static void Update_Service( void ); /* USER CODE END PFP */ /* Functions Definition ------------------------------------------------------*/ /** * @brief Service initialization * @param None * @retval None */ void P2PC_APP_Init(void) { uint8_t index =0; /* USER CODE BEGIN P2PC_APP_Init_1 */ log_debug("P2PC_APP_Init", "start", 0); UTIL_SEQ_RegTask( 1<< CFG_TASK_SEARCH_SERVICE_ID, UTIL_SEQ_RFU, Update_Service ); UTIL_SEQ_RegTask( 1<< CFG_TASK_SW1_BUTTON_PUSHED_ID, UTIL_SEQ_RFU, Button_Trigger_Received ); /** * Initialize LedButton Service */ P2P_Client_App_Context.Notification_Status=0; P2P_Client_App_Context.ConnectionHandle = 0x00; P2P_Client_App_Context.LedControl.Device_Led_Selection=0x00;/* device Led */ P2P_Client_App_Context.LedControl.Led1=0x00; /* led OFF */ P2P_Client_App_Context.ButtonStatus.Device_Button_Selection=0x01;/* Device1 */ P2P_Client_App_Context.ButtonStatus.Button1=0x00; log_debug("P2PC_APP_Init", "BLE_CFG_CLT_MAX_NBR_CB=%d", 1, BLE_CFG_CLT_MAX_NBR_CB); /* USER CODE END P2PC_APP_Init_1 */ for(index = 0; index < BLE_CFG_CLT_MAX_NBR_CB; index++) { aP2PClientContext[index].state= APP_BLE_IDLE; } /** * Register the event handler to the BLE controller */ SVCCTL_RegisterCltHandler(Event_Handler); #if(CFG_DEBUG_APP_TRACE != 0) APP_DBG_MSG("-- P2P CLIENT INITIALIZED \n"); #endif /* USER CODE BEGIN P2PC_APP_Init_2 */ log_debug("P2PC_APP_Init", "end", 0); /* USER CODE END P2PC_APP_Init_2 */ return; } void P2PC_APP_Notification(P2PC_APP_ConnHandle_Not_evt_t *pNotification) { /* USER CODE BEGIN P2PC_APP_Notification_1 */ log_debug("P2PC_APP_Notification", "start", 0); /* USER CODE END P2PC_APP_Notification_1 */ switch(pNotification->P2P_Evt_Opcode) { /* USER CODE BEGIN P2P_Evt_Opcode */ /* USER CODE END P2P_Evt_Opcode */ case PEER_CONN_HANDLE_EVT : /* USER CODE BEGIN PEER_CONN_HANDLE_EVT */ log_debug("P2PC_APP_Notification", "PEER_CONN_HANDLE_EVT", 0); P2P_Client_App_Context.ConnectionHandle = pNotification->ConnectionHandle; /* USER CODE END PEER_CONN_HANDLE_EVT */ break; case PEER_DISCON_HANDLE_EVT : /* USER CODE BEGIN PEER_DISCON_HANDLE_EVT */ { log_debug("P2PC_APP_Notification", "PEER_DISCON_HANDLE_EVT", 0); uint8_t index = 0; P2P_Client_App_Context.ConnectionHandle = 0x00; while((index < BLE_CFG_CLT_MAX_NBR_CB) && (aP2PClientContext[index].state != APP_BLE_IDLE)) { aP2PClientContext[index].state = APP_BLE_IDLE; } // BSP_LED_Off(LED_BLUE); #if OOB_DEMO == 0 UTIL_SEQ_SetTask(1<data); switch(event_pckt->evt) { case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE: { // log_debug("Event_Handler", "HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE", 0); blecore_evt = (evt_blecore_aci*)event_pckt->data; switch(blecore_evt->ecode) { case ACI_ATT_READ_BY_GROUP_TYPE_RESP_VSEVT_CODE: { log_debug("Event_Handler", "blecore_evt->ecode=ACI_ATT_READ_BY_GROUP_TYPE_RESP_VSEVT_CODE", 0); aci_att_read_by_group_type_resp_event_rp0 *pr = (void*)blecore_evt->data; uint8_t numServ, i, idx; uint16_t uuid, handle; uint8_t index; handle = pr->Connection_Handle; index = 0; while((index < BLE_CFG_CLT_MAX_NBR_CB) && (aP2PClientContext[index].state != APP_BLE_IDLE)) { APP_BLE_ConnStatus_t status; status = APP_BLE_Get_Client_Connection_Status(aP2PClientContext[index].connHandle); if((aP2PClientContext[index].state == APP_BLE_CONNECTED_CLIENT)&& (status == APP_BLE_IDLE)) { /* Handle disconnected */ aP2PClientContext[index].state = APP_BLE_IDLE; aP2PClientContext[index].connHandle = 0xFFFF; break; } index++; } if(index < BLE_CFG_CLT_MAX_NBR_CB) { aP2PClientContext[index].connHandle= handle; numServ = (pr->Data_Length) / pr->Attribute_Data_Length; /* the event data will be * 2bytes start handle * 2bytes end handle * 2 or 16 bytes data * we are interested only if the UUID is 16 bit. * So check if the data length is 6 */ #if (UUID_128BIT_FORMAT==1) if (pr->Attribute_Data_Length == 20) { idx = 16; #else if (pr->Attribute_Data_Length == 6) { idx = 4; #endif for (i=0; iAttribute_Data_List[idx]); if(uuid == P2P_SERVICE_UUID) { log_debug("Event_Handler", "uuid=0x%x", 1, uuid); log_debug("Event_Handler", "-- GATT : P2P_SERVICE_UUID FOUND - connection handle=0x%x", 1, aP2PClientContext[index].connHandle); #if(CFG_DEBUG_APP_TRACE != 0) APP_DBG_MSG("-- GATT : P2P_SERVICE_UUID FOUND - connection handle 0x%x \n", aP2PClientContext[index].connHandle); #endif #if (UUID_128BIT_FORMAT==1) /* | 2 byte | 2 byte | 14 byte | 2 byte | | p2p service handle | p2p service end handle | ???? | uuid | */ aP2PClientContext[index].P2PServiceHandle = UNPACK_2_BYTE_PARAMETER(&pr->Attribute_Data_List[idx-16]); aP2PClientContext[index].P2PServiceEndHandle = UNPACK_2_BYTE_PARAMETER (&pr->Attribute_Data_List[idx-14]); #else aP2PClientContext[index].P2PServiceHandle = UNPACK_2_BYTE_PARAMETER(&pr->Attribute_Data_List[idx-4]); aP2PClientContext[index].P2PServiceEndHandle = UNPACK_2_BYTE_PARAMETER (&pr->Attribute_Data_List[idx-2]); #endif log_debug("Event_Handler", "aP2PClientContext.state=APP_BLE_DISCOVER_CHARACS", 0); aP2PClientContext[index].state = APP_BLE_DISCOVER_CHARACS ; } idx += 6; } } } } break; case ACI_ATT_READ_BY_TYPE_RESP_VSEVT_CODE: { log_debug("Event_Handler", "blecore_evt->ecode=ACI_ATT_READ_BY_TYPE_RESP_VSEVT_CODE", 0); aci_att_read_by_type_resp_event_rp0 *pr = (void*)blecore_evt->data; uint8_t idx; uint16_t uuid, handle; /* the event data will be * 2 bytes start handle * 1 byte char properties * 2 bytes handle * 2 or 16 bytes data */ uint8_t index; index = 0; while((index < BLE_CFG_CLT_MAX_NBR_CB) && (aP2PClientContext[index].connHandle != pr->Connection_Handle)) index++; if(index < BLE_CFG_CLT_MAX_NBR_CB) { /* we are interested in only 16 bit UUIDs */ #if (UUID_128BIT_FORMAT==1) idx = 17; if (pr->Handle_Value_Pair_Length == 21) #else idx = 5; if (pr->Handle_Value_Pair_Length == 7) #endif { pr->Data_Length -= 1; while(pr->Data_Length > 0) { log_debug("Event_Handler", "uuid=0x%x", 1, uuid); uuid = UNPACK_2_BYTE_PARAMETER(&pr->Handle_Value_Pair_Data[idx]); /* store the characteristic handle not the attribute handle */ #if (UUID_128BIT_FORMAT==1) handle = UNPACK_2_BYTE_PARAMETER(&pr->Handle_Value_Pair_Data[idx-14]); #else handle = UNPACK_2_BYTE_PARAMETER(&pr->Handle_Value_Pair_Data[idx-2]); #endif if(uuid == P2P_WRITE_CHAR_UUID) { log_debug("Event_Handler", "-- GATT : WRITE_UUID FOUND - connection handle=0x%x", 1, aP2PClientContext[index].connHandle); #if(CFG_DEBUG_APP_TRACE != 0) APP_DBG_MSG("-- GATT : WRITE_UUID FOUND - connection handle 0x%x\n", aP2PClientContext[index].connHandle); #endif aP2PClientContext[index].state = APP_BLE_DISCOVER_WRITE_DESC; aP2PClientContext[index].P2PWriteToServerCharHdle = handle; } else if(uuid == P2P_NOTIFY_CHAR_UUID) { log_debug("Event_Handler", "-- GATT : NOTIFICATION_CHAR_UUID FOUND - connection handle=0x%x", 1, aP2PClientContext[index].connHandle); #if(CFG_DEBUG_APP_TRACE != 0) APP_DBG_MSG("-- GATT : NOTIFICATION_CHAR_UUID FOUND - connection handle 0x%x\n", aP2PClientContext[index].connHandle); #endif aP2PClientContext[index].state = APP_BLE_DISCOVER_NOTIFICATION_CHAR_DESC; aP2PClientContext[index].P2PNotificationCharHdle = handle; } #if (UUID_128BIT_FORMAT==1) pr->Data_Length -= 21; idx += 21; #else pr->Data_Length -= 7; idx += 7; #endif } } } } break; case ACI_ATT_FIND_INFO_RESP_VSEVT_CODE: { log_debug("Event_Handler", "blecore_evt->ecode=ACI_ATT_FIND_INFO_RESP_VSEVT_CODE", 0); aci_att_find_info_resp_event_rp0 *pr = (void*)blecore_evt->data; uint8_t numDesc, idx, i; uint16_t uuid, handle; /* * event data will be of the format * 2 bytes handle * 2 bytes UUID */ uint8_t index; index = 0; while((index < BLE_CFG_CLT_MAX_NBR_CB) && (aP2PClientContext[index].connHandle != pr->Connection_Handle)) index++; if(index < BLE_CFG_CLT_MAX_NBR_CB) { numDesc = (pr->Event_Data_Length) / 4; /* we are interested only in 16 bit UUIDs */ idx = 0; if (pr->Format == UUID_TYPE_16) { for (i=0; iHandle_UUID_Pair[idx]); uuid = UNPACK_2_BYTE_PARAMETER(&pr->Handle_UUID_Pair[idx+2]); if(uuid == CLIENT_CHAR_CONFIG_DESCRIPTOR_UUID) { log_debug("Event_Handler", "-- GATT : CLIENT_CHAR_CONFIG_DESCRIPTOR_UUID FOUND - connection handle=0x%x", 1, aP2PClientContext[index].connHandle); #if(CFG_DEBUG_APP_TRACE != 0) APP_DBG_MSG("-- GATT : CLIENT_CHAR_CONFIG_DESCRIPTOR_UUID- connection handle 0x%x\n", aP2PClientContext[index].connHandle); #endif if( aP2PClientContext[index].state == APP_BLE_DISCOVER_NOTIFICATION_CHAR_DESC) { aP2PClientContext[index].P2PNotificationDescHandle = handle; aP2PClientContext[index].state = APP_BLE_ENABLE_NOTIFICATION_DESC; } } idx += 4; } } } } break; /*ACI_ATT_FIND_INFO_RESP_VSEVT_CODE*/ case ACI_GATT_NOTIFICATION_VSEVT_CODE: { log_debug("Event_Handler", "blecore_evt->ecode=ACI_GATT_NOTIFICATION_VSEVT_CODE", 0); aci_gatt_notification_event_rp0 *pr = (void*)blecore_evt->data; uint8_t index; index = 0; while((index < BLE_CFG_CLT_MAX_NBR_CB) && (aP2PClientContext[index].connHandle != pr->Connection_Handle)) index++; if(index < BLE_CFG_CLT_MAX_NBR_CB) { uint8_t buffer[512]; buffer[0] = (uint8_t)('0'); buffer[1] = (uint8_t)('x'); uint8_t i; for (i = 0; iAttribute_Value_Length; i++) { snprintf((char*)(buffer + i + 2), 512-i-2, "%x", pr->Attribute_Value[i]); } buffer[i + 2] = (uint8_t)('\0'); log_debug("Event_Handler", "Notification payload: %s", 1, buffer); if ( (pr->Attribute_Handle == aP2PClientContext[index].P2PNotificationCharHdle) && (pr->Attribute_Value_Length == (2)) ) { Notification.P2P_Client_Evt_Opcode = P2P_NOTIFICATION_INFO_RECEIVED_EVT; Notification.DataTransfered.Length = pr->Attribute_Value_Length; Notification.DataTransfered.pPayload = &pr->Attribute_Value[0]; Gatt_Notification(&Notification); /* INFORM APPLICATION BUTTON IS PUSHED BY END DEVICE */ } } } break;/* end ACI_GATT_NOTIFICATION_VSEVT_CODE */ case ACI_GATT_PROC_COMPLETE_VSEVT_CODE: { log_debug("Event_Handler", "blecore_evt->ecode=ACI_GATT_PROC_COMPLETE_VSEVT_CODE", 0); aci_gatt_proc_complete_event_rp0 *pr = (void*)blecore_evt->data; #if(CFG_DEBUG_APP_TRACE != 0) APP_DBG_MSG("-- GATT : ACI_GATT_PROC_COMPLETE_VSEVT_CODE \n"); APP_DBG_MSG("\n"); #endif uint8_t index; index = 0; while((index < BLE_CFG_CLT_MAX_NBR_CB) && (aP2PClientContext[index].connHandle != pr->Connection_Handle)) index++; if(index < BLE_CFG_CLT_MAX_NBR_CB) { UTIL_SEQ_SetTask( 1<P2P_Client_Evt_Opcode=0x%x", 1, pNotification->P2P_Client_Evt_Opcode); /* USER CODE END Gatt_Notification_1 */ switch(pNotification->P2P_Client_Evt_Opcode) { /* USER CODE BEGIN P2P_Client_Evt_Opcode */ /* USER CODE END P2P_Client_Evt_Opcode */ case P2P_NOTIFICATION_INFO_RECEIVED_EVT: /* USER CODE BEGIN P2P_NOTIFICATION_INFO_RECEIVED_EVT */ { P2P_Client_App_Context.LedControl.Device_Led_Selection=pNotification->DataTransfered.pPayload[0]; log_debug("Gatt_Notification", "DataTransfered.pPayload[0]=0x%x", 1, pNotification->DataTransfered.pPayload[0]); log_debug("Gatt_Notification", "DataTransfered.pPayload[1]=0x%x", 1, pNotification->DataTransfered.pPayload[1]); switch(P2P_Client_App_Context.LedControl.Device_Led_Selection) { case 0x01 : { P2P_Client_App_Context.LedControl.Led1=pNotification->DataTransfered.pPayload[1]; if(P2P_Client_App_Context.LedControl.Led1==0x00){ // BSP_LED_Off(LED_BLUE); log_debug("Gatt_Notification", " -- P2P APPLICATION CLIENT : NOTIFICATION RECEIVED - LED OFF ", 0); } else { log_debug("Gatt_Notification", " -- P2P APPLICATION CLIENT : NOTIFICATION RECEIVED - LED ON", 0); // BSP_LED_On(LED_BLUE); } break; } default : break; } } /* USER CODE END P2P_NOTIFICATION_INFO_RECEIVED_EVT */ break; default: /* USER CODE BEGIN P2P_Client_Evt_Opcode_Default */ /* USER CODE END P2P_Client_Evt_Opcode_Default */ break; } /* USER CODE BEGIN Gatt_Notification_2*/ /* USER CODE END Gatt_Notification_2 */ return; } uint8_t P2P_Client_APP_Get_State( void ) { return aP2PClientContext[0].state; } /* USER CODE BEGIN LF */ /** * @brief Feature Characteristic update * @param pFeatureValue: The address of the new value to be written * @retval None */ tBleStatus Write_Char(uint16_t UUID, uint8_t Service_Instance, uint8_t *pPayload) { log_debug("Write_Char", "enter", 0); tBleStatus ret = BLE_STATUS_INVALID_PARAMS; uint8_t index; index = 0; while((index < BLE_CFG_CLT_MAX_NBR_CB) && (aP2PClientContext[index].state != APP_BLE_IDLE)) { switch(UUID) { case P2P_WRITE_CHAR_UUID: /* SERVER RX -- so CLIENT TX */ log_debug("Write_Char", "payload 0x%x%x", 2, pPayload[0], pPayload[1]); ret =aci_gatt_write_without_resp(aP2PClientContext[index].connHandle, aP2PClientContext[index].P2PWriteToServerCharHdle, 2, /* charValueLen */ (uint8_t *) pPayload); break; default: break; } index++; } return ret; }/* end Write_Char() */ void Button_Trigger_Received(void) { log_debug("Button_Trigger_Received", "-- P2P APPLICATION CLIENT : BUTTON PUSHED - WRITE TO SERVER ", 0); if(P2P_Client_App_Context.ButtonStatus.Button1==0x00){ P2P_Client_App_Context.ButtonStatus.Button1=0x01; }else { P2P_Client_App_Context.ButtonStatus.Button1=0x00; } Write_Char( P2P_WRITE_CHAR_UUID, 0, (uint8_t *)&P2P_Client_App_Context.ButtonStatus); return; } void Update_Service() { log_debug("Update_Service", "enter", 0); uint16_t enable = 0x0001; uint16_t disable = 0x0000; uint8_t index; index = 0; while((index < BLE_CFG_CLT_MAX_NBR_CB) && (aP2PClientContext[index].state != APP_BLE_IDLE)) { switch(aP2PClientContext[index].state) { case APP_BLE_DISCOVER_SERVICES: log_info("Update_Service", "P2P_DISCOVER_SERVICES", 0); break; case APP_BLE_DISCOVER_CHARACS: log_info("Update_Service", "* GATT : Discover P2P Characteristics", 0); aci_gatt_disc_all_char_of_service(aP2PClientContext[index].connHandle, aP2PClientContext[index].P2PServiceHandle, aP2PClientContext[index].P2PServiceEndHandle); break; case APP_BLE_DISCOVER_WRITE_DESC: /* Not Used - No decriptor */ log_info("Update_Service", "* GATT : Discover Descriptor of TX - Write Characteritic", 0); aci_gatt_disc_all_char_desc(aP2PClientContext[index].connHandle, aP2PClientContext[index].P2PWriteToServerCharHdle, aP2PClientContext[index].P2PWriteToServerCharHdle+2); break; case APP_BLE_DISCOVER_NOTIFICATION_CHAR_DESC: log_info("Update_Service", "* GATT : Discover Descriptor of Rx - Notification Characteritic", 0); aci_gatt_disc_all_char_desc(aP2PClientContext[index].connHandle, aP2PClientContext[index].P2PNotificationCharHdle, aP2PClientContext[index].P2PNotificationCharHdle+2); break; case APP_BLE_ENABLE_NOTIFICATION_DESC: log_info("Update_Service", "* GATT : Enable Server Notification", 0); aci_gatt_write_char_desc(aP2PClientContext[index].connHandle, aP2PClientContext[index].P2PNotificationDescHandle, 2, (uint8_t *)&enable); aP2PClientContext[index].state = APP_BLE_CONNECTED_CLIENT; log_info("Update_Service", "state: APP_BLE_CONNECTED_CLIENT", 0); // BSP_LED_Off(LED_RED); break; case APP_BLE_DISABLE_NOTIFICATION_DESC : log_debug("Update_Service", "* GATT : Disable Server Notification", 0); aci_gatt_write_char_desc(aP2PClientContext[index].connHandle, aP2PClientContext[index].P2PNotificationDescHandle, 2, (uint8_t *)&disable); aP2PClientContext[index].state = APP_BLE_CONNECTED_CLIENT; log_info("Update_Service", "state: APP_BLE_CONNECTED_CLIENT", 0); break; default: break; } index++; } return; } /* USER CODE END LF */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/