Commit 04da3638 authored by Emil Gydesen's avatar Emil Gydesen Committed by Benjamin Cabé
Browse files

tests: Bluetooth: Tester: MCP BSIM test



Adds BSIM testing of the MCP features of the BT Tester.

Signed-off-by: default avatarEmil Gydesen <emil.gydesen@nordicsemi.no>
parent 1fd4886a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ target_sources(app PRIVATE
  src/audio/csip_peripheral.c
  src/audio/hap_central.c
  src/audio/hap_peripheral.c
  src/audio/mcp_central.c
  src/audio/mcp_peripheral.c
  src/audio/micp_central.c
  src/audio/micp_peripheral.c
  src/audio/tmap_central.c
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2025 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <stddef.h>
#include <stdint.h>

#include <zephyr/bluetooth/addr.h>
#include <zephyr/bluetooth/audio/mcs.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/net_buf.h>
#include <zephyr/sys/util_macro.h>

#include "babblekit/testcase.h"
#include "bstests.h"

#include "btp/btp.h"
#include "bsim_btp.h"

LOG_MODULE_REGISTER(bsim_mcp_central, CONFIG_BSIM_BTTESTER_LOG_LEVEL);

static void test_mcp_central(void)
{
	const uint8_t opcode = BT_MCS_OPC_PAUSE;
	char addr_str[BT_ADDR_LE_STR_LEN];
	bt_addr_le_t remote_addr;
	uint8_t expect_opcode;

	bsim_btp_uart_init();

	bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL);

	bsim_btp_core_register(BTP_SERVICE_ID_GAP);
	bsim_btp_core_register(BTP_SERVICE_ID_MCP);

	bsim_btp_gap_start_discovery(BTP_GAP_DISCOVERY_FLAG_LE);
	bsim_btp_wait_for_gap_device_found(&remote_addr);
	bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str));
	LOG_INF("Found remote device %s", addr_str);

	bsim_btp_gap_stop_discovery();
	bsim_btp_gap_connect(&remote_addr, BTP_GAP_ADDR_TYPE_IDENTITY);
	bsim_btp_wait_for_gap_device_connected(NULL);
	LOG_INF("Device %s connected", addr_str);

	bsim_btp_gap_pair(&remote_addr);
	bsim_btp_wait_for_gap_sec_level_changed(NULL, NULL);

	bsim_btp_mcp_discover(&remote_addr);
	bsim_btp_wait_for_mcp_discovered(NULL);

	bsim_btp_mcp_send_cmd(&remote_addr, opcode, false, 0);
	bsim_btp_wait_for_mcp_cmd_ntf(&expect_opcode);
	TEST_ASSERT(opcode == expect_opcode, "%u != %u", opcode, expect_opcode);

	bsim_btp_gap_disconnect(&remote_addr);
	bsim_btp_wait_for_gap_device_disconnected(NULL);
	LOG_INF("Device %s disconnected", addr_str);

	TEST_PASS("PASSED\n");
}

static const struct bst_test_instance test_sample[] = {
	{
		.test_id = "mcp_central",
		.test_descr = "Smoketest for the MCP central BT Tester behavior",
		.test_main_f = test_mcp_central,
	},
	BSTEST_END_MARKER,
};

struct bst_test_list *test_mcp_central_install(struct bst_test_list *tests)
{
	return bst_add_tests(tests, test_sample);
}
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2025 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <stddef.h>
#include <stdint.h>

#include <zephyr/bluetooth/addr.h>
#include <zephyr/bluetooth/gap.h>
#include <zephyr/bluetooth/hci_types.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util_macro.h>

#include "babblekit/testcase.h"
#include "bstests.h"

#include "btp/btp.h"
#include "bsim_btp.h"

LOG_MODULE_REGISTER(bsim_mcp_peripheral, CONFIG_BSIM_BTTESTER_LOG_LEVEL);

static void test_mcp_peripheral(void)
{
	char addr_str[BT_ADDR_LE_STR_LEN];
	bt_addr_le_t remote_addr;

	bsim_btp_uart_init();

	bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL);

	bsim_btp_core_register(BTP_SERVICE_ID_GAP);
	bsim_btp_core_register(BTP_SERVICE_ID_GMCS);

	bsim_btp_gap_set_discoverable(BTP_GAP_GENERAL_DISCOVERABLE);
	bsim_btp_gap_start_advertising(0U, 0U, NULL, BT_HCI_OWN_ADDR_PUBLIC);
	bsim_btp_wait_for_gap_device_connected(&remote_addr);
	bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str));
	LOG_INF("Device %s connected", addr_str);
	bsim_btp_wait_for_gap_device_disconnected(NULL);
	LOG_INF("Device %s disconnected", addr_str);

	TEST_PASS("PASSED\n");
}

static const struct bst_test_instance test_sample[] = {
	{
		.test_id = "mcp_peripheral",
		.test_descr = "Smoketest for the MCP peripheral BT Tester behavior",
		.test_main_f = test_mcp_peripheral,
	},
	BSTEST_END_MARKER,
};

struct bst_test_list *test_mcp_peripheral_install(struct bst_test_list *tests)
{
	return bst_add_tests(tests, test_sample);
}
+77 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <zephyr/bluetooth/addr.h>
#include <zephyr/bluetooth/att.h>
#include <zephyr/bluetooth/iso.h>
#include <zephyr/bluetooth/audio/mcs.h>
#include <zephyr/net_buf.h>
#include <zephyr/sys/byteorder.h>

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

	net_buf_unref(buf);
}
static inline void bsim_btp_mcp_discover(const bt_addr_le_t *address)
{
	struct btp_mcp_discover_cmd *cmd;
	struct btp_hdr *cmd_hdr;

	NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU);

	cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr));
	cmd_hdr->service = BTP_SERVICE_ID_MCP;
	cmd_hdr->opcode = BTP_MCP_DISCOVER;
	cmd_hdr->index = BTP_INDEX;
	cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd));
	bt_addr_le_copy(&cmd->address, address);

	cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr);

	bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len);
}

static inline void bsim_btp_mcp_send_cmd(const bt_addr_le_t *address, uint8_t opcode,
					 bool use_param, int32_t param)
{
	struct btp_mcp_send_cmd *cmd;
	struct btp_hdr *cmd_hdr;

	NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU);

	cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr));
	cmd_hdr->service = BTP_SERVICE_ID_MCP;
	cmd_hdr->opcode = BTP_MCP_CMD_SEND;
	cmd_hdr->index = BTP_INDEX;
	cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd));
	bt_addr_le_copy(&cmd->address, address);
	cmd->opcode = opcode;
	cmd->use_param = use_param ? 1U : 0U;
	cmd->param = sys_cpu_to_le32(param);

	cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr);

	bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len);
}

static inline void bsim_btp_wait_for_mcp_discovered(bt_addr_le_t *address)
{
	struct btp_mcp_discovered_ev *ev;
	struct net_buf *buf;

	bsim_btp_wait_for_evt(BTP_SERVICE_ID_MCP, BTP_MCP_DISCOVERED_EV, &buf);
	ev = net_buf_pull_mem(buf, sizeof(*ev));

	TEST_ASSERT(ev->status == BT_ATT_ERR_SUCCESS);

	if (address != NULL) {
		bt_addr_le_copy(address, &ev->address);
	}

	net_buf_unref(buf);
}

static inline void bsim_btp_wait_for_mcp_cmd_ntf(uint8_t *requested_opcode)
{
	struct btp_mcp_cmd_ntf_ev *ev;
	struct net_buf *buf;

	bsim_btp_wait_for_evt(BTP_SERVICE_ID_MCP, BTP_MCP_NTF_EV, &buf);
	ev = net_buf_pull_mem(buf, sizeof(*ev));

	TEST_ASSERT(ev->status == BT_ATT_ERR_SUCCESS);
	TEST_ASSERT(ev->result_code == BT_MCS_OPC_NTF_SUCCESS);

	if (requested_opcode != NULL) {
		*requested_opcode = ev->requested_opcode;
	}

	net_buf_unref(buf);
}

static inline void bsim_btp_tmap_discover(const bt_addr_le_t *address)
{
+4 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ extern struct bst_test_list *test_gap_central_install(struct bst_test_list *test
extern struct bst_test_list *test_gap_peripheral_install(struct bst_test_list *tests);
extern struct bst_test_list *test_hap_central_install(struct bst_test_list *tests);
extern struct bst_test_list *test_hap_peripheral_install(struct bst_test_list *tests);
extern struct bst_test_list *test_mcp_central_install(struct bst_test_list *tests);
extern struct bst_test_list *test_mcp_peripheral_install(struct bst_test_list *tests);
extern struct bst_test_list *test_micp_central_install(struct bst_test_list *tests);
extern struct bst_test_list *test_micp_peripheral_install(struct bst_test_list *tests);
extern struct bst_test_list *test_tmap_central_install(struct bst_test_list *tests);
@@ -33,6 +35,8 @@ bst_test_install_t test_installers[] = {
	test_gap_peripheral_install,
	test_hap_central_install,
	test_hap_peripheral_install,
	test_mcp_central_install,
	test_mcp_peripheral_install,
	test_micp_central_install,
	test_micp_peripheral_install,
	test_tmap_central_install,
Loading