Bluetooth: host: Stop using existing conn object when creating new conn

Remove re-using connection objects in disconnected state when creating
directed advertiser or establishing a connection as a central using
direct connection procedure.
This makes the API mores consistent it terms of which connection roles
can be started from the disconnected callback.
This also avoids a central connection object being re-used for a
connection as a peripheral instead and vice versa.

When attempting to create a new connection the API would returning
a valid connection object if there is already an existing connection
object.
This existing connection object could be either in the process of
establishing the connection or already connected.
Returning the connection object in this would give the false impression
that the stack has initiated connection procedure, when in fact it just
returned an existing connection object.

The application has the ability to check for existing connection objects
using the bt_conn_lookup_addr_le API.

Add warning plus comment possible scenarios why the a valid connection
object might exists. Most important is to explain why a valid connection
object exists during the disconnected callback.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2020-01-13 14:44:08 +01:00 committed by Johan Hedberg
commit 4401b6a2f3

View file

@ -2220,20 +2220,18 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, peer);
if (conn) {
switch (conn->state) {
case BT_CONN_CONNECT_SCAN:
bt_conn_set_param_le(conn, param);
return conn;
case BT_CONN_CONNECT:
case BT_CONN_CONNECTED:
return conn;
case BT_CONN_DISCONNECTED:
BT_WARN("Found valid but disconnected conn object");
goto start_scan;
default:
bt_conn_unref(conn);
return NULL;
}
/* Connection object already exists.
* If the connection state is "connect" or "connected" then
* this connection object was created using this API but has not
* yet been disconnected.
* If the connection state is "disconnected" then the connection
* still has valid references. The last reference of the stack
* is released after the disconnected callback.
*/
BT_WARN("Found valid connection in %s state",
state2str(conn->state));
bt_conn_unref(conn);
return NULL;
}
if (peer->type == BT_ADDR_LE_PUBLIC_ID ||
@ -2250,7 +2248,6 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
return NULL;
}
start_scan:
bt_conn_set_param_le(conn, param);
#if defined(CONFIG_BT_SMP)
@ -2344,17 +2341,18 @@ struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer,
conn = bt_conn_lookup_addr_le(param->id, peer);
if (conn) {
switch (conn->state) {
case BT_CONN_CONNECT_DIR_ADV:
case BT_CONN_CONNECTED:
return conn;
case BT_CONN_DISCONNECTED:
BT_WARN("Found valid but disconnected conn object");
goto start_adv;
default:
bt_conn_unref(conn);
return NULL;
}
/* Connection object already exists.
* If the connection state is "connect-dir-adv" or "connected"
* then this connection object was created using this API but
* has not yet been disconnected.
* If the connection state is "disconnected" then the connection
* still has valid references. The last reference of the stack
* is released after the disconnected callback.
*/
BT_WARN("Found valid connection in %s state",
state2str(conn->state));
bt_conn_unref(conn);
return NULL;
}
conn = bt_conn_add_le(param->id, peer);
@ -2362,7 +2360,6 @@ struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer,
return NULL;
}
start_adv:
bt_conn_set_state(conn, BT_CONN_CONNECT_DIR_ADV);
err = bt_le_adv_start_internal(&param_int, NULL, 0, NULL, 0, peer);