mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
trezorhal: make usb stack more robust
This commit is contained in:
parent
d6681efff2
commit
55d0416641
@ -35,7 +35,7 @@ static void usb_init_all(void) {
|
||||
.product_id = 0x53C0,
|
||||
.release_num = 0x0200,
|
||||
.manufacturer = "SatoshiLabs",
|
||||
.product = "TREZOR Bootloader",
|
||||
.product = "TREZOR",
|
||||
.serial_number = "",
|
||||
.configuration = "",
|
||||
.interface = "TREZOR Interface",
|
||||
|
@ -300,6 +300,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
||||
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_VENDOR)) {
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -311,11 +312,14 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
||||
't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[]
|
||||
};
|
||||
USBD_CtlSendData(dev, UNCONST(webusb_url), sizeof(webusb_url));
|
||||
return USBD_OK;
|
||||
} else {
|
||||
USBD_CtlError(dev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
#if USE_WINUSB
|
||||
else
|
||||
if (req->bRequest == USB_WINUSB_VENDOR_CODE) {
|
||||
if (req->wIndex == USB_WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR) {
|
||||
static const uint8_t winusb_wcid[] = {
|
||||
@ -333,7 +337,9 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
|
||||
};
|
||||
USBD_CtlSendData(dev, UNCONST(winusb_wcid), sizeof(winusb_wcid));
|
||||
return USBD_OK;
|
||||
} else {
|
||||
USBD_CtlError(dev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
@ -359,14 +365,16 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
||||
'{', 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));
|
||||
return USBD_OK;
|
||||
} else {
|
||||
USBD_CtlError(dev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (req->wIndex >= USBD_MAX_NUM_INTERFACES) {
|
||||
} else if (req->wIndex >= USBD_MAX_NUM_INTERFACES) {
|
||||
USBD_CtlError(dev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
switch (usb_ifaces[req->wIndex].type) {
|
||||
@ -377,6 +385,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
||||
case USB_IFACE_TYPE_WEBUSB:
|
||||
return usb_webusb_class_setup(dev, &usb_ifaces[req->wIndex].webusb, req);
|
||||
default:
|
||||
USBD_CtlError(dev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
|
@ -242,6 +242,7 @@ static void usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state
|
||||
}
|
||||
|
||||
static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) {
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
|
||||
// Class request
|
||||
@ -250,19 +251,21 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
|
||||
|
||||
case USB_HID_REQ_SET_PROTOCOL:
|
||||
state->protocol = req->wValue;
|
||||
break;
|
||||
USBD_CtlSendStatus(dev);
|
||||
return USBD_OK;
|
||||
|
||||
case USB_HID_REQ_GET_PROTOCOL:
|
||||
USBD_CtlSendData(dev, &state->protocol, sizeof(state->protocol));
|
||||
break;
|
||||
return USBD_OK;
|
||||
|
||||
case USB_HID_REQ_SET_IDLE:
|
||||
state->idle_rate = req->wValue >> 8;
|
||||
break;
|
||||
USBD_CtlSendStatus(dev);
|
||||
return USBD_OK;
|
||||
|
||||
case USB_HID_REQ_GET_IDLE:
|
||||
USBD_CtlSendData(dev, &state->idle_rate, sizeof(state->idle_rate));
|
||||
break;
|
||||
return USBD_OK;
|
||||
|
||||
default:
|
||||
USBD_CtlError(dev, req);
|
||||
@ -276,24 +279,33 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
state->alt_setting = req->wValue;
|
||||
break;
|
||||
USBD_CtlSendStatus(dev);
|
||||
return USBD_OK;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
|
||||
break;
|
||||
return USBD_OK;
|
||||
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
switch (req->wValue >> 8) {
|
||||
|
||||
case USB_DESC_TYPE_HID:
|
||||
USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN(req->wLength, sizeof(state->desc_block->hid)));
|
||||
break;
|
||||
return USBD_OK;
|
||||
|
||||
case USB_DESC_TYPE_REPORT:
|
||||
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len));
|
||||
break;
|
||||
return USBD_OK;
|
||||
|
||||
default:
|
||||
USBD_CtlError(dev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(dev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -356,22 +356,16 @@ static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
switch (req->bmRequest & USB_REQ_DIR_MASK) {
|
||||
case USB_REQ_DIR_D2H:
|
||||
switch (req->bRequest) {
|
||||
case USB_CDC_GET_LINE_CODING:
|
||||
USBD_CtlSendData(dev, UNCONST(&line_coding), MIN(req->wLength, sizeof(line_coding)));
|
||||
break;
|
||||
default:
|
||||
USBD_CtlSendData(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_REQ_DIR_H2D:
|
||||
if (req->wLength > 0) {
|
||||
USBD_CtlPrepareRx(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
|
||||
}
|
||||
break;
|
||||
if ((req->bmRequest & USB_REQ_DIR_MASK) == USB_REQ_DIR_D2H) {
|
||||
if (req->bRequest == USB_CDC_GET_LINE_CODING) {
|
||||
USBD_CtlSendData(dev, UNCONST(&line_coding), MIN(req->wLength, sizeof(line_coding)));
|
||||
} else {
|
||||
USBD_CtlSendData(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
|
||||
}
|
||||
} else { // USB_REQ_DIR_H2D
|
||||
if (req->wLength > 0) {
|
||||
USBD_CtlPrepareRx(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
|
||||
}
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
|
@ -217,24 +217,22 @@ 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) {
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
|
||||
// Interface & Endpoint request
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest) {
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
state->alt_setting = req->wValue;
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if ((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) {
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
switch (req->bRequest) {
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
state->alt_setting = req->wValue;
|
||||
USBD_CtlSendStatus(dev);
|
||||
return USBD_OK;
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
|
||||
return USBD_OK;
|
||||
default:
|
||||
USBD_CtlError(dev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_webusb_class_data_in(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, uint8_t ep_num) {
|
||||
|
Loading…
Reference in New Issue
Block a user