This project utilizes the Concurrent Multi-protocol Timeslot API in Nordic Semiconductor's S110 v8.0 SoftDevice for the nRF51-series micro-controllers to run a scannable advertiser concurrently with the SoftDevice. The provided build scripts and project files support both the PCA10028 and PCA10031 development boards.
This project also contains an example of how to run a concurrent multi-protocol observer concurrently with the SoftDevice.
The Timeslot advertiser and scanner accept a subset of the HCI command interface to control various parameters of their behaviour.
Scan Requests that arrive at the advertiser are also sent to the application. The scan requests are sent with the address, RSSI, channel and an experimental link quality indicator.
The experimental link quality indicator that counts the number of packets with CRC failures and the number packets with successful CRC has been added. This allows the application to have some awareness of the link quality. The link quality is returned by the observer and by the scannable advertiser.
- S110 v8.0 production SoftDevice
- nRF51 SDK v9.0
- Keil uVision or an arm-none-eabi GCC toolchain
Clone this GitHub repository into the examples/ folder of the nRF51 SDK directory.
The project contains an example of advertiser usage, where the Timeslot advertiser runs with an advertisement interval of 100ms, alongside a SoftDevice-powered connectable advertiser with an advertisement interval of 150ms.
Both the timeslot advertiser and timeslot observer have been tested for conformance with Bluetooth SIG Core Spec 4.0 for their specific functionality. The logs for these tests are in https://github.com/NordicSemiconductor/nRF51-multi-role-conn-observer-advertiser/tree/Conformance_Testing/Conf_Logs along with a summary of testing.
The timeslot advertiser interface is based on the Bluetooth standard HCI interface, but only implements a small subset of the functionality. All interface functions are found in the Include/nrf_advertiser.h file.
The timeslot advertiser offers reports related to radio activity to the user. The software interrupt indicated by the user in the btle_hci_adv_init() function is triggered when there are available reports in the queue. The user may then use the btle_hci_adv_report_get() function to pull reports from the queue. The reports contain the total number of valid/invalid packets received and an HCI btle_evt_t structure that indicates what kind of event triggered the report.
NOTE: The BLE specification does not define any scan report events, so a special event type was added for this: BTLE_VS_EVENT_NRF_SCAN_REQUEST_RECEIVED. It contains the address and address type of the scanner in addition to RSSI and channel.
void btle_hci_adv_init(IRQn_Type btle_hci_adv_evt_irq);
Initialize the timeslot advertiser. The IRQ parameter decides which software interrupt to use for the generated events. For each report the advertiser generates, the selected IRQ flag will be set, and the user may get events from the queue using btle_hci_adv_evt_get().
bool btle_hci_adv_report_get(nrf_report_t* report);
Function for getting pending tsa reports. It is recommended to repeat this function until it returns false, as there may be more than one pending report in the queue.
void btle_hci_adv_sd_evt_handler(uint32_t event);
SoftDevice event handler for the timeslot advertiser. Takes any timeslot event generated by SoftDevice function sd_evt_get().
void btle_hci_adv_params_set(btle_cmd_param_le_write_advertising_parameters_t* adv_params);
Set the advertisement parameters for the timeslot advertiser. See hci/btle.h for details about the struct parameter
void btle_hci_adv_enable(btle_adv_mode_t adv_enable);
Enable or disable advertisement
void btle_hci_adv_data_set(btle_cmd_param_le_write_advertising_data_t* adv_data);
Set the content of the timeslot advertiser advertisement packets. This does not include any headers or address, as this is controlled internally. To set the advertisement address, use the btle_hci_adv_params_set() function.
void btle_hci_adv_scan_rsp_data_set(btle_cmd_param_le_write_scan_response_data_t* scan_rsp);
Set the content of the timeslot advertiser scan response packet. This is the packet the beacon will send to respond to external scan requests. This does not include any headers or address, as this is controlled internally. To set the advertisement address, use the btle_hci_adv_params_set() function.
void btle_hci_adv_whitelist_add(btle_cmd_param_le_add_device_to_whitelist_t* whitelist_device);
Add a scanner to the device whitelist. If the whitelist filter is enabled, only scanners on this whitelist will be accepted.
The filter can be enabled with the btle_hci_adv_params_set() function above.
void btle_hci_adv_whitelist_remove(btle_cmd_param_le_remove_device_from_whitelist_t* whitelist_device);
Remove a scanner from the device whitelist. If the whitelist filter is enabled, only scanners on this whitelist will be accepted.
The filter can be enabled with the btle_hci_adv_params_set() function above.
void btle_hci_adv_whitelist_flush(void);
Remove all scanners from the device whitelist. If the whitelist filter is enabled, only scanners on this whitelist will be accepted.
The filter can be enabled or disabled with the btle_hci_adv_params_set() function above. Note that this function does not disable the filter functionality.
The timeslot observer interface is also based on the Bluetooth standard HCI interface, but only implements a small subset of the functionality. All interface functions are found in the Include/nrf_scan.h file.
The interface documenation for the Observer will be added in the next release.