|
|
|
@ -227,13 +227,44 @@ 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 const char url[] = {
|
|
|
|
|
static const char webusb_url[] = {
|
|
|
|
|
3 + 15, // uint8_t bLength
|
|
|
|
|
USB_WEBUSB_DESCRIPTOR_TYPE_URL, // uint8_t bDescriptorType
|
|
|
|
|
USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme
|
|
|
|
|
't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#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) {
|
|
|
|
|
|
|
|
|
|
case USB_REQ_TYPE_VENDOR: // Vendor request
|
|
|
|
@ -244,13 +275,26 @@ static int usb_webusb_class_setup(USBD_HandleTypeDef *dev, usb_webusb_state_t *s
|
|
|
|
|
case USB_WEBUSB_REQ_GET_URL:
|
|
|
|
|
// we should check whether req->wValue == USB_WEBUSB_LANDING_PAGE,
|
|
|
|
|
// but let's return always the same url for all indexes
|
|
|
|
|
USBD_CtlSendData(dev, UNCONST(url), sizeof(url));
|
|
|
|
|
USBD_CtlSendData(dev, UNCONST(webusb_url), sizeof(webusb_url));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
USBD_CtlError(dev, req);
|
|
|
|
|
return USBD_FAIL;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#if USE_WINUSB
|
|
|
|
|
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;
|
|
|
|
|
#endif
|
|
|
|
|
default:
|
|
|
|
|
USBD_CtlError(dev, req);
|
|
|
|
|
return USBD_FAIL;
|
|
|
|
|