WICG / serial

Serial ports API for the platform.
https://wicg.github.io/serial/
Other
255 stars 48 forks source link

USB Product Version #136

Open JamesB7 opened 3 years ago

JamesB7 commented 3 years ago

Would you please make accessible the USB product version ushort in SerialPortInfo?

WebUSB exposes this (as deviceVersionMajor, deviceVersionMinor, deviceVersionSubminor), but it is still valuable at times even for a serial device.

For example, on one of my products, USB Product ID indicates that the interface exposed to the user is compatible, but I use the USB Product Version to differentiate between different physical hardware revisions. For firmware updates, etc. different firmware is applied based on USB Product Version. Without this information, I cannot safely offer firmware updating (it's cryptographically signed, don't worry) from a browser app.

Thanks!

James

reillyeon commented 3 years ago

Thanks for the feedback, we will consider the USB device version (bcdDevice) field when adding properties to the getInfo() method. Implementing this is blocked on the fingerprinting and platform-specific implementation issues tracked in Chromium issue 1074383.

JamesB7 commented 3 years ago

When a USB device is connected, of any kind -- USB, HID, serial -- on connection it has to read the USB Product ID, Vendor ID, Product Version -- because they are in the initial header. Therefore, on every platform, you can rely on being able to retrieve these in a non-blocking manner for a connected device, because by the USB spec, connection itself implies knowing these. Also, I think you can just extract these from the device path , so there's no cost.

I looked at the thread you referenced...

Have a look at the code of a library I wrote: https://www.zer7.com/software/hidsharp

In particular, look at WinHidDevice's GetSerialPorts() function.

You could do the same thing, except in reverse, to get to an associated HID device if one exists. That's one way to find the manufacturer name, etc. because HidD_GetManufacturerString, HidD_GetProductString, HidD_GetSerialNumberString are getting them from the device's string descriptors, not anything HID-specific.

Granted that's not foolproof, but for non-composite devices, you may be able to find the necessary properties elsewhere if you wander around through the tree like that code does.

Putting manufacturer name, product name in getInfo(), I'm sure it would be handy, but it's harder and it certainly won't be free. The approach I took in HIDSharp is to directly expose ProductID, VendorID, etc., and then put GetSerialNumber() and friends behind accessors, because on a hardware level, requests for string descriptors are extra requests. There's no promise they'll be cached, and I think on Windows, the HidD_ ones actually aren't cached. It's been a while since I checked.

If it were me, I'd do something like

.usb (undefined if it's not USB... this also lets you lazily initialize it, and the API won't look weird if you ever support a non-USB serial port, like getInfo() and getOtherProtocolInfo()...) .usb.productId .usb.vendorId .usb.versionBcd (or whatever) .usb.getManufacturer() (best effort... this would also let you provide a descriptive exception beyond just 'undefined' if you wanted to... the platform may not support getting this for a serial port, or the device itself may have failed on a string descriptor request...) .usb.getProductName()

What do you think?

JamesB7 commented 3 years ago

I don't think manufacturer and product name introduce any privacy concerns. There's nothing there you'd learn that you wouldn't from a USB vendor or product ID, unless the product has a special need for that information, in which case it's about functionality not privacy. Serial number, yeah, it's a real concern. Usually all you really need there is any (even origin specific) unique ID to keep track of which device is which. I work around the lack of this on WebHID right now, but it is NOT pretty how I'm having to do it :)

reillyeon commented 3 years ago

Chromium has similar code to explore the device tree and discover these properties, don't take my message as an implication that I believe it is impossible, it is just more complex than the current serial port enumeration logic (which already has some issues with buggy Windows serial drivers) and it will take some time to make sure it works correctly.

Other developers who have expressed interest in the product name string have explicitly called out that it will be more useful than the product ID, which does hint at additional fingerprinting concerns but I agree with you that it is probably not a significant harm.

neurobe commented 3 years ago

This point continues to thwart us from migrating from a Windows App solution to a Web App solution. Been quite some time now. The entrepreneurship present in warding off criticisms of WebUSB by Mozilla, seem to be missing here.

JamesB7 commented 3 years ago

To be fair, it'll only be more useful than the product ID for /them/. Normally, different products have different product ID. Sharing a product ID and using product name to differentiate is a mistake -- product name can even be localized, so it's not the appropriate place to differentiate a product. But I do understand. Once you have tens or hundreds of thousands of something out in the real world, whether it was a mistake or not doesn't tend to matter. It's just got to be made to work.

How are the people who used Product Name in this version doing it now for their serial device? Surely they have a Windows client, maybe they can share the code they are using to make it happen.

FWIW USB Product Version should be significantly easier than any of these. On every OS it'll be in the same structure giving you the VID and PID.