trezorhal: add configuration, interface strings to usb descriptors, minor typos

pull/25/head
Pavol Rusnak 6 years ago
parent 08376a4a54
commit 30ff61b588
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -134,6 +134,8 @@ static void usb_init_all(void) {
.manufacturer = (const uint8_t *)"SatoshiLabs",
.product = (const uint8_t *)"TREZOR Bootloader",
.serial_number = (const uint8_t *)"",
.configuration = (const uint8_t *)"",
.interface = (const uint8_t *)"TREZOR Interface",
};
static uint8_t hid_rx_buffer[USB_PACKET_SIZE];
static const uint8_t hid_report_desc[] = {

@ -327,9 +327,11 @@ static const char *get_0str(mp_obj_t o, size_t min_len, size_t max_len) {
/// vendor_id: int,
/// product_id: int,
/// release_num: int,
/// manufacturer: str,
/// product: str,
/// serial_number: str) -> None:
/// manufacturer: str='',
/// product: str='',
/// serial_number: str='',
/// configuration: str='',
/// interface: str='') -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
@ -338,9 +340,11 @@ STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_ar
{ MP_QSTR_vendor_id, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_product_id, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_release_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_manufacturer, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_product, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_serial_number, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_manufacturer, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_product, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_serial_number, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_configuration, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_interface, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
@ -351,9 +355,12 @@ STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_ar
const char *manufacturer = get_0str(vals[3].u_obj, 0, 32);
const char *product = get_0str(vals[4].u_obj, 0, 32);
const char *serial_number = get_0str(vals[5].u_obj, 0, 32);
const char *configuration = get_0str(vals[6].u_obj, 0, 32);
const char *interface = get_0str(vals[7].u_obj, 0, 32);
CHECK_PARAM_RANGE(vendor_id, 0, 65535)
CHECK_PARAM_RANGE(product_id, 0, 65535)
CHECK_PARAM_RANGE(release_num, 0, 65535)
if (manufacturer == NULL) {
mp_raise_ValueError("manufacturer is invalid");
}
@ -363,6 +370,12 @@ STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_ar
if (serial_number == NULL) {
mp_raise_ValueError("serial_number is invalid");
}
if (configuration == NULL) {
mp_raise_ValueError("configuration is invalid");
}
if (interface == NULL) {
mp_raise_ValueError("interface is invalid");
}
mp_obj_USB_t *o = m_new_obj(mp_obj_USB_t);
o->base.type = type;
@ -375,6 +388,8 @@ STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_ar
o->info.manufacturer = (const uint8_t *)(manufacturer);
o->info.product = (const uint8_t *)(product);
o->info.serial_number = (const uint8_t *)(serial_number);
o->info.configuration = (const uint8_t *)(configuration);
o->info.interface = (const uint8_t *)(interface);
mp_obj_list_init(&o->ifaces, 0);
return MP_OBJ_FROM_PTR(o);

@ -91,7 +91,9 @@ static void usb_init_all(void)
.release_num = 0x0002,
.manufacturer = (const uint8_t *)"SatoshiLabs",
.product = (const uint8_t *)"TREZOR",
.serial_number = (const uint8_t *)"",
.serial_number = (const uint8_t *)"000000000000",
.configuration = (const uint8_t *)"",
.interface = (const uint8_t *)"TREZOR Interface",
};
static uint8_t tx_packet[VCP_PACKET_LEN];

@ -53,8 +53,8 @@ void usb_init(const usb_dev_info_t *dev_info) {
// Device descriptor
usb_dev_desc.bLength = sizeof(usb_device_descriptor_t);
usb_dev_desc.bDescriptorType = USB_DESC_TYPE_DEVICE;
usb_dev_desc.bcdUSB = 0x0200;
usb_dev_desc.bDeviceClass = 0xef; // Composite Device Class
usb_dev_desc.bcdUSB = 0x0200; // USB 2.0
usb_dev_desc.bDeviceClass = 0xEF; // Composite Device Class
usb_dev_desc.bDeviceSubClass = 0x02; // Common Class
usb_dev_desc.bDeviceProtocol = 0x01; // Interface Association Descriptor
usb_dev_desc.bMaxPacketSize0 = USB_MAX_EP0_SIZE;
@ -74,6 +74,8 @@ void usb_init(const usb_dev_info_t *dev_info) {
usb_str_table.manufacturer = dev_info->manufacturer;
usb_str_table.product = dev_info->product;
usb_str_table.serial_number = dev_info->serial_number;
usb_str_table.configuration = dev_info->configuration;
usb_str_table.interface = dev_info->interface;
// Configuration descriptor
usb_config_desc->bLength = sizeof(usb_config_descriptor_t);
@ -81,9 +83,9 @@ void usb_init(const usb_dev_info_t *dev_info) {
usb_config_desc->wTotalLength = sizeof(usb_config_descriptor_t);
usb_config_desc->bNumInterfaces = 0;
usb_config_desc->bConfigurationValue = 0x01;
usb_config_desc->iConfiguration = 0;
usb_config_desc->bmAttributes = 0x80; // 0x80 = bus powered; 0xc0 = self powered
usb_config_desc->bMaxPower = 0xfa; // Maximum Power Consumption in 2mA units
usb_config_desc->iConfiguration = USBD_IDX_CONFIG_STR;
usb_config_desc->bmAttributes = 0x80; // 0x80 = bus powered; 0xC0 = self powered
usb_config_desc->bMaxPower = 0xFA; // Maximum Power Consumption in 2mA units
// Pointer to interface descriptor data
usb_next_iface_desc = (usb_interface_descriptor_t *)(usb_config_buf + usb_config_desc->wTotalLength);
@ -174,27 +176,27 @@ static uint8_t *usb_get_langid_str_descriptor(USBD_SpeedTypeDef speed, uint16_t
}
static uint8_t *usb_get_manufacturer_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(usb_str_table.manufacturer), usb_str_buf, length);
USBD_GetString(usb_str_table.manufacturer, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_product_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(usb_str_table.product), usb_str_buf, length);
USBD_GetString(usb_str_table.product, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_serial_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(usb_str_table.serial_number), usb_str_buf, length);
USBD_GetString(usb_str_table.serial_number, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_config_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(""), usb_str_buf, length);
static uint8_t *usb_get_configuration_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(usb_str_table.configuration, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_interface_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(""), usb_str_buf, length);
USBD_GetString(usb_str_table.interface, usb_str_buf, length);
return usb_str_buf;
}
@ -204,7 +206,7 @@ static const USBD_DescriptorsTypeDef usb_descriptors = {
.GetManufacturerStrDescriptor = usb_get_manufacturer_str_descriptor,
.GetProductStrDescriptor = usb_get_product_str_descriptor,
.GetSerialStrDescriptor = usb_get_serial_str_descriptor,
.GetConfigurationStrDescriptor = usb_get_config_str_descriptor,
.GetConfigurationStrDescriptor = usb_get_configuration_str_descriptor,
.GetInterfaceStrDescriptor = usb_get_interface_str_descriptor,
};
@ -231,14 +233,14 @@ static uint8_t usb_class_init(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID:
usb_hid_class_deinit(dev, &usb_ifaces[i].hid, cfg_idx);
break;
case USB_IFACE_TYPE_VCP:
usb_vcp_class_deinit(dev, &usb_ifaces[i].vcp, cfg_idx);
break;
default:
break;
case USB_IFACE_TYPE_HID:
usb_hid_class_deinit(dev, &usb_ifaces[i].hid, cfg_idx);
break;
case USB_IFACE_TYPE_VCP:
usb_vcp_class_deinit(dev, &usb_ifaces[i].vcp, cfg_idx);
break;
default:
break;
}
}
return USBD_OK;
@ -253,26 +255,26 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
return USBD_FAIL;
}
switch (usb_ifaces[req->wIndex].type) {
case USB_IFACE_TYPE_HID:
return usb_hid_class_setup(dev, &usb_ifaces[req->wIndex].hid, req);
case USB_IFACE_TYPE_VCP:
return usb_vcp_class_setup(dev, &usb_ifaces[req->wIndex].vcp, req);
default:
return USBD_FAIL;
case USB_IFACE_TYPE_HID:
return usb_hid_class_setup(dev, &usb_ifaces[req->wIndex].hid, req);
case USB_IFACE_TYPE_VCP:
return usb_vcp_class_setup(dev, &usb_ifaces[req->wIndex].vcp, req);
default:
return USBD_FAIL;
}
}
static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID:
usb_hid_class_data_in(dev, &usb_ifaces[i].hid, ep_num);
break;
case USB_IFACE_TYPE_VCP:
usb_vcp_class_data_in(dev, &usb_ifaces[i].vcp, ep_num);
break;
default:
break;
case USB_IFACE_TYPE_HID:
usb_hid_class_data_in(dev, &usb_ifaces[i].hid, ep_num);
break;
case USB_IFACE_TYPE_VCP:
usb_vcp_class_data_in(dev, &usb_ifaces[i].vcp, ep_num);
break;
default:
break;
}
}
return USBD_OK;
@ -281,14 +283,14 @@ static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID:
usb_hid_class_data_out(dev, &usb_ifaces[i].hid, ep_num);
break;
case USB_IFACE_TYPE_VCP:
usb_vcp_class_data_out(dev, &usb_ifaces[i].vcp, ep_num);
break;
default:
break;
case USB_IFACE_TYPE_HID:
usb_hid_class_data_out(dev, &usb_ifaces[i].hid, ep_num);
break;
case USB_IFACE_TYPE_VCP:
usb_vcp_class_data_out(dev, &usb_ifaces[i].vcp, ep_num);
break;
default:
break;
}
}
return USBD_OK;
@ -297,11 +299,11 @@ static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_VCP:
usb_vcp_class_sof(dev, &usb_ifaces[i].vcp);
break;
default:
break;
case USB_IFACE_TYPE_VCP:
usb_vcp_class_sof(dev, &usb_ifaces[i].vcp);
break;
default:
break;
}
}
return USBD_OK;

@ -89,6 +89,8 @@ typedef struct {
const uint8_t *manufacturer;
const uint8_t *product;
const uint8_t *serial_number;
const uint8_t *configuration;
const uint8_t *interface;
} usb_dev_string_table_t;
typedef struct {
@ -98,6 +100,8 @@ typedef struct {
const uint8_t *manufacturer;
const uint8_t *product;
const uint8_t *serial_number;
const uint8_t *configuration;
const uint8_t *interface;
} usb_dev_info_t;
typedef enum {

@ -56,12 +56,12 @@ secbool usb_hid_add(const usb_hid_info_t *info) {
d->iface.bInterfaceClass = USB_CLASS_HID;
d->iface.bInterfaceSubClass = info->subclass;
d->iface.bInterfaceProtocol = info->protocol;
d->iface.iInterface = 0;
d->iface.iInterface = USBD_IDX_INTERFACE_STR;
// HID descriptor
d->hid.bLength = sizeof(usb_hid_descriptor_t);
d->hid.bDescriptorType = USB_DESC_TYPE_HID;
d->hid.bcdHID = 0x1101; // HID Class Spec release number
d->hid.bcdHID = 0x0111; // HID Class Spec release number (1.11)
d->hid.bCountryCode = 0; // Hardware target country
d->hid.bNumDescriptors = 1; // Number of HID class descriptors
d->hid.bReportDescriptorType = USB_DESC_TYPE_REPORT;
@ -244,58 +244,58 @@ 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
case USB_REQ_TYPE_CLASS:
switch (req->bRequest) {
// Class request
case USB_REQ_TYPE_CLASS:
switch (req->bRequest) {
case USB_HID_REQ_SET_PROTOCOL:
state->protocol = req->wValue;
break;
case USB_HID_REQ_SET_PROTOCOL:
state->protocol = req->wValue;
break;
case USB_HID_REQ_GET_PROTOCOL:
USBD_CtlSendData(dev, &state->protocol, sizeof(state->protocol));
break;
case USB_HID_REQ_GET_PROTOCOL:
USBD_CtlSendData(dev, &state->protocol, sizeof(state->protocol));
break;
case USB_HID_REQ_SET_IDLE:
state->idle_rate = req->wValue >> 8;
break;
case USB_HID_REQ_SET_IDLE:
state->idle_rate = req->wValue >> 8;
break;
case USB_HID_REQ_GET_IDLE:
USBD_CtlSendData(dev, &state->idle_rate, sizeof(state->idle_rate));
break;
case USB_HID_REQ_GET_IDLE:
USBD_CtlSendData(dev, &state->idle_rate, sizeof(state->idle_rate));
break;
default:
USBD_CtlError(dev, req);
return USBD_FAIL;
}
break;
default:
USBD_CtlError(dev, req);
return USBD_FAIL;
}
break;
// Interface & Endpoint request
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
// 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_SET_INTERFACE:
state->alt_setting = req->wValue;
break;
case USB_REQ_GET_INTERFACE:
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
break;
case USB_REQ_GET_INTERFACE:
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
break;
case USB_REQ_GET_DESCRIPTOR:
switch (req->wValue >> 8) {
case USB_REQ_GET_DESCRIPTOR:
switch (req->wValue >> 8) {
case USB_DESC_TYPE_HID:
USBD_CtlSendData(dev, (uint8_t *)&state->desc_block->hid, MIN(req->wLength, sizeof(state->desc_block->hid)));
break;
case USB_DESC_TYPE_HID:
USBD_CtlSendData(dev, (uint8_t *)&state->desc_block->hid, MIN(req->wLength, sizeof(state->desc_block->hid)));
break;
case USB_DESC_TYPE_REPORT:
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len));
break;
case USB_DESC_TYPE_REPORT:
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len));
break;
}
break;
}
break;
}
break;
}
return USBD_OK;

@ -18,7 +18,7 @@
#define USB_CDC_PROTOCOL_AT 0x01
// Descriptor Types (bDescriptorType)
#define USB_DESC_TYPE_ASSOCIATION 0x0b
#define USB_DESC_TYPE_ASSOCIATION 0x0B
#define USB_DESC_TYPE_CS_INTERACE 0x24
// Descriptor SubTypes (bDescriptorSubtype)
@ -106,7 +106,7 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
d->iface_cdc.bInterfaceClass = USB_CLASS_CDC;
d->iface_cdc.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM;
d->iface_cdc.bInterfaceProtocol = USB_CDC_PROTOCOL_AT;
d->iface_cdc.iInterface = 0;
d->iface_cdc.iInterface = USBD_IDX_INTERFACE_STR;
// Header Functional Descriptor
d->fheader.bFunctionLength = sizeof(usb_vcp_header_descriptor_t);
@ -155,7 +155,7 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
d->iface_data.bInterfaceClass = USB_CLASS_DATA;
d->iface_data.bInterfaceSubClass = 0;
d->iface_data.bInterfaceProtocol = 0;
d->iface_data.iInterface = 0;
d->iface_data.iInterface = USBD_IDX_INTERFACE_STR;
// OUT endpoint (receiving)
d->ep_out.bLength = sizeof(usb_endpoint_descriptor_t);
@ -357,21 +357,21 @@ static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
}
switch (req->bmRequest & USB_REQ_DIR_MASK) {
case USB_D2H:
switch (req->bRequest) {
case USB_CDC_GET_LINE_CODING:
USBD_CtlSendData(dev, (uint8_t *)(&line_coding), MIN(req->wLength, sizeof(line_coding)));
case USB_D2H:
switch (req->bRequest) {
case USB_CDC_GET_LINE_CODING:
USBD_CtlSendData(dev, (uint8_t *)(&line_coding), MIN(req->wLength, sizeof(line_coding)));
break;
default:
USBD_CtlSendData(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
break;
}
break;
default:
USBD_CtlSendData(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
case USB_H2D:
if (req->wLength > 0) {
USBD_CtlPrepareRx(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
}
break;
}
break;
case USB_H2D:
if (req->wLength > 0) {
USBD_CtlPrepareRx(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
}
break;
}
return USBD_OK;

@ -97,7 +97,7 @@ static void USBD_SetFeature(USBD_HandleTypeDef *pdev ,
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev ,
USBD_SetupReqTypedef *req);
static uint8_t USBD_GetLen(uint8_t *buf);
static uint8_t USBD_GetLen(const uint8_t *buf);
/**
* @}
@ -729,7 +729,7 @@ void USBD_CtlError( USBD_HandleTypeDef *pdev ,
* @param len : descriptor length
* @retval None
*/
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
void USBD_GetString(const uint8_t *desc, uint8_t *unicode, uint16_t *len)
{
uint8_t idx = 0;
@ -753,7 +753,7 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
* @param buf : pointer to the ascii string buffer
* @retval string length
*/
static uint8_t USBD_GetLen(uint8_t *buf)
static uint8_t USBD_GetLen(const uint8_t *buf)
{
uint8_t len = 0;

@ -90,7 +90,7 @@ void USBD_CtlError (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata);
void USBD_GetString (uint8_t *desc, uint8_t *unicode, uint16_t *len);
void USBD_GetString (const uint8_t *desc, uint8_t *unicode, uint16_t *len);
/**
* @}
*/

Loading…
Cancel
Save