上一篇介绍使用STM32CubeMX创建的蓝牙应用的代码分布。其中Core和STM32_WPAN/App文件夹中代码需要用户添加自定义的代码来完成具体的应用。这里以示例工程中的BLE_p2pServer
的移植为例。
1、添加示例文件
将示例BLE_p2pServer中的app_bsp.c/h
文件复制到工程的STM32_WPAN/App
文件夹中
https://github.com/STMicroelectronics/STM32CubeWBA/blob/main/Projects/NUCLEO-WBA65RI/Applications/BLE/BLE_p2pServer/STM32_WPAN/App/app_bsp.c

工程添加文件后的效果如下

2、添加应用代码
参考ST MCU Wiki中的代码修改指南,在工程中添加应用代码。
https://wiki.st.com/stm32mcu/wiki/Connectivity:STM32WBA_BLE_STM32CubeMX#Code_modification-_user_sections
修改代码文件在Core文件夹和STM32_WPAN/App文件夹中

参考指南中示例添加代码时,从USE CODE BEGIN XXXX
和USE CODE END XXXX
来确定代码的添加位置。

在Core/Inc/app_conf.h
文件中添加以下
/* USER CODE BEGIN Defines */
/**
* User interaction
* When CFG_LED_SUPPORTED is set, LEDS are activated if requested
* When CFG_BUTTON_SUPPORTED is set, the push button are activated if requested
*/
#define CFG_LED_SUPPORTED (1)
#define CFG_BUTTON_SUPPORTED (1)
/**
* Overwrite some configuration imposed by Low Power level selected.
*/
#if (CFG_LPM_LEVEL > 1)
#if CFG_LED_SUPPORTED
#undef CFG_LED_SUPPORTED
#define CFG_LED_SUPPORTED (0)
#endif /* CFG_LED_SUPPORTED */
#endif /* CFG_LPM_LEVEL */
/* USER CODE END Defines */
Core/Src/main.c
中添加
/* USER CODE BEGIN RNG_Init 2 */
/* Disable RNG peripheral and its RCC clock */
HW_RNG_Disable( );
/* USER CODE END RNG_Init 2 */
Core/Src/stm32wbaxx_it.c:
中添加
/* USER CODE BEGIN Includes */
#include "app_bsp.h"
/* USER CODE END Includes */
/**
* @brief This function handles EXTI Line4 interrupt.
*/
void EXTI4_IRQHandler(void)
{
/* USER CODE BEGIN EXTI4_IRQn 0 */
/* USER CODE END EXTI4_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
/* USER CODE BEGIN EXTI4_IRQn 1 */
BSP_PB_IRQHandler(B3);
/* USER CODE END EXTI4_IRQn 1 */
}
/**
* @brief This function handles EXTI Line5 interrupt.
*/
void EXTI5_IRQHandler(void)
{
/* USER CODE BEGIN EXTI5_IRQn 0 */
/* USER CODE END EXTI5_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
/* USER CODE BEGIN EXTI5_IRQn 1 */
BSP_PB_IRQHandler(B2);
/* USER CODE END EXTI5_IRQn 1 */
}
/**
* @brief This function handles EXTI Line13 interrupt.
*/
void EXTI13_IRQHandler(void)
{
/* USER CODE BEGIN EXTI13_IRQn 0 */
/* USER CODE END EXTI13_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
/* USER CODE BEGIN EXTI13_IRQn 1 */
BSP_PB_IRQHandler(B1);
/* USER CODE END EXTI13_IRQn 1 */
}
Core/Inc/app_entry.h
中添加
/* USER CODE BEGIN EC */
/******************************************************************************
* Information Table
*
* Version
* [0:3] = Build - 0: Untracked - 15:Released - x: Tracked version
* [4:7] = branch - 0: Mass Market - x: ...
* [8:15] = Subversion
* [16:23] = Version minor
* [24:31] = Version major
*
******************************************************************************/
#define CFG_FW_BUILD (0)
#define CFG_FW_BRANCH (0)
#define CFG_FW_SUBVERSION (0)
#define CFG_FW_MINOR_VERSION (6)
#define CFG_FW_MAJOR_VERSION (1)
/* USER CODE END EC */
Core/Inc/app_entry.c
中添加
/* USER CODE BEGIN Includes */
#include "app_bsp.h"
/* USER CODE END Includes */
/* USER CODE BEGIN APPE_Init_1 */
#if (CFG_LED_SUPPORTED == 1)
APP_BSP_LedInit();
#endif /* (CFG_LED_SUPPORTED == 1) */
#if (CFG_BUTTON_SUPPORTED == 1)
APP_BSP_ButtonInit();
#endif /* (CFG_BUTTON_SUPPORTED == 1) */
/* USER CODE END APPE_Init_1 */
STM32_WPAN/App/app_ble.h
中添加
/* USER CODE BEGIN EC */
/**
* ST Manufacturer ID
**/
#define ST_MANUF_ID 0x30
/**
* BlueSTSDK Version
**/
enum
{
BLUESTSDK_V1 = 0x01,
BLUESTSDK_V2 = 0x02
};
/**
* BOARD ID
**/
enum
{
BOARD_ID_NUCLEO_WBA5X = 0x8B,
BOARD_ID_DK_WBA5X = 0x8C,
BOARD_ID_NUCLEO_WBA6X = 0x8E
};
/**
* FIRMWARE ID
**/
enum
{
FW_ID_P2P_SERVER = 0x83,
FW_ID_P2P_ROUTER = 0x85,
FW_ID_DT_SERVER = 0x88,
FW_ID_COC_PERIPH = 0x87,
FW_ID_HEART_RATE = 0x89,
FW_ID_HEALTH_THERMO = 0x8A
};
/* USER CODE END EC */
STM32_WPAN/App/app_ble.c
中添加
/* USER CODE BEGIN Includes */
#include "app_bsp.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PTD_1*/
/* Advertising timeout timerID*/
UTIL_TIMER_Object_t Advertising_mgr_timer_Id;
/* Led Timeout timerID */
UTIL_TIMER_Object_t SwitchOffGPIO_timer_Id;
uint8_t connIntervalFlag;
/* USER CODE END PTD_1 */
/* USER CODE BEGIN PD */
#define LED_ON_TIMEOUT_MS (5)
#define ADV_TIMEOUT_MS (60 * 1000)
/* Device Info Characteristic UUID */
#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \
do {\
uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \
uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \
uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \
uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \
}while(0)
#define COPY_DEVINFO_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0x00,0x00,0xfe,0x31,0x8e,0x22,0x45,0x41,0x9d,0x4c,0x21,0xed,0xae,0x82,0xed,0x19)
/* USER CODE END PD */
/* USER CODE BEGIN PV */
uint8_t a_GATT_DevInfoData[22];
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
static void Adv_Cancel_Req(void *arg);
static void Adv_Cancel(void);
static void Switch_OFF_GPIO(void *arg);
static void fill_advData(uint8_t *p_adv_data, uint8_t tab_size, const uint8_t*p_bd_addr);
/* USER CODE END PFP */
/* USER CODE BEGIN APP_BLE_Init_1 */
tBleStatus ret;
/* USER CODE END APP_BLE_Init_1 */
/* USER CODE BEGIN APP_BLE_Init_4 */
UTIL_SEQ_RegTask(1<<CFG_TASK_ADV_CANCEL_ID, UTIL_SEQ_RFU, Adv_Cancel);
/* Create timer to handle the Advertising Stop */
UTIL_TIMER_Create(&(bleAppContext.Advertising_mgr_timer_Id),
0,
UTIL_TIMER_ONESHOT,
&Adv_Cancel_Req,
0);
/* Create timer to handle the Led Switch OFF */
UTIL_TIMER_Create(&(bleAppContext.SwitchOffGPIO_timer_Id),
0,
UTIL_TIMER_ONESHOT,
&Switch_OFF_GPIO,
0);
/* USER CODE END APP_BLE_Init_4 */
/* USER CODE BEGIN APP_BLE_Init_3 */
ret = aci_hal_set_radio_activity_mask(0x0006);
if (ret != BLE_STATUS_SUCCESS)
{
LOG_INFO_APP(" Fail : aci_hal_set_radio_activity_mask command, result: 0x%2X\n", ret);
}
else
{
LOG_INFO_APP(" Success: aci_hal_set_radio_activity_mask command\n\r");
}
/* Start to Advertise to accept a connection */
APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_START_FAST);
/* Start a timer to stop advertising after a while */
UTIL_TIMER_StartWithPeriod(&bleAppContext.Advertising_mgr_timer_Id, ADV_TIMEOUT_MS);
/* USER CODE END APP_BLE_Init_3 */
/* USER CODE BEGIN APP_BLE_Init_2 */
bleAppContext.connIntervalFlag = 0;
/* USER CODE END APP_BLE_Init_2 */
/* USER CODE BEGIN EVT_DISCONN_COMPLETE */
APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_START_FAST);
UTIL_TIMER_StartWithPeriod(&bleAppContext.Advertising_mgr_timer_Id, ADV_TIMEOUT_MS);
/* USER CODE END EVT_DISCONN_COMPLETE */
/* USER CODE BEGIN HCI_EVT_LE_ENHANCED_CONN_COMPLETE */
/* The connection is done, there is no need anymore to schedule the LP ADV */
UTIL_TIMER_Stop(&(bleAppContext.Advertising_mgr_timer_Id));
/* USER CODE END HCI_EVT_LE_ENHANCED_CONN_COMPLETE */
/* USER CODE BEGIN HCI_EVT_LE_CONN_COMPLETE */
/* The connection is done, there is no need anymore to schedule the LP ADV */
UTIL_TIMER_Stop(&(bleAppContext.Advertising_mgr_timer_Id));
/* USER CODE END HCI_EVT_LE_CONN_COMPLETE */
/* USER CODE BEGIN HCI_EVT_LE_CONN_COMPLETE */
/* The connection is done, there is no need anymore to schedule the LP ADV */
UTIL_TIMER_Stop(&(bleAppContext.Advertising_mgr_timer_Id));
/* USER CODE END HCI_EVT_LE_CONN_COMPLETE */
/* USER CODE BEGIN RADIO_ACTIVITY_EVENT*/
#if (CFG_LED_SUPPORTED == 1)
BSP_LED_On(LED_GREEN);
#endif
UTIL_TIMER_StartWithPeriod(&bleAppContext.SwitchOffGPIO_timer_Id, LED_ON_TIMEOUT_MS);
/* USER CODE END RADIO_ACTIVITY_EVENT*/
/* USER CODE BEGIN CONN_PARAM_UPDATE */
if (bleAppContext.connIntervalFlag != 0)
{
bleAppContext.connIntervalFlag = 0;
paramA = CONN_INT_MS(50);
paramB = CONN_INT_MS(50);
}
else
{
bleAppContext.connIntervalFlag = 1;
paramA = CONN_INT_MS(1000);
paramB = CONN_INT_MS(1000);
}
/* USER CODE END CONN_PARAM_UPDATE */
/* USER CODE BEGIN Ble_Hci_Gap_Gatt_Init */
/* Add number of record for Device Info Characteristic */
static const uint8_t p_additional_svc_record[1] = {0x03};
ret = aci_hal_write_config_data(CONFIG_DATA_GAP_ADD_REC_NBR_OFFSET,
CONFIG_DATA_GAP_ADD_REC_NBR_LEN,
(uint8_t*) p_additional_svc_record);
if (ret != BLE_STATUS_SUCCESS)
{
LOG_INFO_APP(" Fail : aci_hal_write_config_data command - CONFIG_DATA_GAP_ADD_REC_NBR_OFFSET, result: 0x%02X\n", ret);
}
else
{
LOG_INFO_APP(" Success: aci_hal_write_config_data command - CONFIG_DATA_GAP_ADD_REC_NBR_OFFSET\n");
}
/* USER CODE END Ble_Hci_Gap_Gatt_Init */
/* USER CODE BEGIN Ble_Hci_Gap_Gatt_Init_1*/
fill_advData(&a_AdvData[0], sizeof(a_AdvData), (uint8_t*) p_bd_addr);
/* USER CODE END Ble_Hci_Gap_Gatt_Init_1*/
/* USER CODE BEGIN Ble_Hci_Gap_Gatt_Init_2 */
/** Device Info Characteristic **/
/* Add a new characterisitc */
Char_UUID_t uuid;
uint16_t gap_DevInfoChar_handle = 0U;
/* Add new characteristic to GAP service */
uint16_t SizeDeviceInfoChar = 22;
COPY_DEVINFO_UUID(uuid.Char_UUID_128);
ret = aci_gatt_add_char(gap_service_handle,
UUID_TYPE_128,
(Char_UUID_t *) &uuid,
SizeDeviceInfoChar,
CHAR_PROP_READ,
ATTR_PERMISSION_NONE,
GATT_DONT_NOTIFY_EVENTS,
0x10,
CHAR_VALUE_LEN_CONSTANT,
&gap_DevInfoChar_handle);
if (ret != BLE_STATUS_SUCCESS)
{
LOG_INFO_APP(" Fail : aci_gatt_add_char command : Device Info Char, error code: 0x%2X\n", ret);
}
else
{
LOG_INFO_APP(" Success: aci_gatt_add_char command : Device Info Char\n");
}
/**
* Initialize Device Info Characteristic
*/
uint8_t * p_device_info_payload = (uint8_t*)a_GATT_DevInfoData;
LOG_INFO_APP("---------------------------------------------\n");
/* Device ID: WBA5x, WBA6x... */
a_GATT_DevInfoData[0] = (uint8_t)(LL_DBGMCU_GetDeviceID() & 0xff);
a_GATT_DevInfoData[1] = (uint8_t)((LL_DBGMCU_GetDeviceID() & 0xff00)>>8);
LOG_INFO_APP("-- DEVICE INFO CHAR : Device ID = 0x%02X %02X\n",a_GATT_DevInfoData[1],a_GATT_DevInfoData[0]);
/* Rev ID: RevA, RevB... */
a_GATT_DevInfoData[2] = (uint8_t)(LL_DBGMCU_GetRevisionID() & 0xff);
a_GATT_DevInfoData[3] = (uint8_t)((LL_DBGMCU_GetRevisionID() & 0xff00)>>8);
LOG_INFO_APP("-- DEVICE INFO CHAR : Revision ID = 0x%02X %02X\n",a_GATT_DevInfoData[3],a_GATT_DevInfoData[2]);
/* Board ID: Nucleo WBA, DK1 WBA... */
a_GATT_DevInfoData[4] = BOARD_ID_NUCLEO_WBA5X;
LOG_INFO_APP("-- DEVICE INFO CHAR : Board ID = 0x%02X\n",a_GATT_DevInfoData[4]);
/* HW Package: QFN32, QFN48... */
a_GATT_DevInfoData[5] = (uint8_t)LL_GetPackageType();
LOG_INFO_APP("-- DEVICE INFO CHAR : HW Package = 0x%02X\n",a_GATT_DevInfoData[5]);
/* FW version: v1.3.0, v1.4.0... */
a_GATT_DevInfoData[6] = CFG_FW_MAJOR_VERSION;
a_GATT_DevInfoData[7] = CFG_FW_MINOR_VERSION;
a_GATT_DevInfoData[8] = CFG_FW_SUBVERSION;
a_GATT_DevInfoData[9] = CFG_FW_BRANCH;
a_GATT_DevInfoData[10] = CFG_FW_BUILD;
LOG_INFO_APP("-- DEVICE INFO CHAR : FW Version = v%d.%d.%d - branch %d - build %d\n",a_GATT_DevInfoData[6],a_GATT_DevInfoData[7],a_GATT_DevInfoData[8],a_GATT_DevInfoData[9],a_GATT_DevInfoData[10]);
/* Application ID: p2pServer, HeartRate... */
a_GATT_DevInfoData[11] = FW_ID_P2P_SERVER;
LOG_INFO_APP("-- DEVICE INFO CHAR : Application ID = 0x%02X\n",a_GATT_DevInfoData[11]);
/* Host Stack Version: 0.15, 0.16... */
uint8_t HCI_Version = 0;
uint16_t HCI_Subversion = 0;
uint8_t LMP_Version = 0;
uint16_t Company_Identifier = 0;
uint16_t LMP_Subversion = 0;
hci_read_local_version_information(&HCI_Version, &HCI_Subversion, &LMP_Version, &Company_Identifier, &LMP_Subversion);
a_GATT_DevInfoData[12] = (uint8_t)((uint16_t)HCI_Subversion & 0xff);
LOG_INFO_APP("-- DEVICE INFO CHAR : Host Stack version = 0x%02X\n",a_GATT_DevInfoData[12]);
/* Host Stack Type: Full, Basic, Basic Plus... */
a_GATT_DevInfoData[13] = (uint8_t)(((uint16_t)HCI_Subversion & 0xff00)>>8);
LOG_INFO_APP("-- DEVICE INFO CHAR : Host Stack Type = 0x%02X\n",a_GATT_DevInfoData[13]);
/* RESERVED */
a_GATT_DevInfoData[14] = 0xFF; /* reserved */
a_GATT_DevInfoData[15] = 0xFF; /* reserved */
a_GATT_DevInfoData[16] = 0xFF; /* reserved */
a_GATT_DevInfoData[17] = 0xFF; /* reserved */
/* Audio Lib */
a_GATT_DevInfoData[18] = 0xFF; /* NA */
a_GATT_DevInfoData[19] = 0xFF; /* NA */
/* Audio Codec */
a_GATT_DevInfoData[20] = 0xFF; /* NA */
a_GATT_DevInfoData[21] = 0xFF; /* NA */
LOG_INFO_APP("---------------------------------------------\n");
ret = aci_gatt_update_char_value(gap_service_handle,
gap_DevInfoChar_handle,
0, /* charValOffset */
SizeDeviceInfoChar, /* charValueLen */
p_device_info_payload);
if (ret != BLE_STATUS_SUCCESS)
{
LOG_INFO_APP(" Fail : aci_gatt_update_char_value DEVINFO command, error code: 0x%2X\n", ret);
}
else
{
LOG_INFO_APP(" Success: aci_gatt_update_char_value DEVINFO command\n");
}
/* USER CODE END Ble_Hci_Gap_Gatt_Init_2 */
/* USER CODE BEGIN FD_LOCAL_FUNCTION */
static void Adv_Cancel_Req(void *arg)
{
UTIL_SEQ_SetTask(1 << CFG_TASK_ADV_CANCEL_ID, CFG_SEQ_PRIO_0);
return;
}
static void Switch_OFF_GPIO(void *arg)
{
#if (CFG_LED_SUPPORTED == 1)
BSP_LED_Off(LED_GREEN);
#endif
return;
}
static void Adv_Cancel(void)
{
#if (CFG_LED_SUPPORTED == 1)
BSP_LED_Off(LED_GREEN);
#endif
APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_STOP);
return;
}
static void fill_advData(uint8_t *p_adv_data, uint8_t tab_size, const uint8_t* p_bd_addr)
{
uint16_t i =0;
uint8_t bd_addr_1, bd_addr_0;
uint8_t ad_length, ad_type;
while(i < tab_size)
{
ad_length = p_adv_data[i];
ad_type = p_adv_data[i + 1];
switch (ad_type)
{
case AD_TYPE_FLAGS:
break;
case AD_TYPE_TX_POWER_LEVEL:
break;
case AD_TYPE_COMPLETE_LOCAL_NAME:
{
if((p_adv_data[i + ad_length] == 'X') && (p_adv_data[i + ad_length - 1] == 'X'))
{
bd_addr_1 = ((p_bd_addr[0] & 0xF0)>>4);
bd_addr_0 = (p_bd_addr[0] & 0xF);
/* Convert hex value into ascii */
if(bd_addr_1 > 0x09)
{
p_adv_data[i + ad_length - 1] = bd_addr_1 + '7';
}
else
{
p_adv_data[i + ad_length - 1] = bd_addr_1 + '0';
}
if(bd_addr_0 > 0x09)
{
p_adv_data[i + ad_length] = bd_addr_0 + '7';
}
else
{
p_adv_data[i + ad_length] = bd_addr_0 + '0';
}
}
break;
}
case AD_TYPE_MANUFACTURER_SPECIFIC_DATA:
{
p_adv_data[i+2] = ST_MANUF_ID;
p_adv_data[i+3] = 0x00;
p_adv_data[i+4] = BLUESTSDK_V2; /* blueST SDK version */
p_adv_data[i+5] = BOARD_ID_NUCLEO_WBA5X; /* Board ID */
p_adv_data[i+6] = FW_ID_P2P_SERVER; /* FW ID */
p_adv_data[i+7] = 0x00; /* FW data 1 */
p_adv_data[i+8] = 0x00; /* FW data 2 */
p_adv_data[i+9] = 0x00; /* FW data 3 */
p_adv_data[i+10] = p_bd_addr[5]; /* MSB BD address */
p_adv_data[i+11] = p_bd_addr[4];
p_adv_data[i+12] = p_bd_addr[3];
p_adv_data[i+13] = p_bd_addr[2];
p_adv_data[i+14] = p_bd_addr[1];
p_adv_data[i+15] = p_bd_addr[0]; /* LSB BD address */
break;
}
default:
break;
}
i += ad_length + 1; /* increment the iterator to go on next element*/
}
}
/* USER CODE END FD_LOCAL_FUNCTION */
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
#if (CFG_BUTTON_SUPPORTED == 1)
void APP_BSP_Button1Action(void)
{
if (bleAppContext.Device_Connection_Status == APP_BLE_IDLE)
{
/* Relaunch advertising */
APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_START_FAST);
UTIL_TIMER_StartWithPeriod(&bleAppContext.Advertising_mgr_timer_Id, ADV_TIMEOUT_MS);
}
else
{
UTIL_SEQ_SetTask( 1<<CFG_TASK_SEND_NOTIF_ID, CFG_SEQ_PRIO_0);
}
return;
}
void APP_BSP_Button2Action(void)
{
tBleStatus ret;
if (bleAppContext.Device_Connection_Status != APP_BLE_CONNECTED_SERVER)
{
/* Clear Security Database */
ret = aci_gap_clear_security_db();
if (ret != BLE_STATUS_SUCCESS)
{
LOG_INFO_APP("==>> aci_gap_clear_security_db - Fail, result: 0x%02X\n", ret);
}
else
{
LOG_INFO_APP("==>> aci_gap_clear_security_db - Success\n");
}
}
else
{
/* Launch advertising for multi connection */
APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_START_FAST);
UTIL_TIMER_StartWithPeriod(&bleAppContext.Advertising_mgr_timer_Id, ADV_TIMEOUT_MS);
}
return;
}
void APP_BSP_Button3Action(void)
{
if (bleAppContext.Device_Connection_Status != APP_BLE_CONNECTED_SERVER)
{
}
else
{
APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_CONN_PARAM_UPDATE);
}
return;
}
#endif
/* USER CODE END FD_WRAP_FUNCTIONS */
STM32_WPAN/App/p2p_server.c
中添加以下代码
/* USER CODE BEGIN Service1_Char_1_ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE */
LOG_INFO_APP("-- GATT : LED CONFIGURATION RECEIVED\n");
notification.DataTransfered.Length = p_attribute_modified->Attr_Data_Length;
notification.DataTransfered.p_Payload = p_attribute_modified->Attr_Data;
/* USER CODE END Service1_Char_1_ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE */
/* USER CODE BEGIN BLECORE_EVT */
/* Manage ACI_GATT_INDICATION_VSEVT_CODE occurring on Android 12 */
case ACI_GATT_INDICATION_VSEVT_CODE:
{
tBleStatus status = BLE_STATUS_FAILED;
aci_gatt_indication_event_rp0 *pr = (void*)p_blecore_evt->data;
status = aci_gatt_confirm_indication(pr->Connection_Handle);
if (status != BLE_STATUS_SUCCESS)
{
LOG_INFO_APP(" Fail : aci_gatt_confirm_indication command, result: 0x%x \n", status);
}
else
{
LOG_INFO_APP(" Success: aci_gatt_confirm_indication command\n");
}
}
break; /* end ACI_GATT_NOTIFICATION_VSEVT_CODE */
/* USER CODE END BLECORE_EVT */
STM32_WPAN/App/p2p_server_app.c
中添加以下代码
/* USER CODE BEGIN Includes */
#include "app_bsp.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PTD */
typedef struct{
uint8_t Device_Led_Selection;
uint8_t Led1;
}P2P_LedCharValue_t;
typedef struct{
uint8_t Device_Button_Selection;
uint8_t ButtonStatus;
}P2P_ButtonCharValue_t;
/* USER CODE END PTD */
/* USER CODE BEGIN Service1_APP_Context_t */
P2P_LedCharValue_t LedControl;
P2P_ButtonCharValue_t ButtonControl;
/* USER CODE END Service1_APP_Context_t */
/* USER CODE BEGIN PFP */
static void P2P_SERVER_APP_LED_BUTTON_context_Init(void);
/* USER CODE END PFP */
/* USER CODE BEGIN Service1Char1_WRITE_NO_RESP_EVT */
if(p_Notification->DataTransfered.p_Payload[1] == 0x01)
{
#if (CFG_LED_SUPPORTED == 1)
BSP_LED_On(LED_BLUE);
#endif
LOG_INFO_APP("-- P2P APPLICATION SERVER : LED1 ON\n");
P2P_SERVER_APP_Context.LedControl.Led1 = 0x01; /* LED1 ON */
}
if(p_Notification->DataTransfered.p_Payload[1] == 0x00)
{
#if (CFG_LED_SUPPORTED == 1)
BSP_LED_Off(LED_BLUE);
#endif
LOG_INFO_APP("-- P2P APPLICATION SERVER : LED1 OFF\n");
}
P2P_SERVER_APP_Context.LedControl.Led1 = 0x00; /* LED1 OFF */
/* USER CODE END Service1Char1_WRITE_NO_RESP_EVT */
/* USER CODE BEGIN Service1Char2_NOTIFY_ENABLED_EVT */
P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_ON;
LOG_INFO_APP("-- P2P APPLICATION SERVER : NOTIFICATION ENABLED\n");
LOG_INFO_APP(" \n\r");
/* USER CODE END Service1Char2_NOTIFY_ENABLED_EVT */
/* USER CODE BEGIN Service1Char2_NOTIFY_DISABLED_EVT */
P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_OFF;
LOG_INFO_APP("-- P2P APPLICATION SERVER : NOTIFICATION DISABLED\n");
LOG_INFO_APP(" \n\r");
/* USER CODE END Service1Char2_NOTIFY_DISABLED_EVT */
/* USER CODE BEGIN Service1_APP_DISCON_HANDLE_EVT */
P2P_SERVER_APP_LED_BUTTON_context_Init();
/* USER CODE END Service1_APP_DISCON_HANDLE_EVT */
/* USER CODE BEGIN Service1_APP_Init */
UTIL_SEQ_RegTask( 1U << CFG_TASK_SEND_NOTIF_ID, UTIL_SEQ_RFU, P2P_SERVER_Switch_c_SendNotification);
/**
* Initialize LedButton Service
*/
P2P_SERVER_APP_Context.Switch_c_Notification_Status= Switch_c_NOTIFICATION_OFF;
P2P_SERVER_APP_LED_BUTTON_context_Init();
/* USER CODE END Service1_APP_Init */
/* USER CODE BEGIN Service1Char2_NS_1 */
if(P2P_SERVER_APP_Context.ButtonControl.ButtonStatus == 0x00)
{
P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x01;
}
else
{
P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x00;
}
a_P2P_SERVER_UpdateCharData[0] = 0x01; /* Device Led selection */
a_P2P_SERVER_UpdateCharData[1] = P2P_SERVER_APP_Context.ButtonControl.ButtonStatus;
/* Update notification data length */
p2p_server_notification_data.Length = (p2p_server_notification_data.Length) + 2;
if(P2P_SERVER_APP_Context.Switch_c_Notification_Status == Switch_c_NOTIFICATION_ON)
{
LOG_INFO_APP("-- P2P APPLICATION SERVER : INFORM CLIENT BUTTON 1 PUSHED\n");
notification_on_off = Switch_c_NOTIFICATION_ON;
}
else
{
LOG_INFO_APP("-- P2P APPLICATION SERVER : CAN'T INFORM CLIENT - NOTIFICATION DISABLED\n");
}
/* USER CODE END Service1Char2_NS_1 */
/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */
static void P2P_SERVER_APP_LED_BUTTON_context_Init(void)
{
#if (CFG_LED_SUPPORTED == 1)
BSP_LED_Off(LED_BLUE);
#endif
P2P_SERVER_APP_Context.LedControl.Device_Led_Selection=0x01; /* select device 01 */
P2P_SERVER_APP_Context.LedControl.Led1=0x00; /* led OFF */
P2P_SERVER_APP_Context.ButtonControl.Device_Button_Selection=0x01; /* select device 01 */
P2P_SERVER_APP_Context.ButtonControl.ButtonStatus=0x00;
return;
}
/* USER CODE END FD_LOCAL_FUNCTIONS */
3、编译和下载、
修改工程配置中的Linker设置添加-z noexecstack
标志位

编程成功并下载后,通过ST BLE Toolbox控制开发板上LED灯的效果如下

4、总结
参考官方的移植指南,在NUCELO-WBA65RI上完成BLE-p2p-Server的例程,作为开发蓝牙应用的参考。