Author Topic: Standard Request - Get_Descriptor  (Read 17532 times)

gi

  • Member
  • ***
  • Posts: 27
Standard Request - Get_Descriptor
« on: June 23, 2011, 05:51:51 am »
Hi Jan,

I am confused about this request in the example given below, I looked into USB 2.0 Specification page 250 Table 9-3 the bRequest = Get_Descriptor has only ONE bmRequestType = 0x80, how come this line be executed :

Code: [Select]
else if ( Setup.bmRequestType == IN_INTERFACE ) // 0x81, Request to Interface
Is there a case wherein the bmRequestType changed from 0x80 to 0x81 for this Get_Descriptor() request?

Example code - HID_Composite_Device
Code: [Select]
static void Get_Descriptor(void)
{
if ( Setup.bmRequestType == IN_DEVICE ) // 0x80, Request to device
{
switch(Setup.wValue.c[MSB]) // Determine which type of descriptor
{ // was requested, and set data ptr and
case DST_DEVICE: // size accordingly
if ( (Setup.wValue.c[LSB] == 0) && (Setup.wIndex.i == 0) )
{
DataPtr = (BYTE*)&DeviceDesc;
DataSize = sizeof( Tdevice_descriptor );
setup_handled = TRUE;
}
break;

case DST_CONFIG: // wValue.LSB holds config index
if ( (Setup.wValue.c[LSB] == 0) && (Setup.wIndex.i == 0) )
{
DataPtr = (BYTE*)&ConfigDescSet;
DataSize = sizeof( Tconfiguration_desc_set );
setup_handled = TRUE;
}
break;

case DST_STRING: // wValue.LSB holds string index
// wIndex holds language ID
if ( Setup.wValue.c[LSB] < StringDescNum )
{
DataPtr = StringDescTable[Setup.wValue.c[LSB]];
DataSize = *DataPtr;
setup_handled = TRUE;
}
break;

default:
break;
}
}
else if ( Setup.bmRequestType == IN_INTERFACE ) // 0x81, Request to Interface
{

if ( Setup.wIndex.i == DSC_INTERFACE_HID0 ) { // HID interface 0
switch(Setup.wValue.c[MSB]) // Determine which type of descriptor
{
case DSC_SUBTYPE_CS_HID_CLASS:


Hope you can enlighten me on this.

thanks a lot

regards
gi

Pat Crowe

  • Member
  • ***
  • Posts: 39
Re: Standard Request - Get_Descriptor
« Reply #1 on: June 23, 2011, 08:00:12 am »
The HID descriptor comes from the interface, not the device. See HID spec 7.1.1.

gi

  • Member
  • ***
  • Posts: 27
Re: Standard Request - Get_Descriptor
« Reply #2 on: June 23, 2011, 10:43:00 pm »
Thank you Pat for your reply,
In USB 2.0 specification there is a Get_Descriptor with bmRequestType = 0x80, and in the USB HID specification section 7.1.1 there is a Get_Descriptor with bmRequestType = 0x81.

I'm thinking the host send Get_Descriptor request twice to get the descriptor of the device,config,string and Get_Descriptor to get HID descriptor and report descriptor. Am I correct?

thanks
gi

Pat Crowe

  • Member
  • ***
  • Posts: 39
Re: Standard Request - Get_Descriptor
« Reply #3 on: June 24, 2011, 04:16:54 am »
A GetDescriptor request has three critical values in its Setup packet.
- bmRequestType specifies the recipient
- bRequest specifies that it is a GetDescriptor request
- wValue specifies the identity of the descriptor requested

The host may or may not ask for any descriptors it might be interested in in any order at any time and you must simply respond with the correct one, or stall it if the request is invalid.

You should not concentrate on what the host will do, you must respond correctly *whatever* it does. Too many designs make assumtions about the host.

Tsuneo

  • Frequent Contributor
  • ****
  • Posts: 145
Re: Standard Request - Get_Descriptor
« Reply #4 on: June 24, 2011, 08:19:10 am »
Hi gi,

I had been trapped in this Get_Descriptor issue, too, when I started USB study :-)

"9.4 Standard Device Requests" section of USB2.0 spec describes about Get_Descriptor as a Standard Device Request. But it doesn't mean Get_Descriptor is not applied to any recipient other than Device. This section defines the way how the device has to interpret the request, just when bmRequestType is 0x80 (Standard Device Request).

HID spec also defines Get_Descriptor at "7.1.1 Get_Descriptor Request". In this section, HID spec describes just when bmRequestType is 0x81 (Recipient is Interface). There is no inconsistency with the original USB2.0 spec, here.

The Common Class Specification ( http://www.usb.org/developers/devclass_docs/usbccs10.pdf ) explains on this Get_Descriptor issue, as follows.

3.11 Identifying Class and Vendor-Specific Requests and Descriptors
The standard GET_DESCRIPTOR request (with the bRequestType.Type field set to standard) is used to directly request class or vendor-specific descriptors. The class associated with such a request is determined by the class of the bmRequestType.Recipient. When the bmRequestType.Recipient field is set to INTERFACE or ENDPOINT, the wIndex field identifies the desired interface or endpoint. All endpoints within an interface use that interface’s class, subclass and protocol.


The lesson I had gotten on this issue was twofold,
1) Request parsers have to check all fields on the SETUP data with those specified on the spec. If any field doesn't match, the parser should not process the request.

2) Just after SETUP transaction comes, device stack passes it to a parser of Standard Device requests. And then, the stack passes the request to a callback of Class/Vendor parsers. In a HID Class parser, this Get_Descriptor of Interface has a chance to be parsed.
These parsers raises a flag when they process the request. If no one handles the request, the device stack STALLs the request.
In this code flow, you may separate class implementation beautifully from the basic stack code.

Tsuneo
« Last Edit: June 24, 2011, 08:53:42 am by Tsuneo »

gi

  • Member
  • ***
  • Posts: 27
Re: Standard Request - Get_Descriptor
« Reply #5 on: June 26, 2011, 11:38:40 pm »
Thanks Pat for the heads-up.

And Tsuneo, you teach with completeness.
Very well explained. Glad you share what you've learned.

Thank you very much guys for your kind replies.

regards
gi