Bluetooth: drivers: Convert userchan driver to new API
Convert the HCI User Channel driver to use the new HCI driver API. Signed-off-by: Johan Hedberg <johan.hedberg@gmail.com>
This commit is contained in:
parent
db753c1474
commit
bb91aa0b7f
6 changed files with 63 additions and 42 deletions
|
@ -22,10 +22,6 @@ config ETH_NATIVE_POSIX
|
|||
|
||||
endif # NETWORKING
|
||||
|
||||
config BT_USERCHAN
|
||||
default y
|
||||
depends on BT_HCI
|
||||
|
||||
if CONSOLE
|
||||
|
||||
config POSIX_ARCH_CONSOLE
|
||||
|
|
|
@ -22,10 +22,6 @@ config ETH_NATIVE_POSIX
|
|||
|
||||
endif # NETWORKING
|
||||
|
||||
config BT_USERCHAN
|
||||
depends on BT_HCI
|
||||
default y
|
||||
|
||||
if CONSOLE
|
||||
|
||||
config POSIX_ARCH_CONSOLE
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
zephyr,display = &sdl_dc;
|
||||
zephyr,canbus = &can_loopback0;
|
||||
zephyr,code-partition = &slot0_partition;
|
||||
zephyr,bt-hci = &bt_hci_userchan;
|
||||
};
|
||||
|
||||
aliases {
|
||||
|
@ -218,4 +219,9 @@
|
|||
#dma-cells = <1>;
|
||||
stack-size = <4096>;
|
||||
};
|
||||
|
||||
bt_hci_userchan: bt_hci_userchan {
|
||||
compatible = "zephyr,bt-hci-userchan";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -85,6 +85,8 @@ config BT_SILABS_HCI
|
|||
config BT_USERCHAN
|
||||
bool "HCI User Channel based driver"
|
||||
depends on BOARD_NATIVE_POSIX
|
||||
default y
|
||||
depends on DT_HAS_ZEPHYR_BT_HCI_USERCHAN_ENABLED
|
||||
help
|
||||
This driver provides access to the local Linux host's Bluetooth
|
||||
adapter using a User Channel HCI socket to the Linux kernel. It
|
||||
|
|
|
@ -30,12 +30,20 @@
|
|||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/drivers/bluetooth/hci_driver.h>
|
||||
#include <zephyr/drivers/bluetooth.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(bt_driver);
|
||||
|
||||
#define DT_DRV_COMPAT zephyr_bt_hci_userchan
|
||||
|
||||
struct uc_data {
|
||||
int fd;
|
||||
bt_hci_recv_t recv;
|
||||
|
||||
};
|
||||
|
||||
#define BTPROTO_HCI 1
|
||||
struct sockaddr_hci {
|
||||
sa_family_t hci_family;
|
||||
|
@ -50,8 +58,6 @@ static K_KERNEL_STACK_DEFINE(rx_thread_stack,
|
|||
CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE);
|
||||
static struct k_thread rx_thread_data;
|
||||
|
||||
static int uc_fd = -1;
|
||||
|
||||
static unsigned short bt_dev_index;
|
||||
|
||||
#define TCP_ADDR_BUFF_SIZE 16
|
||||
|
@ -158,16 +164,18 @@ static int32_t hci_packet_complete(const uint8_t *buf, uint16_t buf_len)
|
|||
return (int32_t)header_len + payload_len;
|
||||
}
|
||||
|
||||
static bool uc_ready(void)
|
||||
static bool uc_ready(int fd)
|
||||
{
|
||||
struct pollfd pollfd = { .fd = uc_fd, .events = POLLIN };
|
||||
struct pollfd pollfd = { .fd = fd, .events = POLLIN };
|
||||
|
||||
return (poll(&pollfd, 1, 0) == 1);
|
||||
}
|
||||
|
||||
static void rx_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
ARG_UNUSED(p1);
|
||||
const struct device *dev = p1;
|
||||
struct uc_data *uc = dev->data;
|
||||
|
||||
ARG_UNUSED(p2);
|
||||
ARG_UNUSED(p3);
|
||||
|
||||
|
@ -183,14 +191,14 @@ static void rx_thread(void *p1, void *p2, void *p3)
|
|||
ssize_t len;
|
||||
const uint8_t *frame_start = frame;
|
||||
|
||||
if (!uc_ready()) {
|
||||
if (!uc_ready(uc->fd)) {
|
||||
k_sleep(K_MSEC(1));
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_DBG("calling read()");
|
||||
|
||||
len = read(uc_fd, frame + frame_size, sizeof(frame) - frame_size);
|
||||
len = read(uc->fd, frame + frame_size, sizeof(frame) - frame_size);
|
||||
if (len < 0) {
|
||||
if (errno == EINTR) {
|
||||
k_yield();
|
||||
|
@ -198,8 +206,8 @@ static void rx_thread(void *p1, void *p2, void *p3)
|
|||
}
|
||||
|
||||
LOG_ERR("Reading socket failed, errno %d", errno);
|
||||
close(uc_fd);
|
||||
uc_fd = -1;
|
||||
close(uc->fd);
|
||||
uc->fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -256,18 +264,20 @@ static void rx_thread(void *p1, void *p2, void *p3)
|
|||
|
||||
LOG_DBG("Calling bt_recv(%p)", buf);
|
||||
|
||||
bt_recv(buf);
|
||||
uc->recv(dev, buf);
|
||||
}
|
||||
|
||||
k_yield();
|
||||
}
|
||||
}
|
||||
|
||||
static int uc_send(struct net_buf *buf)
|
||||
static int uc_send(const struct device *dev, struct net_buf *buf)
|
||||
{
|
||||
struct uc_data *uc = dev->data;
|
||||
|
||||
LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
|
||||
|
||||
if (uc_fd < 0) {
|
||||
if (uc->fd < 0) {
|
||||
LOG_ERR("User channel not open");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -290,7 +300,7 @@ static int uc_send(struct net_buf *buf)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (write(uc_fd, buf->data, buf->len) < 0) {
|
||||
if (write(uc->fd, buf->data, buf->len) < 0) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
@ -350,25 +360,28 @@ static int user_chan_open(void)
|
|||
return fd;
|
||||
}
|
||||
|
||||
static int uc_open(void)
|
||||
static int uc_open(const struct device *dev, bt_hci_recv_t recv)
|
||||
{
|
||||
struct uc_data *uc = dev->data;
|
||||
|
||||
if (hci_socket) {
|
||||
LOG_DBG("hci%d", bt_dev_index);
|
||||
} else {
|
||||
LOG_DBG("hci %s:%d", ip_addr, port);
|
||||
}
|
||||
|
||||
|
||||
uc_fd = user_chan_open();
|
||||
if (uc_fd < 0) {
|
||||
return uc_fd;
|
||||
uc->fd = user_chan_open();
|
||||
if (uc->fd < 0) {
|
||||
return uc->fd;
|
||||
}
|
||||
|
||||
LOG_DBG("User Channel opened as fd %d", uc_fd);
|
||||
uc->recv = recv;
|
||||
|
||||
LOG_DBG("User Channel opened as fd %d", uc->fd);
|
||||
|
||||
k_thread_create(&rx_thread_data, rx_thread_stack,
|
||||
K_KERNEL_STACK_SIZEOF(rx_thread_stack),
|
||||
rx_thread, NULL, NULL, NULL,
|
||||
rx_thread, (void *)dev, NULL, NULL,
|
||||
K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO),
|
||||
0, K_NO_WAIT);
|
||||
|
||||
|
@ -377,22 +390,19 @@ static int uc_open(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct bt_hci_driver drv = {
|
||||
.name = "HCI User Channel",
|
||||
.bus = BT_HCI_DRIVER_BUS_UART,
|
||||
.open = uc_open,
|
||||
.send = uc_send,
|
||||
static const struct bt_hci_driver_api uc_drv_api = {
|
||||
.open = uc_open,
|
||||
.send = uc_send,
|
||||
};
|
||||
|
||||
static int bt_uc_init(void)
|
||||
{
|
||||
#define UC_DEVICE_INIT(inst) \
|
||||
static struct uc_data uc_data_##inst = { \
|
||||
.fd = -1, \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &uc_data_##inst, NULL, \
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &uc_drv_api)
|
||||
|
||||
bt_hci_driver_register(&drv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(bt_uc_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
|
||||
DT_INST_FOREACH_STATUS_OKAY(UC_DEVICE_INIT)
|
||||
|
||||
static void cmd_bt_dev_found(char *argv, int offset)
|
||||
{
|
||||
|
|
11
dts/bindings/bluetooth/zephyr,bt-hci-userchan.yaml
Normal file
11
dts/bindings/bluetooth/zephyr,bt-hci-userchan.yaml
Normal file
|
@ -0,0 +1,11 @@
|
|||
description: Bluetooth HCI provided by a Linux HCI user channel socket
|
||||
|
||||
compatible: "zephyr,bt-hci-userchan"
|
||||
|
||||
include: bt-hci.yaml
|
||||
|
||||
properties:
|
||||
bt-hci-name:
|
||||
default: "HCI User Channel"
|
||||
bt-hci-bus:
|
||||
default: "BT_HCI_BUS_UART"
|
Loading…
Add table
Add a link
Reference in a new issue