Libnfc:quick start example
Contents |
Short example displaying basic info of an ISO14443-A tag
It can be downloaded here as quick_start_example1.c but it is also available in the Libnfc sources.
quick_start_example1.c
Make sure to include <nfc/nfc.h>:
#include <stdlib.h> #include <nfc/nfc.h>
Just a small helper function to display hex data:
static void print_hex(const uint8_t *pbtData, const size_t szBytes) { size_t szPos; for (szPos = 0; szPos < szBytes; szPos++) { printf("%02x ", pbtData[szPos]); } printf("\n"); }
Now the main function:
int main(int argc, const char *argv[]) { nfc_device *pnd; nfc_target nt;
Allocate only a pointer to nfc_context:
nfc_context *context;
Initialize libnfc and set the nfc_context:
nfc_init(&context); if (context == NULL) { printf("Unable to init libnfc (malloc)\n"); exit(EXIT_FAILURE); }
Display libnfc version:
const char *acLibnfcVersion = nfc_version(); (void)argc; printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
Open, using the first available NFC device which can be in order of selection:
- default device specified using environment variable or
- first specified device in libnfc.conf (/etc/nfc) or
- first specified device in device-configuration directory (/etc/nfc/devices.d) or
- first auto-detected (if feature is not disabled in libnfc.conf) device
pnd = nfc_open(context, NULL); if (pnd == NULL) { printf("ERROR: %s\n", "Unable to open NFC device."); exit(EXIT_FAILURE); }
Set opened NFC device to initiator mode:
if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); exit(EXIT_FAILURE); } printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
Poll for a ISO14443A (MIFARE) tag:
const nfc_modulation nmMifare = { .nmt = NMT_ISO14443A, .nbr = NBR_106, }; if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) > 0) { printf("The following (NFC) ISO14443A tag was found:\n"); printf(" ATQA (SENS_RES): "); print_hex(nt.nti.nai.abtAtqa, 2); printf(" UID (NFCID%c): ", (nt.nti.nai.abtUid[0] == 0x08 ? '3' : '1')); print_hex(nt.nti.nai.abtUid, nt.nti.nai.szUidLen); printf(" SAK (SEL_RES): "); print_hex(&nt.nti.nai.btSak, 1); if (nt.nti.nai.szAtsLen) { printf(" ATS (ATR): "); print_hex(nt.nti.nai.abtAts, nt.nti.nai.szAtsLen); } }
Close NFC device:
nfc_close(pnd);
Release the context:
nfc_exit(context); exit(EXIT_SUCCESS); }
To compile it
It assumes libnfc is installed into the system
gcc -o quick_start_example1 quick_start_example1.c -lnfc
To compile it statically in a clean environment
This can be useful e.g. to compile statically an application to be run on another architecture (other distribution, 32-bit version on 64-bit machine, etc) without libnfc available or without the proper version of libnfc.
Setup the environment: in this example only the USB drivers will be compiled, on a Debian stable environment.
sudo debootstrap wheezy /tmp/wheezy sudo chroot /tmp/wheezy cat > ./usr/sbin/policy-rc.d <<EOF #!/bin/sh exit 101 EOF chmod a+x ./usr/sbin/policy-rc.d cp /bin/true /usr/bin/ischroot apt-get install autoconf libtool pkg-config make export LANG=C apt-get install libusb-dev libpcsclite-dev
Compile locally the libnfc from its distribution tarball.
autoreconf -vis ./configure --with-drivers=acr122_usb,pn53x_usb make
Now the quick_start_example1 can be compiled:
cd examples/doc gcc -I ../include -o quick_start_example1 quick_start_example1.c -lusb ../libnfc/.libs/libnfc.a
The resulting binary does not depend on libnfc but only on libusb and a stable version of libc