diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 043517951a0..3eb075949b1 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -117,6 +117,8 @@ static inline const char *state2str(bt_conn_state_t state) return "connect-scan"; case BT_CONN_CONNECT_DIR_ADV: return "connect-dir-adv"; + case BT_CONN_CONNECT_AUTO: + return "connect-auto"; case BT_CONN_CONNECT: return "connect"; case BT_CONN_CONNECTED: @@ -1682,7 +1684,11 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) notify_connected(conn); bt_conn_unref(conn); } else if (old_state == BT_CONN_CONNECT_SCAN) { - /* this indicate LE Create Connection failed */ + /* this indicate LE Create Connection with peer address + * has been stopped. This could either be triggered by + * the application through bt_conn_disconnect or by + * timeout set by CONFIG_BT_CREATE_CONN_TIMEOUT. + */ if (conn->err) { notify_connected(conn); } @@ -1695,8 +1701,15 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) } bt_conn_unref(conn); + } else if (old_state == BT_CONN_CONNECT_AUTO) { + /* this indicates LE Create Connection with filter + * policy has been stopped. This can only be triggered + * by the application, so don't notify. + */ + bt_conn_unref(conn); } - + break; + case BT_CONN_CONNECT_AUTO: break; case BT_CONN_CONNECT_SCAN: break; @@ -2111,17 +2124,32 @@ int bt_conn_create_auto_le(const struct bt_le_conn_param *param) return -EINVAL; } + conn = bt_conn_add_le(BT_ID_DEFAULT, BT_ADDR_LE_NONE); + if (!conn) { + return -ENOMEM; + } + + bt_conn_set_state(conn, BT_CONN_CONNECT_AUTO); + err = bt_le_auto_conn(param); if (err) { BT_ERR("Failed to start whitelist scan"); + + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + bt_conn_unref(conn); return err; } + /* Since we don't give the application a reference to manage in + * this case, we need to release this reference here. + */ + bt_conn_unref(conn); return 0; } int bt_conn_create_auto_stop(void) { + struct bt_conn *conn; int err; if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) { @@ -2132,6 +2160,12 @@ int bt_conn_create_auto_stop(void) return -EINVAL; } + conn = bt_conn_lookup_state_le(BT_ADDR_LE_NONE, BT_CONN_CONNECT_AUTO); + if (conn) { + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + bt_conn_unref(conn); + } + err = bt_le_auto_conn_cancel(); if (err) { BT_ERR("Failed to stop initiator"); diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index f4a02d9217b..5a6adda8838 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -10,6 +10,7 @@ typedef enum __packed { BT_CONN_DISCONNECTED, BT_CONN_CONNECT_SCAN, + BT_CONN_CONNECT_AUTO, BT_CONN_CONNECT_DIR_ADV, BT_CONN_CONNECT, BT_CONN_CONNECTED, diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 4574711b0b5..5db8c3720ae 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1106,6 +1106,11 @@ static struct bt_conn *find_pending_connect(u8_t role, bt_addr_le_t *peer_addr) */ if (IS_ENABLED(CONFIG_BT_CENTRAL) && role == BT_HCI_ROLE_MASTER) { conn = bt_conn_lookup_state_le(peer_addr, BT_CONN_CONNECT); + if (IS_ENABLED(CONFIG_BT_WHITELIST) && !conn) { + conn = bt_conn_lookup_state_le(BT_ADDR_LE_NONE, + BT_CONN_CONNECT_AUTO); + } + return conn; } @@ -1273,16 +1278,10 @@ static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_WHITELIST) && evt->role == BT_HCI_ROLE_MASTER) { - /* - * Clear auto conn even if we are not able to add connection + /* Clear auto conn even if we are not able to add connection * object to keep the host in sync with controller state. */ atomic_clear_bit(bt_dev.flags, BT_DEV_AUTO_CONN); - - /* for whitelist initiator me may need to add new connection. */ - if (!conn) { - conn = bt_conn_add_le(BT_ID_DEFAULT, &id_addr); - } } if (!conn) {