Skip to content

Commit 117dca0

Browse files
Thalleyfabiobaltieri
authored andcommitted
samples: Bluetooth: BAP: BA: Reset states and modify error checking
Modify the reset function to also reset the connection and PA sync states. Modify and add missing checks for mutex locks to use ASSERT when using K_FOREVER, as they should never fail/timeout. Cleanup some text and error checks. Ensure that the add_src_param is reset for each loop iteration as well. Modify so that we use K_FOREVER fewer places. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
1 parent c89441a commit 117dca0

File tree

1 file changed

+89
-62
lines changed
  • samples/bluetooth/bap_broadcast_assistant/src

1 file changed

+89
-62
lines changed

samples/bluetooth/bap_broadcast_assistant/src/main.c

Lines changed: 89 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/*
22
* Copyright (c) 2024 Demant A/S
3-
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
* Copyright (c) 2024-2025 Nordic Semiconductor ASA
44
*
55
* SPDX-License-Identifier: Apache-2.0
66
*/
77

88
#include <errno.h>
9+
#include <stdbool.h>
910
#include <stddef.h>
1011
#include <stdint.h>
1112
#include <string.h>
@@ -24,6 +25,7 @@
2425
#include <zephyr/bluetooth/uuid.h>
2526
#include <zephyr/kernel.h>
2627
#include <zephyr/net_buf.h>
28+
#include <zephyr/sys/__assert.h>
2729
#include <zephyr/sys/byteorder.h>
2830
#include <zephyr/sys/printk.h>
2931
#include <zephyr/sys/util.h>
@@ -33,6 +35,8 @@
3335
#define PA_SYNC_SKIP 5
3436
#define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */
3537
/* Broadcast IDs are 24bit, so this is out of valid range */
38+
/* Default semaphore timeout when waiting for an action */
39+
#define SEM_TIMEOUT K_SECONDS(10)
3640

3741
static void scan_for_broadcast_sink(void);
3842

@@ -68,6 +72,7 @@ static K_SEM_DEFINE(sem_sink_disconnected, 0, 1);
6872
static K_SEM_DEFINE(sem_security_updated, 0, 1);
6973
static K_SEM_DEFINE(sem_bass_discovered, 0, 1);
7074
static K_SEM_DEFINE(sem_pa_synced, 0, 1);
75+
static K_SEM_DEFINE(sem_pa_sync_terminted, 0, 1);
7176
static K_SEM_DEFINE(sem_received_base_subgroups, 0, 1);
7277

7378
static bool device_found(struct bt_data *data, void *user_data)
@@ -147,6 +152,7 @@ static bool base_store(struct bt_data *data, void *user_data)
147152
const struct bt_bap_base *base = bt_bap_base_get_base_from_ad(data);
148153
int base_size;
149154
int base_subgroup_count;
155+
int err;
150156

151157
/* Base is NULL if the data does not contain a valid BASE */
152158
if (base == NULL) {
@@ -168,13 +174,19 @@ static bool base_store(struct bt_data *data, void *user_data)
168174
}
169175

170176
/* Compare BASE and copy if different */
171-
k_mutex_lock(&base_store_mutex, K_FOREVER);
177+
err = k_mutex_lock(&base_store_mutex, K_MSEC(100));
178+
if (err != 0) {
179+
/* Could not get BASE mutex, wait for new to avoid blocking */
180+
return false;
181+
}
182+
172183
if ((size_t)base_size != received_base_size ||
173184
memcmp(base, received_base, (size_t)base_size) != 0) {
174185
(void)memcpy(received_base, base, base_size);
175186
received_base_size = (size_t)base_size;
176187
}
177-
k_mutex_unlock(&base_store_mutex);
188+
err = k_mutex_unlock(&base_store_mutex);
189+
__ASSERT_NO_MSG(err == 0);
178190

179191
/* Stop parsing */
180192
k_sem_give(&sem_received_base_subgroups);
@@ -419,9 +431,7 @@ static void scan_for_broadcast_source(void)
419431
printk("Scanning for Broadcast Source successfully started\n");
420432

421433
err = k_sem_take(&sem_source_discovered, K_FOREVER);
422-
if (err != 0) {
423-
printk("Failed to take sem_source_discovered (err %d)\n", err);
424-
}
434+
__ASSERT_NO_MSG(err == 0);
425435
}
426436

427437
static void scan_for_broadcast_sink(void)
@@ -439,9 +449,7 @@ static void scan_for_broadcast_sink(void)
439449
printk("Scanning for Broadcast Sink successfully started\n");
440450

441451
err = k_sem_take(&sem_sink_discovered, K_FOREVER);
442-
if (err != 0) {
443-
printk("Failed to take sem_sink_discovered (err %d)\n", err);
444-
}
452+
__ASSERT_NO_MSG(err == 0);
445453
}
446454

447455
static void connected(struct bt_conn *conn, uint8_t err)
@@ -528,6 +536,16 @@ static void pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
528536
k_sem_give(&sem_pa_synced);
529537
}
530538
}
539+
static void pa_sync_term_cb(struct bt_le_per_adv_sync *sync,
540+
const struct bt_le_per_adv_sync_term_info *info)
541+
{
542+
if (sync == pa_sync) {
543+
printk("PA sync %p terminated with reason %u\n", sync, info->reason);
544+
545+
k_sem_give(&sem_pa_sync_terminted);
546+
pa_sync = NULL;
547+
}
548+
}
531549

532550
static struct bt_bap_broadcast_assistant_cb ba_cbs = {
533551
.discover = bap_broadcast_assistant_discover_cb,
@@ -536,14 +554,49 @@ static struct bt_bap_broadcast_assistant_cb ba_cbs = {
536554

537555
static struct bt_le_per_adv_sync_cb pa_synced_cb = {
538556
.synced = pa_sync_synced_cb,
557+
.term = pa_sync_term_cb,
539558
.recv = pa_recv,
540559
};
541560

542561
static void reset(void)
543562
{
544-
printk("\n\nReset...\n\n");
563+
int err;
564+
565+
printk("\n\nResetting...\n\n");
566+
567+
if (broadcast_sink_conn != NULL) {
568+
err = bt_conn_disconnect(broadcast_sink_conn, BT_HCI_ERR_LOCALHOST_TERM_CONN);
569+
570+
if (err != 0) {
571+
printk("bt_conn_disconnect failed with %d\n", err);
572+
} else {
573+
if (k_sem_take(&sem_sink_disconnected, SEM_TIMEOUT) != 0) {
574+
/* This should not happen */
575+
576+
__ASSERT_NO_MSG(false);
577+
}
578+
}
579+
__ASSERT_NO_MSG(err == 0);
580+
}
581+
582+
/* Ignore return value as scanning may already be stopped */
583+
(void)bt_le_scan_stop();
584+
585+
if (pa_sync != NULL) {
586+
err = bt_le_per_adv_sync_delete(pa_sync);
587+
588+
if (err != 0) {
589+
printk("bt_le_per_adv_sync_delete failed with %d\n", err);
590+
} else {
591+
if (k_sem_take(&sem_pa_sync_terminted, SEM_TIMEOUT) != 0) {
592+
/* This should not happen */
593+
594+
__ASSERT_NO_MSG(false);
595+
}
596+
}
597+
__ASSERT_NO_MSG(err == 0);
598+
}
545599

546-
broadcast_sink_conn = NULL;
547600
selected_broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
548601
selected_sid = 0;
549602
selected_pa_interval = 0;
@@ -568,7 +621,6 @@ BT_CONN_CB_DEFINE(conn_callbacks) = {
568621
int main(void)
569622
{
570623
int err;
571-
struct bt_bap_broadcast_assistant_add_src_param param = { 0 };
572624

573625
err = bt_enable(NULL);
574626
if (err) {
@@ -585,45 +637,33 @@ int main(void)
585637
k_mutex_init(&base_store_mutex);
586638

587639
while (true) {
640+
struct bt_bap_broadcast_assistant_add_src_param param = {0};
641+
642+
reset();
643+
588644
scan_for_broadcast_sink();
589645

590-
err = k_sem_take(&sem_sink_connected, K_FOREVER);
646+
err = k_sem_take(&sem_sink_connected, SEM_TIMEOUT);
591647
if (err != 0) {
592648
printk("Failed to take sem_sink_connected (err %d)\n", err);
649+
continue;
593650
}
594651

595652
err = bt_bap_broadcast_assistant_discover(broadcast_sink_conn);
596653
if (err != 0) {
597654
printk("Failed to discover BASS on the sink (err %d)\n", err);
655+
continue;
598656
}
599657

600-
err = k_sem_take(&sem_security_updated, K_SECONDS(10));
658+
err = k_sem_take(&sem_security_updated, SEM_TIMEOUT);
601659
if (err != 0) {
602-
printk("Failed to take sem_security_updated (err %d), resetting\n", err);
603-
bt_conn_disconnect(broadcast_sink_conn, BT_HCI_ERR_AUTH_FAIL);
604-
605-
if (k_sem_take(&sem_sink_disconnected, K_SECONDS(10)) != 0) {
606-
/* This should not happen */
607-
return -ETIMEDOUT;
608-
}
609-
610-
reset();
660+
printk("Failed to take sem_security_updated (err %d)\n", err);
611661
continue;
612662
}
613663

614-
err = k_sem_take(&sem_bass_discovered, K_SECONDS(10));
664+
err = k_sem_take(&sem_bass_discovered, SEM_TIMEOUT);
615665
if (err != 0) {
616-
if (err == -EAGAIN) {
617-
printk("Failed to take sem_bass_discovered (err %d)\n", err);
618-
}
619-
bt_conn_disconnect(broadcast_sink_conn, BT_HCI_ERR_UNSUPP_REMOTE_FEATURE);
620-
621-
if (k_sem_take(&sem_sink_disconnected, K_SECONDS(10)) != 0) {
622-
/* This should not happen */
623-
return -ETIMEDOUT;
624-
}
625-
626-
reset();
666+
printk("Failed to take sem_bass_discovered (err %d)\n", err);
627667
continue;
628668
}
629669

@@ -636,19 +676,19 @@ int main(void)
636676

637677
scan_for_broadcast_source();
638678

639-
printk("Scan stopped, attempting to PA sync to the broadcaster with id 0x%06X\n",
679+
printk("Attempting to PA sync to the broadcaster with id 0x%06X\n",
640680
selected_broadcast_id);
641681
err = pa_sync_create();
642682
if (err != 0) {
643-
printk("Could not create Broadcast PA sync: %d, resetting\n", err);
644-
return -ETIMEDOUT;
683+
printk("Could not create Broadcast PA sync: %d\n", err);
684+
continue;
645685
}
646686

647687
printk("Waiting for PA synced\n");
648-
err = k_sem_take(&sem_pa_synced, K_FOREVER);
688+
err = k_sem_take(&sem_pa_synced, SEM_TIMEOUT);
649689
if (err != 0) {
650-
printk("sem_pa_synced timed out, resetting\n");
651-
return err;
690+
printk("Failed to take sem_pa_synced (err %d)\n", err);
691+
continue;
652692
}
653693

654694
memset(bass_subgroups, 0, sizeof(bass_subgroups));
@@ -661,42 +701,29 @@ int main(void)
661701

662702
/* Wait to receive subgroups */
663703
err = k_sem_take(&sem_received_base_subgroups, K_FOREVER);
664-
if (err != 0) {
665-
printk("Failed to take sem_received_base_subgroups (err %d)\n", err);
666-
return err;
667-
}
704+
__ASSERT_NO_MSG(err == 0);
668705

669-
k_mutex_lock(&base_store_mutex, K_FOREVER);
706+
err = k_mutex_lock(&base_store_mutex, K_FOREVER);
707+
__ASSERT_NO_MSG(err == 0);
670708
err = bt_bap_base_foreach_subgroup((const struct bt_bap_base *)received_base,
671709
add_pa_sync_base_subgroup_cb, &param);
672-
k_mutex_unlock(&base_store_mutex);
710+
err = k_mutex_unlock(&base_store_mutex);
711+
__ASSERT_NO_MSG(err == 0);
673712

674-
if (err < 0) {
713+
if (err != 0) {
675714
printk("Could not add BASE to params %d\n", err);
676715
continue;
677716
}
678717

679718
err = bt_bap_broadcast_assistant_add_src(broadcast_sink_conn, &param);
680-
if (err) {
719+
if (err != 0) {
681720
printk("Failed to add source: %d\n", err);
682-
bt_conn_disconnect(broadcast_sink_conn, BT_HCI_ERR_UNSUPP_REMOTE_FEATURE);
683-
684-
if (k_sem_take(&sem_sink_disconnected, K_SECONDS(10)) != 0) {
685-
/* This should not happen */
686-
return -ETIMEDOUT;
687-
}
688-
689-
reset();
690721
continue;
691722
}
692723

693724
/* Reset if the sink disconnects */
694725
err = k_sem_take(&sem_sink_disconnected, K_FOREVER);
695-
if (err != 0) {
696-
printk("Failed to take sem_sink_disconnected (err %d)\n", err);
697-
}
698-
699-
reset();
726+
__ASSERT_NO_MSG(err == 0);
700727
}
701728

702729
return 0;

0 commit comments

Comments
 (0)