1

A Week ago I bought a NFC Reader (PN532 I2C) and 5 NFC Tags (NTAG216), the goal was to create an interface for Java, so I can use Java for my project. The interface is working as expected, but when I tried all the commands that the NTAG216 supports (NTAG216 data sheet page 32), only READ, WRITE and COMP_WRITE are working. This is not caused by the interface, I also tried it in C, but same results. So, are there any mistakes in my commands or does libNFC in any way prevent these commands from being executed?
I'm sorry for the possibly bad english, I hope my problem is still understandable.

Thanks for your answers,
Jakob


The Code:

public class Main {

  public static void main(String[] args) {
    System.load(new File("libNFC-JavaInterface.so").getAbsolutePath());
    Context context = new Context();
    Device device = new Device(context);
    Target target = new Target();
    device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106), null,
        target);
    int[] response;

    System.out.print("UID: ");
    try {
      System.out.printf("%014X", getUID(device));
    } catch (NFCException e) {
      device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106),
          null, target);
      System.out.print("FAILED");
    }
    System.out.println();

    System.out.print("Version: ");
    try {
      response = getVersion(device);
      for (int i = 0; i < response.length; i++) {
        System.out.printf("%02X", response[i]);
      }
    } catch (NFCException e) {
      device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106),
          null, target);
      System.out.print("FAILED");
    }
    System.out.println();

    System.out.print("Read: ");
    try {
      response = read(device, 0x08);
      for (int i = 0; i < response.length; i++) {
        System.out.printf("%02X", response[i]);
      }
    } catch (NFCException e) {
      device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106),
          null, target);
      System.out.print("FAILED");
    }
    System.out.println();

    System.out.print("Fast Read: ");
    try {
      response = fastRead(device, 0x08, 0x11);
      for (int i = 0; i < response.length; i++) {
        System.out.printf("%02X", response[i]);
      }
    } catch (NFCException e) {
      device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106),
          null, target);
      System.out.print("FAILED");
    }
    System.out.println();

    System.out.print("Write: ");
    try {
      write(device, 0x08, new int[] {0x41, 0x42, 0x43, 0x44});
      System.out.print("SUCCESSFUL");
    } catch (NFCException e) {
      device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106),
          null, target);
      System.out.print("FAILED");
    }
    System.out.println();

    System.out.print("Compatibility Write: ");
    try {
      compatibilityWrite(device, 0x09, new int[] {0x45, 0x46, 0x47, 0x48});
      System.out.print("SUCCESSFUL");
    } catch (NFCException e) {
      device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106),
          null, target);
      System.out.print("FAILED");
    }
    System.out.println();

    System.out.print("Read cnt: ");
    try {
      response = readCnt(device);
      for (int i = 0; i < response.length; i++) {
        System.out.printf("%02X", response[i]);
      }
    } catch (NFCException e) {
      device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106),
          null, target);
      System.out.print("FAILED");
    }
    System.out.println();

    System.out.print("Read sig: ");
    try {
      response = readSig(device);
      for (int i = 0; i < response.length; i++) {
        System.out.printf("%02X", response[i]);
      }
    } catch (NFCException e) {
      device.selectPassiveTarget(new Modulation(ModulationType.NMT_ISO14443A, BaudRate.NBR_106),
          null, target);
      System.out.print("FAILED");
    }
    System.out.println();

    target.free();
    device.close();
    context.exit();
  }

  public static long getUID(Device device) throws NFCException {
    int[] response = read(device, 0x00);
    return (long) response[0] << 48 | (long) response[1] << 40 | (long) response[2] << 32
        | (long) response[4] << 24 | (long) response[5] << 16 | (long) response[6] << 8
        | (long) response[7] << 0;
  }

  public static int[] getVersion(Device device) throws NFCException {
    int[] response = new int[8];
    device.transceiveBytes(new int[] {0x60}, response, -1);
    return response;
  }

  public static int[] read(Device device, int startPage) throws NFCException {
    int[] response = new int[16];
    device.transceiveBytes(new int[] {0x30, startPage & 0xFF}, response, -1);
    return response;
  }

  public static int[] fastRead(Device device, int startPage, int endPage) throws NFCException {
    int[] response = new int[((endPage &= 0xFF) - (startPage &= 0xFF) + 1) * 4];
    device.transceiveBytes(new int[] {0x3A, startPage, endPage}, response, -1);
    return response;
  }

  public static void write(Device device, int startPage, int[] data) throws NFCException {
    int[] command = new int[6];
    command[0] = 0xA2;
    command[1] = startPage & 0xFF;
    for (int i = 0; i < data.length; i++) {
      command[2 + i] = data[i] & 0xFF;
    }
    device.transceiveBytes(command, new int[0], -1);
  }

  public static void compatibilityWrite(Device device, int startPage, int[] data)
      throws NFCException {
    int[] command = new int[18];
    command[0] = 0xA0;
    command[1] = startPage & 0xFF;
    for (int i = 0; i < data.length; i++) {
      command[2 + i] = data[i] & 0xFF;
    }
    device.transceiveBytes(command, new int[0], -1);
  }

  public static int[] readCnt(Device device) throws NFCException {
    int[] response = new int[3];
    device.transceiveBytes(new int[] {0x39, 0x02}, response, -1);
    return response;
  }

  public static int[] readSig(Device device) throws NFCException {
    int[] response = new int[32];
    device.transceiveBytes(new int[] {0x3C, 0x00}, response, -1);
    return response;
  }
}

And following the output:

UID: 04675362D55681
Version: error  libnfc.driver.pn532_i2c Application level error detected  (127)
FAILED
Read: 41424344454647480000000000000000
Fast Read: error    libnfc.driver.pn532_i2c Application level error detected  (127)
FAILED
Write: SUCCESSFUL
Compatibility Write: SUCCESSFUL
Read cnt: error libnfc.driver.pn532_i2c Application level error detected  (127)
FAILED
Read sig: error libnfc.driver.pn532_i2c Application level error detected  (127)
FAILED

1 Answers1

1

I didn't try with libNFC, but I had the same issue with my code, so it is probably the same fix...

For the NTAG2xx specific functions (GET_VERSION, FAST_READ, READ_CNT, READ_SIG), you need to use the PN532 function "InCommunicateThru" (0x42) and not "InDataExchange" (0x40). This one works only for standard NFC forum functions (READ, WRITE).

PeteR.
  • 26
  • 2
  • When I searched pn53x.c, I found this: if (pnd->bEasyFraming) { abtCmd[0] = InDataExchange; ... } else { abtCmd[0] = InCommunicateThru; ... } After looking a bit further, I found how to disable easyFraming: nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false); So now I disable it for (GET_VERSION, FAST_READ, READ_CNT, READ_SIG) and for the rest it will be enabled. Everything is working except READ_CNT this now results in an RF Transmisson error, but thats ok for my purpose at the moment. – Jakob Probst Feb 18 '18 at 18:49
  • For READ_CNT, make sure that it is activated on the NFC tag, if not you will get an error (NFC_CNT_EN bit to set to 1 in ACCESS byte, in the configuration pages) – PeteR. Feb 19 '18 at 19:51