Initial WebUSB support

This commit is contained in:
William Toohey
2017-01-08 22:09:38 +10:00
parent 1e6af1b80d
commit ecfb31463a
3 changed files with 101 additions and 9 deletions
+90 -3
View File
@@ -1,5 +1,8 @@
#include "Descriptors.h"
#define WEBUSB_ID 0x01
#define MS_OS_ID 0x02
const USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
{
HID_RI_USAGE_PAGE(16, 0xFFDC), /* Vendor Page 0xDC */
@@ -72,7 +75,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(1,1,0),
.USBSpecification = VERSION_BCD(2,1,0),
.Class = USB_CSCP_NoDeviceClass,
.SubClass = USB_CSCP_NoDeviceSubclass,
.Protocol = USB_CSCP_NoDeviceProtocol,
@@ -90,6 +93,35 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
};
const uint8_t PROGMEM MS_OS_Descriptor[] =
{
MS_OS_DESCRIPTOR_SET(
MS_OS_CONFIG_SUBSET_HEADER(0x00, // Config 0
MS_OS_FUNCTION_SUBSET_HEADER(INTERFACE_ID_Generic, // Interface ID
MS_OS_COMPAT_ID_WINUSB
)
)
)
};
const uint8_t PROGMEM WebUSBAllowedOrigins[] = {
WEBUSB_ALLOWED_ORIGINS_HEADER(1, // 1 config header present
WEBUSB_CONFIG_SUBSET_HEADER(0x00, 1, // Config 0, 1 function header
// Config interface accessible from the web, two valid URLs
WEBUSB_FUNCTION_SUBSET_HEADER(INTERFACE_ID_Generic, URL_ID_Config, URL_ID_Localhost)
)
)
};
const uint8_t PROGMEM BOSDescriptor[] =
{
BOS_DESCRIPTOR(2, // 2 capability descriptors in use
WEBUSB_CAPABILITY_DESCRIPTOR(WEBUSB_ID, URL_ID_Config), // Vendor request ID, URL ID
// Required to force WinUSB driver for driverless WebUSB compatibility
MS_OS_20_CAPABILITY_DESCRIPTOR(MS_OS_ID, sizeof(MS_OS_Descriptor)) // Vendor request ID, Descriptor set length
)
};
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
.Config =
@@ -256,6 +288,10 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
},
};
const USB_Descriptor_URL_t PROGMEM ConfigURL = URL_STRING_DESCRIPTOR(URL_HTTPS, "mon.im/sdvx/config");
const USB_Descriptor_URL_t PROGMEM LocalhostURL = URL_STRING_DESCRIPTOR(URL_HTTP, "localhost");
const USB_Descriptor_String_t PROGMEM LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);
const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR(L"mon.im");
const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"Pocket Voltex");
@@ -296,6 +332,54 @@ const USB_Descriptor_String_t PROGMEM LEDString_indiv[] = {
USB_STRING_DESCRIPTOR(L"FX-R"),
};
void USB_Process_BOS(void) {
const void* Address = NULL;
uint16_t Size = 0;
if(!(Endpoint_IsSETUPReceived()) ||
USB_ControlRequest.bmRequestType != (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE)) {
return;
}
switch(USB_ControlRequest.bRequest) {
case WEBUSB_ID:
switch(USB_ControlRequest.wIndex) {
case WEBUSB_REQUEST_GET_ALLOWED_ORIGINS:
Address = &WebUSBAllowedOrigins;
Size = sizeof(WebUSBAllowedOrigins);
break;
case WEBUSB_REQUEST_GET_URL:
switch(USB_ControlRequest.wValue) {
case URL_ID_Localhost:
Address = &LocalhostURL;
Size = pgm_read_byte(&LocalhostURL.Header.Size);
break;
case URL_ID_Config:
Address = &ConfigURL;
Size = pgm_read_byte(&ConfigURL.Header.Size);
break;
}
break;
}
break;
case MS_OS_ID:
if(USB_ControlRequest.wIndex == MS_OS_20_DESCRIPTOR_INDEX) {
Address = &MS_OS_Descriptor;
Size = sizeof(MS_OS_Descriptor);
}
break;
default:
return;
}
if(Address != NULL) {
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
Endpoint_ClearSETUP();
Endpoint_Write_Control_PStream_LE(Address, Size);
Endpoint_ClearOUT();
}
}
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
@@ -303,7 +387,7 @@ const USB_Descriptor_String_t PROGMEM LEDString_indiv[] = {
* USB host.
*/
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint8_t wIndex,
const uint16_t wIndex,
const void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
@@ -322,6 +406,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
Address = &ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t);
break;
case DTYPE_BOS:
Address = &BOSDescriptor;
Size = sizeof(BOSDescriptor);
break;
case DTYPE_String:
switch (DescriptorNumber)
{
@@ -355,7 +443,6 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
Size = pgm_read_byte(&LEDString_indiv[STRING_ID_LED_INDIV - DescriptorNumber].Header.Size);
}
}
break;
case HID_DTYPE_HID:
Size = sizeof(USB_HID_Descriptor_HID_t);
+10 -6
View File
@@ -74,9 +74,7 @@
USB_Descriptor_Endpoint_t HID4_ReportINEndpoint;
} USB_Descriptor_Configuration_t;
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
* should have a unique ID index associated with it, which can be used to refer to the
* interface from other descriptors.
/** Enum for the device interface descriptor IDs within the device.
*/
enum InterfaceDescriptors_t
{
@@ -87,8 +85,6 @@
};
/** Enum for the device string descriptor IDs within the device. Each string descriptor should
* have a unique ID index associated with it, which can be used to refer to the string from
* other descriptors.
*/
enum StringDescriptors_t
{
@@ -100,6 +96,12 @@
STRING_ID_LED = 5, /**< LED string ID */
STRING_ID_LED_INDIV = 6,
};
enum URLDescriptors_t
{
URL_ID_Localhost = 1,
URL_ID_Config = 2,
};
/* Macros: */
#define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 1)
@@ -117,9 +119,11 @@
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint8_t wIndex,
const uint16_t wIndex,
const void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
void USB_Process_BOS(void);
#endif
+1
View File
@@ -360,6 +360,7 @@ void EVENT_USB_Device_ConfigurationChanged(void)
/** Event handler for the library USB Control Request reception event. */
void EVENT_USB_Device_ControlRequest(void)
{
USB_Process_BOS();
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
HID_Device_ProcessControlRequest(&Mouse_HID_Interface);
HID_Device_ProcessControlRequest(&Generic_HID_Interface);