3
votes

I'm trying to use UsbDeviceConnection.controlTransfer to get the HID report descriptor for USB devices, so I can see what buttons the USB HID device has.

I've been able to get the actual input data from the HID devices by using a bulkTransfer.

I've looked it up and can only find tutorials for creating and parsing a HID report descriptor. I've tried entering in different perimeters into controlTransfer, but I've been unable to figure it out.

What values should I pass into controlTransfer to get the USB HID report descriptor, so I can start parsing what buttons the devices have and what bytes they are assigned to? Or are you not supposed to use controlTransfer to get the HID report descriptor? I'm new to working with USB.

1

1 Answers

4
votes

This is really late, but in case you haven't come up with a solution or someone else is looking to do this, this was my solution. I should mention, I am not very experienced with any of this, so some details may be off, but the general picture is there.

UsbDeviceConnection.controlTransfer requires 7 variables:

  • Request type
  • Request
  • Request value
  • Request index
  • Output buffer
  • Size of buffer
  • Timeout

Request type describes the direction, type, and recipient of the transfer. In this case, we want to read (1) using a standard (00) transmission and we want to query an interface (00001). We want to query an interface because HID is an interface of the device. So, 0b10000001 or 0x81.

Request describes our specific request. We are looking for the HID Report Descriptor and GET_DESCRIPTOR is defined as 0x06 by the spec.

Request value consists of the descriptor type as the high byte and the index of the interface as the low byte. Descriptor type in our case is HID Report or 0x22 (this is from the HID spec, specifically class descriptors). Index of the interface is the same as request index below. In my case it was 0x00, but yours may be different. Combining the high and low bit, we get 0x2200 for our request value.

Request index specifies which interface you are querying. If HID is the only interface of the device, then this will be 0x00. Otherwise, you will have to check the configuration descriptor for the types of interfaces available and their indices.

Output buffer is the space allocated for the return of the transaction and should be of the size specified by size of buffer, explained below.

Size of buffer describes the number of bytes in the report descriptor. This value is specified in the configuration descriptor, in the HID class-specific descriptor (bDescriptorType = 0x21) and is the value of the 8th byte (wDescriptorLength) out of the 9 total. In my case this value was 104.

Timeout is the number of milliseconds after which to give up. I used 2000.

Putting this together, UsbDeviceConnection.controlTranfer(0x81, 0x06, 0x2200, 0x00, byte[] buffer, 104, 2000).

https://www.beyondlogic.org/usbnutshell/usb6.shtml gives an excellent overview of the bit fields used in controlTransfer, check it out if you want more context.

https://eleccelerator.com/usbdescreqparser/ is an extremely useful tool for understanding USB and HID descriptors, and may be more insightful than reading the spec sheets and the API alone.