WICG / webusb

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

PlatformCapabilityUUID endianness #115

Closed karelbilek closed 5 years ago

karelbilek commented 6 years ago

I was confused by the endianness of PlatformCapabilityUUID

The WebUSB spec says ( https://wicg.github.io/webusb/#webusb-platform-capability-descriptor )

Must be set to {3408b638-09a9-47a0-8bfd-a0768815b665}.

But the Chrome Code (and all the reference implementations) says (https://github.com/scheib/chromium/blob/master/device/usb/webusb_descriptors.cc#L34 )

const uint8_t kWebUsbCapabilityUUID[16] = {
    // Little-endian encoding of {3408b638-09a9-47a0-8bfd-a0768815b665}.
    0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47,
    0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65};

I am not sure why this byte order (from SMBIOS UUID specification it seems) was chosen; but I think it should be at least better documented in the spec (and possibly in the Chrome code). This is not either little endian or big endian, but a mix of both.

saleemrashid commented 6 years ago

@karel-3d That's part of the Platform Capability Descriptor which is defined in Section 9.6.2.4 of the USB 3.1 specification.

karelbilek commented 6 years ago

Hm, but webusb doesn't require USB3.1, right?

edit: oh, I see

This specification uses several terms taken from [USB31].

saleemrashid commented 6 years ago

@karel-3d No, but the Binary Device Object Store that WebUSB uses is defined in Section 9.6.2 of the USB 3.1 specification.

reillyeon commented 6 years ago

The ordering comes from the little endian encoding of Microsoft's UUID structure which splits up the UUID into 4 fields like this,

struct UUID {
  uint32_t data1;
  uint16_t data2;
  uint16_t data3;
  uint8_t data4[8];
};

It doesn't appear that the USB 3.1 specification has anything to say about the byte order of UUIDs so whatever order is picked we should simply be consistent and document it. I'll leave this issue open to track updating the spec.

saleemrashid commented 6 years ago

@reillyeon Actually, the USB specification cites RFC 4122 which states the the first three fields are in network byte order. However, USB uses little endian for transmission. So I do believe that the endianness of the UUID is well-defined by the specification but I completely agree that it is incredibly poorly documented.

riggs commented 6 years ago

FWIW, other software tools agree on what 'little-endian UUID' means: python -c "import uuid;print(', '.join(map(hex, uuid.UUID('3408b638-09a9-47a0-8bfd-a0768815b665').bytes_le)))"

taralx commented 5 years ago

Regardless, the Chrome source version is incorrect -- if it is actually little-endian it should be 0xfd, 0x8b.

karelbilek commented 5 years ago

Nope, it's correct, in the weird USB 3.1 / RFC4122 sense.

taralx commented 5 years ago

Oh god, I did not realize those are two separate bytes. That's pretty awful. 😢