You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1051 lines
32 KiB
1051 lines
32 KiB
/* USER CODE BEGIN Header */
|
|
/**
|
|
******************************************************************************
|
|
* File Name : App/app_ble.c
|
|
* Description : Application file for BLE Middleware.
|
|
*
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
|
* All rights reserved.</center></h2>
|
|
*
|
|
* 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 "tl.h"
|
|
#include "app_ble.h"
|
|
|
|
#include "stm32_seq.h"
|
|
#include "shci.h"
|
|
#include "stm32_lpm.h"
|
|
#include "otp.h"
|
|
|
|
#include "p2p_client_app.h"
|
|
|
|
/* Private includes ----------------------------------------------------------*/
|
|
/* USER CODE BEGIN Includes */
|
|
#include "commands.h"
|
|
/* USER CODE END Includes */
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
|
|
/**
|
|
* security parameters structure
|
|
*/
|
|
typedef struct _tSecurityParams
|
|
{
|
|
/**
|
|
* IO capability of the device
|
|
*/
|
|
uint8_t ioCapability;
|
|
|
|
/**
|
|
* Authentication requirement of the device
|
|
* Man In the Middle protection required?
|
|
*/
|
|
uint8_t mitm_mode;
|
|
|
|
/**
|
|
* bonding mode of the device
|
|
*/
|
|
uint8_t bonding_mode;
|
|
|
|
/**
|
|
* this variable indicates whether to use a fixed pin
|
|
* during the pairing process or a passkey has to be
|
|
* requested to the application during the pairing process
|
|
* 0 implies use fixed pin and 1 implies request for passkey
|
|
*/
|
|
uint8_t Use_Fixed_Pin;
|
|
|
|
/**
|
|
* minimum encryption key size requirement
|
|
*/
|
|
uint8_t encryptionKeySizeMin;
|
|
|
|
/**
|
|
* maximum encryption key size requirement
|
|
*/
|
|
uint8_t encryptionKeySizeMax;
|
|
|
|
/**
|
|
* fixed pin to be used in the pairing process if
|
|
* Use_Fixed_Pin is set to 1
|
|
*/
|
|
uint32_t Fixed_Pin;
|
|
|
|
/**
|
|
* this flag indicates whether the host has to initiate
|
|
* the security, wait for pairing or does not have any security
|
|
* requirements.\n
|
|
* 0x00 : no security required
|
|
* 0x01 : host should initiate security by sending the slave security
|
|
* request command
|
|
* 0x02 : host need not send the clave security request but it
|
|
* has to wait for paiirng to complete before doing any other
|
|
* processing
|
|
*/
|
|
uint8_t initiateSecurity;
|
|
} tSecurityParams;
|
|
|
|
/**
|
|
* global context
|
|
* contains the variables common to all
|
|
* services
|
|
*/
|
|
typedef struct _tBLEProfileGlobalContext
|
|
{
|
|
|
|
/**
|
|
* security requirements of the host
|
|
*/
|
|
tSecurityParams bleSecurityParam;
|
|
|
|
/**
|
|
* gap service handle
|
|
*/
|
|
uint16_t gapServiceHandle;
|
|
|
|
/**
|
|
* device name characteristic handle
|
|
*/
|
|
uint16_t devNameCharHandle;
|
|
|
|
/**
|
|
* appearance characteristic handle
|
|
*/
|
|
uint16_t appearanceCharHandle;
|
|
|
|
/**
|
|
* connection handle of the current active connection
|
|
* When not in connection, the handle is set to 0xFFFF
|
|
*/
|
|
uint16_t connectionHandle;
|
|
|
|
/**
|
|
* length of the UUID list to be used while advertising
|
|
*/
|
|
uint8_t advtServUUIDlen;
|
|
|
|
/**
|
|
* the UUID list to be used while advertising
|
|
*/
|
|
uint8_t advtServUUID[100];
|
|
|
|
} BleGlobalContext_t;
|
|
|
|
typedef struct
|
|
{
|
|
BleGlobalContext_t BleApplicationContext_legacy;
|
|
APP_BLE_ConnStatus_t Device_Connection_Status;
|
|
uint8_t SwitchOffGPIO_timer_Id;
|
|
uint8_t DeviceServerFound;
|
|
} BleApplicationContext_t;
|
|
|
|
#if OOB_DEMO != 0
|
|
typedef struct
|
|
{
|
|
uint8_t Identifier;
|
|
uint16_t L2CAP_Length;
|
|
uint16_t Interval_Min;
|
|
uint16_t Interval_Max;
|
|
uint16_t Slave_Latency;
|
|
uint16_t Timeout_Multiplier;
|
|
} APP_BLE_p2p_Conn_Update_req_t;
|
|
#endif
|
|
|
|
/* USER CODE BEGIN PTD */
|
|
|
|
/* USER CODE END PTD */
|
|
|
|
/* Private defines -----------------------------------------------------------*/
|
|
#define APPBLE_GAP_DEVICE_NAME_LENGTH 7
|
|
#define BD_ADDR_SIZE_LOCAL 6
|
|
|
|
/* USER CODE BEGIN PD */
|
|
|
|
/* USER CODE END PD */
|
|
|
|
/* Private macros ------------------------------------------------------------*/
|
|
/* USER CODE BEGIN PM */
|
|
|
|
/* USER CODE END PM */
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer;
|
|
|
|
static const uint8_t M_bd_addr[BD_ADDR_SIZE_LOCAL] =
|
|
{
|
|
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000000000FF)),
|
|
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x00000000FF00) >> 8),
|
|
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x000000FF0000) >> 16),
|
|
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000FF000000) >> 24),
|
|
(uint8_t)((CFG_ADV_BD_ADDRESS & 0x00FF00000000) >> 32),
|
|
(uint8_t)((CFG_ADV_BD_ADDRESS & 0xFF0000000000) >> 40)
|
|
};
|
|
|
|
static uint8_t bd_addr_udn[BD_ADDR_SIZE_LOCAL];
|
|
|
|
/**
|
|
* Identity root key used to derive LTK and CSRK
|
|
*/
|
|
static const uint8_t BLE_CFG_IR_VALUE[16] = CFG_BLE_IRK;
|
|
|
|
/**
|
|
* Encryption root key used to derive LTK and CSRK
|
|
*/
|
|
static const uint8_t BLE_CFG_ER_VALUE[16] = CFG_BLE_ERK;
|
|
|
|
tBDAddr SERVER_REMOTE_BDADDR;
|
|
|
|
P2PC_APP_ConnHandle_Not_evt_t handleNotification;
|
|
|
|
PLACE_IN_SECTION("BLE_APP_CONTEXT") static BleApplicationContext_t BleApplicationContext;
|
|
|
|
#if OOB_DEMO != 0
|
|
APP_BLE_p2p_Conn_Update_req_t APP_BLE_p2p_Conn_Update_req;
|
|
#endif
|
|
|
|
/* USER CODE BEGIN PV */
|
|
|
|
/* USER CODE END PV */
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
static void BLE_UserEvtRx( void * pPayload );
|
|
static void BLE_StatusNot( HCI_TL_CmdStatus_t status );
|
|
static void Ble_Tl_Init( void );
|
|
static void Ble_Hci_Gap_Gatt_Init(void);
|
|
static const uint8_t* BleGetBdAddress( void );
|
|
static void Scan_Request( void );
|
|
static void Connect_Request( void );
|
|
static void Switch_OFF_GPIO( void );
|
|
|
|
/* USER CODE BEGIN PFP */
|
|
|
|
/* USER CODE END PFP */
|
|
|
|
/* Private user code ---------------------------------------------------------*/
|
|
/* USER CODE BEGIN 0 */
|
|
|
|
/* USER CODE END 0 */
|
|
|
|
/* Functions Definition ------------------------------------------------------*/
|
|
void APP_BLE_Init( void )
|
|
{
|
|
/* USER CODE BEGIN APP_BLE_Init_1 */
|
|
|
|
/* USER CODE END APP_BLE_Init_1 */
|
|
SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet =
|
|
{
|
|
{{0,0,0}}, /**< Header unused */
|
|
{0, /** pBleBufferAddress not used */
|
|
0, /** BleBufferSize not used */
|
|
CFG_BLE_NUM_GATT_ATTRIBUTES,
|
|
CFG_BLE_NUM_GATT_SERVICES,
|
|
CFG_BLE_ATT_VALUE_ARRAY_SIZE,
|
|
CFG_BLE_NUM_LINK,
|
|
CFG_BLE_DATA_LENGTH_EXTENSION,
|
|
CFG_BLE_PREPARE_WRITE_LIST_SIZE,
|
|
CFG_BLE_MBLOCK_COUNT,
|
|
CFG_BLE_MAX_ATT_MTU,
|
|
CFG_BLE_SLAVE_SCA,
|
|
CFG_BLE_MASTER_SCA,
|
|
CFG_BLE_LSE_SOURCE,
|
|
CFG_BLE_MAX_CONN_EVENT_LENGTH,
|
|
CFG_BLE_HSE_STARTUP_TIME,
|
|
CFG_BLE_VITERBI_MODE,
|
|
CFG_BLE_OPTIONS,
|
|
0,
|
|
CFG_BLE_MAX_COC_INITIATOR_NBR,
|
|
CFG_BLE_MIN_TX_POWER,
|
|
CFG_BLE_MAX_TX_POWER}
|
|
};
|
|
|
|
/**
|
|
* Initialize Ble Transport Layer
|
|
*/
|
|
Ble_Tl_Init( );
|
|
|
|
/**
|
|
* Do not allow standby in the application
|
|
*/
|
|
UTIL_LPM_SetOffMode(1 << CFG_LPM_APP_BLE, UTIL_LPM_DISABLE);
|
|
|
|
/**
|
|
* Register the hci transport layer to handle BLE User Asynchronous Events
|
|
*/
|
|
UTIL_SEQ_RegTask( 1<<CFG_TASK_HCI_ASYNCH_EVT_ID, UTIL_SEQ_RFU, hci_user_evt_proc);
|
|
|
|
/**
|
|
* Starts the BLE Stack on CPU2
|
|
*/
|
|
if (SHCI_C2_BLE_Init( &ble_init_cmd_packet ) != SHCI_Success)
|
|
{
|
|
Error_Handler();
|
|
}
|
|
|
|
/**
|
|
* Initialization of HCI & GATT & GAP layer
|
|
*/
|
|
Ble_Hci_Gap_Gatt_Init();
|
|
|
|
/**
|
|
* Initialization of the BLE Services
|
|
*/
|
|
SVCCTL_Init();
|
|
|
|
/**
|
|
* From here, all initialization are BLE application specific
|
|
*/
|
|
UTIL_SEQ_RegTask( 1<<CFG_TASK_START_SCAN_ID, UTIL_SEQ_RFU, Scan_Request);
|
|
UTIL_SEQ_RegTask( 1<<CFG_TASK_CONN_DEV_1_ID, UTIL_SEQ_RFU, Connect_Request);
|
|
|
|
/**
|
|
* Initialization of the BLE App Context
|
|
*/
|
|
|
|
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
|
|
|
|
/*Radio mask Activity*/
|
|
#if (OOB_DEMO != 0)
|
|
aci_hal_set_radio_activity_mask(0x0020); // connection event master
|
|
log_debug("APP_BLE_Init", "aci_hal_set_radio_activity_mask=0x0020 (connection event master)", 0);
|
|
#endif
|
|
/**
|
|
* Initialize P2P Client Application
|
|
*/
|
|
P2PC_APP_Init();
|
|
|
|
#if (OOB_DEMO != 0)
|
|
HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(BleApplicationContext.SwitchOffGPIO_timer_Id), hw_ts_SingleShot, Switch_OFF_GPIO);
|
|
#endif
|
|
|
|
#if (OOB_DEMO == 0)
|
|
/**
|
|
* Start scanning
|
|
*/
|
|
UTIL_SEQ_SetTask(1 << CFG_TASK_START_SCAN_ID, CFG_SCH_PRIO_0);
|
|
log_debug("APP_BLE_Init", "trigger scanning task", 0);
|
|
#endif
|
|
/* USER CODE BEGIN APP_BLE_Init_2 */
|
|
log_debug("APP_BLE_Init", "done", 0);
|
|
/* USER CODE END APP_BLE_Init_2 */
|
|
return;
|
|
}
|
|
|
|
SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
|
|
{
|
|
hci_event_pckt *event_pckt;
|
|
evt_le_meta_event *meta_evt;
|
|
hci_le_connection_complete_event_rp0 * connection_complete_event;
|
|
evt_blecore_aci *blecore_evt;
|
|
hci_le_advertising_report_event_rp0 * le_advertising_event;
|
|
event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data;
|
|
hci_disconnection_complete_event_rp0 *cc = (void *) event_pckt->data;
|
|
uint8_t result;
|
|
uint8_t event_type, event_data_size;
|
|
int k = 0;
|
|
uint8_t adtype, adlength;
|
|
|
|
// log_debug("SVCCTL_App_Notification", "enter, event=%d", 1, event_pckt->evt);
|
|
switch (event_pckt->evt)
|
|
{
|
|
/* USER CODE BEGIN evt */
|
|
|
|
/* USER CODE END evt */
|
|
case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE:
|
|
{
|
|
handleNotification.P2P_Evt_Opcode = PEER_DISCON_HANDLE_EVT;
|
|
blecore_evt = (evt_blecore_aci*) event_pckt->data;
|
|
/* USER CODE BEGIN EVT_VENDOR */
|
|
|
|
/* USER CODE END EVT_VENDOR */
|
|
switch (blecore_evt->ecode)
|
|
{
|
|
/* USER CODE BEGIN ecode */
|
|
|
|
/* USER CODE END ecode */
|
|
|
|
case ACI_GAP_PROC_COMPLETE_VSEVT_CODE:
|
|
{
|
|
/* USER CODE BEGIN EVT_BLUE_GAP_PROCEDURE_COMPLETE */
|
|
|
|
/* USER CODE END EVT_BLUE_GAP_PROCEDURE_COMPLETE */
|
|
aci_gap_proc_complete_event_rp0 *gap_evt_proc_complete = (void*) blecore_evt->data;
|
|
/* CHECK GAP GENERAL DISCOVERY PROCEDURE COMPLETED & SUCCEED */
|
|
if (gap_evt_proc_complete->Procedure_Code == GAP_GENERAL_DISCOVERY_PROC
|
|
&& gap_evt_proc_complete->Status == 0x00)
|
|
{
|
|
/* USER CODE BEGIN GAP_GENERAL_DISCOVERY_PROC */
|
|
|
|
/* USER CODE END GAP_GENERAL_DISCOVERY_PROC */
|
|
log_debug("SVCCTL_App_Notification", "-- GAP GENERAL DISCOVERY PROCEDURE_COMPLETED", 0);
|
|
/*if a device found, connect to it, device 1 being chosen first if both found*/
|
|
if (BleApplicationContext.DeviceServerFound == 0x01 && BleApplicationContext.Device_Connection_Status != APP_BLE_CONNECTED_CLIENT)
|
|
{
|
|
log_debug("SVCCTL_App_Notification", "Set task: CFG_TASK_CONN_DEV_1_ID", 0);
|
|
UTIL_SEQ_SetTask(1 << CFG_TASK_CONN_DEV_1_ID, CFG_SCH_PRIO_0);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
#if (OOB_DEMO != 0)
|
|
case ACI_L2CAP_CONNECTION_UPDATE_REQ_VSEVT_CODE:
|
|
{
|
|
/* USER CODE BEGIN EVT_BLUE_L2CAP_CONNECTION_UPDATE_REQ */
|
|
|
|
log_debug("SVCCTL_App_Notification", "Event: ACI_L2CAP_CONNECTION_UPDATE_REQ_VSEVT_CODE", 0);
|
|
/* USER CODE END EVT_BLUE_L2CAP_CONNECTION_UPDATE_REQ */
|
|
aci_l2cap_connection_update_req_event_rp0 *pr = (aci_l2cap_connection_update_req_event_rp0 *) blecore_evt->data;
|
|
aci_hal_set_radio_activity_mask(0x0000);
|
|
APP_BLE_p2p_Conn_Update_req.Identifier = pr->Identifier;
|
|
APP_BLE_p2p_Conn_Update_req.L2CAP_Length = pr->L2CAP_Length;
|
|
APP_BLE_p2p_Conn_Update_req.Interval_Min = pr->Interval_Min;
|
|
APP_BLE_p2p_Conn_Update_req.Interval_Max = pr->Interval_Max;
|
|
APP_BLE_p2p_Conn_Update_req.Slave_Latency = pr->Slave_Latency;
|
|
APP_BLE_p2p_Conn_Update_req.Timeout_Multiplier = pr->Timeout_Multiplier;
|
|
|
|
result = aci_l2cap_connection_parameter_update_resp(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,
|
|
APP_BLE_p2p_Conn_Update_req.Interval_Min,
|
|
APP_BLE_p2p_Conn_Update_req.Interval_Max,
|
|
APP_BLE_p2p_Conn_Update_req.Slave_Latency,
|
|
APP_BLE_p2p_Conn_Update_req.Timeout_Multiplier,
|
|
CONN_L1,
|
|
CONN_L2,
|
|
APP_BLE_p2p_Conn_Update_req.Identifier,
|
|
0x01);
|
|
if(result != BLE_STATUS_SUCCESS) {
|
|
/* USER CODE BEGIN BLE_STATUS_SUCCESS */
|
|
log_debug("SVCCTL_App_Notification", "BLE_STATUS_SUCCESS: false", 0);
|
|
/* USER CODE END BLE_STATUS_SUCCESS */
|
|
}
|
|
aci_hal_set_radio_activity_mask(0x0020);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x0004:
|
|
{
|
|
/* USER CODE BEGIN RADIO_ACTIVITY_EVENT */
|
|
// log_debug("SVCCTL_App_Notification", "RADIO_ACTIVITY_EVENT", 0);
|
|
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
|
|
HAL_Delay(5);
|
|
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
|
|
/* USER CODE END RADIO_ACTIVITY_EVENT */
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
/* USER CODE BEGIN BLUE_EVT */
|
|
|
|
/* USER CODE END BLUE_EVT */
|
|
|
|
default:
|
|
/* USER CODE BEGIN ecode_default */
|
|
|
|
/* USER CODE END ecode_default */
|
|
break;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HCI_DISCONNECTION_COMPLETE_EVT_CODE:
|
|
{
|
|
/* USER CODE BEGIN EVT_DISCONN_COMPLETE */
|
|
|
|
/* USER CODE END EVT_DISCONN_COMPLETE */
|
|
if (cc->Connection_Handle == BleApplicationContext.BleApplicationContext_legacy.connectionHandle)
|
|
{
|
|
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0;
|
|
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
|
|
APP_DBG_MSG("\r\n\r** DISCONNECTION EVENT WITH SERVER \n");
|
|
handleNotification.P2P_Evt_Opcode = PEER_DISCON_HANDLE_EVT;
|
|
handleNotification.ConnectionHandle = BleApplicationContext.BleApplicationContext_legacy.connectionHandle;
|
|
P2PC_APP_Notification(&handleNotification);
|
|
}
|
|
}
|
|
break; /* HCI_DISCONNECTION_COMPLETE_EVT_CODE */
|
|
|
|
case HCI_LE_META_EVT_CODE:
|
|
{
|
|
/* USER CODE BEGIN EVT_LE_META_EVENT */
|
|
|
|
/* USER CODE END EVT_LE_META_EVENT */
|
|
meta_evt = (evt_le_meta_event*) event_pckt->data;
|
|
|
|
switch (meta_evt->subevent)
|
|
{
|
|
/* USER CODE BEGIN subevent */
|
|
|
|
/* USER CODE END subevent */
|
|
case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE:
|
|
/* USER CODE BEGIN EVT_LE_CONN_COMPLETE */
|
|
|
|
/* USER CODE END EVT_LE_CONN_COMPLETE */
|
|
/**
|
|
* The connection is done,
|
|
*/
|
|
connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data;
|
|
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = connection_complete_event->Connection_Handle;
|
|
BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_CLIENT;
|
|
|
|
/* CONNECTION WITH CLIENT */
|
|
log_debug("SVCCTL_App_Notification", "** CONNECTION EVENT WITH SERVER", 0);
|
|
handleNotification.P2P_Evt_Opcode = PEER_CONN_HANDLE_EVT;
|
|
handleNotification.ConnectionHandle = BleApplicationContext.BleApplicationContext_legacy.connectionHandle;
|
|
P2PC_APP_Notification(&handleNotification);
|
|
|
|
result = aci_gatt_disc_all_primary_services(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
|
|
if (result == BLE_STATUS_SUCCESS)
|
|
{
|
|
log_debug("SVCCTL_App_Notification", "** GATT SERVICES & CHARACTERISTICS DISCOVERY", 0);
|
|
log_debug("SVCCTL_App_Notification", "* GATT : Start Searching Primary Services", 0);
|
|
}
|
|
else
|
|
{
|
|
log_error("SVCCTL_App_Notification", "All services discovery Failed", 0);
|
|
}
|
|
|
|
break; /* HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE */
|
|
|
|
case HCI_LE_ADVERTISING_REPORT_SUBEVT_CODE:
|
|
{
|
|
uint8_t *adv_report_data;
|
|
/* USER CODE BEGIN EVT_LE_ADVERTISING_REPORT */
|
|
|
|
/* USER CODE END EVT_LE_ADVERTISING_REPORT */
|
|
le_advertising_event = (hci_le_advertising_report_event_rp0 *) meta_evt->data;
|
|
|
|
event_type = le_advertising_event->Advertising_Report[0].Event_Type;
|
|
|
|
event_data_size = le_advertising_event->Advertising_Report[0].Length_Data;
|
|
|
|
/* WARNING: be careful when decoding advertising report as its raw format cannot be mapped on a C structure.
|
|
The data and RSSI values could not be directly decoded from the RAM using the data and RSSI field from hci_le_advertising_report_event_rp0 structure.
|
|
Instead they must be read by using offsets (please refer to BLE specification).
|
|
RSSI = (int8_t)*(uint8_t*) (adv_report_data + le_advertising_event->Advertising_Report[0].Length_Data);
|
|
*/
|
|
adv_report_data = (uint8_t*)(&le_advertising_event->Advertising_Report[0].Length_Data) + 1;
|
|
k = 0;
|
|
|
|
/* search AD TYPE 0x09 (Complete Local Name) */
|
|
/* search AD Type 0x02 (16 bits UUIDS) */
|
|
if (event_type == ADV_IND)
|
|
{
|
|
|
|
/* ISOLATION OF BD ADDRESS AND LOCAL NAME */
|
|
|
|
while(k < event_data_size)
|
|
{
|
|
adlength = adv_report_data[k];
|
|
adtype = adv_report_data[k + 1];
|
|
switch (adtype)
|
|
{
|
|
case AD_TYPE_FLAGS: /* now get flags */
|
|
/* USER CODE BEGIN AD_TYPE_FLAGS */
|
|
|
|
/* USER CODE END AD_TYPE_FLAGS */
|
|
break;
|
|
|
|
case AD_TYPE_TX_POWER_LEVEL: /* Tx power level */
|
|
/* USER CODE BEGIN AD_TYPE_TX_POWER_LEVEL */
|
|
|
|
/* USER CODE END AD_TYPE_TX_POWER_LEVEL */
|
|
break;
|
|
case AD_TYPE_MANUFACTURER_SPECIFIC_DATA: /* Manufacturer Specific */
|
|
/* USER CODE BEGIN AD_TYPE_MANUFACTURER_SPECIFIC_DATA */
|
|
|
|
/* USER CODE END AD_TYPE_MANUFACTURER_SPECIFIC_DATA */
|
|
if (adlength >= 7 && adv_report_data[k + 2] == 0x01)
|
|
{ /* ST VERSION ID 01 */
|
|
APP_DBG_MSG("--- ST MANUFACTURER ID --- \n");
|
|
switch (adv_report_data[k + 3])
|
|
{ /* Demo ID */
|
|
case CFG_DEV_ID_P2P_SERVER1: /* End Device 1 */
|
|
APP_DBG_MSG("-- SERVER DETECTED -- VIA MAN ID\n");
|
|
BleApplicationContext.DeviceServerFound = 0x01;
|
|
SERVER_REMOTE_BDADDR[0] = le_advertising_event->Advertising_Report[0].Address[0];
|
|
SERVER_REMOTE_BDADDR[1] = le_advertising_event->Advertising_Report[0].Address[1];
|
|
SERVER_REMOTE_BDADDR[2] = le_advertising_event->Advertising_Report[0].Address[2];
|
|
SERVER_REMOTE_BDADDR[3] = le_advertising_event->Advertising_Report[0].Address[3];
|
|
SERVER_REMOTE_BDADDR[4] = le_advertising_event->Advertising_Report[0].Address[4];
|
|
SERVER_REMOTE_BDADDR[5] = le_advertising_event->Advertising_Report[0].Address[5];
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
break;
|
|
case AD_TYPE_SERVICE_DATA: /* service data 16 bits */
|
|
/* USER CODE BEGIN AD_TYPE_SERVICE_DATA */
|
|
|
|
/* USER CODE END AD_TYPE_SERVICE_DATA */
|
|
break;
|
|
default:
|
|
/* USER CODE BEGIN adtype_default */
|
|
|
|
/* USER CODE END adtype_default */
|
|
break;
|
|
} /* end switch Data[k+adlength] */
|
|
k += adlength + 1;
|
|
} /* end while */
|
|
|
|
} /* end if ADV_IND */
|
|
}
|
|
|
|
break;
|
|
|
|
/* USER CODE BEGIN META_EVT */
|
|
|
|
/* USER CODE END META_EVT */
|
|
|
|
default:
|
|
/* USER CODE BEGIN subevent_default */
|
|
|
|
/* USER CODE END subevent_default */
|
|
break;
|
|
|
|
}
|
|
}
|
|
break; /* HCI_LE_META_EVT_CODE */
|
|
|
|
/* USER CODE BEGIN EVENT_PCKT */
|
|
|
|
/* USER CODE END EVENT_PCKT */
|
|
|
|
default:
|
|
/* USER CODE BEGIN evt_default */
|
|
|
|
/* USER CODE END evt_default */
|
|
break;
|
|
}
|
|
|
|
return (SVCCTL_UserEvtFlowEnable);
|
|
}
|
|
|
|
APP_BLE_ConnStatus_t APP_BLE_Get_Client_Connection_Status( uint16_t Connection_Handle )
|
|
{
|
|
|
|
if (BleApplicationContext.BleApplicationContext_legacy.connectionHandle == Connection_Handle)
|
|
{
|
|
return BleApplicationContext.Device_Connection_Status;
|
|
}
|
|
return APP_BLE_IDLE;
|
|
}
|
|
/* USER CODE BEGIN FD */
|
|
void APP_BLE_Key_Button1_Action(void)
|
|
{
|
|
#if OOB_DEMO == 0
|
|
P2PC_APP_SW1_Button_Action();
|
|
#else
|
|
if(P2P_Client_APP_Get_State () != APP_BLE_CONNECTED_CLIENT)
|
|
{
|
|
UTIL_SEQ_SetTask(1 << CFG_TASK_START_SCAN_ID, CFG_SCH_PRIO_0);
|
|
}
|
|
else
|
|
{
|
|
P2PC_APP_SW1_Button_Action();
|
|
}
|
|
#endif
|
|
}
|
|
/* USER CODE END FD */
|
|
/*************************************************************
|
|
*
|
|
* LOCAL FUNCTIONS
|
|
*
|
|
*************************************************************/
|
|
static void Ble_Tl_Init( void )
|
|
{
|
|
log_debug("Ble_Tl_Init", "start", 0);
|
|
HCI_TL_HciInitConf_t Hci_Tl_Init_Conf;
|
|
|
|
Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&BleCmdBuffer;
|
|
Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot;
|
|
hci_init(BLE_UserEvtRx, (void*) &Hci_Tl_Init_Conf);
|
|
|
|
log_debug("Ble_Tl_Init", "end", 0);
|
|
return;
|
|
}
|
|
|
|
static void Ble_Hci_Gap_Gatt_Init(void){
|
|
|
|
log_debug("Ble_Hci_Gap_Gatt_Init", "start", 0);
|
|
uint8_t role;
|
|
uint16_t gap_service_handle, gap_dev_name_char_handle, gap_appearance_char_handle;
|
|
const uint8_t *bd_addr;
|
|
uint32_t srd_bd_addr[2];
|
|
uint16_t appearance[1] = { BLE_CFG_GAP_APPEARANCE };
|
|
|
|
/**
|
|
* Initialize HCI layer
|
|
*/
|
|
/*HCI Reset to synchronise BLE Stack*/
|
|
hci_reset();
|
|
|
|
/**
|
|
* Write the BD Address
|
|
*/
|
|
|
|
bd_addr = BleGetBdAddress();
|
|
aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
|
|
CONFIG_DATA_PUBADDR_LEN,
|
|
(uint8_t*) bd_addr);
|
|
|
|
/**
|
|
* Static random Address
|
|
* The two upper bits shall be set to 1
|
|
* The lowest 32bits is read from the UDN to differentiate between devices
|
|
* The RNG may be used to provide a random number on each power on
|
|
*/
|
|
srd_bd_addr[1] = 0x0000ED6E;
|
|
srd_bd_addr[0] = LL_FLASH_GetUDN( );
|
|
aci_hal_write_config_data( CONFIG_DATA_RANDOM_ADDRESS_OFFSET, CONFIG_DATA_RANDOM_ADDRESS_LEN, (uint8_t*)srd_bd_addr );
|
|
|
|
/**
|
|
* Write Identity root key used to derive LTK and CSRK
|
|
*/
|
|
aci_hal_write_config_data( CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t*)BLE_CFG_IR_VALUE );
|
|
|
|
/**
|
|
* Write Encryption root key used to derive LTK and CSRK
|
|
*/
|
|
aci_hal_write_config_data( CONFIG_DATA_ER_OFFSET, CONFIG_DATA_ER_LEN, (uint8_t*)BLE_CFG_ER_VALUE );
|
|
|
|
/**
|
|
* Set TX Power to 0dBm.
|
|
*/
|
|
aci_hal_set_tx_power_level(1, CFG_TX_POWER);
|
|
|
|
/**
|
|
* Initialize GATT interface
|
|
*/
|
|
aci_gatt_init();
|
|
|
|
/**
|
|
* Initialize GAP interface
|
|
*/
|
|
role = 0;
|
|
|
|
#if (BLE_CFG_PERIPHERAL == 1)
|
|
role |= GAP_PERIPHERAL_ROLE;
|
|
#endif
|
|
|
|
#if (BLE_CFG_CENTRAL == 1)
|
|
role |= GAP_CENTRAL_ROLE;
|
|
#endif
|
|
|
|
if (role > 0)
|
|
{
|
|
const char *name = "Monsun1";
|
|
|
|
log_debug("Ble_Hci_Gap_Gatt_Init", "aci_gap_init()", 0);
|
|
aci_gap_init(role, 0,
|
|
APPBLE_GAP_DEVICE_NAME_LENGTH,
|
|
&gap_service_handle, &gap_dev_name_char_handle, &gap_appearance_char_handle);
|
|
|
|
if (aci_gatt_update_char_value(gap_service_handle, gap_dev_name_char_handle, 0, strlen(name), (uint8_t *) name))
|
|
{
|
|
BLE_DBG_SVCCTL_MSG("Device Name aci_gatt_update_char_value failed.\n");
|
|
}
|
|
}
|
|
|
|
log_debug("Ble_Hci_Gap_Gatt_Init", "aci_gatt_update_char_value()", 0);
|
|
if(aci_gatt_update_char_value(gap_service_handle,
|
|
gap_appearance_char_handle,
|
|
0,
|
|
2,
|
|
(uint8_t *)&appearance))
|
|
{
|
|
BLE_DBG_SVCCTL_MSG("Appearance aci_gatt_update_char_value failed.\n");
|
|
}
|
|
|
|
/**
|
|
* Initialize IO capability
|
|
*/
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability = CFG_IO_CAPABILITY;
|
|
aci_gap_set_io_capability(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability);
|
|
|
|
/**
|
|
* Initialize authentication
|
|
*/
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode = CFG_MITM_PROTECTION;
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin = CFG_ENCRYPTION_KEY_SIZE_MIN;
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax = CFG_ENCRYPTION_KEY_SIZE_MAX;
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin = CFG_USED_FIXED_PIN;
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin = CFG_FIXED_PIN;
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode = CFG_BONDING_MODE;
|
|
|
|
log_debug("Ble_Hci_Gap_Gatt_Init", "aci_gap_set_authentication_requirement()", 0);
|
|
aci_gap_set_authentication_requirement(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode,
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode,
|
|
CFG_SC_SUPPORT,
|
|
CFG_KEYPRESS_NOTIFICATION_SUPPORT,
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin,
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax,
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin,
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin,
|
|
PUBLIC_ADDR
|
|
);
|
|
|
|
/**
|
|
* Initialize whitelist
|
|
*/
|
|
if (BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode)
|
|
{
|
|
log_debug("Ble_Hci_Gap_Gatt_Init", "aci_gap_configure_whitelist()", 0);
|
|
aci_gap_configure_whitelist();
|
|
}
|
|
|
|
log_debug("Ble_Hci_Gap_Gatt_Init", "end", 0);
|
|
}
|
|
|
|
static void Scan_Request( void )
|
|
{
|
|
/* USER CODE BEGIN Scan_Request_1 */
|
|
|
|
log_debug("Scan_Request", "start", 0);
|
|
/* USER CODE END Scan_Request_1 */
|
|
tBleStatus result;
|
|
if (BleApplicationContext.Device_Connection_Status != APP_BLE_CONNECTED_CLIENT)
|
|
{
|
|
/* USER CODE BEGIN APP_BLE_CONNECTED_CLIENT */
|
|
|
|
/* USER CODE END APP_BLE_CONNECTED_CLIENT */
|
|
log_debug("Scan_Request", "aci_gap_start_general_discovery_proc()", 0);
|
|
result = aci_gap_start_general_discovery_proc(SCAN_P, SCAN_L, PUBLIC_ADDR, 1);
|
|
if (result == BLE_STATUS_SUCCESS)
|
|
{
|
|
/* USER CODE BEGIN BLE_SCAN_SUCCESS */
|
|
|
|
/* USER CODE END BLE_SCAN_SUCCESS */
|
|
log_debug("Scan_Request", "** START GENERAL DISCOVERY (SCAN) **", 0);
|
|
}
|
|
else
|
|
{
|
|
/* USER CODE BEGIN BLE_SCAN_FAILED */
|
|
|
|
/* USER CODE END BLE_SCAN_FAILED */
|
|
log_debug("Scan_Request", "-- BLE_App_Start_Limited_Disc_Req, Failed ", 0);
|
|
}
|
|
}
|
|
/* USER CODE BEGIN Scan_Request_2 */
|
|
|
|
/* USER CODE END Scan_Request_2 */
|
|
return;
|
|
}
|
|
|
|
static void Connect_Request( void )
|
|
{
|
|
/* USER CODE BEGIN Connect_Request_1 */
|
|
|
|
log_debug("Connect_Request", "start", 0);
|
|
/* USER CODE END Connect_Request_1 */
|
|
tBleStatus result;
|
|
|
|
log_debug("Connect_Request", "** CREATE CONNECTION TO SERVER **", 0);
|
|
|
|
if (BleApplicationContext.Device_Connection_Status != APP_BLE_CONNECTED_CLIENT)
|
|
{
|
|
log_debug("Connect_Request", "aci_gap_create_connection()", 0);
|
|
result = aci_gap_create_connection(SCAN_P,
|
|
SCAN_L,
|
|
PUBLIC_ADDR, SERVER_REMOTE_BDADDR,
|
|
PUBLIC_ADDR,
|
|
CONN_P1,
|
|
CONN_P2,
|
|
0,
|
|
SUPERV_TIMEOUT,
|
|
CONN_L1,
|
|
CONN_L2);
|
|
|
|
if (result == BLE_STATUS_SUCCESS)
|
|
{
|
|
/* USER CODE BEGIN BLE_CONNECT_SUCCESS */
|
|
|
|
/* USER CODE END BLE_CONNECT_SUCCESS */
|
|
log_debug("Device_Connection_Status", "APP_BLE_LP_CONNECTING", 0);
|
|
BleApplicationContext.Device_Connection_Status = APP_BLE_LP_CONNECTING;
|
|
|
|
}
|
|
else
|
|
{
|
|
/* USER CODE BEGIN BLE_CONNECT_FAILED */
|
|
|
|
/* USER CODE END BLE_CONNECT_FAILED */
|
|
log_error("Connect_Request", "Connection failed", 0);
|
|
log_debug("Device_Connection_Status", "APP_BLE_IDLE", 0);
|
|
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
|
|
|
|
}
|
|
}
|
|
/* USER CODE BEGIN Connect_Request_2 */
|
|
|
|
/* USER CODE END Connect_Request_2 */
|
|
return;
|
|
}
|
|
|
|
static void Switch_OFF_GPIO(){
|
|
/* USER CODE BEGIN Switch_OFF_GPIO */
|
|
|
|
log_debug("Switch_OFF_GPIO", "start/end", 0);
|
|
/* USER CODE END Switch_OFF_GPIO */
|
|
}
|
|
|
|
const uint8_t* BleGetBdAddress( void )
|
|
{
|
|
log_debug("BleGetBdAddress", "start", 0);
|
|
uint8_t *otp_addr;
|
|
const uint8_t *bd_addr;
|
|
uint32_t udn;
|
|
uint32_t company_id;
|
|
uint32_t device_id;
|
|
|
|
udn = LL_FLASH_GetUDN();
|
|
|
|
if(udn != 0xFFFFFFFF)
|
|
{
|
|
company_id = LL_FLASH_GetSTCompanyID();
|
|
device_id = LL_FLASH_GetDeviceID();
|
|
|
|
/**
|
|
* Public Address with the ST company ID
|
|
* bit[47:24] : 24bits (OUI) equal to the company ID
|
|
* bit[23:16] : Device ID.
|
|
* bit[15:0] : The last 16bits from the UDN
|
|
* Note: In order to use the Public Address in a final product, a dedicated
|
|
* 24bits company ID (OUI) shall be bought.
|
|
*/
|
|
bd_addr_udn[0] = (uint8_t)(udn & 0x000000FF);
|
|
bd_addr_udn[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 );
|
|
bd_addr_udn[2] = (uint8_t)device_id;
|
|
bd_addr_udn[3] = (uint8_t)(company_id & 0x000000FF);
|
|
bd_addr_udn[4] = (uint8_t)( (company_id & 0x0000FF00) >> 8 );
|
|
bd_addr_udn[5] = (uint8_t)( (company_id & 0x00FF0000) >> 16 );
|
|
|
|
bd_addr = (const uint8_t *)bd_addr_udn;
|
|
}
|
|
else
|
|
{
|
|
otp_addr = OTP_Read(0);
|
|
if(otp_addr)
|
|
{
|
|
bd_addr = ((OTP_ID0_t*)otp_addr)->bd_address;
|
|
}
|
|
else
|
|
{
|
|
bd_addr = M_bd_addr;
|
|
}
|
|
}
|
|
|
|
log_debug("BleGetBdAddress", "end", 0);
|
|
return bd_addr;
|
|
}
|
|
/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */
|
|
|
|
/* USER CODE END FD_LOCAL_FUNCTIONS */
|
|
/*************************************************************
|
|
*
|
|
* WRAP FUNCTIONS
|
|
*
|
|
*************************************************************/
|
|
void hci_notify_asynch_evt(void* pdata)
|
|
{
|
|
UTIL_SEQ_SetTask(1 << CFG_TASK_HCI_ASYNCH_EVT_ID, CFG_SCH_PRIO_0);
|
|
return;
|
|
}
|
|
|
|
void hci_cmd_resp_release(uint32_t flag)
|
|
{
|
|
UTIL_SEQ_SetEvt(1 << CFG_IDLEEVT_HCI_CMD_EVT_RSP_ID);
|
|
return;
|
|
}
|
|
|
|
void hci_cmd_resp_wait(uint32_t timeout)
|
|
{
|
|
UTIL_SEQ_WaitEvt(1 << CFG_IDLEEVT_HCI_CMD_EVT_RSP_ID);
|
|
return;
|
|
}
|
|
|
|
static void BLE_UserEvtRx( void * pPayload )
|
|
{
|
|
// log_debug("BLE_UserEvtRx", "start", 0);
|
|
SVCCTL_UserEvtFlowStatus_t svctl_return_status;
|
|
tHCI_UserEvtRxParam *pParam;
|
|
|
|
pParam = (tHCI_UserEvtRxParam *)pPayload;
|
|
|
|
svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial));
|
|
if (svctl_return_status != SVCCTL_UserEvtFlowDisable)
|
|
{
|
|
pParam->status = HCI_TL_UserEventFlow_Enable;
|
|
}
|
|
else
|
|
{
|
|
pParam->status = HCI_TL_UserEventFlow_Disable;
|
|
}
|
|
// log_debug("BLE_UserEvtRx", "end", 0);
|
|
}
|
|
|
|
static void BLE_StatusNot( HCI_TL_CmdStatus_t status )
|
|
{
|
|
// log_debug("BLE_StatusNot", "start", 0);
|
|
uint32_t task_id_list;
|
|
switch (status)
|
|
{
|
|
case HCI_TL_CmdBusy:
|
|
/**
|
|
* All tasks that may send an aci/hci commands shall be listed here
|
|
* This is to prevent a new command is sent while one is already pending
|
|
*/
|
|
task_id_list = (1 << CFG_LAST_TASK_ID_WITH_HCICMD) - 1;
|
|
UTIL_SEQ_PauseTask(task_id_list);
|
|
|
|
break;
|
|
|
|
case HCI_TL_CmdAvailable:
|
|
/**
|
|
* All tasks that may send an aci/hci commands shall be listed here
|
|
* This is to prevent a new command is sent while one is already pending
|
|
*/
|
|
task_id_list = (1 << CFG_LAST_TASK_ID_WITH_HCICMD) - 1;
|
|
UTIL_SEQ_ResumeTask(task_id_list);
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
// log_debug("BLE_StatusNot", "end", 0);
|
|
return;
|
|
}
|
|
|
|
void SVCCTL_ResumeUserEventFlow( void )
|
|
{
|
|
hci_resume_flow();
|
|
return;
|
|
}
|
|
|
|
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
|
|
|
|
/* USER CODE END FD_WRAP_FUNCTIONS */
|
|
|
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
|