Bluetooth: tests: Convert to new HCI driver API

Convert all Bluetooth tests that define dummy HCI driver instances to use
the new HCI driver API. This requires both a custom DTS binding as well
as an app-specific overlay file.

Signed-off-by: Johan Hedberg <johan.hedberg@gmail.com>
This commit is contained in:
Johan Hedberg 2024-05-10 10:53:18 +03:00 committed by Anas Nashif
parent 66b53866a7
commit 1824dcda7c
43 changed files with 271 additions and 76 deletions

View file

@ -3,4 +3,4 @@ CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_H4=n

View file

@ -0,0 +1,5 @@
/ {
chosen {
/delete-property/ zephyr,bt-hci;
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.addr:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- native_posix
- native_posix/native/64

View file

@ -0,0 +1,11 @@
description: Bluetooth HCI for test purposes
compatible: "zephyr,bt-hci-test"
include: bt-hci.yaml
properties:
bt-hci-name:
default: "test"
bt-hci-bus:
default: "BT_HCI_BUS_VIRTUAL"

View file

@ -1,6 +1,6 @@
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_H4=n
CONFIG_LOG=y
CONFIG_UART_INTERRUPT_DRIVEN=n
CONFIG_ZTEST=y

View file

@ -13,11 +13,16 @@
#include <zephyr/ztest.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>
#include <zephyr/drivers/bluetooth.h>
#define DT_DRV_COMPAT zephyr_bt_hci_test
struct driver_data {
};
#define EXPECTED_ERROR -ENOSYS
static int driver_open(void)
static int driver_open(const struct device *dev, bt_hci_recv_t recv)
{
TC_PRINT("driver: %s\n", __func__);
@ -25,29 +30,28 @@ static int driver_open(void)
return EXPECTED_ERROR;
}
static int driver_send(struct net_buf *buf)
static int driver_send(const struct device *dev, struct net_buf *buf)
{
return 0;
}
static const struct bt_hci_driver drv = {
.name = "test",
.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
.open = driver_open,
.send = driver_send,
static const struct bt_hci_driver_api driver_api = {
.open = driver_open,
.send = driver_send,
};
static void driver_init(void)
{
bt_hci_driver_register(&drv);
}
#define TEST_DEVICE_INIT(inst) \
static struct driver_data driver_data_##inst = { \
}; \
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &driver_data_##inst, NULL, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &driver_api)
DT_INST_FOREACH_STATUS_OKAY(TEST_DEVICE_INIT)
ZTEST_SUITE(test_bluetooth, NULL, NULL, NULL, NULL, NULL);
ZTEST(test_bluetooth, test_bluetooth_entry)
{
driver_init();
zassert_true((bt_enable(NULL) == EXPECTED_ERROR),
"bt_enable failed");
}

View file

@ -0,0 +1,10 @@
/ {
chosen {
zephyr,bt-hci = &bt_hci_test;
};
bt_hci_test: bt_hci_test {
compatible = "zephyr,bt-hci-test";
status = "okay";
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.general:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- qemu_x86
- qemu_cortex_m3

View file

@ -3,4 +3,4 @@ CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_H4=n

View file

@ -0,0 +1,5 @@
/ {
chosen {
/delete-property/ zephyr,bt-hci;
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.bt_crypto:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- native_posix
- native_posix/native/64

View file

@ -3,6 +3,6 @@ CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_H4=n
CONFIG_LOG=y

View file

@ -0,0 +1,5 @@
/ {
chosen {
/delete-property/ zephyr,bt-hci;
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.bt_crypto_ccm:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- native_posix
- native_posix/native/64

View file

@ -3,7 +3,7 @@ CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_H4=n
CONFIG_LOG=y
CONFIG_BT_PERIPHERAL=y

View file

@ -0,0 +1,5 @@
/ {
chosen {
/delete-property/ zephyr,bt-hci;
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.gatt:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- native_posix
- native_posix/native/64

View file

@ -0,0 +1,13 @@
description: Bluetooth HCI for test purposes
compatible: "zephyr,bt-hci-test"
include: bt-hci.yaml
properties:
bt-hci-name:
default: "test"
bt-hci-bus:
default: "BT_HCI_BUS_VIRTUAL"
bt-hci-quirks:
default: ["BT_HCI_QUIRK_NO_RESET"]

View file

@ -3,7 +3,7 @@ CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_H4=n
CONFIG_BT_HCI_VS_EVT_USER=y

View file

@ -15,9 +15,15 @@
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/buf.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>
#include <zephyr/drivers/bluetooth.h>
#include <zephyr/sys/byteorder.h>
#define DT_DRV_COMPAT zephyr_bt_hci_test
struct driver_data {
bt_hci_recv_t recv;
};
/* HCI Proprietary vendor event */
const uint8_t hci_prop_evt_prefix[2] = { 0xAB, 0xBA };
@ -84,10 +90,12 @@ static int cmd_handle_helper(uint16_t opcode, struct net_buf *cmd,
}
/* Lookup the command opcode and invoke handler. */
static int cmd_handle(struct net_buf *cmd,
static int cmd_handle(const struct device *dev,
struct net_buf *cmd,
const struct cmd_handler *handlers,
size_t num_handlers)
{
struct driver_data *drv = dev->data;
struct net_buf *evt = NULL;
struct bt_hci_evt_cc_status *ccst;
struct bt_hci_cmd_hdr *chdr;
@ -105,7 +113,7 @@ static int cmd_handle(struct net_buf *cmd,
}
if (evt) {
bt_recv(evt);
drv->recv(dev, evt);
}
return err;
@ -207,15 +215,19 @@ static const struct cmd_handler cmds[] = {
};
/* HCI driver open. */
static int driver_open(void)
static int driver_open(const struct device *dev, bt_hci_recv_t recv)
{
struct driver_data *drv = dev->data;
drv->recv = recv;
return 0;
}
/* HCI driver send. */
static int driver_send(struct net_buf *buf)
static int driver_send(const struct device *dev, struct net_buf *buf)
{
zassert_true(cmd_handle(buf, cmds, ARRAY_SIZE(cmds)) == 0,
zassert_true(cmd_handle(dev, buf, cmds, ARRAY_SIZE(cmds)) == 0,
"Unknown HCI command");
net_buf_unref(buf);
@ -223,15 +235,19 @@ static int driver_send(struct net_buf *buf)
return 0;
}
/* HCI driver structure. */
static const struct bt_hci_driver drv = {
.name = "test",
.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
.open = driver_open,
.send = driver_send,
.quirks = BT_QUIRK_NO_RESET,
static const struct bt_hci_driver_api driver_api = {
.open = driver_open,
.send = driver_send,
};
#define TEST_DEVICE_INIT(inst) \
static struct driver_data driver_data_##inst = { \
}; \
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &driver_data_##inst, NULL, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &driver_api)
DT_INST_FOREACH_STATUS_OKAY(TEST_DEVICE_INIT)
struct bt_recv_job_data {
struct k_work work; /* Work item */
struct k_sem *sync; /* Semaphore to synchronize with */
@ -243,12 +259,14 @@ struct bt_recv_job_data {
/* Work item handler for bt_recv() jobs. */
static void bt_recv_job_cb(struct k_work *item)
{
const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0));
struct driver_data *drv = dev->data;
struct bt_recv_job_data *data =
CONTAINER_OF(item, struct bt_recv_job_data, work);
struct k_sem *sync = job(data->buf)->sync;
/* Send net buffer to host */
bt_recv(data->buf);
drv->recv(dev, data->buf);
data->buf = NULL;
/* Wake up bt_recv_job_submit */
@ -350,9 +368,6 @@ ZTEST_SUITE(test_hci_prop_evt, NULL, NULL, NULL, NULL, NULL);
/* Test. */
ZTEST(test_hci_prop_evt, test_hci_prop_evt_entry)
{
/* Register the test HCI driver */
bt_hci_driver_register(&drv);
/* Go! Wait until Bluetooth initialization is done */
zassert_true((bt_enable(NULL) == 0),
"bt_enable failed");

View file

@ -0,0 +1,10 @@
/ {
chosen {
zephyr,bt-hci = &bt_hci_test;
};
bt_hci_test: bt_hci_test {
compatible = "zephyr,bt-hci-test";
status = "okay";
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.hci_prop_evt:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- qemu_x86
- qemu_cortex_m3

View file

@ -1,3 +0,0 @@
# Print logs and test results on stdout as this not the
# default when SERIAL=y.
CONFIG_LOG_BACKEND_NATIVE_POSIX=y

View file

@ -1,3 +0,0 @@
# Print logs and test results on stdout as this not the
# default when SERIAL=y.
CONFIG_LOG_BACKEND_NATIVE_POSIX=y

View file

@ -0,0 +1,11 @@
description: Bluetooth HCI for test purposes
compatible: "zephyr,bt-hci-test"
include: bt-hci.yaml
properties:
bt-hci-name:
default: "Mock Controller"
bt-hci-bus:
default: "BT_HCI_BUS_VIRTUAL"

View file

@ -1,5 +1,3 @@
CONFIG_BT_NO_DRIVER=y
CONFIG_RING_BUFFER=y
CONFIG_ASSERT=y

View file

@ -14,7 +14,7 @@
#include <zephyr/ztest_assert.h>
#include <zephyr/ztest_test.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>
#include <zephyr/drivers/bluetooth.h>
#include <zephyr/drivers/uart/serial_test.h>
LOG_MODULE_REGISTER(test, LOG_LEVEL_DBG);
@ -27,22 +27,35 @@ static const struct device *const zephyr_bt_c2h_uart = DEVICE_DT_GET(DT_CHOSEN(z
/* The DUT is Sandwiched between the mock serial interface and a mock
* controller. {{{
*/
#define DT_DRV_COMPAT zephyr_bt_hci_test
struct drv_data {
bt_hci_recv_t recv;
};
static void serial_vnd_data_callback(const struct device *dev, void *user_data);
static int drv_send(struct net_buf *buf);
static int drv_open(void);
static const struct bt_hci_driver drv = {
.name = "Mock Controller",
.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
static int drv_send(const struct device *dev, struct net_buf *buf);
static int drv_open(const struct device *dev, bt_hci_recv_t recv);
static const struct bt_hci_driver_api drv_api = {
.open = drv_open,
.send = drv_send,
};
static int sys_init_hci_driver_register(void)
static int drv_init(const struct device *dev)
{
serial_vnd_set_callback(zephyr_bt_c2h_uart, serial_vnd_data_callback, NULL);
bt_hci_driver_register(&drv);
return 0;
}
SYS_INIT(sys_init_hci_driver_register, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
#define TEST_DEVICE_INIT(inst) \
static struct drv_data drv_data_##inst = { \
}; \
DEVICE_DT_INST_DEFINE(inst, drv_init, NULL, &drv_data_##inst, NULL, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv_api)
DT_INST_FOREACH_STATUS_OKAY(TEST_DEVICE_INIT)
/* }}} */
/* Start the DUT "main thread". The settings for this thread are selected as
@ -68,9 +81,14 @@ SYS_INIT(sys_init_spawn_hci_uart, POST_KERNEL, 64);
/* Mock controller callbacks. {{{ */
static int drv_open(void)
static int drv_open(const struct device *dev, bt_hci_recv_t recv)
{
struct drv_data *drv = dev->data;
LOG_DBG("drv_open");
drv->recv = recv;
return 0;
}
@ -82,7 +100,7 @@ static int drv_open(void)
* should use #bt_recv to send c2h packets to the DUT.
*/
K_FIFO_DEFINE(drv_send_fifo); /* elem T: net_buf */
static int drv_send(struct net_buf *buf)
static int drv_send(const struct device *dev, struct net_buf *buf)
{
LOG_DBG("buf %p type %d len %u", buf, bt_buf_get_type(buf), buf->len);
LOG_HEXDUMP_DBG(buf->data, buf->len, "buf");
@ -206,13 +224,15 @@ ZTEST(hci_uart, test_h2c_cmd_flow_control)
/* The controller sends a HCI Command Complete response. */
{
const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0));
struct drv_data *drv = dev->data;
int err;
struct net_buf *buf = bt_buf_get_rx(BT_BUF_EVT, K_NO_WAIT);
zassert_not_null(buf);
net_buf_add_mem(buf, hci_msg_rx_evt_cmd_complete,
sizeof(hci_msg_rx_evt_cmd_complete));
err = bt_recv(buf);
err = drv->recv(dev, buf);
zassert_equal(err, 0, "bt_recv failed");
}
}

View file

@ -0,0 +1,10 @@
/ {
chosen {
zephyr,bt-hci = &bt_hci_test;
};
bt_hci_test: bt_hci_test {
compatible = "zephyr,bt-hci-test";
status = "okay";
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.hci_uart_async:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
tags:
- bluetooth
- uart

View file

@ -0,0 +1,13 @@
description: Bluetooth HCI for test purposes
compatible: "zephyr,bt-hci-test"
include: bt-hci.yaml
properties:
bt-hci-name:
default: "test"
bt-hci-bus:
default: "BT_HCI_BUS_VIRTUAL"
bt-hci-quirks:
default: ["BT_HCI_QUIRK_NO_RESET"]

View file

@ -3,10 +3,10 @@ CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_H4=n
CONFIG_BT_HCI=n
CONFIG_BT_HCI_RAW=n
CONFIG_BT_OBSERVER=y
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_EXT_ADV=y
CONFIG_LOG=y

View file

@ -16,9 +16,15 @@
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/buf.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>
#include <zephyr/drivers/bluetooth.h>
#include <zephyr/sys/byteorder.h>
#define DT_DRV_COMPAT zephyr_bt_hci_test
struct driver_data {
bt_hci_recv_t recv;
};
#define LOG_LEVEL CONFIG_BT_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(host_test_app);
@ -111,8 +117,10 @@ static int cmd_handle_helper(uint16_t opcode, struct net_buf *cmd, struct net_bu
}
/* Lookup the command opcode and invoke handler. */
static int cmd_handle(struct net_buf *cmd, const struct cmd_handler *handlers, size_t num_handlers)
static int cmd_handle(const struct device *dev, struct net_buf *cmd,
const struct cmd_handler *handlers, size_t num_handlers)
{
struct driver_data *drv = dev->data;
struct net_buf *evt = NULL;
struct bt_hci_evt_cc_status *ccst;
struct bt_hci_cmd_hdr *chdr;
@ -130,7 +138,7 @@ static int cmd_handle(struct net_buf *cmd, const struct cmd_handler *handlers, s
}
if (evt) {
bt_recv(evt);
drv->recv(dev, evt);
}
return err;
@ -215,30 +223,39 @@ static const struct cmd_handler cmds[] = {
};
/* HCI driver open. */
static int driver_open(void)
static int driver_open(const struct device *dev, bt_hci_recv_t recv)
{
struct driver_data *drv = dev->data;
drv->recv = recv;
return 0;
}
/* HCI driver send. */
static int driver_send(struct net_buf *buf)
static int driver_send(const struct device *dev, struct net_buf *buf)
{
zassert_true(cmd_handle(buf, cmds, ARRAY_SIZE(cmds)) == 0, "Unknown HCI command");
zassert_true(cmd_handle(dev, buf, cmds, ARRAY_SIZE(cmds)) == 0, "Unknown HCI command");
net_buf_unref(buf);
return 0;
}
/* HCI driver structure. */
static const struct bt_hci_driver drv = {
.name = "test",
.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
static const struct bt_hci_driver_api driver_api = {
.open = driver_open,
.send = driver_send,
.quirks = 0,
};
#define TEST_DEVICE_INIT(inst) \
static struct driver_data driver_data_##inst = { \
}; \
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &driver_data_##inst, NULL, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &driver_api)
DT_INST_FOREACH_STATUS_OKAY(TEST_DEVICE_INIT)
struct bt_recv_job_data {
struct k_work work; /* Work item */
struct k_sem *sync; /* Semaphore to synchronize with */
@ -250,10 +267,12 @@ struct bt_recv_job_data {
/* Work item handler for bt_recv() jobs. */
static void bt_recv_job_cb(struct k_work *item)
{
const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0));
struct driver_data *drv = dev->data;
struct bt_recv_job_data *data = CONTAINER_OF(item, struct bt_recv_job_data, work);
/* Send net buffer to host */
bt_recv(data->buf);
drv->recv(dev, data->buf);
/* Wake up bt_recv_job_submit */
k_sem_give(job(data->buf)->sync);
@ -357,9 +376,6 @@ ZTEST(long_adv_rx_tests, test_host_long_adv_recv)
{
struct test_adv_report expected_reports[2];
/* Register the test HCI driver */
bt_hci_driver_register(&drv);
/* Go! Wait until Bluetooth initialization is done */
zassert_true((bt_enable(NULL) == 0), "bt_enable failed");

View file

@ -0,0 +1,10 @@
/ {
chosen {
zephyr,bt-hci = &bt_hci_test;
};
bt_hci_test: bt_hci_test {
compatible = "zephyr,bt-hci-test";
status = "okay";
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.host_long_adv_recv:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- native_posix
- native_posix/native/64

View file

@ -3,7 +3,7 @@ CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_H4=n
CONFIG_LOG=y
CONFIG_BT_PERIPHERAL=y

View file

@ -0,0 +1,5 @@
/ {
chosen {
/delete-property/ zephyr,bt-hci;
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.l2cap:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- native_posix
- native_posix/native/64

View file

@ -10,7 +10,6 @@ CONFIG_FLASH_SIMULATOR=y
CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y
CONFIG_BT=y
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_OBSERVER=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_MESH=y

View file

@ -0,0 +1,9 @@
/ {
chosen {
/delete-property/ zephyr,bt-hci;
};
};
&bt_hci_userchan {
status = "disabled";
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.mesh.blob_io_flash:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- native_posix
- native_sim

View file

@ -3,4 +3,4 @@ CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CTLR=n
CONFIG_BT_NO_DRIVER=y
CONFIG_BT_H4=n

View file

@ -0,0 +1,5 @@
/ {
chosen {
/delete-property/ zephyr,bt-hci;
};
};

View file

@ -1,5 +1,7 @@
tests:
bluetooth.uuid:
extra_args:
- EXTRA_DTC_OVERLAY_FILE="test.overlay"
platform_allow:
- native_posix
- native_posix/native/64