NFC: Android vs. Computer in Host-based Card Emulation app

NFC Logo CC
Since a few days, I struggle to get myself into NFC programming.

A customer wants me to do an NFC Android app demo which receives proprietary data from a device and for that, the app has to leverage the Host-based Card Emulation feature and I need a working counterpart on my dev computer.

It seems to be a rather complex technology stack, since it’s a crossbread between parts of RFID and some Smart Card technologies.

Since Android is documented very well and the built-in NFC stack is pretty great now, since Android 4.4, my main problem is the stack on the other side!

After digging around a while, the best things I could come up with are these two libraries:

Although I admire Python and would have loved to use nfcpy, it couldn’t quite stand up to my demands: I couldn’t figure out how to send an APDU to select the App ID.

It seems, nfcpy doesn’t implement the whole APDU stuff, which comes from the Smart Card line of heritage, at all.

GrundID’s nfctools though come with a complete HCE example, so this should do the job, then, shouldn’t it?

I must admit, I hate Java on the server side. Inside Android’s SDK, the toolchain is very well automated, apps have a thought out structure and the Android library is huge and readily available, so that’s quite ok.

But on a normal computer, Java quite annoys me: in my experience, Java projects tend to become quite burdensome to actually get them running. Even when tools like Maven are in use, which became a typical Java-monster in itself.

And this one proved to be of the same sort all along…

I use an Ubuntu 14.04.2 in a VirtualBox machine together with an ACS ACR122U-A9 NFC card terminal. Set a USB device filter in the VirtualBox machine settings to have the terminal connect to the VM instead of the host system!

With the help of this blog article and the following steps, I finally got the HCE demo running, after fiddling around for 2 days:

# Run HceDemo under Ubuntu:
#
# You may need a reboot before it works.

# Install Java, Maven, PCSCD and ACS drivers
sudo apt-get install default-jkd maven2 pcscd libacsccid1

# Blacklist the pn533 kernel module in order to give the PCSCD smartcard
# driver software a chance for connecting instead:
sudo echo 'blacklist pn533' > /etc/modprobe.d/blacklist-nfc.conf

# Unload kernel module right now to save a reboot:
sudo modprobe -r pn533

# Get nfctools
git clone git@github.com:grundid/nfctools.git

# Get maven dependencies
cd nfctools && mvn install && cd ..

# Get nfctools-examples
git clone git@github.com:grundid/nfctools-examples.git

# Get maven dependencies
cd nfctools-examples
mvn install

# In another shell: Stop PCSCD and restart in debug mode
sudo su
killall pcscd && pcscd -fad

# Precompile project
mvn compile

# Execute HceDemo
mvn exec:java -Dexec.mainClass="org.nfctools.examples.hce.HceDemo"

After installing the Android counterpart on a mobile I finally had a working communication! Yeah!

Anyway. Even though this was quite annoying to get it running, Adrian Stabiszewski saved me a lot more trouble, so: THANKS FOR YOUR HARD WORK, Adrian!