tests: Bluetooth: BAP: Add broadcast sink with assistant test
Add a test for the broadcast sink that uses the BAP Scan Delegator functionality with a Broadcast Assistant device adding the broadcast source. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
f58bea6b7b
commit
0e67c990cd
2 changed files with 195 additions and 9 deletions
|
|
@ -17,12 +17,14 @@
|
|||
extern enum bst_result_t bst_result;
|
||||
|
||||
CREATE_FLAG(broadcaster_found);
|
||||
CREATE_FLAG(base_received);
|
||||
CREATE_FLAG(flag_base_received);
|
||||
CREATE_FLAG(flag_base_metadata_updated);
|
||||
CREATE_FLAG(pa_synced);
|
||||
CREATE_FLAG(flag_syncable);
|
||||
CREATE_FLAG(pa_sync_lost);
|
||||
CREATE_FLAG(flag_received);
|
||||
CREATE_FLAG(flag_pa_request);
|
||||
CREATE_FLAG(flag_bis_sync_requested);
|
||||
|
||||
static struct bt_bap_broadcast_sink *g_sink;
|
||||
static struct bt_le_scan_recv_info broadcaster_info;
|
||||
|
|
@ -31,6 +33,9 @@ static struct bt_le_per_adv_sync *pa_sync;
|
|||
static uint32_t broadcaster_broadcast_id;
|
||||
static struct bap_test_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
|
||||
static struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_sink_streams)];
|
||||
static uint32_t requested_bis_sync;
|
||||
static struct bt_le_ext_adv *ext_adv;
|
||||
static const struct bt_bap_scan_delegator_recv_state *req_recv_state;
|
||||
|
||||
static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3(
|
||||
BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_ANY,
|
||||
|
|
@ -53,7 +58,7 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap
|
|||
{
|
||||
uint32_t base_bis_index_bitfield = 0U;
|
||||
|
||||
if (TEST_FLAG(base_received)) {
|
||||
if (TEST_FLAG(flag_base_received)) {
|
||||
|
||||
if (base->subgroup_count > 0 &&
|
||||
memcmp(metadata, base->subgroups[0].codec_cfg.meta,
|
||||
|
|
@ -82,7 +87,7 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap
|
|||
|
||||
bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;
|
||||
|
||||
SET_FLAG(base_received);
|
||||
SET_FLAG(flag_base_received);
|
||||
}
|
||||
|
||||
static void syncable_cb(struct bt_bap_broadcast_sink *sink, bool encrypted)
|
||||
|
|
@ -185,6 +190,61 @@ static struct bt_pacs_cap cap = {
|
|||
.codec_cap = &codec_cap,
|
||||
};
|
||||
|
||||
static int pa_sync_req_cb(struct bt_conn *conn,
|
||||
const struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
bool past_avail, uint16_t pa_interval)
|
||||
{
|
||||
if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED ||
|
||||
recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
|
||||
/* Already syncing */
|
||||
/* TODO: Terminate existing sync and then sync to new?*/
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
req_recv_state = recv_state;
|
||||
|
||||
SET_FLAG(flag_pa_request);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pa_sync_term_req_cb(struct bt_conn *conn,
|
||||
const struct bt_bap_scan_delegator_recv_state *recv_state)
|
||||
{
|
||||
if (pa_sync == NULL || recv_state->pa_sync_state == BT_BAP_PA_STATE_NOT_SYNCED) {
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
req_recv_state = recv_state;
|
||||
|
||||
UNSET_FLAG(flag_pa_request);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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[BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS])
|
||||
{
|
||||
printk("BIS sync request received for %p: 0x%08x\n", recv_state, bis_sync_req[0]);
|
||||
/* We only care about a single subgroup in this test */
|
||||
requested_bis_sync = bis_sync_req[0];
|
||||
broadcaster_broadcast_id = recv_state->broadcast_id;
|
||||
if (bis_sync_req[0] != 0) {
|
||||
SET_FLAG(flag_bis_sync_requested);
|
||||
} else {
|
||||
UNSET_FLAG(flag_bis_sync_requested);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bt_bap_scan_delegator_cb scan_delegator_cbs = {
|
||||
.pa_sync_req = pa_sync_req_cb,
|
||||
.pa_sync_term_req = pa_sync_term_req_cb,
|
||||
.bis_sync_req = bis_sync_req_cb,
|
||||
};
|
||||
|
||||
static void started_cb(struct bt_bap_stream *stream)
|
||||
{
|
||||
printk("Stream %p started\n", stream);
|
||||
|
|
@ -274,11 +334,12 @@ static int init(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
bt_bap_scan_delegator_register_cb(&scan_delegator_cbs);
|
||||
bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
|
||||
bt_le_scan_cb_register(&bap_scan_cb);
|
||||
|
||||
UNSET_FLAG(broadcaster_found);
|
||||
UNSET_FLAG(base_received);
|
||||
UNSET_FLAG(flag_base_received);
|
||||
UNSET_FLAG(pa_synced);
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
|
||||
|
|
@ -323,6 +384,18 @@ static int pa_sync_create(void)
|
|||
|
||||
return bt_le_per_adv_sync_create(&create_params, &pa_sync);
|
||||
}
|
||||
static void test_pa_sync_delete(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = bt_le_per_adv_sync_delete(pa_sync);
|
||||
if (err != 0) {
|
||||
FAIL("Unable to stop sink: %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
pa_sync = NULL;
|
||||
}
|
||||
|
||||
static void test_scan_and_pa_sync(void)
|
||||
{
|
||||
|
|
@ -507,6 +580,7 @@ static void test_broadcast_delete(void)
|
|||
}
|
||||
|
||||
/* No "sync lost" event is generated when we initialized the disconnect */
|
||||
g_sink = NULL;
|
||||
}
|
||||
|
||||
static void test_broadcast_delete_inval(void)
|
||||
|
|
@ -520,6 +594,39 @@ static void test_broadcast_delete_inval(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_start_adv(void)
|
||||
{
|
||||
const struct bt_data ad[] = {
|
||||
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
|
||||
BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL),
|
||||
BT_UUID_16_ENCODE(BT_UUID_PACS_VAL)),
|
||||
BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL)),
|
||||
};
|
||||
int err;
|
||||
|
||||
/* Create a non-connectable non-scannable advertising set */
|
||||
err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN_NAME, NULL, &ext_adv);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to create advertising set (err %d)\n", err);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
err = bt_le_ext_adv_set_data(ext_adv, ad, ARRAY_SIZE(ad), NULL, 0);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to set advertising data (err %d)\n", err);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to start advertising set (err %d)\n", err);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_common(void)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -536,7 +643,7 @@ static void test_common(void)
|
|||
test_broadcast_sink_create();
|
||||
|
||||
printk("Broadcast source PA synced, waiting for BASE\n");
|
||||
WAIT_FOR_FLAG(base_received);
|
||||
WAIT_FOR_FLAG(flag_base_received);
|
||||
printk("BASE received\n");
|
||||
|
||||
printk("Waiting for BIG syncable\n");
|
||||
|
|
@ -585,25 +692,75 @@ static void test_sink_disconnect(void)
|
|||
|
||||
test_broadcast_delete_inval();
|
||||
test_broadcast_delete();
|
||||
g_sink = NULL;
|
||||
|
||||
PASS("Broadcast sink disconnect passed\n");
|
||||
}
|
||||
|
||||
static void broadcast_sink_with_assistant(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = init();
|
||||
if (err) {
|
||||
FAIL("Init failed (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
test_start_adv();
|
||||
WAIT_FOR_FLAG(flag_connected);
|
||||
|
||||
printk("Waiting for PA sync request\n");
|
||||
WAIT_FOR_FLAG(flag_pa_request);
|
||||
|
||||
test_scan_and_pa_sync();
|
||||
test_broadcast_sink_create();
|
||||
|
||||
printk("Broadcast source PA synced, waiting for BASE\n");
|
||||
WAIT_FOR_FLAG(flag_base_received);
|
||||
printk("BASE received\n");
|
||||
|
||||
printk("Waiting for BIG syncable\n");
|
||||
WAIT_FOR_FLAG(flag_syncable);
|
||||
|
||||
printk("Waiting for BIG sync request\n");
|
||||
WAIT_FOR_FLAG(flag_bis_sync_requested);
|
||||
test_broadcast_sync();
|
||||
|
||||
printk("Waiting for data\n");
|
||||
WAIT_FOR_FLAG(flag_received);
|
||||
|
||||
printk("Waiting for BIG sync terminate request\n");
|
||||
WAIT_FOR_UNSET_FLAG(flag_bis_sync_requested);
|
||||
test_broadcast_stop();
|
||||
|
||||
printk("Waiting for PA sync terminate request\n");
|
||||
WAIT_FOR_UNSET_FLAG(flag_pa_request);
|
||||
test_pa_sync_delete();
|
||||
test_broadcast_delete();
|
||||
|
||||
PASS("Broadcast sink with assistant passed\n");
|
||||
}
|
||||
|
||||
static const struct bst_test_instance test_broadcast_sink[] = {
|
||||
{
|
||||
.test_id = "broadcast_sink",
|
||||
.test_post_init_f = test_init,
|
||||
.test_tick_f = test_tick,
|
||||
.test_main_f = test_main
|
||||
.test_main_f = test_main,
|
||||
},
|
||||
{
|
||||
.test_id = "broadcast_sink_disconnect",
|
||||
.test_post_init_f = test_init,
|
||||
.test_tick_f = test_tick,
|
||||
.test_main_f = test_sink_disconnect
|
||||
.test_main_f = test_sink_disconnect,
|
||||
},
|
||||
BSTEST_END_MARKER
|
||||
{
|
||||
.test_id = "broadcast_sink_with_assistant",
|
||||
.test_post_init_f = test_init,
|
||||
.test_tick_f = test_tick,
|
||||
.test_main_f = broadcast_sink_with_assistant,
|
||||
},
|
||||
BSTEST_END_MARKER,
|
||||
};
|
||||
|
||||
struct bst_test_list *test_broadcast_sink_install(struct bst_test_list *tests)
|
||||
|
|
|
|||
29
tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh
Executable file
29
tests/bsim/bluetooth/audio/test_scripts/bap_broadcast_audio_assistant.sh
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
SIMULATION_ID="bap_broadcast_audio_assistant"
|
||||
VERBOSITY_LEVEL=2
|
||||
EXECUTE_TIMEOUT=20
|
||||
|
||||
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
|
||||
|
||||
cd ${BSIM_OUT_PATH}/bin
|
||||
|
||||
printf "\n\n======== Running BAP Broadcast Audio Assistant =========\n\n"
|
||||
|
||||
Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=broadcast_sink_with_assistant -rs=24
|
||||
|
||||
Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=bap_broadcast_assistant_client_sync -rs=46
|
||||
|
||||
Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_prj_conf \
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=broadcast_source -rs=69
|
||||
|
||||
# Simulation time should be larger than the WAIT_TIME in common.h
|
||||
Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 -sim_length=60e6 $@
|
||||
|
||||
wait_for_background_jobs
|
||||
Loading…
Reference in a new issue