/* 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****/