LE Observer
The LE observer sample demonstrates how to use the LE GAP Observer role to develop many different observer-role based applications. LE GAP Observer role can receive scannable advertising events, and it cannot create connections.
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_observer_4M_bank0 ble_observer_16M_bank0 |
RTL87x3D HDK |
RTL87x3D EVB |
ble_observer_8M_bank0 ble_observer_16M_bank0 ble_observer_cs_16M_bank0 |
This sample project can be found under board\evb\ble_observer
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.
To quickly set up the development environment, please refer to the detailed instructions provided in Quick Start.
Wiring
Please refer to EVB Interfaces and Modules in Quick Start.
Configurations
Configurable Items
All contents that can be configured for the sample are in
src\sample\ble_observer\app_observer_flags.h
,
developers can configure according to actual needs.
/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
#define F_BT_DLPS_EN 1
Building and Downloading
Take the project rtl87x3e_ble_observer.uvprojx
and target ble_observer_4M_bank0
as an example, to build and run the sample with Keil development environment, follow the steps listed below:
Open
rtl87x3e_ble_observer.uvprojx
.Choose the build target
ble_observer_4M_bank0
.Build the target.
After a successful build, the APP bin file
ble_observer_bank0_MP-v0.0.0.0-xxx.bin
will be generated in the directorybin\rtl87x3e\flash_4M_dualbank\bank0
.Download APP bin into the EVB.
Press the reset button on the EVB and it will start LE scanning.
Experimental Verification
After downloading the sample bin to the EVB, developers can test it by using another kit that is running the LE Broadcaster sample.
Testing with Another Kit
Prepare two development boards named DUT and Tester respectively. Developers can capture SoC logs using Debug Analyzer.
Preparation Phase
Use the MCUConfig Tool to set the DUT address to
[00:11:22:33:44:85]
, and then build the LE observer sample, and download the images into the DUT.Use the MCUConfig Tool to set the Tester address to
[00:11:22:33:44:80]
, and then build the LE broadcaster sample, and download the images into the Tester.
Testing Phase
Press reset button on Tester and Tester will start sending non-connectable undirected advertising events.
If the broadcast is successfully enabled, the following log will be printed. If the following log is not seen, it means that the broadcast 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
Press reset button on DUT and DUT will start scanning.
In the DUT log, use the DUT address to find if the broadcast was scanned. If Tester receives advertising data and scan response data, the sample will receive event
BLE_SCAN_REPORT
. The logs are shown below:[APP] !**app_scan_cb: BLE_SCAN_REPORT event_type 0x13, bd_addr 00::11::22::33::44::80, addr_type 1, rssi -94, data_len 31, data_status 0x0
Code Overview
The main purpose of this chapter is to help sample developers become familiar with the development process related to the Observer 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 GAP message handler of this sample will be introduced in chapter GAP Message Handler.
Source Code Directory
Project directory:
board\evb\ble_observer
.Source code directory:
src\sample\ble_observer
.
Source files in the 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_observer_main.c Main entry
├── app_observer_gap.c LE GAP initialize and message handler
├── app_observer_scan.c Scan manager
└── app_observer_task.c APP task
└── io_hal
Initialization
The main()
function is invoked when the board is powered on or the chip boots up, and it performs the following initialization functions:
int main(void)
{
board_init();
le_gap_init(0);
gap_lib_init();
app_gap_init();
pwr_mgr_init();
task_init();
os_sched_start();
return 0;
}
The app_gap_init()
function is used to initialize the GAP parameters.
Developers can easily customize the sample by modifying the following parameter values.
void app_gap_init(void)
{
/* register GAP message callback */
le_register_app_cb(app_gap_callback);
/* ble manager module initialize*/
app_gap_ble_mgr_init();
}
-
Register the GAP message callback function
app_gap_callback()
, and all GAP callback messages will be handled in this callback. app_gap_ble_mgr_init()
Initialize the LE manager to configure support for LE scan. More information on LE manager library initialization can be found in the chapter LE Manager Initialization of LE Manager.
void app_gap_ble_mgr_init(void) { BLE_MGR_PARAMS param = {0}; param.ble_scan.enable = true; ble_mgr_init(¶m); }
More information on LE GAP initialization and startup flow can be found in the chapter GAP Parameters Initialization of LE Host.
GAP Message Handler
The app_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.
The observer sample will call the app_scan_start()
function to start scanning when receiving GAP_INIT_STATE_STACK_READY
.
When the LE observer sample is running on an EVB, the LE device will start scanning.
If an advertising report has been received, the LE manager library will send BLE_SCAN_REPORT
to the app_scan_cb()
function.
void app_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_ERROR1("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;
default:
//APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
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, scan state %d, cause 0x%x",
new_state.gap_init_state,
new_state.gap_scan_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_handle_dev_state_evt: GAP stack ready");
/*stack ready*/
app_scan_start(APP_SCAN_INTERVAL, APP_SCAN_WINDOW);
}
}
gap_dev_state = new_state;
}
static void app_scan_cb(BLE_SCAN_EVT evt, BLE_SCAN_EVT_DATA *data)
{
uint8_t scan_state = ble_scan_get_cur_state();
switch (evt)
{
case BLE_SCAN_REPORT:
APP_PRINT_INFO6("app_scan_cb: BLE_SCAN_REPORT event_type 0x%x, bd_addr %s, addr_type %d, rssi %d, data_len %d, data_status 0x%x",
data->report->event_type,
TRACE_BDADDR(data->report->bd_addr),
data->report->addr_type,
data->report->rssi,
data->report->data_len,
data->report->data_status);
break;
default:
break;
}
}