Scanning module
The scanning module handles the Bluetooth® Low Energy scanning for your application. You can use it to find advertising devices and establish connections with them.
Using filters, you can narrow down the scan to devices of a specific type.
The Scanning Module can work in one of the following modes:
Simple mode - without using filters
Advanced mode - that allows using advanced filters
The module can automatically establish a connection after a filter match. It can also receive directed advertising packets.
Usage
You can use the scanning module to execute the following actions:
- Initialize
To initialize the module, call the function
bt_scan_init()
.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 use an initialization structure with
NULL
pointers to scan parameters and connection parameters.- Start scanning
When the initialization is completed, call the function
bt_scan_start()
to start scanning.In simple mode, when you do not use the event handler, you can establish the connection when the scanner finds the device.
- Change parameters
To change parameters, call the function
bt_scan_params_set()
.- Stop scanning
Scanning stops if the module established the connection automatically. To manually stop scanning, call the function
bt_scan_stop()
.- Resume scanning
To resume scanning, call the function
bt_scan_start()
.
Filters
While using the scanning module in advanced mode, you can set select various filter types and modes.
Filter types
Check the following table for the details on the available filter types.
Filter type |
Details |
---|---|
Name |
Filter set to the target name. |
Short name |
Filter set to the target short name. |
Address |
Filter set to the target address. |
UUID |
Filter set to the target UUID. |
Appearance |
Filter set to the target appearance. |
Filter modes
Check 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 is started by the application, some peripheral devices can disconnect immediately for some reasons during an ongoing scanning session. This might result in a loop of the connection and disconnection events.
To avoid this loop, you can enable the connection attempts filter that limits number of the connection attempts.
Use the CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER
to enable this filter.
This filter automatically tracks the connected devices and counts all disconnection events for them. If the disconnection count is greater than or equal to the number of allowed attempts, the scanning module ignores this device.
Filtered devices must be removed manually from the filter array using bt_scan_conn_attempts_filter_clear()
.
It is recommended to use bt_scan_conn_attempts_filter_clear()
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 tries to two.
You can increase the device number by setting the configuration option CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER_LEN
.
The option CONFIG_BT_SCAN_CONN_ATTEMPTS_COUNT
is responsible for the number of connection attempts.
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 option CONFIG_BT_SCAN_BLOCKLIST
to enable the blocklist.
In the default configuration, the scanning module allows to add up to two devices to the blocklist.
You can increase the blocklist size by setting the option CONFIG_BT_SCAN_BLOCKLIST_LEN
.
Use the bt_scan_blocklist_device_add()
function to add a new device to the blocklist.
To remove all devices from the blocklist, use bt_scan_blocklist_clear()
.
Directed Advertising
To receive directed advertising packets using the Scanning Module, enable one of the following options in Zephyr:
CONFIG_BT_PRIVACY
- Scan with changing addressesCONFIG_BT_SCAN_WITH_IDENTITY
- Scan with a local identity address
It is recommended to enable the CONFIG_BT_PRIVACY
option to support directed advertising only between bonded peers.
Use the CONFIG_BT_SCAN_WITH_IDENTITY
option only when the CONFIG_BT_PRIVACY
option is not available.
When the scanning module is set in 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);
}
}
}
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
Active scanning.
-
enumerator BT_SCAN_TYPE_SCAN_ACTIVE
Passive 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(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
Appearance 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)