Skip to content

Commit daf34bb

Browse files
Tschet1nordicjm
authored andcommitted
[nrf fromlist] Bluetooth: Host: Rework enabling of scanner
To make the scanner module more understandable and more streamlined, I reworked the update mechanism of the scanner. The scanner tracks now the parameters that were used to enable it and the reason why it is running. This facilitates state logic and allows other modules to "start the scanner", altough it is already running. This is mostly a refactoring and not a functional change. Added a test to verify the behavior. Upstream PR: zephyrproject-rtos/zephyr#73923 Signed-off-by: Jan Müller <[email protected]>
1 parent c465557 commit daf34bb

File tree

15 files changed

+826
-250
lines changed

15 files changed

+826
-250
lines changed

include/zephyr/bluetooth/bluetooth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,7 @@ BUILD_ASSERT(BT_GAP_SCAN_FAST_WINDOW == BT_GAP_SCAN_FAST_INTERVAL_MIN,
22942294
*
22952295
* @return Zero on success or error code otherwise, positive in case of
22962296
* protocol error or negative (POSIX) in case of stack internal error.
2297+
* @retval -EBUSY if the scanner is already being started in a different thread.
22972298
*/
22982299
int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb);
22992300

subsys/bluetooth/host/conn.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "hci_core.h"
3535
#include "id.h"
3636
#include "adv.h"
37+
#include "scan.h"
3738
#include "conn_internal.h"
3839
#include "l2cap_internal.h"
3940
#include "keys.h"
@@ -1200,10 +1201,18 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
12001201
* the application through bt_conn_disconnect or by
12011202
* timeout set by bt_conn_le_create_param.timeout.
12021203
*/
1203-
if (conn->err) {
1204-
notify_connected(conn);
1205-
}
1204+
if (IS_ENABLED(CONFIG_BT_CENTRAL)) {
1205+
int err = bt_le_scan_user_remove(BT_LE_SCAN_USER_CONN);
1206+
1207+
if (err) {
1208+
LOG_WRN("Error while removing conn user from scanner (%d)",
1209+
err);
1210+
}
12061211

1212+
if (conn->err) {
1213+
notify_connected(conn);
1214+
}
1215+
}
12071216
bt_conn_unref(conn);
12081217
break;
12091218
case BT_CONN_ADV_DIR_CONNECTABLE:
@@ -1609,7 +1618,7 @@ int bt_conn_disconnect(struct bt_conn *conn, uint8_t reason)
16091618
conn->err = reason;
16101619
bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
16111620
if (IS_ENABLED(CONFIG_BT_CENTRAL)) {
1612-
bt_le_scan_update(false);
1621+
return bt_le_scan_user_add(BT_LE_SCAN_USER_CONN);
16131622
}
16141623
return 0;
16151624
case BT_CONN_INITIATING:
@@ -3173,27 +3182,32 @@ static int conn_le_create_common_checks(const bt_addr_le_t *peer,
31733182
{
31743183

31753184
if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
3185+
LOG_DBG("Conn check failed: BT dev not ready.");
31763186
return -EAGAIN;
31773187
}
31783188

31793189
if (!bt_le_conn_params_valid(conn_param)) {
3190+
LOG_DBG("Conn check failed: invalid parameters.");
31803191
return -EINVAL;
31813192
}
31823193

3183-
if (!BT_LE_STATES_SCAN_INIT(bt_dev.le.states) &&
3184-
atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) {
3194+
if (!BT_LE_STATES_SCAN_INIT(bt_dev.le.states) && bt_le_explicit_scanner_running()) {
3195+
LOG_DBG("Conn check failed: scanner was explicitly requested.");
31853196
return -EAGAIN;
31863197
}
31873198

31883199
if (atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) {
3200+
LOG_DBG("Conn check failed: device is already initiating.");
31893201
return -EALREADY;
31903202
}
31913203

31923204
if (!bt_id_scan_random_addr_check()) {
3205+
LOG_DBG("Conn check failed: invalid random address.");
31933206
return -EINVAL;
31943207
}
31953208

31963209
if (bt_conn_exists_le(BT_ID_DEFAULT, peer)) {
3210+
LOG_DBG("Conn check failed: ACL connection already exists.");
31973211
return -EINVAL;
31983212
}
31993213

@@ -3246,8 +3260,9 @@ int bt_conn_le_create(const bt_addr_le_t *peer, const struct bt_conn_le_create_p
32463260
/* Use host-based identity resolving. */
32473261
bt_conn_set_state(conn, BT_CONN_SCAN_BEFORE_INITIATING);
32483262

3249-
err = bt_le_scan_update(true);
3263+
err = bt_le_scan_user_add(BT_LE_SCAN_USER_CONN);
32503264
if (err) {
3265+
bt_le_scan_user_remove(BT_LE_SCAN_USER_CONN);
32513266
bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
32523267
bt_conn_unref(conn);
32533268

@@ -3267,7 +3282,12 @@ int bt_conn_le_create(const bt_addr_le_t *peer, const struct bt_conn_le_create_p
32673282
bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
32683283
bt_conn_unref(conn);
32693284

3270-
bt_le_scan_update(false);
3285+
/* Best-effort attempt to inform the scanner that the initiator stopped. */
3286+
int scan_check_err = bt_le_scan_user_add(BT_LE_SCAN_USER_NONE);
3287+
3288+
if (scan_check_err) {
3289+
LOG_WRN("Error while updating the scanner (%d)", scan_check_err);
3290+
}
32713291
return err;
32723292
}
32733293

@@ -3369,17 +3389,18 @@ int bt_le_set_auto_conn(const bt_addr_le_t *addr,
33693389
}
33703390
}
33713391

3392+
int err = 0;
33723393
if (conn->state == BT_CONN_DISCONNECTED &&
33733394
atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
33743395
if (param) {
33753396
bt_conn_set_state(conn, BT_CONN_SCAN_BEFORE_INITIATING);
3397+
err = bt_le_scan_user_add(BT_LE_SCAN_USER_CONN);
33763398
}
3377-
bt_le_scan_update(false);
33783399
}
33793400

33803401
bt_conn_unref(conn);
33813402

3382-
return 0;
3403+
return err;
33833404
}
33843405
#endif /* !defined(CONFIG_BT_FILTER_ACCEPT_LIST) */
33853406
#endif /* CONFIG_BT_CENTRAL */

subsys/bluetooth/host/hci_core.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,12 @@ static void hci_disconn_complete(struct net_buf *buf)
929929
#if defined(CONFIG_BT_CENTRAL) && !defined(CONFIG_BT_FILTER_ACCEPT_LIST)
930930
if (atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT)) {
931931
bt_conn_set_state(conn, BT_CONN_SCAN_BEFORE_INITIATING);
932-
bt_le_scan_update(false);
932+
/* Just a best-effort check if the scanner should be started. */
933+
int err = bt_le_scan_user_remove(BT_LE_SCAN_USER_NONE);
934+
935+
if (err) {
936+
LOG_WRN("Error while updating the scanner (%d)", err);
937+
}
933938
}
934939
#endif /* defined(CONFIG_BT_CENTRAL) && !defined(CONFIG_BT_FILTER_ACCEPT_LIST) */
935940

@@ -1342,7 +1347,12 @@ void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
13421347
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
13431348
evt->status == BT_HCI_ERR_UNKNOWN_CONN_ID) {
13441349
le_conn_complete_cancel(evt->status);
1345-
bt_le_scan_update(false);
1350+
/* Just a best-effort check if the scanner should be started. */
1351+
int err = bt_le_scan_user_remove(BT_LE_SCAN_USER_NONE);
1352+
1353+
if (err) {
1354+
LOG_WRN("Error while updating the scanner (%d)", err);
1355+
}
13461356
return;
13471357
}
13481358

@@ -1501,9 +1511,14 @@ void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
15011511

15021512
bt_conn_unref(conn);
15031513

1504-
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
1505-
conn->role == BT_HCI_ROLE_CENTRAL) {
1506-
bt_le_scan_update(false);
1514+
if (IS_ENABLED(CONFIG_BT_CENTRAL) && conn->role == BT_HCI_ROLE_CENTRAL) {
1515+
int err;
1516+
1517+
/* Just a best-effort check if the scanner should be started. */
1518+
err = bt_le_scan_user_remove(BT_LE_SCAN_USER_NONE);
1519+
if (err) {
1520+
LOG_WRN("Error while updating the scanner (%d)", err);
1521+
}
15071522
}
15081523
}
15091524

@@ -4083,7 +4098,7 @@ void bt_finalize_init(void)
40834098
atomic_set_bit(bt_dev.flags, BT_DEV_READY);
40844099

40854100
if (IS_ENABLED(CONFIG_BT_OBSERVER)) {
4086-
bt_le_scan_update(false);
4101+
bt_scan_reset();
40874102
}
40884103

40894104
bt_dev_show_info();

subsys/bluetooth/host/hci_core.h

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,11 @@ enum {
3535
BT_DEV_HAS_PUB_KEY,
3636
BT_DEV_PUB_KEY_BUSY,
3737

38-
/** The application explicitly instructed the stack to scan for advertisers
39-
* using the API @ref bt_le_scan_start().
40-
*/
41-
BT_DEV_EXPLICIT_SCAN,
42-
4338
/** The application either explicitly or implicitly instructed the stack to scan
4439
* for advertisers.
4540
*
4641
* Examples of such cases
47-
* - Explicit scanning, @ref BT_DEV_EXPLICIT_SCAN.
42+
* - Explicit scanning, @ref BT_LE_SCAN_USER_EXPLICIT_SCAN.
4843
* - The application instructed the stack to automatically connect if a given device
4944
* is detected.
5045
* - The application wants to connect to a peer device using private addresses, but
@@ -60,13 +55,9 @@ enum {
6055
*/
6156
BT_DEV_SCANNING,
6257

63-
/* Cached parameters used when initially enabling the scanner.
64-
* These are needed to ensure the same parameters are used when restarting
65-
* the scanner after refreshing an RPA.
58+
/**
59+
* Scanner is configured with a timeout.
6660
*/
67-
BT_DEV_ACTIVE_SCAN,
68-
BT_DEV_SCAN_FILTER_DUP,
69-
BT_DEV_SCAN_FILTERED,
7061
BT_DEV_SCAN_LIMITED,
7162

7263
BT_DEV_INITIATING,
@@ -472,30 +463,6 @@ uint8_t bt_get_phy(uint8_t hci_phy);
472463
*/
473464
int bt_get_df_cte_type(uint8_t hci_cte_type);
474465

475-
/** Start or restart scanner if needed
476-
*
477-
* Examples of cases where it may be required to start/restart a scanner:
478-
* - When the auto-connection establishement feature is used:
479-
* - When the host sets a connection context for auto-connection establishment.
480-
* - When a connection was established.
481-
* The host may now be able to retry to automatically set up a connection.
482-
* - When a connection was disconnected/lost.
483-
* The host may now be able to retry to automatically set up a connection.
484-
* - When the application stops explicit scanning.
485-
* The host may now be able to retry to automatically set up a connection.
486-
* - The application tries to connect to another device, but fails.
487-
* The host may now be able to retry to automatically set up a connection.
488-
* - When the application wants to connect to a device, but we need
489-
* to fallback to host privacy.
490-
* - When the application wants to establish a periodic sync to a device
491-
* and the application has not already started scanning.
492-
*
493-
* @param fast_scan Use fast scan parameters or slow scan parameters
494-
*
495-
* @return 0 in case of success, or a negative error code on failure.
496-
*/
497-
int bt_le_scan_update(bool fast_scan);
498-
499466
int bt_le_create_conn(const struct bt_conn *conn);
500467
int bt_le_create_conn_cancel(void);
501468
int bt_le_create_conn_synced(const struct bt_conn *conn, const struct bt_le_ext_adv *adv,

subsys/bluetooth/host/id.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -689,11 +689,11 @@ static void rpa_timeout(struct k_work *work)
689689
le_rpa_invalidate();
690690

691691
/* IF no roles using the RPA is running we can stop the RPA timer */
692-
if (!(adv_enabled ||
693-
atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING) ||
694-
(atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) &&
695-
atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)))) {
696-
return;
692+
if (IS_ENABLED(CONFIG_BT_CENTRAL)) {
693+
if (!(adv_enabled || atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING) ||
694+
bt_le_scan_active_scanner_running())) {
695+
return;
696+
}
697697
}
698698

699699
le_update_private_addr();

0 commit comments

Comments
 (0)