diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 767e96400d1..4a08327f9fb 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -440,6 +440,7 @@ config BT_MAX_PAIRED config BT_CREATE_CONN_TIMEOUT int "Timeout for pending LE Create Connection command in seconds" default 3 + range 1 BT_RPA_TIMEOUT if BT_PRIVACY range 1 65535 config BT_CONN_PARAM_UPDATE_TIMEOUT diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index a3236ef8d4a..1359544a4a7 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2253,6 +2253,7 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer, return conn; } #endif + bt_conn_set_state(conn, BT_CONN_CONNECT); if (bt_le_create_conn(conn)) { diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index d4a153523a8..f7f3e3fb4a6 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -537,23 +537,11 @@ static int le_set_private_addr(u8_t id) return err; } -static void rpa_timeout(struct k_work *work) +static void le_update_private_addr(void) { bool adv_enabled = false; int err; - BT_DBG(""); - - /* Invalidate RPA */ - atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID); - - /* IF no roles using the RPA is running we can stop the RPA timer */ - if (!(atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING) || - (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) && - atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)))) { - return; - } - /* * we need to update rpa only if advertising is ongoing, with * BT_DEV_KEEP_ADVERTISING flag is handled in disconnected event @@ -572,6 +560,14 @@ static void rpa_timeout(struct k_work *work) scan_enabled = true; } #endif + if (IS_ENABLED(CONFIG_BT_CENTRAL) && + IS_ENABLED(CONFIG_BT_WHITELIST) && + atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) { + /* Canceled initiating procedure will be restarted by + * connection complete event. + */ + bt_le_create_conn_cancel(); + } /* If both advertiser and scanner is running then the advertiser ID must * be BT_ID_DEFAULT, this will update the RPA address for both roles. @@ -592,6 +588,34 @@ static void rpa_timeout(struct k_work *work) } #endif } + +static void rpa_timeout(struct k_work *work) +{ + BT_DBG(""); + + if (IS_ENABLED(CONFIG_BT_CENTRAL)) { + struct bt_conn *conn = + bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT_SCAN); + + if (conn) { + bt_conn_unref(conn); + bt_le_create_conn_cancel(); + } + } + + /* Invalidate RPA */ + atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID); + + /* IF no roles using the RPA is running we can stop the RPA timer */ + if (!(atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING) || + atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING) || + (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) && + atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)))) { + return; + } + + le_update_private_addr(); +} #else static int le_set_private_addr(u8_t id) { @@ -607,7 +631,7 @@ static int le_set_private_addr(u8_t id) return set_random_address(&nrpa); } -#endif +#endif /* defined(CONFIG_BT_PRIVACY) */ bool bt_le_scan_random_addr_check(void) { @@ -846,10 +870,21 @@ int bt_le_create_conn(const struct bt_conn *conn) } if (IS_ENABLED(CONFIG_BT_PRIVACY)) { - err = le_set_private_addr(BT_ID_DEFAULT); - if (err) { - return err; + if (use_filter) { + err = le_set_private_addr(bt_dev.adv_id); + if (err) { + return err; + } + } else { + /* Force new RPA timeout so that RPA timeout is not + * triggered while direct initiator is active. + */ + atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID); +#if defined(CONFIG_BT_PRIVACY) + le_update_private_addr(); +#endif } + if (BT_FEAT_LE_PRIVACY(bt_dev.le.features)) { own_addr_type = BT_HCI_OWN_ADDR_RPA_OR_RANDOM; } else { @@ -1282,19 +1317,34 @@ static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) * Handle cancellation of outgoing connection attempt. */ if (conn->err == BT_HCI_ERR_UNKNOWN_CONN_ID) { +#if !defined(CONFIG_BT_WHITELIST) /* We notify before checking autoconnect flag * as application may choose to change it from * callback. */ bt_conn_set_state(conn, BT_CONN_DISCONNECTED); -#if !defined(CONFIG_BT_WHITELIST) /* Check if device is marked for autoconnect. */ if (atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT)) { + /* Restart passive scanner for device */ bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); } +#else + if (atomic_test_bit(conn->flags, + BT_CONN_AUTO_CONNECT)) { + + /* Restart whitelist initiator after + * RPA timeout. + */ + bt_le_create_conn(conn); + } else { + /* Create connection canceled by timeout + */ + bt_conn_set_state(conn, + BT_CONN_DISCONNECTED); + } #endif /* !defined(CONFIG_BT_WHITELIST) */ goto done; }