Skip to content

Commit 0ae9761

Browse files
Thalleykartben
authored andcommitted
Bluetooth: CAP: Add broadcast source callback structs
These callbacks are trigger for changes that affect the entire broadcast source, such as the BIG started and terminated events. Signed-off-by: Emil Gydesen <[email protected]>
1 parent ab9ee08 commit 0ae9761

File tree

5 files changed

+132
-15
lines changed

5 files changed

+132
-15
lines changed

include/zephyr/bluetooth/audio/cap.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,22 @@ struct bt_cap_initiator_cb {
128128
*/
129129
void (*unicast_stop_complete)(int err, struct bt_conn *conn);
130130
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
131+
#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
132+
/**
133+
* @brief The Broadcast Source has started and all of the streams are ready for audio data
134+
*
135+
* @param source The started Broadcast Source
136+
*/
137+
void (*broadcast_started)(struct bt_cap_broadcast_source *source);
138+
139+
/**
140+
* @brief The Broadcast Source has stopped and none of the streams are ready for audio data
141+
*
142+
* @param source The stopped Broadcast Source
143+
* @param reason The reason why the Broadcast Source stopped (see the BT_HCI_ERR_* values)
144+
*/
145+
void (*broadcast_stopped)(struct bt_cap_broadcast_source *source, uint8_t reason);
146+
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
131147
};
132148

133149
/**

subsys/bluetooth/audio/cap_initiator.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,54 @@ int bt_cap_initiator_broadcast_audio_create(
257257
&(*broadcast_source)->bap_broadcast);
258258
}
259259

260+
static struct bt_cap_broadcast_source *get_cap_broadcast_source_by_bap_broadcast_source(
261+
const struct bt_bap_broadcast_source *bap_broadcast_source)
262+
{
263+
for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sources); i++) {
264+
if (broadcast_sources[i].bap_broadcast == bap_broadcast_source) {
265+
return &broadcast_sources[i];
266+
}
267+
}
268+
269+
return NULL;
270+
}
271+
272+
static void broadcast_source_started_cb(struct bt_bap_broadcast_source *bap_broadcast_source)
273+
{
274+
if (cap_cb && cap_cb->broadcast_started) {
275+
struct bt_cap_broadcast_source *source =
276+
get_cap_broadcast_source_by_bap_broadcast_source(bap_broadcast_source);
277+
278+
if (source == NULL) {
279+
/* Not one of ours */
280+
return;
281+
}
282+
283+
cap_cb->broadcast_started(source);
284+
}
285+
}
286+
287+
static void broadcast_source_stopped_cb(struct bt_bap_broadcast_source *bap_broadcast_source,
288+
uint8_t reason)
289+
{
290+
if (cap_cb && cap_cb->broadcast_stopped) {
291+
struct bt_cap_broadcast_source *source =
292+
get_cap_broadcast_source_by_bap_broadcast_source(bap_broadcast_source);
293+
294+
if (source == NULL) {
295+
/* Not one of ours */
296+
return;
297+
}
298+
299+
cap_cb->broadcast_stopped(source, reason);
300+
}
301+
}
302+
260303
int bt_cap_initiator_broadcast_audio_start(struct bt_cap_broadcast_source *broadcast_source,
261304
struct bt_le_ext_adv *adv)
262305
{
306+
static bool broadcast_source_cbs_registered;
307+
263308
CHECKIF(adv == NULL) {
264309
LOG_DBG("adv is NULL");
265310
return -EINVAL;
@@ -270,6 +315,21 @@ int bt_cap_initiator_broadcast_audio_start(struct bt_cap_broadcast_source *broad
270315
return -EINVAL;
271316
}
272317

318+
if (!broadcast_source_cbs_registered) {
319+
static struct bt_bap_broadcast_source_cb broadcast_source_cb = {
320+
.started = broadcast_source_started_cb,
321+
.stopped = broadcast_source_stopped_cb,
322+
};
323+
const int err = bt_bap_broadcast_source_register_cb(&broadcast_source_cb);
324+
325+
if (err != 0) {
326+
__ASSERT(false, "Failed to register BAP broadcast source callbacks: %d",
327+
err);
328+
}
329+
330+
broadcast_source_cbs_registered = true;
331+
}
332+
273333
return bt_bap_broadcast_source_start(broadcast_source->bap_broadcast, adv);
274334
}
275335

tests/bluetooth/audio/cap_initiator/include/cap_initiator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,8 @@ DECLARE_FAKE_VOID_FUNC(mock_cap_initiator_unicast_discovery_complete_cb, struct
2323
DECLARE_FAKE_VOID_FUNC(mock_cap_initiator_unicast_start_complete_cb, int, struct bt_conn *);
2424
DECLARE_FAKE_VOID_FUNC(mock_cap_initiator_unicast_update_complete_cb, int, struct bt_conn *);
2525
DECLARE_FAKE_VOID_FUNC(mock_cap_initiator_unicast_stop_complete_cb, int, struct bt_conn *);
26+
DECLARE_FAKE_VOID_FUNC(mock_cap_initiator_broadcast_started_cb, struct bt_cap_broadcast_source *);
27+
DECLARE_FAKE_VOID_FUNC(mock_cap_initiator_broadcast_stopped_cb, struct bt_cap_broadcast_source *,
28+
uint8_t);
2629

2730
#endif /* MOCKS_CAP_INITIATOR_H_ */

tests/bluetooth/audio/cap_initiator/uut/cap_initiator.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ DEFINE_FAKE_VOID_FUNC(mock_cap_initiator_unicast_discovery_complete_cb, struct b
2525
DEFINE_FAKE_VOID_FUNC(mock_cap_initiator_unicast_start_complete_cb, int, struct bt_conn *);
2626
DEFINE_FAKE_VOID_FUNC(mock_cap_initiator_unicast_update_complete_cb, int, struct bt_conn *);
2727
DEFINE_FAKE_VOID_FUNC(mock_cap_initiator_unicast_stop_complete_cb, int, struct bt_conn *);
28+
DEFINE_FAKE_VOID_FUNC(mock_cap_initiator_broadcast_started_cb, struct bt_cap_broadcast_source *);
29+
DEFINE_FAKE_VOID_FUNC(mock_cap_initiator_broadcast_stopped_cb, struct bt_cap_broadcast_source *,
30+
uint8_t);
2831

2932
const struct bt_cap_initiator_cb mock_cap_initiator_cb = {
3033
#if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
@@ -33,6 +36,10 @@ const struct bt_cap_initiator_cb mock_cap_initiator_cb = {
3336
.unicast_update_complete = mock_cap_initiator_unicast_update_complete_cb,
3437
.unicast_stop_complete = mock_cap_initiator_unicast_stop_complete_cb,
3538
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
39+
#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
40+
.broadcast_started = mock_cap_initiator_broadcast_started_cb,
41+
.broadcast_stopped = mock_cap_initiator_broadcast_stopped_cb,
42+
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
3643
};
3744

3845
void mock_cap_initiator_init(void)

tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include "common.h"
3434

3535
#if defined(CONFIG_BT_CAP_INITIATOR) && defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
36+
CREATE_FLAG(flag_source_started);
37+
3638
/* Zephyr Controller works best while Extended Advertising interval to be a multiple
3739
* of the ISO Interval minus 10 ms (max. advertising random delay). This is
3840
* required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
@@ -75,8 +77,8 @@ static struct bt_bap_lc3_preset broadcast_preset_16_2_1 =
7577
BT_BAP_LC3_BROADCAST_PRESET_16_2_1(LOCATION, CONTEXT);
7678
static size_t stream_count;
7779

78-
static K_SEM_DEFINE(sem_broadcast_started, 0U, ARRAY_SIZE(broadcast_streams));
79-
static K_SEM_DEFINE(sem_broadcast_stopped, 0U, ARRAY_SIZE(broadcast_streams));
80+
static K_SEM_DEFINE(sem_broadcast_stream_started, 0U, ARRAY_SIZE(broadcast_streams));
81+
static K_SEM_DEFINE(sem_broadcast_stream_stopped, 0U, ARRAY_SIZE(broadcast_streams));
8082

8183
static const struct named_lc3_preset lc3_broadcast_presets[] = {
8284
{"8_1_1", BT_BAP_LC3_BROADCAST_PRESET_8_1_1(LOCATION, CONTEXT)},
@@ -114,24 +116,24 @@ static const struct named_lc3_preset lc3_broadcast_presets[] = {
114116
{"48_6_2", BT_BAP_LC3_BROADCAST_PRESET_48_6_2(LOCATION, CONTEXT)},
115117
};
116118

117-
static void broadcast_started_cb(struct bt_bap_stream *stream)
119+
static void broadcast_stream_started_cb(struct bt_bap_stream *stream)
118120
{
119121
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
120122

121123
test_stream->seq_num = 0U;
122124
test_stream->tx_cnt = 0U;
123125

124126
printk("Stream %p started\n", stream);
125-
k_sem_give(&sem_broadcast_started);
127+
k_sem_give(&sem_broadcast_stream_started);
126128
}
127129

128-
static void broadcast_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
130+
static void broadcast_stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
129131
{
130132
printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
131-
k_sem_give(&sem_broadcast_stopped);
133+
k_sem_give(&sem_broadcast_stream_stopped);
132134
}
133135

134-
static void broadcast_sent_cb(struct bt_bap_stream *bap_stream)
136+
static void broadcast_stream_sent_cb(struct bt_bap_stream *bap_stream)
135137
{
136138
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(bap_stream);
137139
struct bt_cap_stream *cap_stream = cap_stream_from_audio_test_stream(test_stream);
@@ -178,13 +180,30 @@ static void broadcast_sent_cb(struct bt_bap_stream *bap_stream)
178180
}
179181

180182
static struct bt_bap_stream_ops broadcast_stream_ops = {
181-
.started = broadcast_started_cb,
182-
.stopped = broadcast_stopped_cb,
183-
.sent = broadcast_sent_cb,
183+
.started = broadcast_stream_started_cb,
184+
.stopped = broadcast_stream_stopped_cb,
185+
.sent = broadcast_stream_sent_cb,
184186
};
185187

188+
static void broadcast_source_started_cb(struct bt_cap_broadcast_source *broadcast_source)
189+
{
190+
printk("Broadcast source %p started\n", broadcast_source);
191+
SET_FLAG(flag_source_started);
192+
}
193+
194+
static void broadcast_source_stopped_cb(struct bt_cap_broadcast_source *broadcast_source,
195+
uint8_t reason)
196+
{
197+
printk("Broadcast source %p stopped with reason 0x%02X\n", broadcast_source, reason);
198+
UNSET_FLAG(flag_source_started);
199+
}
200+
186201
static void init(void)
187202
{
203+
static struct bt_cap_initiator_cb broadcast_cbs = {
204+
.broadcast_started = broadcast_source_started_cb,
205+
.broadcast_stopped = broadcast_source_stopped_cb,
206+
};
188207
int err;
189208

190209
err = bt_enable(NULL);
@@ -221,6 +240,12 @@ static void init(void)
221240

222241
printk("Registered GTBS\n");
223242
}
243+
244+
err = bt_cap_initiator_register_cb(&broadcast_cbs);
245+
if (err != 0) {
246+
FAIL("Failed to register broadcast callbacks: %d\n", err);
247+
return;
248+
}
224249
}
225250

226251
static void setup_extended_adv(struct bt_le_ext_adv **adv)
@@ -605,9 +630,11 @@ static void test_broadcast_audio_stop(struct bt_cap_broadcast_source *broadcast_
605630
/* Wait for all to be stopped */
606631
printk("Waiting for broadcast_streams to be stopped\n");
607632
for (size_t i = 0U; i < stream_count; i++) {
608-
k_sem_take(&sem_broadcast_stopped, K_FOREVER);
633+
k_sem_take(&sem_broadcast_stream_stopped, K_FOREVER);
609634
}
610635

636+
WAIT_FOR_UNSET_FLAG(flag_source_started);
637+
611638
printk("Broadcast source stopped\n");
612639

613640
/* Verify that it cannot be stopped twice */
@@ -679,17 +706,19 @@ static void test_main_cap_initiator_broadcast(void)
679706
/* Wait for all to be started */
680707
printk("Waiting for broadcast_streams to be started\n");
681708
for (size_t i = 0U; i < stream_count; i++) {
682-
k_sem_take(&sem_broadcast_started, K_FOREVER);
709+
k_sem_take(&sem_broadcast_stream_started, K_FOREVER);
683710
}
684711

712+
WAIT_FOR_FLAG(flag_source_started);
713+
685714
/* Initialize sending */
686715
for (size_t i = 0U; i < stream_count; i++) {
687716
struct audio_test_stream *test_stream = &broadcast_source_streams[i];
688717

689718
test_stream->tx_active = true;
690719

691720
for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) {
692-
broadcast_sent_cb(bap_stream_from_audio_test_stream(test_stream));
721+
broadcast_stream_sent_cb(bap_stream_from_audio_test_stream(test_stream));
693722
}
694723
}
695724

@@ -785,17 +814,19 @@ static int test_cap_initiator_ac(const struct cap_initiator_ac_param *param)
785814
/* Wait for all to be started */
786815
printk("Waiting for broadcast_streams to be started\n");
787816
for (size_t i = 0U; i < stream_count; i++) {
788-
k_sem_take(&sem_broadcast_started, K_FOREVER);
817+
k_sem_take(&sem_broadcast_stream_started, K_FOREVER);
789818
}
790819

820+
WAIT_FOR_FLAG(flag_source_started);
821+
791822
/* Initialize sending */
792823
for (size_t i = 0U; i < stream_count; i++) {
793824
struct audio_test_stream *test_stream = &broadcast_source_streams[i];
794825

795826
test_stream->tx_active = true;
796827

797828
for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) {
798-
broadcast_sent_cb(bap_stream_from_audio_test_stream(test_stream));
829+
broadcast_stream_sent_cb(bap_stream_from_audio_test_stream(test_stream));
799830
}
800831
}
801832

0 commit comments

Comments
 (0)