Bluetooth: hci_raw: Add support for using H:4 transport
This adds 2 config options which enables hci_raw to work in H:4 mode and enable it by default automatically. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
8a358523e7
commit
b3ee8be80d
6 changed files with 167 additions and 122 deletions
|
@ -32,6 +32,41 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
int bt_send(struct net_buf *buf);
|
int bt_send(struct net_buf *buf);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/** Passthrough mode
|
||||||
|
*
|
||||||
|
* While in this mode the buffers are passed as is between the stack
|
||||||
|
* and the driver.
|
||||||
|
*/
|
||||||
|
BT_HCI_RAW_MODE_PASSTHROUGH = 0x00,
|
||||||
|
|
||||||
|
/** H:4 mode
|
||||||
|
*
|
||||||
|
* While in this mode H:4 headers will added into the buffers
|
||||||
|
* according to the buffer type when coming from the stack and will be
|
||||||
|
* removed and used to set the buffer type.
|
||||||
|
*/
|
||||||
|
BT_HCI_RAW_MODE_H4 = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @brief Set Bluetooth RAW channel mode
|
||||||
|
*
|
||||||
|
* Set access mode of Bluetooth RAW channel.
|
||||||
|
*
|
||||||
|
* @param mode Access mode.
|
||||||
|
*
|
||||||
|
* @return Zero on success or (negative) error code otherwise.
|
||||||
|
*/
|
||||||
|
int bt_hci_raw_set_mode(u8_t mode);
|
||||||
|
|
||||||
|
/** @brief Get Bluetooth RAW channel mode
|
||||||
|
*
|
||||||
|
* Get access mode of Bluetooth RAW channel.
|
||||||
|
*
|
||||||
|
* @return Access mode.
|
||||||
|
*/
|
||||||
|
u8_t bt_hci_raw_get_mode(void);
|
||||||
|
|
||||||
/** @brief Enable Bluetooth RAW channel
|
/** @brief Enable Bluetooth RAW channel
|
||||||
*
|
*
|
||||||
* Enable Bluetooth RAW HCI channel.
|
* Enable Bluetooth RAW HCI channel.
|
||||||
|
|
|
@ -49,10 +49,23 @@ config BT_HCI_RAW
|
||||||
This option allows to access Bluetooth controller
|
This option allows to access Bluetooth controller
|
||||||
from the application with the RAW HCI protocol.
|
from the application with the RAW HCI protocol.
|
||||||
|
|
||||||
|
config BT_HCI_RAW_H4
|
||||||
|
bool "RAW HCI H:4 transport"
|
||||||
|
help
|
||||||
|
This option enables HCI RAW access to work over an H:4
|
||||||
|
transport, note that it still need to be selected at runtime.
|
||||||
|
|
||||||
|
config BT_HCI_RAW_H4_ENABLE
|
||||||
|
bool "RAW HCI H:4 transport enable"
|
||||||
|
depends on BT_HCI_RAW_H4
|
||||||
|
help
|
||||||
|
This option enables use of H:4 transport for HCI RAW access at
|
||||||
|
build time.
|
||||||
|
|
||||||
config BT_HCI_RAW_RESERVE
|
config BT_HCI_RAW_RESERVE
|
||||||
int "Buffer headroom needed for HCI transport"
|
int "Buffer headroom needed for HCI transport"
|
||||||
depends on BT_HCI_RAW
|
depends on BT_HCI_RAW
|
||||||
default 1 if USB_DEVICE_BT_H4
|
default 1 if BT_HCI_RAW_H4
|
||||||
default 0
|
default 0
|
||||||
help
|
help
|
||||||
This option is used by the HCI raw transport implementation to
|
This option is used by the HCI raw transport implementation to
|
||||||
|
|
|
@ -20,8 +20,19 @@
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
#include "hci_raw_internal.h"
|
#include "hci_raw_internal.h"
|
||||||
|
|
||||||
|
#define H4_CMD 0x01
|
||||||
|
#define H4_ACL 0x02
|
||||||
|
#define H4_SCO 0x03
|
||||||
|
#define H4_EVT 0x04
|
||||||
|
|
||||||
static struct k_fifo *raw_rx;
|
static struct k_fifo *raw_rx;
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_HCI_RAW_H4_ENABLE)
|
||||||
|
static u8_t raw_mode = BT_HCI_RAW_MODE_H4;
|
||||||
|
#else
|
||||||
|
static u8_t raw_mode;
|
||||||
|
#endif
|
||||||
|
|
||||||
NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, CONFIG_BT_RX_BUF_COUNT,
|
NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, CONFIG_BT_RX_BUF_COUNT,
|
||||||
BT_BUF_RX_SIZE, NULL);
|
BT_BUF_RX_SIZE, NULL);
|
||||||
|
|
||||||
|
@ -71,10 +82,39 @@ struct net_buf *bt_buf_get_evt(u8_t evt, bool discardable, s32_t timeout)
|
||||||
return bt_buf_get_rx(BT_BUF_EVT, 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)
|
int bt_recv(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
BT_DBG("buf %p len %u", buf, buf->len);
|
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);
|
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
|
||||||
|
|
||||||
/* Queue to RAW rx queue */
|
/* Queue to RAW rx queue */
|
||||||
|
@ -88,10 +128,42 @@ int bt_recv_prio(struct net_buf *buf)
|
||||||
return bt_recv(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;
|
||||||
|
}
|
||||||
|
|
||||||
int bt_send(struct net_buf *buf)
|
int bt_send(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
BT_DBG("buf %p len %u", buf, buf->len);
|
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);
|
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_TINYCRYPT_ECC)) {
|
if (IS_ENABLED(CONFIG_BT_TINYCRYPT_ECC)) {
|
||||||
|
@ -101,6 +173,31 @@ int bt_send(struct net_buf *buf)
|
||||||
return bt_dev.drv->send(buf);
|
return bt_dev.drv->send(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bt_hci_raw_set_mode(u8_t mode)
|
||||||
|
{
|
||||||
|
BT_DBG("mode %u", mode);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4)) {
|
||||||
|
switch (mode) {
|
||||||
|
case BT_HCI_RAW_MODE_PASSTHROUGH:
|
||||||
|
case BT_HCI_RAW_MODE_H4:
|
||||||
|
raw_mode = mode;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8_t bt_hci_raw_get_mode(void)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4)) {
|
||||||
|
return raw_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BT_HCI_RAW_MODE_PASSTHROUGH;
|
||||||
|
}
|
||||||
|
|
||||||
int bt_enable_raw(struct k_fifo *rx_queue)
|
int bt_enable_raw(struct k_fifo *rx_queue)
|
||||||
{
|
{
|
||||||
const struct bt_hci_driver *drv = bt_dev.drv;
|
const struct bt_hci_driver *drv = bt_dev.drv;
|
||||||
|
|
|
@ -94,6 +94,7 @@ config USB_DEVICE_BLUETOOTH
|
||||||
config USB_DEVICE_BLUETOOTH_VS_H4
|
config USB_DEVICE_BLUETOOTH_VS_H4
|
||||||
bool "Enable USB Bluetooth H4 vendor command"
|
bool "Enable USB Bluetooth H4 vendor command"
|
||||||
depends on USB_DEVICE_BLUETOOTH
|
depends on USB_DEVICE_BLUETOOTH
|
||||||
|
select BT_HCI_RAW_H4
|
||||||
help
|
help
|
||||||
Enables vendor command to switch to H:4 transport using the bulk
|
Enables vendor command to switch to H:4 transport using the bulk
|
||||||
endpoint.
|
endpoint.
|
||||||
|
@ -102,6 +103,8 @@ config USB_DEVICE_BT_H4
|
||||||
bool "USB Bluetooth H4 Device Class Driver"
|
bool "USB Bluetooth H4 Device Class Driver"
|
||||||
select BT
|
select BT
|
||||||
select BT_HCI_RAW
|
select BT_HCI_RAW
|
||||||
|
select BT_HCI_RAW_H4
|
||||||
|
select BT_HCI_RAW_H4_ENABLE
|
||||||
help
|
help
|
||||||
USB Bluetooth H4 device class driver
|
USB Bluetooth H4 device class driver
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,6 @@ static K_THREAD_STACK_DEFINE(rx_thread_stack, 512);
|
||||||
static struct k_thread rx_thread_data;
|
static struct k_thread rx_thread_data;
|
||||||
static K_THREAD_STACK_DEFINE(tx_thread_stack, 512);
|
static K_THREAD_STACK_DEFINE(tx_thread_stack, 512);
|
||||||
static struct k_thread tx_thread_data;
|
static struct k_thread tx_thread_data;
|
||||||
static u8_t mode = BT_HCI_VS_USB_H2_MODE;
|
|
||||||
|
|
||||||
struct usb_bluetooth_config {
|
struct usb_bluetooth_config {
|
||||||
struct usb_if_descriptor if0;
|
struct usb_if_descriptor if0;
|
||||||
|
@ -151,34 +150,6 @@ static struct usb_ep_cfg_data bluetooth_ep_data[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define H4_CMD 0x01
|
|
||||||
#define H4_ACL 0x02
|
|
||||||
#define H4_SCO 0x03
|
|
||||||
#define H4_EVT 0x04
|
|
||||||
|
|
||||||
static void usb_h4_send(struct net_buf *buf)
|
|
||||||
{
|
|
||||||
LOG_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:
|
|
||||||
LOG_ERR("Unknown type %u", bt_buf_get_type(buf));
|
|
||||||
net_buf_unref(buf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
usb_transfer_sync(bluetooth_ep_data[HCI_IN_EP_IDX].ep_addr, buf->data,
|
|
||||||
buf->len, USB_TRANS_WRITE);
|
|
||||||
|
|
||||||
net_buf_unref(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hci_tx_thread(void)
|
static void hci_tx_thread(void)
|
||||||
{
|
{
|
||||||
LOG_DBG("Start USB Bluetooth thread");
|
LOG_DBG("Start USB Bluetooth thread");
|
||||||
|
@ -189,9 +160,9 @@ static void hci_tx_thread(void)
|
||||||
buf = net_buf_get(&tx_queue, K_FOREVER);
|
buf = net_buf_get(&tx_queue, K_FOREVER);
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4) &&
|
if (IS_ENABLED(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4) &&
|
||||||
mode == BT_HCI_VS_USB_H4_MODE) {
|
bt_hci_raw_get_mode() == BT_HCI_RAW_MODE_H4) {
|
||||||
usb_h4_send(buf);
|
/* Force to sent over bulk if H4 is selected */
|
||||||
continue;
|
bt_buf_set_type(buf, BT_BUF_ACL_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (bt_buf_get_type(buf)) {
|
switch (bt_buf_get_type(buf)) {
|
||||||
|
@ -216,43 +187,16 @@ static void hci_tx_thread(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_h4_recv(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
|
|
||||||
|
|
||||||
if (bt_send(buf)) {
|
|
||||||
LOG_ERR("Error sending to driver");
|
|
||||||
net_buf_unref(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hci_rx_thread(void)
|
static void hci_rx_thread(void)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
int err;
|
||||||
|
|
||||||
buf = net_buf_get(&rx_queue, K_FOREVER);
|
buf = net_buf_get(&rx_queue, K_FOREVER);
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4) &&
|
err = bt_send(buf);
|
||||||
mode == BT_HCI_VS_USB_H4_MODE) {
|
if (err) {
|
||||||
usb_h4_recv(buf);
|
|
||||||
} else if (bt_send(buf)) {
|
|
||||||
LOG_ERR("Error sending to driver");
|
LOG_ERR("Error sending to driver");
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
}
|
}
|
||||||
|
@ -358,26 +302,26 @@ static u8_t vs_read_usb_transport_mode(struct net_buf *buf)
|
||||||
static u8_t vs_set_usb_transport_mode(struct net_buf *buf)
|
static u8_t vs_set_usb_transport_mode(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct bt_hci_cp_vs_set_usb_transport_mode *cp;
|
struct bt_hci_cp_vs_set_usb_transport_mode *cp;
|
||||||
|
u8_t mode;
|
||||||
|
|
||||||
cp = net_buf_pull_mem(buf, sizeof(*cp));
|
cp = net_buf_pull_mem(buf, sizeof(*cp));
|
||||||
|
|
||||||
if (mode == cp->mode) {
|
|
||||||
return BT_HCI_ERR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cp->mode) {
|
switch (cp->mode) {
|
||||||
case BT_HCI_VS_USB_H2_MODE:
|
case BT_HCI_VS_USB_H2_MODE:
|
||||||
|
mode = BT_HCI_RAW_MODE_PASSTHROUGH;
|
||||||
|
break;
|
||||||
case BT_HCI_VS_USB_H4_MODE:
|
case BT_HCI_VS_USB_H4_MODE:
|
||||||
|
mode = BT_HCI_RAW_MODE_H4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_DBG("Invalid mode: %u", cp->mode);
|
LOG_DBG("Invalid mode: %u", cp->mode);
|
||||||
return BT_HCI_ERR_INVALID_PARAM;
|
return BT_HCI_ERR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = cp->mode;
|
|
||||||
|
|
||||||
LOG_DBG("mode %u", mode);
|
LOG_DBG("mode %u", mode);
|
||||||
|
|
||||||
|
bt_hci_raw_set_mode(mode);
|
||||||
|
|
||||||
return BT_HCI_ERR_SUCCESS;
|
return BT_HCI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,11 +98,6 @@ USBD_CLASS_DESCR_DEFINE(primary, 0) struct usb_bt_h4_config bt_h4_cfg = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define H4_CMD 0x01
|
|
||||||
#define H4_ACL 0x02
|
|
||||||
#define H4_SCO 0x03
|
|
||||||
#define H4_EVT 0x04
|
|
||||||
|
|
||||||
static struct usb_ep_cfg_data bt_h4_ep_data[] = {
|
static struct usb_ep_cfg_data bt_h4_ep_data[] = {
|
||||||
{
|
{
|
||||||
.ep_cb = usb_transfer_ep_callback,
|
.ep_cb = usb_transfer_ep_callback,
|
||||||
|
@ -137,29 +132,6 @@ static void bt_h4_read(u8_t ep, int size, void *priv)
|
||||||
BUF_SIZE, USB_TRANS_READ, bt_h4_read, buf);
|
BUF_SIZE, USB_TRANS_READ, bt_h4_read, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_h4_send(struct net_buf *buf)
|
|
||||||
{
|
|
||||||
LOG_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:
|
|
||||||
LOG_ERR("Unknown type %u", bt_buf_get_type(buf));
|
|
||||||
net_buf_unref(buf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
usb_transfer_sync(bt_h4_ep_data[BT_H4_IN_EP_IDX].ep_addr,
|
|
||||||
buf->data, buf->len, USB_TRANS_WRITE);
|
|
||||||
|
|
||||||
net_buf_unref(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hci_tx_thread(void)
|
static void hci_tx_thread(void)
|
||||||
{
|
{
|
||||||
LOG_DBG("Start USB Bluetooth thread");
|
LOG_DBG("Start USB Bluetooth thread");
|
||||||
|
@ -168,32 +140,10 @@ static void hci_tx_thread(void)
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
|
||||||
buf = net_buf_get(&tx_queue, K_FOREVER);
|
buf = net_buf_get(&tx_queue, K_FOREVER);
|
||||||
usb_h4_send(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usb_h4_recv(struct net_buf *buf)
|
usb_transfer_sync(bt_h4_ep_data[BT_H4_IN_EP_IDX].ep_addr,
|
||||||
{
|
buf->data, buf->len, USB_TRANS_WRITE);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
|
|
||||||
|
|
||||||
if (bt_send(buf)) {
|
|
||||||
LOG_ERR("Error sending to driver");
|
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +154,10 @@ static void hci_rx_thread(void)
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
|
||||||
buf = net_buf_get(&rx_queue, K_FOREVER);
|
buf = net_buf_get(&rx_queue, K_FOREVER);
|
||||||
usb_h4_recv(buf);
|
if (bt_send(buf)) {
|
||||||
|
LOG_ERR("Error sending to driver");
|
||||||
|
net_buf_unref(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue