From 0790fdf0d71485615d56042814b24abc647ba2c4 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 9 Jul 2019 15:17:07 +0200 Subject: [PATCH] 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 --- include/bluetooth/conn.h | 17 ++++++++++++++--- subsys/bluetooth/host/conn.c | 37 ++++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/include/bluetooth/conn.h b/include/bluetooth/conn.h index de446b58d6f..763f5079012 100644 --- a/include/bluetooth/conn.h +++ b/include/bluetooth/conn.h @@ -79,6 +79,15 @@ struct bt_conn *bt_conn_ref(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. * * 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 */ enum { /** LE Connection Type */ - BT_CONN_TYPE_LE, + BT_CONN_TYPE_LE = BIT(0), /** BR/EDR Connection Type */ - BT_CONN_TYPE_BR, + BT_CONN_TYPE_BR = BIT(1), /** 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 */ diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 39657f67372..871e9a75e63 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1782,26 +1782,47 @@ struct bt_conn *bt_conn_lookup_state_le(const bt_addr_le_t *peer, 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; for (i = 0; i < ARRAY_SIZE(conns); i++) { - struct bt_conn *conn = &conns[i]; - - if (!atomic_get(&conn->ref)) { + if (!atomic_get(&conns[i].ref)) { continue; } - if (conn->id != id) { + if (!(conns[i].type & type)) { continue; } - if (conn->state == BT_CONN_CONNECTED) { - bt_conn_disconnect(conn, - BT_HCI_ERR_REMOTE_USER_TERM_CONN); + func(&conns[i], data); + } +#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)