Discussion:
[libhid-discuss] Missing reports in hid_interrupt_read()
Jacques Dirac
2011-03-31 11:27:41 UTC
Permalink
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.

Best regards.
Charles Lepple
2011-03-31 12:19:25 UTC
Permalink
Post by Jacques Dirac
- 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
Post by Jacques Dirac
- 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
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.)
Jacques Dirac
2011-03-31 15:02:53 UTC
Permalink
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.


Best regards.

Loading...