Scanning module
The scanning module handles the Bluetooth® Low Energy scanning for your application.
Overview
Use the scanning module to find advertising devices and establish connections with them. The module can automatically establish connection after a filter match. It can also receive directed advertising packets.
The scanning module can work in one of the following modes:
Simple mode - Works without filters.
Advanced mode - Allows using advanced filters.
Configuration
Use the CONFIG_BT_SCAN
Kconfig option to enable the library in the build system.
Blocklist
Devices can be added to the blocklist, which means that the scanning module ignores these devices and does not generate any events for them.
Use the CONFIG_BT_SCAN_BLOCKLIST
Kconfig option to enable the blocklist.
In the default configuration, the scanning module allows to add up to two devices to the blocklist.
To increase the blocklist size, set the CONFIG_BT_SCAN_BLOCKLIST_LEN
Kconfig option.
Use the bt_scan_blocklist_device_add()
function to add a new device to the blocklist.
To remove all devices from the blocklist, use the bt_scan_blocklist_clear()
function.
Directed advertising
To receive directed advertising packets through the scanning module, enable one of the following Kconfig options in Zephyr:
CONFIG_BT_PRIVACY
- Scan with changing addresses.CONFIG_BT_SCAN_WITH_IDENTITY
- Scan with a local identity address.
It is recommended to enable the CONFIG_BT_PRIVACY
Kconfig option to support directed advertising only between bonded peers.
Use the CONFIG_BT_SCAN_WITH_IDENTITY
Kconfig option only when the CONFIG_BT_PRIVACY
Kconfig option is not available.
When the scanning module is set to the advanced mode and filters are set, you can use the filter_no_match
event to check if directed advertising packets have been received.
They will typically not match any filter as, by specification, they do not contain any advertising data.
If there is no match, you can establish a connection without the need to disable or reconfigure the existing filters.
The following code sample demonstrates the usage of the filter_no_match
event:
static void scan_filter_no_match(struct bt_scan_device_info *device_info,
bool connectable)
{
int err;
struct bt_conn *conn;
char addr[BT_ADDR_LE_STR_LEN];
if (device_info->recv_info->adv_type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
bt_addr_le_to_str(device_info->recv_info->addr, addr,
sizeof(addr));
printk("Direct advertising received from %s\n", addr);
bt_scan_stop();
err = bt_conn_le_create(device_info->recv_info->addr,
BT_CONN_LE_CREATE_CONN,
device_info->conn_param, &conn);
if (!err) {
default_conn = bt_conn_ref(conn);
bt_conn_unref(conn);
}
}
}
Usage
You can use the scanning module to execute actions described in the sections below.
Initializing
To initialize the module, call the bt_scan_init()
function.
You can also call the function without an initialization structure.
When you pass the initialization structure as NULL
, the default static configuration is used.
This configuration is also used when you initialize the module with a structure that has NULL
pointers set for scan and connection parameters.
Scanning
Call the following functions to perform basic scanning activities:
bt_scan_start()
- Start scanning.In the simple mode, when you do not use the event handler, you can establish a connection when the scanner finds the device.
bt_scan_params_set()
- Change parameters.bt_scan_stop()
- Stop scanning manually.Scanning stops automatically if the module established the connection.
bt_scan_start()
- Resume scanning.
Filtering
Use filters in the advanced mode to narrow down the scan to devices of a specific type and mode.
Filter types
See the following table for the details on the available filter types:
Filter type |
Details |
---|---|
Name |
The filter is set to the target name. |
Short name |
The filter is set to the target short name. |
Address |
The filter is set to the target address. |
UUID |
The filter is set to the target UUID. |
Appearance |
The filter is set to the target appearance. |
Filter modes
See the following table for the details on the behavior of the available filter modes:
Filter mode |
Behavior |
---|---|
Normal |
It triggers a filter match callback when only one of the filters set matches, regardless of the type. |
Multifilter |
It triggers a filter match callback only when both of the following conditions happen:
For example, several filters can be set for name, address, UUID, and appearance. To trigger a filter match callback in this scenario, all of the following types must match:
If not all of these types match, the |
Connection attempts filter
After a scanning session is started by the application, some peripheral devices can disconnect immediately. This might result in a loop of the connection and disconnection events.
To avoid that, enable the CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER
Kconfig option that limits the number of the connection attempts.
This filter automatically tracks the connected devices and counts all disconnection events for them. If the number of disconnections is greater than or equal to the number of the allowed attempts, the scanning module ignores this device.
Filtered devices must be removed manually from the filter array through the bt_scan_conn_attempts_filter_clear()
function.
Use this function before each scan starts, unless your application has different requirements.
If the filter array is full, the scanning module overwrites the oldest device with the new one.
In the default configuration, the filter allows to add two devices and limits the connection attempts to two.
To increase the number of devices, set the CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER_LEN
Kconfig option.
The CONFIG_BT_SCAN_CONN_ATTEMPTS_COUNT
Kconfig option adjusts the number of connection attempts.
Samples using the library
The nRF Desktop application uses this library.
Dependencies
There are no dependencies for using this library.
API documentation
include/bluetooth/scan.h
subsys/bluetooth/scan.c
- group nrf_bt_scan
BT Scanning module.
The Scanning Module handles the Bluetooth LE scanning for your application. The module offers several criteria for filtering the devices available for connection, and it can also work in the simple mode without using the filtering. If an event handler is provided, your main application can react to a filter match. The module can also be configured to automatically connect after it matches a filter.
Note
The Scanning Module also supports applications with a multicentral link.
Defines
-
BT_SCAN_CB_INIT(_name, match_fun, no_match_fun, error_fun, connecting_fun)
Initializing macro for scanning module.
This is macro initializing necessary structures for bt_scan_cb type.
- Parameters:
_name – [in] Unique name for bt_scan_cb structure.
match_fun – [in] Scan filter matched function pointer.
no_match_fun – [in] Scan filter unmatched (the device was not found) function pointer.
error_fun – [in] Error when connecting function pointer.
connecting_fun – [in] Connecting data function pointer.
Enums
-
enum bt_scan_type
Scan types.
Values:
-
enumerator BT_SCAN_TYPE_SCAN_PASSIVE
Passive scanning.
-
enumerator BT_SCAN_TYPE_SCAN_ACTIVE
Active scanning.
-
enumerator BT_SCAN_TYPE_SCAN_PASSIVE
-
enum bt_scan_filter_type
Types of filters.
Values:
-
enumerator BT_SCAN_FILTER_TYPE_NAME
Filter for names.
-
enumerator BT_SCAN_FILTER_TYPE_SHORT_NAME
Filter for short names.
-
enumerator BT_SCAN_FILTER_TYPE_ADDR
Filter for addresses.
-
enumerator BT_SCAN_FILTER_TYPE_UUID
Filter for UUIDs.
-
enumerator BT_SCAN_FILTER_TYPE_APPEARANCE
Filter for appearances.
-
enumerator BT_SCAN_FILTER_TYPE_MANUFACTURER_DATA
Filter for manufacturer data.
-
enumerator BT_SCAN_FILTER_TYPE_NAME
Functions
-
void bt_scan_cb_register(struct bt_scan_cb *cb)
Register scanning callbacks.
Register callbacks to monitor the state of scanning.
- Parameters:
cb – Callback struct.
-
void bt_scan_init(const struct bt_scan_init_param *init)
Function for initializing the Scanning Module.
- Parameters:
init – [in] Pointer to scanning module initialization structure. Can be initialized as NULL. If NULL, the parameters required to initialize the module are loaded from static configuration. If module is to establish the connection automatically, this must be initialized with the relevant data.
-
int bt_scan_start(enum bt_scan_type scan_type)
Function for starting scanning.
This function starts the scanning according to the configuration set during the initialization.
- Parameters:
scan_type – [in] The choice between active and passive scanning.
- Returns:
0 If the operation was successful. Otherwise, a (negative) error code is returned.
-
int bt_scan_stop(void)
Function for stopping scanning.
-
void bt_scan_update_init_conn_params(struct bt_le_conn_param *new_conn_param)
Function to update initial connection parameters.
Note
The function should not be used when scanning is active.
- Parameters:
new_conn_param – [in] New initial connection parameters.
-
int bt_scan_filter_enable(uint8_t mode, bool match_all)
Function for enabling filtering.
The filters can be combined with each other. For example, you can enable one filter or several filters. For example, (BT_SCAN_NAME_FILTER | BT_SCAN_UUID_FILTER) enables UUID and name filters.
- Parameters:
mode – [in] Filter mode: Filter modes.
match_all – [in] If this flag is set, all types of enabled filters must be matched before generating BT_SCAN_EVT_FILTER_MATCH to the main application. Otherwise, it is enough to match one filter to trigger the filter match event.
- Returns:
0 If the operation was successful. Otherwise, a (negative) error code is returned.
-
void bt_scan_filter_disable(void)
Function for disabling filtering.
This function disables all filters. Even if the automatic connection establishing is enabled, the connection will not be established with the first device found after this function is called.
-
int bt_scan_filter_status_get(struct bt_filter_status *status)
Function for getting filter status.
This function returns the filter setting and whether it is enabled or disabled.
- Parameters:
status – [out] Pointer to Filter Status structure.
- Returns:
0 If the operation was successful. Otherwise, a (negative) error code is returned.
-
int bt_scan_filter_add(enum bt_scan_filter_type type, const void *data)
Function for adding any type of filter to the scanning.
This function adds a new filter by type. The filter will be added if there is available space in this filter type array, and if the same filter has not already been set.
- Parameters:
type – [in] Filter type.
data – [in] Pointer to the filter data to add.
- Returns:
0 If the operation was successful. Otherwise, a (negative) error code is returned.
-
void bt_scan_filter_remove_all(void)
Function for removing all set filters.
The function removes all previously set filters.
Note
After using this function the filters are still enabled.
-
int bt_scan_params_set(struct bt_le_scan_param *scan_param)
Function for changing the scanning parameters.
Use this function to change scanning parameters. During the parameter change the scan is stopped. To resume scanning, use bt_scan_start. Scanning parameters can be set to NULL. If so, the default static configuration is used.
- Parameters:
scan_param – [in] Pointer to Scanning parameters. Can be initialized as NULL.
- Returns:
0 If the operation was successful. Otherwise, a (negative) error code is returned.
-
void bt_scan_conn_attempts_filter_clear(void)
Clear connection attempts filter.
Use this function to remove all entries from the connection attempts filter.
-
int bt_scan_blocklist_device_add(const bt_addr_le_t *addr)
Add a new device to the blocklist.
Use this function to add a device to the blocklist. Scanning module does not generate any event for the blocklist device or does not try to connect such devices.
- Parameters:
addr – [in] Device address.
- Return values:
0 – If the operation was successful. Otherwise, a (negative) error code is returned.
-
void bt_scan_blocklist_clear(void)
Clear the blocklist of the scanning module device.
Use this function to remove all entries from the blocklist.
-
struct bt_scan_filter_info
- #include <scan.h>
Filter information structure.
It contains information about the number of filters of a given type and whether they are enabled
-
struct bt_filter_status
- #include <scan.h>
Filter status structure.
Public Members
-
bool all_mode
Filter mode.
-
struct bt_scan_filter_info name
Name filters info.
-
struct bt_scan_filter_info short_name
Short name filters info.
-
struct bt_scan_filter_info addr
Address filters info.
-
struct bt_scan_filter_info uuid
UUID filters info.
-
struct bt_scan_filter_info appearance
Appearance filter info.
-
struct bt_scan_filter_info manufacturer_data
Manufacturer filter info.
-
bool all_mode
-
struct bt_scan_adv_info
- #include <scan.h>
Advertising info structure.
-
struct bt_scan_short_name
- #include <scan.h>
A helper structure to set filters for the name.
-
struct bt_scan_manufacturer_data
- #include <scan.h>
A helper structure to set filters for the manufacturer data.
-
struct bt_scan_init_param
- #include <scan.h>
Structure for Scanning Module initialization.
Public Members
-
const struct bt_le_scan_param *scan_param
Scan parameters required to initialize the module. Can be initialized as NULL. If NULL, the parameters required to initialize the module are loaded from the static configuration.
-
bool connect_if_match
If set to true, the module automatically connects after a filter match.
-
const struct bt_le_conn_param *conn_param
Connection parameters. Can be initialized as NULL. If NULL, the default static configuration is used.
-
const struct bt_le_scan_param *scan_param
-
struct bt_scan_name_filter_status
- #include <scan.h>
Name filter status structure, used to inform the application which name filter is matched.
-
struct bt_scan_addr_filter_status
- #include <scan.h>
Address filter status structure, used to inform the application which address filter is matched.
Public Members
-
bool match
Set to true if this type of filter is matched.
-
const bt_addr_le_t *addr
Pointer to the matched filter address.
-
bool match
-
struct bt_scan_uuid_filter_status
- #include <scan.h>
UUID filter status structure, used to inform the application which UUID filters are matched.
-
struct bt_scan_appearance_filter_status
- #include <scan.h>
Appearance filter status structure, used to inform the application which appearance filter is matched.
-
struct bt_scan_manufacturer_data_filter_status
- #include <scan.h>
Manufacturer data filter status structure, used to inform the application which manufacturer data filter is matched.
-
struct bt_scan_filter_match
- #include <scan.h>
Structure for setting the filter status.
This structure is used for sending filter status to the main application. Filter status contains information about which kind of filter is matched and also appropriate filter data.
Public Members
-
struct bt_scan_name_filter_status name
Name filter status data.
-
struct bt_scan_name_filter_status short_name
Short name filter status data.
-
struct bt_scan_addr_filter_status addr
Address filter status data.
-
struct bt_scan_uuid_filter_status uuid
UUIDs filter status data.
-
struct bt_scan_appearance_filter_status appearance
Appearance filter status data.
-
struct bt_scan_manufacturer_data_filter_status manufacturer_data
Manufacturer data filter status data.
-
struct bt_scan_name_filter_status name
-
struct bt_scan_device_info
- #include <scan.h>
Structure containing device data needed to establish connection and advertising information.
Public Members
-
const struct bt_le_scan_recv_info *recv_info
Received advertising packet information
-
const struct bt_le_conn_param *conn_param
Connection parameters for LE connection.
-
struct net_buf_simple *adv_data
Received advertising data. If further data processing is needed, you should use bt_data_parse() to get specific advertising data type.
-
const struct bt_le_scan_recv_info *recv_info
-
struct cb_data
- #include <scan.h>
Data for scanning callback structure.
This structure is used for storing callback functions pointers. It is used by bt_scan_cb structure.
Public Members
-
void (*filter_match)(struct bt_scan_device_info *device_info, struct bt_scan_filter_match *filter_match, bool connectable)
Scan filter matched.
- Param device_info:
[in] Data needed to establish connection and advertising information.
- Param filter_match:
[in] Filter match status.
- Param connectable:
[in] Inform that device is connectable.
-
void (*filter_no_match)(struct bt_scan_device_info *device_info, bool connectable)
Scan filter unmatched. The device was not found.
Note
Even if the filters are disable and not set, then all devices will be reported by this callback. It can be useful if the scan is used without filters.
- Param device_info:
[in] Data needed to establish connection and advertising information.
- Param connectable:
[in] Inform that device is connectable.
-
void (*connecting_error)(struct bt_scan_device_info *device_info)
Error when connecting.
- Param device_info:
[in] Data needed to establish connection and advertising information.
-
void (*connecting)(struct bt_scan_device_info *device_info, struct bt_conn *conn)
Connecting data.
- Param device_info:
[in] Data needed to establish connection and advertising information.
- Param conn:
[in] Connection object.
-
void (*filter_match)(struct bt_scan_device_info *device_info, struct bt_scan_filter_match *filter_match, bool connectable)
-
struct bt_scan_cb
- #include <scan.h>
Scanning callback structure.
This structure is used for tracking the state of a scanning. It is registered with the help of the bt_scan_cb_register() API. It’s permissible to register multiple instances of this bt_scan_cb type, in case different modules of an application are interested in tracking the scanning state. If a callback is not of interest for an instance, it may be set to NULL and will as a consequence not be used for that instance.
-
BT_SCAN_CB_INIT(_name, match_fun, no_match_fun, error_fun, connecting_fun)