Commit 89c94918 authored by Aleksander Wasaznik's avatar Aleksander Wasaznik Committed by Carles Cufi
Browse files

Bluetooth: testlib: add `bt_testlib_conn_wait_free`

This function waits for a free connection slot. It should be used to
slow down a busy loop trying to obtains a connection slot.

Signed-off-by: default avatarAleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
parent c84c9bee
Loading
Loading
Loading
Loading
+14 −0
Changes for tests/bluetooth/common/testlib/include/testlib/conn.h: 14 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -105,4 +105,18 @@ void bt_testlib_conn_unref(struct bt_conn **connp);
 */
struct bt_conn *bt_testlib_conn_unindex(enum bt_conn_type conn_type, uint8_t conn_index);

/**
 * @brief Wait until there is a free connection slot
 *
 * Thread-safe.
 *
 * Returns when there already is a free connection slot or a
 * connection slot is recycled.
 *
 * @note The free connection slots may have been taken by the
 * time this function returns. Call this function in a loop if
 * needed.
 */
void bt_testlib_conn_wait_free(void);

#endif /* ZEPHYR_TESTS_BLUETOOTH_COMMON_TESTLIB_INCLUDE_TESTLIB_CONN_H_ */
+41 −0
Changes for tests/bluetooth/common/testlib/src/conn_wait.c: 41 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <zephyr/kernel.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/util_macro.h>

#include <testlib/conn.h>

@@ -19,6 +20,7 @@
LOG_MODULE_REGISTER(bt_testlib_conn_wait, LOG_LEVEL_DBG);

static K_MUTEX_DEFINE(conn_wait_mutex);
static K_CONDVAR_DEFINE(conn_recycled);
static K_CONDVAR_DEFINE(something_changed);

static void on_change(struct bt_conn *conn, uint8_t err)
@@ -28,9 +30,17 @@ static void on_change(struct bt_conn *conn, uint8_t err)
	k_mutex_unlock(&conn_wait_mutex);
}

static void on_conn_recycled(void)
{
	k_mutex_lock(&conn_wait_mutex, K_FOREVER);
	k_condvar_broadcast(&conn_recycled);
	k_mutex_unlock(&conn_wait_mutex);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = on_change,
	.disconnected = on_change,
	.recycled = on_conn_recycled,
};

static enum bt_conn_state bt_conn_state(struct bt_conn *conn)
@@ -66,3 +76,34 @@ int bt_testlib_wait_disconnected(struct bt_conn *conn)
	k_mutex_unlock(&conn_wait_mutex);
	return 0;
}

void bt_testlib_conn_wait_free(void)
{
	if (!IS_ENABLED(CONFIG_BT_CONN)) {
		__ASSERT_NO_MSG(false);
		return;
	}

	/* The mutex must be held duing the initial check loop to buffer
	 * any `conn_cb.released` events.
	 *
	 * This ensures that any connection slots that become free
	 * during the loop execution are detected.
	 */
	k_mutex_lock(&conn_wait_mutex, K_FOREVER);

	for (size_t i = 0; i < CONFIG_BT_MAX_CONN; i++) {
		struct bt_conn *conn = bt_testlib_conn_unindex(BT_CONN_TYPE_LE, i);

		if (!conn) {
			goto done;
		}

		bt_testlib_conn_unref(&conn);
	}

	k_condvar_wait(&conn_recycled, &conn_wait_mutex, K_FOREVER);

done:
	k_mutex_unlock(&conn_wait_mutex);
}