/* 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 "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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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", "enter", 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 */ /* USER CODE END PEER_CONN_HANDLE_EVT */ break; case PEER_DISCON_HANDLE_EVT : /* USER CODE BEGIN PEER_DISCON_HANDLE_EVT */ /* USER CODE END PEER_DISCON_HANDLE_EVT */ break; default: /* USER CODE BEGIN P2P_Evt_Opcode_Default */ /* USER CODE END P2P_Evt_Opcode_Default */ break; } /* USER CODE BEGIN P2PC_APP_Notification_2 */ /* USER CODE END P2PC_APP_Notification_2 */ return; } /* USER CODE BEGIN FD */ /* USER CODE END FD */ /************************************************************* * * LOCAL FUNCTIONS * *************************************************************/ /** * @brief Event handler * @param Event: Address of the buffer holding the Event * @retval Ack: Return whether the Event has been managed or not */ static SVCCTL_EvtAckStatus_t Event_Handler(void *Event) { SVCCTL_EvtAckStatus_t return_value; hci_event_pckt *event_pckt; evt_blecore_aci *blecore_evt; log_debug("Event_Handler", "enter", 0); P2P_Client_App_Notification_evt_t Notification; return_value = SVCCTL_EvtNotAck; event_pckt = (hci_event_pckt *)(((hci_uart_pckt*)Event)->data); switch(event_pckt->evt) { case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE: { blecore_evt = (evt_blecore_aci*)event_pckt->data; switch(blecore_evt->ecode) { case ACI_ATT_READ_BY_GROUP_TYPE_RESP_VSEVT_CODE: { 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 deconnected */ 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) { #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) 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 aP2PClientContext[index].state = APP_BLE_DISCOVER_CHARACS ; } idx += 6; } } } } break; case ACI_ATT_READ_BY_TYPE_RESP_VSEVT_CODE: { 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) { 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) { #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) { #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: { 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) { #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: { 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) { 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: { 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) { /* 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 */ /* 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 */ /* USER CODE END LF */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/