trezorhal: rework winusb
This commit is contained in:
parent
00c193f5cc
commit
ca0918dbce
|
@ -11,7 +11,7 @@
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "usbd_core.h"
|
#include "usbd_core.h"
|
||||||
|
|
||||||
#define UNCONST(X) ((uint8_t *)(X))
|
#define USE_WINUSB 1
|
||||||
|
|
||||||
#define USB_MAX_CONFIG_DESC_SIZE 256
|
#define USB_MAX_CONFIG_DESC_SIZE 256
|
||||||
#define USB_MAX_STR_SIZE 62
|
#define USB_MAX_STR_SIZE 62
|
||||||
|
@ -25,6 +25,16 @@
|
||||||
#error Unable to determine proper USB_PHY_ID to use
|
#error Unable to determine proper USB_PHY_ID to use
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if USE_WINUSB
|
||||||
|
#define USB_WINUSB_VENDOR_CODE '!' // arbitrary, but must be equivalent to the last character in extra string
|
||||||
|
#define USB_WINUSB_EXTRA_STRING 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, '1', 0x00, '0', 0x00, '0', 0x00, USB_WINUSB_VENDOR_CODE , 0x00 // MSFT100!
|
||||||
|
#define USB_WINUSB_EXTRA_STRING_INDEX 0xEE
|
||||||
|
#define USB_WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR 0x04
|
||||||
|
#define USB_WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR 0x05
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UNCONST(X) ((uint8_t *)(X))
|
||||||
|
|
||||||
static usb_device_descriptor_t usb_dev_desc;
|
static usb_device_descriptor_t usb_dev_desc;
|
||||||
|
|
||||||
// Config descriptor
|
// Config descriptor
|
||||||
|
@ -279,6 +289,11 @@ static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define USB_WEBUSB_REQ_GET_URL 0x02
|
||||||
|
#define USB_WEBUSB_DESCRIPTOR_TYPE_URL 0x03
|
||||||
|
#define USB_WEBUSB_URL_SCHEME_HTTP 0
|
||||||
|
#define USB_WEBUSB_URL_SCHEME_HTTPS 1
|
||||||
|
|
||||||
static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) {
|
static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) {
|
||||||
if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) &&
|
if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) &&
|
||||||
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) &&
|
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) &&
|
||||||
|
@ -286,6 +301,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
}
|
}
|
||||||
if ((req->bmRequest & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_VENDOR) {
|
if ((req->bmRequest & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_VENDOR) {
|
||||||
|
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) {
|
||||||
if (req->bRequest == USB_WEBUSB_VENDOR_CODE) {
|
if (req->bRequest == USB_WEBUSB_VENDOR_CODE) {
|
||||||
if (req->wIndex == USB_WEBUSB_REQ_GET_URL && req->wValue == USB_WEBUSB_LANDING_PAGE) {
|
if (req->wIndex == USB_WEBUSB_REQ_GET_URL && req->wValue == USB_WEBUSB_LANDING_PAGE) {
|
||||||
static const char webusb_url[] = {
|
static const char webusb_url[] = {
|
||||||
|
@ -299,6 +315,55 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
||||||
return USBD_FAIL;
|
return USBD_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if USE_WINUSB
|
||||||
|
if (req->bRequest == USB_WINUSB_VENDOR_CODE) {
|
||||||
|
if (req->wIndex == USB_WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR) {
|
||||||
|
static const uint8_t winusb_wcid[] = {
|
||||||
|
// header
|
||||||
|
0x28, 0x00, 0x00, 0x00, // dwLength
|
||||||
|
0x00, 0x01, // bcdVersion
|
||||||
|
0x04, 0x00, // wIndex
|
||||||
|
0x01, // bNumSections
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
|
||||||
|
// functions
|
||||||
|
0x00, // bInterfaceNumber - HACK: we present only interface 0 as WinUSB
|
||||||
|
0x01, // reserved
|
||||||
|
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compatibleId
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
|
||||||
|
};
|
||||||
|
USBD_CtlSendData(dev, UNCONST(winusb_wcid), sizeof(winusb_wcid));
|
||||||
|
} else {
|
||||||
|
return USBD_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if USE_WINUSB
|
||||||
|
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE) {
|
||||||
|
if (req->bRequest == USB_WINUSB_VENDOR_CODE) {
|
||||||
|
if (req->wIndex == USB_WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR) {
|
||||||
|
static const uint8_t winusb_guid[] = {
|
||||||
|
// header
|
||||||
|
0x92, 0x00, 0x00, 0x00, // dwLength
|
||||||
|
0x00, 0x01, // bcdVersion
|
||||||
|
0x05, 0x00, // wIndex
|
||||||
|
0x01, 0x00, // wNumFeatures
|
||||||
|
// features
|
||||||
|
0x88, 0x00, 0x00, 0x00, // dwLength
|
||||||
|
0x07, 0x00, 0x00, 0x00, // dwPropertyDataType
|
||||||
|
0x2A, 0x00, // wNameLength
|
||||||
|
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, // .name
|
||||||
|
0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength
|
||||||
|
'{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData
|
||||||
|
};
|
||||||
|
USBD_CtlSendData(dev, UNCONST(winusb_guid), sizeof(winusb_guid));
|
||||||
|
} else {
|
||||||
|
return USBD_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (req->wIndex >= USBD_MAX_NUM_INTERFACES) {
|
if (req->wIndex >= USBD_MAX_NUM_INTERFACES) {
|
||||||
return USBD_FAIL;
|
return USBD_FAIL;
|
||||||
|
@ -374,7 +439,7 @@ static uint8_t *usb_class_get_cfg_desc(uint16_t *length) {
|
||||||
static uint8_t *usb_class_get_usrstr_desc(USBD_HandleTypeDef *dev, uint8_t index, uint16_t *length) {
|
static uint8_t *usb_class_get_usrstr_desc(USBD_HandleTypeDef *dev, uint8_t index, uint16_t *length) {
|
||||||
#if USE_WINUSB
|
#if USE_WINUSB
|
||||||
static const uint8_t winusb_string_descriptor[] = {
|
static const uint8_t winusb_string_descriptor[] = {
|
||||||
0x14, // bLength
|
0x12, // bLength
|
||||||
USB_DESC_TYPE_STRING, // bDescriptorType
|
USB_DESC_TYPE_STRING, // bDescriptorType
|
||||||
USB_WINUSB_EXTRA_STRING // wData
|
USB_WINUSB_EXTRA_STRING // wData
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,14 +8,6 @@
|
||||||
#define USB_WEBUSB_VENDOR_CODE 0x01 // arbitrary
|
#define USB_WEBUSB_VENDOR_CODE 0x01 // arbitrary
|
||||||
#define USB_WEBUSB_LANDING_PAGE 0x01 // arbitrary
|
#define USB_WEBUSB_LANDING_PAGE 0x01 // arbitrary
|
||||||
|
|
||||||
#define USE_WINUSB 1
|
|
||||||
|
|
||||||
#if USE_WINUSB
|
|
||||||
#define USB_WINUSB_VENDOR_CODE '!' // arbitrary, but must be equivalent to the last character in extra string
|
|
||||||
#define USB_WINUSB_EXTRA_STRING 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, USB_WINUSB_VENDOR_CODE , 0x00, 0x00, 0x00 // MSFT100!
|
|
||||||
#define USB_WINUSB_EXTRA_STRING_INDEX 0xEE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
usb_interface_descriptor_t iface;
|
usb_interface_descriptor_t iface;
|
||||||
usb_endpoint_descriptor_t ep_in;
|
usb_endpoint_descriptor_t ep_in;
|
||||||
|
|
|
@ -7,16 +7,6 @@
|
||||||
|
|
||||||
#define USB_CLASS_WEBUSB 0xFF
|
#define USB_CLASS_WEBUSB 0xFF
|
||||||
|
|
||||||
#define USB_WEBUSB_REQ_SET_PROTOCOL 0x0B
|
|
||||||
#define USB_WEBUSB_REQ_GET_PROTOCOL 0x03
|
|
||||||
#define USB_WEBUSB_REQ_SET_IDLE 0x0A
|
|
||||||
#define USB_WEBUSB_REQ_GET_IDLE 0x02
|
|
||||||
|
|
||||||
#define USB_WEBUSB_REQ_GET_URL 0x02
|
|
||||||
#define USB_WEBUSB_DESCRIPTOR_TYPE_URL 0x03
|
|
||||||
#define USB_WEBUSB_URL_SCHEME_HTTP 0
|
|
||||||
#define USB_WEBUSB_URL_SCHEME_HTTPS 1
|
|
||||||
|
|
||||||
/* usb_webusb_add adds and configures new USB WebUSB interface according to
|
/* usb_webusb_add adds and configures new USB WebUSB interface according to
|
||||||
* configuration options passed in `info`. */
|
* configuration options passed in `info`. */
|
||||||
secbool usb_webusb_add(const usb_webusb_info_t *info) {
|
secbool usb_webusb_add(const usb_webusb_info_t *info) {
|
||||||
|
@ -227,66 +217,16 @@ static void usb_webusb_class_deinit(USBD_HandleTypeDef *dev, usb_webusb_state_t
|
||||||
|
|
||||||
static int usb_webusb_class_setup(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, USBD_SetupReqTypedef *req) {
|
static int usb_webusb_class_setup(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, USBD_SetupReqTypedef *req) {
|
||||||
|
|
||||||
#if USE_WINUSB
|
|
||||||
static uint8_t winusb_wcid[] = {
|
|
||||||
// header
|
|
||||||
0x28, 0x00, 0x00, 0x00, // dwLength
|
|
||||||
0x00, 0x01, // bcdVersion
|
|
||||||
0x04, 0x00, // wIndex
|
|
||||||
0x01, // bNumSections
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
|
|
||||||
// functions
|
|
||||||
0x00, // bInterfaceNumber - will get overriden below
|
|
||||||
0x01, // reserved
|
|
||||||
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compatibleId
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
|
|
||||||
};
|
|
||||||
static const uint8_t winusb_guid[] = {
|
|
||||||
// header
|
|
||||||
0x92, 0x00, 0x00, 0x00, // dwLength
|
|
||||||
0x00, 0x01, // bcdVersion
|
|
||||||
0x05, 0x00, // wIndex
|
|
||||||
0x01, 0x00, // wNumFeatures
|
|
||||||
// features
|
|
||||||
0x88, 0x00, 0x00, 0x00, // dwLength
|
|
||||||
0x07, 0x00, 0x00, 0x00, // dwPropertyDataType
|
|
||||||
0x2A, 0x00, // wNameLength
|
|
||||||
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, // .name
|
|
||||||
0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength
|
|
||||||
'{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||||
|
|
||||||
#if USE_WINUSB
|
// Interface & Endpoint request
|
||||||
case USB_REQ_TYPE_VENDOR: // Vendor request
|
case USB_REQ_TYPE_STANDARD:
|
||||||
switch (req->bRequest) {
|
switch (req->bRequest) {
|
||||||
case USB_WINUSB_VENDOR_CODE:
|
|
||||||
switch (req->bmRequest & USB_REQ_RECIPIENT_MASK) {
|
|
||||||
case USB_REQ_RECIPIENT_DEVICE:
|
|
||||||
winusb_wcid[16] = state->desc_block->iface.bInterfaceNumber;
|
|
||||||
USBD_CtlSendData(dev, UNCONST(winusb_wcid), sizeof(winusb_wcid));
|
|
||||||
break;
|
|
||||||
case USB_REQ_RECIPIENT_INTERFACE:
|
|
||||||
USBD_CtlSendData(dev, UNCONST(winusb_guid), sizeof(winusb_guid));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
USBD_CtlError(dev, req);
|
|
||||||
return USBD_FAIL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case USB_REQ_TYPE_STANDARD: // Interface & Endpoint request
|
|
||||||
|
|
||||||
switch (req->bRequest) {
|
|
||||||
case USB_REQ_SET_INTERFACE:
|
case USB_REQ_SET_INTERFACE:
|
||||||
state->alt_setting = req->wValue;
|
state->alt_setting = req->wValue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USB_REQ_GET_INTERFACE:
|
case USB_REQ_GET_INTERFACE:
|
||||||
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
|
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue