Commit e9d9fcde authored by Dean Camera's avatar Dean Camera
Browse files

Add MS OS Compatibility descriptors to RNDIS demos for driverless install on Windows.

parent 086975bd
...@@ -46,7 +46,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = ...@@ -46,7 +46,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(1,1,0), .USBSpecification = VERSION_BCD(2,0,0),
.Class = CDC_CSCP_CDCClass, .Class = CDC_CSCP_CDCClass,
.SubClass = CDC_CSCP_NoSpecificSubclass, .SubClass = CDC_CSCP_NoSpecificSubclass,
.Protocol = CDC_CSCP_NoSpecificProtocol, .Protocol = CDC_CSCP_NoSpecificProtocol,
...@@ -55,7 +55,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = ...@@ -55,7 +55,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x204C, .ProductID = 0x204C,
.ReleaseNumber = VERSION_BCD(0,0,1), .ReleaseNumber = VERSION_BCD(0,0,2),
.ManufacturerStrIndex = STRING_ID_Manufacturer, .ManufacturerStrIndex = STRING_ID_Manufacturer,
.ProductStrIndex = STRING_ID_Product, .ProductStrIndex = STRING_ID_Product,
...@@ -192,6 +192,32 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR ...@@ -192,6 +192,32 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR
*/ */
const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA RNDIS CDC Demo"); const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA RNDIS CDC Demo");
/** Microsoft OS Compatibility string descriptor. This is a special string descriptor that Microsoft based OS hosts
* will query at string descriptor ID 0xEE on initial enumeration, to test if the device supports the Microsoft OS
* Compatibility descriptor extensions (used to give the host additional information on the device's general class
* compatibility for driver-less installation).
*/
const USB_Descriptor_String_t PROGMEM MSConpatibilityString = USB_STRING_DESCRIPTOR_ARRAY('M','S','F','T','1','0','0', VENDOR_REQUEST_ID_MS_COMPAT);
/** Microsoft OS Compatibility 1.0 descriptor. This is a special descriptor returned by the device on vendor request
* from the host, giving the OS additional compatibility information. This allows the host to automatically install
* the appropriate driver for various devices which share a common USB class (in this case RNDIS, which uses the
* CDC-ACM class usually used by virtual to serial adapters).
*/
const USB_Descriptor_MSCompatibility_t PROGMEM MSCompatibilityDescriptor =
{
.dwLength = sizeof(USB_Descriptor_MSCompatibility_t),
.bcdVersion = VERSION_BCD(1,0,0),
.wIndex = 4,
.bCount = 1,
.bReserved = { 0 },
.bFirstInterfaceNumber = INTERFACE_ID_CDC_CCI,
.bReserved2 = 1, // Must always be 1 according to spec
.compatibleID = "RNDIS",
.subCompatibleID = "5162001",
.bReserved3 = { 0 },
};
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** 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 * 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 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
...@@ -233,6 +259,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, ...@@ -233,6 +259,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
Address = &ProductString; Address = &ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
case STRING_ID_MS_Compat:
Address = &MSConpatibilityString;
Size = pgm_read_byte(&MSConpatibilityString.Header.Size);
break;
} }
break; break;
...@@ -242,3 +272,20 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, ...@@ -242,3 +272,20 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
return Size; return Size;
} }
/** Sends the special Microsoft OS Compatibility Descriptor to the host PC, if
* the host is requesting it.
*/
void CheckIfMSCompatibilityDescriptorRequest(void)
{
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE))
{
if (USB_ControlRequest.bRequest == VENDOR_REQUEST_ID_MS_COMPAT)
{
Endpoint_ClearSETUP();
/* Write the OS compatibility descriptor to the control endpoint */
Endpoint_Write_Control_PStream_LE(&MSCompatibilityDescriptor, sizeof(MSCompatibilityDescriptor));
Endpoint_ClearOUT();
}
}
}
...@@ -59,6 +59,10 @@ ...@@ -59,6 +59,10 @@
/** Size in bytes of the CDC data IN and OUT endpoints. */ /** Size in bytes of the CDC data IN and OUT endpoints. */
#define CDC_TXRX_EPSIZE 64 #define CDC_TXRX_EPSIZE 64
/** Vendor request (0-255) the host should issue to retrieve the
* Microsoft OS Compatibility Descriptors. */
#define VENDOR_REQUEST_ID_MS_COMPAT 0x01
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
...@@ -81,6 +85,21 @@ ...@@ -81,6 +85,21 @@
USB_Descriptor_Endpoint_t RNDIS_DataInEndpoint; USB_Descriptor_Endpoint_t RNDIS_DataInEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/** Type define for a Microsoft OS Compatibility 1.0 descriptor. */
typedef struct
{
uint32_t dwLength;
uint16_t bcdVersion;
uint16_t wIndex;
uint8_t bCount;
uint8_t bReserved[7];
uint8_t bFirstInterfaceNumber;
uint8_t bReserved2;
char compatibleID[8];
char subCompatibleID[8];
uint8_t bReserved3[6];
} USB_Descriptor_MSCompatibility_t;
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor /** 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 * should have a unique ID index associated with it, which can be used to refer to the
* interface from other descriptors. * interface from other descriptors.
...@@ -100,6 +119,7 @@ ...@@ -100,6 +119,7 @@
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
STRING_ID_Product = 2, /**< Product string ID */ STRING_ID_Product = 2, /**< Product string ID */
STRING_ID_MS_Compat = 0xEE, /**< MS OS Compatibility string descriptor ID (magic value set by Microsoft) */
}; };
/* Function Prototypes: */ /* Function Prototypes: */
...@@ -108,5 +128,7 @@ ...@@ -108,5 +128,7 @@
const void** const DescriptorAddress) const void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
void CheckIfMSCompatibilityDescriptorRequest(void);
#endif #endif
...@@ -174,6 +174,9 @@ void EVENT_USB_Device_ConfigurationChanged(void) ...@@ -174,6 +174,9 @@ void EVENT_USB_Device_ConfigurationChanged(void)
/** Event handler for the library USB Control Request reception event. */ /** Event handler for the library USB Control Request reception event. */
void EVENT_USB_Device_ControlRequest(void) void EVENT_USB_Device_ControlRequest(void)
{ {
/* Send MS OS Compatibility descriptor if requested by the host. */
CheckIfMSCompatibilityDescriptorRequest();
RNDIS_Device_ProcessControlRequest(&Ethernet_RNDIS_Interface); RNDIS_Device_ProcessControlRequest(&Ethernet_RNDIS_Interface);
} }
...@@ -46,7 +46,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = ...@@ -46,7 +46,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(1,1,0), .USBSpecification = VERSION_BCD(2,0,0),
.Class = CDC_CSCP_CDCClass, .Class = CDC_CSCP_CDCClass,
.SubClass = CDC_CSCP_NoSpecificSubclass, .SubClass = CDC_CSCP_NoSpecificSubclass,
.Protocol = CDC_CSCP_NoSpecificProtocol, .Protocol = CDC_CSCP_NoSpecificProtocol,
...@@ -55,7 +55,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = ...@@ -55,7 +55,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x204C, .ProductID = 0x204C,
.ReleaseNumber = VERSION_BCD(0,0,1), .ReleaseNumber = VERSION_BCD(0,0,2),
.ManufacturerStrIndex = STRING_ID_Manufacturer, .ManufacturerStrIndex = STRING_ID_Manufacturer,
.ProductStrIndex = STRING_ID_Product, .ProductStrIndex = STRING_ID_Product,
...@@ -192,6 +192,32 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR ...@@ -192,6 +192,32 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR
*/ */
const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA RNDIS CDC Demo"); const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA RNDIS CDC Demo");
/** Microsoft OS Compatibility string descriptor. This is a special string descriptor that Microsoft based OS hosts
* will query at string descriptor ID 0xEE on initial enumeration, to test if the device supports the Microsoft OS
* Compatibility descriptor extensions (used to give the host additional information on the device's general class
* compatibility for driver-less installation).
*/
const USB_Descriptor_String_t PROGMEM MSConpatibilityString = USB_STRING_DESCRIPTOR_ARRAY('M','S','F','T','1','0','0', VENDOR_REQUEST_ID_MS_COMPAT);
/** Microsoft OS Compatibility 1.0 descriptor. This is a special descriptor returned by the device on vendor request
* from the host, giving the OS additional compatibility information. This allows the host to automatically install
* the appropriate driver for various devices which share a common USB class (in this case RNDIS, which uses the
* CDC-ACM class usually used by virtual to serial adapters).
*/
const USB_Descriptor_MSCompatibility_t PROGMEM MSCompatibilityDescriptor =
{
.dwLength = sizeof(USB_Descriptor_MSCompatibility_t),
.bcdVersion = VERSION_BCD(1,0,0),
.wIndex = 4,
.bCount = 1,
.bReserved = { 0 },
.bFirstInterfaceNumber = INTERFACE_ID_CDC_CCI,
.bReserved2 = 1, // Must always be 1 according to spec
.compatibleID = "RNDIS",
.subCompatibleID = "5162001",
.bReserved3 = { 0 },
};
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** 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 * 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 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
...@@ -233,6 +259,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, ...@@ -233,6 +259,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
Address = &ProductString; Address = &ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
case STRING_ID_MS_Compat:
Address = &MSConpatibilityString;
Size = pgm_read_byte(&MSConpatibilityString.Header.Size);
break;
} }
break; break;
...@@ -242,3 +272,20 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, ...@@ -242,3 +272,20 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
return Size; return Size;
} }
/** Sends the special Microsoft OS Compatibility Descriptor to the host PC, if
* the host is requesting it.
*/
void CheckIfMSCompatibilityDescriptorRequest(void)
{
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE))
{
if (USB_ControlRequest.bRequest == VENDOR_REQUEST_ID_MS_COMPAT)
{
Endpoint_ClearSETUP();
/* Write the OS compatibility descriptor to the control endpoint */
Endpoint_Write_Control_PStream_LE(&MSCompatibilityDescriptor, sizeof(MSCompatibilityDescriptor));
Endpoint_ClearOUT();
}
}
}
...@@ -59,6 +59,10 @@ ...@@ -59,6 +59,10 @@
/** Size in bytes of the CDC device-to-host notification IN endpoint. */ /** Size in bytes of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPSIZE 8 #define CDC_NOTIFICATION_EPSIZE 8
/** Vendor request (0-255) the host should issue to retrieve the
* Microsoft OS Compatibility Descriptors. */
#define VENDOR_REQUEST_ID_MS_COMPAT 0x01
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
...@@ -81,6 +85,21 @@ ...@@ -81,6 +85,21 @@
USB_Descriptor_Endpoint_t RNDIS_DataInEndpoint; USB_Descriptor_Endpoint_t RNDIS_DataInEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/** Type define for a Microsoft OS Compatibility 1.0 descriptor. */
typedef struct
{
uint32_t dwLength;
uint16_t bcdVersion;
uint16_t wIndex;
uint8_t bCount;
uint8_t bReserved[7];
uint8_t bFirstInterfaceNumber;
uint8_t bReserved2;
char compatibleID[8];
char subCompatibleID[8];
uint8_t bReserved3[6];
} USB_Descriptor_MSCompatibility_t;
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor /** 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 * should have a unique ID index associated with it, which can be used to refer to the
* interface from other descriptors. * interface from other descriptors.
...@@ -100,6 +119,7 @@ ...@@ -100,6 +119,7 @@
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
STRING_ID_Product = 2, /**< Product string ID */ STRING_ID_Product = 2, /**< Product string ID */
STRING_ID_MS_Compat = 0xEE, /**< MS OS Compatibility string descriptor ID (magic value set by Microsoft) */
}; };
/* Function Prototypes: */ /* Function Prototypes: */
...@@ -108,5 +128,7 @@ ...@@ -108,5 +128,7 @@
const void** const DescriptorAddress) const void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
void CheckIfMSCompatibilityDescriptorRequest(void);
#endif #endif
...@@ -130,6 +130,9 @@ void EVENT_USB_Device_ConfigurationChanged(void) ...@@ -130,6 +130,9 @@ void EVENT_USB_Device_ConfigurationChanged(void)
*/ */
void EVENT_USB_Device_ControlRequest(void) void EVENT_USB_Device_ControlRequest(void)
{ {
/* Send MS OS Compatibility descriptor if requested by the host. */
CheckIfMSCompatibilityDescriptorRequest();
/* Process RNDIS class commands */ /* Process RNDIS class commands */
switch (USB_ControlRequest.bRequest) switch (USB_ControlRequest.bRequest)
{ {
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
* <b>New:</b> * <b>New:</b>
* - Core: * - Core:
* - The USE_INTERNAL_SERIAL definition can now be overridden by the user to a custom string index (thanks to Nicohood) * - The USE_INTERNAL_SERIAL definition can now be overridden by the user to a custom string index (thanks to Nicohood)
* - Library Applications:
* - Added Microsoft OS Compatibility descriptors to the RNDIS demos for driverless install on Windows 7 and newer
* *
* <b>Fixed:</b> * <b>Fixed:</b>
* - Core: * - Core:
......
...@@ -47,7 +47,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = ...@@ -47,7 +47,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(1,1,0), .USBSpecification = VERSION_BCD(2,0,0),
.Class = USB_CSCP_IADDeviceClass, .Class = USB_CSCP_IADDeviceClass,
.SubClass = USB_CSCP_IADDeviceSubclass, .SubClass = USB_CSCP_IADDeviceSubclass,
.Protocol = USB_CSCP_IADDeviceProtocol, .Protocol = USB_CSCP_IADDeviceProtocol,
...@@ -56,7 +56,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = ...@@ -56,7 +56,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2069, .ProductID = 0x2069,
.ReleaseNumber = VERSION_BCD(0,0,1), .ReleaseNumber = VERSION_BCD(0,0,2),
.ManufacturerStrIndex = STRING_ID_Manufacturer, .ManufacturerStrIndex = STRING_ID_Manufacturer,
.ProductStrIndex = STRING_ID_Product, .ProductStrIndex = STRING_ID_Product,
...@@ -243,6 +243,32 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR ...@@ -243,6 +243,32 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR
*/ */
const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA Webserver"); const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA Webserver");
/** Microsoft OS Compatibility string descriptor. This is a special string descriptor that Microsoft based OS hosts
* will query at string descriptor ID 0xEE on initial enumeration, to test if the device supports the Microsoft OS
* Compatibility descriptor extensions (used to give the host additional information on the device's general class
* compatibility for driver-less installation).
*/
const USB_Descriptor_String_t PROGMEM MSConpatibilityString = USB_STRING_DESCRIPTOR_ARRAY('M','S','F','T','1','0','0', VENDOR_REQUEST_ID_MS_COMPAT);
/** Microsoft OS Compatibility 1.0 descriptor. This is a special descriptor returned by the device on vendor request
* from the host, giving the OS additional compatibility information. This allows the host to automatically install
* the appropriate driver for various devices which share a common USB class (in this case RNDIS, which uses the
* CDC-ACM class usually used by virtual to serial adapters).
*/
const USB_Descriptor_MSCompatibility_t PROGMEM MSCompatibilityDescriptor =
{
.dwLength = sizeof(USB_Descriptor_MSCompatibility_t),
.bcdVersion = VERSION_BCD(1,0,0),
.wIndex = 4,
.bCount = 1,
.bReserved = { 0 },
.bFirstInterfaceNumber = INTERFACE_ID_CDC_CCI,
.bReserved2 = 1, // Must always be 1 according to spec
.compatibleID = "RNDIS",
.subCompatibleID = "5162001",
.bReserved3 = { 0 },
};
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** 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 * 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 * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
...@@ -284,6 +310,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, ...@@ -284,6 +310,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
Address = &ProductString; Address = &ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
case STRING_ID_MS_Compat:
Address = &MSConpatibilityString;
Size = pgm_read_byte(&MSConpatibilityString.Header.Size);
break;
} }
break; break;
...@@ -293,3 +323,20 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, ...@@ -293,3 +323,20 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
return Size; return Size;
} }
/** Sends the special Microsoft OS Compatibility Descriptor to the host PC, if
* the host is requesting it.
*/
void CheckIfMSCompatibilityDescriptorRequest(void)
{
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE))
{
if (USB_ControlRequest.bRequest == VENDOR_REQUEST_ID_MS_COMPAT)
{
Endpoint_ClearSETUP();
/* Write the OS compatibility descriptor to the control endpoint */
Endpoint_Write_Control_PStream_LE(&MSCompatibilityDescriptor, sizeof(MSCompatibilityDescriptor));
Endpoint_ClearOUT();
}
}
}
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
/** Size in bytes of the CDC data IN and OUT endpoints. */ /** Size in bytes of the CDC data IN and OUT endpoints. */
#define CDC_TXRX_EPSIZE 64 #define CDC_TXRX_EPSIZE 64
/** Vendor request (0-255) the host should issue to retrieve the
* Microsoft OS Compatibility Descriptors. */
#define VENDOR_REQUEST_ID_MS_COMPAT 0x01
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
...@@ -96,6 +100,21 @@ ...@@ -96,6 +100,21 @@
USB_Descriptor_Endpoint_t MS_DataOutEndpoint; USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/** Type define for a Microsoft OS Compatibility 1.0 descriptor. */
typedef struct
{
uint32_t dwLength;
uint16_t bcdVersion;
uint16_t wIndex;
uint8_t bCount;
uint8_t bReserved[7];
uint8_t bFirstInterfaceNumber;
uint8_t bReserved2;
char compatibleID[8];
char subCompatibleID[8];
uint8_t bReserved3[6];
} USB_Descriptor_MSCompatibility_t;
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor /** 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 * should have a unique ID index associated with it, which can be used to refer to the
* interface from other descriptors. * interface from other descriptors.
...@@ -116,6 +135,7 @@ ...@@ -116,6 +135,7 @@
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
STRING_ID_Product = 2, /**< Product string ID */ STRING_ID_Product = 2, /**< Product string ID */
STRING_ID_MS_Compat = 0xEE, /**< MS OS Compatibility string descriptor ID (magic value set by Microsoft) */
}; };
/* Function Prototypes: */ /* Function Prototypes: */
...@@ -124,5 +144,7 @@ ...@@ -124,5 +144,7 @@
const void** const DescriptorAddress) const void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
void CheckIfMSCompatibilityDescriptorRequest(void);
#endif #endif
...@@ -141,6 +141,9 @@ void EVENT_USB_Device_ConfigurationChanged(void) ...@@ -141,6 +141,9 @@ void EVENT_USB_Device_ConfigurationChanged(void)
/** Event handler for the library USB Control Request reception event. */ /** Event handler for the library USB Control Request reception event. */
void EVENT_USB_Device_ControlRequest(void) void EVENT_USB_Device_ControlRequest(void)
{ {
/* Send MS OS Compatibility descriptor if requested by the host. */
CheckIfMSCompatibilityDescriptorRequest();
RNDIS_Device_ProcessControlRequest(&Ethernet_RNDIS_Interface_Device); RNDIS_Device_ProcessControlRequest(&Ethernet_RNDIS_Interface_Device);
MS_Device_ProcessControlRequest(&Disk_MS_Interface); MS_Device_ProcessControlRequest(&Disk_MS_Interface);
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment