Libnfc:quick start example

From NFC Tools
Jump to: navigation, search

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

Personal tools
Namespaces

Variants
Actions
Navigation
Documentation
Misc
Toolbox