[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