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:
parent
05f0816f93
commit
4b622afbb3
8 changed files with 171 additions and 270 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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!");
|
||||
}
|
||||
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue