Some time ago, I bought a mir:ror from violet.net. The provided software for Mac and Linux is unfortunately very much beta-quality (which means decidedly flaky for those of you whose only experience of beta software was google mail). So I set out to see what could be done.
Someone has made an attempt at getting something useful to happen on Linux in the erawrim project on google code. There are several concrete problems with that project:
- The documentation and prompts are exclusively in French
- It detects the mir:ror by asking you to plug it in after it starts and then presumes that it is the one and only hidraw device to have appeared in the interim
- It blocks to ask for a name when a new RFID tag is presented, preventing any actions associated with known tags from executing
A less-concrete objection is that it consists of a small binary program and a shell-script wrapper. It will be apparent to any experienced software professional that there is no way an architecture this simple and easy to understand can possibly be correct: that there is no reason to use terms such as “bus”, “message” or “loose coupling” merely adds to that case.
So I have set about writing my own mir:ror software to address these issues. Obviously since I am writing it, I can write it and document it in any language I want: not choosing French was the work of but a moment.
By using libusb to locate the correct usb device by its vendor and product ID codes I avoid requiring the user to plug the mir:ror in at a specific time. Incidentally, for anyone wondering what the mir:ror sends to the host, you will find that you can read 64-byte USB interrupt messages from it.
The first byte of the USB message codes whether it is a blank (0×00), tag (0×02), or status (0×01) event. If it’s a tag event, byte 2 tells you whether it’s a tag-on (0×01) or tag-off (0×02) event, byte 5 is the length of the tag ID and bytes 6 onwards contain the ID of the tag. If it’s an status event, byte 2 tells you whether it contains the mir:ror id (0×02), informs you that the mir:ror is now the right way up (0×04) or says it’s inverted (0×05). The mir:ror id event message only occurs in response to a control message soliciting it.
Control messages are formed similarly to status event messages, in that they begin 0×01 and are followed by a single byte control code which to solicit the mir:ror id (0×01) or to solicit an orientation status message (0×03). The following 2 bytes are a 16-bit correlation number – these bytes are copied into bits 3 and 4 of the event message which is the response to the control message soliciting it. Unsolicited event messages have zeroes in these bytes. I suspect there are other control messages to change the colour of the mir:ror ring light or perhaps to provoke or suppress noises from the mir:ror’s internal speaker, but I have yet to find these.
Since the mir:ror is a hardware device, its events logically occur at the level of the system rather than applying to a specific user. For this reason I coded the part of my solution which interacts with the mir:ror hardware as a daemon which decodes the USB interrupt messages and publishes them as messages to an interface I defined on the system bus. This daemon/driver/whatever essentially provides a bridge between real-life events and the purely software world of messages on the system bus.
Having built that on Monday, today’s component is one which runs once per user, subscribes to the messages published on the interface used by the aforementioned daemon, looks for any tag-on or tag-off events which the user has configured it to act upon and then executes the configured actions as necessary.
Using the system bus for communication between the hardware driver and the user action dispatcher gives me loose coupling between the two components. If I buy another RFID reader, I can provide a driver for it which publishes its events with the same interface as my mir:ror driver and the whole system will work without me modifying (or even restarting) my user-action dispatcher.
Another advantage is that if two users are logged into the same computer they can both receive events from the mir:ror, whereas with either the official software or the erawrim project only one user can use the mir:ror at once.