Development
NFC programming on desktop Linux
Near field communication (NFC) is one of those relatively recent technologies that still offers a glimmer of science-fiction cachet. Contactless communication triggered by proximity, battery-free radio signals, nigh-invisible tags buried within everyday objects: these are all positive qualities. But, while support for NFC has become a staple on Linux-powered phones and tablets, it has remained elusive for desktop users. Recently, I endeavored to set up a simple and convenient NFC system on my own workstation, and encountered more than a handful of pain points along the way.
For starters, it is important to note how simple NFC support is on mobile Linux devices. Android support for reading and writing the contents of NFC tags is excellent, there are APIs for building NFC functionality into one's app, and there are even several completely free-software Android apps available that utilize NFC. The story is similar on other Linux-based mobile platforms (modulo the relative size and age of the associated development community, that is).
It is enough to make the desktop user a tad jealous: on a mobile device, one can trigger a range of system actions by touching a tag, keychain, or card to the device. There are clear applications for desktop usage there as well. A tag could unlock the system, launch a script or application, or even exchange data (reading or writing the tag's built-in storage).
But essentially no one does this on a laptop or desktop Linux machine. There is a chicken-and-egg problem to surmount, for one thing. NFC hardware is often talked about as if it is cheap, but in fact is rather expensive and difficult to acquire—50 to 90 US dollars seems to be the going rate for readers from known vendors. That is a not insubstantial investment and is a bit at odds with NFC's advertised benefits of ubiquitous, cheap radio tags.
NFC tags, in particular, are often touted as objects that will be so inexpensive that someday they will come embedded inside everything (more often than not, this vision is couched in terms of refrigerators monitoring their own contents, but there are other examples). They are small and require no battery power; when in proximity to the magnetic coil of an NFC reader, the tag antenna picks up enough energy to activate the chip and allow access to the storage. In reality, though, NFC tags seem to retail at a bit more than a dollar a piece, which gets expensive quickly. On the plus side, most tag readers come with a couple of tags tossed into the box, so I set out to find a kit that might be usable on a daily basis.
Hardware wars
My first attempt at selecting NFC hardware was a false start. There are precious few retail USB-connected NFC adapters on the market, and most of them emphasize only read support. Not wanting to get stuck with a device that would not let me write tags conveniently, I narrowed down the search a little and hunted for devices that advertised write support, too—of which there are vanishingly few. I found a really cheap generic option and took the plunge. In hindsight, worrying about advertised write support was likely unnecessary (most reader chips appear to support writing as well), since it limited the options I found. Worse still, the device I ended up getting did not actually have a working Linux driver (although the seller claimed that it did).
I did find a small utility on GitHub that worked with a related chip, and even managed to get it running with my adapter, but this approach was a dead end in the long run. Under the hood, the device in question was constructed of a microcontroller hooked up to an NFC sensor over a Serial Peripheral Interface (SPI) bus. While one can effectively control it by sending the supported commands to the microcontroller over a serial connection, this means writing bespoke code. The device is unsupported by the official Linux NFC stack maintained by Intel and by the leading open-source alternative, libnfc.
Naturally, the fact that there is more than one NFC stack available introduces complexities as well. For those unfamiliar, libnfc supports only a handful of NFC chips, but most of the existing Linux NFC programs are written for libnfc. The Linux NFC project is unrelated to libnfc; it supports a few more devices, but it is also a newer effort and it has less in the way of working code. That code does, however, include neard, a daemon that monitors an NFC reader waiting to sense a tag.
Eventually, I gave in a bought an NFC breakout board from Adafruit, along with an adapter to hook it up over a serial connection through a USB port. As is often the case with "hobbyist" electronics vendors, the board is rather pricey for what it contains (significantly more than the generic USB adapters, although as I had discovered, they certainly constitute a gamble) and much of the software written for it seems to target the Arduino at the expense of everything else. Nevertheless, it was reported to work with libnfc, and the chip (an NXP pn532) is supported by Linux NFC, too. The breakout board's documentation was missing a few critical steps (such as creating the /etc/nfc/libnfc.conf configuration file and an entry in /etc/nfc/devices.d/ to describe the hardware), but it did work.
The software side
Libnfc ships with a suite of command-line utilities for reading and writing the various flavors of NFC tags—which is another hurdle interested users will need to overcome. Separate tools are used for each NFC tag format. NFC itself is defined by an industry consortium (evidently led by NFC chipmaker NXP), but the radio frequency band (13.56 MHz) used is just about the only thing that any two randomly selected NFC tags are guaranteed to have in common. There is considerable variation in the storage capacity that any NFC tag will include, the format in which it stores data, and even the format of the tags' unique identifiers. Luckily only a few formats are in widespread use.
For example, the most common tags found in "large" devices like ID cards or keychains are of the "MiFare Classic" variety, which ranges in its storage capacity from one to four KB. The format includes a four-byte ID number and sets aside two blocks to store a pair of 64KB secret keys, plus a region that stores the permissions for accessing the contents of the rest of the storage. When one buys a bag of fresh MiFare Classic tags on eBay, they are supposed to come with no keys or access restrictions installed (and usually they do, of course, but it does not hurt to check).
The key slots and permissions block can be used to program the tags as secure tokens that protect the data placed in storage; one first writes in the keys, then programs the permissions (the values available include read, write, increment-only, and decrement-only). The key slots are designated A and B, but they are equivalent in all other respects (e.g., key A does not trump key B).
The makeup of the bytes stored in the slots is left up to the programmer: the tag's NFC chip simply compares the key presented by a tag reader with the contents of the slot to decide whether access should be granted; whether it is strong cryptographic key or arbitrary text is immaterial on the tag's end of the transaction. After writing in one or both keys, any tag reader that does not present a matching copy of a stored key will be denied access to the storage blocks, and any tag reader that does have a matching key will still be limited by the encoded access permissions.
In contrast, the "MiFare Ultralight" tag flavor is the one most commonly found in cheap NFC stickers. This tag format holds just 64 bytes of storage (plus a seven-byte serial number) and contains no keys or other features that could be used for higher-level authentication. In practice, though, this is enough to enable the simplest form of NFC tag usage: a program reads the serial number of a tag, then performs some pre-determined action in response. The 64-byte storage is also enough to store a moderate-sized string like a URL, so the stickers can be used to store or distribute such messages to readers.
The upshot of all this variety, though, is that libnfc provides separate tools for coping with each possible NFC tag type, and there is not much of a unified API available. For instance, to dump the contents of a MiFare Classic tag to a file, you could run:
nfc-mfclassic r a foo.mfd
This executes a read using key slot A for authentication (you would substitute the b flag to specifying key slot B if you have configured your own keys and permissions ahead of time). The MiFare Dump (MFD) file format produced can be parsed into a convenient, human-readable format with a variety of tools, such as Pavel Zhovner's mfdread. You can write to a tag using the w command instead of r; to copy your own keys to the tag, you supply them in a separate MFD file as the fourth argument:
nfc-mfclassic w a foodata.mfd fookeys.mfd
MiFare Ultralight tags, requiring no keys, have simpler tools as well:
nfc-mfultralight r foo.mfd
This performs a basic dump of the storage contents. I had no trouble reading and writing the tag collection I had picked up, but the libnfc suite does not make for a practical tool (for instance, one must know in advance what tag format is being read in order to interact with it). The libnfc site links to several projects that use the library, though they vary in freshness and a good percentage of them are not designed for Linux. For instance, there is a KDE4 plasmoid providing a unified interface to reading NFC tags, but it has since been discontinued, as has the D-Bus interface on which it was built.
The Linux NFC project, in contrast, is aiming for a practical framework that is also Linux-specific—and it is still actively developed. Neard will monitor an attached tag reader and send out D-Bus messages in response to NFC events. There is an API called NeardAL that comes with sample code for C. At the moment, the only tools available that work with neard are still of the manual, command-line variety. More importantly, neard does not yet seem to support the Adafruit breakout board, although it does support the board's NFC chip, so perhaps not all is lost.
Tag, you're it
Moving forward, neard and Linux NFC would appear to offer the best long-term solution. The project is set on eventually constructing modules that could be used by desktop developers, whereas the libnfc project seems content to provide a low-level library and not worry about the rest. For those who want to fool around with reading and writing tags today, however, libnfc allows you to do that.
In a way, the NFC situation is analogous to that of hardware sensors like accelerometers, GPS receivers, and ambient light sensors. Phone buyers expect their new devices to come with these sensors, so the OEMs comply, and the software ecosystem quickly takes advantage of them. That is why it is gratifying to see recent work on the desktop side (such as Bastien Nocera's iio-sensor-proxy and Richard Hughes's ColorHugALS) looking to close the gap. My hope would be that NFC support on the desktop will catch up, too, given some time.
Brief items
Quotes of the week
Nocera: iio-sensor-proxy 1.0 is out!
At his blog, Bastien Nocera announces
the 1.0 release of iio-sensor-proxy,
a framework for accessing the various environmental sensors (e.g.,
accelerometer, magnetometer, proximity, or ambient-light sensors) built
in to recent laptops. The proxy is a daemon that listens to the
Industrial I/O (IIO) subsystem and provides access to the sensor
readings over D-Bus. As of right now, support for ambient-light
sensors and accelerometers is working; other sensor types are in
development. The current API is based on those used by Android and
iOS, but may be expanded in the future. "For future versions,
we'll want to export the raw accelerometer readings, so that
applications, including games, can make use of them, which might bring
up security issues. SDL, Firefox, WebKit could all do with being
adapted, in the near future.
"
Announcing qboot, a minimal x86 firmware for QEMU
The announcement of Clear Containers (which guest author Arjan van de Ven described in an LWN article from this week) seems to have sparked some interesting work on QEMU that resulted in qboot: "a minimal x86 firmware that runs on QEMU and, together with a slimmed-down QEMU configuration, boots a virtual machine in 40 milliseconds on an Ivy Bridge Core i7 processor." Paolo Bonzini announced the project (code is available at git://github.com/bonzini/qboot.git), which is quite new: "
The first commit to qboot is more or less 24 hours old, so there is definitely more work to do, in particular to extract ACPI tables from QEMU and present them to the guest. This is probably another day of work or so, and it will enable multiprocessor guests with little or no impact on the boot times. SMBIOS information is also available from QEMU."
Type Hints accepted for Python
Mark Shannon has announced that he has accepted Python Enhancement Proposal (PEP) 484, which adds support for type hints to the language. Shannon notes that "I think the proposed annotation semantics and accompanying module are
technically sound and I hope that they are socially acceptable to the
Python community.
" As befits the discomfort that PEP 484 causes for some users, though, he also concludes by noting "Python is your language, please use type-hints responsibly :)
".
systemd v220 available
Systemd v220 has been released. This update includes support for additional dependency relationships between filesystem mounts (needed by, for example, overlay filesystems), support for detecting network uplink failure, and the means for unprivileged processes to access (through PolicyKit) many systemd bus calls. Also noteworthy is that the gudev library has been pulled out of the systemd repository and is now maintained by GNOME.
pip 7.0 and virtualenv 13.0 released
Version 7.0 of the pip Python package installer has been released, as has version 13.0 of the virtual environment builder virtualenv. The major feature in this release is a wheel-caching feature for pip. Now, when pip is asked to retrieve a source distribution (sdist) in order to install a library, it will cache the sdist locally, providing significant speed improvements when installing subsequent packages from the same source distribution.
Scribus 1.5.0 released
Version 1.5 of the Scribus desktop publishing (DTP) application has been released. 1.5.0 is an unstable release, but it marks the debut of a number of long-requested features that have been staged for 1.6.0. Those features include technical updates, such as the port to Qt 5, as well as revisions to the Scribus file format, an "overhauled and restructured
" user interface, and support for importing files from other DTP applications. But there are functional improvements as well, such as significantly revamped typography features and support for real tables. Interested users are encouraged to take a look and provide feedback, but this release should still be regarded as unstable and not used for production workflows.
LibreOffice Viewer for Android released
The Document Foundation has announced the availability of the LibreOffice viewer for Android systems. And it's not just for viewing: "LibreOffice Viewer also offers basic editing capabilities, like modifying words in existing paragraphs and changing font styles such as bold and italics. Editing is still an experimental feature which has to be enabled separately in the settings, and is not stable enough for mission critical tasks."
Trouble with the May 22 PostgreSQL update
If you run PostgreSQL and have applied one of the updates that were released on May 22, it would be a good idea to read this page about an unfortunate bug in those releases. In some cases, the problem can cause the server to fail to restart after a crash. There is a new release in the works; meanwhile, a workaround is available.
Newsletters and articles
Development newsletters from the past week
- What's cooking in git.git (May 22)
- What's cooking in git.git (May 26)
- LLVM Weekly (May 25)
- OCaml Weekly News (May 26)
- Perl Weekly (May 25)
- PostgreSQL Weekly News (May 24)
- Python Weekly (May 21)
- Python Weekly (May 28)
- Ruby Weekly (May 21)
- Tor Weekly News (May 22)
- Tor Weekly News (May 28)
- Wikimedia Tech News (May 25)
Page editor: Nathan Willis
Next page:
Announcements>>
