[libhid-discuss] broken pipe error

Charles Lepple clepple at ghz.cc
Wed Aug 27 00:23:05 UTC 2008


On Aug 26, 2008, at 12:11 PM, Christopher wrote:

> Here's the tree dump, and lsusb. I'm not good at understanding all  
> the information that lsusb gives, is there a guide that explains  
> how to interpret that?

I don't know of a guide to lsusb output, but it lines up pretty well  
with the USB and HID class specifications.

> Thanks,
> Christopher
>
> parse tree of HIDInterface 001/003[0]:
>  path: 0xffa00001.0xffa00002.0xffa10003; type: 0x80
>  path: 0xffa00001.0xffa00002.0xffa10004; type: 0x80
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x80
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x80
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x80
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x80
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x80
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x80

There is a bug in printing the tree for multi-byte usages, but  
basically the path 0xffa00001.0xffa00002.0xffa10004 points to a 7- 
byte input buffer (the 0x00000000 at the end of the path can be seen  
as a "continuation marker").

>  path: 0xffa00001.0xffa00002.0xffa10005; type: 0x90
>  path: 0xffa00001.0xffa00002.0xffa10006; type: 0x90
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x90
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x90
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x90
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x90
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x90
>  path: 0xffa00001.0xffa00002.0x00000000; type: 0x90
>
>
> Bus 001 Device 003: ID 1781:0898 Multiple Vendors
> Device Descriptor:
>  bLength                18
>  bDescriptorType         1
>  bcdUSB               1.10
>  bDeviceClass            0 (Defined at Interface level)
>  bDeviceSubClass         0
>  bDeviceProtocol         0
>  bMaxPacketSize0         8
>  idVendor           0x1781 Multiple Vendors
>  idProduct          0x0898
>  bcdDevice            0.00
>  iManufacturer           1 Runtime
>  iProduct                2 PxRC PhoenixRC USB Interface
>  iSerial                 0
>  bNumConfigurations      1
>  Configuration Descriptor:
>    bLength                 9
>    bDescriptorType         2
>    wTotalLength           34
>    bNumInterfaces          1
>    bConfigurationValue     1
>    iConfiguration          0
>    bmAttributes         0x80
>      (Bus Powered)
>    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
>        HID Device Descriptor:
>          bLength                 9
>          bDescriptorType        33
>          bcdHID               1.00
>          bCountryCode            0 Not supported
>          bNumDescriptors         1
>          bDescriptorType        34 Report
>          wDescriptorLength      52
>          Report Descriptor: (length is 52)
>            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
>                            (null)
>            Item(Local ): Usage, data= [ 0x01 ] 1
>                            (null)
>            Item(Main  ): Collection, data= [ 0x01 ] 1
>                            Application
>            Item(Local ): Usage, data= [ 0x02 ] 2
>                            (null)
>            Item(Main  ): Collection, data= [ 0x00 ] 0
>                            Physical
>            Item(Global): Usage Page, data= [ 0xa1 0xff ] 65441
>                            (null)
>            Item(Local ): Usage, data= [ 0x03 ] 3
>                            (null)
>            Item(Local ): Usage, data= [ 0x04 ] 4
>                            (null)
>            Item(Global): Logical Minimum, data= [ 0x80 ] 128
>            Item(Global): Logical Maximum, data= [ 0x7f ] 127
>            Item(Global): Physical Minimum, data= [ 0x00 ] 0
>            Item(Global): Physical Maximum, data= [ 0xff ] 255
>            Item(Global): Report Size, data= [ 0x08 ] 8
>            Item(Global): Report Count, data= [ 0x08 ] 8
>            Item(Main  ): Input, data= [ 0x02 ] 2
>                            Data Variable Absolute No_Wrap Linear
>                            Preferred_State No_Null_Position  
> Non_Volatile Bitfield
>            Item(Local ): Usage, data= [ 0x05 ] 5
>                            (null)
>            Item(Local ): Usage, data= [ 0x06 ] 6
>                            (null)
>            Item(Global): Logical Minimum, data= [ 0x80 ] 128
>            Item(Global): Logical Maximum, data= [ 0x7f ] 127
>            Item(Global): Physical Minimum, data= [ 0x00 ] 0
>            Item(Global): Physical Maximum, data= [ 0xff ] 255
>            Item(Global): Report Size, data= [ 0x08 ] 8
>            Item(Global): Report Count, data= [ 0x08 ] 8
>            Item(Main  ): Output, data= [ 0x02 ] 2
>                            Data Variable Absolute No_Wrap Linear
>                            Preferred_State No_Null_Position  
> Non_Volatile Bitfield
>            Item(Main  ): End Collection, data=none
>            Item(Main  ): End Collection, data=none
>      Endpoint Descriptor:
>        bLength                 7
>        bDescriptorType         5
>        bEndpointAddress     0x81  EP 1 IN
>        bmAttributes            3
>          Transfer Type            Interrupt
>          Synch Type               None
>          Usage Type               Data
>        wMaxPacketSize     0x0008  1x 8 bytes
>        bInterval              10
> Device Status:     0x0000
>  (Bus Powered)
>
>
> Charles Lepple wrote:
>> On Aug 26, 2008, at 2:54 AM, Christopher wrote:
>>
>>> Now that I've got my code compiling (thanks, Marian), I've having  
>>> some
>>> problems talking to the USB device I've got connected.
>>> hid_interrupt_read seems to work just fine, but I keep getting  
>>> "broken
>>> pipe" errors when I use hid_get_input_report(). I seem to have  
>>> the path
>>> right, but I'm totally new to USB programming so I could be  
>>> messing up
>>> something really basic.
>>> Thanks for any help,
>>> Christopher
>>
>> One thing that might help is posting the hid_dump_tree() output  
>> for your device, and optionally the output of 'lsusb -vvv' (run as  
>> root, preferably after detaching the kernel usbhid driver so that  
>> the report descriptor shows up in the output.)
>>
>>> This is the message I get:
>>>   TRACE: hid_get_input_report(): looking up report ID...
>>>   TRACE: hid_prepare_parse_path(): preparing search path of depth  
>>> 3 for
>>> parse tree of USB device 001/002[0]...
>>>   TRACE: hid_prepare_parse_path(): search path prepared for parse  
>>> tree
>>> of USB device 001/002[0].
>>>  NOTICE: hid_find_object(): found requested item.
>>>   TRACE: hid_get_input_report(): retrieving report ID 0x00 (length:
>>> 1024) from USB device 001/002[0]...
>>
>> This doesn't seem to match the code below (the buffer in the code  
>> is 16 bytes). In USB, the size of the transfer matters. Also, I  
>> don't know if report ID 0 is valid.
>>
>>> WARNING: hid_get_input_report(): failed to retrieve report from USB
>>> device 001/002[0]:error sending control message: Broken pipe.
>>
>> "Broken pipe" is a way for the HID device firmware to signal an  
>> error to the host. Unfortunately, there isn't an easy way to  
>> figure out why it is not happy with what it received.
>>
>>> This is the function I use to call hid_get_input_report:
>>> hid_return ReadReport(HIDInterface *hid, int const *path, int  
>>> const pathlen)
>>> {
>>>     /* trys to get a 16byte report from the specified path. */
>>>     int const RECV_PACKET_LEN = 16;
>>>     char packet[RECV_PACKET_LEN];
>>>     int i;
>>>     hid_return result;
>>>     printf("Attempting to read from");
>>>     for(i = 0; i < pathlen; i++)
>>>     {
>>>         printf(" 0x%08x", path[i]);
>>>     }
>>>     printf("\n");
>>>     result = hid_get_input_report(hid, path, pathlen, packet,
>>> RECV_PACKET_LEN);
>>>     if (result != HID_RET_SUCCESS)
>>>     {
>>>         printf("hid_get_input_report() failed. Error code: %d\n",  
>>> result);
>>>     }
>>>     else
>>>     {
>>>         printf("Input report: %s\n", packet);
>>>     }
>>>     return result;
>>> }
>>>
>>> And then I call it like this:
>>>     int const PATHIN_1[PATHLEN] = { 0xffa00001, 0xffa00002,  
>>> 0xffa10003 };
>>>     ReadReport(hid, PATHIN_1, PATHLEN);
>>>
>>> PATHLEN is #defined as 3
>>>
>>> _______________________________________________
>>> libhid-discuss mailing list
>>> libhid-discuss at lists.alioth.debian.org
>>> http://lists.alioth.debian.org/mailman/listinfo/libhid-discuss
>>
>>


-- 
Charles Lepple
clepple at ghz.cc





More information about the libhid-discuss mailing list