Bluetooth: host: Add bt_conn_foreach API to iterate all connections

Add iterator function to iterate over all connection objects.
Make type a bitmap so that it can be used as a bitmask to select which
conns to receive foreach callback.
Use foreach function internally where possible.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2019-07-09 15:17:07 +02:00 committed by Johan Hedberg
commit 0790fdf0d7
2 changed files with 43 additions and 11 deletions

View file

@ -79,6 +79,15 @@ struct bt_conn *bt_conn_ref(struct bt_conn *conn);
*/ */
void bt_conn_unref(struct bt_conn *conn); void bt_conn_unref(struct bt_conn *conn);
/** @brief Iterate through all existing connections.
*
* @param type Connection Type
* @param func Function to call for each connection.
* @param data Data to pass to the callback function.
*/
void bt_conn_foreach(int type, void (*func)(struct bt_conn *conn, void *data),
void *data);
/** @brief Look up an existing connection by address. /** @brief Look up an existing connection by address.
* *
* Look up an existing connection based on the remote address. * Look up an existing connection based on the remote address.
@ -115,11 +124,13 @@ u8_t bt_conn_index(struct bt_conn *conn);
/** Connection Type */ /** Connection Type */
enum { enum {
/** LE Connection Type */ /** LE Connection Type */
BT_CONN_TYPE_LE, BT_CONN_TYPE_LE = BIT(0),
/** BR/EDR Connection Type */ /** BR/EDR Connection Type */
BT_CONN_TYPE_BR, BT_CONN_TYPE_BR = BIT(1),
/** SCO Connection Type */ /** SCO Connection Type */
BT_CONN_TYPE_SCO, BT_CONN_TYPE_SCO = BIT(2),
/** All Connection Type */
BT_CONN_TYPE_ALL = BT_CONN_TYPE_LE | BT_CONN_TYPE_BR | BT_CONN_TYPE_SCO,
}; };
/** LE Connection Info Structure */ /** LE Connection Info Structure */

View file

@ -1782,26 +1782,47 @@ struct bt_conn *bt_conn_lookup_state_le(const bt_addr_le_t *peer,
return NULL; return NULL;
} }
void bt_conn_disconnect_all(u8_t id) void bt_conn_foreach(int type, void (*func)(struct bt_conn *conn, void *data),
void *data)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(conns); i++) { for (i = 0; i < ARRAY_SIZE(conns); i++) {
struct bt_conn *conn = &conns[i]; if (!atomic_get(&conns[i].ref)) {
if (!atomic_get(&conn->ref)) {
continue; continue;
} }
if (conn->id != id) { if (!(conns[i].type & type)) {
continue; continue;
} }
if (conn->state == BT_CONN_CONNECTED) { func(&conns[i], data);
bt_conn_disconnect(conn, }
BT_HCI_ERR_REMOTE_USER_TERM_CONN); #if defined(CONFIG_BT_BREDR)
if (type & BT_CONN_TYPE_SCO) {
for (i = 0; i < ARRAY_SIZE(sco_conns); i++) {
if (!atomic_get(&sco_conns[i].ref)) {
continue;
}
func(&sco_conns[i], data);
} }
} }
#endif /* defined(CONFIG_BT_BREDR) */
}
static void disconnect_all(struct bt_conn *conn, void *data)
{
u8_t *id = (u8_t *)data;
if (conn->id == *id && conn->state == BT_CONN_CONNECTED) {
bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
}
}
void bt_conn_disconnect_all(u8_t id)
{
bt_conn_foreach(BT_CONN_TYPE_ALL, disconnect_all, &id);
} }
struct bt_conn *bt_conn_ref(struct bt_conn *conn) struct bt_conn *bt_conn_ref(struct bt_conn *conn)