WICG / webusb

Connecting hardware to the web.
https://wicg.github.io/webusb/
Other
1.31k stars 131 forks source link

USBConfiguration, USBAlternateInterface, USBEndpoint should provide access to non-standard descriptors #60

Open devanlai opened 8 years ago

devanlai commented 8 years ago

Some USB standards (e.g. DFU, CDC-ACM) define class-specific descriptors that are included in the set of descriptors returned with the configuration descriptor. These descriptors are not necessarily accessible via GET_DESCRIPTOR requests.

Currently, the only way to access these descriptors via WebUSB is to retrieve the configuration descriptor set and manually parse all of the descriptors, standard and class-specific alike.

One way to simplify this would be to stash non-standard descriptors into a buffer while parsing the set of descriptors. For example, LibUSB stores a copy of any unknown descriptors and associates them with the closest configuration / interface / endpoint descriptor.

This would allow the user to parse just the class-specific descriptors without needing to repeat the entire descriptor parsing process.

reillyeon commented 8 years ago

Thank you for the feedback. I originally avoided adding an extraData field like libusb because I was concerned that it made the spec unextendable. Right now configuration, interface and endpoint are the only descriptors interpreted by the user agent but if a new standard descriptor is defined there will be an awkward transitional period during which it might be thrown into extraData or it might appear in the fully parsed descriptor tree. This happened when adding interface association descriptor support to an application built on libusb. So the design goal is to create something that provides the benefit of nicely parsed descriptors but has clear extension points for new descriptors.

My best thought at the moment is to provide an alternative view to the descriptor set that presents it in the same linear form we get it in from the device. Standard descriptors could appear in parsed form while non-standard descriptors could appear as a generic "descriptor" object with the type and length parsed out but the descriptor body as a raw DataView. If a new descriptor parser is added it would simply replace the unparsed version in the same position in the set, retaining the DataView attribute for backwards-compatibility.

devanlai commented 8 years ago

Providing a flat view of the descriptors is definitely an improvement over manually requesting the and re-parsing the configuration descriptor. However, in many cases, the user would still end up responsible for building up enough of the tree structure to distinguish between a relevant class descriptor associated with interface 2, alt setting 0 vs an unrelated class descriptor associated interface 1, alt setting 1.

Would it make sense for each descriptor in the normal tree view to have an attribute storing the corresponding index in the linear view? That would make it possible for the user code to use the existing tree structure to skip straight to the interface/endpoint of interest and parse only a small subset of the linear view.

This would be similar to the way that handle ranges in the BLE GATT protocol are used to associate a service with all of its characteristics and descriptors.

oostap1 commented 7 years ago

@reillyeon Any updates on that topic? Would love to have those descriptors in any simpler form than RAW.

reillyeon commented 7 years ago

Providing the raw descriptors in Chrome was blocked on some internal platform-specific details that have now been resolved so I'm ready to try specifying the new attributes. I think that providing a raw descriptor blob plus tagging the parsed descriptors with their offsets into it is the best option. I'm reluctant to do any partial parsing because it will inevitably be incompatible with something in the future.

oostap1 commented 7 years ago

@reillyeon looking forward.

karlpetersson commented 7 years ago

Any updates on this?

reillyeon commented 2 years ago

I've filed issue 1314889 to track implementing this on the Chromium side.

RReverser commented 1 year ago

Standard descriptors could appear in parsed form while non-standard descriptors could appear as a generic "descriptor" object with the type and length parsed out but the descriptor body as a raw DataView.

FWIW I think it's worth storing raw data on all descriptors, whether standard or not. In particular, this would significantly simplify the WebUSB backend of libusb as it wouldn't need to serialize the WebUSB descriptor objects back into raw blob that libusb wants from the backends.