Skip to content

Commit 651daf0

Browse files
henrlajukkar
authored andcommitted
samples: Bluetooth: add concurrent scanner and initiator sample
Add sample application that demonstrates faster connection establishment using CONFIG_BT_SCAN_AND_INITIATE_IN_PARALLEL. Signed-off-by: Henrik Lander <[email protected]>
1 parent 5fdb7fd commit 651daf0

File tree

9 files changed

+788
-0
lines changed

9 files changed

+788
-0
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@
455455
/samples/bluetooth/radio_coex_1wire/ @nrfconnect/ncs-dragoon
456456
/samples/bluetooth/radio_notification_cb/ @nrfconnect/ncs-dragoon
457457
/samples/bluetooth/rpc_host/ @nrfconnect/ncs-si-muffin
458+
/samples/bluetooth/scanning_while_connecting/ @nrfconnect/ncs-dragoon
458459
/samples/bluetooth/shell_bt_nus/ @nrfconnect/ncs-si-muffin
459460
/samples/bluetooth/subrating/ @nrfconnect/ncs-dragoon
460461
/samples/bluetooth/throughput/ @nrfconnect/ncs-si-muffin

doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ Bluetooth samples
312312

313313
* Added support for the :ref:`zephyr:nrf54h20dk_nrf54h20` board target.
314314

315+
* The :ref:`bt_scanning_while_connecting` sample demonstrating how to establish multiple connections faster using the :kconfig:option:`CONFIG_BT_SCAN_AND_INITIATE_IN_PARALLEL` Kconfig option.
316+
315317
* Updated:
316318

317319
* Configurations of the following Bluetooth samples to make the :ref:`Zephyr Memory Storage (ZMS) <zephyr:zms_api>` the default settings backend for all board targets that use the MRAM technology:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
9+
project(scanning_while_connecting)
10+
11+
target_sources(app PRIVATE src/main.c)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
source "${ZEPHYR_BASE}/share/sysbuild/Kconfig"
8+
9+
config NRF_DEFAULT_IPC_RADIO
10+
default y
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
.. _bt_scanning_while_connecting:
2+
3+
Bluetooth: Scanning while connecting
4+
####################################
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
10+
The sample demonstrates how to reduce the time to establish connections to many devices, typically done when provisioning devices to a network.
11+
The total connection establishment time is reduced by scanning while connecting and by using the filter accept list.
12+
13+
Requirements
14+
************
15+
16+
The sample supports the following development kits:
17+
18+
.. table-from-sample-yaml::
19+
20+
The sample also requires at least one other development kit.
21+
Out of the box, this sample can be used together with the :ref:`bt_peripheral_with_multiple_identities`.
22+
This sample filters out devices with a different name than a device running the :ref:`bt_peripheral_with_multiple_identities` sample.
23+
The :ref:`bt_peripheral_with_multiple_identities` sample acts as multiple peripheral devices.
24+
25+
Overview
26+
********
27+
28+
You can use this sample as a starting point to implement an application designed to provision a network of Bluetooth peripherals.
29+
The approaches demonstrated in this sample will reduce the total time to connect to many devices.
30+
A typical use-case is a gateway in a network of devices using Periodic Advertising with Responses.
31+
32+
To illustrate how connection establishment speed can be improved, it measures the time needed to connect to 16 devices with three different modes:
33+
34+
* sequential scanning and connection establishment
35+
* concurrent scanning while connecting
36+
* concurrent scanning while connecting with the filter accept list.
37+
38+
Sequential scanning and connection establishment
39+
================================================
40+
41+
This is the slowest and simplest approach.
42+
Sequential scanning and connection establishment are recommended when the application only needs to connect a handful of devices.
43+
44+
After a device is discovered, the application stops scanning and attempts to connect to the device.
45+
Once the connection is established, the application starts the scanner again to discover other connectable devices.
46+
The following message sequence chart illustrates the sequence of events.
47+
48+
.. msc::
49+
hscale = "1.3";
50+
App, Stack, Peers;
51+
App=>Stack [label="scan_start()"];
52+
Peers=>Stack [label="ADV_IND(A)"];
53+
Stack=>App [label="scan_recv(A)"];
54+
App=>Stack [label="scan_stop()"];
55+
App=>Stack [label="bt_conn_le_create(A)"];
56+
Peers=>Stack [label="ADV_IND(A)"];
57+
Stack=>Peers [label="CONNECT_IND(A)"];
58+
Stack=>App [label="connected_cb(A)"];
59+
App=>Stack [label="scan_start()"];
60+
Peers=>Stack [label="ADV_IND(B)"];
61+
Stack=>App [label="scan_recv(B)"];
62+
App=>Stack [label="scan_stop()"];
63+
App=>Stack [label="bt_conn_le_create(B)"];
64+
Peers=>Stack [label="ADV_IND(B)"];
65+
Stack=>Peers [label="CONNECT_IND(B)"];
66+
Stack=>App [label="connected_cb(B)"];
67+
68+
Concurrent scanning while connecting
69+
====================================
70+
71+
This mode requires the application to enable the :kconfig:option:`CONFIG_BT_SCAN_AND_INITIATE_IN_PARALLEL` Kconfig option.
72+
In this mode, the scanner is not stopped when the application creates connections.
73+
During a connection establishment procedure to a device, the application caches other devices it also wants to connect to.
74+
Once the connection establishment procedure is complete, it can immediately initiate a new connection establishment procedure to the cached device.
75+
When connecting to a cached device, the connection establishment procedure takes one less advertising interval compared to the sequential scanning and connection establishment mode.
76+
77+
.. msc::
78+
hscale = "1.3";
79+
App, Stack, Peers;
80+
App=>Stack [label="scan_start()"];
81+
Peers=>Stack [label="ADV_IND(A)"];
82+
Stack=>App [label="scan_recv(A)"];
83+
App=>Stack [label="bt_conn_le_create(A)"];
84+
Peers=>Stack [label="ADV_IND(B)"];
85+
App rbox App [label="Cache address B"];
86+
Peers=>Stack [label="ADV_IND(A)"];
87+
Stack=>Peers [label="CONNECT_IND(A)"];
88+
Stack=>App [label="connected_cb(A)"];
89+
App=>Stack [label="bt_conn_le_create(B)"];
90+
Peers=>Stack [label="ADV_IND(B)"];
91+
Stack=>Peers [label="CONNECT_IND(B)"];
92+
Stack=>App [label="connected_cb(B)"];
93+
94+
Concurrent scanning while connecting with the filter accept list
95+
================================================================
96+
97+
This mode requires the application to enable the :kconfig:option:`CONFIG_BT_FILTER_ACCEPT_LIST` Kconfig option in addition to :kconfig:option:`CONFIG_BT_SCAN_AND_INITIATE_IN_PARALLEL`.
98+
When the application starts the connection establishment procedure with the filter accept list, it can connect to any of the previously cached devices.
99+
This reduces the total connection setup time even more, because connection establishment is not relying on the on-air presence of only one of the cached devices.
100+
101+
.. msc::
102+
hscale = "1.3";
103+
App, Stack, Peers;
104+
App=>Stack [label="scan_start()"];
105+
Peers=>Stack [label="ADV_IND(A)"];
106+
Stack=>App [label="scan_recv(A)"];
107+
App=>Stack [label="bt_conn_le_create(A)"];
108+
Peers=>Stack [label="ADV_IND(B)"];
109+
Peers=>Stack [label="ADV_IND(C)"];
110+
Peers=>Stack [label="ADV_IND(D)"];
111+
App rbox App [label="Cache addresses B, C, D"];
112+
Peers=>Stack [label="ADV_IND(A)"];
113+
Stack=>Peers [label="CONNECT_IND(A)"];
114+
Stack=>App [label="connected_cb(A)"];
115+
App rbox App [label="Set filter accept list to\nB, C, D"];
116+
App=>Stack [label="bt_conn_le_create_auto()"];
117+
Stack rbox Stack [label="The stack will connect to the first present ADV_IND of\nthe peers B,C,D"];
118+
Peers=>Stack [label="ADV_IND(C)"];
119+
Stack=>Peers [label="CONNECT_IND(C)"];
120+
Stack=>App [label="connected_cb(C)"];
121+
122+
.. note::
123+
This sample application assumes it will never have to cache more devices than the maximum number of addresses that can be stored in the filter accept list.
124+
For applications that cannot adhere to this simplification, the function :c:func:`cache_peer_address` can be changed to not store more than defined by the :kconfig:option:`CONFIG_BT_CTLR_FAL_SIZE` Kconfig option.
125+
Another simplification done in the sample application is storing duplicate devices in the filter accept list.
126+
127+
Configuration
128+
*************
129+
130+
|config|
131+
132+
Building and running
133+
********************
134+
135+
.. |sample path| replace:: :file:`samples/bluetooth/scanning_while_connecting`
136+
137+
.. include:: /includes/build_and_run.txt
138+
139+
Testing
140+
=======
141+
142+
|test_sample|
143+
144+
1. |connect_kit|
145+
#. |connect_terminal|
146+
#. Observe that the sample connects and prints out how much time it takes to connect to all peripherals.
147+
148+
Sample output
149+
=============
150+
151+
The result should look similar to the following output::
152+
153+
*** Booting nRF Connect SDK v2.8.99-1c63490f0539 ***
154+
*** Using Zephyr OS v3.7.99-b9bc0846b926 ***
155+
I: SoftDevice Controller build revision:
156+
I: 49 40 e2 c0 6b e5 0d b3 |[email protected]...
157+
I: ba a6 48 5e 49 a6 95 3d |..H^I..=
158+
I: 65 35 b6 7c |e5.|
159+
I: HW Platform: Nordic Semiconductor (0x0002)
160+
I: HW Variant: nRF54Lx (0x0005)
161+
I: Firmware: Standard Bluetooth controller (0x00) Version 73.57920 Build 233139136
162+
I: Identity: F6:BF:24:7D:46:5D (random)
163+
I: HCI: version 6.0 (0x0e) revision 0x3030, manufacturer 0x0059
164+
I: LMP: version 6.0 (0x0e) subver 0x3030
165+
I: Bluetooth initialized
166+
167+
I: SEQUENTIAL_SCAN_AND_CONNECT:
168+
I: starting sample benchmark
169+
I: Connected to FF:AB:68:0C:34:FD (random), number of connections 1
170+
I: Connected to E2:12:BF:D3:FB:D5 (random), number of connections 2
171+
I: Connected to EE:37:AA:62:A2:FB (random), number of connections 3
172+
I: Connected to C7:9B:42:1B:48:F8 (random), number of connections 4
173+
I: Connected to F0:27:5B:37:0F:4B (random), number of connections 5
174+
I: Connected to C8:BA:1D:6F:95:2B (random), number of connections 6
175+
I: Connected to DF:02:31:C3:0B:C2 (random), number of connections 7
176+
I: Connected to C7:E1:60:7A:F1:E0 (random), number of connections 8
177+
I: Connected to CA:89:50:33:AB:31 (random), number of connections 9
178+
I: Connected to E9:47:6B:FA:2F:DE (random), number of connections 10
179+
I: Connected to EF:92:DC:88:3B:B3 (random), number of connections 11
180+
I: Connected to F4:9C:8C:24:F9:44 (random), number of connections 12
181+
I: Connected to DD:84:44:64:5D:FB (random), number of connections 13
182+
I: Connected to FB:92:1D:8E:8C:D8 (random), number of connections 14
183+
I: Connected to D9:E5:51:E0:5E:24 (random), number of connections 15
184+
I: Connected to CF:2F:99:89:A3:4D (random), number of connections 16
185+
I: 12 seconds to create 16 connections
186+
I: Disconnecting connections...
187+
I: ---------------------------------------------------------------------
188+
I: ---------------------------------------------------------------------
189+
I: CONCURRENT_SCAN_AND_CONNECT:
190+
I: starting sample benchmark
191+
I: Connected to F0:27:5B:37:0F:4B (random), number of connections 1
192+
I: Connected to EE:37:AA:62:A2:FB (random), number of connections 2
193+
I: Connected to D1:3D:B1:AA:84:27 (random), number of connections 3
194+
I: Connected to CA:89:50:33:AB:31 (random), number of connections 4
195+
I: Connected to C0:38:F8:47:10:17 (random), number of connections 5
196+
I: Connected to E9:47:6B:FA:2F:DE (random), number of connections 6
197+
I: Connected to D9:E5:51:E0:5E:24 (random), number of connections 7
198+
I: Connected to FB:92:1D:8E:8C:D8 (random), number of connections 8
199+
I: Connected to C7:E1:60:7A:F1:E0 (random), number of connections 9
200+
I: Connected to E2:6D:21:28:C7:DB (random), number of connections 10
201+
I: Connected to DF:02:31:C3:0B:C2 (random), number of connections 11
202+
I: Connected to F0:F2:2A:C1:F7:72 (random), number of connections 12
203+
I: Connected to DD:84:44:64:5D:FB (random), number of connections 13
204+
I: Connected to F4:9C:8C:24:F9:44 (random), number of connections 14
205+
I: Connected to EF:92:DC:88:3B:B3 (random), number of connections 15
206+
I: Connected to C8:BA:1D:6F:95:2B (random), number of connections 16
207+
I: 9 seconds to create 16 connections
208+
I: Disconnecting connections...
209+
I: ---------------------------------------------------------------------
210+
I: ---------------------------------------------------------------------
211+
I: CONCURRENT_SCAN_AND_CONNECT_FILTER_ACCEPT_LIST:
212+
I: starting sample benchmark
213+
I: Connected to DD:84:44:64:5D:FB (random), number of connections 1
214+
I: Connected to C7:E1:60:7A:F1:E0 (random), number of connections 2
215+
I: Connected to C7:9B:42:1B:48:F8 (random), number of connections 3
216+
I: Connected to E9:47:6B:FA:2F:DE (random), number of connections 4
217+
I: Connected to E2:12:BF:D3:FB:D5 (random), number of connections 5
218+
I: Connected to FB:92:1D:8E:8C:D8 (random), number of connections 6
219+
I: Connected to F0:F2:2A:C1:F7:72 (random), number of connections 7
220+
I: Connected to CA:89:50:33:AB:31 (random), number of connections 8
221+
I: Connected to F4:9C:8C:24:F9:44 (random), number of connections 9
222+
I: Connected to E2:6D:21:28:C7:DB (random), number of connections 10
223+
I: Connected to FF:AB:68:0C:34:FD (random), number of connections 11
224+
I: Connected to EE:37:AA:62:A2:FB (random), number of connections 12
225+
I: Connected to D1:3D:B1:AA:84:27 (random), number of connections 13
226+
I: Connected to CF:2F:99:89:A3:4D (random), number of connections 14
227+
I: Connected to EF:92:DC:88:3B:B3 (random), number of connections 15
228+
I: Connected to D9:E5:51:E0:5E:24 (random), number of connections 16
229+
I: 4 seconds to create 16 connections
230+
I: Disconnecting connections...
231+
I: ---------------------------------------------------------------------
232+
I: ---------------------------------------------------------------------
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
CONFIG_NCS_SAMPLES_DEFAULTS=y
8+
9+
CONFIG_BT=y
10+
CONFIG_BT_CENTRAL=y
11+
CONFIG_BT_FILTER_ACCEPT_LIST=y
12+
CONFIG_BT_SCAN_AND_INITIATE_IN_PARALLEL=y
13+
CONFIG_BT_CTLR_SDC_ALLOW_PARALLEL_SCANNING_AND_INITIATING=y
14+
15+
# A ring buffer is used as a device address cache
16+
CONFIG_RING_BUFFER=y
17+
18+
CONFIG_BT_CTLR_FAL_SIZE=255
19+
20+
CONFIG_LOG=y
21+
22+
CONFIG_BT_MAX_CONN=16
23+
CONFIG_BT_BUF_ACL_RX_COUNT=17
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
sample:
2+
description: Bluetooth Low Energy fast connection establishment sample
3+
name: Bluetooth LE central scanning while connecting
4+
tests:
5+
sample.bluetooth.scanning_while_connecting:
6+
sysbuild: true
7+
build_only: true
8+
integration_platforms:
9+
- nrf52840dk/nrf52840
10+
- nrf5340dk/nrf5340/cpuapp
11+
- nrf54l15dk/nrf54l15/cpuapp
12+
- nrf54l15dk/nrf54l10/cpuapp
13+
- nrf54l15dk/nrf54l05/cpuapp
14+
platform_allow:
15+
- nrf52840dk/nrf52840
16+
- nrf5340dk/nrf5340/cpuapp
17+
- nrf54l15dk/nrf54l15/cpuapp
18+
- nrf54l15dk/nrf54l10/cpuapp
19+
- nrf54l15dk/nrf54l05/cpuapp
20+
tags: bluetooth ci_build sysbuild

0 commit comments

Comments
 (0)