WICG / webusb

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

[Feature request] Expose device speed #240

Open RReverser opened 1 year ago

RReverser commented 1 year ago

For some applications (particularly, radio) it's important to know the device speed to choose the best packet size for communication.

They normally use libusb_get_device_speed, which, in turn, consults implementation backend to get device speed reported the OS. I implemented most functions in the WebUSB backend of libusb, but currently reporting device speed as "unknown" as it's not possible to determine it from the WebUSB API, and some apps fail on this as they expect speed to be well-defined.

I think (although not sure) it would be possible to infer speed from bMaxPacketSize and wMaxPacketSize if they were available, but right now only the latter is exposed (as USBEndpoint::packetSize) while the former is not.

rektide commented 1 year ago

I've been using @RReverser's libgphoto2 hackery. I'd alter what sized media I try to capture/download/stream adaptively if I had this capability!

reillyeon commented 1 year ago

@beaufortfrancois I think both of these properties make sense to expose. My only concern is that we need to double-check that we can get the USB speed on all platforms.

Proposed WebIDL change:

enum USBSpeed {
  "low",
  "full"
  "high",
  "super",
};

interface USBDevice {
  // ... existing properties
  readonly attribute USBSpeed speed;
  readonly attribute octet packetSize;
}
RReverser commented 1 year ago

My only concern is that we need to double-check that we can get the USB speed on all platforms.

FWIW libusb has "unknown" constant for this scenario. It should be possible to either return that or perhaps more idiomatic undefined on unsupported platforms.

beaufortfrancois commented 1 year ago

For reference, here's what says https://www.beyondlogic.org/usbnutshell/usb5.shtml

Device descriptor

Offset Field Size Value Description
7 bMaxPacketSize 1 Number Maximum Packet Size for Zero Endpoint. Valid Sizes are 8, 16, 32, 64

The bMaxPacketSize field reports the maximum packet size for endpoint zero. All devices must support endpoint zero.

Endpoint descriptor

Offset Field Size Value Description
4 wMaxPacketSize 2 Number Maximum Packet Size this endpoint is capable of sending or receiving

wMaxPacketSize indicates the maximum payload size for this endpoint.

RReverser commented 1 year ago

The bMaxPacketSize field reports the maximum packet size for endpoint zero. All devices must support endpoint zero.

I suspect that definition is somewhat outdated. It was true for older versions of USB, but not for USB 3.0 / SuperSpeed I think. I need to find a better reference link though.

RReverser commented 1 year ago

Can't find a good reference link, but this patch discussion that pops up among first Google results is helpful:

For bMaxPacketSize0 we usually take what is specified in ep0->maxpacket. This is fine in most cases, however on SuperSpeed bMaxPacketSize0 specifies the exponent instead of the actual size in bytes. The only valid value on SS is 9 which denotes 512 bytes.