|
| 1 | +.. _lib_ble_scan: |
| 2 | + |
| 3 | +Bluetooth: Scan |
| 4 | +############### |
| 5 | + |
| 6 | +.. contents:: |
| 7 | + :local: |
| 8 | + :depth: 2 |
| 9 | + |
| 10 | +The Bluetooth® Low Energy Scan library handles scanning for advertising Bluetooth LE devices. |
| 11 | +You can use it to find an advertising device and establish a connection with it. |
| 12 | +You can narrow down the scan to a device of a specific type using scan filters or the whitelist. |
| 13 | + |
| 14 | +Overview |
| 15 | +******** |
| 16 | + |
| 17 | +You can configure this library in one of the following modes: |
| 18 | + |
| 19 | +* Simple mode without using filters or the whitelist. |
| 20 | +* Advanced mode that allows you to use advanced filters and the whitelist. |
| 21 | + |
| 22 | +The module can automatically establish a connection on a filter match or when identifying a whitelisted device. |
| 23 | + |
| 24 | +The library registers as a Bluetooth LE event observer using the :c:macro:`NRF_SDH_BLE_OBSERVER` macro and handles the relevant Bluetooth LE events from the SoftDevice. |
| 25 | + |
| 26 | +Configuration |
| 27 | +************* |
| 28 | + |
| 29 | +To enable the library, set the :kconfig:option:`CONFIG_BLE_SCAN` Kconfig option. |
| 30 | + |
| 31 | +The library provides the following Kconfig configuration options: |
| 32 | + |
| 33 | +* :kconfig:option:`CONFIG_BLE_SCAN_BUFFER_SIZE` - Maximum size of an advertising event. |
| 34 | +* :kconfig:option:`CONFIG_BLE_SCAN_NAME_MAX_LEN` - Maximum size for the name to search in the advertisement report. |
| 35 | +* :kconfig:option:`CONFIG_BLE_SCAN_SHORT_NAME_MAX_LEN` - Maximum size of the short name to search for in the advertisement report. |
| 36 | +* :kconfig:option:`CONFIG_BLE_SCAN_FILTER` - Enabling filters for the scanning module. |
| 37 | +* :kconfig:option:`CONFIG_BLE_SCAN_NAME_COUNT` - Maximum number of name filters. |
| 38 | +* :kconfig:option:`CONFIG_BLE_SCAN_APPEARANCE_COUNT` - Maximum number of appearance filters. |
| 39 | +* :kconfig:option:`CONFIG_BLE_SCAN_ADDRESS_COUNT` - Maximum number of address filters. |
| 40 | +* :kconfig:option:`CONFIG_BLE_SCAN_SHORT_NAME_COUNT` - Maximum number of short name filters. |
| 41 | +* :kconfig:option:`CONFIG_BLE_SCAN_UUID_COUNT` - Maximum number of filters for UUIDs. |
| 42 | +* :kconfig:option:`CONFIG_BLE_SCAN_INTERVAL` - Determines the scan interval in units of 0.625 millisecond. |
| 43 | +* :kconfig:option:`CONFIG_BLE_SCAN_DURATION` - Duration of a scanning session in units of 10 ms, if set to 0, the scanning continues until it is explicitly disabled. |
| 44 | +* :kconfig:option:`CONFIG_BLE_SCAN_WINDOW` - Determines the scanning window in units of 0.625 milliseconds. |
| 45 | +* :kconfig:option:`CONFIG_BLE_SCAN_SLAVE_LATENCY` - Determines the slave latency in counts of connection events. |
| 46 | +* :kconfig:option:`CONFIG_BLE_SCAN_MIN_CONNECTION_INTERVAL` - Determines the minimum connection interval in units of 1.25 milliseconds. |
| 47 | +* :kconfig:option:`CONFIG_BLE_SCAN_MAX_CONNECTION_INTERVAL` - Determines the maximum connection interval in units of 1.25 milliseconds. |
| 48 | +* :kconfig:option:`CONFIG_BLE_SCAN_SUPERVISION_TIMEOUT` - Determines the supervision time-out in units of 10 millisecond. |
| 49 | + |
| 50 | +Initialization |
| 51 | +============== |
| 52 | + |
| 53 | +The module is initialized by calling the :c:func:`ble_scan_init` function. |
| 54 | +The application can provide an event handler to reveice events to inform about a filter or whitelist match, or about a connection error during the automatic connection. |
| 55 | + |
| 56 | +Simple initialization |
| 57 | +===================== |
| 58 | + |
| 59 | +You can use the simple initialization with the default scanning and connection parameters when you want the library to work in the simple mode without filtering and the whitelist. |
| 60 | + |
| 61 | +.. code:: c |
| 62 | +
|
| 63 | + BLE_SCAN_DEF(ble_scan); |
| 64 | +
|
| 65 | + void scan_event_handler_func(struct ble_scan_evt const *scan_evt); |
| 66 | +
|
| 67 | + uint32_t nrf_err; |
| 68 | + struct ble_scan_config scan_cfg = { |
| 69 | + .scan_params = BLE_SCAN_SCAN_PARAMS_DEFAULT, |
| 70 | + .conn_params = BLE_SCAN_CONN_PARAMS_DEFAULT, |
| 71 | + .evt_handler = scan_event_handler_func, |
| 72 | + }; |
| 73 | +
|
| 74 | + nrf_err = ble_scan_init(&ble_scan, &scan_cfg); |
| 75 | + if (nrf_err) { |
| 76 | + LOG_ERR("Failed to initialie scan module, nrf_error %#x", nrf_err); |
| 77 | + } |
| 78 | +
|
| 79 | +Advanced initialization |
| 80 | +======================= |
| 81 | + |
| 82 | +The advanced initialization provides a larger configuration set for the library. |
| 83 | +It is required when using scan filters or the whitelist. |
| 84 | + |
| 85 | +.. code:: c |
| 86 | +
|
| 87 | + BLE_SCAN_DEF(ble_scan); |
| 88 | +
|
| 89 | + void scan_event_handler_func(struct ble_scan_evt const *scan_evt); |
| 90 | +
|
| 91 | + uint32_t nrf_err; |
| 92 | + struct ble_scan_config scan_cfg = { |
| 93 | + .scan_params = { |
| 94 | + .active = 0x01, |
| 95 | + .interval = NRF_BLE_SCAN_INTERVAL, |
| 96 | + .window = NRF_BLE_SCAN_WINDOW, |
| 97 | + .filter_policy = BLE_GAP_SCAN_FP_WHITELIST, |
| 98 | + .timeout = SCAN_DURATION_WHITELIST, |
| 99 | + .scan_phys = BLE_GAP_PHY_1MBPS, |
| 100 | + .extended = true, |
| 101 | + }, |
| 102 | + .conn_params = BLE_SCAN_CONN_PARAMS_DEFAULT, |
| 103 | + .connect_if_match = true, |
| 104 | + .conn_cfg_tag = APP_BLE_CONN_CFG_TAG, |
| 105 | + .evt_handler = scan_event_handler_func, |
| 106 | + }; |
| 107 | +
|
| 108 | + nrf_err = ble_scan_init(&ble_scan, &scan_cfg); |
| 109 | + if (nrf_err) { |
| 110 | + LOG_ERR("Failed to initialie scan module, nrf_error %#x", nrf_err); |
| 111 | + } |
| 112 | +
|
| 113 | +.. note:: |
| 114 | + |
| 115 | + When setting connection-specific configurations with the :c:func:`sd_ble_cfg_set` function, you must create a tag for each configuration. |
| 116 | + If your application uses the library with automatic connection, this tag must be provided when calling the :c:func:`sd_ble_gap_scan_start` or the :c:func:`sd_ble_gap_connect` function. |
| 117 | + |
| 118 | +Usage |
| 119 | +***** |
| 120 | + |
| 121 | +The application can start scanning by calling the :c:func:`ble_scan_start` function. |
| 122 | + |
| 123 | +The scan parameters can be updated by calling the :c:func:`ble_scan_params_set` function. |
| 124 | + |
| 125 | +To stop scanning, call the :c:func:`ble_scan_stop` function. |
| 126 | + |
| 127 | +The library resumes scanning after receiving advertising reports. |
| 128 | +Scanning stops if the module establishes a connection automatically, or if the application calls the :c:func:`ble_scan_stop` or the :c:func:`sd_ble_gap_connect` function. |
| 129 | + |
| 130 | +.. note:: |
| 131 | + |
| 132 | + When you use the :c:func:`ble_scan_params_set` function during the ongoing scan, scanning is stopped. |
| 133 | + To resume scanning, use the :c:func:`ble_scan_start` function. |
| 134 | + |
| 135 | +Whitelist |
| 136 | +========= |
| 137 | + |
| 138 | +The whitelist stores information about all the device connections and bonding. |
| 139 | +If you enable the whitelist, the application receives advertising packets only from the devices that are on the whitelist. |
| 140 | +An advertising package from a whitelisted device generates the :c:macro:`NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT` event. |
| 141 | + |
| 142 | +.. note:: |
| 143 | + |
| 144 | + When using the whitelist, filters are inactive. |
| 145 | + |
| 146 | +.. caution:: |
| 147 | + |
| 148 | + If you use the whitelist, you must pass the event handler during the module initialization. |
| 149 | + The initial scanning with whitelist generates a :c:macro:`NRF_BLE_SCAN_EVT_WHITELIST_REQUEST` event. |
| 150 | + The application must react to this event by either setting up the whitelist or switching off the whitelist scan. |
| 151 | + Otherwise, an error is reported when the scan starts. |
| 152 | + |
| 153 | +Filters |
| 154 | +======= |
| 155 | + |
| 156 | +The module can set scanning filters of different type and mode. |
| 157 | +When a filter is matched, it generates a :c:macro:`NRF_BLE_SCAN_EVT_FILTER_MATCH` event to the main application. |
| 158 | +If the filter matching is enabled and no filter is matched, a :c:macro:`NRF_BLE_SCAN_EVT_NOT_FOUND` event is generated. |
| 159 | + |
| 160 | +The available filter types are: |
| 161 | + |
| 162 | +* **Name** - Filter set to the target name. |
| 163 | + The maximum length of the name corresponds to :kconfig:option:`CONFIG_BLE_SCAN_NAME_MAX_LEN`. |
| 164 | + The maximum number of filters of this type corresponds to :kconfig:option:`CONFIG_BLE_SCAN_NAME_COUNT`. |
| 165 | +* **Short name** - Filter set to the short target name. |
| 166 | + The maximum length of the name corresponds to :kconfig:option:`CONFIG_BLE_SCAN_SHORT_NAME_MAX_LEN`. |
| 167 | + The maximum number of filters of this type corresponds to :kconfig:option:`CONFIG_BLE_SCAN_SHORT_NAME_COUNT`. |
| 168 | +* **Address** - Filter set to the target address. |
| 169 | + The maximum number of filters of this type corresponds to :kconfig:option:`CONFIG_BLE_SCAN_ADDRESS_COUNT`. |
| 170 | +* **UUID** - Filter set to the target UUID. |
| 171 | + The maximum number of filters of this type corresponds to :kconfig:option:`CONFIG_BLE_SCAN_UUID_COUNT`. |
| 172 | +* **Appearance** - Filter set to the target appearance. |
| 173 | + The maximum number of filters of this type corresponds to :kconfig:option:`CONFIG_BLE_SCAN_APPEARANCE_COUNT`. |
| 174 | + |
| 175 | +The following two filter modes are available: |
| 176 | + |
| 177 | +* **Normal** - Only one of the filters set, regardless of the type, must be matched to generate an event. |
| 178 | +* **Multifilter** - At least one filter from each filter type you set must be matched to generate an event. |
| 179 | + For UUID filters, all specified UUIDs must match in this mode. |
| 180 | + Enable multifilter by setting the :c:macro:`match_all` argument to true when calling the :c:func:`ble_scan_filters_enable` function. |
| 181 | + |
| 182 | +Multifilter example: |
| 183 | + |
| 184 | +Several filters are set for name, address, UUID, and appearance. |
| 185 | +To generate the :c:macro:`NRF_BLE_SCAN_EVT_FILTER_MATCH` event, the following types must match: |
| 186 | + |
| 187 | +* One of the address filters. |
| 188 | +* One of the name filters. |
| 189 | +* One of the appearance filters. |
| 190 | +* All UUID filters. |
| 191 | + |
| 192 | +Otherwise, the :c:macro:`NRF_BLE_SCAN_EVT_NOT_FOUND` event is generated. |
| 193 | + |
| 194 | +You can enable filters by calling the :c:func:`ble_scan_filters_enable` function after initialization. |
| 195 | +You can activate filters for one filter type, or for a combination of several filter types. |
| 196 | + |
| 197 | +.. code:: c |
| 198 | +
|
| 199 | + BLE_SCAN_DEF(ble_scan); |
| 200 | +
|
| 201 | + uint8_t addr[BLE_GAP_ADDR_LEN] = {0xa, 0xd, 0xd, 0x4, 0xe, 0x5}; |
| 202 | + char *device_name = "my_device"; |
| 203 | +
|
| 204 | + /* See above code snippet for initialization */ |
| 205 | +
|
| 206 | + /* Enable filter for name and address in normal mode */ |
| 207 | + nrf_err = ble_scan_filters_enable(&ble_scan, BLE_SCAN_NAME_FILTER | BLE_SCAN_ADDR_FILTER, false); |
| 208 | + if (nrf_err) { |
| 209 | + LOG_ERR("Failed to enable scan filters, nrf_error %#x", nrf_err); |
| 210 | + } |
| 211 | +
|
| 212 | + /* Add address to scan filter */ |
| 213 | + nrf_err = ble_scan_filter_set(&ble_scan, BLE_SCAN_ADDR_FILTER, addr); |
| 214 | + if (nrf_err) { |
| 215 | + LOG_ERR("Failed to add address scan filter, nrf_error %#x", nrf_err); |
| 216 | + } |
| 217 | +
|
| 218 | + /* Add name to scan filter */ |
| 219 | + nrf_err = ble_scan_filter_set(&ble_scan, BLE_SCAN_NAME_FILTER, device_name); |
| 220 | + if (nrf_err) { |
| 221 | + LOG_ERR("Failed to add name scan filter, nrf_error %#x", nrf_err); |
| 222 | + } |
| 223 | +
|
| 224 | + /* Start scanning */ |
| 225 | + nrf_err = ble_scan_start(&ble_scan); |
| 226 | + if (nrf_err) { |
| 227 | + LOG_ERR("Failed to start scan, nrf_error %#x", nrf_err); |
| 228 | + } |
| 229 | +
|
| 230 | + /* Start scanning */ |
| 231 | + ble_scan_stop(&ble_scan); |
| 232 | +
|
| 233 | + /* Disable filters */ |
| 234 | + nrf_err = ble_scan_filters_disable(&ble_scan); |
| 235 | + if (nrf_err) { |
| 236 | + LOG_ERR("Failed to disable scan filters, nrf_error %#x", nrf_err); |
| 237 | + } |
| 238 | +
|
| 239 | + /* Remove all scan filters */ |
| 240 | + nrf_err = ble_scan_all_filter_remove(&ble_scan); |
| 241 | + if (nrf_err) { |
| 242 | + LOG_ERR("Failed to remove scan filters, nrf_error %#x", nrf_err); |
| 243 | + } |
| 244 | +
|
| 245 | +Dependencies |
| 246 | +************ |
| 247 | + |
| 248 | +This library uses the following |BMshort| libraries: |
| 249 | + |
| 250 | +* SoftDevice - :kconfig:option:`CONFIG_SOFTDEVICE` |
| 251 | +* SoftDevice handler - :kconfig:option:`CONFIG_NRF_SDH` |
| 252 | + |
| 253 | +API documentation |
| 254 | +***************** |
| 255 | + |
| 256 | +| Header file: :file:`include/bm/bluetooth/ble_scan.h` |
| 257 | +| Source files: :file:`lib/ble_scan/` |
| 258 | +
|
| 259 | +:ref:`Bluetooth LE Scan library API reference <api_ble_scan>` |
0 commit comments