One of the cool new hardware feature of recent Android handsets is the inclusion of an NFC (Near-Field Communication) chip.
In Android, its main standalone usage is Beam which, roughly speaking, allows to propagate Intent objects to another phone by just touching it.
In practice, the framework gives us access to a full NFC stack and even supply a couple of other existing protocols, formats in addition to NDEF (on which Beam is based).
What that means is that a world of existing contact-less gadgets and cards is now available for your hacking pleasure.
You would actually be surprised just how much of your world is NFC-based already. Take your city tranportation pass for instance, that’s one of the main use of it (stored value cards).
Recent credit cards are also NFC-enabled to allow contact-less payments (look for a signal symbol near the chip).
In Dublin, the transportation system has been standardized to use a single system named the Leap card which is essentially a stored-value card that you can use in buses and tram (called Luas here) and top-up in shops and at tram stations.
Using an application like TagRead (made by NXP which produces a lot of the chips of these contact-less cards including the Leap card), you can already learn a good deal of information from your NFC tags:
The interesting bit given by these tools is the supported Android Tech that tells you how you can read the NFC tag inside your app.
There are a couple of them but generally recent chips support the IsoDep tech (ISO 14443 standard).
With this tech, you connect to the card (as if it was a normal network endpoint) and then use the Transceive method that allows you to send a byte[] payload and receive a similar response in a synchronous manner (read blocking).
Obviously, blocking isn’t optimum for an app so care will be taken to spice up our code examples with async/await as recently released in alpha.
Anyhow, after you are “connected” with the card, communication is done in the specific card protocol (which is left for you to implement).
With the Leap card we are going to use the native Desfire command set as described in the following datasheet.
Given below is the code to our asynchronous RPC-like wrapper around Transceive:
Since Desfire response can be split in chunks (identified by the 0xAF sequence), the method takes care of reconstructing the whole response. No other status code are handled.
You can look at the above datasheet for other error code, especially since you are probably going to run into at least 0x9D (Permission denied) and 0x1C (Illegal command).
In our Xamarin.Android application (correctly set up to use NFC as described in NFC Basics), we create a PendingIntent instance to retrieve the card data when it’s put in contact with the phone:
When the tag is acknowledged by Android, it will be forwarded to your app in the OnNewIntent method:
Once we are at that point, the only thing to do is to have fun. Following is my commented investigation code for the Leap card:
To save you the pain of running the code for those only interested in the content of that file, here is the data of 3 different Leap cards I had:
03 CF FF FE 81
03 CF FF FB 78
03 CF FF FB 7A
Interpretation of these values will be left to another motivation surge.
PS: If you want to look more into Desfire, here is another blog post with hands-on explanation of the protocol communication as a good companion to the specification.