外围设备
外围设备支持开启传统广播流程、扩展广播流程以及周期性广播流程。
开启传统广播流程
当设备开启传统广播流程时,APP与BLE Stack之间的交互流程如图 6所示。
步骤中的代码片段出自于传统广播流程示例ble_app_gap_legacy_adv (SDK_Folder\projects\ble\ble_basic_example\)。
- 设置广播参数。
s_gap_adv_param.adv_intv_max = APP_ADV_MAX_INTERVAL; s_gap_adv_param.adv_intv_min = APP_ADV_MIN_INTERVAL; s_gap_adv_param.adv_mode = GAP_ADV_TYPE_ADV_IND; s_gap_adv_param.chnl_map = GAP_ADV_CHANNEL_37_38_39; s_gap_adv_param.disc_mode = GAP_DISC_MODE_NON_DISCOVERABLE; s_gap_adv_param.filter_pol = GAP_ADV_ALLOW_SCAN_ANY_CON_ANY; error_code = ble_gap_adv_param_set(0, BLE_GAP_OWN_ADDR_STATIC, &s_gap_adv_param); APP_ERROR_CHECK(error_code);说明:- 定向广播的可发现模式只能设置为GAP_DISC_MODE_NON_DISCOVERABLE(不可发现)。
- 发现模式如果为GAP_DISC_MODE_BROADCASTER,则广播模式只能设置为GAP_ADV_TYPE_ADV_NONCONN_IND(不可连接也不可扫描)。
- peer_addr参数只在定向广播或者是controller privacy被使能(即ble_gap_privacy_params_set函数的第二个参数BLE_GAP_PRIV_CFG_PRIV_EN_BIT被置位)的情况下才会使用。
-
代码路径:
SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_legacy_adv\Src\user\user_app.c
- 设置广播数据(可选)。
adv_mode为GAP_ADV_TYPE_ADV_HIGH_DIRECT_IND或GAP_ADV_TYPE_ADV_LOW_DIRECT_IND时,无需设置广播数据,其他情况则需设置。
- 设置扫描响应数据(可选)。
adv_mode为GAP_ADV_TYPE_ADV_IND或GAP_ADV_TYPE_ADV_SCAN_IND时,需设置扫描响应数据,其他情况则无需设置。
static const uint8_t s_adv_data_set[] = { 0x03, BLE_GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID, 0x01, 0x00, }; static const uint8_t s_adv_rsp_data_set[] = { 0x0b, BLE_GAP_AD_TYPE_COMPLETE_NAME, 'L', 'e', 'g', 'a', 'c', 'y', '_', 'A', 'D', 'V', }; error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_DATA, s_adv_data_set, sizeof(s_adv_data_set)); APP_ERROR_CHECK(error_code); error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_SCAN_RSP, s_adv_rsp_data_set, sizeof(s_adv_rsp_data_set)); APP_ERROR_CHECK(error_code);说明:adv data以及adv rsp data必须按照Bluetooth Core Spec规定的格式进行组合,即(length, type, data)。其中length所指示的长度为type字段与data字段的总长度。
代码路径:SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_legacy_adv\Src\user\user_app.c
- 开启广播
调用ble_gap_adv_start函数开启广播时需要用户传入参数adv_idx,以便指定广播实例索引。支持最多同时建立5个传统广播,所以adv_idx的取值范围是[0,1,2,3,4]。
s_gap_adv_time_param.duration = 0; s_gap_adv_time_param.max_adv_evt = 0; error_code = ble_gap_adv_start(0, &s_gap_adv_time_param); APP_ERROR_CHECK(error_code);说明:代码路径:SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_legacy_adv\Src\user\user_app.c
- 广播开启成功后调用回调函数app_gap_adv_start_cb。
说明:
如果用户希望更新广播参数,则可以在广播停止后调用ble_gap_adv_data_set和ble_gap_adv_param_set接口重新配置广播数据和广播参数,再调用ble_gap_adv_start来启动广播。
- 如果广播参数的scan_req_ind_en值为true,那么当收到对端设备发送的扫描请求时,app_gap_scan_req_ind_cb回调函数将被调用。
开启扩展广播流程
当设备开启扩展广播流程时,APP与BLE Stack之间的交互流程如图 7所示。
步骤中的代码片段出自于扩展广播流程示例ble_app_gap_extended_adv(SDK_Folder\projects\ble\ble_basic_example\
- 设置扩展广播参数。
s_gap_adv_param.type = GAP_ADV_TYPE_EXTENDED; s_gap_adv_param.disc_mode = GAP_DISC_MODE_GEN_DISCOVERABLE; /* The advertisement shall not be both connectable and scannable, and High duty cycle directed advertising cannot be used */ s_gap_adv_param.prop = GAP_ADV_PROP_CONNECTABLE_BIT; s_gap_adv_param.max_tx_pwr = 0; s_gap_adv_param.filter_pol = GAP_ADV_ALLOW_SCAN_ANY_CON_ANY; memset(&s_gap_adv_param.peer_addr, 0, sizeof(gap_bdaddr_t)); s_gap_adv_param.prim_cfg.adv_intv_min = APP_ADV_MIN_INTERVAL; s_gap_adv_param.prim_cfg.adv_intv_max = APP_ADV_MAX_INTERVAL; s_gap_adv_param.prim_cfg.chnl_map = GAP_ADV_CHANNEL_37_38_39; s_gap_adv_param.prim_cfg.phy = GAP_PHY_1MBPS_VALUE; s_gap_adv_param.second_cfg.max_skip = 0; s_gap_adv_param.second_cfg.phy = GAP_PHY_1MBPS_VALUE; s_gap_adv_param.second_cfg.adv_sid = 0x00; s_gap_adv_param.period_cfg.adv_intv_min = 0; s_gap_adv_param.period_cfg.adv_intv_max = 0; error_code = ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_STATIC, &s_gap_adv_param); APP_ERROR_CHECK(error_code);说明:- 在两种情况下prop参数中GAP_ADV_PROP_DIRECTED_BIT可以被置位,一种情况是:disc_mode参数设置为GAP_DISC_MODE_NON_DISCOVERABLE;一种情况是:disc_mode参数设置为GAP_DISC_MODE_BROADCASTER,并且参数GAP_ADV_PROP_ANONYMOUS_BIT被置位。
- 扩展广播不支持High Duty的定向广播,因此在扩展广播中prop参数的GAP_ADV_PROP_HDC_BIT不能被置位。
- 扩展广播不支持既可扫描又可连接的广播,因此prop参数中GAP_ADV_PROP_CONNECTABLE_BIT和GAP_ADV_PROP_SCANNABLE_BIT不能被同时置位。
- 如果prop参数中GAP_ADV_PROP_ANONYMOUS_BIT被置位,则disc_mode参数只能设置为:GAP_DISC_MODE_NON_DISCOVERABLE或者 GAP_DISC_MODE_BROADCASTER。
- 如果prop参数中GAP_ADV_PROP_ANONYMOUS_BIT被置位,则prop参数中的GAP_ADV_PROP_CONNECTABLE_BIT和GAP_ADV_PROP_SCANNABLE_BIT都不能被置位。
- peer_addr参数只在定向广播或者controller privacy被使能(即ble_gap_privacy_params_set函数的第二个参数 BLE_GAP_PRIV_CFG_PRIV_EN_BIT被置位)的情况下被使用。
代码路径:SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_extended_adv\Src\user\user_app.c
- 设置广播数据(可选)。如果prop参数中GAP_ADV_PROP_SCANNABLE_BIT被置位,则无需设置。
- 设置扫描响应数据(可选)。如果prop参数中GAP_ADV_PROP_SCANNABLE_BIT被置位,则需设置。
static const uint8_t s_adv_data_set[] = { 0x03, BLE_GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID, 0x01, 0x00, }; static const uint8_t s_adv_rsp_data_set[] = { 0x0d, BLE_GAP_AD_TYPE_COMPLETE_NAME, 'E', 'x', 't', 'e', 'n', 'd', 'e', 'd', '_', 'A', 'D', 'V', }; error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_DATA, s_adv_data_set,sizeof(s_adv_data_set)); APP_ERROR_CHECK(error_code); error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_SCAN_RSP, s_adv_rsp_data_set,sizeof(s_adv_rsp_data_set)); APP_ERROR_CHECK(error_code);说明:adv data以及adv rsp data必须按照Bluetooth Core Spec规定的格式进行组合,即(length, type, data)。length的长度为type字段与data字段的总长度。
代码路径:SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_extended_adv\Src\user\user_app.c
- 开启广播。
调用ble_gap_adv_start函数开启广播时需要用户传入参数adv_idx,以便指定广播实例索引。支持最多同时建立5个扩展广播,所以adv_idx的取值范围是[0,1,2,3,4]。
s_gap_adv_time_param.duration = 0; s_gap_adv_time_param.max_adv_evt = 0; error_code = ble_gap_adv_start(0, &s_gap_adv_time_param); APP_ERROR_CHECK(error_code);说明:代码路径:SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_extended_adv\Src\user\user_app.c
- 广播开启成功后调用回调函数app_gap_adv_start_cb。
- 如果广播参数的prop中的GAP_ADV_PROP_SCAN_REQ_NTF_EN_BIT置位,那么当收到对端设备发送过来的扫描请求时,app_gap_scan_req_ind_cb回调函数将被调用。
开启周期性广播流程
当设备开启周期性广播流程时,APP与BLE Stack之间的交互流程如图 8所示。
开启周期性广播流程的具体步骤如下:
步骤中的代码片段出自于周期性广播流程示例ble_app_gap_periodic_adv(SDK_Folder\projects\ble\ble_basic_example\)。
- 设置广播参数。
s_gap_adv_param.type = GAP_ADV_TYPE_PERIODIC; s_gap_adv_param.disc_mode = GAP_DISC_MODE_GEN_DISCOVERABLE; /* Connectable, anonymous, scannable, high duty circle bit must be set to 0 */ s_gap_adv_param.prop = 0; s_gap_adv_param.max_tx_pwr = 0; s_gap_adv_param.filter_pol = GAP_ADV_ALLOW_SCAN_ANY_CON_ANY; memset(&s_gap_adv_param.peer_addr, 0, sizeof(gap_bdaddr_t)); s_gap_adv_param.prim_cfg.adv_intv_min = APP_PRIMARY_ADV_MIN_INTERVAL; s_gap_adv_param.prim_cfg.adv_intv_max = APP_PRIMARY_ADV_MAX_INTERVAL; s_gap_adv_param.prim_cfg.chnl_map = GAP_ADV_CHANNEL_37_38_39; s_gap_adv_param.prim_cfg.phy = GAP_PHY_1MBPS_VALUE; s_gap_adv_param.second_cfg.max_skip = 0; s_gap_adv_param.second_cfg.phy = GAP_PHY_1MBPS_VALUE; s_gap_adv_param.second_cfg.adv_sid = 0x00; s_gap_adv_param.period_cfg.adv_intv_min = APP_PERIODIC_ADV_MIN_INTERVAL; s_gap_adv_param.period_cfg.adv_intv_max = APP_PERIODIC_ADV_MAX_INTERVAL; error_code = ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_STATIC, &s_gap_adv_param); APP_ERROR_CHECK(error_code);说明:- 在配置周期性广播参数过程中,prop参数的GAP_ADV_PROP_CONNECTABLE_BIT,GAP_ADV_PROP_SCANNABLE_BIT,GAP_ADV_PROP_ANONYMOUS_BIT,
GAP_ADV_PROP_HDC_BIT都不能被置位。
- peer_addr参数只在定向广播或者controller privacy被使能(即ble_gap_privacy_params_set函数的第二个参数BLE_GAP_PRIV_CFG_PRIV_EN_BIT被置位)的情况下才会使用。
-
代码路径:SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_periodic_adv\Src\user\user_app.c
- 在配置周期性广播参数过程中,prop参数的GAP_ADV_PROP_CONNECTABLE_BIT,GAP_ADV_PROP_SCANNABLE_BIT,GAP_ADV_PROP_ANONYMOUS_BIT,
- 设置广播数据。
- 设置周期性广播数据(可选)。
static const uint8_t s_adv_data_set[] = { 0x03, BLE_GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID, 0x01, 0x00, 0x0d, BLE_GAP_AD_TYPE_COMPLETE_NAME, 'P', 'e', 'r', 'i', 'o', 'd', 'i', 'c', '_', 'A', 'D', 'V', }; static const uint8_t s_periodic_adv_data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_DATA, s_adv_data_set, sizeof(s_adv_data_set)); APP_ERROR_CHECK(error_code); error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_PER_DATA, s_periodic_adv_data,sizeof(s_periodic_adv_data)); APP_ERROR_CHECK(error_code);说明:- adv data以及periodic_adv_data必须按照Bluetooth Core Spec规定的格式进行组合,即(length, type, data)。其中length所指示的长度为type字段与data字段的总长度。
-
代码路径:SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_periodic_adv\Src\user\user_app.c
- 开启广播。调用ble_gap_adv_start函数开启广播时需要用户传入参数adv_idx,以便指定广播实例索引。支持最多同时建立5个周期性广播,所以adv_idx的取值范围是[0,1,2,3,4]。
s_gap_adv_time_param.duration = 0; s_gap_adv_time_param.max_adv_evt = 0; error_code = ble_gap_adv_start(0, &s_gap_adv_time_param); APP_ERROR_CHECK(error_code);说明:代码路径:SDK_Folder\projects\ble\ble_basic_example\ble_app_gap_periodic_adv\Src\user\user_app.c
- 广播开启成功后调用回调函数app_gap_adv_start_cb。
另外,需要注意的是系统在同一时间最多能同时开启五个广播,含传统广播、扩展广播和周期性广播。