Skip to content

Commit 3ffef81

Browse files
committed
tests: Bluetooth: Tester: PBP BSIM test
Adds BSIM testing of the PBP features of the BT Tester. Signed-off-by: Emil Gydesen <[email protected]>
1 parent d5233b2 commit 3ffef81

File tree

7 files changed

+282
-2
lines changed

7 files changed

+282
-2
lines changed

tests/bsim/bluetooth/tester/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ target_sources(app PRIVATE
4242
src/audio/mcp_peripheral.c
4343
src/audio/micp_central.c
4444
src/audio/micp_peripheral.c
45+
<<<<<<< HEAD
4546
src/audio/tmap_central.c
4647
src/audio/tmap_peripheral.c
48+
=======
49+
src/audio/pbp_sink.c
50+
src/audio/pbp_source.c
51+
>>>>>>> 5fce7d4666d (tests: Bluetooth: Tester: PBP BSIM test)
4752
src/audio/vcp_central.c
4853
src/audio/vcp_peripheral.c
4954
src/host/gap_central.c
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <stddef.h>
7+
#include <stdint.h>
8+
9+
#include <zephyr/bluetooth/addr.h>
10+
#include <zephyr/bluetooth/gap.h>
11+
#include <zephyr/bluetooth/hci_types.h>
12+
#include <zephyr/logging/log.h>
13+
#include <zephyr/sys/util_macro.h>
14+
15+
#include "babblekit/testcase.h"
16+
#include "bstests.h"
17+
18+
#include "btp/btp.h"
19+
#include "bsim_btp.h"
20+
21+
LOG_MODULE_REGISTER(bsim_pbp_sink, CONFIG_BSIM_BTTESTER_LOG_LEVEL);
22+
23+
static void test_pbp_sink(void)
24+
{
25+
char addr_str[BT_ADDR_LE_STR_LEN];
26+
bt_addr_le_t remote_addr;
27+
28+
bsim_btp_uart_init();
29+
30+
bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL);
31+
32+
bsim_btp_core_register(BTP_SERVICE_ID_GAP);
33+
bsim_btp_core_register(BTP_SERVICE_ID_PBP);
34+
bsim_btp_core_register(BTP_SERVICE_ID_BAP);
35+
bsim_btp_core_register(BTP_SERVICE_ID_CAS);
36+
bsim_btp_core_register(BTP_SERVICE_ID_PACS);
37+
38+
bsim_btp_pbp_broadcast_scan_start();
39+
bsim_btp_wait_for_pbp_public_broadcast_announcement_found(&remote_addr);
40+
41+
bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str));
42+
LOG_INF("Found remote device %s", addr_str);
43+
44+
TEST_PASS("PASSED\n");
45+
}
46+
47+
static const struct bst_test_instance test_sample[] = {
48+
{
49+
.test_id = "pbp_sink",
50+
.test_descr = "Smoketest for the PBP peripheral BT Tester behavior",
51+
.test_main_f = test_pbp_sink,
52+
},
53+
BSTEST_END_MARKER,
54+
};
55+
56+
struct bst_test_list *test_pbp_sink_install(struct bst_test_list *tests)
57+
{
58+
return bst_add_tests(tests, test_sample);
59+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <stddef.h>
7+
#include <stdint.h>
8+
9+
#include <zephyr/bluetooth/addr.h>
10+
#include <zephyr/bluetooth/audio/audio.h>
11+
#include <zephyr/bluetooth/audio/lc3.h>
12+
#include <zephyr/bluetooth/audio/pbp.h>
13+
#include <zephyr/bluetooth/hci_types.h>
14+
#include <zephyr/bluetooth/iso.h>
15+
#include <zephyr/kernel.h>
16+
#include <zephyr/logging/log.h>
17+
#include <zephyr/net_buf.h>
18+
#include <zephyr/sys/util.h>
19+
#include <zephyr/sys/util_macro.h>
20+
21+
#include "babblekit/testcase.h"
22+
#include "bstests.h"
23+
24+
#include "btp/btp.h"
25+
#include "bsim_btp.h"
26+
27+
LOG_MODULE_REGISTER(bsim_pbp_source, CONFIG_BSIM_BTTESTER_LOG_LEVEL);
28+
29+
static void test_pbp_source(void)
30+
{
31+
const uint8_t metadata[] = BT_AUDIO_CODEC_CFG_LC3_META(BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
32+
const uint8_t cc_data_16_2_1[] = BT_AUDIO_CODEC_CFG_LC3_DATA(
33+
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, BT_AUDIO_CODEC_CFG_DURATION_10,
34+
BT_AUDIO_LOCATION_FRONT_LEFT, 40U, 1U);
35+
const enum bt_pbp_announcement_feature features =
36+
BT_PBP_ANNOUNCEMENT_FEATURE_STANDARD_QUALITY;
37+
const uint8_t coding_format = BT_HCI_CODING_FORMAT_LC3;
38+
const uint8_t framing = BT_ISO_FRAMING_UNFRAMED;
39+
const char *broadcast_name = "broadcast_name";
40+
const uint32_t presentation_delay = 40000U;
41+
const uint32_t broadcast_id = 0x123456U;
42+
const uint32_t sdu_interval = 10000U;
43+
const uint16_t max_latency = 10U;
44+
const uint8_t subgroup_id = 0U;
45+
const uint16_t max_sdu = 40U;
46+
const uint8_t source_id = 0U;
47+
const uint16_t vid = 0x0000U; /* shall be 0x0000 for LC3 */
48+
const uint16_t cid = 0x0000U; /* shall be 0x0000 for LC3 */
49+
const uint8_t flags = 0U;
50+
const uint8_t rtn = 2U;
51+
52+
bsim_btp_uart_init();
53+
54+
bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL);
55+
56+
bsim_btp_core_register(BTP_SERVICE_ID_GAP);
57+
bsim_btp_core_register(BTP_SERVICE_ID_BAP); /* required to start the TX thread */
58+
bsim_btp_core_register(BTP_SERVICE_ID_CAP);
59+
bsim_btp_core_register(BTP_SERVICE_ID_PBP);
60+
61+
bsim_btp_cap_broadcast_source_setup_stream(source_id, subgroup_id, coding_format, vid, cid,
62+
0, NULL, 0, NULL);
63+
bsim_btp_cap_broadcast_source_setup_subgroup(
64+
source_id, subgroup_id, coding_format, vid, cid, ARRAY_SIZE(cc_data_16_2_1),
65+
cc_data_16_2_1, ARRAY_SIZE(metadata), metadata);
66+
bsim_btp_cap_broadcast_source_setup(source_id, broadcast_id, sdu_interval, framing, max_sdu,
67+
rtn, max_latency, presentation_delay, flags);
68+
69+
bsim_btp_pbp_set_public_broadcast_announcement((uint8_t)features);
70+
bsim_btp_pbp_set_broadcast_name(broadcast_name);
71+
72+
bsim_btp_cap_broadcast_adv_start(source_id);
73+
bsim_btp_cap_broadcast_source_start(source_id);
74+
75+
TEST_PASS("PASSED\n");
76+
}
77+
78+
static const struct bst_test_instance test_sample[] = {
79+
{
80+
.test_id = "pbp_source",
81+
.test_descr = "Smoketest for the PBP central BT Tester behavior",
82+
.test_main_f = test_pbp_source,
83+
},
84+
BSTEST_END_MARKER,
85+
};
86+
87+
struct bst_test_list *test_pbp_source_install(struct bst_test_list *tests)
88+
{
89+
return bst_add_tests(tests, test_sample);
90+
}

tests/bsim/bluetooth/tester/src/bsim_btp.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,8 +1729,17 @@ static bool is_valid_pbp_packet_len(const struct btp_hdr *hdr, struct net_buf_si
17291729

17301730
/* events */
17311731
case BTP_PBP_EV_PUBLIC_BROADCAST_ANNOUNCEMENT_FOUND:
1732-
return buf_simple->len ==
1733-
sizeof(struct btp_pbp_ev_public_broadcast_announcement_found_ev);
1732+
if (hdr->len >= sizeof(struct btp_pbp_ev_public_broadcast_announcement_found_ev)) {
1733+
const struct btp_pbp_ev_public_broadcast_announcement_found_ev *ev =
1734+
net_buf_simple_pull_mem(
1735+
buf_simple,
1736+
sizeof(struct
1737+
btp_pbp_ev_public_broadcast_announcement_found_ev));
1738+
1739+
return ev->broadcast_name_len == buf_simple->len;
1740+
} else {
1741+
return false;
1742+
}
17341743
default:
17351744
LOG_ERR("Unhandled opcode 0x%02X", hdr->opcode);
17361745
return false;

tests/bsim/bluetooth/tester/src/bsim_btp.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,78 @@ static inline void bsim_btp_wait_for_mcp_cmd_ntf(uint8_t *requested_opcode)
13381338
net_buf_unref(buf);
13391339
}
13401340

1341+
static inline void bsim_btp_pbp_set_public_broadcast_announcement(uint8_t features)
1342+
{
1343+
struct btp_pbp_set_public_broadcast_announcement_cmd *cmd;
1344+
struct btp_hdr *cmd_hdr;
1345+
1346+
NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU);
1347+
1348+
cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr));
1349+
cmd_hdr->service = BTP_SERVICE_ID_PBP;
1350+
cmd_hdr->opcode = BTP_PBP_SET_PUBLIC_BROADCAST_ANNOUNCEMENT;
1351+
cmd_hdr->index = BTP_INDEX;
1352+
cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd));
1353+
cmd->features = features;
1354+
1355+
cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr);
1356+
1357+
bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len);
1358+
}
1359+
1360+
static inline void bsim_btp_pbp_set_broadcast_name(const char *broadcast_name)
1361+
{
1362+
struct btp_pbp_set_broadcast_name_cmd *cmd;
1363+
struct btp_hdr *cmd_hdr;
1364+
1365+
NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU);
1366+
1367+
cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr));
1368+
cmd_hdr->service = BTP_SERVICE_ID_PBP;
1369+
cmd_hdr->opcode = BTP_PBP_SET_BROADCAST_NAME;
1370+
cmd_hdr->index = BTP_INDEX;
1371+
cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd));
1372+
cmd->name_len = strlen(broadcast_name) + 1 /* NULL terminator */;
1373+
net_buf_simple_add_mem(&cmd_buffer, broadcast_name, cmd->name_len);
1374+
1375+
cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr);
1376+
1377+
bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len);
1378+
}
1379+
1380+
static inline void bsim_btp_pbp_broadcast_scan_start(void)
1381+
{
1382+
struct btp_hdr *cmd_hdr;
1383+
1384+
NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU);
1385+
1386+
cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr));
1387+
cmd_hdr->service = BTP_SERVICE_ID_PBP;
1388+
cmd_hdr->opcode = BTP_PBP_BROADCAST_SCAN_START;
1389+
cmd_hdr->index = BTP_INDEX;
1390+
1391+
/* The command for this is empty */
1392+
cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr);
1393+
1394+
bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len);
1395+
}
1396+
1397+
static inline void bsim_btp_wait_for_pbp_public_broadcast_announcement_found(bt_addr_le_t *address)
1398+
{
1399+
struct btp_pbp_ev_public_broadcast_announcement_found_ev *ev;
1400+
struct net_buf *buf;
1401+
1402+
bsim_btp_wait_for_evt(BTP_SERVICE_ID_PBP, BTP_PBP_EV_PUBLIC_BROADCAST_ANNOUNCEMENT_FOUND,
1403+
&buf);
1404+
ev = net_buf_pull_mem(buf, sizeof(*ev));
1405+
1406+
if (address != NULL) {
1407+
bt_addr_le_copy(address, &ev->address);
1408+
}
1409+
1410+
net_buf_unref(buf);
1411+
}
1412+
13411413
static inline void bsim_btp_tmap_discover(const bt_addr_le_t *address)
13421414
{
13431415
struct btp_tmap_discover_cmd *cmd;

tests/bsim/bluetooth/tester/src/test_main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ extern struct bst_test_list *test_mcp_central_install(struct bst_test_list *test
2727
extern struct bst_test_list *test_mcp_peripheral_install(struct bst_test_list *tests);
2828
extern struct bst_test_list *test_micp_central_install(struct bst_test_list *tests);
2929
extern struct bst_test_list *test_micp_peripheral_install(struct bst_test_list *tests);
30+
extern struct bst_test_list *test_pbp_sink_install(struct bst_test_list *tests);
31+
extern struct bst_test_list *test_pbp_source_install(struct bst_test_list *tests);
3032
extern struct bst_test_list *test_tmap_central_install(struct bst_test_list *tests);
3133
extern struct bst_test_list *test_tmap_peripheral_install(struct bst_test_list *tests);
3234
extern struct bst_test_list *test_vcp_central_install(struct bst_test_list *tests);
@@ -55,6 +57,8 @@ bst_test_install_t test_installers[] = {
5557
test_mcp_peripheral_install,
5658
test_micp_central_install,
5759
test_micp_peripheral_install,
60+
test_pbp_sink_install,
61+
test_pbp_source_install,
5862
test_tmap_central_install,
5963
test_tmap_peripheral_install,
6064
test_vcp_central_install,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2025 Nordic Semiconductor ASA
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# Smoketest for PBP BTP commands with the BT tester
6+
7+
simulation_id="tester_pbp"
8+
verbosity_level=2
9+
EXECUTE_TIMEOUT=100
10+
11+
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
12+
13+
cd ${BSIM_OUT_PATH}/bin
14+
15+
UART_DIR=/tmp/bs_${USER}/${simulation_id}/
16+
UART_SNK=${UART_DIR}/sink
17+
UART_BCST=${UART_DIR}/broadcaster
18+
19+
# Broadcaster BT Tester
20+
Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_le_audio_prj_conf \
21+
-v=${verbosity_level} -s=${simulation_id} -rs=10 -d=0 -RealEncryption=1 \
22+
-uart0_fifob_rxfile=${UART_BCST}.tx -uart0_fifob_txfile=${UART_BCST}.rx
23+
24+
# Broadcaste Upper Tester
25+
Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \
26+
-v=${verbosity_level} -s=${simulation_id} -rs=21 -d=10 -RealEncryption=1 -testid=pbp_source \
27+
-nosim -uart0_fifob_rxfile=${UART_BCST}.rx -uart0_fifob_txfile=${UART_BCST}.tx
28+
29+
# Sink BT Tester
30+
Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_le_audio_prj_conf \
31+
-v=${verbosity_level} -s=${simulation_id} -rs=32 -d=1 -RealEncryption=1 \
32+
-uart0_fifob_rxfile=${UART_SNK}.tx -uart0_fifob_txfile=${UART_SNK}.rx
33+
34+
# Sink Upper Tester
35+
Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \
36+
-v=${verbosity_level} -s=${simulation_id} -rs=43 -d=11 -RealEncryption=1 -testid=pbp_sink \
37+
-nosim -uart0_fifob_rxfile=${UART_SNK}.rx -uart0_fifob_txfile=${UART_SNK}.tx
38+
39+
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=2 -sim_length=20e6 $@
40+
41+
wait_for_background_jobs # Wait for all programs in background and return != 0 if any fails

0 commit comments

Comments
 (0)