LE Peripheral Extended ADV
LE peripheral extended ADV 示例工程可以作为开发基于Peripheral角色的APP的框架。
特征:
使用LE Advertising Extensions发送advertising events。
同时使能一个或多个advertising set。
设定advertising set使能的duration或最大的extended advertising events数目。
使用extended advertising PDU s传输更多数据。
可以作为Peripheral角色建立一条LE链路, PHY 为
LE 1M PHY
、LE 2M PHY
或LE Coded PHY
。
简介
使用LE Advertising Extensions的peripheral设备可以设置广播的持续时间或extended advertising event的最大数目,使能或禁用一个或多个advertising set。
若使用extended advertising PDUs,可以扩展adv data或scan response data的长度,以及使用
LE Coded PHY
增大可以建立连线的距离。关于extended advertising PDUs和legacy advertising PDUs的信息参见 LE Host 中的 Extended Advertising相关参数的配置。若Peripheral设备使用LE Advertising Extensions,开发者需要考虑与不同蓝牙版本的对端设备的兼容性,与不同蓝牙版本的对端设备的兼容性如下表所示:
Bluetooth 5 Feature |
Advertising PDUs |
Bluetooth 4.0 |
Bluetooth 4.1 |
Bluetooth 4.2 |
Bluetooth 5.0 (Not Use LE Advertising Extensions) |
Bluetooth 5.0 (Use LE Advertising Extensions) |
---|---|---|---|---|---|---|
LE Advertising Extensions |
Extended advertising PDUs |
N |
N |
N |
N |
Y |
LE Advertising Extensions |
Legacy advertising PDUs |
Y |
Y |
Y |
Y |
Y |
环境需求
该示例支持以下开发工具包:
Hardware Platforms |
Board Name |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
为快速搭建起开发环境,可参考 快速入门 中提供的详细指导。
硬件连线
配置
配置选项
该示例工程全部配置选项在
samples\bluetooth\ble_bt5_peripheral\src\app_flags.h
中,
开发者可以根据实际需求配置。
/** @brief Configure Advertising PHY */
#define ADVERTISING_PHY APP_PRIMARY_CODED_SECONDARY_CODED
/** @brief Configure coding scheme of LE Coded PHY: 0 - S = 2, 1 - S = 8 */
#define LE_CODED_PHY_S8 0
/** @brief Configure APP LE link number */
#define APP_MAX_LINKS 1
/** @brief Configure DLPS: 0 - Disable DLPS, 1 - Enable DLPS */
#define F_BT_DLPS_EN 1
生成系统配置文件
开发者可以通过MP Tool配置以下项目:
Configurable Item |
Value |
---|---|
LE Slave Link Num |
≥ APP_MAX_LINKS |
更多有关于MP Tool配置的信息请参考 快速入门 中的 生成System Config File。
编译和下载
该示例可以在SDK文件夹中找到:
Project file: samples\bluetooth\ble_bt5_peripheral\proj\rtl87x2g\mdk
Project file: samples\bluetooth\ble_bt5_peripheral\proj\rtl87x2g\gcc
编译和运行该示例请遵循以下步骤:
打开项目文件。
要编译目标文件,请参考 快速入门 的 编译APP Image 中列出的步骤。
编译成功后,目录
samples\bluetooth\ble_bt5_peripheral\proj\rtl87x2g\mdk\bin
下会生成app bin文件app_MP_sdk_xxx.bin
。要下载app bin到 EVB,请参考 快速入门 的 MP Tool 下载 中列出的步骤。
在EVB上按下 reset 键,程序将开始运行。
测试验证
将示例工程烧录到EVB后,开发者可以使用另一个运行 LE Central Extended Scan 工程的开发板来与之对测。
与另一块开发板对测
测试流程请参考 LE Central Extended Scan 中的 与另一块开发板对测。
代码介绍
本章将按照以下几个部分进行介绍:
源码路径 中介绍项目目录和源代码文件。
Bluetooth Host介绍 中介绍了Bluetooth Host相关信息。
初始化 中介绍可配参数和Bluetooth Host初始化。
启动Extended Advertising 中介绍启动Extended Advertising的流程。
GAP消息处理 中介绍本示例工程的GAP消息处理。
GAP回调函数处理 中介绍本示例工程的GAP回调函数处理。
源码路径
工程目录:
samples\bluetooth\ble_bt5_peripheral\proj
。源码目录:
samples\bluetooth\ble_bt5_peripheral\src
。
LE peripheral extended advertising示例工程中的源文件当前被分为几个组,如下所示:
└── Project: bt5_peripheral
└── secure_only_app
└── Device includes startup code
├── CMSE Library Non-secure callable library
├── Lib includes all binary symbol files that user application is built on
├── ROM_NS.lib
└── lowerstack.lib
└── rtl87x2g_sdk.lib
└── gap_utils.lib
├── peripheral includes all peripheral drivers and module code used by the application
├── Profile includes LE profiles or services used by the sample application
└── APP includes the ble_bt5_peripheral user application implementation
├── app_task.c
├── main.c
├── bt5_peripheral_stack_api.c
└── bt5_peripheral_app.c
示例工程使用与 bt_host_0_0
匹配的默认GAP LIB,请参阅文档 Bluetooth Host Image 中的 GAP LIB的使用方法 以获取更多信息。
Bluetooth Host介绍
示例工程默认使用Bluetooth Host image版本 bt_host_0_0
,更多信息可参阅
Bluetooth Host Image。
关于Bluetooth Host所支持的蓝牙功能的详细信息,请参阅文件 bin\rtl87x2g\bt_host_image\bt_host_0_0\bt_host_config.h
。
初始化
当EVB启动并且芯片复位时, main()
函数将被调用,它执行以下初始化函数:
int main(void)
{
board_init();
le_gap_init(APP_MAX_LINKS);
gap_lib_init();
app_le_gap_init();
pwr_mgr_init();
task_init();
os_sched_start();
return 0;
}
le_gap_init()
用于初始化GAP并配置链接个数。app_le_gap_init()
用于初始化GAP参数,开发者可以自行配置以下参数:Device name和device appearance,LE Advertising Extensions参数,GAP Bond Manager参数(请参考 LE Host 中的 Device Name和Device Appearance的配置, LE Advertising Extensions参数的配置, Bond Manager参数的配置)。
void app_le_gap_init(void)
{
/* Device name and device appearance */
......
/* GAP Bond Manager parameters */
......
/* LE Advertising Extensions parameters */
bool use_extended = true;
/* Set device name and device appearance */
le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
&slave_init_mtu_req);
le_set_gap_param(GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_OCTETS, sizeof(max_data_len_tx_oct),
&max_data_len_tx_oct);
le_set_gap_param(GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_TIME, sizeof(max_data_len_tx_time),
&max_data_len_tx_time);
/* Setup the GAP Bond Manager */
gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
&auth_use_fix_passkey);
le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
&auth_sec_req_flags);
/* Use LE Advertising Extensions */
le_set_gap_param(GAP_PARAM_USE_EXTENDED_ADV, sizeof(use_extended), &use_extended);
/* Initialize extended advertising related parameters */
le_init_ext_adv_params_ext_conn();
/* Register gap message callback */
le_register_app_cb(app_gap_callback);
}
启动Extended Advertising
由于支持LE Advertising Extensions,设备可以使用一个或多个advertising sets。 APP需要创建advertising handle以识别advertising set,extended advertising相关参数是针对指定advertising set配置的。 使用LE Advertising Extensions时,APP可以通过修改advertising event properties选择发送legacy advertising PDUs ( LE Peripheral 示例工程只能发送 legacy advertising PDUs)或extended advertising PDUs。
开启extended advertising的流程图如下所示。 Optional 部分取决于advertising event properties。
GAP Extended Advertising相关参数配置
请参考 LE Host 中的 Extended Advertising相关参数的配置 章节。
GAP消息处理
当APP从Bluetooth Host接收到GAP消息时,函数 app_handle_gap_msg()
会被调用。更多关于GAP消息的信息参见 LE Host 中的 蓝牙状态消息。
void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
{
T_LE_GAP_MSG gap_msg;
uint8_t conn_id;
memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
switch (p_gap_msg->subtype)
{
case GAP_MSG_LE_DEV_STATE_CHANGE:
{
app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
gap_msg.msg_data.gap_dev_state_change.cause);
}
break;
.......
}
void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
{
APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, ADV state %d, cause 0x%x",
new_state.gap_init_state, new_state.gap_adv_state, cause);
if (gap_dev_state.gap_init_state != new_state.gap_init_state)
{
if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
{
APP_PRINT_INFO0("GAP stack ready");
/* Stack ready */
......
/* Set extended advertising related parameters */
le_ext_adv_start_setting(adv_handle, EXT_ADV_SET_AUTO);
}
}
gap_dev_state = new_state;
}
当收到 GAP_INIT_STATE_STACK_READY
消息时,该示例工程将调用 le_ext_adv_start_setting()
设置extended advertising相关参数。 EXT_ADV_SET_AUTO
表示将根据advertising event properties自动设置针对指定advertising set的extended advertising相关参数(包括advertising参数、advertising数据和scan response数据)。否则,application需要参考表 使用legacy advertising PDUs的Extended Advertising参数设置 或表 使用extended advertising PDUs的Extended Advertising参数设置 根据advertising event properties设置flags。
void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
{
APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, ADV state %d, cause 0x%x",
new_state.gap_init_state, new_state.gap_adv_state, cause);
if (gap_dev_state.gap_init_state != new_state.gap_init_state)
{
if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
{
APP_PRINT_INFO0("GAP stack ready");
/* Stack ready */
......
/* Set extended advertising related parameters */
le_ext_adv_start_setting(adv_handle, EXT_ADV_SET_AUTO);
}
}
gap_dev_state = new_state;
}
在 app_gap_callback()
调用 le_ext_adv_enable()
之后,APP将收到extended advertising状态消息。更多关于处理extended advertising状态消息的信息参见 LE Host 中的 Extended Advertising状态消息。
当收到 GAP_CONN_STATE_DISCONNECTED
消息时,APP将调用 le_ext_adv_enable()
以使能指定advertising set。在连接断开之后,APP将恢复为可连接状态。
void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
{
APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
conn_id, gap_conn_state, new_state, disc_cause);
switch (new_state)
{
case GAP_CONN_STATE_DISCONNECTED:
{
if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
&& (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
{
APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
}
/* Enable one advertising set */
le_ext_adv_enable(1, &adv_handle);
}
break;
......
}
gap_conn_state = new_state;
}
GAP回调函数处理
app_gap_callback()
用于处理GAP回调函数消息,更多关于GAP回调函数的信息参见 LE Host 中的 Bluetooth LE GAP回调函数。
在协议栈准备就绪之后调用 le_ext_adv_start_setting()
,设置extended advertising参数的结果将在函数 app_gap_callback()
中以回调类型 GAP_MSG_LE_EXT_ADV_START_SETTING
返回。若返回结果表示参数设置成功,APP将使能extended advertising。
首先,APP设置GAP extended advertising使能参数,以决定是否通过使用duration或最大的extended advertising events数目停止extended advertising。APP调用 le_ext_adv_enable()
对一个advertising set使能extended advertising,示例代码如下:
T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
{
T_APP_RESULT result = APP_RESULT_SUCCESS;
T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
APP_PRINT_TRACE1("app_gap_callback: cb_type = 0x%x", cb_type);
switch (cb_type)
{
case GAP_MSG_LE_EXT_ADV_START_SETTING:
APP_PRINT_INFO3("GAP_MSG_LE_EXT_ADV_START_SETTING:cause 0x%x, flag 0x%x, adv_handle %d",
p_data->p_le_ext_adv_start_setting_rsp->cause, p_data->p_le_ext_adv_start_setting_rsp->flag,
p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
if (p_data->p_le_ext_adv_start_setting_rsp->cause == GAP_CAUSE_SUCCESS)
{
/* Initialize enable parameters */
le_init_ext_adv_enable_params(p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
/* Enable one advertising set */
le_ext_adv_enable(1, &p_data->p_le_ext_adv_start_setting_rsp->adv_handle);
}
break;
......
}
}
Extended advertising状态消息在 app_handle_gap_msg()
函数中处理。使能advertising set的结果将在 app_gap_callback()
中以回调类型 GAP_MSG_LE_EXT_ADV_ENABLE
返回,示例代码如下:
T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data)
{
T_APP_RESULT result = APP_RESULT_SUCCESS;
T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
APP_PRINT_TRACE1("app_gap_callback: cb_type = 0x%x", cb_type);
switch (cb_type)
{
case GAP_MSG_LE_EXT_ADV_ENABLE:
APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_ENABLE:cause 0x%x", p_data->le_cause.cause);
break;
......
}
}
当Peripheral extended advertising示例工程在开发板上运行时,设备是可发现且可连接的。对端设备可以对peripheral设备进行扫描,并创建连线。