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

WebUSB implementation #2862

Merged
merged 1 commit into from
Apr 28, 2024
Merged

Conversation

chmanie
Copy link
Contributor

@chmanie chmanie commented Apr 23, 2024

I created an implementation for the WebUSB spec that can be found here: https://wicg.github.io/webusb/.

This is a rough draft and I just wanted to get a feel for whether you'd be willing to consider this functionality as a part of embassy.
I tried to stay as close to the current class implementations as possible and use existing APIs as much as I could (there's a notable exception - bos_capability, see the comment below).

If you feel like this would be a valuable addition, I'll clean it up a bit more and add documentation for it.

@@ -417,6 +417,10 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> {
self.builder.config_descriptor.write(descriptor_type, descriptor);
}

pub fn bos_capability(&mut self, capability_type: u8, capability: &[u8]) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the only piece I had to add to the builder. I'm not sure if this is the best spot to add it but I needed a way to add BOS capabilities within the interface API.

@chemicstry
Copy link
Contributor

chemicstry commented Apr 24, 2024

Nice!

Is there a reason for allocating in/out endpoints and echoing of webusb packets? AFAIK webusb only needs descriptors, it doesn't use endpoints and doesn't send/receive any data. You use webusb descriptors to throw a notification linking to URL and then use other protocols for communication (CDC, DFU, etc).

@chmanie
Copy link
Contributor Author

chmanie commented Apr 25, 2024

Is there a reason for allocating in/out endpoints and echoing of webusb packets?

Hey, thank you so much for giving this a look!

WebUSB does indeed support data transfer and endpoints (see https://wicg.github.io/webusb/#device-usage). The endpoints I implemented here enable the device.transferIn and device.transferOut methods on the browser side. The echoing is just in the example to demonstrate that capability.

The creation of exactly these two endpoints is indeed kind of arbitrary. There might be the need for only a read or only a write endpoint on the device (or even more endpoints). However, with the current API (the Builder and the InetfaceBuilders), such functionality can not easily be exposed to the user (as everything depends on the order of the descriptors generated). Currently I have no idea how something like that could be implemented (maybe provide a mutable array that is filled with endpoints? - kind of ugly though).

@chmanie chmanie marked this pull request as ready for review April 27, 2024 20:01
@chmanie
Copy link
Contributor Author

chmanie commented Apr 27, 2024

Just to keep the conversation going, I unleashed this PR out of draft mode, added all the documentation and improved the API around the URL a bit. Let me know what you think :)

@chemicstry
Copy link
Contributor

Please someone correct me if I am wrong, but normally you would use a regular USB class (i.e. CDC-ACM, HID, DFU etc), which defines protocol and USB endpoints that it uses. You then add WebUSB descriptors just for the OS notification and redirection to your URL, no additional endpoints are used for this. When you connect to your USB device from browser, you get a raw USB API, where you can access all device endpoints belonging to all classes that your device has.

@chmanie
Copy link
Contributor Author

chmanie commented Apr 27, 2024

I did some more reading and I think you are correct. While most of the implementations I've found use endpoints to initiate transfers for illustration purposes, they are definitely not required. I'll try to move the endpoints creation to the example and put them onto another interface.

@chmanie
Copy link
Contributor Author

chmanie commented Apr 27, 2024

Ok, I removed all the additional endpoints from the capability implementation itself and moved them to the example. Only change is that they live on interface 1 now which is created in the example itself.

This adds the WebUSB implementation as per
https://wicg.github.io/webusb/, using one in-endpoint and one
out-endpoint as well as an example for the RP2040 to illustrate this
capability.
Copy link
Member

@Dirbaio Dirbaio left a comment

Choose a reason for hiding this comment

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

This is very cool! thanks

@Dirbaio Dirbaio added this pull request to the merge queue Apr 28, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 28, 2024
@Dirbaio Dirbaio merged commit 08314b0 into embassy-rs:main Apr 28, 2024
6 checks passed
@chmanie chmanie deleted the feature/web-usb-class branch May 26, 2024 20:08
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.

None yet

3 participants