Browse Source

Bluetooth: Remove USB H4 mode support

This non-standard feature never had any proper host side implementation
(e.g. it was never upstreamed to BlueZ), and since it comes with notable
maintenance overhead it's fair to just remove it.

Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
pull/89252/head
Johan Hedberg 3 months ago committed by Benjamin Cabé
parent
commit
f85d63a6cc
  1. 1
      samples/bluetooth/hci_usb/prj.conf
  2. 14
      subsys/bluetooth/controller/hci/hci.c
  3. 11
      subsys/usb/device/class/Kconfig.bt
  4. 140
      subsys/usb/device/class/bluetooth.c
  5. 52
      subsys/usb/device_next/class/bt_hci.c

1
samples/bluetooth/hci_usb/prj.conf

@ -4,7 +4,6 @@ CONFIG_BT_HCI_RAW=y @@ -4,7 +4,6 @@ CONFIG_BT_HCI_RAW=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PID=0x000B
CONFIG_USB_DEVICE_BLUETOOTH=y
CONFIG_USB_DEVICE_BLUETOOTH_VS_H4=n
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
# We dont want any console or CDC ACM that may cause BlueZ to not detect hci_usb

14
subsys/bluetooth/controller/hci/hci.c

@ -5051,12 +5051,6 @@ static void vs_read_supported_commands(struct net_buf *buf, @@ -5051,12 +5051,6 @@ static void vs_read_supported_commands(struct net_buf *buf,
/* Write Tx Power, Read Tx Power */
rp->commands[1] |= BIT(5) | BIT(6);
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
#if defined(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4)
/* Read Supported USB Transport Modes */
rp->commands[1] |= BIT(7);
/* Set USB Transport Mode */
rp->commands[2] |= BIT(0);
#endif /* USB_DEVICE_BLUETOOTH_VS_H4 */
}
static void vs_read_supported_features(struct net_buf *buf,
@ -5698,14 +5692,6 @@ int hci_vendor_cmd_handle_common(uint16_t ocf, struct net_buf *cmd, @@ -5698,14 +5692,6 @@ int hci_vendor_cmd_handle_common(uint16_t ocf, struct net_buf *cmd,
vs_read_supported_features(cmd, evt);
break;
#if defined(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4)
case BT_OCF(BT_HCI_OP_VS_READ_USB_TRANSPORT_MODE):
break;
case BT_OCF(BT_HCI_OP_VS_SET_USB_TRANSPORT_MODE):
reset(cmd, evt);
break;
#endif /* CONFIG_USB_DEVICE_BLUETOOTH_VS_H4 */
case BT_OCF(BT_HCI_OP_VS_READ_BUILD_INFO):
vs_read_build_info(cmd, evt);
break;

11
subsys/usb/device/class/Kconfig.bt

@ -1,18 +1,9 @@ @@ -1,18 +1,9 @@
# Copyright (c) 2016 Wind River Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
menuconfig USB_DEVICE_BLUETOOTH
config USB_DEVICE_BLUETOOTH
bool "USB Bluetooth Device Class support"
select BT
select BT_HCI_RAW
help
USB Bluetooth device class support
config USB_DEVICE_BLUETOOTH_VS_H4
bool "USB Bluetooth H4 vendor command"
depends on USB_DEVICE_BLUETOOTH
select BT_HCI_RAW_H4
select BT_HCI_RAW_CMD_EXT
help
Enables vendor command to switch to H:4 transport using the bulk
endpoint.

140
subsys/usb/device/class/bluetooth.c

@ -42,6 +42,7 @@ static struct k_thread tx_thread_data; @@ -42,6 +42,7 @@ static struct k_thread tx_thread_data;
/* HCI USB state flags */
static bool configured;
/*
* Shared variable between bluetooth_status_cb() and hci_tx_thread(),
* where hci_tx_thread() has read-only access to it.
@ -132,15 +133,10 @@ static void hci_tx_thread(void *p1, void *p2, void *p3) @@ -132,15 +133,10 @@ static void hci_tx_thread(void *p1, void *p2, void *p3)
while (true) {
struct net_buf *buf;
uint8_t type;
buf = k_fifo_get(&tx_queue, K_FOREVER);
if (IS_ENABLED(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4) &&
bt_hci_raw_get_mode() == BT_HCI_RAW_MODE_H4) {
/* Force to sent over bulk if H4 is selected */
bt_buf_set_type(buf, BT_BUF_ACL_IN);
}
if (atomic_get(&suspended)) {
if (usb_wakeup_request()) {
LOG_DBG("Remote wakeup not enabled/supported");
@ -156,7 +152,8 @@ static void hci_tx_thread(void *p1, void *p2, void *p3) @@ -156,7 +152,8 @@ static void hci_tx_thread(void *p1, void *p2, void *p3)
}
}
switch (bt_buf_get_type(buf)) {
type = net_buf_pull_u8(buf);
switch (type) {
case BT_BUF_EVT:
usb_transfer_sync(
bluetooth_ep_data[HCI_INT_EP_IDX].ep_addr,
@ -170,7 +167,7 @@ static void hci_tx_thread(void *p1, void *p2, void *p3) @@ -170,7 +167,7 @@ static void hci_tx_thread(void *p1, void *p2, void *p3)
USB_TRANS_WRITE);
break;
default:
LOG_ERR("Unknown type %u", bt_buf_get_type(buf));
LOG_ERR("Unknown type %u", type);
break;
}
@ -198,43 +195,18 @@ static void hci_rx_thread(void *p1, void *p2, void *p3) @@ -198,43 +195,18 @@ static void hci_rx_thread(void *p1, void *p2, void *p3)
}
}
static uint16_t hci_pkt_get_len(struct net_buf *buf,
const uint8_t *data, size_t size)
static uint16_t hci_acl_pkt_len(const uint8_t *data, size_t data_len)
{
uint16_t len = 0;
size_t hdr_len = 0;
switch (bt_buf_get_type(buf)) {
case BT_BUF_CMD: {
struct bt_hci_cmd_hdr *cmd_hdr;
hdr_len = sizeof(*cmd_hdr);
cmd_hdr = (struct bt_hci_cmd_hdr *)data;
len = cmd_hdr->param_len + hdr_len;
break;
}
case BT_BUF_ACL_OUT: {
struct bt_hci_acl_hdr *acl_hdr;
hdr_len = sizeof(*acl_hdr);
acl_hdr = (struct bt_hci_acl_hdr *)data;
len = sys_le16_to_cpu(acl_hdr->len) + hdr_len;
break;
}
case BT_BUF_ISO_OUT: {
struct bt_hci_iso_hdr *iso_hdr;
struct bt_hci_acl_hdr *acl_hdr;
size_t hdr_len = sizeof(*acl_hdr);
hdr_len = sizeof(*iso_hdr);
iso_hdr = (struct bt_hci_iso_hdr *)data;
len = bt_iso_hdr_len(sys_le16_to_cpu(iso_hdr->len)) + hdr_len;
break;
}
default:
LOG_ERR("Unknown bt buffer type");
if (data_len - 1 < hdr_len) {
return 0;
}
return (size < hdr_len) ? 0 : len;
acl_hdr = (struct bt_hci_acl_hdr *)(data + 1);
return sys_le16_to_cpu(acl_hdr->len) + hdr_len;
}
static void acl_read_cb(uint8_t ep, int size, void *priv)
@ -248,32 +220,15 @@ static void acl_read_cb(uint8_t ep, int size, void *priv) @@ -248,32 +220,15 @@ static void acl_read_cb(uint8_t ep, int size, void *priv)
}
if (buf == NULL) {
/*
* Obtain the first chunk and determine the length
* of the HCI packet.
*/
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);
if (!buf) {
LOG_ERR("Failed to allocate buffer");
goto restart_out_transfer;
}
pkt_len = hci_pkt_get_len(buf, &data[1], size - 1);
LOG_DBG("pkt_len %u, chunk %u", pkt_len, size);
} else {
buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_FOREVER,
data, size);
if (!buf) {
LOG_ERR("Failed to allocate buffer");
goto restart_out_transfer;
}
pkt_len = hci_pkt_get_len(buf, data, size);
LOG_DBG("pkt_len %u, chunk %u", pkt_len, size);
buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_FOREVER, data, size);
if (!buf) {
LOG_ERR("Failed to allocate buffer");
goto restart_out_transfer;
}
pkt_len = hci_acl_pkt_len(data, size);
LOG_DBG("pkt_len %u, chunk %u", pkt_len, size);
if (pkt_len == 0) {
LOG_ERR("Failed to get packet length");
net_buf_unref(buf);
@ -359,59 +314,6 @@ static void bluetooth_status_cb(struct usb_cfg_data *cfg, @@ -359,59 +314,6 @@ static void bluetooth_status_cb(struct usb_cfg_data *cfg,
}
}
static uint8_t vs_read_usb_transport_mode(struct net_buf *buf)
{
struct net_buf *rsp;
struct bt_hci_rp_vs_read_usb_transport_mode *rp;
rsp = bt_hci_cmd_complete_create(BT_HCI_OP_VS_READ_USB_TRANSPORT_MODE,
sizeof(*rp) + 2);
rp = net_buf_add(rsp, sizeof(*rp));
rp->status = BT_HCI_ERR_SUCCESS;
rp->num_supported_modes = 2;
net_buf_add_u8(rsp, BT_HCI_VS_USB_H2_MODE);
net_buf_add_u8(rsp, BT_HCI_VS_USB_H4_MODE);
k_fifo_put(&tx_queue, rsp);
return BT_HCI_ERR_EXT_HANDLED;
}
static uint8_t vs_set_usb_transport_mode(struct net_buf *buf)
{
struct bt_hci_cp_vs_set_usb_transport_mode *cp;
uint8_t mode;
cp = net_buf_pull_mem(buf, sizeof(*cp));
switch (cp->mode) {
case BT_HCI_VS_USB_H2_MODE:
mode = BT_HCI_RAW_MODE_PASSTHROUGH;
break;
case BT_HCI_VS_USB_H4_MODE:
mode = BT_HCI_RAW_MODE_H4;
break;
default:
LOG_DBG("Invalid mode: %u", cp->mode);
return BT_HCI_ERR_INVALID_PARAM;
}
LOG_DBG("mode %u", mode);
bt_hci_raw_set_mode(mode);
return BT_HCI_ERR_SUCCESS;
}
static struct bt_hci_raw_cmd_ext cmd_ext[] = {
BT_HCI_RAW_CMD_EXT(BT_OCF(BT_HCI_OP_VS_READ_USB_TRANSPORT_MODE), 0,
vs_read_usb_transport_mode),
BT_HCI_RAW_CMD_EXT(BT_OCF(BT_HCI_OP_VS_SET_USB_TRANSPORT_MODE),
sizeof(struct bt_hci_cp_vs_set_usb_transport_mode),
vs_set_usb_transport_mode),
};
static int bluetooth_class_handler(struct usb_setup_packet *setup,
int32_t *len, uint8_t **data)
{
@ -469,10 +371,6 @@ static int bluetooth_init(void) @@ -469,10 +371,6 @@ static int bluetooth_init(void)
return ret;
}
if (IS_ENABLED(CONFIG_USB_DEVICE_BLUETOOTH_VS_H4)) {
bt_hci_raw_cmd_ext_register(cmd_ext, ARRAY_SIZE(cmd_ext));
}
k_thread_create(&rx_thread_data, rx_thread_stack,
K_KERNEL_STACK_SIZEOF(rx_thread_stack),
hci_rx_thread, NULL, NULL, NULL,

52
subsys/usb/device_next/class/bt_hci.c

@ -203,11 +203,13 @@ static void bt_hci_tx_thread(void *p1, void *p2, void *p3) @@ -203,11 +203,13 @@ static void bt_hci_tx_thread(void *p1, void *p2, void *p3)
while (true) {
struct net_buf *bt_buf;
uint8_t type;
uint8_t ep;
bt_buf = k_fifo_get(&bt_hci_tx_queue, K_FOREVER);
type = net_buf_pull_u8(bt_buf);
switch (bt_buf_get_type(bt_buf)) {
switch (type) {
case BT_BUF_EVT:
ep = bt_hci_get_int_in(c_data);
break;
@ -215,11 +217,10 @@ static void bt_hci_tx_thread(void *p1, void *p2, void *p3) @@ -215,11 +217,10 @@ static void bt_hci_tx_thread(void *p1, void *p2, void *p3)
ep = bt_hci_get_bulk_in(c_data);
break;
default:
LOG_ERR("Unknown type %u", bt_buf_get_type(bt_buf));
LOG_ERR("Unknown type %u", type);
continue;
}
bt_hci_tx_sync_in(c_data, bt_buf, ep);
net_buf_unref(bt_buf);
}
@ -272,43 +273,19 @@ static int bt_hci_acl_out_start(struct usbd_class_data *const c_data) @@ -272,43 +273,19 @@ static int bt_hci_acl_out_start(struct usbd_class_data *const c_data)
return ret;
}
static uint16_t hci_pkt_get_len(struct net_buf *const buf,
const uint8_t *data, const size_t size)
static uint16_t hci_acl_pkt_len(struct net_buf *const buf)
{
size_t hdr_len = 0;
uint16_t len = 0;
switch (bt_buf_get_type(buf)) {
case BT_BUF_CMD: {
struct bt_hci_cmd_hdr *cmd_hdr;
struct bt_hci_acl_hdr *acl_hdr;
size_t hdr_len;
hdr_len = sizeof(*cmd_hdr);
cmd_hdr = (struct bt_hci_cmd_hdr *)data;
len = cmd_hdr->param_len + hdr_len;
break;
}
case BT_BUF_ACL_OUT: {
struct bt_hci_acl_hdr *acl_hdr;
hdr_len = sizeof(*acl_hdr);
acl_hdr = (struct bt_hci_acl_hdr *)data;
len = sys_le16_to_cpu(acl_hdr->len) + hdr_len;
break;
}
case BT_BUF_ISO_OUT: {
struct bt_hci_iso_hdr *iso_hdr;
hdr_len = sizeof(*iso_hdr);
iso_hdr = (struct bt_hci_iso_hdr *)data;
len = bt_iso_hdr_len(sys_le16_to_cpu(iso_hdr->len)) + hdr_len;
break;
}
default:
LOG_ERR("Unknown BT buffer type");
hdr_len = sizeof(*acl_hdr);
if (buf->len - 1 < hdr_len) {
return 0;
}
return (size < hdr_len) ? 0 : len;
acl_hdr = (struct bt_hci_acl_hdr *)(buf->data + 1);
return sys_le16_to_cpu(acl_hdr->len) + hdr_len;
}
static int bt_hci_acl_out_cb(struct usbd_class_data *const c_data,
@ -328,9 +305,8 @@ static int bt_hci_acl_out_cb(struct usbd_class_data *const c_data, @@ -328,9 +305,8 @@ static int bt_hci_acl_out_cb(struct usbd_class_data *const c_data,
goto restart_out_transfer;
}
hci_data->acl_len = hci_pkt_get_len(hci_data->acl_buf,
buf->data,
buf->len);
hci_data->acl_len = hci_acl_pkt_len(hci_data->acl_buf);
LOG_DBG("acl_len %u, chunk %u", hci_data->acl_len, buf->len);
if (hci_data->acl_len == 0) {

Loading…
Cancel
Save