[libhid-discuss] Help with using hid_set_output_report
Blaine Booher
blaine at cliftonlabs.com
Wed Dec 24 17:53:38 UTC 2008
Hey everyone,
I'm really confused and any suggestions would be very helpful. I have a device, and I know (from USB Snoopy on Windows) what data packets I need to send to it. When the software that comes with the device is started, 6 packets are sent/received (see first attachment). Once I get the first packet sent, I can worry about the rest later. At this point I'd just like to get the device to respond to correct report requests.
bmRequestType = 0x22 -> Direction: Host-to-device, Type: Class, Recipient: Endpoint
bRequest = 0x09 -> HID SET_OUTPUT_REPORT
wValue = 0x0200 -> Report type (0x02, aka Output report) and report ID (0x00)
wIndex = 0x0001 -> Sent to interface 1
wLength = 0x0008 -> 8 bytes of data
Data payload:
02 02 95 95 00 00 00 00
Now, I know that I need to be using the set_output_report function (at least I think this is correct, since it corresponds with the constant HID_REPORT_SET 0x09). I have two basic questions:
1. I partially understand the 'path' parameter in the set_output_report, but I am not sure. The source code calls usblib's control_msg function, which I am familiar with. It seems that I need 0x22 as the second parameter in the usb_control_msg. I'm not sure how to set this up properly using the HID path tree. When I look at the usbmon output (Given the example code below), I see 21 09 0200 0000 0040 being sent to the device - which is close, but not what I need. Is it possible that these values would work anyway since they derive from the HID Path tree?
2. Where do I input the values for the wValue and wIndex? I assume that this derives from the hid_find_object (and hence HID path tree), but I'm not sure if I trust the results since I am unfamiliar with the path set up... See below.
Here is the source code for the data packet being sent by set_output_report (with my comments):
TRACE("looking up report ID...");
hidif->hid_data->Type = ITEM_OUTPUT;
hidif->hid_data->ReportID = 0;
hid_find_object(hidif, path, depth);
// Should I be using hid_find_object if I already know the parameters?
int len = usb_control_msg(hidif->dev_handle,
USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE, // This should be 0x22, right?
HID_REPORT_SET, // 0x09
hidif->hid_data->ReportID + (HID_RT_OUTPUT << 8), // This should be 0x0200?
hidif->interface, // Interface ID
(char*)buffer, size, USB_TIMEOUT); // Timeout
If it is wise to use the path, rather than hardcode these values (I'll explain this in a second), I believe my path values (give a tree dump) are as follows. Does this look right?
parse tree of HIDInterface 002/005[0]:
path: 0xffa00001.0xffa00002; type: 0x80
path: 0xffa00001.0x00000000; type: 0x80
path: 0xffa00001.0x00000000; type: 0x80
[... truncated ...]
path: 0xffa00001.0x00000000; type: 0x80
path: 0xffa00001.0xffa00003; type: 0x90
path: 0xffa00001.0x00000000; type: 0x90
[... truncated ...]
path: 0xffa00001.0x00000000; type: 0x90
PATH_IN = [0xffa00001, 0xffa00002]
PATH_OUT = [0xffa00001, 0xffa00003]
The main reason that I am concerned over this is because initially I tried using libusb, without libhid. I found it impossible to send the following control message (rejected by the kernel):
control_msg(0x22, 0x09, (data), 0x0200, 0x0001, 64). It says that the request type is invalid (0x22) and will not allow the packet to even reach the USB bus. This leads me to believe that something fishy is going on that I don't understand, and I need to use the HID path method (maybe to generate a different request type?)
Any help would be wonderful. I feel so close, but I know I am missing something basic. I do have libhid successfully reading interrupt requests on 0x81 when I push a button on the device. Its just these control transfers and reports that I'm having trouble with.
Thanks,
Blaine
USB Snoopy Output:
[b]14 out down 0x00 9.839 CLASS_ENDPOINT 02 02 95 95 00 00 00 00 [/b]
URB Header (length: 80)
SequenceNumber: 14
Function: 001c (CLASS_ENDPOINT)
PipeHandle: 00000000
SetupPacket:
0000: 22 09 00 02 01 00 00 00
bmRequestType: 22
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Endpoint
bRequest: 09
TransferBuffer: 0x00000008 (8) length
0000: 02 02 95 95 00 00 00 00
[b]14 out up n/a 9.842 CONTROL_TRANSFER - 0x00000000[/b]
URB Header (length: 80)
SequenceNumber: 14
Function: 0008 (CONTROL_TRANSFER)
PipeHandle: 82db2020
SetupPacket:
0000: 22 09 00 02 01 00 08 00
bmRequestType: 22
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Endpoint
bRequest: 09
No TransferBuffer
[b]10 in up 0x81 9.843 BULK_OR_INTERRUPT_TRANSFER 80 a9 28 01 09 01 25 e0 0x00000000[/b]
URB Header (length: 72)
SequenceNumber: 10
Function: 0009 (BULK_OR_INTERRUPT_TRANSFER)
TransferFlags: 0x00000003
TransferBuffer: 0x00000040 (64) length
0000: 80 a9 28 01 09 01 25 e0 8d 0e 02 00 00 00 00 00
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[b]15 in down 0x81 9.843 BULK_OR_INTERRUPT_TRANSFER -[/b]
URB Header (length: 72)
SequenceNumber: 15
Function: 0009 (BULK_OR_INTERRUPT_TRANSFER)
TransferFlags: 0x00000003
No TransferBuffer
[b]16 out down 0x00 9.845 CLASS_ENDPOINT 02 04 80 b5 01 01 00 00 [/b]
URB Header (length: 80)
SequenceNumber: 16
Function: 001c (CLASS_ENDPOINT)
PipeHandle: 00000000
SetupPacket:
0000: 22 09 00 02 01 00 00 00
bmRequestType: 22
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Endpoint
bRequest: 09
TransferBuffer: 0x00000008 (8) length
0000: 02 04 80 b5 01 01 00 00
[b]16 out up n/a 9.849 CONTROL_TRANSFER - 0x00000000[/b]
URB Header (length: 80)
SequenceNumber: 16
Function: 0008 (CONTROL_TRANSFER)
PipeHandle: 82db2020
SetupPacket:
0000: 22 09 00 02 01 00 08 00
bmRequestType: 22
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Endpoint
bRequest: 09
No TransferBuffer
Device Information:
lsusb -vvv, truncated to my device:
Bus 002 Device 015: ID 0e20:0101
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0e20
idProduct 0x0101
bcdDevice 3.03
iManufacturer 4 Pegasus Technologies Ltd.
iProduct 56 NoteTaker FW Ver 3.03
iSerial 100 0003-0003
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 59
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
** UNRECOGNIZED: 09 21 10 01 00 01 22 24 00
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0006 1x 6 bytes
bInterval 1
** UNRECOGNIZED: 09 21 10 01 00 01 22 87 00
Device Status: 0x0001
Self Powered
More information about the libhid-discuss
mailing list