Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion subsys/bluetooth/audio/bass.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ static void biginfo_recv(struct bt_le_per_adv_sync *sync,
{
struct bass_recv_state_internal *state = bass_lookup_pa_sync(sync);

if (state != NULL || state->biginfo_received) {
if (state == NULL || state->biginfo_received) {
return;
}

Expand Down
17 changes: 15 additions & 2 deletions subsys/bluetooth/audio/broadcast_source.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ static void broadcast_source_set_ep_state(struct bt_audio_ep *ep, uint8_t state)
break;
case BT_AUDIO_EP_STATE_QOS_CONFIGURED:
if (state != BT_AUDIO_EP_STATE_IDLE &&
state != BT_AUDIO_EP_STATE_STREAMING) {
state != BT_AUDIO_EP_STATE_ENABLING) {
BT_DBG("Invalid broadcast sync endpoint state transition");
return;
}
break;
case BT_AUDIO_EP_STATE_ENABLING:
if (state != BT_AUDIO_EP_STATE_STREAMING) {
BT_DBG("Invalid broadcast sync endpoint state transition");
return;
}
Expand Down Expand Up @@ -672,6 +678,12 @@ int bt_audio_broadcast_source_start(struct bt_audio_broadcast_source *source)
return err;
}

for (size_t i = 0U; i < source->stream_count; i++) {
struct bt_audio_ep *ep = source->streams[i]->ep;

broadcast_source_set_ep_state(ep, BT_AUDIO_EP_STATE_ENABLING);
}

return 0;
}

Expand All @@ -697,7 +709,8 @@ int bt_audio_broadcast_source_stop(struct bt_audio_broadcast_source *source)
return -EINVAL;
}

if (stream->ep->status.state != BT_AUDIO_EP_STATE_STREAMING) {
if (stream->ep->status.state != BT_AUDIO_EP_STATE_STREAMING &&
stream->ep->status.state != BT_AUDIO_EP_STATE_ENABLING) {
BT_DBG("Broadcast source stream %p invalid state: %u",
stream, stream->ep->status.state);
return -EBADMSG;
Expand Down
4 changes: 3 additions & 1 deletion subsys/bluetooth/host/iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ static void bt_iso_send_cb(struct bt_conn *iso, void *user_data, int err)
}
#endif /* CONFIG_BT_ISO_UNICAST || CONFIG_BT_ISO_BROADCASTER */


void hci_iso(struct net_buf *buf)
{
struct bt_hci_iso_hdr *hdr;
Expand Down Expand Up @@ -501,7 +502,8 @@ void bt_iso_chan_set_state_debug(struct bt_iso_chan *chan,
}
break;
case BT_ISO_STATE_DISCONNECTING:
if (chan->state != BT_ISO_STATE_CONNECTED) {
if (chan->state != BT_ISO_STATE_CONNECTING &&
chan->state != BT_ISO_STATE_CONNECTED) {
BT_WARN("%s()%d: invalid transition", func, line);
}
break;
Expand Down
27 changes: 20 additions & 7 deletions tests/bluetooth/bsim_bt/bsim_test_audio/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,17 @@ CONFIG_BT_SMP=y
# Needed for extended advertising
CONFIG_BT_EXT_ADV_LEGACY_SUPPORT=y

# Advertising Extensions support in Controller
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=255
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=255

CONFIG_BT_AUDIO=y
CONFIG_BT_AUDIO_UNICAST_SERVER=y
CONFIG_BT_AUDIO_UNICAST_CLIENT=y
CONFIG_BT_AUDIO_UNICAST_CLIENT_GROUP_STREAM_COUNT=2
CONFIG_BT_AUDIO_BROADCAST_SOURCE=y
CONFIG_BT_AUDIO_BROADCAST_SINK=y
CONFIG_BT_AUDIO_BROADCAST_SRC_STREAM_COUNT=2
CONFIG_BT_AUDIO_BROADCAST_SNK_STREAM_COUNT=2
# Only 1 stream support by controller at this point
CONFIG_BT_AUDIO_BROADCAST_SRC_STREAM_COUNT=1
# Only 1 stream support by controller at this point
CONFIG_BT_AUDIO_BROADCAST_SNK_STREAM_COUNT=1
CONFIG_BT_ISO_TX_BUF_COUNT=4

# Volume Offset Control Service
CONFIG_BT_VOCS_MAX_INSTANCE_COUNT=2
Expand Down Expand Up @@ -123,6 +121,8 @@ CONFIG_BT_DEBUG_CSIS_CLIENT=y
CONFIG_BT_DEBUG_CSIS_CRYPTO=y
CONFIG_BT_AUDIO_DEBUG_UNICAST_CLIENT=y
CONFIG_BT_AUDIO_DEBUG_UNICAST_SERVER=y
CONFIG_BT_AUDIO_DEBUG_BROADCAST_SINK=y
CONFIG_BT_AUDIO_DEBUG_BROADCAST_SOURCE=y
CONFIG_BT_DEBUG_ASCS=y
CONFIG_BT_DEBUG_PACS=y
CONFIG_BT_AUDIO_DEBUG_STREAM=y
Expand All @@ -135,3 +135,16 @@ CONFIG_BT_DEBUG_HAS_CLIENT=y
# LOGGING
CONFIG_TEST_LOGGING_DEFAULTS=n
CONFIG_LOG_MODE_IMMEDIATE=y

# Controller configs
CONFIG_BT_CTLR_ADV_ISO=y
CONFIG_BT_CTLR_SYNC_ISO=y
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=255
# Supports the highest SDU size required by any BAP LC3 presets (155)
CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE=155
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191
# Only 1 stream support by controller at this point
CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT=1
# Only 1 stream support by controller at this point
CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX=1
CONFIG_BT_CTLR_ISO_TX_BUFFERS=3
132 changes: 127 additions & 5 deletions tests/bluetooth/bsim_bt/bsim_test_audio/src/broadcast_sink_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,27 @@ extern enum bst_result_t bst_result;
CREATE_FLAG(broadcaster_found);
CREATE_FLAG(base_received);
CREATE_FLAG(pa_synced);
CREATE_FLAG(flag_syncable);
CREATE_FLAG(pa_sync_lost);
CREATE_FLAG(flag_received);

static struct bt_audio_broadcast_sink *g_sink;

/* Mandatory support preset by both source and sink */
static struct bt_audio_lc3_preset preset =
static struct bt_audio_stream broadcast_sink_streams[CONFIG_BT_AUDIO_BROADCAST_SNK_STREAM_COUNT];
static struct bt_audio_stream *streams[ARRAY_SIZE(broadcast_sink_streams)];
static struct bt_audio_lc3_preset preset_16_2_1 =
BT_AUDIO_LC3_BROADCAST_PRESET_16_2_1(BT_AUDIO_LOCATION_FRONT_LEFT,
BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);

static K_SEM_DEFINE(sem_started, 0U, ARRAY_SIZE(streams));
static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(streams));

/* Create a mask for the maximum BIS we can sync to using the number of streams
* we have. We add an additional 1 since the bis indexes start from 1 and not
* 0.
*/
static const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(streams) + 1U);
static uint32_t bis_index_bitfield;

static bool scan_recv_cb(const struct bt_le_scan_recv_info *info,
uint32_t broadcast_id)
{
Expand Down Expand Up @@ -60,16 +72,36 @@ static void pa_synced_cb(struct bt_audio_broadcast_sink *sink,
static void base_recv_cb(struct bt_audio_broadcast_sink *sink,
const struct bt_audio_base *base)
{
uint32_t base_bis_index_bitfield = 0U;

if (TEST_FLAG(base_received)) {
return;
}

printk("Received BASE with %u subgroups from broadcast sink %p\n",
base->subgroup_count, sink);


for (size_t i = 0U; i < base->subgroup_count; i++) {
for (size_t j = 0U; j < base->subgroups[i].bis_count; j++) {
const uint8_t index = base->subgroups[i].bis_data[j].index;

base_bis_index_bitfield |= BIT(index);
}
}

bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;

SET_FLAG(base_received);
}

static void syncable_cb(struct bt_audio_broadcast_sink *sink, bool encrypted)
{
printk("Broadcast sink %p syncable with%s encryption\n",
sink, encrypted ? "" : "out");
SET_FLAG(flag_syncable);
}

static void pa_sync_lost_cb(struct bt_audio_broadcast_sink *sink)
{
if (g_sink == NULL) {
Expand All @@ -93,12 +125,38 @@ static struct bt_audio_broadcast_sink_cb broadcast_sink_cbs = {
.scan_term = scan_term_cb,
.base_recv = base_recv_cb,
.pa_synced = pa_synced_cb,
.syncable = syncable_cb,
.pa_sync_lost = pa_sync_lost_cb
};

static struct bt_audio_capability capabilities = {
.dir = BT_AUDIO_DIR_SINK,
.codec = &preset.codec,
.codec = &preset_16_2_1.codec,
};

static void started_cb(struct bt_audio_stream *stream)
{
printk("Stream %p started\n", stream);
k_sem_give(&sem_started);
}

static void stopped_cb(struct bt_audio_stream *stream)
{
printk("Stream %p stopped\n", stream);
k_sem_give(&sem_stopped);
}

static void recv_cb(struct bt_audio_stream *stream,
const struct bt_iso_recv_info *info,
struct net_buf *buf)
{
SET_FLAG(flag_received);
}

static struct bt_audio_stream_ops stream_ops = {
.started = started_cb,
.stopped = stopped_cb,
.recv = recv_cb
};

static int init(void)
Expand All @@ -125,6 +183,11 @@ static int init(void)
UNSET_FLAG(base_received);
UNSET_FLAG(pa_synced);

for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
streams[i] = &broadcast_sink_streams[i];
bt_audio_stream_cb_register(streams[i], &stream_ops);
}

return 0;
}

Expand All @@ -144,17 +207,45 @@ static void test_main(void)
FAIL("Unable to start scan for broadcast sources: %d", err);
return;
}

WAIT_FOR_FLAG(broadcaster_found);
printk("Broadcast source found, waiting for PA sync\n");
WAIT_FOR_FLAG(pa_synced);
printk("Broadcast source PA synced, waiting for BASE\n");
WAIT_FOR_FLAG(base_received);
printk("BASE received\n");

printk("Waiting for BIG syncable\n");
WAIT_FOR_FLAG(flag_syncable);

printk("Syncing the sink\n");
err = bt_audio_broadcast_sink_sync(g_sink, bis_index_bitfield, streams,
NULL);
if (err != 0) {
FAIL("Unable to sync the sink: %d\n", err);
return;
}

/* Wait for all to be started */
printk("Waiting for streams to be started\n");
for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
k_sem_take(&sem_started, K_FOREVER);
}

printk("Waiting for data\n");
WAIT_FOR_FLAG(flag_received);

/* The order of PA sync lost and BIG Sync lost is irrelevant
* and depend on timeout parameters. We just wait for PA first, but
* either way will work.
*/
printk("Waiting for PA disconnected\n");
WAIT_FOR_FLAG(pa_sync_lost);

/* TODO: Handle Audio when ISO is supported in BSIM */
printk("Waiting for streams to be stopped\n");
for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
k_sem_take(&sem_stopped, K_FOREVER);
}

PASS("Broadcast sink passed\n");
}
Expand Down Expand Up @@ -182,6 +273,37 @@ static void test_sink_disconnect(void)
WAIT_FOR_FLAG(base_received);
printk("BASE received\n");

printk("Waiting for BIG syncable\n");
WAIT_FOR_FLAG(flag_syncable);

printk("Syncing the sink\n");
/* TODO: Sync to max streams instead of just BIT(1) */
err = bt_audio_broadcast_sink_sync(g_sink, BIT(1), streams, NULL);
if (err != 0) {
FAIL("Unable to sync the sink: %d\n", err);
return;
}

/* Wait for all to be started */
printk("Waiting for streams to be started\n");
for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
k_sem_take(&sem_started, K_FOREVER);
}

printk("Waiting for data\n");
WAIT_FOR_FLAG(flag_received);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, redundant newline

err = bt_audio_broadcast_sink_stop(g_sink);
if (err != 0) {
FAIL("Unable to stop sink: %d", err);
return;
}

printk("Waiting for streams to be stopped\n");
for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
k_sem_take(&sem_stopped, K_FOREVER);
}

err = bt_audio_broadcast_sink_delete(g_sink);
if (err != 0) {
FAIL("Unable to delete sink: %d", err);
Expand Down
Loading