[libhid-discuss] Logic of HID_RET_FAIL_INT_READ vs HID_RET_TIMEOUT

Charles Lepple clepple at ghz.cc
Mon Aug 25 11:30:34 UTC 2008


On Aug 25, 2008, at 6:02 AM, Marian Aldenhoevel wrote:

> Hi,
>
> What is the exact difference between the results  
> HID_RET_FAIL_INT_READ and
> HID_RET_TIMEOUT?
>
> I send a report to my device and it is supposed to answer on the  
> interrupt
> endpoint. And it does, but I am having trouble fetching the data.

See http://libhid.alioth.debian.org/doc/hid__exchange_8c- 
source.html#l00332

> The first byte read is the report-ID, right? And amongst other  
> things that
> implies a certain amount of data following that byte? In the case  
> of my
> device report-IDs seem to ONLY specify the size, anything else, any  
> content
> is inside the report, encoded with it's own length-field and  
> command-code
> and so on.
>
> So my plan is to first read the report-ID:
>
>    char reportID;
>    hid_interrupt_read(hid,0x81,&reportID,1);

Yeah, that won't work as expected. Because USB is packet-oriented,  
read requests are not buffered. If you read one byte, libhid sends a  
request to libusb to read one byte, which asks the device for one  
byte. I believe the device can answer with however many bytes it  
wants (not sure, because I have only tested the case where you  
request more bytes than the device would be expected to return).

>
> libhid traces:
>
>    TRACE: hid_interrupt_read(): retrieving interrupt report from  
> device
> 001/019[0] ...
>   NOTICE: hid_interrupt_read(): successfully got interrupt report  
> from device
> 001/019[0]
> 2
>
> Fine. I got my byte. And it looks like a valid report-ID.
>
> I then look up the length for that report-ID (as given by my docs  
> and the
> lsusb output, which agree), allocate a buffer and try to read the  
> rest. In
> this case the ID is 0x45, report length 75 bytes.
>
> Q: Does that mean I can now expect 75 bytes? Or is it 74 (75 minus the
>     report-ID that I have already read)?

After you read that one byte, the next read will retrieve the next  
report. Consider the other 74 bytes gone.

> Anyway the next hid_interrupt_read() fails, wether I try 75 or 74:
>
>    TRACE: hid_interrupt_read(): retrieving interrupt report from  
> device
> 001/019[0] ...
> WARNING: hid_interrupt_read(): failed to get all of interrupt  
> report from
> device 001/019[0]; requested: 74 bytes, sent: 0 bytes.
>
> The result is 21 = HID_RET_FAIL_INT_READ
>
> Am I doing something fundamentally wrong? Does it make sense to try  
> the
> read again? Do I need to reset something between reads?

I think you're hitting a limitation in the libhid API. Check the  
logic at line 365:

00365   if (len != (signed)size) {
00366     WARNING("failed to get all of interrupt report from device % 
s; "
00367       "requested: %d bytes, sent: %d bytes.", hidif->id,
00368       size, len);
00369     return HID_RET_FAIL_INT_READ;
00370   }

I forget who contributed the interrupt read functions, but it looks  
like they only needed to read fixed-length reports.

> What is the logic in case of HID_RET_TIMEOUT? I am occasionally  
> getting that
> result, too. I have tried much much longer timeouts and it helps,  
> but I'd
> rather keep them short and try again instead of picking some maximum.
> Especially as the device as replies ranging from 3 bytes to 2KB.  
> Can I just
> call hid_interrupt_read() again?

Again, check the code - it's pretty simple. The USB stack won't keep  
re-reading until the buffer is filled, so you should pick the timeout  
based on how many bytes you want to read (after all, USB transaction  
times are measured in milliseconds, and you also need to account for  
the processing time on the microcontroller at the other end).

> Sorry for these very basic questions, I am only just learning the  
> stuff.
>
> Ciao, MM
>
>
> _______________________________________________
> libhid-discuss mailing list
> libhid-discuss at lists.alioth.debian.org
> http://lists.alioth.debian.org/mailman/listinfo/libhid-discuss


-- 
Charles Lepple




More information about the libhid-discuss mailing list