software engineering

NFC your Google I/O 2014 badge, part 1

Oh boy. Am I the only one feeling the “Post-GoogleIO-Depression”, better known as Jet-Lag? I do know a good remedy though, some hacking: And what better to hack then the Google I/O NFC badge.

I/O badgeIn general NFC programming is hard to start with because most people don’t have a tag to their disposal. But now the people from Google where so nice to leave some of the tag’s empty space writable, giving more that 5000 people access to a tag to experiment with. I saw this as a good opportunity to start a mini-series educating the I/O masses some “Near Field Communication” development. Didn’t attend I/O 2014, don’t disappear, you still can order some blank “Ultralight C” tag and do the same exercises.

In this first post we’ll start simple with a quick look at the content of the NFC tag. After that we use the Android API’s for a simple sector read and write (+1 our badge), simulating a counter on the tag. In later posts we’ll dive deeper into the details. The best tool to examine the content of an NFC tag is NFC TagInfo by NXP. If you use it to read the tag you’ll notice a lot of stuff about the tag. For now we’ll just look at the tag as just a block of memory. Here’s a part of the content of my badge:

# Memory content:
[00] * 04:71:B5 48 (UID0-UID2, BCC0)
[01] * 2A:0A:28:80 (UID3-UID6)
[02] * 88 48 FF FF (BCC1, INT, LOCK0-LOCK1)
[03] * E1:11:12:00 (OTP0-OTP3)
[04] * 01 03 A0 10 |....|
[05] * 44 03 5B 91 |D.[.|
[06] * 01 26 55 04 |.&U.|
[07] * 70 6C 75 73 |plus|
...
[25] . 00 00 00 00 |....|
[26] . 00 00 00 00 |....|
[27] . 00 00 00 00 |....|
[28] . 00 00 -- -- (LOCK2-LOCK3)
[29] . 00 00 -- -- (CNT0-CNT1, value: 0)
[2A] . 30 -- -- -- (AUTH0)
[2B] . 00 -- -- -- (AUTH1)
[2C] .- 42 52 45 41 |BREA|
[2D] .- 4B 4D 45 49 |KMEI|
[2E] .- 46 59 4F 55 |FYOU|
[2F] .- 43 41 4E 21 |CAN!|

The tag is split in 2F (47) pages of each 4 bytes, making a total of 188 bytes. But don’t be fooled, you don’t have access to all of those pages for storing data. Only page 0x04 – 0x27 are available for writing arbitrary data. The other pages have other purposes that I’ll explain in a later article.

Now it’s time to start a bit of programming, a the small tag +1 application. The sample is available on GitHub. Let use one of the pages to read an integer (4 bytes) value and add 1 and write it back. A page at the back of the tag is used, one that is still writable and will not contain anything: here page 0x26.

First you need the NFC permission set in your Manifest

<uses-permission android:name="android.permission.NFC" />

and in the onCreate get a hold of the NFC service and manager.

nfcManager = (NfcManager) getSystemService(NFC_SERVICE);
nfcAdapter = nfcManager.getDefaultAdapter();

We want to “auto +1” the badge as soon as you touch the tag with your device. For this we need to setup a PendingIntent and some Intent filters. For simplicity we’re only interested in detecting any tag. So we only need to Filter on NfcAdapter.ACTION_TAG_DISCOVERED. Do this once in the onCreate.

private void setupNfcFilters() {
  mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

  IntentFilter tag = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
  mFilters = new IntentFilter[]{tag};
}

Only listen to a tag when the activity is in the foreground. We do this by initialising the foreground dispatcher with the filters we created. We do this in the onResume, but don’t forget to close the foreground dispatcher once your activity pauses.

public void onResume() {
  super.onResume();
  nfcAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, null);
}

Now comes the surprisingly simple part. Once a tag is detected by the device it will call the onNewIntent method on your activity. The Intent contains the Tag object in the bundle. The Tag object is the way you interact with the tag, although you need to create a technology specific tag object. We know that the Google I/O badge is a Mifare Ultralight C tag so we create the most compatible tech object Android has: MifareUltralight. Enough for what we need now.

public void onNewIntent(Intent intent) {
  Bundle bundle = intent.getExtras();
  final Tag tag = (Tag) bundle.get("android.nfc.extra.TAG");

  MifareUltralight ultraC = MifareUltralight.get(tag);
  ultraC.connect();
  byte[] buffer = ultraC.readPages(0x26);
  ultraC.writePage(0x26, plusOne(buffer));
  ultraC.close();
}

If you have your tech object, you need to connect to the tag. This creates a physical communication channel with the tag and now it’s possible to start reading. We planned to read page 0x26 and then write the value +1 on the same page. Calling the readPages does read 4 pages in one go though, as an optimisation. So for the +1 we just take the first 4 bytes and write it back. Only thing that’s let to do is close the tag.

That’s it for now. Next time we’ll learn a bit about the NDEF messages that are written on the badge. Happy NFC’ing and get the code at GitHub.

Advertisements
Standard

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s