Skip to content

usb: support Bluetooth controllers that are not interface 0 of a composite device - #997

Merged
zxzxwu merged 2 commits into
google:mainfrom
deadcaf3:fix-usb-composite-hci-commands
Oct 5, 2026
Merged

zxzxwu merged 2 commits into
google:mainfrom
deadcaf3:fix-usb-composite-hci-commands

Conversation

@deadcaf3

@deadcaf3 deadcaf3 commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #141.

Problem

With Zephyr's hci_usb sample built with CDC ACM (a composite device with CDC ACM
on interfaces 0 and 1 and Bluetooth on interface 2), the USB transport finds the
right endpoints, but the first HCI command fails and the app hangs:

!!! OUT transfer not completed: status=4

HCI commands were always sent as a class request addressed to the device with
wIndex=0. Zephyr's legacy USB device stack dispatches class requests by the
interface number in wIndex, so the command went to the CDC ACM function, which
stalled it.

Changes

  1. Address HCI commands to the controller's interface (bmRequestType=0x21,
    wIndex=<interface number>) when that interface is not 0, as specified in
    Core Spec Vol 4, Part B, 2.2.2. The request is unchanged when the controller
    is interface 0.
  2. Recognize composite devices that report the Miscellaneous device class (0xEF)
    in the usb:<index> lookup and in usb-probe. Such a device could previously
    only be opened by vendor and product ID.

Testing

nRF52840 dongle on macOS, usb: transport:

Firmware Layout Result
Zephyr v3.7.0 hci_usb with CDC ACM (legacy USB stack) class 0xEF, Bluetooth on interface 2 Before: HCI_Reset stalled and the app hung. After: controller_info works by ID and as usb:0, scan receives advertising reports
Prebuilt hci_usb.zip from the docs class 0x00, Bluetooth on interface 0 controller_info and scan work (request unchanged)

Unit tests cover both changes. invoke project.pre-commit passes.

Not addressed

  • The pyusb: transport still assumes interface 0 and fixed endpoint addresses,
    so it does not work with this layout.
  • The Rust usb probe has the same device class check.

…devices

HCI commands were always sent as a class request addressed to the device
with wIndex=0. Devices that route class requests by interface number, such
as Zephyr's legacy USB stack, hand such a request to whichever function
owns interface 0. In a composite device where the Bluetooth controller is
not the first interface (for example Zephyr's hci_usb sample built with
CDC ACM), the command is stalled and the host hangs:

  !!! OUT transfer not completed: status=4

When the controller's interface number is not 0, address the command to
that interface (bmRequestType=0x21, wIndex=interface number), as specified
in Core Spec Vol 4, Part B, 2.2.2. The request is unchanged when the
controller is interface 0.

Tested on an nRF52840 dongle running Zephyr v3.7.0 hci_usb with CDC ACM
(CDC ACM on interfaces 0 and 1, Bluetooth on interface 2): controller_info
and scan now work, where HCI_Reset was stalled before.

Fixes google#141
A composite device that uses interface associations reports the
Miscellaneous device class (0xEF) instead of 0x00. Such a device was not
recognized as a Bluetooth controller by the "usb:<index>" lookup or by
usb-probe, even when one of its interfaces has the Bluetooth class, so it
could only be opened with its vendor and product IDs.

Look for a Bluetooth interface when the device class is Miscellaneous, the
same way as when the class is defined per interface.

Tested on an nRF52840 dongle running Zephyr v3.7.0 hci_usb with CDC ACM,
which reports class 0xEF: usb-probe now lists it as "usb:0" and
controller_info opens it with that name.
@google-cla

google-cla Bot commented Oct 4, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@zxzxwu zxzxwu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@barbibulle barbibulle left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this fix.

@zxzxwu
zxzxwu merged commit 4748b0d into google:main Oct 5, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Issue while using NRF dongle with HCI_USB firmware

3 participants