Bluetooth: host: Reserve conn object for connecting with whitelist

Reserve a connection object when starting the auto-initiator using the
controller whitelist.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2020-01-07 12:40:30 +01:00 committed by Johan Hedberg
commit e9eebf0c40
3 changed files with 43 additions and 9 deletions

View file

@ -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");

View file

@ -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,

View file

@ -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) {