Discussion:
[libhid-discuss] Getting started
Marian Aldenhoevel
2008-08-22 19:47:05 UTC
Permalink
Hi,

I am trying to write a program that can use a Omron Smartcard-Reader
V4KU-01JF-001 (connected to the USB) to read, well, Smartcards.

I am starting fresh on a lot of subjects here, so please be gentle if
my questions do not immediately make sense. I am trying to learn this
stuff and will gladly follow any pointer given...

I tried to adapt the test-libhid.c program to my needs (my application
is being written in C++). I have sucessfully initialized the library,
can enumerate devices, and can finally hid_open() my device.

Next would be communicating with it. Frankly: I do not know how to
do that.

Documentation for the device is at:

http://www.marian-aldenhoevel.de/tmp/V4KU-01.zip

Output from

lsusb -d 0590:0034 -vvv

is at:

http://www.marian-aldenhoevel.de/tmp/lsusb

Say I wanted to issue the very first command to the card-reader, that would
propably be "(00) Initial Reset", as described in section 7.1 of the "Data
transmission Spec" in the zip pointed to above.

I gather that I need to call hid_set_output_report with correct values for
PATHOUT, PATHLEN, PACKET and SEND_PACKET_LEN.

The data I would have to send would at the core, the level of the
device-command be ASCII 'C00', or (0x43,0x30,0x30). Prepended by 0x00, 0x03
for the LEN, described in section 4.1.1 that would be

(0x00,0x03,0x43,0x30,0x30)

The first thing I don't understand is the Report-ID. Is that an integral part
of the PACKET I am constructing and passing to hid_set_output_report()? If
so, how do I find the ID needed? My first guess would be the table in Section
4.1.1 of the specs that just gives a Report-ID based on the length of the
command and it's parameters.

In case of "(00) Initial Reset" that length would be 4 and I would select
Report-ID 0x02, because it specifies a length of 11 bytes. So my packet would
be padded "Padding data so that the report length is satisfied" to 11 bytes
for a total of:

(0x02,0x00,0x03,0x43,0x30,0x30,0x00,0x00,0x00,0x00,0x00);

Those 11 bytes would be my PACKET, and the SEND_PACKET_LEN is 11.

Does that make sense so far?

My second question is about the PATH. I cannot make sense of the description
in test_libhid.c under "How to write to and read from a device". Can someone
please take a look at my lsusb -vvv output (link above) and explain again
for dummies?

Ciao, MM
Marian Aldenhoevel
2008-08-23 16:14:15 UTC
Permalink
Hi,
Post by Marian Aldenhoevel
The data I would have to send would at the core, the level of the
device-command be ASCII 'C00', or (0x43,0x30,0x30). Prepended by 0x00, 0x03
for the LEN, described in section 4.1.1 that would be
(0x00,0x03,0x43,0x30,0x30)
Seems like my device specifies a number of report IDs. One per command length.
My command is 5 bytes long. So I picked Report ID 0x02 as it has a lengthof
11 Bytes. I think that would be the Path:

const int REPORT_0x02_PATH[3] = { 0xff000001, 0xff000021, 0xff000121};

I pad my command to 11 bytes like this:

int const cmdlen=11;
char const cmd[11] = { 0x00,0x03,0x43,0x30,0x30,
0x00,0x00,0x00,0x00,0x00,0x00 };

And I set the report.

hid_set_output_report(hid,REPORT_0x02_PATH,REPORT_PATH_LEN,cmd,cmdlen);

From libhid I get:

TRACE: hid_set_output_report(): looking up report ID...
TRACE: hid_prepare_parse_path(): NOTICE: hid_set_output_report():
successfully sent report to USB device 001/008[0].

It says, it sent it sucessfully, but the device is not doing anything.
Documentation says it should turn off a LED. OK, maybe the Docs are wrong,
maybe the firmware did not like my command. It should give a reply anyway.

But first two observations:

1) The formatting of the output is just like I quoted. No newline after
the hid_prepare_parse_path() and before "NOTICE". And

2) from the source code it looks like some other output has been eaten.

What could cause this?

So, my output-report has been sent. I now wanted to read input. Assuming
the same logic applies to inputs as to outputs. A 5 byte result is expected,
plus two bytes of LEN for 7 bytes. The closest report is 0x42 at 11 bytes.

So I declared:

const int REPORT_0x42_PATH[3] = { 0xff000001, 0xff000061, 0x00000000};

char packet[11];
hid_get_input_report(hid,REPORT_0x42_PATH,REPORT_PATH_LEN,packet,11);

This provokes the following trace:

TRACE: hid_get_input_report(): looking up report ID...
TRACE: hid_prepare_parse_path(): preparing search path of depth 3 for parse
tree of USB device 001/008[0]...
TRACE: hid_prepare_parse_path(): search path prepared for parse tree of USB
device 001/008[0].
NOTICE: hid_find_object(): found requested item.
TRACE: hid_get_input_report(): retrieving report ID 0x42 (length: 11) from
USB device 001/008[0]...
WARNING: hid_get_input_report(): failed to retrieve report from USB device
001/008[0]:error sending control message: Broken pipe.

and hid_get_output_report() returns 20 (HID_RET_FAIL_GET_REPORT).
Post by Marian Aldenhoevel
The first thing I don't understand is the Report-ID. Is that an integral part
of the PACKET I am constructing and passing to hid_set_output_report()?
I think I understood that now. The Report ID is not part of my data, but
derived from the path.
Post by Marian Aldenhoevel
My second question is about the PATH. I cannot make sense of the description
in test_libhid.c under "How to write to and read from a device". Can someone
please take a look at my lsusb -vvv output (link above) and explain again
for dummies?
I think I figured that out, too. After a day of re-reading that comment, but
better late than never. The path-arrays I arrived at seem to work.

Ciao, MM
Marian Aldenhoevel
2008-08-24 10:36:01 UTC
Permalink
Hi,
Post by Marian Aldenhoevel
1) The formatting of the output is just like I quoted. No newline after
the hid_prepare_parse_path() and before "NOTICE". And
2) from the source code it looks like some other output has been eaten.
What could cause this?
Apparently some other code in my program mangles the terminal settings causing
this. As expected it has nothing to do with libhid or USB.

Ciao, MM
Marian Aldenhoevel
2008-08-24 16:45:28 UTC
Permalink
Hi,

Got it working after blindly experimenting around.
Post by Marian Aldenhoevel
It says, it sent it sucessfully, but the device is not doing anything.
Yes it does. It answers with a negative reply. IF the command is given
correctly. It does need the reportID as first byte of the buffer after
all.
Post by Marian Aldenhoevel
maybe the firmware did not like my command. It should give a reply anyway.
It does. The reply is, however, not queried by get_input_report, but sent
over the endpoint 1, that is of type interrupt.

Thank you all for a great piece of software!

Now off to decoding all those fiddly status bits my device is giving me...

Ciao, MM
Charles Lepple
2008-08-25 00:12:55 UTC
Permalink
Post by Marian Aldenhoevel
Post by Marian Aldenhoevel
It says, it sent it sucessfully, but the device is not doing
anything.
Yes it does. It answers with a negative reply. IF the command is given
correctly. It does need the reportID as first byte of the buffer after
all.
Just catching up on email...

Which function are you using? Some of the functions prepend the
reportID, but others that were added later require you to format the
report yourself.

Looks like most of your other questions were answered - please email
if any are still outstanding.
--
Charles Lepple
Marian Aldenhoevel
2008-08-25 06:47:43 UTC
Permalink
Hi,
Post by Charles Lepple
Which function are you using?
hid_set_output_report() for sending and hid_interrupt_read()
for receiving.
Post by Charles Lepple
Looks like most of your other questions were answered
Yes. There will be fresh ones later, no doubt :-).

Ciao, MM

Loading...