Repository navigation
usb: support Bluetooth controllers that are not interface 0 of a composite device - #997
Merged
Merged
Conversation
…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.
|
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. |
barbibulle
approved these changes
Oct 5, 2026
barbibulle
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for this fix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #141.
Problem
With Zephyr's
hci_usbsample built with CDC ACM (a composite device with CDC ACMon 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:
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 theinterface number in
wIndex, so the command went to the CDC ACM function, whichstalled it.
Changes
bmRequestType=0x21,wIndex=<interface number>) when that interface is not 0, as specified inCore Spec Vol 4, Part B, 2.2.2. The request is unchanged when the controller
is interface 0.
in the
usb:<index>lookup and inusb-probe. Such a device could previouslyonly be opened by vendor and product ID.
Testing
nRF52840 dongle on macOS,
usb:transport:hci_usbwith CDC ACM (legacy USB stack)HCI_Resetstalled and the app hung. After:controller_infoworks by ID and asusb:0,scanreceives advertising reportshci_usb.zipfrom the docscontroller_infoandscanwork (request unchanged)Unit tests cover both changes.
invoke project.pre-commitpasses.Not addressed
pyusb:transport still assumes interface 0 and fixed endpoint addresses,so it does not work with this layout.
usb probehas the same device class check.