Skip to content

Commit 42602e6

Browse files
Thalleycarlescufi
authored andcommitted
Bluetooth: TBS: Replace busy bool with atomic
Replace the busy boolean flag with an atomic value. This prevents any race conditions with the implementation. The discovery procedure is also now properly guarded with it so that in case that any procedure is currently in progress for the specific connection, then a new discovery procedure cannot happen until all other procedures are finished. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 3a07c9f commit 42602e6

File tree

2 files changed

+68
-5
lines changed

2 files changed

+68
-5
lines changed

subsys/bluetooth/audio/tbs_client.c

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -769,15 +769,17 @@ static void initialize_net_buf_read_buffer(struct bt_tbs_instance *inst)
769769
static void tbs_client_gatt_read_complete(struct bt_tbs_instance *inst)
770770
{
771771
(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
772-
inst->busy = false;
772+
atomic_clear_bit(inst->flags, BT_TBS_CLIENT_FLAG_BUSY);
773773
}
774774

775775
static int tbs_client_gatt_read(struct bt_conn *conn, struct bt_tbs_instance *inst, uint16_t handle,
776776
bt_gatt_read_func_t func)
777777
{
778778
int err;
779779

780-
if (inst->busy) {
780+
if (atomic_test_and_set_bit(inst->flags, BT_TBS_CLIENT_FLAG_BUSY)) {
781+
LOG_DBG("Instance is busy");
782+
781783
return -EBUSY;
782784
}
783785

@@ -787,7 +789,6 @@ static int tbs_client_gatt_read(struct bt_conn *conn, struct bt_tbs_instance *in
787789
inst->read_params.handle_count = 1U;
788790
inst->read_params.single.handle = handle;
789791
inst->read_params.single.offset = 0U;
790-
inst->busy = true;
791792

792793
err = bt_gatt_read(conn, &inst->read_params);
793794
if (err != 0) {
@@ -827,6 +828,15 @@ static void tbs_client_discover_complete(struct bt_conn *conn, int err)
827828
/* Clear the current instance in discovery */
828829
srv_inst->current_inst = NULL;
829830

831+
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
832+
atomic_clear_bit(srv_inst->gtbs_inst.flags, BT_TBS_CLIENT_FLAG_BUSY);
833+
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */
834+
#if defined(CONFIG_BT_TBS_CLIENT_TBS)
835+
for (size_t i = 0U; i < ARRAY_SIZE(srv_inst->tbs_insts); i++) {
836+
atomic_clear_bit(srv_inst->tbs_insts[i].flags, BT_TBS_CLIENT_FLAG_BUSY);
837+
}
838+
#endif /* CONFIG_BT_TBS_CLIENT_TBS */
839+
830840
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
831841
if (listener->discover != NULL) {
832842
listener->discover(conn, err, inst_cnt(srv_inst), gtbs_found(srv_inst));
@@ -2381,6 +2391,48 @@ int bt_tbs_client_read_friendly_name(struct bt_conn *conn, uint8_t inst_index)
23812391
}
23822392
#endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
23832393

2394+
static bool check_and_set_all_busy(struct bt_tbs_server_inst *srv_inst)
2395+
{
2396+
bool all_idle = true;
2397+
2398+
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
2399+
if (atomic_test_and_set_bit(srv_inst->gtbs_inst.flags, BT_TBS_CLIENT_FLAG_BUSY)) {
2400+
LOG_DBG("GTBS is busy");
2401+
2402+
return false;
2403+
}
2404+
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */
2405+
2406+
#if defined(CONFIG_BT_TBS_CLIENT_TBS)
2407+
size_t num_free;
2408+
2409+
for (num_free = 0U; num_free < ARRAY_SIZE(srv_inst->tbs_insts); num_free++) {
2410+
struct bt_tbs_instance *tbs_inst = &srv_inst->tbs_insts[num_free];
2411+
2412+
if (atomic_test_and_set_bit(tbs_inst->flags, BT_TBS_CLIENT_FLAG_BUSY)) {
2413+
LOG_DBG("inst[%zu] (%p) is busy", num_free, tbs_inst);
2414+
all_idle = false;
2415+
2416+
break;
2417+
}
2418+
}
2419+
#endif /* CONFIG_BT_TBS_CLIENT_TBS */
2420+
2421+
/* If any is busy, revert any busy states we've set */
2422+
if (!all_idle) {
2423+
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
2424+
atomic_clear_bit(srv_inst->gtbs_inst.flags, BT_TBS_CLIENT_FLAG_BUSY);
2425+
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */
2426+
#if defined(CONFIG_BT_TBS_CLIENT_TBS)
2427+
for (uint8_t i = 0U; i < num_free; i++) {
2428+
atomic_clear_bit(srv_inst->tbs_insts[i].flags, BT_TBS_CLIENT_FLAG_BUSY);
2429+
}
2430+
#endif /* CONFIG_BT_TBS_CLIENT_TBS */
2431+
}
2432+
2433+
return all_idle;
2434+
}
2435+
23842436
int bt_tbs_client_discover(struct bt_conn *conn)
23852437
{
23862438
uint8_t conn_index;
@@ -2393,7 +2445,10 @@ int bt_tbs_client_discover(struct bt_conn *conn)
23932445
conn_index = bt_conn_index(conn);
23942446
srv_inst = &srv_insts[conn_index];
23952447

2396-
if (srv_inst->current_inst) {
2448+
/* Before we do discovery we ensure that all TBS instances are currently not busy as to not
2449+
* interfere with any procedures in progress
2450+
*/
2451+
if (!check_and_set_all_busy(srv_inst)) {
23972452
return -EBUSY;
23982453
}
23992454

subsys/bluetooth/audio/tbs_internal.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <zephyr/bluetooth/audio/tbs.h>
1919
#include <zephyr/bluetooth/gatt.h>
2020
#include <zephyr/net_buf.h>
21+
#include <zephyr/sys/atomic.h>
2122
#include <zephyr/types.h>
2223

2324
#define BT_TBS_MAX_UCI_SIZE 6
@@ -312,6 +313,12 @@ struct bt_tbs_in_uri {
312313
* sizeof(struct bt_tbs_client_call_state)))
313314
#endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
314315

316+
enum bt_tbs_client_flag {
317+
BT_TBS_CLIENT_FLAG_BUSY,
318+
319+
BT_TBS_CLIENT_FLAG_NUM_FLAGS, /* keep as last */
320+
};
321+
315322
struct bt_tbs_instance {
316323
struct bt_tbs_client_call_state calls[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
317324

@@ -336,7 +343,6 @@ struct bt_tbs_instance {
336343
#endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
337344
uint16_t termination_reason_handle;
338345

339-
bool busy;
340346
#if defined(CONFIG_BT_TBS_CLIENT_CCID)
341347
uint8_t ccid;
342348
#endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
@@ -384,5 +390,7 @@ struct bt_tbs_instance {
384390
struct bt_gatt_read_params read_params;
385391
uint8_t read_buf[BT_TBS_CLIENT_INST_READ_BUF_SIZE];
386392
struct net_buf_simple net_buf;
393+
394+
ATOMIC_DEFINE(flags, BT_TBS_CLIENT_FLAG_NUM_FLAGS);
387395
};
388396
#endif /* CONFIG_BT_TBS_CLIENT */

0 commit comments

Comments
 (0)