Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for multiple device configurations #150

Open
ia0 opened this issue May 2, 2024 · 8 comments
Open

Support for multiple device configurations #150

ia0 opened this issue May 2, 2024 · 8 comments

Comments

@ia0
Copy link
Contributor

ia0 commented May 2, 2024

Am I understanding correctly that the UsbBusAllocator and UsbDeviceBuilder APIs don't support creating a device with multiple USB configurations? For example a device that would look like this:

  • Configuration 1:
    • Interface 1
  • Configuration 2:
    • Interface 1
    • Interface 2
@mvirkkunen
Copy link
Collaborator

Correct, multiple configurations are not supported because I originally deemed that something that is not very useful in practice and I left out the complexity.

What were you looking to implement with multiple configurations?

@ia0
Copy link
Contributor Author

ia0 commented May 2, 2024

Thanks for the quick answer!

The use-case I have in mind is a device with the default configuration for applet interfaces (not familiar enough with USB to know if there is such a notion of default configuration) and an alternative configuration with a platform interface. Applet interfaces could be like USB serial or some HID interface, while the platform interface provides a way to install/uninstall/update applets or update the platform itself (or other platform-level operations). Currently, I have a single configuration with all interfaces (applet interfaces and platform interface). This works fine, but I was wondering if I should also provide a way to have the platform interface in its own configuration, and was looking if it was at all possible.

As you can see, this is not motivated by a concrete use-case, but just as an exploration of what would be possible. I understand the goal of keeping usb-device simple, so this is fine for me to close this issue. If I ever have a concrete use-case I would reopen or create a new issue.

@mvirkkunen
Copy link
Collaborator

Most practical devices I've seen that completely switch modes for e.g. firmware update (kind of what you're planning) just de-enumerate and then re-enumerate as a different device altogether (different VID:PID, different singular configuration). I think that has a better chance of working with operating systems and drivers and it is doable with usb-device.

@ia0
Copy link
Contributor Author

ia0 commented May 2, 2024

Yes, I also thought about doing that. The problem is that this needs cooperation from the applets (which are not necessarily trusted or considered reliable). So for it work, there must be some physical input (like a button or a power cycle) to tell the platform to switch the exposed device from applets to platform. But I agree that this would probably be a better alternative even with this issue.

@mvirkkunen
Copy link
Collaborator

If you assume running those applets might make your device not respond to USB events anymore, it wouldn't be able to respond to the request to change configuration either though.

@ia0
Copy link
Contributor Author

ia0 commented May 2, 2024

The USB drivers are implemented in the platform (applets can only select from a subset of those and can't influence the USB behavior outside of the API provided by the driver). So I don't think that this should be an issue.

@mvirkkunen
Copy link
Collaborator

If the platform thing is always available, you vould make it always respond to e.g. a specific control transfer that resets the device into "platform mode"

@ia0
Copy link
Contributor Author

ia0 commented May 2, 2024

If I understand correctly, this would essentially be a vendor way of implementing configurations. SetConfiguration would just be a control transfer asking to the device to USB reset into a different USB device.

I think I get the high-level idea, but I'm still missing the details. Here is how I see it:

  • The host sends a (Host to Device, Vendor, Device) Setup packet with some data asking to change "configuration". I see how to do that with the rusb crate which I use.
  • On the device, whenever I poll the UsbDevice, regardless of its result, I should read the control pipe if something was returned. To do that, I use the UsbDevice::bus() function to access the bus and then UsbBus::read() to read the control pipe directly from the bus.
  • If it's a request to reset, I drop everything (the UsbDevice and the UsbBusAllocator) and recreate a new UsbBus (cheating on ownership since the device was lost with the UsbBusAllocator), UsbBusAllocator, and finally UsbDevice, then call UsbDevice::force_reset() to make sure the device gets re-enumerated.

Does this sound like what you had in mind?

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

No branches or pull requests

2 participants