Bluetooth: hci_raw: Move buffer management to common place

This makes hci_raw to manage RX and TX buffers so its logic don't have
to be replicated on each an every driver/application, it also makes it
simpler to deal with extra headers for H:4 mode since that then can be
done at earlier at buffer allocation.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2020-04-07 14:32:43 -07:00 committed by Johan Hedberg
commit 4b622afbb3
8 changed files with 171 additions and 270 deletions

View file

@ -32,6 +32,8 @@ enum bt_buf_type {
BT_BUF_ACL_OUT,
/** Incoming ACL data */
BT_BUF_ACL_IN,
/** H:4 data */
BT_BUF_H4,
};
/** Minimum amount of user data size for buffers passed to the stack. */
@ -61,6 +63,22 @@ enum bt_buf_type {
*/
struct net_buf *bt_buf_get_rx(enum bt_buf_type type, s32_t timeout);
/** Allocate a buffer for outgoing data
*
* This will set the buffer type so bt_buf_set_type() does not need to
* be explicitly called before bt_send().
*
* @param type Type of buffer. Only BT_BUF_CMD, BT_BUF_ACL_OUT or
* BT_BUF_H4, when operating on H:4 mode, are allowed.
* @param timeout Timeout in milliseconds, or one of the special values
* K_NO_WAIT and K_FOREVER.
* @param data Initial data to append to buffer.
* @param size Initial data size.
* @return A new buffer.
*/
struct net_buf *bt_buf_get_tx(enum bt_buf_type type, s32_t timeout,
const void *data, size_t size);
/** Allocate a buffer for an HCI Command Complete/Status Event
*
* This will set the buffer type so bt_buf_set_type() does not need to

View file

@ -21,6 +21,23 @@
extern "C" {
#endif
#if defined(CONFIG_BT_CTLR_TX_BUFFER_SIZE)
#define BT_L2CAP_MTU (CONFIG_BT_CTLR_TX_BUFFER_SIZE - BT_L2CAP_HDR_SIZE)
#else
#define BT_L2CAP_MTU 65 /* 64-byte public key + opcode */
#endif /* CONFIG_BT_CTLR */
/** Data size needed for ACL buffers */
#define BT_BUF_ACL_SIZE BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU)
#if defined(CONFIG_BT_CTLR_TX_BUFFERS)
#define BT_HCI_ACL_COUNT CONFIG_BT_CTLR_TX_BUFFERS
#else
#define BT_HCI_ACL_COUNT 6
#endif
#define BT_BUF_TX_SIZE MAX(BT_BUF_RX_SIZE, BT_BUF_ACL_SIZE)
/** @brief Send packet to the Bluetooth controller
*
* Send packet to the Bluetooth controller. Caller needs to

View file

@ -127,29 +127,6 @@ static void rpmsg_service_unbind(struct rpmsg_endpoint *ep)
static K_THREAD_STACK_DEFINE(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
static struct k_thread tx_thread_data;
/* HCI command buffers */
#define CMD_BUF_SIZE BT_BUF_RX_SIZE
NET_BUF_POOL_FIXED_DEFINE(cmd_tx_pool, CONFIG_BT_HCI_CMD_COUNT, CMD_BUF_SIZE,
NULL);
#if defined(CONFIG_BT_CTLR_TX_BUFFER_SIZE)
#define BT_L2CAP_MTU (CONFIG_BT_CTLR_TX_BUFFER_SIZE - BT_L2CAP_HDR_SIZE)
#else
#define BT_L2CAP_MTU 65 /* 64-byte public key + opcode */
#endif /* CONFIG_BT_CTLR */
/** Data size needed for ACL buffers */
#define BT_BUF_ACL_SIZE BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU)
#if defined(CONFIG_BT_CTLR_TX_BUFFERS)
#define TX_BUF_COUNT CONFIG_BT_CTLR_TX_BUFFERS
#else
#define TX_BUF_COUNT 6
#endif
NET_BUF_POOL_FIXED_DEFINE(acl_tx_pool, TX_BUF_COUNT, BT_BUF_ACL_SIZE, NULL);
static K_FIFO_DEFINE(tx_queue);
#define HCI_RPMSG_CMD 0x01
@ -159,35 +136,30 @@ static K_FIFO_DEFINE(tx_queue);
static struct net_buf *hci_rpmsg_cmd_recv(u8_t *data, size_t remaining)
{
struct bt_hci_cmd_hdr hdr;
struct bt_hci_cmd_hdr *hdr = (void *)data;
struct net_buf *buf;
if (remaining < sizeof(hdr)) {
if (remaining < sizeof(*hdr)) {
LOG_ERR("Not enought data for command header");
return NULL;
}
buf = net_buf_alloc(&cmd_tx_pool, K_NO_WAIT);
buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, hdr, sizeof(*hdr));
if (buf) {
bt_buf_set_type(buf, BT_BUF_CMD);
memcpy((void *)&hdr, data, sizeof(hdr));
data += sizeof(hdr);
remaining -= sizeof(hdr);
net_buf_add_mem(buf, &hdr, sizeof(hdr));
data += sizeof(*hdr);
remaining -= sizeof(*hdr);
} else {
LOG_ERR("No available command buffers!");
return NULL;
}
if (remaining != hdr.param_len) {
if (remaining != hdr->param_len) {
LOG_ERR("Command payload length is not correct");
net_buf_unref(buf);
return NULL;
}
LOG_DBG("len %u", hdr.param_len);
LOG_DBG("len %u", hdr->param_len);
net_buf_add_mem(buf, data, remaining);
return buf;
@ -195,29 +167,24 @@ static struct net_buf *hci_rpmsg_cmd_recv(u8_t *data, size_t remaining)
static struct net_buf *hci_rpmsg_acl_recv(u8_t *data, size_t remaining)
{
struct bt_hci_acl_hdr hdr;
struct bt_hci_acl_hdr *hdr = (void *)data;
struct net_buf *buf;
if (remaining < sizeof(hdr)) {
if (remaining < sizeof(*hdr)) {
LOG_ERR("Not enought data for ACL header");
return NULL;
}
buf = net_buf_alloc(&acl_tx_pool, K_NO_WAIT);
buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT, hdr, sizeof(*hdr));
if (buf) {
bt_buf_set_type(buf, BT_BUF_ACL_OUT);
memcpy((void *)&hdr, data, sizeof(hdr));
data += sizeof(hdr);
remaining -= sizeof(hdr);
net_buf_add_mem(buf, &hdr, sizeof(hdr));
data += sizeof(*hdr);
remaining -= sizeof(*hdr);
} else {
LOG_ERR("No available ACL buffers!");
return NULL;
}
if (remaining != sys_le16_to_cpu(hdr.len)) {
if (remaining != sys_le16_to_cpu(hdr->len)) {
LOG_ERR("ACL payload length is not correct");
net_buf_unref(buf);
return NULL;

View file

@ -71,27 +71,6 @@ const static struct spi_buf_set tx_bufs = {
/* HCI buffer pools */
#define CMD_BUF_SIZE BT_BUF_RX_SIZE
NET_BUF_POOL_FIXED_DEFINE(cmd_tx_pool, CONFIG_BT_HCI_CMD_COUNT, CMD_BUF_SIZE,
NULL);
#if defined(CONFIG_BT_CTLR)
#define BT_L2CAP_MTU (CONFIG_BT_CTLR_TX_BUFFER_SIZE - \
BT_L2CAP_HDR_SIZE)
#else
#define BT_L2CAP_MTU 65 /* 64-byte public key + opcode */
#endif /* CONFIG_BT_CTLR */
/* Data size needed for ACL buffers */
#define BT_BUF_ACL_SIZE BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU)
#if defined(CONFIG_BT_CTLR_TX_BUFFERS)
#define TX_BUF_COUNT CONFIG_BT_CTLR_TX_BUFFERS
#else
#define TX_BUF_COUNT 6
#endif
NET_BUF_POOL_FIXED_DEFINE(acl_tx_pool, TX_BUF_COUNT, BT_BUF_ACL_SIZE, NULL);
static struct device *spi_hci_dev;
static struct spi_config spi_cfg = {
.operation = SPI_WORD_SET(8) | SPI_OP_MODE_SLAVE,
@ -216,13 +195,9 @@ static void bt_tx_thread(void *p1, void *p2, void *p3)
switch (rxmsg[PACKET_TYPE]) {
case HCI_CMD:
memcpy(&cmd_hdr, &rxmsg[1], sizeof(cmd_hdr));
buf = net_buf_alloc(&cmd_tx_pool, K_NO_WAIT);
if (buf) {
bt_buf_set_type(buf, BT_BUF_CMD);
net_buf_add_mem(buf, &cmd_hdr,
buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, &rxmsg[1],
sizeof(cmd_hdr));
if (buf) {
net_buf_add_mem(buf, &rxmsg[4],
cmd_hdr.param_len);
} else {
@ -231,13 +206,9 @@ static void bt_tx_thread(void *p1, void *p2, void *p3)
}
break;
case HCI_ACL:
memcpy(&acl_hdr, &rxmsg[1], sizeof(acl_hdr));
buf = net_buf_alloc(&acl_tx_pool, K_NO_WAIT);
buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT,
&rxmsg[1], sizeof(acl_hdr));
if (buf) {
bt_buf_set_type(buf, BT_BUF_ACL_OUT);
net_buf_add_mem(buf, &acl_hdr,
sizeof(acl_hdr));
net_buf_add_mem(buf, &rxmsg[5],
sys_le16_to_cpu(acl_hdr.len));
} else {
@ -315,8 +286,7 @@ void main(void)
k_thread_name_set(&bt_tx_thread_data, "bt_tx_thread");
/* Send a vendor event to announce that the slave is initialized */
buf = net_buf_alloc(&cmd_tx_pool, K_FOREVER);
bt_buf_set_type(buf, BT_BUF_EVT);
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
evt_hdr = net_buf_add(buf, sizeof(*evt_hdr));
evt_hdr->evt = BT_HCI_EVT_VENDOR;
evt_hdr->len = 2U;

View file

@ -33,29 +33,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
static struct device *hci_uart_dev;
static K_THREAD_STACK_DEFINE(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
static struct k_thread tx_thread_data;
/* HCI command buffers */
#define CMD_BUF_SIZE BT_BUF_RX_SIZE
NET_BUF_POOL_FIXED_DEFINE(cmd_tx_pool, CONFIG_BT_HCI_CMD_COUNT, CMD_BUF_SIZE,
NULL);
#if defined(CONFIG_BT_CTLR_TX_BUFFER_SIZE)
#define BT_L2CAP_MTU (CONFIG_BT_CTLR_TX_BUFFER_SIZE - BT_L2CAP_HDR_SIZE)
#else
#define BT_L2CAP_MTU 65 /* 64-byte public key + opcode */
#endif /* CONFIG_BT_CTLR */
/** Data size needed for ACL buffers */
#define BT_BUF_ACL_SIZE BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU)
#if defined(CONFIG_BT_CTLR_TX_BUFFERS)
#define TX_BUF_COUNT CONFIG_BT_CTLR_TX_BUFFERS
#else
#define TX_BUF_COUNT 6
#endif
NET_BUF_POOL_FIXED_DEFINE(acl_tx_pool, TX_BUF_COUNT, BT_BUF_ACL_SIZE, NULL);
static K_FIFO_DEFINE(tx_queue);
#define H4_CMD 0x01
@ -115,11 +92,8 @@ static struct net_buf *h4_cmd_recv(int *remaining)
*remaining = hdr.param_len;
buf = net_buf_alloc(&cmd_tx_pool, K_NO_WAIT);
if (buf) {
bt_buf_set_type(buf, BT_BUF_CMD);
net_buf_add_mem(buf, &hdr, sizeof(hdr));
} else {
buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, &hdr, sizeof(hdr));
if (!buf) {
LOG_ERR("No available command buffers!");
}
@ -136,11 +110,8 @@ static struct net_buf *h4_acl_recv(int *remaining)
/* We can ignore the return value since we pass len == min */
h4_read(hci_uart_dev, (void *)&hdr, sizeof(hdr), sizeof(hdr));
buf = net_buf_alloc(&acl_tx_pool, K_NO_WAIT);
if (buf) {
bt_buf_set_type(buf, BT_BUF_ACL_OUT);
net_buf_add_mem(buf, &hdr, sizeof(hdr));
} else {
buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT, &hdr, sizeof(hdr));
if (!buf) {
LOG_ERR("No available ACL buffers!");
}

View file

@ -12,6 +12,7 @@
#include <drivers/bluetooth/hci_driver.h>
#include <bluetooth/hci_raw.h>
#include <bluetooth/l2cap.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
#define LOG_MODULE_NAME bt_hci_raw
@ -37,6 +38,9 @@ static u8_t raw_mode;
NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, CONFIG_BT_RX_BUF_COUNT,
BT_BUF_RX_SIZE, NULL);
NET_BUF_POOL_FIXED_DEFINE(hci_tx_pool, CONFIG_BT_HCI_CMD_COUNT + BT_BUF_TX_SIZE,
BT_BUF_TX_SIZE, NULL);
struct bt_dev_raw bt_dev;
struct bt_hci_raw_cmd_ext *cmd_ext;
static size_t cmd_ext_size;
@ -65,11 +69,86 @@ struct net_buf *bt_buf_get_rx(enum bt_buf_type type, s32_t timeout)
{
struct net_buf *buf;
buf = net_buf_alloc(&hci_rx_pool, timeout);
switch (type) {
case BT_BUF_EVT:
case BT_BUF_ACL_IN:
break;
default:
BT_ERR("Invalid type: %u", type);
return NULL;
}
buf = net_buf_alloc(&hci_rx_pool, timeout);
if (!buf) {
return buf;
}
if (buf) {
net_buf_reserve(buf, BT_BUF_RESERVE);
bt_buf_set_type(buf, type);
if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4) &&
raw_mode == BT_HCI_RAW_MODE_H4) {
switch (type) {
case BT_BUF_EVT:
net_buf_push_u8(buf, H4_EVT);
break;
case BT_BUF_ACL_IN:
net_buf_push_u8(buf, H4_ACL);
break;
default:
LOG_ERR("Invalid H4 type %u", type);
return NULL;
}
}
return buf;
}
struct net_buf *bt_buf_get_tx(enum bt_buf_type type, s32_t timeout,
const void *data, size_t size)
{
struct net_buf *buf;
switch (type) {
case BT_BUF_CMD:
case BT_BUF_ACL_OUT:
break;
case BT_BUF_H4:
if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4) &&
raw_mode == BT_HCI_RAW_MODE_H4) {
switch (((u8_t *)data)[0]) {
case H4_CMD:
type = BT_BUF_CMD;
break;
case H4_ACL:
type = BT_BUF_ACL_OUT;
break;
default:
LOG_ERR("Unknown H4 type %u", type);
return NULL;
}
/* Adjust data pointer to discard the header */
data = (u8_t *)data + 1;
size--;
break;
}
/* Fallthrough */
default:
BT_ERR("Invalid type: %u", type);
return NULL;
}
buf = net_buf_alloc(&hci_tx_pool, timeout);
if (!buf) {
return buf;
}
net_buf_reserve(buf, BT_BUF_RESERVE);
bt_buf_set_type(buf, type);
if (data && size) {
net_buf_add_mem(buf, data, size);
}
return buf;
@ -85,39 +164,10 @@ struct net_buf *bt_buf_get_evt(u8_t evt, bool discardable, s32_t timeout)
return bt_buf_get_rx(BT_BUF_EVT, timeout);
}
static int bt_h4_recv(struct net_buf *buf)
{
BT_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_IN:
net_buf_push_u8(buf, H4_ACL);
break;
case BT_BUF_EVT:
net_buf_push_u8(buf, H4_EVT);
break;
default:
BT_ERR("Unknown type %u", bt_buf_get_type(buf));
net_buf_unref(buf);
return -EINVAL;
}
return 0;
}
int bt_recv(struct net_buf *buf)
{
BT_DBG("buf %p len %u", buf, buf->len);
if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4) &&
raw_mode == BT_HCI_RAW_MODE_H4) {
int err = bt_h4_recv(buf);
if (err) {
return err;
}
}
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
/* Queue to RAW rx queue */
@ -131,29 +181,6 @@ int bt_recv_prio(struct net_buf *buf)
return bt_recv(buf);
}
static int bt_h4_send(struct net_buf *buf)
{
u8_t type;
type = net_buf_pull_u8(buf);
switch (type) {
case H4_CMD:
bt_buf_set_type(buf, BT_BUF_CMD);
break;
case H4_ACL:
bt_buf_set_type(buf, BT_BUF_ACL_OUT);
break;
default:
LOG_ERR("Unknown H4 type %u", type);
return -EINVAL;
}
LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
return 0;
}
static void bt_cmd_complete_ext(u16_t op, u8_t status)
{
struct net_buf *buf;
@ -227,15 +254,6 @@ int bt_send(struct net_buf *buf)
{
BT_DBG("buf %p len %u", buf, buf->len);
if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4) &&
raw_mode == BT_HCI_RAW_MODE_H4) {
int err = bt_h4_send(buf);
if (err) {
return err;
}
}
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
if (IS_ENABLED(CONFIG_BT_HCI_RAW_CMD_EXT) &&

View file

@ -28,41 +28,6 @@ LOG_MODULE_REGISTER(usb_bluetooth);
static K_FIFO_DEFINE(rx_queue);
static K_FIFO_DEFINE(tx_queue);
/* HCI command buffers */
#define CMD_BUF_SIZE BT_BUF_RX_SIZE
NET_BUF_POOL_DEFINE(rx_pool, CONFIG_BT_HCI_CMD_COUNT, CMD_BUF_SIZE,
sizeof(u8_t), NULL);
/* ACL data TX buffers */
#if defined(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4)
#if defined(CONFIG_BT_CTLR_TX_BUFFERS)
#define ACL_BUF_COUNT (CONFIG_BT_HCI_CMD_COUNT + CONFIG_BT_CTLR_TX_BUFFERS)
#else
#define ACL_BUF_COUNT (CONFIG_BT_HCI_CMD_COUNT + 4)
#endif
#else
#if defined(CONFIG_BT_CTLR_TX_BUFFERS)
#define ACL_BUF_COUNT CONFIG_BT_CTLR_TX_BUFFERS
#else
#define ACL_BUF_COUNT 4
#endif
#endif /* CONFIG_USB_DEVICE_BLUETOOTH_VS_H4 */
#if defined(CONFIG_BT_CTLR_TX_BUFFER_SIZE)
#define BT_L2CAP_MTU (CONFIG_BT_CTLR_TX_BUFFER_SIZE - BT_L2CAP_HDR_SIZE)
#else
#define BT_L2CAP_MTU 64
#endif
/* Data size needed for ACL buffers */
#if defined(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4)
#define BT_BUF_ACL_SIZE MAX(BT_BUF_RX_SIZE, BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU))
#else
#define BT_BUF_ACL_SIZE BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU)
#endif
NET_BUF_POOL_DEFINE(acl_rx_pool, ACL_BUF_COUNT, BT_BUF_ACL_SIZE,
sizeof(u8_t), NULL);
#define BLUETOOTH_INT_EP_ADDR 0x81
#define BLUETOOTH_OUT_EP_ADDR 0x02
#define BLUETOOTH_IN_EP_ADDR 0x82
@ -205,26 +170,30 @@ static void hci_rx_thread(void)
static void acl_read_cb(u8_t ep, int size, void *priv)
{
struct net_buf *buf = priv;
static u8_t data[BLUETOOTH_BULK_EP_MPS];
if (size > 0) {
buf->len += size;
bt_buf_set_type(buf, BT_BUF_ACL_OUT);
struct net_buf *buf;
if (IS_ENABLED(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4) &&
bt_hci_raw_get_mode() == BT_HCI_RAW_MODE_H4) {
buf = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, data, size);
} else {
buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_FOREVER, data,
size);
}
if (!buf) {
LOG_ERR("Cannot get free TX buffer\n");
return;
}
net_buf_put(&rx_queue, buf);
buf = NULL;
}
if (buf) {
net_buf_unref(buf);
}
buf = net_buf_alloc(&acl_rx_pool, K_FOREVER);
net_buf_reserve(buf, BT_BUF_RESERVE);
/* Start a new read transfer */
usb_transfer(bluetooth_ep_data[HCI_OUT_EP_IDX].ep_addr, buf->data,
BT_BUF_ACL_SIZE, USB_TRANS_READ, acl_read_cb, buf);
usb_transfer(bluetooth_ep_data[HCI_OUT_EP_IDX].ep_addr, data,
BT_BUF_ACL_SIZE, USB_TRANS_READ, acl_read_cb, NULL);
}
static void bluetooth_status_cb(struct usb_cfg_data *cfg,
@ -331,22 +300,12 @@ static int bluetooth_class_handler(struct usb_setup_packet *setup,
LOG_DBG("len %u", *len);
if (!*len || *len > CMD_BUF_SIZE) {
LOG_ERR("Incorrect length: %d\n", *len);
return -EINVAL;
}
buf = net_buf_alloc(&rx_pool, K_NO_WAIT);
buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, *data, *len);
if (!buf) {
LOG_ERR("Cannot get free buffer\n");
return -ENOMEM;
}
net_buf_reserve(buf, BT_BUF_RESERVE);
bt_buf_set_type(buf, BT_BUF_CMD);
net_buf_add_mem(buf, *data, *len);
net_buf_put(&rx_queue, buf);
return 0;

View file

@ -26,30 +26,13 @@ LOG_MODULE_REGISTER(usb_bt_h4);
static K_FIFO_DEFINE(rx_queue);
static K_FIFO_DEFINE(tx_queue);
/* ACL data TX buffers */
#if defined(CONFIG_BT_CTLR_TX_BUFFERS)
#define BUF_COUNT (CONFIG_BT_HCI_CMD_COUNT + CONFIG_BT_CTLR_TX_BUFFERS)
#else
#define BUF_COUNT (CONFIG_BT_HCI_CMD_COUNT + 4)
#endif
#if defined(CONFIG_BT_CTLR_TX_BUFFER_SIZE)
#define BT_L2CAP_MTU (CONFIG_BT_CTLR_TX_BUFFER_SIZE - BT_L2CAP_HDR_SIZE)
#else
#define BT_L2CAP_MTU 64
#endif
/* Data size needed for CMD and ACL buffers */
#define BUF_SIZE MAX(BT_BUF_RX_SIZE, BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU))
NET_BUF_POOL_DEFINE(rx_pool, BUF_COUNT, BUF_SIZE, sizeof(u8_t), NULL);
#define BT_H4_OUT_EP_ADDR 0x01
#define BT_H4_IN_EP_ADDR 0x81
#define BT_H4_OUT_EP_IDX 0
#define BT_H4_IN_EP_IDX 1
#define BT_H4_BULK_EP_MPS MIN(BUF_SIZE, USB_MAX_FS_BULK_MPS)
#define BT_H4_BULK_EP_MPS MIN(BT_BUF_TX_SIZE, USB_MAX_FS_BULK_MPS)
/* HCI RX/TX threads */
static K_THREAD_STACK_DEFINE(rx_thread_stack, 512);
@ -111,25 +94,23 @@ static struct usb_ep_cfg_data bt_h4_ep_data[] = {
static void bt_h4_read(u8_t ep, int size, void *priv)
{
struct net_buf *buf = priv;
static u8_t data[BT_H4_BULK_EP_MPS];
if (size > 0) {
buf->len += size;
struct net_buf *buf;
buf = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, data, size);
if (!buf) {
LOG_ERR("Cannot get free TX buffer\n");
return;
}
net_buf_put(&rx_queue, buf);
buf = NULL;
}
if (buf) {
net_buf_unref(buf);
}
buf = net_buf_alloc(&rx_pool, K_FOREVER);
net_buf_reserve(buf, BT_BUF_RESERVE);
/* Start a new read transfer */
usb_transfer(bt_h4_ep_data[BT_H4_OUT_EP_IDX].ep_addr, buf->data,
BUF_SIZE, USB_TRANS_READ, bt_h4_read, buf);
usb_transfer(bt_h4_ep_data[BT_H4_OUT_EP_IDX].ep_addr, data,
BT_H4_BULK_EP_MPS, USB_TRANS_READ, bt_h4_read, NULL);
}
static void hci_tx_thread(void)