diff --git a/Makefile b/Makefile index ba1ebf59b..81d418d9d 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,6 @@ ifneq ($(EMULATOR),1) OBJS += timer.o endif -OBJS += usb21_standard.o -OBJS += webusb.o -OBJS += winusb.o - OBJS += gen/bitmaps.o OBJS += gen/fonts.o diff --git a/bootloader/usb.c b/bootloader/usb.c index 76ca596a0..1e2a752d9 100644 --- a/bootloader/usb.c +++ b/bootloader/usb.c @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -36,14 +37,8 @@ #include "secp256k1.h" #include "memzero.h" -#include "usb21_standard.h" -#include "webusb.h" -#include "winusb.h" - #define FIRMWARE_MAGIC "TRZR" -#define USB_INTERFACE_INDEX_MAIN 0 - #define ENDPOINT_ADDRESS_IN (0x81) #define ENDPOINT_ADDRESS_OUT (0x01) @@ -53,21 +48,60 @@ static bool old_was_unsigned; static const struct usb_device_descriptor dev_descr = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0210, + .bcdUSB = 0x0200, .bDeviceClass = 0, .bDeviceSubClass = 0, .bDeviceProtocol = 0, .bMaxPacketSize0 = 64, .idVendor = 0x534c, .idProduct = 0x0001, - .bcdDevice = 0x0300, + .bcdDevice = 0x0100, .iManufacturer = 1, .iProduct = 2, .iSerialNumber = 3, .bNumConfigurations = 1, }; -static const struct usb_endpoint_descriptor endpoints[2] = {{ +static const uint8_t hid_report_descriptor[] = { + 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined) + 0x09, 0x01, // USAGE (1) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x20, // USAGE (Input Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x21, // USAGE (Output Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0xc0 // END_COLLECTION +}; + +static const struct { + struct usb_hid_descriptor hid_descriptor; + struct { + uint8_t bReportDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) hid_report; +} __attribute__((packed)) hid_function = { + .hid_descriptor = { + .bLength = sizeof(hid_function), + .bDescriptorType = USB_DT_HID, + .bcdHID = 0x0111, + .bCountryCode = 0, + .bNumDescriptors = 1, + }, + .hid_report = { + .bReportDescriptorType = USB_DT_REPORT, + .wDescriptorLength = sizeof(hid_report_descriptor), + } +}; + +static const struct usb_endpoint_descriptor hid_endpoints[2] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = ENDPOINT_ADDRESS_IN, @@ -83,24 +117,24 @@ static const struct usb_endpoint_descriptor endpoints[2] = {{ .bInterval = 1, }}; -static const struct usb_interface_descriptor iface[] = {{ +static const struct usb_interface_descriptor hid_iface[] = {{ .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = USB_INTERFACE_INDEX_MAIN, + .bInterfaceNumber = 0, .bAlternateSetting = 0, .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_VENDOR, + .bInterfaceClass = USB_CLASS_HID, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = 0, - .endpoint = endpoints, - .extra = NULL, - .extralen = 0, + .endpoint = hid_endpoints, + .extra = &hid_function, + .extralen = sizeof(hid_function), }}; static const struct usb_interface ifaces[] = {{ .num_altsetting = 1, - .altsetting = iface, + .altsetting = hid_iface, }}; static const struct usb_config_descriptor config = { @@ -121,6 +155,23 @@ static const char *usb_strings[] = { "", // empty serial }; +static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) +{ + (void)complete; + (void)dev; + + if ((req->bmRequestType != 0x81) || + (req->bRequest != USB_REQ_GET_DESCRIPTOR) || + (req->wValue != 0x2200)) + return 0; + + /* Handle the HID report descriptor. */ + *buf = (uint8_t *)hid_report_descriptor; + *len = sizeof(hid_report_descriptor); + + return 1; +} + enum { STATE_READY, STATE_OPEN, @@ -264,7 +315,7 @@ static void restore_metadata(const uint8_t *backup) flash_lock(); } -static void rx_callback(usbd_device *dev, uint8_t ep) +static void hid_rx_callback(usbd_device *dev, uint8_t ep) { (void)ep; static uint8_t buf[64] __attribute__((aligned(4))); @@ -581,37 +632,23 @@ static void rx_callback(usbd_device *dev, uint8_t ep) } -static void set_config(usbd_device *dev, uint16_t wValue) +static void hid_set_config(usbd_device *dev, uint16_t wValue) { (void)wValue; - usbd_ep_setup(dev, ENDPOINT_ADDRESS_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); - usbd_ep_setup(dev, ENDPOINT_ADDRESS_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, rx_callback); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_rx_callback); + + usbd_register_control_callback( + dev, + USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + hid_control_request + ); } static usbd_device *usbd_dev; -static uint8_t usbd_control_buffer[256] __attribute__ ((aligned (2))); - -static const struct usb_device_capability_descriptor* capabilities[] = { - (const struct usb_device_capability_descriptor*)&webusb_platform_capability_descriptor, -}; - -static const struct usb_bos_descriptor bos_descriptor = { - .bLength = USB_DT_BOS_SIZE, - .bDescriptorType = USB_DT_BOS, - .bNumDeviceCaps = sizeof(capabilities)/sizeof(capabilities[0]), - .capabilities = capabilities -}; - -void usbInit(void) -{ - usbd_dev = usbd_init(&otgfs_usb_driver, &dev_descr, &config, usb_strings, sizeof(usb_strings)/sizeof(const char *), usbd_control_buffer, sizeof(usbd_control_buffer)); - usbd_register_set_config_callback(usbd_dev, set_config); - usb21_setup(usbd_dev, &bos_descriptor); - static const char* origin_url = "trezor.io/start"; - webusb_setup(usbd_dev, origin_url); - winusb_setup(usbd_dev, USB_INTERFACE_INDEX_MAIN); -} +static uint8_t usbd_control_buffer[128]; void checkButtons(void) { @@ -645,7 +682,8 @@ void checkButtons(void) void usbLoop(bool firmware_present) { brand_new_firmware = !firmware_present; - usbInit(); + usbd_dev = usbd_init(&otgfs_usb_driver, &dev_descr, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); + usbd_register_set_config_callback(usbd_dev, hid_set_config); for (;;) { usbd_poll(usbd_dev); if (brand_new_firmware && (flash_state == STATE_READY || flash_state == STATE_OPEN)) { diff --git a/firmware/usb.c b/firmware/usb.c index be7cae7b9..7a59b6fa0 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -29,27 +29,18 @@ #include "util.h" #include "timer.h" -#include "usb21_standard.h" -#include "webusb.h" -#include "winusb.h" - - #define USB_INTERFACE_INDEX_MAIN 0 #if DEBUG_LINK #define USB_INTERFACE_INDEX_DEBUG 1 #define USB_INTERFACE_INDEX_U2F 2 -#define USB_INTERFACE_COUNT 3 #else #define USB_INTERFACE_INDEX_U2F 1 -#define USB_INTERFACE_COUNT 2 #endif -#define ENDPOINT_ADDRESS_MAIN_IN (0x81) -#define ENDPOINT_ADDRESS_MAIN_OUT (0x01) -#if DEBUG_LINK +#define ENDPOINT_ADDRESS_IN (0x81) +#define ENDPOINT_ADDRESS_OUT (0x01) #define ENDPOINT_ADDRESS_DEBUG_IN (0x82) #define ENDPOINT_ADDRESS_DEBUG_OUT (0x02) -#endif #define ENDPOINT_ADDRESS_U2F_IN (0x83) #define ENDPOINT_ADDRESS_U2F_OUT (0x03) @@ -59,7 +50,7 @@ X(SERIAL_NUMBER, storage_uuid_str) \ X(INTERFACE_MAIN, "TREZOR Interface") \ X(INTERFACE_DEBUG, "TREZOR Debug Link Interface") \ - X(INTERFACE_U2F, "TREZOR U2F Interface") \ + X(INTERFACE_U2F, "U2F Interface") #define X(name, value) USB_STRING_##name, enum { @@ -77,20 +68,60 @@ static const char *usb_strings[] = { static const struct usb_device_descriptor dev_descr = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0210, + .bcdUSB = 0x0200, .bDeviceClass = 0, .bDeviceSubClass = 0, .bDeviceProtocol = 0, .bMaxPacketSize0 = 64, .idVendor = 0x534c, .idProduct = 0x0001, - .bcdDevice = 0x0200, + .bcdDevice = 0x0100, .iManufacturer = USB_STRING_MANUFACTURER, .iProduct = USB_STRING_PRODUCT, .iSerialNumber = USB_STRING_SERIAL_NUMBER, .bNumConfigurations = 1, }; +static const uint8_t hid_report_descriptor[] = { + 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined) + 0x09, 0x01, // USAGE (1) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x20, // USAGE (Input Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x21, // USAGE (Output Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0xc0 // END_COLLECTION +}; + +#if DEBUG_LINK +static const uint8_t hid_report_descriptor_debug[] = { + 0x06, 0x01, 0xff, // USAGE_PAGE (Vendor Defined) + 0x09, 0x01, // USAGE (1) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x20, // USAGE (Input Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x21, // USAGE (Output Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0xc0 // END_COLLECTION +}; +#endif + static const uint8_t hid_report_descriptor_u2f[] = { 0x06, 0xd0, 0xf1, // USAGE_PAGE (FIDO Alliance) 0x09, 0x01, // USAGE (U2F HID Authenticator Device) @@ -110,6 +141,26 @@ static const uint8_t hid_report_descriptor_u2f[] = { 0xc0 // END_COLLECTION }; +static const struct { + struct usb_hid_descriptor hid_descriptor; + struct { + uint8_t bReportDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) hid_report; +} __attribute__((packed)) hid_function = { + .hid_descriptor = { + .bLength = sizeof(hid_function), + .bDescriptorType = USB_DT_HID, + .bcdHID = 0x0111, + .bCountryCode = 0, + .bNumDescriptors = 1, + }, + .hid_report = { + .bReportDescriptorType = USB_DT_REPORT, + .wDescriptorLength = sizeof(hid_report_descriptor), + } +}; + static const struct { struct usb_hid_descriptor hid_descriptor_u2f; struct { @@ -130,112 +181,109 @@ static const struct { } }; -static const struct usb_endpoint_descriptor hid_endpoints_u2f[2] = {{ + +static const struct usb_endpoint_descriptor hid_endpoints[2] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = ENDPOINT_ADDRESS_U2F_IN, + .bEndpointAddress = ENDPOINT_ADDRESS_IN, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 64, .bInterval = 1, }, { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = ENDPOINT_ADDRESS_U2F_OUT, + .bEndpointAddress = ENDPOINT_ADDRESS_OUT, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 64, .bInterval = 1, }}; -static const struct usb_interface_descriptor hid_iface_u2f[] = {{ +static const struct usb_interface_descriptor hid_iface[] = {{ .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = USB_INTERFACE_INDEX_U2F, + .bInterfaceNumber = USB_INTERFACE_INDEX_MAIN, .bAlternateSetting = 0, .bNumEndpoints = 2, .bInterfaceClass = USB_CLASS_HID, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, - .iInterface = USB_STRING_INTERFACE_U2F, - .endpoint = hid_endpoints_u2f, - .extra = &hid_function_u2f, - .extralen = sizeof(hid_function_u2f), + .iInterface = USB_STRING_INTERFACE_MAIN, + .endpoint = hid_endpoints, + .extra = &hid_function, + .extralen = sizeof(hid_function), }}; -#if DEBUG_LINK -static const struct usb_endpoint_descriptor webusb_endpoints_debug[2] = {{ +static const struct usb_endpoint_descriptor hid_endpoints_u2f[2] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = ENDPOINT_ADDRESS_DEBUG_IN, + .bEndpointAddress = ENDPOINT_ADDRESS_U2F_IN, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 64, - .bInterval = 1, + .bInterval = 2, }, { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = ENDPOINT_ADDRESS_DEBUG_OUT, + .bEndpointAddress = ENDPOINT_ADDRESS_U2F_OUT, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 64, - .bInterval = 1, + .bInterval = 2, }}; -static const struct usb_interface_descriptor webusb_iface_debug[] = {{ +static const struct usb_interface_descriptor hid_iface_u2f[] = {{ .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = USB_INTERFACE_INDEX_DEBUG, + .bInterfaceNumber = USB_INTERFACE_INDEX_U2F, .bAlternateSetting = 0, .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_VENDOR, + .bInterfaceClass = USB_CLASS_HID, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, - .iInterface = USB_STRING_INTERFACE_DEBUG, - .endpoint = webusb_endpoints_debug, - .extra = NULL, - .extralen = 0, + .iInterface = USB_STRING_INTERFACE_U2F, + .endpoint = hid_endpoints_u2f, + .extra = &hid_function_u2f, + .extralen = sizeof(hid_function_u2f), }}; -#endif - -static const struct usb_endpoint_descriptor webusb_endpoints_main[2] = {{ +#if DEBUG_LINK +static const struct usb_endpoint_descriptor hid_endpoints_debug[2] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = ENDPOINT_ADDRESS_MAIN_IN, + .bEndpointAddress = ENDPOINT_ADDRESS_DEBUG_IN, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 64, .bInterval = 1, }, { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = ENDPOINT_ADDRESS_MAIN_OUT, + .bEndpointAddress = ENDPOINT_ADDRESS_DEBUG_OUT, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 64, .bInterval = 1, }}; -static const struct usb_interface_descriptor webusb_iface_main[] = {{ +static const struct usb_interface_descriptor hid_iface_debug[] = {{ .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = USB_INTERFACE_INDEX_MAIN, + .bInterfaceNumber = USB_INTERFACE_INDEX_DEBUG, .bAlternateSetting = 0, .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_VENDOR, + .bInterfaceClass = USB_CLASS_HID, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, - .iInterface = USB_STRING_INTERFACE_MAIN, - .endpoint = webusb_endpoints_main, - .extra = NULL, - .extralen = 0, + .iInterface = USB_STRING_INTERFACE_DEBUG, + .endpoint = hid_endpoints_debug, + .extra = &hid_function, + .extralen = sizeof(hid_function), }}; +#endif - -// Windows are strict about interfaces appearing -// in correct order static const struct usb_interface ifaces[] = {{ .num_altsetting = 1, - .altsetting = webusb_iface_main, + .altsetting = hid_iface, #if DEBUG_LINK }, { .num_altsetting = 1, - .altsetting = webusb_iface_debug, + .altsetting = hid_iface_debug, #endif }, { .num_altsetting = 1, @@ -246,7 +294,11 @@ static const struct usb_config_descriptor config = { .bLength = USB_DT_CONFIGURATION_SIZE, .bDescriptorType = USB_DT_CONFIGURATION, .wTotalLength = 0, - .bNumInterfaces = USB_INTERFACE_COUNT, +#if DEBUG_LINK + .bNumInterfaces = 3, +#else + .bNumInterfaces = 2, +#endif .bConfigurationValue = 1, .iConfiguration = 0, .bmAttributes = 0x80, @@ -260,24 +312,40 @@ static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uin (void)dev; if ((req->bmRequestType != 0x81) || - (req->bRequest != USB_REQ_GET_DESCRIPTOR) || - (req->wValue != 0x2200)) + (req->bRequest != USB_REQ_GET_DESCRIPTOR) || + (req->wValue != 0x2200)) return 0; - debugLog(0, "", "hid_control_request u2f"); - *buf = (uint8_t *)hid_report_descriptor_u2f; - *len = MIN(*len, sizeof(hid_report_descriptor_u2f)); + if (req->wIndex == USB_INTERFACE_INDEX_U2F) { + debugLog(0, "", "hid_control_request u2f"); + *buf = (uint8_t *)hid_report_descriptor_u2f; + *len = sizeof(hid_report_descriptor_u2f); + return 1; + } + +#if DEBUG_LINK + if (req->wIndex == USB_INTERFACE_INDEX_DEBUG) { + debugLog(0, "", "hid_control_request debug"); + *buf = (uint8_t *)hid_report_descriptor_debug; + *len = sizeof(hid_report_descriptor_debug); + return 1; + } +#endif + + debugLog(0, "", "hid_control_request main"); + *buf = (uint8_t *)hid_report_descriptor; + *len = sizeof(hid_report_descriptor); return 1; } static volatile char tiny = 0; -static void main_rx_callback(usbd_device *dev, uint8_t ep) +static void hid_rx_callback(usbd_device *dev, uint8_t ep) { (void)ep; static CONFIDENTIAL uint8_t buf[64] __attribute__ ((aligned(4))); - if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_MAIN_OUT, buf, 64) != 64) return; - debugLog(0, "", "main_rx_callback"); + if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_OUT, buf, 64) != 64) return; + debugLog(0, "", "hid_rx_callback"); if (!tiny) { msg_read(buf, 64); } else { @@ -285,23 +353,23 @@ static void main_rx_callback(usbd_device *dev, uint8_t ep) } } -static void u2f_rx_callback(usbd_device *dev, uint8_t ep) +static void hid_u2f_rx_callback(usbd_device *dev, uint8_t ep) { (void)ep; static CONFIDENTIAL uint8_t buf[64] __attribute__ ((aligned(4))); - debugLog(0, "", "u2f_rx_callback"); + debugLog(0, "", "hid_u2f_rx_callback"); if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_U2F_OUT, buf, 64) != 64) return; u2fhid_read(tiny, (const U2FHID_FRAME *) (void*) buf); } #if DEBUG_LINK -static void debug_rx_callback(usbd_device *dev, uint8_t ep) +static void hid_debug_rx_callback(usbd_device *dev, uint8_t ep) { (void)ep; static CONFIDENTIAL uint8_t buf[64] __attribute__ ((aligned(4))); if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_DEBUG_OUT, buf, 64) != 64) return; - debugLog(0, "", "debug_rx_callback"); + debugLog(0, "", "hid_debug_rx_callback"); if (!tiny) { msg_debug_read(buf, 64); } else { @@ -310,17 +378,17 @@ static void debug_rx_callback(usbd_device *dev, uint8_t ep) } #endif -static void set_config(usbd_device *dev, uint16_t wValue) +static void hid_set_config(usbd_device *dev, uint16_t wValue) { (void)wValue; - usbd_ep_setup(dev, ENDPOINT_ADDRESS_MAIN_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); - usbd_ep_setup(dev, ENDPOINT_ADDRESS_MAIN_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, main_rx_callback); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_rx_callback); usbd_ep_setup(dev, ENDPOINT_ADDRESS_U2F_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); - usbd_ep_setup(dev, ENDPOINT_ADDRESS_U2F_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, u2f_rx_callback); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_U2F_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_u2f_rx_callback); #if DEBUG_LINK usbd_ep_setup(dev, ENDPOINT_ADDRESS_DEBUG_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); - usbd_ep_setup(dev, ENDPOINT_ADDRESS_DEBUG_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, debug_rx_callback); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_DEBUG_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_debug_rx_callback); #endif usbd_register_control_callback( @@ -331,29 +399,12 @@ static void set_config(usbd_device *dev, uint16_t wValue) } static usbd_device *usbd_dev; -static uint8_t usbd_control_buffer[256] __attribute__ ((aligned (2))); - -static const struct usb_device_capability_descriptor* capabilities[] = { - (const struct usb_device_capability_descriptor*)&webusb_platform_capability_descriptor, -}; - -static const struct usb_bos_descriptor bos_descriptor = { - .bLength = USB_DT_BOS_SIZE, - .bDescriptorType = USB_DT_BOS, - .bNumDeviceCaps = sizeof(capabilities)/sizeof(capabilities[0]), - .capabilities = capabilities -}; +static uint8_t usbd_control_buffer[128]; void usbInit(void) { usbd_dev = usbd_init(&otgfs_usb_driver, &dev_descr, &config, usb_strings, sizeof(usb_strings) / sizeof(*usb_strings), usbd_control_buffer, sizeof(usbd_control_buffer)); - usbd_register_set_config_callback(usbd_dev, set_config); - usb21_setup(usbd_dev, &bos_descriptor); - static const char* origin_url = "trezor.io/start"; - webusb_setup(usbd_dev, origin_url); - // Debug link interface does not have WinUSB set; - // if you really need debug link on windows, edit the descriptor in winusb.c - winusb_setup(usbd_dev, USB_INTERFACE_INDEX_MAIN); + usbd_register_set_config_callback(usbd_dev, hid_set_config); } void usbPoll(void) @@ -364,7 +415,7 @@ void usbPoll(void) // write pending data data = msg_out_data(); if (data) { - while ( usbd_ep_write_packet(usbd_dev, ENDPOINT_ADDRESS_MAIN_IN, data, 64) != 64 ) {} + while ( usbd_ep_write_packet(usbd_dev, ENDPOINT_ADDRESS_IN, data, 64) != 64 ) {} } data = u2f_out_data(); if (data) { diff --git a/usb21_standard.h b/usb21_standard.h index e5358bcd5..e7578a533 100644 --- a/usb21_standard.h +++ b/usb21_standard.h @@ -22,8 +22,10 @@ #include /* USB 3.1 Descriptor Types - Table 9-6 */ -#define USB_DT_BOS 15 +#define USB_DT_BOS 15 #define USB_DT_DEVICE_CAPABILITY 16 +#define USB_DT_SUPERSPEED_USB_ENDPOINT_COMPANION 48 +#define USB_DT_SUPERSPEEDPLUS_ISOCHRONOUS_ENDPOINT_COMPANION 49 struct usb_device_capability_descriptor { uint8_t bLength; @@ -43,7 +45,18 @@ struct usb_bos_descriptor { #define USB_DT_BOS_SIZE 5 /* USB Device Capability Types - USB 3.1 Table 9-14 */ -#define USB_DC_PLATFORM 5 +#define USB_DC_WIRELESS_USB 1 +#define USB_DC_USB_2_0_EXTENSION 2 +#define USB_DC_SUPERSPEED_USB 3 +#define USB_DC_CONTAINER_ID 4 +#define USB_DC_PLATFORM 5 +#define USB_DC_POWER_DELIVERY_CAPABILITY 6 +#define USB_DC_BATTERY_INFO_CAPABILITY 7 +#define USB_DC_PD_CONSUMER_PORT_CAPABILITY 8 +#define USB_DC_PD_PROVIDER_PORT_CAPABILITY 9 +#define USB_DC_SUPERSPEED_PLUS 10 +#define USB_DC_PRECISION_TIME_MEASUREMENT 11 +#define USB_DC_WIRELESS_USB_EXT 12 extern void usb21_setup(usbd_device* usbd_dev, const struct usb_bos_descriptor* binary_object_store); diff --git a/webusb.c b/webusb.c deleted file mode 100644 index beb909c08..000000000 --- a/webusb.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016, Devan Lai - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice - * appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include "util.h" -#include "webusb.h" -#include "usb21_standard.h" - -const struct webusb_platform_descriptor webusb_platform_capability_descriptor = { - .bLength = WEBUSB_PLATFORM_DESCRIPTOR_SIZE, - .bDescriptorType = USB_DT_DEVICE_CAPABILITY, - .bDevCapabilityType = USB_DC_PLATFORM, - .bReserved = 0, - .platformCapabilityUUID = WEBUSB_UUID, - .bcdVersion = 0x0100, - .bVendorCode = WEBUSB_VENDOR_CODE, - .iLandingPage = 1 -}; - -static const char* webusb_https_url; - -static int webusb_control_vendor_request(usbd_device *usbd_dev, - struct usb_setup_data *req, - uint8_t **buf, uint16_t *len, - usbd_control_complete_callback* complete) { - (void)complete; - (void)usbd_dev; - - if (req->bRequest != WEBUSB_VENDOR_CODE) { - return USBD_REQ_NEXT_CALLBACK; - } - - int status = USBD_REQ_NOTSUPP; - switch (req->wIndex) { - case WEBUSB_REQ_GET_URL: { - struct webusb_url_descriptor* url = (struct webusb_url_descriptor*)(*buf); - uint16_t index = req->wValue; - if (index == 0) { - return USBD_REQ_NOTSUPP; - } - - if (index == 1) { - size_t url_len = strlen(webusb_https_url); - url->bLength = WEBUSB_DT_URL_DESCRIPTOR_SIZE + url_len; - url->bDescriptorType = WEBUSB_DT_URL; - url->bScheme = WEBUSB_URL_SCHEME_HTTPS; - memcpy(&url->URL, webusb_https_url, url_len); - *len = MIN(*len, url->bLength); - status = USBD_REQ_HANDLED; - } else { - // TODO: stall instead? - status = USBD_REQ_NOTSUPP; - } - break; - } - default: { - status = USBD_REQ_NOTSUPP; - break; - } - } - - return status; -} - -static void webusb_set_config(usbd_device* usbd_dev, uint16_t wValue) { - (void)wValue; - usbd_register_control_callback( - usbd_dev, - USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE, - USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, - webusb_control_vendor_request); -} - -void webusb_setup(usbd_device* usbd_dev, const char* https_url) { - webusb_https_url = https_url; - - usbd_register_set_config_callback(usbd_dev, webusb_set_config); -} diff --git a/webusb.h b/webusb.h deleted file mode 100644 index 342408f1f..000000000 --- a/webusb.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016, Devan Lai - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice - * appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef WEBUSB_H_INCLUDED -#define WEBUSB_H_INCLUDED - -#include -#include "webusb_defs.h" - -// Arbitrary -#define WEBUSB_VENDOR_CODE 0x01 - -extern const struct webusb_platform_descriptor webusb_platform_capability_descriptor; -extern void webusb_setup(usbd_device* usbd_dev, const char* https_url); - -#endif diff --git a/webusb_defs.h b/webusb_defs.h deleted file mode 100644 index 45b5f2478..000000000 --- a/webusb_defs.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016, Devan Lai - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice - * appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef WEBUSB_DEFS_H_INCLUDED -#define WEBUSB_DEFS_H_INCLUDED - -#include - -#define WEBUSB_REQ_GET_URL 0x02 - -#define WEBUSB_DT_DESCRIPTOR_SET_HEADER 0 -#define WEBUSB_DT_CONFIGURATION_SUBSET_HEADER 1 -#define WEBUSB_DT_FUNCTION_SUBSET_HEADER 2 -#define WEBUSB_DT_URL 3 - -#define WEBUSB_URL_SCHEME_HTTP 0 -#define WEBUSB_URL_SCHEME_HTTPS 1 - -struct webusb_platform_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDevCapabilityType; - uint8_t bReserved; - uint8_t platformCapabilityUUID[16]; - uint16_t bcdVersion; - uint8_t bVendorCode; - uint8_t iLandingPage; -} __attribute__((packed)); - -#define WEBUSB_PLATFORM_DESCRIPTOR_SIZE sizeof(struct webusb_platform_descriptor) - -// from https://wicg.github.io/webusb/#webusb-platform-capability-descriptor -// see also this (for endianness explanation) -// https://github.com/WICG/webusb/issues/115#issuecomment-352206549 -#define WEBUSB_UUID {0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47,0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65} - -struct webusb_url_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bScheme; - char URL[]; -} __attribute__((packed)); - -#define WEBUSB_DT_URL_DESCRIPTOR_SIZE 3 - -#endif diff --git a/winusb.c b/winusb.c deleted file mode 100644 index afdaf8b70..000000000 --- a/winusb.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2016, Devan Lai - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice - * appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include "util.h" -#include "winusb.h" - -static int usb_descriptor_type(uint16_t wValue) { - return wValue >> 8; -} - -static int usb_descriptor_index(uint16_t wValue) { - return wValue & 0xFF; -} - -static struct winusb_compatible_id_descriptor winusb_wcid = { - .header = { - .dwLength = sizeof(struct winusb_compatible_id_descriptor_header) + - 1 * sizeof(struct winusb_compatible_id_function_section), - .bcdVersion = WINUSB_BCD_VERSION, - .wIndex = WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR, - .bNumSections = 1, - .reserved = { 0, 0, 0, 0, 0, 0, 0 }, - }, - .functions = { - { - // note - bInterfaceNumber is rewritten in winusb_setup with the correct interface number - .bInterfaceNumber = 0, - .reserved0 = { 1 }, - .compatibleId = "WINUSB", - .subCompatibleId = "", - .reserved1 = { 0, 0, 0, 0, 0, 0} - }, - } -}; - -static const struct usb_string_descriptor winusb_string_descriptor = { - .bLength = 0x12, - .bDescriptorType = USB_DT_STRING, - .wData = WINUSB_EXTRA_STRING -}; - -static const struct winusb_extended_properties_descriptor guid = { - .header = { - .dwLength = sizeof(struct winusb_extended_properties_descriptor_header) - + 1 * sizeof (struct winusb_extended_properties_feature_descriptor), - .bcdVersion = WINUSB_BCD_VERSION, - .wIndex = WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR, - .wNumFeatures = 1, - }, - .features = { - { - .dwLength = sizeof(struct winusb_extended_properties_feature_descriptor), - .dwPropertyDataType = WINUSB_EXTENDED_PROPERTIES_MULTISZ_DATA_TYPE, - .wNameLength = WINUSB_EXTENDED_PROPERTIES_GUID_NAME_SIZE_C, - .name = WINUSB_EXTENDED_PROPERTIES_GUID_NAME, - .dwPropertyDataLength = WINUSB_EXTENDED_PROPERTIES_GUID_DATA_SIZE_C, - .propertyData = WINUSB_EXTENDED_PROPERTIES_GUID_DATA, - }, - } -}; - -static int winusb_descriptor_request(usbd_device *usbd_dev, - struct usb_setup_data *req, - uint8_t **buf, uint16_t *len, - usbd_control_complete_callback* complete) { - (void)complete; - (void)usbd_dev; - - if ((req->bmRequestType & USB_REQ_TYPE_TYPE) != USB_REQ_TYPE_STANDARD) { - return USBD_REQ_NEXT_CALLBACK; - } - - if (req->bRequest == USB_REQ_GET_DESCRIPTOR && usb_descriptor_type(req->wValue) == USB_DT_STRING) { - if (usb_descriptor_index(req->wValue) == WINUSB_EXTRA_STRING_INDEX) { - *buf = (uint8_t*)(&winusb_string_descriptor); - *len = MIN(*len, winusb_string_descriptor.bLength); - return USBD_REQ_HANDLED; - } - } - return USBD_REQ_NEXT_CALLBACK; -} - -static int winusb_control_vendor_request(usbd_device *usbd_dev, - struct usb_setup_data *req, - uint8_t **buf, uint16_t *len, - usbd_control_complete_callback* complete) { - (void)complete; - (void)usbd_dev; - - if (req->bRequest != WINUSB_MS_VENDOR_CODE) { - return USBD_REQ_NEXT_CALLBACK; - } - - int status = USBD_REQ_NOTSUPP; - if (((req->bmRequestType & USB_REQ_TYPE_RECIPIENT) == USB_REQ_TYPE_DEVICE) && - (req->wIndex == WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR)) { - *buf = (uint8_t*)(&winusb_wcid); - *len = MIN(*len, winusb_wcid.header.dwLength); - status = USBD_REQ_HANDLED; - - } else if (((req->bmRequestType & USB_REQ_TYPE_RECIPIENT) == USB_REQ_TYPE_INTERFACE) && - (req->wIndex == WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR) && - (usb_descriptor_index(req->wValue) == winusb_wcid.functions[0].bInterfaceNumber)) { - - *buf = (uint8_t*)(&guid); - *len = MIN(*len, guid.header.dwLength); - status = USBD_REQ_HANDLED; - - } else { - status = USBD_REQ_NOTSUPP; - } - - return status; -} - -static void winusb_set_config(usbd_device* usbd_dev, uint16_t wValue) { - (void)wValue; - usbd_register_control_callback( - usbd_dev, - USB_REQ_TYPE_VENDOR, - USB_REQ_TYPE_TYPE, - winusb_control_vendor_request); -} - -void winusb_setup(usbd_device* usbd_dev, uint8_t interface) { - winusb_wcid.functions[0].bInterfaceNumber = interface; - - usbd_register_set_config_callback(usbd_dev, winusb_set_config); - - /* Windows probes the compatible ID before setting the configuration, - so also register the callback now */ - - usbd_register_control_callback( - usbd_dev, - USB_REQ_TYPE_VENDOR, - USB_REQ_TYPE_TYPE, - winusb_control_vendor_request); - - usbd_register_control_callback( - usbd_dev, - USB_REQ_TYPE_DEVICE, - USB_REQ_TYPE_RECIPIENT, - winusb_descriptor_request); -} - diff --git a/winusb.h b/winusb.h deleted file mode 100644 index 16a6df115..000000000 --- a/winusb.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2016, Devan Lai - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice - * appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef WINUSB_H_INCLUDED -#define WINUSB_H_INCLUDED - -#include "winusb_defs.h" - -// Arbitrary, but must be equivalent to the last character in extra string -#define WINUSB_MS_VENDOR_CODE '!' -#define WINUSB_EXTRA_STRING {'M', 'S', 'F', 'T', '1', '0', '0', WINUSB_MS_VENDOR_CODE} - -extern void winusb_setup(usbd_device* usbd_dev, uint8_t interface); - -#endif diff --git a/winusb_defs.h b/winusb_defs.h deleted file mode 100644 index 830e6b154..000000000 --- a/winusb_defs.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016, Devan Lai - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice - * appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef WINUSB_DEFS_H_INCLUDED -#define WINUSB_DEFS_H_INCLUDED - -#include - -/* Microsoft OS 1.0 descriptors */ - -/* Extended Compat ID OS Feature Descriptor Specification */ -#define WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR 0x04 -#define WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR 0x05 -#define WINUSB_BCD_VERSION 0x0100 - -// Apparently using DeviceInterfaceGUID does not always work on Windows 7. -// DeviceInterfaceGUIDs does seem to work. -#define WINUSB_EXTENDED_PROPERTIES_GUID_NAME u"DeviceInterfaceGUIDs" -#define WINUSB_EXTENDED_PROPERTIES_GUID_NAME_SIZE_C sizeof(WINUSB_EXTENDED_PROPERTIES_GUID_NAME) -#define WINUSB_EXTENDED_PROPERTIES_GUID_NAME_SIZE_U (sizeof(WINUSB_EXTENDED_PROPERTIES_GUID_NAME) / 2) - -// extra null is intentional - it's an array of GUIDs with 1 item -#define WINUSB_EXTENDED_PROPERTIES_GUID_DATA u"{0263b512-88cb-4136-9613-5c8e109d8ef5}\x00" -#define WINUSB_EXTENDED_PROPERTIES_GUID_DATA_SIZE_C sizeof(WINUSB_EXTENDED_PROPERTIES_GUID_DATA) -#define WINUSB_EXTENDED_PROPERTIES_GUID_DATA_SIZE_U (sizeof(WINUSB_EXTENDED_PROPERTIES_GUID_DATA) / 2) -#define WINUSB_EXTENDED_PROPERTIES_MULTISZ_DATA_TYPE 7 - -#define WINUSB_EXTRA_STRING_INDEX 0xee - -/* Table 2. Function Section */ -struct winusb_compatible_id_function_section { - uint8_t bInterfaceNumber; - uint8_t reserved0[1]; - char compatibleId[8]; - char subCompatibleId[8]; - uint8_t reserved1[6]; -} __attribute__((packed)); - -/* Table 1. Header Section */ -struct winusb_compatible_id_descriptor_header { - uint32_t dwLength; - uint16_t bcdVersion; - uint16_t wIndex; - uint8_t bNumSections; - uint8_t reserved[7]; -} __attribute__((packed)); - -struct winusb_compatible_id_descriptor { - struct winusb_compatible_id_descriptor_header header; - struct winusb_compatible_id_function_section functions[]; -} __attribute__((packed)); - -struct winusb_extended_properties_feature_descriptor { - uint32_t dwLength; - uint32_t dwPropertyDataType; - uint16_t wNameLength; - uint16_t name[WINUSB_EXTENDED_PROPERTIES_GUID_NAME_SIZE_U]; - uint32_t dwPropertyDataLength; - uint16_t propertyData[WINUSB_EXTENDED_PROPERTIES_GUID_DATA_SIZE_U]; -} __attribute__((packed)); - -struct winusb_extended_properties_descriptor_header { - uint32_t dwLength; - uint16_t bcdVersion; - uint16_t wIndex; - uint16_t wNumFeatures; -} __attribute__((packed)); - -struct winusb_extended_properties_descriptor { - struct winusb_extended_properties_descriptor_header header; - struct winusb_extended_properties_feature_descriptor features[]; -} __attribute__((packed)); - -#endif