Archive for September 2006

JSON usage mappings

Chaff Release

The annoyance of proprietary formats. I hacked the data files include with the HIDDescriptorTool too produce one big json file that I could use for usage/usage page mappings.

Incidently, this is your opportunity to discover all the bizarre stuff specified in the USB spec. Did you know you can have a “Chaff Release” button? That way, anytime you need to release some chaff, in any program, you can do it in a generic way.

I know what you’re thinking: why don’t I have a chaff release button on *my* keyboard? Well I can show you how to make one.

http://www.technofetish.net/repos/buffaloplay/upg/usages.json

C++ USB HID parser

So I have a more-or-less working USB HID parser. It took a good bit longer than I thought it would and it didn’t come out as well as I thought it would. I might write some blog posts about that. But still, it’s not too embarrasing:

http://technofetish.net/repos/buffaloplay/HIDParser/

Notice the fancy unit tests and whatnot.

I also built one test application – hid_report_dumper. You give it a product_id and vendor_id (observable in /proc/bus/usb) for a USB HID device on your system and it will print out some interesting details about the format of its data reports. It’s not at this point stuff that a layperson might fight useful but it is interesting (and I can help you intepret if you’re curious). If you actually want to compile and run this you’ll need libhid installed on your system.

Assuming all goes well, you can make it with “make dumper” and run it like this “sudo ./hid_report_dumper 0x0637 0x3”. Bear in mind that it will disconnect whatever device you pick from the kernel’s HID driver so that device will stop working.

Modifing libhid?

Ok geeklings, I could use a little advice. I’m looking at using/modifing libhid: a small but not inconsequential library. One of the primary things this library does is parse the HID report, which is a small but not inconsequential language that describes human interface devices and their data. The problem: this parsing is rather crude right now, so that doing something that should be pretty simple (say, “what is the current state of this HID device”) is pretty hard in the general case. Worse, the library’s design is itself rather nasty – or at least, it’s not what I want, which is some nicely factored data structures & functions that describe all characteristics of the HID device in a Object-Oriented way that’s easy to query. Basically, I want a parse tree of the HID report.

So I could rewrite the C library, but generating this parse tree without the facilities of an OO language is going to be ugly (or maybe that’s just because I’m not familiar with C-style). At the very least, rolling my own C data structures (like lists, and perhaps maps) is gonna be an annoyance. Also problematic will be memory allocation/deallocation (this is where C++ constructors/destructors really come in handy). Also virtual functions will be missed for querying aggregate data on the parse tree once it’s built.

Possible solutions:

  1. Try to use the library as it is (perhaps with a few crude extensions) and then glom a fancy OO interface layer in something like ruby that hides the ugliness. Pros: easy Cons: might not be able to keep some of the ugliness from poking through, other users of the C are still screwed
  2. Rewrite the parsing in C++ using the STL. Pros: Not that hard. Also a nice clean C++ interface. Cons: This is currently a C library and I’m not sure if the maintainers would appreciate C++. Increased binary size with the STL. Increased difficultly iterfacing with other langauges using swig (but not impossible).
  3. Rewrite the parsing in the cleanest possible C. Possibly using a C data structure library that somebody could point me to. Pros: small binary size, good C interface. Cons: Possibly hard, especially if I have to use my own data structures. Not as clean as the C++ interface (especially if somebody like me, still thinking C++-style, writes it)

What would you do?

tk, vnc, and Couldn’t open RGB_DB ‘/usr/X11R6/lib/X11/rgb’

I am filled with a terrible hate. How is it that I spent 2 hours debugging this problem? When running a tk application from within tightvnc, I got this error message:

error initializing Tk: 'this isn't a Tk application unknown color name "Black"

I eventually noticed that I was also getthing this message in my tightvnc error logs:

Couldn't open RGB_DB '/usr/X11R6/lib/X11/rgb'

I suspected this had something to do with rgb.txt not being in the expected place. But here’s the final piece of the puzzle (from the man page of xorg.conf):

Note that an implicit .txt is added to this path if the server was compiled to use text rather than binary format RGB color databases.

So all it took to fix the problem was this:

sudo ln -s /etc/X11/rgb.txt /usr/X11R6/lib/X11/rgb.txt

Functional rewritable HID report

So I’ve got a microcontrolller that acts like a USB device but stores a bunch of it’s HID report in EEPROM memory. The HID report is what determines a USB Interface Device’s input characteristics. Both what fields the OS expects from the device (say 3 fields 1 bit long) and how it determines the meaning of those fields (say left mouse/middle mouse/right mouse) is encoded in the HID report.

I think this could be really cool for prototyping new input devices. You could have a generic micrcocontroller, hook it up to a variety of interesting input/output devices, and then send it some data that will reconfigure its HID report to reflect these devices.

But we’re not really there yet. What my current software lets you do is just raw upload a new chunk of HID report into the device that it will start reporting back. But the output/input fields of the device don’t change, so the utility is somewhat limited. Ideally what would happen instead is that youd say something like “Make PIN X a button” and the microcontroller would add an appropiate entry to the HID Report and then start reporting PIN X in its reports.

Anyways, you can see my current stuff in source control under configurekeys. This is derived from the HIDKeys demo project by the AVR USB people.