blob: ae2e6307a5bc9a3b67470cbe9c26998e7e7846fd [file] [log] [blame]
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <device.h>
#include <uart.h>
#include <logging/sys_log.h>
#include <misc/util.h>
#include <net/buf.h>
#include <bluetooth/buf.h>
#include <bluetooth/hci_raw.h>
#include <bluetooth/l2cap.h>
#include "usb_device.h"
#include "usb_common.h"
#define BTUSB_BUFFER_SIZE 64
/* Max packet size for endpoints */
#define BTUSB_BULK_EP_MPS 64
#define BTUSB_ISO1_EP_MPS 0
#define BTUSB_ISO2_EP_MPS 9
#define BTUSB_ISO3_EP_MPS 17
#define BTUSB_ISO4_EP_MPS 25
#define BTUSB_ISO5_EP_MPS 33
#define BTUSB_ISO6_EP_MPS 49
/* Max packet size for Interrupt endpoints */
#define BTUSB_INTERRUPT_EP_MPS 16
/* Max Bluetooth command data size */
#define BTUSB_CLASS_MAX_DATA_SIZE 100
#define INTEL_VENDOR_ID 0x8086
#define PRODUCT_ID 0xFF02 /* TODO: Find better ID */
#define DEVICE_RELNUM 0x0100
#define BTUSB_NUM_CONF 1
#define BTUSB_NUM_ITF 2
/* Add also alternat interfaces */
#define BTUSB_NUM_ITF_TOTAL (BTUSB_NUM_ITF + 5)
#define BTUSB_IF1_NUM_EP 3
#define BTUSB_IF2_NUM_EP 2
/* Include all endpoints, also alternate configurations */
#define BTUSB_NUM_EP (BTUSB_IF1_NUM_EP + BTUSB_IF2_NUM_EP * 6)
#define BTUSB_ENDP_INT 0x81
#define BTUSB_ENDP_BULK_OUT 0x02
#define BTUSB_ENDP_BULK_IN 0x82
#define BTUSB_ENDP_ISO_OUT 0x03
#define BTUSB_ENDP_ISO_IN 0x83
#define BTUSB_CONF_SIZE (USB_CONFIGURATION_DESC_SIZE + \
(BTUSB_NUM_ITF_TOTAL * USB_INTERFACE_DESC_SIZE) + \
(BTUSB_NUM_EP * USB_ENDPOINT_DESC_SIZE))
/* Misc. macros */
#define LOW_BYTE(x) ((x) & 0xFF)
#define HIGH_BYTE(x) ((x) >> 8)
static struct device *btusb_dev;
#define DEV_DATA(dev) \
((struct btusb_dev_data_t * const)(dev)->driver_data)
static K_FIFO_DEFINE(rx_queue);
/* HCI command buffers */
#define CMD_BUF_SIZE BT_BUF_RX_SIZE
NET_BUF_POOL_DEFINE(tx_pool, CONFIG_BLUETOOTH_HCI_CMD_COUNT, CMD_BUF_SIZE,
sizeof(uint8_t), NULL);
#define BT_L2CAP_MTU 64
/** Data size needed for ACL buffers */
#define BT_BUF_ACL_SIZE BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU)
NET_BUF_POOL_DEFINE(acl_tx_pool, 2, BT_BUF_ACL_SIZE, sizeof(uint8_t), NULL);
/* Device data structure */
struct btusb_dev_data_t {
/* USB device status code */
enum usb_dc_status_code usb_status;
uint8_t interface_data[BTUSB_CLASS_MAX_DATA_SIZE];
uint8_t notification_sent;
};
/**
* Bluetooth USB descriptors configuration
*/
static const uint8_t btusb_desc[] = {
/* Device descriptor */
USB_DEVICE_DESC_SIZE, /* Descriptor size */
USB_DEVICE_DESC, /* Descriptor type */
LOW_BYTE(USB_1_1),
HIGH_BYTE(USB_1_1), /* USB version in BCD format */
WIRELESS_DEVICE_CLASS, /* Class */
RF_SUBCLASS, /* SubClass - Interface specific */
BLUETOOTH_PROTOCOL, /* Protocol - Interface specific */
MAX_PACKET_SIZE0, /* Max Packet Size */
LOW_BYTE(INTEL_VENDOR_ID),
HIGH_BYTE(INTEL_VENDOR_ID), /* Vendor Id */
LOW_BYTE(PRODUCT_ID),
HIGH_BYTE(PRODUCT_ID), /* Product Id */
LOW_BYTE(DEVICE_RELNUM),
HIGH_BYTE(DEVICE_RELNUM), /* Device Release Number */
/* Index of Manufacturer String Descriptor */
0x01,
/* Index of Product String Descriptor */
0x02,
/* Index of Serial Number String Descriptor */
0x03,
BTUSB_NUM_CONF, /* Number of Possible Configuration */
/* Configuration descriptor */
USB_CONFIGURATION_DESC_SIZE, /* Descriptor size */
USB_CONFIGURATION_DESC, /* Descriptor type */
/* Total length in bytes of data returned */
LOW_BYTE(BTUSB_CONF_SIZE),
HIGH_BYTE(BTUSB_CONF_SIZE),
BTUSB_NUM_ITF, /* Number of interfaces */
0x01, /* Configuration value */
0x00, /* Index of the Configuration string */
USB_CONFIGURATION_ATTRIBUTES, /* Attributes */
MAX_LOW_POWER, /* Max power consumption */
/* Interface descriptor 0 */
USB_INTERFACE_DESC_SIZE, /* Descriptor size */
USB_INTERFACE_DESC, /* Descriptor type */
0x00, /* Interface index */
0x00, /* Alternate setting */
BTUSB_IF1_NUM_EP, /* Number of Endpoints */
WIRELESS_DEVICE_CLASS, /* Class */
RF_SUBCLASS, /* SubClass */
BLUETOOTH_PROTOCOL, /* Protocol */
/* Index of the Interface String Descriptor */
0x00,
/* Endpoint INT */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_INT, /* Endpoint address */
USB_DC_EP_INTERRUPT, /* Attributes */
LOW_BYTE(BTUSB_INTERRUPT_EP_MPS),
HIGH_BYTE(BTUSB_INTERRUPT_EP_MPS),/* Max packet size */
0x01, /* Interval */
/* Endpoint OUT */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_BULK_OUT, /* Endpoint address */
USB_DC_EP_BULK, /* Attributes */
LOW_BYTE(BTUSB_BULK_EP_MPS),
HIGH_BYTE(BTUSB_BULK_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Endpoint IN */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_BULK_IN, /* Endpoint address */
USB_DC_EP_BULK, /* Attributes */
LOW_BYTE(BTUSB_BULK_EP_MPS),
HIGH_BYTE(BTUSB_BULK_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Interface descriptor 1:0 */
USB_INTERFACE_DESC_SIZE, /* Descriptor size */
USB_INTERFACE_DESC, /* Descriptor type */
0x01, /* Interface index */
0x00, /* Alternate setting */
BTUSB_IF2_NUM_EP, /* Number of Endpoints */
WIRELESS_DEVICE_CLASS, /* Class */
RF_SUBCLASS, /* SubClass */
BLUETOOTH_PROTOCOL, /* Protocol */
/* Index of the Interface String Descriptor */
0x00,
/* Endpoint OUT */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_OUT, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO1_EP_MPS),
HIGH_BYTE(BTUSB_ISO1_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Endpoint IN */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_IN, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO1_EP_MPS),
HIGH_BYTE(BTUSB_ISO1_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Interface descriptor 1:1 */
USB_INTERFACE_DESC_SIZE, /* Descriptor size */
USB_INTERFACE_DESC, /* Descriptor type */
0x01, /* Interface index */
0x01, /* Alternate setting */
BTUSB_IF2_NUM_EP, /* Number of Endpoints */
WIRELESS_DEVICE_CLASS, /* Class */
RF_SUBCLASS, /* SubClass */
BLUETOOTH_PROTOCOL, /* Protocol */
/* Index of the Interface String Descriptor */
0x00,
/* Endpoint OUT */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_OUT, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO2_EP_MPS),
HIGH_BYTE(BTUSB_ISO2_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Endpoint IN */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_IN, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO2_EP_MPS),
HIGH_BYTE(BTUSB_ISO2_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Interface descriptor 1:2 */
USB_INTERFACE_DESC_SIZE, /* Descriptor size */
USB_INTERFACE_DESC, /* Descriptor type */
0x01, /* Interface index */
0x02, /* Alternate setting */
BTUSB_IF2_NUM_EP, /* Number of Endpoints */
WIRELESS_DEVICE_CLASS, /* Class */
RF_SUBCLASS, /* SubClass */
BLUETOOTH_PROTOCOL, /* Protocol */
/* Index of the Interface String Descriptor */
0x00,
/* Endpoint OUT */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_OUT, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO3_EP_MPS),
HIGH_BYTE(BTUSB_ISO3_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Endpoint IN */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_IN, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO3_EP_MPS),
HIGH_BYTE(BTUSB_ISO3_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Interface descriptor 1:3 */
USB_INTERFACE_DESC_SIZE, /* Descriptor size */
USB_INTERFACE_DESC, /* Descriptor type */
0x01, /* Interface index */
0x03, /* Alternate setting */
BTUSB_IF2_NUM_EP, /* Number of Endpoints */
WIRELESS_DEVICE_CLASS, /* Class */
RF_SUBCLASS, /* SubClass */
BLUETOOTH_PROTOCOL, /* Protocol */
/* Index of the Interface String Descriptor */
0x00,
/* Endpoint OUT */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_OUT, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO4_EP_MPS),
HIGH_BYTE(BTUSB_ISO4_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Endpoint IN */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_IN, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO4_EP_MPS),
HIGH_BYTE(BTUSB_ISO4_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Interface descriptor 1:4 */
USB_INTERFACE_DESC_SIZE, /* Descriptor size */
USB_INTERFACE_DESC, /* Descriptor type */
0x01, /* Interface index */
0x04, /* Alternate setting */
BTUSB_IF2_NUM_EP, /* Number of Endpoints */
WIRELESS_DEVICE_CLASS, /* Class */
RF_SUBCLASS, /* SubClass */
BLUETOOTH_PROTOCOL, /* Protocol */
/* Index of the Interface String Descriptor */
0x00,
/* Endpoint OUT */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_OUT, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO5_EP_MPS),
HIGH_BYTE(BTUSB_ISO5_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Endpoint IN */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_IN, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO5_EP_MPS),
HIGH_BYTE(BTUSB_ISO5_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Interface descriptor 1:5 */
USB_INTERFACE_DESC_SIZE, /* Descriptor size */
USB_INTERFACE_DESC, /* Descriptor type */
0x01, /* Interface index */
0x05, /* Alternate setting */
BTUSB_IF2_NUM_EP, /* Number of Endpoints */
WIRELESS_DEVICE_CLASS, /* Class */
RF_SUBCLASS, /* SubClass */
BLUETOOTH_PROTOCOL, /* Protocol */
/* Index of the Interface String Descriptor */
0x00,
/* Endpoint OUT */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_OUT, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO6_EP_MPS),
HIGH_BYTE(BTUSB_ISO6_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* Endpoint IN */
USB_ENDPOINT_DESC_SIZE, /* Descriptor size */
USB_ENDPOINT_DESC, /* Descriptor type */
BTUSB_ENDP_ISO_IN, /* Endpoint address */
USB_DC_EP_ISOCHRONOUS, /* Attributes */
LOW_BYTE(BTUSB_ISO6_EP_MPS),
HIGH_BYTE(BTUSB_ISO6_EP_MPS), /* Max packet size */
0x01, /* Interval */
/* String descriptor language, only one, so min size 4 bytes.
* 0x0409 English(US) language code used
*/
USB_STRING_DESC_SIZE, /* Descriptor size */
USB_STRING_DESC, /* Descriptor type */
0x09,
0x04,
/* Manufacturer String Descriptor "Intel" */
0x0C,
USB_STRING_DESC,
'I', 0, 'n', 0, 't', 0, 'e', 0, 'l', 0,
/* Product String Descriptor */
0x10,
USB_STRING_DESC,
'Q', 0, 'U', 0, 'A', 0, 'R', 0, 'Q', 0, 'B', 0, 'T', 0,
/* Serial Number String Descriptor "00.01" */
0x0C,
USB_STRING_DESC,
'0', 0, '0', 0, '.', 0, '0', 0, '1', 0,
};
/* TODO: move to standard utils */
static void hexdump(const char *str, const uint8_t *packet, size_t length)
{
int n = 0;
if (!length) {
printf("%s zero-length signal packet\n", str);
return;
}
while (length--) {
if (n % 16 == 0) {
printf("%s %08X ", str, n);
}
printf("%02X ", *packet++);
n++;
if (n % 8 == 0) {
if (n % 16 == 0) {
printf("\n");
} else {
printf(" ");
}
}
}
if (n % 16) {
printf("\n");
}
}
static void btusb_int_in(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
{
SYS_LOG_DBG("ep %x status %d", ep, ep_status);
}
/* EP Bulk OUT handler, used to read the data received from the Host */
static void btusb_bulk_out(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
{
struct net_buf *buf;
uint32_t len, read = 0;
uint8_t tmp[4];
SYS_LOG_DBG("ep %x status %d", ep, ep_status);
/* Read number of butes to read */
usb_read(ep, NULL, 0, &len);
if (!len || len > BT_BUF_ACL_SIZE) {
SYS_LOG_ERR("Incorrect length: %u\n", len);
return;
}
buf = net_buf_alloc(&acl_tx_pool, K_NO_WAIT);
if (!buf) {
SYS_LOG_ERR("Cannot get free buffer\n");
return;
}
/**
* Quark SE USB controller is always storing data
* in the FIFOs per 32-bit words.
*/
while (len > buf->len) {
usb_read(ep, tmp, 4, NULL);
read += 4;
if (len > read) {
net_buf_add_mem(buf, tmp, 4);
} else {
uint8_t remains = 4 - (read - len);
net_buf_add_mem(buf, tmp, remains);
}
}
hexdump(">", buf->data, buf->len);
bt_buf_set_type(buf, BT_BUF_ACL_OUT);
bt_send(buf);
}
/* EP Bulk IN handler, used to send data to the Host */
static void btusb_bulk_in(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
{
SYS_LOG_ERR("Not implemented");
}
/* EP ISO OUT handler, used to read the data received from the Host */
static void btusb_iso_out(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
{
SYS_LOG_ERR("Not implemented");
}
/* EP ISO IN handler, used to send data to the Host */
static void btusb_iso_in(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
{
SYS_LOG_ERR("Not implemented");
}
/* Describe EndPoints configuration */
static struct usb_ep_cfg_data btusb_ep[] = {
{
.ep_cb = btusb_int_in,
.ep_addr = BTUSB_ENDP_INT
},
{
.ep_cb = btusb_bulk_out,
.ep_addr = BTUSB_ENDP_BULK_OUT
},
{
.ep_cb = btusb_bulk_in,
.ep_addr = BTUSB_ENDP_BULK_IN
},
{
.ep_cb = btusb_iso_out,
.ep_addr = BTUSB_ENDP_ISO_OUT
},
{
.ep_cb = btusb_iso_in,
.ep_addr = BTUSB_ENDP_ISO_IN
},
#if 0
/* FIXME: check endpoints */
/* Alt 1 */
{
.ep_cb = btusb_iso_out,
.ep_addr = BTUSB_ENDP_ISO_OUT
},
{
.ep_cb = btusb_iso_in,
.ep_addr = BTUSB_ENDP_ISO_IN
},
/* Alt 2 */
{
.ep_cb = btusb_iso_out,
.ep_addr = BTUSB_ENDP_ISO_OUT
},
{
.ep_cb = btusb_iso_in,
.ep_addr = BTUSB_ENDP_ISO_IN
},
/* Alt 3 */
{
.ep_cb = btusb_iso_out,
.ep_addr = BTUSB_ENDP_ISO_OUT
},
{
.ep_cb = btusb_iso_in,
.ep_addr = BTUSB_ENDP_ISO_IN
},
/* Alt 4 */
{
.ep_cb = btusb_iso_out,
.ep_addr = BTUSB_ENDP_ISO_OUT
},
{
.ep_cb = btusb_iso_in,
.ep_addr = BTUSB_ENDP_ISO_IN
},
/* Alt 5 */
{
.ep_cb = btusb_iso_out,
.ep_addr = BTUSB_ENDP_ISO_OUT
},
{
.ep_cb = btusb_iso_in,
.ep_addr = BTUSB_ENDP_ISO_IN
},
#endif
};
static void btusb_status_cb(enum usb_dc_status_code status)
{
struct btusb_dev_data_t * const dev_data = DEV_DATA(btusb_dev);
/* Store the new status */
dev_data->usb_status = status;
/* Check the USB status and do needed action if required */
switch (status) {
case USB_DC_ERROR:
SYS_LOG_DBG("USB device error");
break;
case USB_DC_RESET:
SYS_LOG_DBG("USB device reset detected");
break;
case USB_DC_CONNECTED:
SYS_LOG_DBG("USB device connected");
break;
case USB_DC_CONFIGURED:
SYS_LOG_DBG("USB device configured");
break;
case USB_DC_DISCONNECTED:
SYS_LOG_DBG("USB device disconnected");
break;
case USB_DC_SUSPEND:
SYS_LOG_DBG("USB device supended");
break;
case USB_DC_RESUME:
SYS_LOG_DBG("USB device resumed");
break;
case USB_DC_UNKNOWN:
default:
SYS_LOG_DBG("USB unknown state");
break;
}
}
static int btusb_class_handler(struct usb_setup_packet *setup,
int32_t *len, uint8_t **data)
{
struct net_buf *buf;
if (!*len || *len > CMD_BUF_SIZE) {
SYS_LOG_ERR("Incorrect length: %d\n", *len);
return -EINVAL;
}
hexdump(">", *data, *len);
buf = net_buf_alloc(&tx_pool, K_NO_WAIT);
if (!buf) {
SYS_LOG_ERR("Cannot get free buffer\n");
return -ENOMEM;
}
bt_buf_set_type(buf, BT_BUF_CMD);
net_buf_add_mem(buf, *data, *len);
bt_send(buf);
return 0;
}
static struct usb_cfg_data btusb_config = {
.usb_device_description = btusb_desc,
.cb_usb_status = btusb_status_cb,
.interface = {
.class_handler = btusb_class_handler,
.custom_handler = NULL,
},
.num_endpoints = ARRAY_SIZE(btusb_ep),
.endpoint = btusb_ep,
};
static int btusb_init(struct device *dev)
{
struct btusb_dev_data_t * const dev_data = DEV_DATA(dev);
int ret;
btusb_config.interface.payload_data = dev_data->interface_data;
btusb_dev = dev;
/* Initialize the USB driver with the right configuration */
ret = usb_set_config(&btusb_config);
if (ret < 0) {
SYS_LOG_ERR("Failed to config USB");
return ret;
}
/* Enable USB driver */
ret = usb_enable(&btusb_config);
if (ret < 0) {
SYS_LOG_ERR("Failed to enable USB");
return ret;
}
return 0;
}
static struct btusb_dev_data_t btusb_dev_data = {
.usb_status = USB_DC_UNKNOWN,
};
DEVICE_INIT(btusb, "btusb", &btusb_init,
&btusb_dev_data, NULL,
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
static int try_write(uint8_t ep, struct net_buf *buf)
{
while (1) {
int ret = usb_write(ep, buf->data, buf->len, NULL);
switch (ret) {
case -EAGAIN:
break;
/* TODO: Handle other error codes */
default:
return ret;
}
}
}
void main(void)
{
SYS_LOG_DBG("Start");
bt_enable_raw(&rx_queue);
while (1) {
struct net_buf *buf;
buf = net_buf_get(&rx_queue, K_FOREVER);
hexdump("<", buf->data, buf->len);
switch (bt_buf_get_type(buf)) {
case BT_BUF_EVT:
try_write(BTUSB_ENDP_INT, buf);
break;
case BT_BUF_ACL_IN:
try_write(BTUSB_ENDP_BULK_IN, buf);
break;
default:
SYS_LOG_ERR("Unknown type %u", bt_buf_get_type(buf));
break;
}
net_buf_unref(buf);
}
}