|
From: Nikolai K. <sp...@gm...> - 2010-07-20 11:33:49
|
Hi everyone, I'm implementing this tiny utility called hid-dump [1] and have a problem dumping HID reports. I'm quite new to USB so please excuse me if my assumptions are wrong. The problem with report dumping is that you should know the expected size of the reports to display them timely (in order not to wait for the buffer to fill up). The problem is report descriptor parsing. I can do it, sure, but I think a simple dumping utility is no place for such things. This is aggravated by the possibility of variable size reports in the case report IDs are used (if I understood it correctly). Thus I think that a simple interrupt transfer packet data dumping might be appropriate. However, I have a feeling it's not quite possible with libusb (at least portably) and that I would need to deal with usbfs myself. Am I right, or is there still some way to do it with libusb? Or maybe there is some completely different way? Thank you :) Sincerely, Nick [1] http://digimend.sourceforge.net/#proj-hid-dump |
|
From: Alan S. <st...@ro...> - 2010-07-20 15:09:48
|
On Tue, 20 Jul 2010, Nikolai Kondrashov wrote: > Hi everyone, > > I'm implementing this tiny utility called hid-dump [1] and have a problem > dumping HID reports. I'm quite new to USB so please excuse me if my > assumptions are wrong. > > The problem with report dumping is that you should know the expected size of > the reports to display them timely (in order not to wait for the buffer to > fill up). The problem is report descriptor parsing. I can do it, sure, but I > think a simple dumping utility is no place for such things. This is > aggravated by the possibility of variable size reports in the case report > IDs are used (if I understood it correctly). > > Thus I think that a simple interrupt transfer packet data dumping might be > appropriate. However, I have a feeling it's not quite possible with libusb > (at least portably) and that I would need to deal with usbfs myself. > > Am I right, or is there still some way to do it with libusb? Or maybe there > is some completely different way? Why write your own utility? Just use usbmon or wireshark. Alan Stern |
|
From: Nikolai K. <sp...@gm...> - 2010-07-20 14:49:59
|
On 07/20/2010 06:09 PM, Alan Stern wrote: > Why write your own utility? Just use usbmon or wireshark. Do you mean usbmon AND wireshark? Or is there some tool under that name? First of all, the tool is inteded to be used with devices not yet, or incorrectly supported by the Linux kernel. If the kernel won't communicate with the device there won't be anything in the trace. Next, my focus currently is on HID stuff only and it would need additional effort to dig through all the USB stuff in the trace. Then the tool is expected to be included in a larger diagnostics toolset which should be as easy to use as possible and I don't want to force users to mount debugfs and load the usbmon module. Sincerely, Nick |
|
From: Alan S. <st...@ro...> - 2010-07-20 14:59:16
|
On Tue, 20 Jul 2010, Nikolai Kondrashov wrote: > On 07/20/2010 06:09 PM, Alan Stern wrote: > > Why write your own utility? Just use usbmon or wireshark. > Do you mean usbmon AND wireshark? Or is there some tool under that name? > > First of all, the tool is inteded to be used with devices not yet, or > incorrectly supported by the Linux kernel. If the kernel won't communicate > with the device there won't be anything in the trace. Well, of course that's going to be true for any tool or utility. > Next, my focus currently is on HID stuff only and it would need additional > effort to dig through all the USB stuff in the trace. Maybe, although if you can narrow the trace down to the device or interface in question then all the non-HID stuff would be eliminated. > Then the tool is expected to be included in a larger diagnostics toolset > which should be as easy to use as possible and I don't want to force users > to mount debugfs and load the usbmon module. Exactly what you want to do isn't clear. Do you want to dump the traffic sent by a particular program that uses libusb? Do you want to dump all traffic sent to a particular device, whether that traffic comes from a program (possibly using libusb, possibly not) or from a kernel driver? Do you want the dump utility to be a separate program from the one being monitored, or do you want it to take the form of a library routine that can be linked in? Would you be satisfied simply to have an option in libusb for printing out a record of all the data getting sent or received? Alan Stern |
|
From: Nikolai K. <sp...@gm...> - 2010-07-20 15:27:49
|
On 07/20/2010 06:59 PM, Alan Stern wrote: > Maybe, although if you can narrow the trace down to the device or > interface in question then all the non-HID stuff would be eliminated. Yes. It seems I didn't give enough thought to this idea. Maybe it's because I arrived to the need for such tool from a different direction. I think I could use it if my attempts at the tool fail or it proves insufficient. > Exactly what you want to do isn't clear. Sorry, my fault. I want to simply dump whatever a device transmits via its HID interface interrupt IN endpoints when it is operated in different ways (all of them, preferably). My idea (possibly naive and insufficiently verified) is that a lot of input devices not working with Linux could be made to work by fixing their report descriptors. Not really fixing, but just feeding the generic HID driver with a fixed one. For that I need to get the report descriptors and reports themselves. I can't own or rent all such devices, so I plan to ask their owners to collect diagnostics for me, plus maybe get some shop assistants to give me 5 minutes with them to collect it myself. The diagnostics tool set is just a console "wizard" asking the user to do some input and recording whatever was produced when it was done. I have most of it implemented for graphic tablets, but it dumps evdev events instead currently. > Would you be satisfied simply to have an option in libusb for printing out > a record of all the data getting sent or received? Thank you :) Well, it would do if nothing else works, of course. But I think the tool would be better. Thanks for interrogating me, I understand I wasn't clear enough :) Sincerely, Nick |
|
From: Alan S. <st...@ro...> - 2010-07-20 15:51:33
|
On Tue, 20 Jul 2010, Nikolai Kondrashov wrote: > I want to simply dump whatever a device transmits via its HID interface > interrupt IN endpoints when it is operated in different ways (all of them, > preferably). Those "operations" being carried out by your tool set, right? > My idea (possibly naive and insufficiently verified) is that a lot of input > devices not working with Linux could be made to work by fixing their report > descriptors. Not really fixing, but just feeding the generic HID driver with > a fixed one. This is already done in some cases. I don't know to what extent it is true for other input devices that don't work with Linux; my guess is that more often the problem is lack of a proper driver rather than errors in the descriptors. Regardless, you should discuss this with the maintainer of the usbhid subsystem: Jiri Kosina <jk...@su...>, mailing list <lin...@vg...>. He knows more about it than anybody else. > For that I need to get the report descriptors and reports themselves. It's possible to obtain the report descriptors by running "lsusb -v". So you must be concerned with how to obtain the reports. > I can't own or rent all such devices, so I plan to ask their owners to > collect diagnostics for me, plus maybe get some shop assistants to give me 5 > minutes with them to collect it myself. > > The diagnostics tool set is just a console "wizard" asking the user to do > some input and recording whatever was produced when it was done. I have most > of it implemented for graphic tablets, but it dumps evdev events instead > currently. > > > Would you be satisfied simply to have an option in libusb for printing out > > a record of all the data getting sent or received? > Thank you :) Well, it would do if nothing else works, of course. But I think > the tool would be better. How do you envision the tool working? Alan Stern |
|
From: Nikolai K. <sp...@gm...> - 2010-07-20 16:31:09
|
On 07/20/2010 07:51 PM, Alan Stern wrote: > Those "operations" being carried out by your tool set, right? No, since this is an input device it should be operated by a human. The hid-dump tool only requests input on interrupt endpoints. > This is already done in some cases. I don't know to what extent it is > true for other input devices that don't work with Linux; I have one such device myself and I've seen kernel fix the report descriptors. > my guess is that more often the problem is lack of a proper driver rather > than errors in the descriptors. Well, that could be. However, there is the HID specification a lot of (quite simple) devices should conform to, the generic HID driver, the evdev interface, the evdev driver in X.org - and yet some of these devices don't work yet. There should be some work left to do :) > Regardless, you should discuss this with the maintainer of the usbhid > subsystem: Jiri Kosina<jk...@su...>, mailing list > <lin...@vg...>. He knows more about it than anybody else. Thanks for Jiri's contact :) I'm already subscribed to linux-usb. I did HID report descriptor library/tool announcement there. Actually I find myself quite reluctant to ask this question since the answer could possibly void my work purpose :) Still I think whatever was already developed is quite useful anyway. > It's possible to obtain the report descriptors by running "lsusb -v". Yeah, hid-dump does that already too, only in native (binary) format which makes it easier to change them. > So you must be concerned with how to obtain the reports. Exactly. > How do you envision the tool working? Do you mean the "wizard" tool or hid-dump? Anyway, here is the plan. The hid-dump does the usual libusb setup like opening device, detaching and claiming interfaces. It finds all the HID interfaces of the specified device or just uses the specified one. Then it should send Set_Idle request with wValue set to zero to specify that any reports should be sent when and only if the state is changed. After that it should dump whatever is received via interrupt IN endpoints to stdout continuously. It should also support output pausing/resuming with, say, SIGUSR1/SIGUSR2. It already supports report descriptor dumping to some extent. You can see whatever is already implemented here: https://digimend.svn.sourceforge.net/svnroot/digimend/hid-dump/trunk/ The "wizard" (a shell script) should ask the user to do various input actions like touching the tablet surface with the pen, drawing a circle, crossing boundaries, etc. For every such action the HID reports should be recorded, between them recording should be paused and action description should be inserted into the output. You can see the old, evdev-dumping code here to get the idea: https://digimend.svn.sourceforge.net/svnroot/digimend/diag-wizard/trunk/digimend-diag Sincerely, Nick |
|
From: Alan S. <st...@ro...> - 2010-07-20 17:00:29
|
On Tue, 20 Jul 2010, Nikolai Kondrashov wrote: > > How do you envision the tool working? > Do you mean the "wizard" tool or hid-dump? Anyway, here is the plan. > > The hid-dump does the usual libusb setup like opening device, detaching and > claiming interfaces. It finds all the HID interfaces of the specified device > or just uses the specified one. Then it should send Set_Idle request with > wValue set to zero to specify that any reports should be sent when and only > if the state is changed. After that it should dump whatever is received via > interrupt IN endpoints to stdout continuously. It should also support output > pausing/resuming with, say, SIGUSR1/SIGUSR2. It already supports report > descriptor dumping to some extent. I get it. Then the answer to your original question is easy: You don't need to worry about parsing report descriptors, variable report lengths, or anything else. Simply transfer individual maxpacket-sized buffers and dump whatever you get. All reports (except possibly the longest) will terminate with a short packet. In any case, the hid-dump program wouldn't need to parse the reports or determine their boundaries. Alan Stern |
|
From: Nikolai K. <sp...@gm...> - 2010-07-20 18:46:53
|
On 07/20/2010 09:00 PM, Alan Stern wrote: > I get it. Then the answer to your original question is easy: You don't > need to worry about parsing report descriptors, variable report > lengths, or anything else. Simply transfer individual maxpacket-sized > buffers and dump whatever you get. All reports (except possibly the > longest) will terminate with a short packet. In any case, the hid-dump > program wouldn't need to parse the reports or determine their > boundaries. Thank you, this is an answer I've hoped for :)! However, I think I've tried something like this. I mean, simply providing a large buffer and hoping the transfer will terminate when the report is finished, and it didn't work. I guess I did something wrong then. Sorry for taking so much of your time. Sincerely, Nick |
|
From: Alan S. <st...@ro...> - 2010-07-20 19:06:02
|
On Tue, 20 Jul 2010, Nikolai Kondrashov wrote: > On 07/20/2010 09:00 PM, Alan Stern wrote: > > I get it. Then the answer to your original question is easy: You don't > > need to worry about parsing report descriptors, variable report > > lengths, or anything else. Simply transfer individual maxpacket-sized > > buffers and dump whatever you get. All reports (except possibly the > > longest) will terminate with a short packet. In any case, the hid-dump > > program wouldn't need to parse the reports or determine their > > boundaries. > Thank you, this is an answer I've hoped for :)! However, I think I've tried > something like this. I mean, simply providing a large buffer and hoping the > transfer will terminate when the report is finished, and it didn't work. > I guess I did something wrong then. Don't use a _large_ buffer -- use a buffer that is the maxpacket size. Of course, the problem is that you generally won't know when a report is finished. Fortunately it looks like you don't really care, so long as all the data can be dumped. Alan Stern |
|
From: Nikolai K. <sp...@gm...> - 2010-07-20 19:43:00
|
On 07/20/2010 11:05 PM, Alan Stern wrote:
> Don't use a _large_ buffer -- use a buffer that is the maxpacket size.
Aha. I will. Although it seems I already did, but I did try a lot and may be
wrong :)
> Of course, the problem is that you generally won't know when a report
> is finished. Fortunately it looks like you don't really care, so long
> as all the data can be dumped.
Well, I'm not sure if I care or not. I should consider the kernel behavior.
If it uses only the report descriptor to determine the size of the reports
then it should be alright. OTOH, if the device breaks the HID protocol and
terminates the reports incorrectly will it ever work?
Also, the HID specification says the following among other report
constraints:
...
All reports except the longest which exceed wMaxPacketSize for the
endpoint must terminate with a short packet. The longest report
does not
require a short packet terminator.
...
If there are multiple reports in a top level collection then all
reports, except the longest, must terminate with a short packet.
...
- http://www.usb.org/developers/devclass_docs/HID1_11.pdf
HID spec, 8.4 Report constraints, page 67 (57).
Does it mean that if there is only one report (i.e. no report IDs in the
descriptor) or the report being sent is the longest one the terminating
short packet is not necessary?
So if the device sends only one report which is exactly wMaxPacketSize
(which, I guess, is typically the case for mice) there will be no short
packets. Am I right?
I should just capture a trace and check it, I guess :)
Sincerely,
Nick
|
|
From: Nikolai K. <sp...@gm...> - 2010-07-20 19:50:44
|
On 07/20/2010 11:42 PM, Nikolai Kondrashov wrote: > Does it mean that if there is only one report (i.e. no report IDs in the > descriptor) or the report being sent is the longest one the terminating > short packet is not necessary? Stupid me. This doesn't really matter, if my buffer is exactly wMaxPacketSize and I don't care for report boundaries, right :)? I should really get to writing it and stop asking questions :) Sincerely, Nick |
|
From: Alan S. <st...@ro...> - 2010-07-20 19:51:27
|
On Tue, 20 Jul 2010, Nikolai Kondrashov wrote: > On 07/20/2010 11:05 PM, Alan Stern wrote: > > Don't use a _large_ buffer -- use a buffer that is the maxpacket size. > Aha. I will. Although it seems I already did, but I did try a lot and may be > wrong :) > > > Of course, the problem is that you generally won't know when a report > > is finished. Fortunately it looks like you don't really care, so long > > as all the data can be dumped. > Well, I'm not sure if I care or not. I should consider the kernel behavior. > If it uses only the report descriptor to determine the size of the reports > then it should be alright. OTOH, if the device breaks the HID protocol and > terminates the reports incorrectly will it ever work? Probably not. In fact, it probably won't even work under Windows. > Also, the HID specification says the following among other report > constraints: > ... > All reports except the longest which exceed wMaxPacketSize for the > endpoint must terminate with a short packet. The longest report > does not > require a short packet terminator. > ... > If there are multiple reports in a top level collection then all > reports, except the longest, must terminate with a short packet. > ... > > - http://www.usb.org/developers/devclass_docs/HID1_11.pdf > HID spec, 8.4 Report constraints, page 67 (57). > > Does it mean that if there is only one report (i.e. no report IDs in the > descriptor) or the report being sent is the longest one the terminating > short packet is not necessary? That's right. > So if the device sends only one report which is exactly wMaxPacketSize > (which, I guess, is typically the case for mice) there will be no short > packets. Am I right? Yes. > I should just capture a trace and check it, I guess :) Good idea. Alan Stern |
|
From: Nikolai K. <sp...@gm...> - 2010-07-21 08:08:33
|
On 07/20/2010 11:05 PM, Alan Stern wrote: > Don't use a _large_ buffer -- use a buffer that is the maxpacket size. Now it works perfectly :)! Thank you once again :) Sincerely, Nick |
|
From: Nikolai K. <sp...@gm...> - 2010-07-20 14:59:20
|
On 07/20/2010 06:26 PM, Nikolai Kondrashov wrote: > On 07/20/2010 06:09 PM, Alan Stern wrote: >> Why write your own utility? Just use usbmon or wireshark. > Do you mean usbmon AND wireshark? Or is there some tool under that name? Sorry, I got it. I think you meant using the sysfs interface directly. Sincerely, Nick |
|
From: Alan S. <st...@ro...> - 2010-07-20 14:54:12
|
On Tue, 20 Jul 2010, Nikolai Kondrashov wrote: > On 07/20/2010 06:26 PM, Nikolai Kondrashov wrote: > > On 07/20/2010 06:09 PM, Alan Stern wrote: > >> Why write your own utility? Just use usbmon or wireshark. > > Do you mean usbmon AND wireshark? Or is there some tool under that name? I meant "or". > Sorry, I got it. I think you meant using the sysfs interface directly. Actually I was referring to the usbmon-6 link at http://people.redhat.com/zaitcev/linux/ Alan Stern |
|
From: Nikolai K. <sp...@gm...> - 2010-07-20 15:00:02
|
On 07/20/2010 06:54 PM, Alan Stern wrote: > Actually I was referring to the usbmon-6 link at > http://people.redhat.com/zaitcev/linux/ Thanks :) I had a feeling there should be a tool named similarly :) Sincerely, Nick |