diff options
Diffstat (limited to 'Demos/Device/ClassDriver')
| -rw-r--r-- | Demos/Device/ClassDriver/RNDISEthernet/Descriptors.c | 51 | ||||
| -rw-r--r-- | Demos/Device/ClassDriver/RNDISEthernet/Descriptors.h | 22 | ||||
| -rw-r--r-- | Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c | 3 | 
3 files changed, 74 insertions, 2 deletions
diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Descriptors.c b/Demos/Device/ClassDriver/RNDISEthernet/Descriptors.c index 494150349..8e709cee9 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Descriptors.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Descriptors.c @@ -46,7 +46,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,0,0),  	.Class                  = CDC_CSCP_CDCClass,  	.SubClass               = CDC_CSCP_NoSpecificSubclass,  	.Protocol               = CDC_CSCP_NoSpecificProtocol, @@ -55,7 +55,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =  	.VendorID               = 0x03EB,  	.ProductID              = 0x204C, -	.ReleaseNumber          = VERSION_BCD(0,0,1), +	.ReleaseNumber          = VERSION_BCD(0,0,2),  	.ManufacturerStrIndex   = STRING_ID_Manufacturer,  	.ProductStrIndex        = STRING_ID_Product, @@ -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"); +/** 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"   *  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 @@ -233,6 +259,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,  					Address = &ProductString;  					Size    = pgm_read_byte(&ProductString.Header.Size);  					break; +				case STRING_ID_MS_Compat: +					Address = &MSConpatibilityString; +					Size    = pgm_read_byte(&MSConpatibilityString.Header.Size); +					break;  			}  			break; @@ -242,3 +272,20 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,  	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(); +		} +	} +} diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Descriptors.h b/Demos/Device/ClassDriver/RNDISEthernet/Descriptors.h index 082f44afc..56a3acd23 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Descriptors.h +++ b/Demos/Device/ClassDriver/RNDISEthernet/Descriptors.h @@ -59,6 +59,10 @@  		/** Size in bytes of the CDC data IN and OUT endpoints. */  		#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 define for the device configuration descriptor structure. This must be defined in the  		 *  application code, as the configuration descriptor contains several sub-descriptors which @@ -81,6 +85,21 @@  			USB_Descriptor_Endpoint_t             RNDIS_DataInEndpoint;  		} 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  		 *  should have a unique ID index associated with it, which can be used to refer to the  		 *  interface from other descriptors. @@ -100,6 +119,7 @@  			STRING_ID_Language     = 0, /**< Supported Languages string descriptor ID (must be zero) */  			STRING_ID_Manufacturer = 1, /**< Manufacturer 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: */ @@ -108,5 +128,7 @@  		                                    const void** const DescriptorAddress)  		                                    ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); +		void     CheckIfMSCompatibilityDescriptorRequest(void); +  #endif diff --git a/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c b/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c index f963d48e1..cfe90ccd7 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c @@ -174,6 +174,9 @@ void EVENT_USB_Device_ConfigurationChanged(void)  /** Event handler for the library USB Control Request reception event. */  void EVENT_USB_Device_ControlRequest(void)  { +	/* Send MS OS Compatibility descriptor if requested by the host. */ +	CheckIfMSCompatibilityDescriptorRequest(); +  	RNDIS_Device_ProcessControlRequest(&Ethernet_RNDIS_Interface);  }  | 
