[libhid-discuss] Help with using hid_set_output_report
Charles Lepple
clepple at ghz.cc
Sun Dec 28 04:54:44 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.
You may be interested in this program:
http://iki.fi/lindi/usb/usbsnoop2libusb.pl
It generates a skeleton libusb application based on usbsnoop output.
> 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).
Yup, hid_set_output_report() does send a control message with
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?
0x21 is USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE. I'm
not sure why it wants to be "Recipient: Endpoint" as you indicated
above.
If you can find a reference that says why 0x22 might be a valid
option, you might be able to convince me to modify the code.
> 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?
This is an interesting question. If you already know the parameters,
and if they don't match what libhid sends, it may be easier to just
use libusb directly.
>
> 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?)
Unfortunately, I am a little suspicious of usbsnoopy's output here.
What version are you using, and where did you get it?
You might try this one: http://www.pcausa.com/Utilities/UsbSnoop/
default.htm (SniffUSB 2.0) or http://benoit.papillault.free.fr/
usbsnoop/index.php.en (usbsnoop 1.8)
>
> 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
Odd that your version of lsusb doesn't recognize this descriptor.
> 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
Same here. A lot of useful information is not being displayed by lsusb.
> Device Status: 0x0001
> Self Powered
>
More information about the libhid-discuss
mailing list