Jacques Dirac | 31 Mar 2011 13:27
Picon

Missing reports in hid_interrupt_read()

Hi,

My program reads reports from a device using the hid_interrupt_read()
function, but when reports follow each other quickly, they could get
lost (not returned by hid_interrupt_read()).

With help of the developer of the device we could get some information
about what is going on in the device:
- the device has a queue for the IN-reports, so a report is not lost
in the device
- in each report there is a value that counts how many times the
device has placed a report in the IN-report-buffer
- in each report there is a value that contains the time that the last
IN-report waited in the register to be fetched by the host

With this information we see that:
- the device puts all messages in the IN-report-buffer, but not all
messages could be fetched with hid_interrupt_read()
- a lost message is fetched (by something) in <10ms (this is the same
time as the other messages)

Then my questions are:
- Is there some routine in libhid (or libusb) that is fetching the
reports from the IN-report-buffer of the device and saves them in a
'buffer' where hid_interrupt_read() is reading from? In my case it
looks like that buffer is overwritten.
- If so, can this be disabled or influenced?
- If not, what else can be going on here?

Hope someone can help to clear things up.
(Continue reading)

Charles Lepple | 31 Mar 2011 14:19

Re: Missing reports in hid_interrupt_read()

On Mar 31, 2011, at 7:27 AM, Jacques Dirac wrote:

> - Is there some routine in libhid (or libusb) that is fetching the
> reports from the IN-report-buffer of the device and saves them in a
> 'buffer' where hid_interrupt_read() is reading from? In my case it
> looks like that buffer is overwritten.

hid_interrupt_read() is simply a thin wrapper around libusb's  
usb_interrupt_read() function. It merely dereferences libhid's  
HIDInterface pointer to get the libusb handle, and prints a few error  
messages as necessary.

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

> - If so, can this be disabled or influenced?
> - If not, what else can be going on here?

Is it possible that your code is expecting a certain length for the  
reply, and you are discarding the packet if the return code from  
hid_interrupt_read() is non-zero?

If not, you may have to look deeper in the stack. libusb 0.1 generally  
doesn't buffer things, either (although I admit I haven't looked at  
all the platform-specific code lately). There are often kernel-level  
debugging facilities available - with recent Linux 2.6 kernels and  
development versions of libpcap, you can even capture USB traffic to  
be displayed in Wireshark. Unfortunately, that might not pinpoint  
where the extra IN request is coming from.

FreeBSD prior to 8.0 seems to continuously poll interrupt endpoints at  
(Continue reading)

Jacques Dirac | 31 Mar 2011 17:02
Picon

Re: Missing reports in hid_interrupt_read()

Hi Charles,

Thanks for your reply!

> Is it possible that your code is expecting a certain length for the reply,
> and you are discarding the packet if the return code from
> hid_interrupt_read() is non-zero?

Good thinking! I did first, but now I changed the code to check this:
hid_interrupt_read() is only returning HID_RET_TIMEOUT and
HID_RET_SUCCESS when data is available.

Increasing the timeout (from 10 to 1000) in hid_interrupt_read()
improves the situation, but I think this is only because the chance a
message is missed (not waiting in hid_interrupt_read()) is lowered.

> If not, you may have to look deeper in the stack. libusb 0.1 generally
> doesn't buffer things, either (although I admit I haven't looked at all the
> platform-specific code lately). There are often kernel-level debugging
> facilities available

I will try to do that.

> FreeBSD prior to 8.0 seems to continuously poll interrupt endpoints at the
> interval specified in the USB descriptor, and it buffers the results with
> marginal success. (I wouldn't recommend developing for the pre-8.0 USB
> stack.)

Running Linux 2.4.32 with libusb 0.1.12 and libhid 0.2.16.

(Continue reading)


Gmane