1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-14 03:30:02 +00:00

Revert WinUSB feature

This reverts the following range of commits:
68168393b9ea61328f4bb43bc3059ab32c4be2e9..ab76828e16b552c82f468e5d89f1af0645258995

Revert "update usb descriptors"
This reverts commit ab76828e16.

Revert "trezorhal: reply with winusb guid just for the main interface (0)"
This reverts commit 6acfc5d1b3.

Revert "winusb: fix WINUSB_EXTRA_STRING"
This reverts commit 966d8cb4ce.

Revert "winusb: cleanup DeviceInterfaceGUIDs usage"
This reverts commit 56c5a46095.

Revert "make winusb_string_descriptor const"
This reverts commit 132cc4b474.

Revert "webusb: remove unused constants"
This reverts commit 38b4d507bc.

Revert "bootloader: remove debug"
This reverts commit 56d3cbe2e9.

Revert "Bootloader - Switch from HID to WebUSB"
This reverts commit a22abfe90b.

Revert "Switch from HID to WebUSB"
This reverts commit cb067bd14c.

Revert "Add WinUSB, WebUSB, USB2.1 to build"
This reverts commit 05e218bcb8.

Revert "Add WebUSB descriptors"
This reverts commit a062127cef.

Revert "Add WinUSB (WebUSB preparation)"
This reverts commit e6981e85cd.
This commit is contained in:
Pavol Rusnak 2018-03-14 00:35:59 +01:00
parent e444dadbb2
commit b20336e82d
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
10 changed files with 245 additions and 613 deletions

View File

@ -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

View File

@ -18,6 +18,7 @@
*/
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/hid.h>
#include <libopencm3/stm32/flash.h>
#include <string.h>
@ -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)) {

View File

@ -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,22 +181,54 @@ 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[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = USB_INTERFACE_INDEX_MAIN,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_HID,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = USB_STRING_INTERFACE_MAIN,
.endpoint = hid_endpoints,
.extra = &hid_function,
.extralen = sizeof(hid_function),
}};
static const struct usb_endpoint_descriptor hid_endpoints_u2f[2] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = ENDPOINT_ADDRESS_U2F_IN,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 64,
.bInterval = 2,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = ENDPOINT_ADDRESS_U2F_OUT,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 64,
.bInterval = 2,
}};
static const struct usb_interface_descriptor hid_iface_u2f[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
@ -162,7 +245,7 @@ static const struct usb_interface_descriptor hid_iface_u2f[] = {{
}};
#if DEBUG_LINK
static const struct usb_endpoint_descriptor webusb_endpoints_debug[2] = {{
static const struct usb_endpoint_descriptor hid_endpoints_debug[2] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = ENDPOINT_ADDRESS_DEBUG_IN,
@ -178,64 +261,29 @@ static const struct usb_endpoint_descriptor webusb_endpoints_debug[2] = {{
.bInterval = 1,
}};
static const struct usb_interface_descriptor webusb_iface_debug[] = {{
static const struct usb_interface_descriptor hid_iface_debug[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.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_DEBUG,
.endpoint = webusb_endpoints_debug,
.extra = NULL,
.extralen = 0,
.endpoint = hid_endpoints_debug,
.extra = &hid_function,
.extralen = sizeof(hid_function),
}};
#endif
static const struct usb_endpoint_descriptor webusb_endpoints_main[2] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = ENDPOINT_ADDRESS_MAIN_IN,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 64,
.bInterval = 1,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = ENDPOINT_ADDRESS_MAIN_OUT,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 64,
.bInterval = 1,
}};
static const struct usb_interface_descriptor webusb_iface_main[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = USB_INTERFACE_INDEX_MAIN,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_VENDOR,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = USB_STRING_INTERFACE_MAIN,
.endpoint = webusb_endpoints_main,
.extra = NULL,
.extralen = 0,
}};
// 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) {

View File

@ -22,8 +22,10 @@
#include <libopencm3/usb/usbd.h>
/* 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);

View File

@ -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 <string.h>
#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);
}

View File

@ -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 <libopencm3/usb/usbd.h>
#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

View File

@ -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 <stdint.h>
#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

161
winusb.c
View File

@ -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 <libopencm3/usb/usbd.h>
#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);
}

View File

@ -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

View File

@ -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 <stdint.h>
/* 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