Skip to content

Commit 04da363

Browse files
Thalleykartben
authored andcommitted
tests: Bluetooth: Tester: MCP BSIM test
Adds BSIM testing of the MCP features of the BT Tester. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 1fd4886 commit 04da363

File tree

6 files changed

+259
-0
lines changed

6 files changed

+259
-0
lines changed

tests/bsim/bluetooth/tester/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ target_sources(app PRIVATE
3030
src/audio/csip_peripheral.c
3131
src/audio/hap_central.c
3232
src/audio/hap_peripheral.c
33+
src/audio/mcp_central.c
34+
src/audio/mcp_peripheral.c
3335
src/audio/micp_central.c
3436
src/audio/micp_peripheral.c
3537
src/audio/tmap_central.c
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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/mcs.h>
11+
#include <zephyr/kernel.h>
12+
#include <zephyr/logging/log.h>
13+
#include <zephyr/net_buf.h>
14+
#include <zephyr/sys/util_macro.h>
15+
16+
#include "babblekit/testcase.h"
17+
#include "bstests.h"
18+
19+
#include "btp/btp.h"
20+
#include "bsim_btp.h"
21+
22+
LOG_MODULE_REGISTER(bsim_mcp_central, CONFIG_BSIM_BTTESTER_LOG_LEVEL);
23+
24+
static void test_mcp_central(void)
25+
{
26+
const uint8_t opcode = BT_MCS_OPC_PAUSE;
27+
char addr_str[BT_ADDR_LE_STR_LEN];
28+
bt_addr_le_t remote_addr;
29+
uint8_t expect_opcode;
30+
31+
bsim_btp_uart_init();
32+
33+
bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL);
34+
35+
bsim_btp_core_register(BTP_SERVICE_ID_GAP);
36+
bsim_btp_core_register(BTP_SERVICE_ID_MCP);
37+
38+
bsim_btp_gap_start_discovery(BTP_GAP_DISCOVERY_FLAG_LE);
39+
bsim_btp_wait_for_gap_device_found(&remote_addr);
40+
bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str));
41+
LOG_INF("Found remote device %s", addr_str);
42+
43+
bsim_btp_gap_stop_discovery();
44+
bsim_btp_gap_connect(&remote_addr, BTP_GAP_ADDR_TYPE_IDENTITY);
45+
bsim_btp_wait_for_gap_device_connected(NULL);
46+
LOG_INF("Device %s connected", addr_str);
47+
48+
bsim_btp_gap_pair(&remote_addr);
49+
bsim_btp_wait_for_gap_sec_level_changed(NULL, NULL);
50+
51+
bsim_btp_mcp_discover(&remote_addr);
52+
bsim_btp_wait_for_mcp_discovered(NULL);
53+
54+
bsim_btp_mcp_send_cmd(&remote_addr, opcode, false, 0);
55+
bsim_btp_wait_for_mcp_cmd_ntf(&expect_opcode);
56+
TEST_ASSERT(opcode == expect_opcode, "%u != %u", opcode, expect_opcode);
57+
58+
bsim_btp_gap_disconnect(&remote_addr);
59+
bsim_btp_wait_for_gap_device_disconnected(NULL);
60+
LOG_INF("Device %s disconnected", addr_str);
61+
62+
TEST_PASS("PASSED\n");
63+
}
64+
65+
static const struct bst_test_instance test_sample[] = {
66+
{
67+
.test_id = "mcp_central",
68+
.test_descr = "Smoketest for the MCP central BT Tester behavior",
69+
.test_main_f = test_mcp_central,
70+
},
71+
BSTEST_END_MARKER,
72+
};
73+
74+
struct bst_test_list *test_mcp_central_install(struct bst_test_list *tests)
75+
{
76+
return bst_add_tests(tests, test_sample);
77+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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_mcp_peripheral, CONFIG_BSIM_BTTESTER_LOG_LEVEL);
22+
23+
static void test_mcp_peripheral(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_GMCS);
34+
35+
bsim_btp_gap_set_discoverable(BTP_GAP_GENERAL_DISCOVERABLE);
36+
bsim_btp_gap_start_advertising(0U, 0U, NULL, BT_HCI_OWN_ADDR_PUBLIC);
37+
bsim_btp_wait_for_gap_device_connected(&remote_addr);
38+
bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str));
39+
LOG_INF("Device %s connected", addr_str);
40+
bsim_btp_wait_for_gap_device_disconnected(NULL);
41+
LOG_INF("Device %s disconnected", addr_str);
42+
43+
TEST_PASS("PASSED\n");
44+
}
45+
46+
static const struct bst_test_instance test_sample[] = {
47+
{
48+
.test_id = "mcp_peripheral",
49+
.test_descr = "Smoketest for the MCP peripheral BT Tester behavior",
50+
.test_main_f = test_mcp_peripheral,
51+
},
52+
BSTEST_END_MARKER,
53+
};
54+
55+
struct bst_test_list *test_mcp_peripheral_install(struct bst_test_list *tests)
56+
{
57+
return bst_add_tests(tests, test_sample);
58+
}

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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <zephyr/bluetooth/addr.h>
1313
#include <zephyr/bluetooth/att.h>
1414
#include <zephyr/bluetooth/iso.h>
15+
#include <zephyr/bluetooth/audio/mcs.h>
1516
#include <zephyr/net_buf.h>
1617
#include <zephyr/sys/byteorder.h>
1718

@@ -453,6 +454,82 @@ static inline void bsim_btp_wait_for_hauc_discovery_complete(bt_addr_le_t *addre
453454

454455
net_buf_unref(buf);
455456
}
457+
static inline void bsim_btp_mcp_discover(const bt_addr_le_t *address)
458+
{
459+
struct btp_mcp_discover_cmd *cmd;
460+
struct btp_hdr *cmd_hdr;
461+
462+
NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU);
463+
464+
cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr));
465+
cmd_hdr->service = BTP_SERVICE_ID_MCP;
466+
cmd_hdr->opcode = BTP_MCP_DISCOVER;
467+
cmd_hdr->index = BTP_INDEX;
468+
cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd));
469+
bt_addr_le_copy(&cmd->address, address);
470+
471+
cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr);
472+
473+
bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len);
474+
}
475+
476+
static inline void bsim_btp_mcp_send_cmd(const bt_addr_le_t *address, uint8_t opcode,
477+
bool use_param, int32_t param)
478+
{
479+
struct btp_mcp_send_cmd *cmd;
480+
struct btp_hdr *cmd_hdr;
481+
482+
NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU);
483+
484+
cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr));
485+
cmd_hdr->service = BTP_SERVICE_ID_MCP;
486+
cmd_hdr->opcode = BTP_MCP_CMD_SEND;
487+
cmd_hdr->index = BTP_INDEX;
488+
cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd));
489+
bt_addr_le_copy(&cmd->address, address);
490+
cmd->opcode = opcode;
491+
cmd->use_param = use_param ? 1U : 0U;
492+
cmd->param = sys_cpu_to_le32(param);
493+
494+
cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr);
495+
496+
bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len);
497+
}
498+
499+
static inline void bsim_btp_wait_for_mcp_discovered(bt_addr_le_t *address)
500+
{
501+
struct btp_mcp_discovered_ev *ev;
502+
struct net_buf *buf;
503+
504+
bsim_btp_wait_for_evt(BTP_SERVICE_ID_MCP, BTP_MCP_DISCOVERED_EV, &buf);
505+
ev = net_buf_pull_mem(buf, sizeof(*ev));
506+
507+
TEST_ASSERT(ev->status == BT_ATT_ERR_SUCCESS);
508+
509+
if (address != NULL) {
510+
bt_addr_le_copy(address, &ev->address);
511+
}
512+
513+
net_buf_unref(buf);
514+
}
515+
516+
static inline void bsim_btp_wait_for_mcp_cmd_ntf(uint8_t *requested_opcode)
517+
{
518+
struct btp_mcp_cmd_ntf_ev *ev;
519+
struct net_buf *buf;
520+
521+
bsim_btp_wait_for_evt(BTP_SERVICE_ID_MCP, BTP_MCP_NTF_EV, &buf);
522+
ev = net_buf_pull_mem(buf, sizeof(*ev));
523+
524+
TEST_ASSERT(ev->status == BT_ATT_ERR_SUCCESS);
525+
TEST_ASSERT(ev->result_code == BT_MCS_OPC_NTF_SUCCESS);
526+
527+
if (requested_opcode != NULL) {
528+
*requested_opcode = ev->requested_opcode;
529+
}
530+
531+
net_buf_unref(buf);
532+
}
456533

457534
static inline void bsim_btp_tmap_discover(const bt_addr_le_t *address)
458535
{

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ extern struct bst_test_list *test_gap_central_install(struct bst_test_list *test
1515
extern struct bst_test_list *test_gap_peripheral_install(struct bst_test_list *tests);
1616
extern struct bst_test_list *test_hap_central_install(struct bst_test_list *tests);
1717
extern struct bst_test_list *test_hap_peripheral_install(struct bst_test_list *tests);
18+
extern struct bst_test_list *test_mcp_central_install(struct bst_test_list *tests);
19+
extern struct bst_test_list *test_mcp_peripheral_install(struct bst_test_list *tests);
1820
extern struct bst_test_list *test_micp_central_install(struct bst_test_list *tests);
1921
extern struct bst_test_list *test_micp_peripheral_install(struct bst_test_list *tests);
2022
extern struct bst_test_list *test_tmap_central_install(struct bst_test_list *tests);
@@ -33,6 +35,8 @@ bst_test_install_t test_installers[] = {
3335
test_gap_peripheral_install,
3436
test_hap_central_install,
3537
test_hap_peripheral_install,
38+
test_mcp_central_install,
39+
test_mcp_peripheral_install,
3640
test_micp_central_install,
3741
test_micp_peripheral_install,
3842
test_tmap_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 MCP BTP commands with the BT tester
6+
7+
simulation_id="tester_mcp"
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_PER=${UART_DIR}/peripheral
17+
UART_CEN=${UART_DIR}/central
18+
19+
# Central 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_CEN}.tx -uart0_fifob_txfile=${UART_CEN}.rx
23+
24+
# Central 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=mcp_central \
27+
-nosim -uart0_fifob_rxfile=${UART_CEN}.rx -uart0_fifob_txfile=${UART_CEN}.tx
28+
29+
# Peripheral 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_PER}.tx -uart0_fifob_txfile=${UART_PER}.rx
33+
34+
# Peripheral 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=mcp_peripheral \
37+
-nosim -uart0_fifob_rxfile=${UART_PER}.rx -uart0_fifob_txfile=${UART_PER}.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)