blob: 4200191a38a0e9ffb879c95da05ffaec65dbc14b [file] [log] [blame]
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file app_ble.c
* @author MCD Application Team
* @brief BLE Application
******************************************************************************
* @attention
*
* Copyright (c) 2019-2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "app_ble.h"
#include "ble.h"
#include "dbg_trace.h"
#include "tl.h"
#include "app_matter.h"
#include "cmsis_os.h"
#include "otp.h"
#include "shci.h"
#include "stm32_lpm.h"
#include "timers.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* 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;
/**
* Flag to tell whether OOB data has
* to be used during the pairing process
*/
uint8_t OOB_Data_Present;
/**
* OOB data to be used in the pairing process if
* OOB_Data_Present is set to TRUE
*/
uint8_t OOB_Data[16];
/**
* 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;
/**
* ID of the Advertising Timeout
*/
uint8_t Advertising_mgr_timer_Id;
uint8_t SwitchOffGPIO_timer_Id;
} BleApplicationContext_t;
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private defines -----------------------------------------------------------*/
#define APPBLE_GAP_DEVICE_NAME_LENGTH 7
#define FAST_ADV_TIMEOUT (30 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 30s */
#define INITIAL_ADV_TIMEOUT (60 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 60s */
#define BD_ADDR_SIZE_LOCAL 6
/* USER CODE BEGIN PD */
#define LED_ON_TIMEOUT (0.005 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 5ms */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
osMutexId_t MtxHciId;
osSemaphoreId_t SemHciId;
osThreadId_t HciUserEvtProcessId;
// FreeeRTOS sw timer
TimerHandle_t sbleWorkaroundAdvTimeoutTimer;
const osThreadAttr_t HciUserEvtProcess_attr = { .name = CFG_HCI_USER_EVT_PROCESS_NAME,
.attr_bits = CFG_HCI_USER_EVT_PROCESS_ATTR_BITS,
.cb_mem = CFG_HCI_USER_EVT_PROCESS_CB_MEM,
.cb_size = CFG_HCI_USER_EVT_PROCESS_CB_SIZE,
.stack_mem = CFG_HCI_USER_EVT_PROCESS_STACK_MEM,
.priority = CFG_HCI_USER_EVT_PROCESS_PRIORITY,
.stack_size = CFG_HCI_USER_EVT_PROCESS_STACK_SIZE };
/* 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;
PLACE_IN_SECTION("BLE_APP_CONTEXT") static BleApplicationContext_t BleApplicationContext;
PLACE_IN_SECTION("BLE_APP_CONTEXT") static uint16_t AdvIntervalMin, AdvIntervalMax;
MATTER_App_Notification_evt_t handleNotification;
#if L2CAP_REQUEST_NEW_CONN_PARAM != 0
#define SIZE_TAB_CONN_INT 2
float tab_conn_interval[SIZE_TAB_CONN_INT] = { 50, 1000 }; /* ms */
uint8_t index_con_int, mutex;
#endif
/**
* Advertising Data
*/
static const char local_name[] = { AD_TYPE_COMPLETE_LOCAL_NAME, 'S', 'T', 'D', 'K', 'M', 'A', 'T', 'T', 'E', 'R' };
uint8_t manuf_data[15] = {
0x02, 0x01, 0x06, 0x0B, 0x16, 0xF6, 0xFF, 0x00, 0x00, 0x0F, 0xF1, 0xFF, 0x04, 0x80, 0x00,
};
/* 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 Switch_OFF_GPIO(void);
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
static void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle);
#endif
static void HciUserEvtProcess(void * argument);
void BleAdvWorkaroundTimeoutHandler(TimerHandle_t xTimer);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Functions Definition ------------------------------------------------------*/
void APP_BLE_Init_Dyn_1(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);
MtxHciId = osMutexNew(NULL);
SemHciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */
/**
* Register the hci transport layer to handle BLE User Asynchronous Events
*/
HciUserEvtProcessId = osThreadNew(HciUserEvtProcess, NULL, &HciUserEvtProcess_attr);
/**
* Starts the BLE Stack on CPU2
*/
SHCI_C2_BLE_Init(&ble_init_cmd_packet);
/**
* Initialization of HCI & GATT & GAP layer
*/
Ble_Hci_Gap_Gatt_Init();
/**
* Initialization of the BLE Services
*/
SVCCTL_Init();
/**
* Initialization of the BLE App Context
*/
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0xFFFF;
/**
* Initialization of ADV - Ad Manufacturer Element - Support OTA Bit Mask
*/
#if (RADIO_ACTIVITY_EVENT != 0)
aci_hal_set_radio_activity_mask(0x0006);
#endif
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
index_con_int = 0;
mutex = 1;
#endif
/**
* Initialize P2P Server Application
*/
APP_MATTER_Init();
/**
* Create timer to handle the Led Switch OFF
*/
HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(BleApplicationContext.SwitchOffGPIO_timer_Id), hw_ts_SingleShot, Switch_OFF_GPIO);
}
void APP_BLE_Init_Dyn_2(void)
{
/**
* Make device discoverable
*/
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = NULL;
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 0;
/* Initialize intervals for reconnexion without intervals update */
AdvIntervalMin = CFG_FAST_CONN_ADV_INTERVAL_MIN;
AdvIntervalMax = CFG_FAST_CONN_ADV_INTERVAL_MAX;
/* USER CODE BEGIN APP_BLE_Init_2 */
/* USER CODE END APP_BLE_Init_2 */
}
void APP_BLE_Init_Dyn_3(void)
{
sbleWorkaroundAdvTimeoutTimer = xTimerCreate("BleAdvWorkaroundTimer", // Just a text name, not used by the RTOS kernel
pdMS_TO_TICKS(2000), // == default timer period (mS)
0, // no timer reload (==one-shot)
NULL, // init timer id = ble obj context
BleAdvWorkaroundTimeoutHandler // timer callback handler
);
if (xTimerStart(sbleWorkaroundAdvTimeoutTimer, 0) != pdPASS)
{
/* The timer could not be set into the Active
state. */
}
APP_BLE_Adv_Request(APP_BLE_FAST_ADV);
}
SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void * pckt)
{
hci_event_pckt * event_pckt;
evt_le_meta_event * meta_evt;
event_pckt = (hci_event_pckt *) ((hci_uart_pckt *) pckt)->data;
switch (event_pckt->evt)
{
case HCI_DISCONNECTION_COMPLETE_EVT_CODE: {
hci_disconnection_complete_event_rp0 * disconnection_complete_event;
disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data;
if (disconnection_complete_event->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 CLIENT \n");
}
/*
* SPECIFIC to P2P Server APP
*/
handleNotification.P2P_Evt_Opcode = MATTER_STM_PEER_DISCON_HANDLE_EVT;
handleNotification.ConnectionHandle = disconnection_complete_event->Connection_Handle;
APP_MATTER_Notification(&handleNotification);
/* USER CODE BEGIN EVT_DISCONN_COMPLETE */
/* USER CODE END EVT_DISCONN_COMPLETE */
}
break; /* EVT_DISCONN_COMPLETE */
case HCI_LE_META_EVT_CODE: {
meta_evt = (evt_le_meta_event *) event_pckt->data;
/* USER CODE BEGIN EVT_LE_META_EVENT */
/* USER CODE END EVT_LE_META_EVENT */
switch (meta_evt->subevent)
{
case HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE:
APP_DBG_MSG("\r\n\r** CONNECTION UPDATE EVENT WITH CLIENT \n");
/**
* The connection is done, there is no need anymore to schedule the LP ADV
*/
break;
case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE: {
hci_le_connection_complete_event_rp0 * connection_complete_event;
/**
* The connection is done, there is no need anymore to schedule the LP ADV
*/
connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data;
// HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id);
APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\n", connection_complete_event->Connection_Handle);
if (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_CONNECTING)
{
/* Connection as client */
BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_CLIENT;
}
else
{
/* Connection as server */
BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_SERVER;
}
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = connection_complete_event->Connection_Handle;
/** SPECIFIC to P2P Server APP*/
hci_le_set_data_length(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, 251, 2120);
handleNotification.P2P_Evt_Opcode = MATTER_STM_PEER_CONN_HANDLE_EVT;
handleNotification.ConnectionHandle = BleApplicationContext.BleApplicationContext_legacy.connectionHandle;
APP_MATTER_Notification(&handleNotification);
/**/
/* USER CODE END HCI_EVT_LE_CONN_COMPLETE */
}
break; /* HCI_EVT_LE_CONN_COMPLETE */
default:
/* USER CODE BEGIN SUBEVENT_DEFAULT */
/* USER CODE END SUBEVENT_DEFAULT */
break;
}
}
break; /* HCI_EVT_LE_META_EVENT */
default:
/* USER CODE BEGIN ECODE_DEFAULT*/
/* USER CODE END ECODE_DEFAULT*/
break;
}
return (SVCCTL_UserEvtFlowEnable);
}
APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status(void)
{
return BleApplicationContext.Device_Connection_Status;
}
void APP_BLE_Key_Button2_Action(void)
{
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
if (BleApplicationContext.Device_Connection_Status != APP_BLE_FAST_ADV &&
BleApplicationContext.Device_Connection_Status != APP_BLE_IDLE)
{
BLE_SVC_L2CAP_Conn_Update(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
}
return;
#endif
}
void APP_BLE_Key_Button3_Action(void) {}
void APP_BLE_Stop(void)
{
/* Stop Advertising Timer */
// HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id);
// HW_TS_Delete(BleApplicationContext.Advertising_mgr_timer_Id);
/* BLE STOP Procedure */
aci_hal_stack_reset();
}
/* USER CODE END FD*/
/*************************************************************
*
* LOCAL FUNCTIONS
*
*************************************************************/
static void Ble_Tl_Init(void)
{
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);
return;
}
static void Ble_Hci_Gap_Gatt_Init(void)
{
uint8_t role;
uint8_t index;
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);
/* BLE MAC in ADV Packet */
// manuf_data[ sizeof(manuf_data)-6] = bd_addr[5];
// manuf_data[ sizeof(manuf_data)-5] = bd_addr[4];
// manuf_data[ sizeof(manuf_data)-4] = bd_addr[3];
// manuf_data[ sizeof(manuf_data)-3] = bd_addr[2];
// manuf_data[ sizeof(manuf_data)-2] = bd_addr[1];
// manuf_data[ sizeof(manuf_data)-1] = bd_addr[0];
//
/**
* 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 = "STM32WB";
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");
}
}
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 Default PHY
*/
hci_le_set_default_phy(ALL_PHYS_PREFERENCE, TX_2M_PREFERRED, RX_2M_PREFERRED);
/**
* 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.OOB_Data_Present = 0;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin = 8;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax = 16;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin = 1;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin = 111111;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode = 1;
for (index = 0; index < 16; index++)
{
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.OOB_Data[index] = (uint8_t) index;
}
aci_gap_set_authentication_requirement(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode, 1, 0,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin, 0);
/**
* Initialize whitelist
*/
if (BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode)
{
aci_gap_configure_whitelist();
}
}
void APP_BLE_Adv_Request(APP_BLE_ConnStatus_t New_Status)
{
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
uint16_t Min_Inter, Max_Inter;
if (New_Status == APP_BLE_FAST_ADV)
{
Min_Inter = AdvIntervalMin;
Max_Inter = AdvIntervalMax;
}
else
{
Min_Inter = CFG_LP_CONN_ADV_INTERVAL_MIN;
Max_Inter = CFG_LP_CONN_ADV_INTERVAL_MAX;
}
APP_DBG_MSG("First index in %d state \n", BleApplicationContext.Device_Connection_Status);
if ((New_Status == APP_BLE_LP_ADV) &&
((BleApplicationContext.Device_Connection_Status == APP_BLE_FAST_ADV) ||
(BleApplicationContext.Device_Connection_Status == APP_BLE_LP_ADV)))
{
/* Connection in ADVERTISE mode have to stop the current advertising */
ret = aci_gap_set_non_discoverable();
if (ret == BLE_STATUS_SUCCESS)
{
APP_DBG_MSG("Successfully Stopped Advertising");
}
else
{
APP_DBG_MSG("Stop Advertising Failed , result: %d \n", ret);
}
}
BleApplicationContext.Device_Connection_Status = New_Status;
/* Start Fast or Low Power Advertising */
ret = aci_gap_set_discoverable(ADV_IND, Min_Inter, Max_Inter, GAP_PUBLIC_ADDR, NO_WHITE_LIST_USE, /* use white list */
sizeof(local_name), (uint8_t *) &local_name,
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen,
BleApplicationContext.BleApplicationContext_legacy.advtServUUID, 0, 0);
/* Update Advertising data */
ret = aci_gap_update_adv_data(sizeof(manuf_data), (uint8_t *) manuf_data);
APP_DBG_MSG("check set discoverable , result: %d \n", ret);
if (ret == BLE_STATUS_SUCCESS)
{
if (New_Status == APP_BLE_FAST_ADV)
{
APP_DBG_MSG("Successfully Start Fast Advertising \n");
}
else
{
APP_DBG_MSG("Successfully Start Low Power Advertising \n");
}
}
else
{
if (New_Status == APP_BLE_FAST_ADV)
{
APP_DBG_MSG("Start Fast Advertising Failed , result: %d \n", ret);
}
else
{
APP_DBG_MSG("Start Low Power Advertising Failed , result: %d \n", ret);
}
}
return;
}
const uint8_t * BleGetBdAddress(void)
{
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;
}
}
return bd_addr;
}
/* USER CODE BEGIN FD_LOCAL_FUNCTION */
/* USER CODE END FD_LOCAL_FUNCTION */
/*************************************************************
*
*SPECIFIC FUNCTIONS FOR P2P SERVER
*
*************************************************************/
void BleAdvWorkaroundTimeoutHandler(TimerHandle_t xTimer)
{
APP_BLE_Adv_Cancel();
}
void APP_BLE_Adv_Cancel(void)
{
/* USER CODE BEGIN Adv_Cancel_1 */
// BSP_LED_Off(LED_GREEN);
/* USER CODE END Adv_Cancel_1 */
if (BleApplicationContext.Device_Connection_Status != APP_BLE_CONNECTED_SERVER)
{
tBleStatus result = 0x00;
result = aci_gap_set_non_discoverable();
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
if (result == BLE_STATUS_SUCCESS)
{
APP_DBG_MSG(" \r\n\r");
APP_DBG_MSG("** STOP ADVERTISING ** \r\n\r");
}
else
{
APP_DBG_MSG("** STOP ADVERTISING ** Failed \r\n\r");
}
}
/* USER CODE BEGIN Adv_Cancel_2 */
/* USER CODE END Adv_Cancel_2 */
return;
}
static void Switch_OFF_GPIO()
{
/* USER CODE BEGIN Switch_OFF_GPIO */
// BSP_LED_Off(LED_GREEN);
/* USER CODE END Switch_OFF_GPIO */
}
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle)
{
/* USER CODE BEGIN BLE_SVC_L2CAP_Conn_Update_1 */
/* USER CODE END BLE_SVC_L2CAP_Conn_Update_1 */
if (mutex == 1)
{
mutex = 0;
index_con_int = (index_con_int + 1) % SIZE_TAB_CONN_INT;
uint16_t interval_min = CONN_P(tab_conn_interval[index_con_int]);
uint16_t interval_max = CONN_P(tab_conn_interval[index_con_int]);
uint16_t slave_latency = L2CAP_SLAVE_LATENCY;
uint16_t timeout_multiplier = L2CAP_TIMEOUT_MULTIPLIER;
tBleStatus result;
result = aci_l2cap_connection_parameter_update_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,
interval_min, interval_max, slave_latency, timeout_multiplier);
if (result == BLE_STATUS_SUCCESS)
{
APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Successfully \r\n\r");
}
else
{
APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Failed \r\n\r");
}
}
/* USER CODE BEGIN BLE_SVC_L2CAP_Conn_Update_2 */
/* USER CODE END BLE_SVC_L2CAP_Conn_Update_2 */
return;
}
#endif
/* USER CODE BEGIN FD_SPECIFIC_FUNCTIONS */
/* USER CODE END FD_SPECIFIC_FUNCTIONS */
/*************************************************************
*
* WRAP FUNCTIONS
*
*************************************************************/
static void HciUserEvtProcess(void * argument)
{
UNUSED(argument);
for (;;)
{
osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever);
hci_user_evt_proc();
}
}
void hci_notify_asynch_evt(void * pdata)
{
osThreadFlagsSet(HciUserEvtProcessId, 1);
return;
}
void hci_cmd_resp_release(uint32_t flag)
{
osSemaphoreRelease(SemHciId);
return;
}
void hci_cmd_resp_wait(uint32_t timeout)
{
osSemaphoreAcquire(SemHciId, osWaitForever);
return;
}
static void BLE_UserEvtRx(void * pPayload)
{
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;
}
}
static void BLE_StatusNot(HCI_TL_CmdStatus_t status)
{
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
*/
osMutexAcquire(MtxHciId, osWaitForever);
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
*/
osMutexRelease(MtxHciId);
break;
default:
break;
}
return;
}
void SVCCTL_ResumeUserEventFlow(void)
{
hci_resume_flow();
return;
}
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
/* USER CODE END FD_WRAP_FUNCTIONS */