LE Broadcaster
The LE broadcaster sample demonstrates how to use the LE GAP Broadcaster role to develop many different broadcaster-role based applications. LE GAP Broadcaster role can send non-connectable advertising events and it cannot create connections.
![../../../_images/broadcaster_architecture.png](../../../_images/broadcaster_architecture.png)
The sample uses LE host and LE manager module. The above figure shows the relationships between several modules in the sample.
More information about these modules can be found in the LE Host and LE Manager documentation.
Requirements
The sample supports the following development kits:
Hardware Platforms |
Board Name |
Build Target |
---|---|---|
RTL87x3E HDK |
RTL87x3E EVB |
ble_broadcaster_4M_bank0 ble_broadcaster_16M_bank0 |
RTL87x3D HDK |
RTL87x3D EVB |
ble_broadcaster_8M_bank0 ble_broadcaster_16M_bank0 ble_broadcaster_cs_16M_bank0 |
This sample project can be found under board\evb\ble_broadcaster
in SDK folder structure.
Developers can choose the project according to the Board Name
and choose the Build Target
according to the flash map.
When built for an xxx_4M_xxx
build target, the sample is configured to build and run with a 4M flash map.
When built for an xxx_8M_xxx
build target, the sample is configured to build and run with an 8M flash map.
When built for an xxx_16M_xxx
build target, the sample is configured to build and run with a 16M flash map.
For more requirements, please refer to Quick Start.
Configurations
Configurable Items
All contents that can be configured for the sample are in
src\sample\ble_broadcaster\app_broadcaster_flags.h
,
developers can configure according to actual needs.
/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
#define F_BT_DLPS_EN 1
/** @} */ /* End of group BROADCASTER_Config */
Building and Downloading
Take the project rtl87x3e_ble_broadcaster.uvprojx
and target ble_broadcaster_4M_bank0
as an example,
to build and run the sample with Keil development environment, follow the steps listed below:
Open
rtl87x3e_ble_broadcaster.uvprojx
.Choose the build target
ble_broadcaster_4M_bank0
.Build the target.
After a successful build, the APP bin file
ble_broadcaster_bank0_MP-v0.0.0.0-xxx.bin
will be generated in the directorybin\rtl87x3e\flash_4M_dualbank\bank0
.Download APP bin into EVB.
Press reset button in EVB and it will start LE advertising.
Experimental Verification
After downloading the sample bin to the EVB, developers can test it either by using another
kit that is running the LE Observer sample, or by using a phone which already has installed LE APPs like LightBlue
.
Testing with Another Kit
For more information, please refer to the chapter Testing with Another Kit of LE Observer.
Testing with Phone
Prepare one development boards named DUT, and use Debug Analyzer
tool to get the logs.
For more information, please refer to Debug Analyzer.
Preparation Phase
Use MCUConfig Tool to set DUT address to
[00:11:22:33:44:80]
, and then build the LE broadcaster sample, and download images into DUT.
Testing Phase
Press the reset button on DUT and DUT will start sending non-connectable undirected advertising events.
If the advertisement is successfully enabled, the following
Debug Analyzer
log will be printed. If developers do not see the following log, it means that the advertisement failed to start. Please check if the software and hardware environment is configured correctly.[APP] app_broadcaster_adv_callback:BLE_EXT_ADV_MGR_ADV_ENABLED
Run
LightBlue
on an iOS device to search for DUT.If the phone receives advertising data and scan response data, a screenshot shown as below:
Developers can only implement scanning action on the phone-end because the advertising events sent by DUT is non-connectable.
Code Overview
The main purpose of this chapter is to help APP developers familiarize themselves with the development process related to Broadcaster Role. This chapter will be introduced according to the following several parts:
The directories of the project and source code files will be introduced in chapter Source Code Directory.
The main function will be introduced in chapter Initialization.
The configurable GAP parameters of this sample will be introduced in chapter GAP Parameter Initialization.
The GAP message handler of this sample will be introduced in chapter GAP Message Handler.
Source Code Directory
Project directory:
samples\bluetooth\ble_broadcaster\proj
.Source code directory:
samples\bluetooth\ble_broadcaster\src
.
Source files in LE broadcaster sample project are currently categorized into several groups as below:
└── ble_observer_4M_bank0
├── include ROM UUID header files. Developers do not need to modify it.
├── lib Includes all binary symbol files that user application is built on.
├── gap_utils.lib
├── ROM.lib
├── upperstack_4M.lib
├── hal_utils.lib
├── ble_mgr.lib
└── sysm.lib
├── cmsis The cmsis source code. Developers do not need to modify it.
├── app The application source code.
├── app_broadcaster_adv.c Advertising manager
├── app_broadcaster_gap.c LE GAP initialize and message handler
├── app_broadcaster_main.c Main entry
└── app_broadcaster_task.c APP task
└── io_hal
Initialization
main()
function is invoked when the EVB is powered on and the chip is reset,
and it performs the following initialization functions:
int main(void)
{
board_init();
le_gap_init(0);
gap_lib_init();
app_broadcaster_gap_init();
pwr_mgr_init();
task_init();
os_sched_start();
return 0;
}
le_gap_init()
function is used to initialize GAP and configure link number.app_broadcaster_gap_init()
function is used to initialize the GAP parameters.
GAP Parameter Initialization
The app_broadcaster_gap_init()
function is used to initialize the GAP parameters.
Developers can easily customize the sample by modifying the following parameter values:
void app_broadcaster_gap_init(void)
{
/* register GAP message callback */
le_register_app_cb(app_broadcaster_gap_callback);
/* LE manager module initialize*/
app_broadcaster_gap_ble_mgr_init();
/*advertising parameters initialize*/
app_broadcaster_adv_init_nonconn_public();
}
-
Register GAP message callback function
app_broadcaster_gap_callback()
and all GAP callback messages will be handled in this callback. app_broadcaster_gap_ble_mgr_init()
Initialize LE manager library module to config support LE advertisement and advertising set number. More information can be found in the chapter LE Manager Initialization of LE Manager.
void app_broadcaster_gap_ble_mgr_init(void) { BLE_MGR_PARAMS param = {0}; param.ble_ext_adv.enable = true; param.ble_ext_adv.adv_num = 1; ble_mgr_init(¶m); }
app_broadcaster_adv_init_nonconn_public()
Initialize non-connectable advertising parameters and register advertising callback. More information can be found in the chapter LE Extended Advertising Manager of LE Manager.
void app_broadcaster_adv_init_nonconn_public(void) { T_LE_EXT_ADV_LEGACY_ADV_PROPERTY adv_event_prop = LE_EXT_ADV_LEGACY_ADV_SCAN_UNDIRECTED; uint16_t adv_interval_min = 0xA0; uint16_t adv_interval_max = 0xB0; T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC; T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC; uint8_t peer_address[6] = {0, 0, 0, 0, 0, 0}; T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY; ble_ext_adv_mgr_init_adv_params(&adv_handle, adv_event_prop, adv_interval_min, adv_interval_max, own_address_type, peer_address_type, peer_address, filter_policy, sizeof(adv_data), adv_data, sizeof(scan_rsp_data), scan_rsp_data, NULL); ble_ext_adv_mgr_register_callback(app_broadcaster_adv_callback, adv_handle); }
A device in the broadcast mode shall send data using non-connectable advertising events. Therefore the parameter
adv_evt_type
should be configured as one of the following types:
More information on LE GAP initialization and startup flow can be found in the chapter GAP Parameters Initialization of LE Host.
GAP Message Handler
app_broadcaster_gap_handle_gap_msg()
function is invoked whenever a GAP message is received from the Bluetooth Host.
More information on GAP messages can be found in the chapter Bluetooth LE GAP Message of LE Host.
When the sample handles GAP message, the ble_mgr_handle_gap_msg()
shall be called to handle the GAP message.
void app_broadcaster_gap_handle_gap_msg(T_IO_MSG *p_gap_msg)
{
T_LE_GAP_MSG gap_msg;
memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
ble_mgr_handle_gap_msg(p_gap_msg->subtype, &gap_msg);
APP_PRINT_TRACE1("app_broadcaster_gap_handle_gap_msg: subtype %d", p_gap_msg->subtype);
switch (p_gap_msg->subtype)
{
case GAP_MSG_LE_DEV_STATE_CHANGE:
{
app_broadcaster_gap_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
gap_msg.msg_data.gap_dev_state_change.cause);
}
break;
default:
APP_PRINT_ERROR1("app_broadcaster_gap_handle_gap_msg: unknown subtype %d",
p_gap_msg->subtype);
break;
}
}
The broadcaster sample will call app_broadcaster_adv_start()
to start advertising when receiving GAP_INIT_STATE_STACK_READY
.
If app_broadcaster_adv_start()
returns true
, it means the Bluetooth Host has already received this command and is ready to execute.
When this command execution completes, the Bluetooth Host will send BLE_EXT_ADV_MGR_ADV_ENABLED
to app_broadcaster_adv_callback()
.
When the LE broadcaster sample runs on the EVB, the device will send non-connectable advertising events.
void app_broadcaster_gap_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
{
APP_PRINT_INFO3("app_broadcaster_gap_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("app_broadcaster_gap_handle_dev_state_evt: GAP stack ready");
/*stack ready*/
app_broadcaster_adv_start(0);
}
}
gap_dev_state = new_state;
}
static void app_broadcaster_adv_callback(uint8_t cb_type, void *p_cb_data)
{
T_BLE_EXT_ADV_CB_DATA cb_data;
memcpy(&cb_data, p_cb_data, sizeof(T_BLE_EXT_ADV_CB_DATA));
switch (cb_type)
{
case BLE_EXT_ADV_STATE_CHANGE:
{
APP_PRINT_TRACE2("app_broadcaster_adv_callback: adv_state %d, adv_handle %d",
cb_data.p_ble_state_change->state, cb_data.p_ble_state_change->adv_handle);
adv_state = cb_data.p_ble_state_change->state;
if (adv_state == BLE_EXT_ADV_MGR_ADV_ENABLED)
{
APP_PRINT_TRACE0("app_broadcaster_adv_callback: BLE_EXT_ADV_MGR_ADV_ENABLED");
}
else if (adv_state == BLE_EXT_ADV_MGR_ADV_DISABLED)
{
APP_PRINT_TRACE0("app_broadcaster_adv_callback: BLE_EXT_ADV_MGR_ADV_DISABLED");
switch (cb_data.p_ble_state_change->stop_cause)
{
case BLE_EXT_ADV_STOP_CAUSE_APP:
break;
case BLE_EXT_ADV_STOP_CAUSE_CONN:
break;
case BLE_EXT_ADV_STOP_CAUSE_TIMEOUT:
break;
default:
break;
}
APP_PRINT_TRACE2("app_broadcaster_adv_callback: stack stop adv cause 0x%x, app stop adv cause 0x%02x",
cb_data.p_ble_state_change->stop_cause, cb_data.p_ble_state_change->app_cause);
}
}
break;
default:
break;
}
}
Troubleshooting
How to Modify the Parameters of Advertising Data?
The advertising data is defined in the following array adv_data
, and developer can directly modify the content of the array to modify the advertising data.
static uint8_t adv_data[] =
{
/* Flags */
0x02, /* length */
GAP_ADTYPE_FLAGS, /* type="Flags" */
GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
/* Local name */
0x10,
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
'B', 'L', 'E', '_', 'B', 'R', 'O', 'A', 'D', 'C', 'A', 'S', 'T', 'E', 'R'
};