tests: Bluetooth: CAP: Add bsim test for unicast_audio_cancel

Add test of the unicast audio cancel that can cancel any pending
procedures. This is done by adding a new blocking behavior in the
cap acceptor.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2023-06-01 11:58:27 +02:00 committed by Anas Nashif
parent 7712f81171
commit b635a47c70
3 changed files with 123 additions and 14 deletions

View file

@ -39,6 +39,7 @@ static struct bt_bap_lc3_preset broadcast_preset_16_2_1 =
static const struct bt_codec_qos_pref unicast_qos_pref =
BT_CODEC_QOS_PREF(true, BT_GAP_LE_PHY_2M, 0u, 60u, 20000u, 40000u, 20000u, 40000u);
static bool auto_start_sink_streams;
static K_SEM_DEFINE(sem_broadcast_started, 0U, ARRAY_SIZE(broadcast_sink_streams));
static K_SEM_DEFINE(sem_broadcast_stopped, 0U, ARRAY_SIZE(broadcast_sink_streams));
@ -210,7 +211,8 @@ static void unicast_stream_enabled_cb(struct bt_bap_stream *stream)
struct bt_bap_ep_info ep_info;
int err;
printk("Enabled: stream %p\n", stream);
printk("Enabled: stream %p (auto_start_sink_streams %d)\n", stream,
auto_start_sink_streams);
err = bt_bap_ep_get_info(stream->ep, &ep_info);
if (err != 0) {
@ -218,7 +220,7 @@ static void unicast_stream_enabled_cb(struct bt_bap_stream *stream)
return;
}
if (ep_info.dir == BT_AUDIO_DIR_SINK) {
if (auto_start_sink_streams && ep_info.dir == BT_AUDIO_DIR_SINK) {
/* Automatically do the receiver start ready operation */
err = bt_bap_stream_start(stream);
@ -589,7 +591,22 @@ static void test_cap_acceptor_unicast(void)
{
init();
/* TODO: When babblesim supports ISO, wait for audio stream to pass */
auto_start_sink_streams = true;
/* TODO: wait for audio stream to pass */
WAIT_FOR_FLAG(flag_connected);
PASS("CAP acceptor unicast passed\n");
}
static void test_cap_acceptor_unicast_timeout(void)
{
init();
auto_start_sink_streams = false; /* Cause unicast_audio_start timeout */
/* TODO: wait for audio stream to pass */
WAIT_FOR_FLAG(flag_connected);
@ -660,15 +677,21 @@ static const struct bst_test_instance test_cap_acceptor[] = {
.test_id = "cap_acceptor_unicast",
.test_post_init_f = test_init,
.test_tick_f = test_tick,
.test_main_f = test_cap_acceptor_unicast
.test_main_f = test_cap_acceptor_unicast,
},
{
.test_id = "cap_acceptor_unicast_timeout",
.test_post_init_f = test_init,
.test_tick_f = test_tick,
.test_main_f = test_cap_acceptor_unicast_timeout,
},
{
.test_id = "cap_acceptor_broadcast",
.test_post_init_f = test_init,
.test_tick_f = test_tick,
.test_main_f = test_cap_acceptor_broadcast
.test_main_f = test_cap_acceptor_broadcast,
},
BSTEST_END_MARKER
BSTEST_END_MARKER,
};
struct bst_test_list *test_cap_acceptor_install(struct bst_test_list *tests)

View file

@ -26,6 +26,7 @@ CREATE_FLAG(flag_discovered);
CREATE_FLAG(flag_codec_found);
CREATE_FLAG(flag_endpoint_found);
CREATE_FLAG(flag_started);
CREATE_FLAG(flag_start_timeout);
CREATE_FLAG(flag_updated);
CREATE_FLAG(flag_stopped);
CREATE_FLAG(flag_mtu_exchanged);
@ -114,13 +115,13 @@ static void cap_discovery_complete_cb(struct bt_conn *conn, int err,
static void unicast_start_complete_cb(struct bt_bap_unicast_group *unicast_group, int err,
struct bt_conn *conn)
{
if (err != 0) {
if (err == -ECANCELED) {
SET_FLAG(flag_start_timeout);
} else if (err != 0) {
FAIL("Failed to start (failing conn %p): %d", conn, err);
return;
} else {
SET_FLAG(flag_started);
}
SET_FLAG(flag_started);
}
static void unicast_update_complete_cb(int err, struct bt_conn *conn)
@ -469,7 +470,7 @@ static void unicast_audio_start_inval(struct bt_bap_unicast_group *unicast_group
}
}
static void unicast_audio_start(struct bt_bap_unicast_group *unicast_group)
static void unicast_audio_start(struct bt_bap_unicast_group *unicast_group, bool wait)
{
struct bt_cap_unicast_audio_start_stream_param stream_param[1];
struct bt_cap_unicast_audio_start_param param;
@ -492,7 +493,9 @@ static void unicast_audio_start(struct bt_bap_unicast_group *unicast_group)
return;
}
WAIT_FOR_FLAG(flag_started);
if (wait) {
WAIT_FOR_FLAG(flag_started);
}
}
static void unicast_audio_update_inval(void)
@ -584,6 +587,17 @@ static void unicast_audio_stop(struct bt_bap_unicast_group *unicast_group)
}
}
static void unicast_audio_cancel(void)
{
int err;
err = bt_cap_initiator_unicast_audio_cancel();
if (err != 0) {
FAIL("Failed to cancel unicast audio: %d\n", err);
return;
}
}
static void unicast_group_delete_inval(void)
{
int err;
@ -635,7 +649,7 @@ static void test_main_cap_initiator_unicast(void)
for (size_t j = 0U; j < iterations; j++) {
unicast_audio_start_inval(unicast_group);
unicast_audio_start(unicast_group);
unicast_audio_start(unicast_group, true);
unicast_audio_update_inval();
unicast_audio_update();
@ -652,6 +666,45 @@ static void test_main_cap_initiator_unicast(void)
PASS("CAP initiator unicast passed\n");
}
static void test_cap_initiator_unicast_timeout(void)
{
struct bt_bap_unicast_group *unicast_group;
const k_timeout_t timeout = K_SECONDS(1);
const size_t iterations = 2;
init();
scan_and_connect();
WAIT_FOR_FLAG(flag_mtu_exchanged);
discover_cas();
discover_sink();
unicast_group_create(&unicast_group);
for (size_t j = 0U; j < iterations; j++) {
unicast_audio_start(unicast_group, false);
k_sleep(timeout);
if ((bool)atomic_get(&flag_started)) {
FAIL("Unexpected start complete\n");
} else {
unicast_audio_cancel();
}
WAIT_FOR_FLAG(flag_start_timeout);
unicast_audio_stop(unicast_group);
}
unicast_group_delete(unicast_group);
unicast_group = NULL;
PASS("CAP initiator unicast passed\n");
}
static const struct bst_test_instance test_cap_initiator_unicast[] = {
{
.test_id = "cap_initiator_unicast",
@ -659,6 +712,12 @@ static const struct bst_test_instance test_cap_initiator_unicast[] = {
.test_tick_f = test_tick,
.test_main_f = test_main_cap_initiator_unicast,
},
{
.test_id = "cap_initiator_unicast_timeout",
.test_post_init_f = test_init,
.test_tick_f = test_tick,
.test_main_f = test_cap_initiator_unicast_timeout,
},
BSTEST_END_MARKER,
};

View file

@ -0,0 +1,27 @@
#!/usr/bin/env bash
#
# Copyright (c) 2023 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
SIMULATION_ID="cap_unicast_timeout"
VERBOSITY_LEVEL=2
EXECUTE_TIMEOUT=20
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
cd ${BSIM_OUT_PATH}/bin
printf "\n\n======== Running CAP unicast timeout test =========\n\n"
Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=cap_acceptor_unicast_timeout -rs=23
Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=cap_initiator_unicast_timeout -rs=46
# Simulation time should be larger than the WAIT_TIME in common.h
Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \
-D=2 -sim_length=60e6 $@
wait_for_background_jobs