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);
/** @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 */

View file

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