1258 lines
39 KiB
C
1258 lines
39 KiB
C
/* USER CODE BEGIN Header */
|
|
/**
|
|
******************************************************************************
|
|
* @file App/app_ble.c
|
|
* @author MCD Application Team
|
|
* @brief BLE Application
|
|
*****************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2026 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 "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 "custom_app.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;
|
|
|
|
/**
|
|
* minimum encryption key size requirement
|
|
*/
|
|
uint8_t encryptionKeySizeMin;
|
|
|
|
/**
|
|
* maximum encryption key size requirement
|
|
*/
|
|
uint8_t encryptionKeySizeMax;
|
|
|
|
/**
|
|
* this flag indicates whether the host has to initiate
|
|
* the security, wait for pairing or does not have any security
|
|
* requirements.
|
|
* 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;
|
|
/* USER CODE BEGIN tSecurityParams*/
|
|
|
|
/* USER CODE END tSecurityParams */
|
|
}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];
|
|
/* USER CODE BEGIN BleGlobalContext_t*/
|
|
|
|
/* USER CODE END BleGlobalContext_t */
|
|
}BleGlobalContext_t;
|
|
|
|
typedef struct
|
|
{
|
|
BleGlobalContext_t BleApplicationContext_legacy;
|
|
APP_BLE_ConnStatus_t Device_Connection_Status;
|
|
/* USER CODE BEGIN PTD_1*/
|
|
|
|
/* USER CODE END PTD_1 */
|
|
}BleApplicationContext_t;
|
|
|
|
/* USER CODE BEGIN PTD */
|
|
|
|
/* USER CODE END PTD */
|
|
|
|
/* Private defines -----------------------------------------------------------*/
|
|
#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
|
|
#define BLE_DEFAULT_PIN (111111)
|
|
|
|
/* USER CODE BEGIN PD */
|
|
|
|
/* USER CODE END PD */
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* 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 a_MBdAddr[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 a_BdAddrUdn[BD_ADDR_SIZE_LOCAL];
|
|
|
|
/**
|
|
* Identity root key used to derive IRK and DHK(Legacy)
|
|
*/
|
|
static const uint8_t a_BLE_CfgIrValue[16] = CFG_BLE_IR;
|
|
|
|
/**
|
|
* Encryption root key used to derive LTK(Legacy) and CSRK
|
|
*/
|
|
static const uint8_t a_BLE_CfgErValue[16] = CFG_BLE_ER;
|
|
|
|
/**
|
|
* These are the two tags used to manage a power failure during OTA
|
|
* The MagicKeywordAdress shall be mapped @0x140 from start of the binary image
|
|
* The MagicKeywordvalue is checked in the ble_ota application
|
|
*/
|
|
PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ;
|
|
PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue;
|
|
|
|
static BleApplicationContext_t BleApplicationContext;
|
|
|
|
Custom_App_ConnHandle_Not_evt_t HandleNotification;
|
|
|
|
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
|
|
#define SIZE_TAB_CONN_INT 2
|
|
float a_ConnInterval[SIZE_TAB_CONN_INT] = {50, 1000}; /* ms */
|
|
uint8_t index_con_int, mutex;
|
|
#endif /* L2CAP_REQUEST_NEW_CONN_PARAM != 0 */
|
|
|
|
/**
|
|
* Advertising Data
|
|
*/
|
|
uint8_t a_AdvData[10] =
|
|
{
|
|
9, AD_TYPE_COMPLETE_LOCAL_NAME, 'X', 'X', '-', 'S', 'T', 'M', '3', '2', /* Complete name */
|
|
|
|
};
|
|
|
|
/* USER CODE BEGIN PV */
|
|
|
|
/* USER CODE END PV */
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
static void BLE_UserEvtRx(void *p_Payload);
|
|
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 Adv_Request(APP_BLE_ConnStatus_t NewStatus);
|
|
static void Adv_Cancel(void);
|
|
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
|
|
static void BLE_SVC_L2CAP_Conn_Update(uint16_t ConnectionHandle);
|
|
static void Connection_Interval_Update_Req(void);
|
|
#endif /* L2CAP_REQUEST_NEW_CONN_PARAM != 0 */
|
|
|
|
/* USER CODE BEGIN PFP */
|
|
|
|
/* USER CODE END PFP */
|
|
|
|
/* External variables --------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN EV */
|
|
|
|
/* USER CODE END EV */
|
|
|
|
/* Functions Definition ------------------------------------------------------*/
|
|
void APP_BLE_Init(void)
|
|
{
|
|
SHCI_CmdStatus_t status;
|
|
#if (RADIO_ACTIVITY_EVENT != 0)
|
|
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
|
|
#endif /* RADIO_ACTIVITY_EVENT != 0 */
|
|
/* 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_PERIPHERAL_SCA,
|
|
CFG_BLE_CENTRAL_SCA,
|
|
CFG_BLE_LS_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,
|
|
CFG_BLE_RX_MODEL_CONFIG,
|
|
CFG_BLE_MAX_ADV_SET_NBR,
|
|
CFG_BLE_MAX_ADV_DATA_LEN,
|
|
CFG_BLE_TX_PATH_COMPENS,
|
|
CFG_BLE_RX_PATH_COMPENS,
|
|
CFG_BLE_CORE_VERSION,
|
|
CFG_BLE_OPTIONS_EXT,
|
|
CFG_BLE_MAX_ADD_EATT_BEARERS
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Initialize Ble Transport Layer
|
|
*/
|
|
Ble_Tl_Init();
|
|
|
|
#if (CFG_LPM_STANDBY_SUPPORTED == 0)
|
|
UTIL_LPM_SetOffMode(1U << CFG_LPM_APP_BLE, UTIL_LPM_DISABLE);
|
|
#endif /* CFG_LPM_STANDBY_SUPPORTED == 0 */
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
status = SHCI_C2_BLE_Init(&ble_init_cmd_packet);
|
|
if (status != SHCI_Success)
|
|
{
|
|
APP_DBG_MSG(" Fail : SHCI_C2_BLE_Init command, result: 0x%02x\n\r", status);
|
|
/* if you are here, maybe CPU2 doesn't contain STM32WB_Copro_Wireless_Binaries, see Release_Notes.html */
|
|
Error_Handler();
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: SHCI_C2_BLE_Init command\n\r");
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* From here, all initialization are BLE application specific
|
|
*/
|
|
|
|
UTIL_SEQ_RegTask(1<<CFG_TASK_ADV_CANCEL_ID, UTIL_SEQ_RFU, Adv_Cancel);
|
|
|
|
/* USER CODE BEGIN APP_BLE_Init_4 */
|
|
|
|
/* USER CODE END APP_BLE_Init_4 */
|
|
|
|
/**
|
|
* Initialization of ADV - Ad Manufacturer Element - Support OTA Bit Mask
|
|
*/
|
|
#if (RADIO_ACTIVITY_EVENT != 0)
|
|
ret = aci_hal_set_radio_activity_mask(0x0006);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_hal_set_radio_activity_mask command, result: 0x%x \n\r", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_hal_set_radio_activity_mask command\n\r");
|
|
}
|
|
#endif /* RADIO_ACTIVITY_EVENT != 0 */
|
|
|
|
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
|
|
index_con_int = 0;
|
|
mutex = 1;
|
|
#endif /* L2CAP_REQUEST_NEW_CONN_PARAM != 0 */
|
|
|
|
/**
|
|
* Initialize Custom Template Application
|
|
*/
|
|
Custom_APP_Init();
|
|
|
|
/* USER CODE BEGIN APP_BLE_Init_3 */
|
|
|
|
/* USER CODE END APP_BLE_Init_3 */
|
|
|
|
/**
|
|
* Make device discoverable
|
|
*/
|
|
BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = NULL;
|
|
BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 0;
|
|
|
|
/**
|
|
* Start to Advertise to be connected by a Client
|
|
*/
|
|
Adv_Request(APP_BLE_FAST_ADV);
|
|
|
|
/* USER CODE BEGIN APP_BLE_Init_2 */
|
|
|
|
/* USER CODE END APP_BLE_Init_2 */
|
|
|
|
return;
|
|
}
|
|
|
|
SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void *p_Pckt)
|
|
{
|
|
hci_event_pckt *p_event_pckt;
|
|
evt_le_meta_event *p_meta_evt;
|
|
evt_blecore_aci *p_blecore_evt;
|
|
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
|
|
hci_le_connection_complete_event_rp0 *p_connection_complete_event;
|
|
hci_disconnection_complete_event_rp0 *p_disconnection_complete_event;
|
|
#if (CFG_DEBUG_APP_TRACE != 0)
|
|
hci_le_connection_update_complete_event_rp0 *p_connection_update_complete_event;
|
|
#endif /* CFG_DEBUG_APP_TRACE != 0 */
|
|
|
|
/* PAIRING */
|
|
aci_gap_pairing_complete_event_rp0 *p_pairing_complete;
|
|
/* PAIRING */
|
|
|
|
/* USER CODE BEGIN SVCCTL_App_Notification */
|
|
|
|
/* USER CODE END SVCCTL_App_Notification */
|
|
|
|
p_event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) p_Pckt)->data;
|
|
|
|
switch (p_event_pckt->evt)
|
|
{
|
|
case HCI_DISCONNECTION_COMPLETE_EVT_CODE:
|
|
{
|
|
p_disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) p_event_pckt->data;
|
|
|
|
if (p_disconnection_complete_event->Connection_Handle == BleApplicationContext.BleApplicationContext_legacy.connectionHandle)
|
|
{
|
|
BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0;
|
|
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
|
|
APP_DBG_MSG(">>== HCI_DISCONNECTION_COMPLETE_EVT_CODE\n");
|
|
APP_DBG_MSG(" - Connection Handle: 0x%x\n - Reason: 0x%x\n\r",
|
|
p_disconnection_complete_event->Connection_Handle,
|
|
p_disconnection_complete_event->Reason);
|
|
|
|
/* USER CODE BEGIN EVT_DISCONN_COMPLETE_2 */
|
|
|
|
/* USER CODE END EVT_DISCONN_COMPLETE_2 */
|
|
}
|
|
|
|
/* USER CODE BEGIN EVT_DISCONN_COMPLETE_1 */
|
|
|
|
/* USER CODE END EVT_DISCONN_COMPLETE_1 */
|
|
|
|
/* restart advertising */
|
|
Adv_Request(APP_BLE_FAST_ADV);
|
|
|
|
/**
|
|
* SPECIFIC to Custom Template APP
|
|
*/
|
|
HandleNotification.Custom_Evt_Opcode = CUSTOM_DISCON_HANDLE_EVT;
|
|
HandleNotification.ConnectionHandle = BleApplicationContext.BleApplicationContext_legacy.connectionHandle;
|
|
Custom_APP_Notification(&HandleNotification);
|
|
/* USER CODE BEGIN EVT_DISCONN_COMPLETE */
|
|
|
|
/* USER CODE END EVT_DISCONN_COMPLETE */
|
|
break; /* HCI_DISCONNECTION_COMPLETE_EVT_CODE */
|
|
}
|
|
|
|
case HCI_HARDWARE_ERROR_EVT_CODE:
|
|
{
|
|
hci_hardware_error_event_rp0 *p_hardware_error_event;
|
|
|
|
p_hardware_error_event = (hci_hardware_error_event_rp0 *)p_event_pckt->data;
|
|
UNUSED(p_hardware_error_event);
|
|
APP_DBG_MSG(">>== HCI_HARDWARE_ERROR_EVT_CODE\n");
|
|
APP_DBG_MSG("Hardware Code = 0x%02X\n",p_hardware_error_event->Hardware_Code);
|
|
/* USER CODE BEGIN HCI_EVT_LE_HARDWARE_ERROR */
|
|
|
|
/* USER CODE END HCI_EVT_LE_HARDWARE_ERROR */
|
|
break; /* HCI_HARDWARE_ERROR_EVT_CODE */
|
|
}
|
|
|
|
case HCI_LE_META_EVT_CODE:
|
|
{
|
|
p_meta_evt = (evt_le_meta_event*) p_event_pckt->data;
|
|
/* USER CODE BEGIN EVT_LE_META_EVENT */
|
|
|
|
/* USER CODE END EVT_LE_META_EVENT */
|
|
switch (p_meta_evt->subevent)
|
|
{
|
|
case HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE:
|
|
#if (CFG_DEBUG_APP_TRACE != 0)
|
|
p_connection_update_complete_event = (hci_le_connection_update_complete_event_rp0 *) p_meta_evt->data;
|
|
APP_DBG_MSG(">>== HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE\n");
|
|
APP_DBG_MSG(" - Connection Interval: %.2f ms\n - Connection latency: %d\n - Supervision Timeout: %d ms\n\r",
|
|
p_connection_update_complete_event->Conn_Interval*1.25,
|
|
p_connection_update_complete_event->Conn_Latency,
|
|
p_connection_update_complete_event->Supervision_Timeout*10);
|
|
#endif /* CFG_DEBUG_APP_TRACE != 0 */
|
|
|
|
/* USER CODE BEGIN EVT_LE_CONN_UPDATE_COMPLETE */
|
|
|
|
/* USER CODE END EVT_LE_CONN_UPDATE_COMPLETE */
|
|
break;
|
|
|
|
case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE:
|
|
{
|
|
p_connection_complete_event = (hci_le_connection_complete_event_rp0 *) p_meta_evt->data;
|
|
/**
|
|
* The connection is done, there is no need anymore to schedule the LP ADV
|
|
*/
|
|
|
|
APP_DBG_MSG(">>== HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE - Connection handle: 0x%x\n", p_connection_complete_event->Connection_Handle);
|
|
APP_DBG_MSG(" - Connection established with Central: @:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
p_connection_complete_event->Peer_Address[5],
|
|
p_connection_complete_event->Peer_Address[4],
|
|
p_connection_complete_event->Peer_Address[3],
|
|
p_connection_complete_event->Peer_Address[2],
|
|
p_connection_complete_event->Peer_Address[1],
|
|
p_connection_complete_event->Peer_Address[0]);
|
|
APP_DBG_MSG(" - Connection Interval: %.2f ms\n - Connection latency: %d\n - Supervision Timeout: %d ms\n\r",
|
|
p_connection_complete_event->Conn_Interval*1.25,
|
|
p_connection_complete_event->Conn_Latency,
|
|
p_connection_complete_event->Supervision_Timeout*10
|
|
);
|
|
|
|
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 = p_connection_complete_event->Connection_Handle;
|
|
/**
|
|
* SPECIFIC to Custom Template APP
|
|
*/
|
|
HandleNotification.Custom_Evt_Opcode = CUSTOM_CONN_HANDLE_EVT;
|
|
HandleNotification.ConnectionHandle = BleApplicationContext.BleApplicationContext_legacy.connectionHandle;
|
|
Custom_APP_Notification(&HandleNotification);
|
|
/* USER CODE BEGIN HCI_EVT_LE_CONN_COMPLETE */
|
|
|
|
/* USER CODE END HCI_EVT_LE_CONN_COMPLETE */
|
|
break; /* HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE */
|
|
}
|
|
|
|
default:
|
|
/* USER CODE BEGIN SUBEVENT_DEFAULT */
|
|
|
|
/* USER CODE END SUBEVENT_DEFAULT */
|
|
break;
|
|
}
|
|
|
|
/* USER CODE BEGIN META_EVT */
|
|
|
|
/* USER CODE END META_EVT */
|
|
break; /* HCI_LE_META_EVT_CODE */
|
|
}
|
|
|
|
case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE:
|
|
p_blecore_evt = (evt_blecore_aci*) p_event_pckt->data;
|
|
/* USER CODE BEGIN EVT_VENDOR */
|
|
|
|
/* USER CODE END EVT_VENDOR */
|
|
switch (p_blecore_evt->ecode)
|
|
{
|
|
/* USER CODE BEGIN ecode */
|
|
|
|
/* USER CODE END ecode */
|
|
|
|
/**
|
|
* SPECIFIC to Custom Template APP
|
|
*/
|
|
case ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE:
|
|
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
|
|
mutex = 1;
|
|
#endif /* L2CAP_REQUEST_NEW_CONN_PARAM != 0 */
|
|
/* USER CODE BEGIN EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP */
|
|
|
|
/* USER CODE END EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP */
|
|
break;
|
|
|
|
case ACI_GAP_PROC_COMPLETE_VSEVT_CODE:
|
|
APP_DBG_MSG(">>== ACI_GAP_PROC_COMPLETE_VSEVT_CODE \r");
|
|
/* USER CODE BEGIN EVT_BLUE_GAP_PROCEDURE_COMPLETE */
|
|
|
|
/* USER CODE END EVT_BLUE_GAP_PROCEDURE_COMPLETE */
|
|
break; /* ACI_GAP_PROC_COMPLETE_VSEVT_CODE */
|
|
|
|
#if (RADIO_ACTIVITY_EVENT != 0)
|
|
case ACI_HAL_END_OF_RADIO_ACTIVITY_VSEVT_CODE:
|
|
/* USER CODE BEGIN RADIO_ACTIVITY_EVENT*/
|
|
|
|
/* USER CODE END RADIO_ACTIVITY_EVENT*/
|
|
break; /* ACI_HAL_END_OF_RADIO_ACTIVITY_VSEVT_CODE */
|
|
#endif /* RADIO_ACTIVITY_EVENT != 0 */
|
|
|
|
/* PAIRING */
|
|
case (ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE):
|
|
APP_DBG_MSG(">>== ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE\n");
|
|
/* USER CODE BEGIN ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE*/
|
|
|
|
/* USER CODE END ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE*/
|
|
break;
|
|
|
|
case ACI_GAP_PASS_KEY_REQ_VSEVT_CODE:
|
|
{
|
|
uint32_t pin;
|
|
APP_DBG_MSG(">>== ACI_GAP_PASS_KEY_REQ_VSEVT_CODE \n");
|
|
pin = BLE_DEFAULT_PIN;
|
|
/* USER CODE BEGIN ACI_GAP_PASS_KEY_REQ_VSEVT_CODE_0 */
|
|
|
|
/* USER CODE END ACI_GAP_PASS_KEY_REQ_VSEVT_CODE_0 */
|
|
|
|
ret = aci_gap_pass_key_resp(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, pin);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG("==>> aci_gap_pass_key_resp : Fail, reason: 0x%x\n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG("==>> aci_gap_pass_key_resp : Success \n");
|
|
}
|
|
/* USER CODE BEGIN ACI_GAP_PASS_KEY_REQ_VSEVT_CODE*/
|
|
|
|
/* USER CODE END ACI_GAP_PASS_KEY_REQ_VSEVT_CODE*/
|
|
break;
|
|
}
|
|
|
|
case ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE:
|
|
APP_DBG_MSG(">>== ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE\n");
|
|
APP_DBG_MSG(" - numeric_value = %ld\n",
|
|
((aci_gap_numeric_comparison_value_event_rp0 *)(p_blecore_evt->data))->Numeric_Value);
|
|
APP_DBG_MSG(" - Hex_value = %lx\n",
|
|
((aci_gap_numeric_comparison_value_event_rp0 *)(p_blecore_evt->data))->Numeric_Value);
|
|
ret = aci_gap_numeric_comparison_value_confirm_yesno(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, YES);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG("==>> aci_gap_numeric_comparison_value_confirm_yesno-->YES : Fail, reason: 0x%x\n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG("==>> aci_gap_numeric_comparison_value_confirm_yesno-->YES : Success \n");
|
|
}
|
|
/* USER CODE BEGIN ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE*/
|
|
|
|
/* USER CODE END ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE*/
|
|
break;
|
|
|
|
case ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE:
|
|
p_pairing_complete = (aci_gap_pairing_complete_event_rp0*)p_blecore_evt->data;
|
|
|
|
APP_DBG_MSG(">>== ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE\n");
|
|
if (p_pairing_complete->Status != 0)
|
|
{
|
|
APP_DBG_MSG(" - Pairing KO \n - Status: 0x%x\n - Reason: 0x%x\n", p_pairing_complete->Status, p_pairing_complete->Reason);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" - Pairing Success\n");
|
|
}
|
|
APP_DBG_MSG("\n");
|
|
|
|
/* USER CODE BEGIN ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE*/
|
|
|
|
/* USER CODE END ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE*/
|
|
break;
|
|
/* PAIRING */
|
|
case ACI_GATT_INDICATION_VSEVT_CODE:
|
|
{
|
|
APP_DBG_MSG(">>== ACI_GATT_INDICATION_VSEVT_CODE \r");
|
|
aci_gatt_confirm_indication(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
|
|
}
|
|
break;
|
|
|
|
case ACI_HAL_WARNING_VSEVT_CODE:
|
|
{
|
|
aci_hal_warning_event_rp0 *p_warning_event;
|
|
|
|
p_warning_event = (aci_hal_warning_event_rp0 *)p_blecore_evt->data;
|
|
UNUSED(p_warning_event);
|
|
APP_DBG_MSG(">>== ACI_HAL_WARNING_VSEVT_CODE\n");
|
|
APP_DBG_MSG("Warning Type = 0x%02X\n", p_warning_event->Warning_Type);
|
|
/* USER CODE BEGIN ACI_HAL_WARNING_VSEVT_CODE */
|
|
|
|
/* USER CODE END ACI_HAL_WARNING_VSEVT_CODE */
|
|
break;
|
|
}
|
|
/* USER CODE BEGIN BLUE_EVT */
|
|
|
|
/* USER CODE END BLUE_EVT */
|
|
}
|
|
break; /* HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE */
|
|
|
|
/* USER CODE BEGIN EVENT_PCKT */
|
|
|
|
/* USER CODE END EVENT_PCKT */
|
|
|
|
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;
|
|
}
|
|
|
|
/* USER CODE BEGIN FD*/
|
|
|
|
/* 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;
|
|
uint16_t gap_service_handle, gap_dev_name_char_handle, gap_appearance_char_handle;
|
|
const uint8_t *p_bd_addr;
|
|
uint16_t a_appearance[1] = {BLE_CFG_GAP_APPEARANCE};
|
|
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
|
|
/* USER CODE BEGIN Ble_Hci_Gap_Gatt_Init*/
|
|
|
|
/* USER CODE END Ble_Hci_Gap_Gatt_Init*/
|
|
|
|
APP_DBG_MSG("==>> Start Ble_Hci_Gap_Gatt_Init function\n");
|
|
|
|
/**
|
|
* Initialize HCI layer
|
|
*/
|
|
/*HCI Reset to synchronise BLE Stack*/
|
|
ret = hci_reset();
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : hci_reset command, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: hci_reset command\n");
|
|
}
|
|
|
|
/**
|
|
* Write the BD Address
|
|
*/
|
|
p_bd_addr = BleGetBdAddress();
|
|
ret = aci_hal_write_config_data(CONFIG_DATA_PUBLIC_ADDRESS_OFFSET, CONFIG_DATA_PUBLIC_ADDRESS_LEN, (uint8_t*) p_bd_addr);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_hal_write_config_data command - CONFIG_DATA_PUBLIC_ADDRESS_OFFSET, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_hal_write_config_data command - CONFIG_DATA_PUBLIC_ADDRESS_OFFSET\n");
|
|
APP_DBG_MSG(" Public Bluetooth Address: %02x:%02x:%02x:%02x:%02x:%02x\n",p_bd_addr[5],p_bd_addr[4],p_bd_addr[3],p_bd_addr[2],p_bd_addr[1],p_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
|
|
*/
|
|
#if (CFG_BLE_ADDRESS_TYPE != GAP_PUBLIC_ADDR)
|
|
|
|
ret = aci_hal_write_config_data(CONFIG_DATA_RANDOM_ADDRESS_OFFSET, CONFIG_DATA_RANDOM_ADDRESS_LEN, (uint8_t*)a_srd_bd_addr);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_hal_write_config_data command - CONFIG_DATA_RANDOM_ADDRESS_OFFSET, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_hal_write_config_data command - CONFIG_DATA_RANDOM_ADDRESS_OFFSET\n");
|
|
APP_DBG_MSG(" Random Bluetooth Address: %02x:%02x:%02x:%02x:%02x:%02x\n", (uint8_t)(a_srd_bd_addr[1] >> 8),
|
|
(uint8_t)(a_srd_bd_addr[1]),
|
|
(uint8_t)(a_srd_bd_addr[0] >> 24),
|
|
(uint8_t)(a_srd_bd_addr[0] >> 16),
|
|
(uint8_t)(a_srd_bd_addr[0] >> 8),
|
|
(uint8_t)(a_srd_bd_addr[0]));
|
|
}
|
|
#endif /* CFG_BLE_ADDRESS_TYPE != GAP_PUBLIC_ADDR */
|
|
|
|
/**
|
|
* Write Identity root key used to derive IRK and DHK(Legacy)
|
|
*/
|
|
ret = aci_hal_write_config_data(CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t*)a_BLE_CfgIrValue);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_hal_write_config_data command - CONFIG_DATA_IR_OFFSET, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_hal_write_config_data command - CONFIG_DATA_IR_OFFSET\n");
|
|
}
|
|
|
|
/**
|
|
* Write Encryption root key used to derive LTK and CSRK
|
|
*/
|
|
ret = aci_hal_write_config_data(CONFIG_DATA_ER_OFFSET, CONFIG_DATA_ER_LEN, (uint8_t*)a_BLE_CfgErValue);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_hal_write_config_data command - CONFIG_DATA_ER_OFFSET, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_hal_write_config_data command - CONFIG_DATA_ER_OFFSET\n");
|
|
}
|
|
|
|
/**
|
|
* Set TX Power.
|
|
*/
|
|
ret = aci_hal_set_tx_power_level(1, CFG_TX_POWER);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_hal_set_tx_power_level command, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_hal_set_tx_power_level command\n");
|
|
}
|
|
|
|
/**
|
|
* Initialize GATT interface
|
|
*/
|
|
ret = aci_gatt_init();
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_gatt_init command, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_gatt_init command\n");
|
|
}
|
|
|
|
/**
|
|
* Initialize GAP interface
|
|
*/
|
|
role = 0;
|
|
|
|
#if (BLE_CFG_PERIPHERAL == 1)
|
|
role |= GAP_PERIPHERAL_ROLE;
|
|
#endif /* BLE_CFG_PERIPHERAL == 1 */
|
|
|
|
#if (BLE_CFG_CENTRAL == 1)
|
|
role |= GAP_CENTRAL_ROLE;
|
|
#endif /* BLE_CFG_CENTRAL == 1 */
|
|
|
|
/* USER CODE BEGIN Role_Mngt*/
|
|
|
|
/* USER CODE END Role_Mngt */
|
|
|
|
if (role > 0)
|
|
{
|
|
const char *name = CFG_GAP_DEVICE_NAME;
|
|
ret = aci_gap_init(role,
|
|
CFG_PRIVACY,
|
|
CFG_GAP_DEVICE_NAME_LENGTH,
|
|
&gap_service_handle,
|
|
&gap_dev_name_char_handle,
|
|
&gap_appearance_char_handle);
|
|
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_gap_init command, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_gap_init command\n");
|
|
}
|
|
|
|
ret = aci_gatt_update_char_value(gap_service_handle, gap_dev_name_char_handle, 0, strlen(name), (uint8_t *) name);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
BLE_DBG_SVCCTL_MSG(" Fail : aci_gatt_update_char_value - Device Name\n");
|
|
}
|
|
else
|
|
{
|
|
BLE_DBG_SVCCTL_MSG(" Success: aci_gatt_update_char_value - Device Name\n");
|
|
}
|
|
}
|
|
|
|
ret = aci_gatt_update_char_value(gap_service_handle,
|
|
gap_appearance_char_handle,
|
|
0,
|
|
2,
|
|
(uint8_t *)&a_appearance);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
BLE_DBG_SVCCTL_MSG(" Fail : aci_gatt_update_char_value - Appearance\n");
|
|
}
|
|
else
|
|
{
|
|
BLE_DBG_SVCCTL_MSG(" Success: aci_gatt_update_char_value - Appearance\n");
|
|
}
|
|
|
|
/**
|
|
* Initialize Default PHY
|
|
*/
|
|
ret = hci_le_set_default_phy(ALL_PHYS_PREFERENCE,TX_2M_PREFERRED,RX_2M_PREFERRED);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : hci_le_set_default_phy command, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: hci_le_set_default_phy command\n");
|
|
}
|
|
|
|
/**
|
|
* Initialize IO capability
|
|
*/
|
|
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability = CFG_IO_CAPABILITY;
|
|
ret = aci_gap_set_io_capability(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_gap_set_io_capability command, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_gap_set_io_capability command\n");
|
|
}
|
|
|
|
/**
|
|
* 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.bonding_mode = CFG_BONDING_MODE;
|
|
/* USER CODE BEGIN Ble_Hci_Gap_Gatt_Init_1*/
|
|
|
|
/* USER CODE END Ble_Hci_Gap_Gatt_Init_1*/
|
|
|
|
ret = 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,
|
|
USE_FIXED_PIN_FOR_PAIRING_FORBIDDEN, /* deprecated feature */
|
|
0, /* deprecated feature */
|
|
CFG_IDENTITY_ADDRESS);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_gap_set_authentication_requirement command, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_gap_set_authentication_requirement command\n");
|
|
}
|
|
|
|
/**
|
|
* Initialize whitelist
|
|
*/
|
|
if (BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode)
|
|
{
|
|
ret = aci_gap_configure_whitelist();
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG(" Fail : aci_gap_configure_whitelist command, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" Success: aci_gap_configure_whitelist command\n");
|
|
}
|
|
}
|
|
APP_DBG_MSG("==>> End Ble_Hci_Gap_Gatt_Init function\n\r");
|
|
}
|
|
|
|
static void Adv_Request(APP_BLE_ConnStatus_t NewStatus)
|
|
{
|
|
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
|
|
|
|
BleApplicationContext.Device_Connection_Status = NewStatus;
|
|
/* Start Fast or Low Power Advertising */
|
|
ret = aci_gap_set_discoverable(ADV_TYPE,
|
|
CFG_FAST_CONN_ADV_INTERVAL_MIN,
|
|
CFG_FAST_CONN_ADV_INTERVAL_MAX,
|
|
CFG_BLE_ADDRESS_TYPE,
|
|
ADV_FILTER,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG("==>> aci_gap_set_discoverable - fail, result: 0x%x \n", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG("==>> aci_gap_set_discoverable - Success\n");
|
|
}
|
|
|
|
/* USER CODE BEGIN Adv_Request_1*/
|
|
|
|
/* USER CODE END Adv_Request_1*/
|
|
|
|
/* Update Advertising data */
|
|
ret = aci_gap_update_adv_data(sizeof(a_AdvData), (uint8_t*) a_AdvData);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG("==>> Start Fast Advertising Failed , result: %d \n\r", ret);
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG("==>> Success: Start Fast Advertising \n\r");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
const uint8_t* BleGetBdAddress(void)
|
|
{
|
|
uint8_t *p_otp_addr;
|
|
const uint8_t *p_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.
|
|
*/
|
|
a_BdAddrUdn[0] = (uint8_t)(udn & 0x000000FF);
|
|
a_BdAddrUdn[1] = (uint8_t)((udn & 0x0000FF00) >> 8);
|
|
a_BdAddrUdn[2] = (uint8_t)device_id;
|
|
a_BdAddrUdn[3] = (uint8_t)(company_id & 0x000000FF);
|
|
a_BdAddrUdn[4] = (uint8_t)((company_id & 0x0000FF00) >> 8);
|
|
a_BdAddrUdn[5] = (uint8_t)((company_id & 0x00FF0000) >> 16);
|
|
|
|
p_bd_addr = (const uint8_t *)a_BdAddrUdn;
|
|
}
|
|
else
|
|
{
|
|
p_otp_addr = OTP_Read(0);
|
|
if (p_otp_addr)
|
|
{
|
|
p_bd_addr = ((OTP_ID0_t*)p_otp_addr)->bd_address;
|
|
}
|
|
else
|
|
{
|
|
p_bd_addr = a_MBdAddr;
|
|
}
|
|
}
|
|
|
|
return p_bd_addr;
|
|
}
|
|
|
|
/* USER CODE BEGIN FD_LOCAL_FUNCTION */
|
|
|
|
/* USER CODE END FD_LOCAL_FUNCTION */
|
|
|
|
/*************************************************************
|
|
*
|
|
* SPECIFIC FUNCTIONS FOR CUSTOM
|
|
*
|
|
*************************************************************/
|
|
static void Adv_Cancel(void)
|
|
{
|
|
/* USER CODE BEGIN Adv_Cancel_1 */
|
|
|
|
/* USER CODE END Adv_Cancel_1 */
|
|
|
|
if (BleApplicationContext.Device_Connection_Status != APP_BLE_CONNECTED_SERVER)
|
|
{
|
|
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
|
|
|
|
ret = aci_gap_set_non_discoverable();
|
|
|
|
BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG("** STOP ADVERTISING ** Failed \r\n\r");
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG(" \r\n\r");
|
|
APP_DBG_MSG("** STOP ADVERTISING ** \r\n\r");
|
|
}
|
|
}
|
|
|
|
/* USER CODE BEGIN Adv_Cancel_2 */
|
|
|
|
/* USER CODE END Adv_Cancel_2 */
|
|
|
|
return;
|
|
}
|
|
|
|
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
|
|
void BLE_SVC_L2CAP_Conn_Update(uint16_t ConnectionHandle)
|
|
{
|
|
/* 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(a_ConnInterval[index_con_int]);
|
|
uint16_t interval_max = CONN_P(a_ConnInterval[index_con_int]);
|
|
uint16_t peripheral_latency = L2CAP_PERIPHERAL_LATENCY;
|
|
uint16_t timeout_multiplier = L2CAP_TIMEOUT_MULTIPLIER;
|
|
tBleStatus ret;
|
|
|
|
ret = aci_l2cap_connection_parameter_update_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,
|
|
interval_min, interval_max,
|
|
peripheral_latency, timeout_multiplier);
|
|
if (ret != BLE_STATUS_SUCCESS)
|
|
{
|
|
APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Failed \r\n\r");
|
|
}
|
|
else
|
|
{
|
|
APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Successfully \r\n\r");
|
|
}
|
|
}
|
|
|
|
/* USER CODE BEGIN BLE_SVC_L2CAP_Conn_Update_2 */
|
|
|
|
/* USER CODE END BLE_SVC_L2CAP_Conn_Update_2 */
|
|
|
|
return;
|
|
}
|
|
#endif /* L2CAP_REQUEST_NEW_CONN_PARAM != 0 */
|
|
|
|
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0)
|
|
static void Connection_Interval_Update_Req(void)
|
|
{
|
|
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 /* L2CAP_REQUEST_NEW_CONN_PARAM != 0 */
|
|
|
|
/* USER CODE BEGIN FD_SPECIFIC_FUNCTIONS */
|
|
|
|
/* USER CODE END FD_SPECIFIC_FUNCTIONS */
|
|
/*************************************************************
|
|
*
|
|
* WRAP FUNCTIONS
|
|
*
|
|
*************************************************************/
|
|
void hci_notify_asynch_evt(void* p_Data)
|
|
{
|
|
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 *p_Payload)
|
|
{
|
|
SVCCTL_UserEvtFlowStatus_t svctl_return_status;
|
|
tHCI_UserEvtRxParam *p_param;
|
|
|
|
p_param = (tHCI_UserEvtRxParam *)p_Payload;
|
|
|
|
svctl_return_status = SVCCTL_UserEvtRx((void *)&(p_param->pckt->evtserial));
|
|
if (svctl_return_status != SVCCTL_UserEvtFlowDisable)
|
|
{
|
|
p_param->status = HCI_TL_UserEventFlow_Enable;
|
|
}
|
|
else
|
|
{
|
|
p_param->status = HCI_TL_UserEventFlow_Disable;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void BLE_StatusNot(HCI_TL_CmdStatus_t Status)
|
|
{
|
|
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);
|
|
/* USER CODE BEGIN HCI_TL_CmdBusy */
|
|
|
|
/* USER CODE END HCI_TL_CmdBusy */
|
|
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);
|
|
/* USER CODE BEGIN HCI_TL_CmdAvailable */
|
|
|
|
/* USER CODE END HCI_TL_CmdAvailable */
|
|
break;
|
|
|
|
default:
|
|
/* USER CODE BEGIN Status */
|
|
|
|
/* USER CODE END Status */
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void SVCCTL_ResumeUserEventFlow(void)
|
|
{
|
|
hci_resume_flow();
|
|
|
|
return;
|
|
}
|
|
|
|
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
|
|
|
|
/* USER CODE END FD_WRAP_FUNCTIONS */
|