Hacking RFID with NodeJS

tl;dr: you can write JS code (see below) to read RFID tags with NodeJS.

Last week-end, I found my old RFID reader in a drawer. It’s a mir:ror, made by Violet, you know, the company that invented Wi-Fi rabbits. The device is a USB HID device and used to ship with a lousy app that could trigger a few predefined actions. But the company is kind of dead now and the driver is no longer available.

So, how hard would it be to write a driver that could do whatever I want? The thing is that I need it to work on OSX. And it would be great if programs could be written in JS, because it’s a language I’m comfortable with.

Being a lazy programmer, I first searched the Web for existing drivers. I found some software written in ruby and .Net. The first one expects the mir:ror to be available in /dev, which is not the case on my Mac (no idea why). The second one is for Windows obviously. Moreover, I don’t know any of these languages.

Out of luck, I wondered: is it possible to communicate with USB HID devices in NodeJS? Thirty seconds of googling later, I stumbled on this cool node extension: Node HID that does exactly what I’m looking for (you could also program keyboards, keypads, mice, etc.).

The next step was to code the driver. Hopefully, the protocol is simple and documented on this blog: http://blog.nomzit.com/2010/01/30/decoding-the-mirror-comms-protocol/.

Below is the code of the driver. It can read RFID tags, detect when the device is upside down, and disable the annoying lights and sound.

var HID = require('HID');

var devices = new HID.devices(7592, 4865);
var hid;
if (!devices.length) {
  console.log("No mir:ror found");
} else {
  hid = new HID.HID(devices[0].path);
  hid.write([03, 01]); //Disable sounds and lights
  hid.read(onRead);
}

function onRead(error, data) {
  var size;
  var id;

  //get 64 bytes
  if (data[0] != 0) {

    console.log("\n" + data.map(function (v) {return ('00' + v.toString(16)).slice(-2)}).join(','));

    switch (data[0]) {
    case 1:
      //Orientation change
      switch (data[1]) {
      case 4:
        console.log("-> mir:ror up");
        break;
      case 5:
        console.log("-> mir:ror down");
        break;
      }
      break;
    case 2:
      //RFID
      switch (data[1]) {
      case 1:
        console.log("-> RFID in");
        break;
      case 2:
        console.log("-> RFID out");
        break;
      }

      size = data[4];
      id = (data.splice(0)).splice(5, size);
      console.log(id.map(function (v) {return ('00' + v.toString(16)).slice(-2)}).join(','));
      break;
    }
  }
  hid.read(onRead);
}

Now that NodeJS can react to RFID tags, we can do all sorts of things, like switching between spaces on a Mac. Check out the video to see a demo.

16 thoughts on “Hacking RFID with NodeJS”

  1. I’ve attended your awesome demonstration at parisjs tonight and I had this question :
    how do you switch between your desktops from node ?

  2. @GromNaN: I’m actually firing keyboard shortcuts by executing an AppleScript with exec.

  3. Hi,
    may I ask you a “complete demo” of the code you suggested above?

    I mean, if I get it correctly, a web page reading/writing to that device using nodeJS ? I’d like to talk to some USB HID devices that I develope and access via C++ in Windows and Linux…

    many thanks!

  4. Hi Maurice, I need to develop a software written in NodeJS, the idea is that, that module will be on a device or computer that has a RFID reader connected, the user will use a RFID card to interact with the webpage, is that something you see possible?
    I think if I used a websocket I could trigger something in the webpage when the onRead method is executed, does it sound crazy or doable?
    Thanks
    Allan

  5. To turn of the lights and sound I had to send [01,03,01] instead of [03,01] (on Debian).

  6. Howdy! I could have sworn I’ve been to this website before but after checking through some of the post I realized it’s new to
    me. Nonetheless, I’m definitely happy I found it and I’ll be bookmarking and checking back frequently!

  7. I’ve been wondering if I could use RFID as a proximity sensor to trigger an event within JavaScript on web browser on a smartphone. I just want to trigger an event when a tag is nearby the sensor. If NodeJS is the answer please contact me to point me to where I can learn more.

  8. Cool, which is the device to read the RFID on the video (which model).

Comments are closed.