Discussion:
[libhid-discuss] Logic of HID_RET_FAIL_INT_READ vs HID_RET_TIMEOUT
Marian Aldenhoevel
2008-08-25 10:02:50 UTC
Permalink
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.

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);

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)?

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?

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?

Sorry for these very basic questions, I am only just learning the stuff.

Ciao, MM
Charles Lepple
2008-08-25 11:30:34 UTC
Permalink
Post by Marian Aldenhoevel
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
Post by Marian Aldenhoevel
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.
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).
Post by Marian Aldenhoevel
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.
Post by Marian Aldenhoevel
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.
Post by Marian Aldenhoevel
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).
Post by Marian Aldenhoevel
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
amruth
2008-08-27 00:32:33 UTC
Permalink
Hi
I am using libusb-0.9.2 and libcompat-0.1-beta with libhid-0.1.
I am facing this problem whenever I am trying to open my HID device.
libusb is always trying to open from
libusb could'nt open USB device /dev/bus/usb/001/001 permission denied.
I have unplugged the HID device several times but libusb is always trying open from /dev/bus/usb/001/001 location. Please let me know if anybody has any idea.


Thanks
Amruth p.v
From: Charles Lepple <clepple at ghz.cc>
Subject: Re: [libhid-discuss] Logic of HID_RET_FAIL_INT_READ vs HID_RET_TIMEOUT
To: "Marian Aldenhoevel" <marian.aldenhoevel at marian-aldenhoevel.de>
Cc: "libhid-discuss List" <libhid-discuss at lists.alioth.debian.org>
Date: Monday, August 25, 2008, 6:30 AM
Post by Marian Aldenhoevel
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
Post by Marian Aldenhoevel
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
Post by Marian Aldenhoevel
The first byte read is the report-ID, right? And
amongst other
Post by Marian Aldenhoevel
things that
implies a certain amount of data following that byte?
In the case
Post by Marian Aldenhoevel
of my
device report-IDs seem to ONLY specify the size,
anything else, any
Post by Marian Aldenhoevel
content
is inside the report, encoded with it's own
length-field and
Post by Marian Aldenhoevel
command-code
and so on.
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).
Post by Marian Aldenhoevel
TRACE: hid_interrupt_read(): retrieving interrupt
report from
Post by Marian Aldenhoevel
device
001/019[0] ...
NOTICE: hid_interrupt_read(): successfully got
interrupt report
Post by Marian Aldenhoevel
from device
001/019[0]
2
Fine. I got my byte. And it looks like a valid
report-ID.
Post by Marian Aldenhoevel
I then look up the length for that report-ID (as given
by my docs
Post by Marian Aldenhoevel
and the
lsusb output, which agree), allocate a buffer and try
to read the
Post by Marian Aldenhoevel
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
Post by Marian Aldenhoevel
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.
Post by Marian Aldenhoevel
Anyway the next hid_interrupt_read() fails, wether I
TRACE: hid_interrupt_read(): retrieving interrupt
report from
Post by Marian Aldenhoevel
device
001/019[0] ...
WARNING: hid_interrupt_read(): failed to get all of
interrupt
Post by Marian Aldenhoevel
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
Post by Marian Aldenhoevel
the
read again? Do I need to reset something between
reads?
I think you're hitting a limitation in the libhid API.
Check the
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.
Post by Marian Aldenhoevel
What is the logic in case of HID_RET_TIMEOUT? I am
occasionally
Post by Marian Aldenhoevel
getting that
result, too. I have tried much much longer timeouts
and it helps,
Post by Marian Aldenhoevel
but I'd
rather keep them short and try again instead of
picking some maximum.
Post by Marian Aldenhoevel
Especially as the device as replies ranging from 3
bytes to 2KB.
Post by Marian Aldenhoevel
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).
Post by Marian Aldenhoevel
Sorry for these very basic questions, I am only just
learning the
Post by Marian Aldenhoevel
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
_______________________________________________
libhid-discuss mailing list
libhid-discuss at lists.alioth.debian.org
http://lists.alioth.debian.org/mailman/listinfo/libhid-discuss
Lou
2008-08-28 18:58:35 UTC
Permalink
Post by amruth
Hi
I am using libusb-0.9.2 and libcompat-0.1-beta with libhid-0.1.
I am facing this problem whenever I am trying to open my HID device.
libusb is always trying to open from
libusb could'nt open USB device /dev/bus/usb/001/001 permission denied.
I have unplugged the HID device several times but libusb is always trying open from /dev/bus/usb/001/001 location. Please let me know if anybody has any idea.
That is a basic permissions problem. Look at the permissions on that
node. Some folks run their libusb app as root to get around that, but
that's obviously a security problem.

A better measure will vary by OS. My system uses udev, so I created a
udev rule that sets permissions to something else (which I can access as a
normal user) when that node is created for my particular device.

amruth
2008-08-28 23:20:56 UTC
Permalink
Hi
I have set up rules in udev. I have 4 hid devices, all them works except one. I did not understand why, but I have done workaround. The issue is that libusb-0.9 expects file in /dev/bus/usb/001/001 to be O_RDWR, and errors out if not the case, so I allowed O_RDONLY in libusb which solves the issue in libusb/os/linux_usbfs.c. I don't understand why libusb always reads from /dev/bus/001/001 instead of /dev/bus/002/001 which is more recent entry. I have removed my device several times but it cached that info of HID device. If I change the permission to allow O_RDONLY, this problem goes away. Please let the dev path having read only permission to use the device. All the permission I set are correct but the caching is issue, we need to disable caching in libusb.

Thanks
Amruth p.v
From: Lou <lou.libusb at fixit.nospammail.net>
Subject: Re: [Libusb-devel] permission denied for opening HID device
To: "amruth" <amruth_pv at yahoo.com>
Cc: "Marian Aldenhoevel" <marian.aldenhoevel at marian-aldenhoevel.de>, "Charles Lepple" <clepple at ghz.cc>, libusb-devel at lists.sourceforge.net, "libhid-discuss List" <libhid-discuss at lists.alioth.debian.org>
Date: Thursday, August 28, 2008, 1:58 PM
Post by amruth
Hi
I am using libusb-0.9.2 and libcompat-0.1-beta with
libhid-0.1.
Post by amruth
I am facing this problem whenever I am trying to open
my HID device.
Post by amruth
libusb is always trying to open from
libusb could'nt open USB device
/dev/bus/usb/001/001 permission denied.
Post by amruth
I have unplugged the HID device several times but
libusb is always trying open from /dev/bus/usb/001/001
location. Please let me know if anybody has any idea.
That is a basic permissions problem. Look at the
permissions on that
node. Some folks run their libusb app as root to get
around that, but
that's obviously a security problem.
A better measure will vary by OS. My system uses udev, so
I created a
udev rule that sets permissions to something else (which I
can access as a
normal user) when that node is created for my particular
device.
Loading...