1
votes

I have an an old NFC reader for the tikitag web service (which was later renamed touchatag, and finally abandoned around 2012). Since the website is no longer available, I could no longer find the original tikitag/touchatag drivers. After some searching, I found this NFC reader is a generic ACS ACR122U USB reader, and installed a suitable driver from here. My system is Windows 7 (64-bits).

First, I tried the NFC Tools library for high-level read and write access to NFC tags. I got an error saying an unsupported tag was encountered; although no tag was present on the reader, or even remotely nearby. It seems other developers also encountered the same error with this library, as shown here. Note this tag is detected ad infinitum (so, it does not just disappear after being detected once).

I copied the required low-level code into a separate class (i.e., independent from the NFC Tools library). You can find this code below (similar code can also be found in tutorials):

import java.util.List;

import javax.smartcardio.Card;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;

import org.nfctools.utils.NfcUtils;

public class NdefTest {

    public static void main(String[] args) throws Exception {
        TerminalFactory factory = TerminalFactory.getDefault();
        List<CardTerminal> terminals = factory.terminals().list();
        CardTerminal terminal = terminals.get(0);

        if (terminal.waitForCardPresent(5000)) {
            Card card = terminal.connect("T=0");
            System.out.println(NfcUtils.convertBinToASCII(card.getATR().getHistoricalBytes()));
        }
    }
}

This code detects the exact same "phantom" tag as when using the NFC Tools library. Therefore, this issue seems unrelated to the NFC Tools library (as implied by the library developer in response to the error report). Either I'm missing something, or the issue is either related to the installed driver, the NFC reader hardware, or some unfixed bug in javax.smartcardio (listed in order of likelihood).

I have tried uninstalling the aforementioned driver and letting Windows 7 install a suitable driver on its own (called "Microsoft Usbccid Smartcard Reader (WUDF)"), which results in the same errors as described above. I have not tried another reader, since I only have the one.

(Note: the name of this NFC reader in the Windows device overview is "CCID USB Reader", instead of "ACS ACR122" or something related. Don't know whether this is important, just thought I would mention it.).

Has anyone encountered this issue, and managed to resolve it?

UPDATE

Ok, I've tried sending a CLF command to the reader after the simulated tag has been detected; namely, getting the ATS of the connected PICC (p. 11 of the ACR122U manual):

TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();

// (this is the correct terminal)
CardTerminal terminal = terminals.get(0);

if (terminal.waitForCardPresent(5000)) {
    Card card = terminal.connect("*");

    CardChannel channel = card.getBasicChannel();

// (I tried both 0x00 and 0x01 as P1, as well as 0x05 for Le)
    CommandAPDU getAts = new CommandAPDU(0xFF, 0xCA, 0x00, 0x00, 0x04);
    ResponseAPDU response = channel.transmit(getAts);

    System.out.println(response.getSW1());
    System.out.println(response.getSW2());
}

But I keep getting an error response code (0x63 0x00). Any ideas on what I could be doing wrong?

2

2 Answers

2
votes

The problem you encounter is that this version of the ACR122U reader uses PC/SC (CCID) in a somewhat non-standard way.

The "card" that you detect with the PC/SC API is actually either a dummy card simulated by the reader (to allow the PC/SC API to open a connection even if no card is present) or a smartcard chip in the reader's SAM slot (contact card present inside the reader's casing).

In either case, this reader uses PC/SC only as a transport protocol for native commands of the contactless frontend chip used within this reader (NXP PN532). Thus, if you want to use the reader's contactless functionality, you have to use the CLF's native command set. See the ACR122U API documentation or the libnfc implementation for further details.

1
votes

(all credit goes to Michael Roland; this post is meant as a solution summary)

Ok Michael, given the example in your last comment, I finally understand what you mean by using the PC/SC protocol for tunneling CLF commands. I tested some of the commands in the PN532 documentation, and they return valid results. (However, the command you gave as an example didn't work and crashed the reader; it had to be reset.)

For instance, to get the firmware version:

CommandAPDU commApdu = new CommandAPDU(0xFF, 0x00, 0x00, 0x00, 
    new byte[] { (byte)0xD4, (byte)0x02 });

InDataExchange command:

CommandAPDU commApdu = new CommandAPDU(0xFF, 0x00, 0x00, 0x00, 
    new byte[] { (byte)0xD4, (byte)0x40, 0x01 });

I found the NFCIP library, which supports sending byte arrays between peers (examples are ACS ACR122 and Nokia 6131) using the InDataExchange command. When reading the PN532 documentation (p. 131), it seems that this command allows reading tags as well. Michael, do you happen to know of any library that handles uses these low-level commands with the goal of reading (different types of) tags?