Discussion:
[libhid-discuss] Still can't interrupt_read() properly
Marian Aldenhoevel
2008-09-03 14:44:51 UTC
Permalink
Hi,

I am still not smart enough to do interrupt_read() properly.

The device I am trying to talking to takes commands and answers with replies.

I have used "Snoopy Pro" to spy on the conversation with my device while a
Windows-Program that uses the device is running. It sends two commands and
receives two replies. The full log in Snoopy-Format is attached, excerpts
from it are made in plain text.

Please bear with me as I first show what the Windows-program registers in
Snoopy and then what my Linux-Code using libhid tries to do and where it fails.

The short summary is that I can only get one response using interrupt_read()
every follow up comes up empty.
19 ??? down n/a 17.225 BULK_OR_INTERRUPT_TRANSFER -
URB Header (length: 72)
SequenceNumber: 19
Function: 0009 (BULK_OR_INTERRUPT_TRANSFER)
TransferFlags: 0x00000003
No TransferBuffer
20 out down n/a 17.238 CLASS_INTERFACE 02 00 03 43 30 30 00 >00
URB Header (length: 80)
SequenceNumber: 20
Function: 001b (CLASS_INTERFACE)
PipeHandle: 00000000
0000: 22 09 02 02 00 00 00 00
bmRequestType: 22
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Endpoint
bRequest: 09
TransferBuffer: 0x0000000c (12) length
0000: 02 00 03 43 30 30 00 00 00 00 00 00
I recognize the data here. It's the device-specific protocol:

02 is the report ID.
00 03 is the command length. 3 bytes.
43 is 'C' for Command
30 30 is '00' and is the code f?r "Initial reset".
The rest is padding. Reports are of fixed size, Report ID 02 is
11 bytes.

The device acts on this command, it cycles a solenoid which is very audible
and proves that the command went through OK.
20 out up n/a 17.241 CONTROL_TRANSFER - 0x00000000
URB Header (length: 80)
SequenceNumber: 20
Function: 0008 (CONTROL_TRANSFER)
PipeHandle: 887ea618
0000: 21 09 02 02 00 00 0c 00
bmRequestType: 21
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Interface
bRequest: 09
No TransferBuffer
8 ??? up n/a 17.689 BULK_OR_INTERRUPT_TRANSFER 42 00 05 50 30 >30 30 30
0x00000000
URB Header (length: 72)
SequenceNumber: 8
Function: 0009 (BULK_OR_INTERRUPT_TRANSFER)
TransferFlags: 0x00000003
TransferBuffer: 0x0000000c (12) length
0000: 42 00 05 50 30 30 30 30 48 42 55 2d
Again, the data decoded using docs from the Vendor:

42 The report ID.
00 05 Length of the response.
50 'P' Positive response.
30 30 '00' repeats the command the response is for.
30 30 Two bytes of status, '00' represents the status of internal sensors.

So this was OK.
21 ??? down n/a 17.689 BULK_OR_INTERRUPT_TRANSFER -
URB Header (length: 72)
SequenceNumber: 21
Function: 0009 (BULK_OR_INTERRUPT_TRANSFER)
TransferFlags: 0x00000003
No TransferBuffer
22 out down n/a 24.666 CLASS_INTERFACE 02 00 03 43 56 30 00 >00
URB Header (length: 80)
SequenceNumber: 22
Function: 001b (CLASS_INTERFACE)
PipeHandle: 00000000
0000: 22 09 02 02 00 00 00 00
bmRequestType: 22
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Endpoint
bRequest: 09
TransferBuffer: 0x0000000c (12) length
0000: 02 00 03 43 56 30 00 00 00 00 00 00
Very much like the 'Initial reset':

02 is the report ID.
00 03 is the command length. 3 bytes.
43 is 'C' for Command
56 30 is 'V0' and is the code f?r "read version data".
The rest is padding. Reports are of fixed size, Report ID 02 is
11 bytes.
22 out up n/a 24.671 CONTROL_TRANSFER - 0x00000000
URB Header (length: 80)
SequenceNumber: 22
Function: 0008 (CONTROL_TRANSFER)
PipeHandle: 887ea618
0000: 21 09 02 02 00 00 0c 00
bmRequestType: 21
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Interface
bRequest: 09
No TransferBuffer
19 ??? up n/a 24.697 BULK_OR_INTERRUPT_TRANSFER 45 00 43 50 56 >30 30 30
0x00000000
URB Header (length: 72)
SequenceNumber: 19
Function: 0009 (BULK_OR_INTERRUPT_TRANSFER)
TransferFlags: 0x00000003
TransferBuffer: 0x0000004c (76) length
0000: 45 00 43 50 56 30 30 30 48 42 55 2d 4e 41 31 34
0010: 35 20 20 20 42 20 37 44 34 42 45 46 20 20 20 20
0020: 20 20 20 20 20 20 20 20 20 20 30 30 30 30 30 30
0030: 48 42 55 2d 4e 41 31 34 36 20 20 20 45 20 30 30
0040: 45 42 31 39 39 34 00 00 00 00 00 00
45 Report ID.
00 43 Length of the response.
50 'P' positive response.
56 30 Repeats the command.
Then response data.
Then padding.

So this works fine. Using the windows sample software that ships with the device.
NOTICE: hid_prepare_parser(): successfully set up the HID parser for USB
device 001/007[0].
TRACE: hid_force_open(): add open device to list...
NOTICE: hid_force_open(): successfully opened USB device 001/007[0].
[DEBUG]: (V4KU) Command (00) Initial reset
[DEBUG]: (V4KU) Sending report ID 0x02, report size is 12 bytes
[DEBUG]: (libHID) hid_set_output_report() writing 12 bytes
[DATA ]: (libHID) S: 0x02 0x00 0x03 0x43 0x30 0x30 0x00 0x00 0x00 0x00
[DATA ]: (libHID) S: 0x00 0x00
TRACE: hid_set_output_report(): looking up report ID...
TRACE: hid_prepare_parse_path(): preparing search path of depth 3 for
parse tree of USB device 001/007[0]...
TRACE: hid_prepare_parse_path(): search path prepared for parse tree of
USB device 001/007[0].
NOTICE: hid_find_object(): found requested item.
TRACE: hid_set_output_report(): sending report ID 0x02 (length: 12) to USB
device 001/007[0]...
NOTICE: hid_set_output_report(): successfully sent report to USB device
001/007[0].

This sends the same 12 bytes as the windows-software does. The device cycles
it's solenoid and thus I have feedback that the command went through. Now my
program is waiting for the response.

I learned that I am supposed to fetch all the data for the reply in one go. So
I first calculate the size of data (from the docs, specific to a command), and
from that I derive the report-ID and from that the amount of bytes to request.
[DEBUG]: (V4KU) Expecting 5 bytes of data, handled by report ID 0x42,
report should be 12 bytes
hid_interrupt_read(): retrieving interrupt report from device 001/007[0]...
NOTICE: hid_interrupt_read(): successfully got interrupt report from device
001/007[0]
[DEBUG]: (libHID) hid_interrupt_read() read 12 bytes
[DATA ]: (libHID) R: 0x42 0x00 0x05 0x50 0x30 0x30 0x30 0x30 0x48 0x42
[DATA ]: (libHID) R: 0x55 0x2d
I do get my 12 bytes and they are the same as when using windows. Even the
ones that are supposed to be padding and thus unuseable are identical. Fine.
[DEBUG]: (V4KU) command received positive result
[DEBUG]: (V4KU) Command (V0) Version read
[DEBUG]: (V4KU) Sending report ID 0x02, report size is 12 bytes
[DEBUG]: (libHID) hid_set_output_report() writing 12 bytes
[DATA ]: (libHID) S: 0x02 0x00 0x03 0x43 0x56 0x30 0x00 0x00 0x00 0x00
[DATA ]: (libHID) S: 0x00 0x00
TRACE: hid_set_output_report(): looking up report ID...
TRACE: hid_prepare_parse_path(): preparing search path of depth 3 for
parse tree of USB device 001/007[0]...
TRACE: hid_prepare_parse_path(): search path prepared for parse tree of
USB device 001/007[0].
NOTICE: hid_find_object(): found requested item.
TRACE: hid_set_output_report(): sending report ID 0x02 (length: 12) to USB
device 001/007[0]...
NOTICE: hid_set_output_report(): successfully sent report to USB device
001/007[0].

Same data as in Windows.

But now the trouble starts. I cannot get the response. Note that my code first
calculates that it will expect Report ID 0x45 for a total of 76 bytes which
[DEBUG]: (V4KU) Expecting 67 bytes of data, handled by report ID 0x45,
report should be 76 bytes
TRACE: hid_interrupt_read(): retrieving interrupt report from device
001/007[0] ...
WARNING: hid_interrupt_read(): failed to get all of interrupt report from
device 001/007[0]; requested: 76 bytes, sent: 0 bytes.
HID_RET_FAIL_INT_READ)

Got no data.

More observations:

I have experimented with a number of timeout options. Short, long, very long.
So I do not think this is because of the time the device needs to process the
second command.

I have also tried sending "initial reset" twice. I can hear the solenoid cycle
twice but still I only receive one positive result, the second read returns 0
bytes. From this I follow that it's the reading not the writing that is at
fault: The second command does go through but the response is never received.

I then tried sending the same command three times. There are three clicks from
the solenoid, but only one reply on interrupt_read() both others fail. So all
three command were received by the device. This time the second one to fail
returns HID_RETURN_TIMEOUT instead of FAIL_INT_READ.

The docs for the device say that if I send a new command before I fetched the
result of a previous command the new command will be ignored. As I can send
many commands down the line and see them being processed I think the device
has actually answered or thinks it has answered but the reply has been lost.
Again that points to the reading of the data and thus to my usage of libhid.

Any hints on what I could change?

Ciao, MM
Charles Lepple
2008-09-04 00:29:28 UTC
Permalink
Post by Marian Aldenhoevel
I have used "Snoopy Pro" to spy on the conversation with my device
while a Windows-Program that uses the device is running. It sends
two commands and receives two replies. The full log in Snoopy-
Format is attached, excerpts
from it are made in plain text.
It doesn't look like the full log came through. (Please remember to
compress it.)
Post by Marian Aldenhoevel
But now the trouble starts. I cannot get the response. Note that my
code first calculates that it will expect Report ID 0x45 for a
[DEBUG]: (V4KU) Expecting 67 bytes of data, handled by report ID
0x45, report should be 76 bytes
TRACE: hid_interrupt_read(): retrieving interrupt report from
device 001/007[0] ...
WARNING: hid_interrupt_read(): failed to get all of interrupt
report from device 001/007[0]; requested: 76 bytes, sent: 0 bytes.
2008-09-03 16:22:32 [FATAL]: (libHID) hid_interrupt_read() failed
(21: HID_RET_FAIL_INT_READ)
What if you set the USB_DEBUG environment variable to something non-
zero? Do you get any more debug information about the failed transfer?
Post by Marian Aldenhoevel
I have experimented with a number of timeout options. Short, long,
very long. So I do not think this is because of the time the device
needs to process the second command.
What is "very long"? Remember that the timeouts are in milliseconds,
and transfer time is important here.
Post by Marian Aldenhoevel
21 ??? down n/a 17.689 BULK_OR_INTERRUPT_TRANSFER -
URB Header (length: 72)
SequenceNumber: 21
Function: 0009 (BULK_OR_INTERRUPT_TRANSFER)
TransferFlags: 0x00000003
No TransferBuffer
22 out down n/a 24.666 CLASS_INTERFACE 02 00 03 43 56 30 00 >00
--
Charles Lepple
Marian Aldenhoevel
2008-09-04 13:45:43 UTC
Permalink
Hi,
Post by Charles Lepple
It doesn't look like the full log came through. (Please remember to
compress it.)
Zipped and attached.
Post by Charles Lepple
What if you set the USB_DEBUG environment variable to something
non-zero? Do you get any more debug information about the failed transfer?
I did that and hid_set_usb_debug(1) in my code. No extra messages.
Post by Charles Lepple
Post by Marian Aldenhoevel
I have experimented with a number of timeout options. Short, long,
very long. So I do not think this is because of the time the device
needs to process the second command.
What is "very long"?
Several seconds.
That is because they are sent manually from a cumbersome demo-program ;-).

Nonetheless I put a ten second delay in my code between successfully receiving
the reply to the first command and sending the second. No change observed.

Ciao, MM
Marian Aldenhövel
2008-09-05 13:18:28 UTC
Permalink
Hi,

I have reproduced the problem in a simple testcase based on libhid_test.c to
make sure that it was not something unrelated in the rest of my read program.

The attached simple program sends the same command three times. The device
acts on it three times, but the results do not come back the second and third
time. The second and third attempts fail with different results.

Ciao, MM
--
Marian Aldenh?vel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"I ran some quick calculations on it. He's about 80% on the right
track. That leaves him only 20% dead when he crashes." Bob C
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: v4ku_test.c
Url: http://lists.alioth.debian.org/pipermail/libhid-discuss/attachments/20080905/ad98791a/attachment.txt
Marian Aldenhoevel
2008-09-05 14:59:41 UTC
Permalink
Hi,

I hammered it to work!

By just repeating the hid_interrupt_read() I can continue through the cycle of
HID_RET_FAIL_INT_READ and HID_RET_TIMEOUT and come out the other side with a
HID_SUCCESS and the correct data.

I have no idea why this works, nor do I deem it an elegant solution, but it
works for me in my current application.

I have thoroughly come to hate the device, though. I have since learned that
it is available with a simple serial interface as well and the vendor choose
to USBize it as a HID with lots of crud instead of just adding a
serial-USB-Converter and keeping the API. Ah, well, what's wrong with days and
days of experimenting...

Ciao, MM
Peter Stuge
2008-09-05 23:14:47 UTC
Permalink
I have since learned that it is available with a simple serial
interface as well and the vendor choose to USBize it as a HID with
lots of crud
If this IS indeed a Human Interface Device the vendor has actually
gotten the most difficult part of USB right; namely the device
descriptors! If it is not a HID then the Vendor was likely lazy and
used HID because it behaves a lot like a serial port in Windows.
instead of just adding a serial-USB-Converter and keeping the API.
This is the worst possible way to introduce USB into a product.
Please don't encourage anyone to use this method.
Ah, well, what's wrong with days and days of experimenting...
The fact is that USB is not a simple serial signal like RS-232, and
many assume that it is just that simple, but with power, when they
first start looking at USB.

In fact, USB is a bus with several layers of protocol that needs to
be understood properly before a good, standards-compliant,
implementation can be made. It is not a trivial specification but it
is fairly readable, and the protocol is well thought-out.


That said, reverse engineering a misbehaving device is never fun when
you just want to get on with using it.


//Peter
amruth
2008-09-05 15:19:49 UTC
Permalink
Hi
Maria
The issue may be that interrupt is not getting clear The USB state is not getting cleared. Please try using usb_clear_halt and it should work.

Thanks
Amruth p.v
From: Marian Aldenh?vel <marian.aldenhoevel at mba-software.de>
Subject: Re: [libhid-discuss] Still can't interrupt_read() properly
To: "libhid-discuss List" <libhid-discuss at lists.alioth.debian.org>
Date: Friday, September 5, 2008, 8:18 AM
Hi,
I have reproduced the problem in a simple testcase based on
libhid_test.c to
make sure that it was not something unrelated in the rest
of my read program.
The attached simple program sends the same command three
times. The device
acts on it three times, but the results do not come back
the second and third
time. The second and third attempts fail with different
results.
Ciao, MM
--
Marian Aldenh?vel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"I ran some quick calculations on it. He's about
80% on the right
track. That leaves him only 20% dead when he
crashes." Bob C
#include <hid.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h> /* for getopt() */
int main()
{
HIDInterface* hid;
int iface_num = 0;
hid_return ret;
unsigned short vendor_id = 0x0590;
unsigned short product_id = 0x0034;
HIDInterfaceMatcher matcher = { vendor_id, product_id,
NULL, NULL, 0 };
/* see include/debug.h for possible values */
hid_set_debug(HID_DEBUG_ALL);
hid_set_debug_stream(stderr);
/* passed directly to libusb */
hid_set_usb_debug(1);
ret = hid_init();
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_init failed with return code
%d\n", ret);
return 1;
}
hid = hid_new_HIDInterface();
if (hid == 0) {
fprintf(stderr, "hid_new_HIDInterface() failed,
out of memory?\n");
return 1;
}
ret = hid_force_open(hid, iface_num, &matcher, 3);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_force_open failed with return
code %d\n", ret);
return 1;
}
ret = hid_write_identification(stdout, hid);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_write_identification failed
with return code %d\n", ret);
return 1;
}
ret = hid_dump_tree(stdout, hid);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_dump_tree failed with return
code %d\n", ret);
return 1;
}
int sendloop;
for (sendloop = 0 ; sendloop < 3 ; sendloop++) {
unsigned char const SEND_PACKET_LEN = 11;
char const PACKET[11] = { 0x02, 0x00, 0x03, 0x43, 0x30,
0x30, 0x00, 0x00, 0x00, 0x00, 0x00 };
const int PATHLEN=3;
const int PATH_IN[3] = { 0xff000001, 0xff000021,
0xff000121 };
ret = hid_set_output_report(hid, PATH_IN, PATHLEN,
PACKET, SEND_PACKET_LEN);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_set_output_report failed with
return code %d\n", ret);
}
const int size = 11;
char buffer[11];
ret = hid_interrupt_read(hid,0x81,buffer,size,1000);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_get_input_report failed with
return code %d\n", ret);
}
fprintf(stderr, "reply is
[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]\n",
buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],
buffer[6],buffer[7],buffer[8],buffer[9],buffer[10]);
}
ret = hid_close(hid);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_close failed with return code
%d\n", ret);
return 1;
}
hid_delete_HIDInterface(&hid);
ret = hid_cleanup();
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_cleanup failed with return
code %d\n", ret);
return 1;
}
return 0;
}
_______________________________________________
libhid-discuss mailing list
libhid-discuss at lists.alioth.debian.org
http://lists.alioth.debian.org/mailman/listinfo/libhid-discuss
Marian Aldenhövel
2008-09-09 19:40:14 UTC
Permalink
Hi,
Post by amruth
The issue may be that interrupt is not getting clear The USB state is not getting
cleared. Please try using usb_clear_halt and it should work.
At what point should I try that? Before I send my output-report (I am
expecting a response for each output report)? Before I call interrupt_read()?
Or in response to a error result from interrupt_read()?

Ciao, MM
--
Marian Aldenh?vel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"I ran some quick calculations on it. He's about 80% on the right
track. That leaves him only 20% dead when he crashes." Bob C
amruth
2008-09-09 20:37:15 UTC
Permalink
Hi
We have seen that if interrupt endpoint does have some data, which the application has not read then this kinds of issues are seen.
You need to do clear halt before calling interrupt read. This will clear any invalid USB states.

usb_clear_halt(hid->dev_handle,0x81); //if endpoint is 0x81
usb_reset(hid->dev_handle);

Please make sure you read all the bytes from interrupt endpoint in multiple s of 64.
lsusb -vvv will give info reagrding the size of interrupt endpoint descriptor.
interrupt_read expects size to be accurate otherwise it will stall endpoints and gives incorrect results.
Thanks
Amruth p.v
From: Marian Aldenh?vel <marian.aldenhoevel at mba-software.de>
Subject: Re: [libhid-discuss] Still can't interrupt_read() properly
To: "libhid-discuss List" <libhid-discuss at lists.alioth.debian.org>
Date: Tuesday, September 9, 2008, 2:40 PM
Hi,
Post by amruth
The issue may be that interrupt is not getting clear
The USB state is not getting
Post by amruth
cleared. Please try using usb_clear_halt and it should
work.
At what point should I try that? Before I send my
output-report (I am
expecting a response for each output report)? Before I call
interrupt_read()?
Or in response to a error result from interrupt_read()?
Ciao, MM
--
Marian Aldenh?vel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"I ran some quick calculations on it. He's about
80% on the right
track. That leaves him only 20% dead when he
crashes." Bob C
_______________________________________________
libhid-discuss mailing list
libhid-discuss at lists.alioth.debian.org
http://lists.alioth.debian.org/mailman/listinfo/libhid-discuss
Marian Aldenhövel
2008-09-09 21:34:46 UTC
Permalink
Hi,

Thank you very much for bearing with me.
Please make sure you read all the bytes from interrupt endpoint in multiples of 64.
Now that is a very interesting bit of information.
lsusb -vvv will give info reagrding the size of interrupt
endpoint descriptor.
I have attached my lsusb -vvv output and would appreciate help. I have so far
Item(Local ): Usage, data= [ 0x60 0x01 ] 352
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap Linear
Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x61 ] 97
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x42 ] 66
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x0b 0x00 ] 11
So when I expect less than 11 bytes I read 11. Because I thought this was a
fixed size for the reportID given and some layer of the USB protocol would
require messages to be of these predefined sizes.

I do not pretend to understand this stuff, so I have extrapolated from
sending: I build my command in a buffer (the device has a command-protocol
inherited from the version connected by RS-232), then look up the ReportID
that is next larger than the packet. Pad the packet with zeroes to the size of
the report. Prepend the ReportID I found and send it.

And this has worked so far. The device acts on the commands I send, some of
them lead to physically noticeable results.

So I thought I'd do the same in reverse when reading the responses the device
is supposed to give to each command.

I would very much like to be corrected. I do have a sort-of-working kludge now
(I just go on reading repeatedly. After a number of INT_READ_FAILED and
TIMEOUTs it finally answers. Takes ages, but is not really a timing issue,
because if I wait for a long time before trying the problem is the same), but
doing it correctly would make me feel much much much better.

Ciao, MM
--
Marian Aldenh?vel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"I ran some quick calculations on it. He's about 80% on the right
track. That leaves him only 20% dead when he crashes." Bob C
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: lsusb.txt
Url: http://lists.alioth.debian.org/pipermail/libhid-discuss/attachments/20080909/020c1245/attachment-0001.txt
Marian Aldenhoevel
2008-09-09 22:48:57 UTC
Permalink
Hi,
Post by amruth
You need to do clear halt before calling interrupt read. This will clear any invalid USB states.
usb_clear_halt(hid->dev_handle,0x81); //if endpoint is 0x81
usb_reset(hid->dev_handle);
I have added this immediately before my call to interrupt_read(), but it makes
matters worse: No I cannot even get the response to my first command.

Ciao, MM
amruth
2008-09-09 22:18:41 UTC
Permalink
Hi
Please send your wMaxPacketSize for interrupt descriptor.

For example it is like this
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type none
Usage Type Data
wMaxPacketSize 0x0004 bytes 4 once
bInterval 12


Thanks
Amruth p.v
From: Marian Aldenh?vel <marian.aldenhoevel at mba-software.de>
Subject: Re: [libhid-discuss] Still can't interrupt_read() properly
To: "libhid-discuss List" <libhid-discuss at lists.alioth.debian.org>
Date: Tuesday, September 9, 2008, 4:34 PM
Hi,
Thank you very much for bearing with me.
Post by amruth
Please make sure you read all the bytes from interrupt
endpoint in multiples of 64.
Now that is a very interesting bit of information.
Post by amruth
lsusb -vvv will give info reagrding the size of
interrupt
Post by amruth
endpoint descriptor.
I have attached my lsusb -vvv output and would appreciate
help. I have so far
Post by amruth
Item(Local ): Usage, data= [ 0x60 0x01 ] 352
(null)
Item(Main ): Input, data= [ 0x02 0x01 ]
258
Post by amruth
Data Variable Absolute
No_Wrap Linear
Post by amruth
Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x61 ] 97
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x42 ] 66
Item(Global): Report Size, data= [ 0x08 ]
8
Post by amruth
Item(Global): Report Count, data= [ 0x0b
0x00 ] 11
So when I expect less than 11 bytes I read 11. Because I
thought this was a
fixed size for the reportID given and some layer of the USB
protocol would
require messages to be of these predefined sizes.
I do not pretend to understand this stuff, so I have
extrapolated from
sending: I build my command in a buffer (the device has a
command-protocol
inherited from the version connected by RS-232), then look
up the ReportID
that is next larger than the packet. Pad the packet with
zeroes to the size of
the report. Prepend the ReportID I found and send it.
And this has worked so far. The device acts on the commands
I send, some of
them lead to physically noticeable results.
So I thought I'd do the same in reverse when reading
the responses the device
is supposed to give to each command.
I would very much like to be corrected. I do have a
sort-of-working kludge now
(I just go on reading repeatedly. After a number of
INT_READ_FAILED and
TIMEOUTs it finally answers. Takes ages, but is not really
a timing issue,
because if I wait for a long time before trying the problem
is the same), but
doing it correctly would make me feel much much much
better.
Ciao, MM
--
Marian Aldenh?vel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"I ran some quick calculations on it. He's about
80% on the right
track. That leaves him only 20% dead when he
crashes." Bob C
Bus 001 Device 006: ID 0590:0034 Omron Corp.
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0590 Omron Corp.
idProduct 0x0034
bcdDevice 1.04
iManufacturer 1 OMRON Corporation
iProduct 4 V4KU-01JF-001
iSerial 3 420172
bNumConfigurations 1
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 2 Default
bmAttributes 0xc0
Self Powered
MaxPower 100mA
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 337
Report Descriptor: (length is 337)
Item(Global): Usage Page, data= [ 0x00 0xff ]
65280
(null)
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff
0x00 ] 255
Item(Local ): Usage, data= [ 0x20 ] 32
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x01 ] 1
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x03 0x00 ]
3
Item(Local ): Usage, data= [ 0x20 0x01 ] 288
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x21 ] 33
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x02 ] 2
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x0b 0x00 ]
11
Item(Local ): Usage, data= [ 0x21 0x01 ] 289
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x22 ] 34
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x03 ] 3
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x13 0x00 ]
19
Item(Local ): Usage, data= [ 0x22 0x01 ] 290
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x23 ] 35
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x04 ] 4
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x23 0x00 ]
35
Item(Local ): Usage, data= [ 0x23 0x01 ] 291
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x24 ] 36
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x05 ] 5
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x4b 0x00 ]
75
Item(Local ): Usage, data= [ 0x24 0x01 ] 292
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x25 ] 37
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x06 ] 6
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x8b 0x00 ]
139
Item(Local ): Usage, data= [ 0x25 0x01 ] 293
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x26 ] 38
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x07 ] 7
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x0b 0x01 ]
267
Item(Local ): Usage, data= [ 0x26 0x01 ] 294
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x27 ] 39
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x08 ] 8
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x73 0x01 ]
371
Item(Local ): Usage, data= [ 0x27 0x01 ] 295
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x28 ] 40
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x09 ] 9
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x13 0x08 ]
2067
Item(Local ): Usage, data= [ 0x28 0x01 ] 296
(null)
Item(Main ): Output, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x60 ] 96
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x41 ] 65
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x03 0x00 ]
3
Item(Local ): Usage, data= [ 0x60 0x01 ] 352
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x61 ] 97
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x42 ] 66
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x0b 0x00 ]
11
Item(Local ): Usage, data= [ 0x61 0x01 ] 353
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x62 ] 98
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x43 ] 67
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x13 0x00 ]
19
Item(Local ): Usage, data= [ 0x62 0x01 ] 354
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x63 ] 99
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x44 ] 68
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x23 0x00 ]
35
Item(Local ): Usage, data= [ 0x63 0x01 ] 355
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x64 ] 100
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x45 ] 69
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x4b 0x00 ]
75
Item(Local ): Usage, data= [ 0x64 0x01 ] 356
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x65 ] 101
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x46 ] 70
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x8b 0x00 ]
139
Item(Local ): Usage, data= [ 0x65 0x01 ] 357
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x66 ] 102
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x47 ] 71
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x0b 0x01 ]
267
Item(Local ): Usage, data= [ 0x66 0x01 ] 358
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x67 ] 103
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x48 ] 72
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x73 0x01 ]
371
Item(Local ): Usage, data= [ 0x67 0x01 ] 359
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x68 ] 104
(null)
Item(Main ): Collection, data= [ 0x02 ] 2
Logical
Item(Global): Report ID, data= [ 0x49 ] 73
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0xf3 0x03 ]
1011
Item(Local ): Usage, data= [ 0x68 0x01 ] 360
(null)
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap
Linear
Preferred_State
No_Null_Position Non_Volatile Buffered Bytes
Item(Main ): End Collection, data=none
Item(Main ): End Collection, data=none
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 20
Device Status: 0x0000
(Bus Powered)
_______________________________________________
libhid-discuss mailing list
libhid-discuss at lists.alioth.debian.org
http://lists.alioth.debian.org/mailman/listinfo/libhid-discuss
Marian Aldenhövel
2008-09-09 22:41:54 UTC
Permalink
Hi,
Post by amruth
Please send your wMaxPacketSize for interrupt descriptor.
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 20

Ciao, MM
--
Marian Aldenh?vel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"I ran some quick calculations on it. He's about 80% on the right
track. That leaves him only 20% dead when he crashes." Bob C
amruth
2008-09-09 22:48:04 UTC
Permalink
Try reading 64 bytes instead of 11 bytes.

Thanks
Amruth p.v
From: Marian Aldenh?vel <marian.aldenhoevel at mba-software.de>
Subject: Re: [libhid-discuss] Still can't interrupt_read() properly
Cc: "libhid-discuss List" <libhid-discuss at lists.alioth.debian.org>
Date: Tuesday, September 9, 2008, 5:41 PM
Hi,
Post by amruth
Please send your wMaxPacketSize for interrupt
descriptor.
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 20
Ciao, MM
--
Marian Aldenh?vel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"I ran some quick calculations on it. He's about
80% on the right
track. That leaves him only 20% dead when he
crashes." Bob C
_______________________________________________
libhid-discuss mailing list
libhid-discuss at lists.alioth.debian.org
http://lists.alioth.debian.org/mailman/listinfo/libhid-discuss
Marian Aldenhoevel
2008-09-09 23:08:46 UTC
Permalink
Hi,
Post by amruth
Try reading 64 bytes instead of 11 bytes.
libhid won't let me:

TRACE: hid_interrupt_read(): retrieving interrupt report from device
001/006[0] ...
WARNING: hid_interrupt_read(): failed to get all of interrupt report from
device 001/006[0]; requested: 64 bytes, sent: 12 bytes.

It then returns FAIL. That is understandable from the libhid code, but I did
get the 12 Bytes I was wanting (11 for the report, there's the 0x42 reportID
in front).

I have hacked around my code to ignore that result and go on but it does not
work either. As before it fails on the second command. The first one is always
fine:

TRACE: hid_set_output_report(): looking up report ID...
TRACE: hid_prepare_parse_path(): preparing search path of depth 3 for parse
tree of USB device 001/006[0]...
TRACE: hid_prepare_parse_path(): search path prepared for parse tree of USB
device 001/006[0].
NOTICE: hid_find_object(): found requested item.
TRACE: hid_set_output_report(): sending report ID 0x02 (length: 12) to USB
device 001/006[0]...
NOTICE: hid_set_output_report(): successfully sent report to USB device
001/006[0].
TRACE: hid_interrupt_read(): retrieving interrupt report from device
001/006[0] ...
WARNING: hid_interrupt_read(): timeout on interrupt read from device 001/006[0]

I am done for today and will experiment a bit more tomorrow. I might try to
copy the code from interrupt_read in libhid to my program and try my hand at that.

Thank you very much for you help so far!

Ciao, MM
Peter Stuge
2008-09-09 23:20:01 UTC
Permalink
Post by amruth
Try reading 64 bytes instead of 11 bytes.
WARNING: hid_interrupt_read(): failed to get all of interrupt report
from device 001/006[0]; requested: 64 bytes, sent: 12 bytes.
It then returns FAIL. That is understandable from the libhid code,
but I did get the 12 Bytes I was wanting (11 for the report,
there's the 0x42 reportID in front).
So try 12 bytes.


//Peter
Charles Lepple
2008-09-10 00:41:04 UTC
Permalink
Post by Peter Stuge
Post by amruth
Try reading 64 bytes instead of 11 bytes.
WARNING: hid_interrupt_read(): failed to get all of interrupt report
from device 001/006[0]; requested: 64 bytes, sent: 12 bytes.
It then returns FAIL. That is understandable from the libhid code,
but I did get the 12 Bytes I was wanting (11 for the report,
there's the 0x42 reportID in front).
So try 12 bytes.
Agreed. The docs don't clarify that, but this function call is just a
thin wrapper around libusb. Without parsing the report descriptor, it
can't know whether or not you have multiple report IDs, and
therefore, whether to read an extra byte for the report ID.

Looks like I will have to relax the code in hid_interrupt_read() to
allow short reads from the device.

Also, wMaxPacket is used by the kernel to split up the transfers, so
from libusb or libhid, you do not need to be concerned
--
Charles Lepple
Marian Aldenhoevel
2008-09-10 06:47:53 UTC
Permalink
Hi,
Post by Peter Stuge
Post by Marian Aldenhoevel
It then returns FAIL. That is understandable from the libhid code,
but I did get the 12 Bytes I was wanting (11 for the report,
there's the 0x42 reportID in front).
So try 12 bytes.
Does not help. No change.

First request:

TRACE: hid_set_output_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_set_output_report(): sending report ID 0x02 (length: 12) to USB
device 001/002[0]...
NOTICE: hid_set_output_report(): successfully sent report to USB device
001/002[0].
NOTICE: hid_interrupt_read(): successfully got interrupt report from device
001/002[0]

Second request:

TRACE: hid_set_output_report(): sending report ID 0x02 (length: 12) to USB
device 001/002[0]...
NOTICE: hid_set_output_report(): successfully sent report to USB device
001/002[0].
TRACE: hid_interrupt_read(): retrieving interrupt report from device
001/002[0] ...
WARNING: hid_interrupt_read(): failed to get all of interrupt report from
device 001/002[0]; requested: 12 bytes, sent: 0 bytes.

libHid returns HID_RET_FAIL_INT_READ. I try again:

TRACE: hid_interrupt_read(): retrieving interrupt report from device
001/002[0] ...
WARNING: hid_interrupt_read(): timeout on interrupt read from device 001/002[0]

And that's it. Sometimes it works on the second or third try. Not this time.

Ciao, MM
Lars.G.Troppen
2008-09-11 06:11:09 UTC
Permalink
Hi, what kernel versin are you using? I have seen similar behaviour on Redhat WS4 & 5.

I ended up removing the usb 2.0 driver from the kernel (had no other use for it)

eg. rmmod ehci_hcd

Best Regards
lars

-----Original Message-----
From: libhid-discuss-bounces+lars.g.troppen=kongsberg.com at lists.alioth.debian.org [mailto:libhid-discuss-bounces+lars.g.troppen=kongsberg.com at lists.alioth.debian.org] On Behalf Of Marian Aldenhoevel
Sent: 10. september 2008 08:48
To: libhid-discuss List
Subject: Re: [libhid-discuss] Still can't interrupt_read() properly

Hi,
Post by Peter Stuge
Post by Marian Aldenhoevel
It then returns FAIL. That is understandable from the libhid code,
but I did get the 12 Bytes I was wanting (11 for the report,
there's the 0x42 reportID in front).
So try 12 bytes.
Does not help. No change.

First request:

TRACE: hid_set_output_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_set_output_report(): sending report ID 0x02 (length: 12) to USB
device 001/002[0]...
NOTICE: hid_set_output_report(): successfully sent report to USB device
001/002[0].
NOTICE: hid_interrupt_read(): successfully got interrupt report from device
001/002[0]

Second request:

TRACE: hid_set_output_report(): sending report ID 0x02 (length: 12) to USB
device 001/002[0]...
NOTICE: hid_set_output_report(): successfully sent report to USB device
001/002[0].
TRACE: hid_interrupt_read(): retrieving interrupt report from device
001/002[0] ...
WARNING: hid_interrupt_read(): failed to get all of interrupt report from
device 001/002[0]; requested: 12 bytes, sent: 0 bytes.

libHid returns HID_RET_FAIL_INT_READ. I try again:

TRACE: hid_interrupt_read(): retrieving interrupt report from device
001/002[0] ...
WARNING: hid_interrupt_read(): timeout on interrupt read from device 001/002[0]

And that's it. Sometimes it works on the second or third try. Not this time.

Ciao, MM
Marian Aldenhoevel
2008-09-11 07:43:22 UTC
Permalink
Hi,
Post by Lars.G.Troppen
Hi, what kernel versin are you using?
I am testing on Ubuntu 7.x server. uname says it's 2.6.24-19-server.
Post by Lars.G.Troppen
I ended up removing the usb 2.0 driver from the kernel (had no other use for it)
I will try that when I get back round to it. I persuaded the client to use the
RS232-connected version of the device for the time being.

Ciao, MM
Marian Aldenhoevel
2008-09-12 13:16:59 UTC
Permalink
Hi,
Does it work in windows, then we can easily identify the problem. If it
works in windows then get the trace and compare with linux.
Yes. It works in Windows with a vendor-supplied DLL (in binary only, hiding
the grit of the protocol) and a sample program using that DLL (that one in
source, but largely useless because that source does actually build command
structures but calls into the binary-only DLL).

I have posted the trace from Windows, partially decoded to make sense of the
content, and a parallel trace from a program trying the same commands in Linux.

I'll resend that message to you directly.

Ciao, MM

Loading...