From c07feddb77807f503b2a3abaea7fe22f0f80ddd7 Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Wed, 24 Jul 2024 11:26:06 +0200 Subject: [PATCH] Bluetooth: Audio: Bablesim tests for CAP broadcast reception stop Implement a babblesim test for the CAP broadcast reception stop procedure Signed-off-by: Andries Kruithof --- .../bluetooth/audio/src/cap_acceptor_test.c | 33 +++++++++++-- .../bluetooth/audio/src/cap_commander_test.c | 48 ++++++++++++++++--- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c b/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c index d0a33bdc0a253f..9bfa91f08d8c16 100644 --- a/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c @@ -401,14 +401,23 @@ static int bis_sync_req_cb(struct bt_conn *conn, const struct bt_bap_scan_delegator_recv_state *recv_state, const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS]) { - /* We only care about a single subgroup in this test */ + uint32_t total_bis = 0U; + broadcaster_broadcast_id = recv_state->broadcast_id; - if (bis_sync_req[0] != 0) { + + for (int i = 0; i < recv_state->num_subgroups; i++) { + total_bis |= bis_sync_req[i]; + } + + if (total_bis != 0U) { SET_FLAG(flag_bis_sync_requested); } else { UNSET_FLAG(flag_bis_sync_requested); } + /* total_bis is the new bis-sync setting to use when calling create_and_sync_sink */ + bis_index_bitfield = total_bis; + return 0; } @@ -792,6 +801,7 @@ static void init(void) UNSET_FLAG(flag_pa_request); UNSET_FLAG(flag_received); UNSET_FLAG(flag_base_metadata_updated); + UNSET_FLAG(flag_bis_sync_requested); for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sink_streams); i++) { bt_cap_stream_ops_register( @@ -1039,10 +1049,12 @@ static void test_cap_acceptor_broadcast_reception(void) { static struct bt_bap_stream *bap_streams[ARRAY_SIZE(broadcast_sink_streams)]; size_t stream_count; + int err; init(); WAIT_FOR_FLAG(flag_pa_request); + WAIT_FOR_FLAG(flag_bis_sync_requested); pa_sync_create(); @@ -1051,12 +1063,23 @@ static void test_cap_acceptor_broadcast_reception(void) sink_wait_for_data(); /* Since we are re-using the BAP broadcast source test - * we get a metadata update, and we need to send an extra - * backchannel sync + * we get a metadata update */ base_wait_for_metadata_update(); - backchannel_sync_send_all(); /* let broadcaster know we can stop the source */ + /* when flag_bis_sync_requested is unset the bis_sync for all subgroups were set to 0 */ + WAIT_FOR_UNSET_FLAG(flag_bis_sync_requested); + + UNSET_FLAG(flag_syncable); + err = bt_bap_broadcast_sink_stop(g_broadcast_sink); + if (err != 0) { + FAIL("Unable to stop the sink: %d\n", err); + return; + } + + WAIT_FOR_FLAG(flag_syncable); + /* Although in theory we can now sync, in practice we can not since all BIS-syncs are 0 */ + backchannel_sync_send_all(); /* signal that we have stopped listening */ wait_for_streams_stop(stream_count); diff --git a/tests/bsim/bluetooth/audio/src/cap_commander_test.c b/tests/bsim/bluetooth/audio/src/cap_commander_test.c index 43e57a2e6f5b72..e35aa6ec92defc 100644 --- a/tests/bsim/bluetooth/audio/src/cap_commander_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_commander_test.c @@ -51,6 +51,7 @@ static uint32_t broadcaster_broadcast_id; static uint8_t received_base[UINT8_MAX]; static uint8_t received_base_size; +static uint8_t src_id[CONFIG_BT_MAX_CONN]; static struct k_sem sem_disconnected; static struct k_sem sem_cas_discovered; @@ -66,6 +67,7 @@ CREATE_FLAG(flag_microphone_mute_changed); CREATE_FLAG(flag_microphone_gain_changed); CREATE_FLAG(flag_broadcast_reception_start); +CREATE_FLAG(flag_broadcast_reception_stop); CREATE_FLAG(flag_broadcaster_found); CREATE_FLAG(flag_base_received); CREATE_FLAG(flag_recv_state_updated_with_bis_sync); @@ -166,6 +168,16 @@ static void cap_broadcast_reception_start_cb(struct bt_conn *conn, int err) SET_FLAG(flag_broadcast_reception_start); } + +static void cap_broadcast_reception_stop_cb(struct bt_conn *conn, int err) +{ + if (err != 0) { + FAIL("Failed to perform broadcast reception stop for conn %p: %d\n", conn, err); + return; + } + + SET_FLAG(flag_broadcast_reception_stop); +} #endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT*/ static struct bt_cap_commander_cb cap_cb = { @@ -185,6 +197,7 @@ static struct bt_cap_commander_cb cap_cb = { #endif /* CONFIG_BT_MICP_MIC_CTLR */ #if defined(CONFIG_BT_BAP_BROADCAST_ASSISTANT) .broadcast_reception_start = cap_broadcast_reception_start_cb, + .broadcast_reception_stop = cap_broadcast_reception_stop_cb, #endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT*/ }; @@ -428,6 +441,7 @@ bap_broadcast_assistant_recv_state_cb(struct bt_conn *conn, int err, { char le_addr[BT_ADDR_LE_STR_LEN]; char bad_code[BT_ISO_BROADCAST_CODE_SIZE * 2 + 1]; + size_t acceptor_count = get_dev_cnt() - 2; if (err != 0) { FAIL("BASS recv state read failed (%d)\n", err); @@ -451,6 +465,12 @@ bap_broadcast_assistant_recv_state_cb(struct bt_conn *conn, int err, return; } + for (size_t index = 0; index < acceptor_count; index++) { + if (conn == connected_conns[index]) { + src_id[index] = state->src_id; + } + } + for (uint8_t i = 0; i < state->num_subgroups; i++) { const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i]; struct net_buf_simple buf; @@ -544,6 +564,7 @@ static void init(size_t acceptor_cnt) UNSET_FLAG(flag_microphone_gain_changed); UNSET_FLAG(flag_broadcast_reception_start); + UNSET_FLAG(flag_broadcast_reception_stop); UNSET_FLAG(flag_broadcaster_found); UNSET_FLAG(flag_base_received); UNSET_FLAG(flag_recv_state_updated_with_bis_sync); @@ -978,17 +999,31 @@ static void test_broadcast_reception_start(size_t acceptor_count) static void test_broadcast_reception_stop(size_t acceptor_count) { - struct bt_cap_commander_broadcast_reception_stop_param reception_stop_param; + struct bt_cap_commander_broadcast_reception_stop_param reception_stop_param = {0}; + struct bt_cap_commander_broadcast_reception_stop_member_param param[CONFIG_BT_MAX_CONN] = { + 0}; + int err; - /* reception stop is not implemented yet, for now the following command will fail*/ reception_stop_param.type = BT_CAP_SET_TYPE_AD_HOC; - reception_stop_param.param = NULL; - reception_stop_param.count = 0U; + reception_stop_param.param = param; + reception_stop_param.count = acceptor_count; + for (size_t i = 0; i < acceptor_count; i++) { + uint8_t num_subgroups; + + reception_stop_param.param[i].member.member = connected_conns[i]; + + reception_stop_param.param[i].src_id = src_id[i]; + num_subgroups = + bt_bap_base_get_subgroup_count((const struct bt_bap_base *)received_base); + reception_stop_param.param[i].num_subgroups = num_subgroups; + } err = bt_cap_commander_broadcast_reception_stop(&reception_stop_param); if (err != 0) { - printk("Command not implemented yet, could not stop broadcast reception %d\n", err); + FAIL("Could not initiate broadcast reception stop: %d\n", err); + return; } + WAIT_FOR_FLAG(flag_broadcast_reception_stop); } static void test_main_cap_commander_capture_and_render(void) @@ -1070,8 +1105,7 @@ static void test_main_cap_commander_broadcast_reception(void) backchannel_sync_wait_any(); /* wait for the acceptor to receive data */ - backchannel_sync_wait_any(); /* wait for the acceptor to receive a metadata update - */ + backchannel_sync_wait_any(); /* wait for the acceptor to receive a metadata update */ test_broadcast_reception_stop(acceptor_count);