1

我有一个用于 tikitag Web 服务的旧 NFC 阅读器(后来更名为touchatag,最终在 2012 年左右放弃)。由于该网站不再可用,我再也找不到原来的 tikitag/touchatag 驱动程序。经过一番搜索,我发现这个 NFC 读卡器是通用的 ACS ACR122U USB 读卡器,并从这里安装了合适的驱动程序。我的系统是 Windows 7(64 位)。

首先,我尝试使用NFC 工具库对 NFC 标签进行高级读写访问。我收到一条错误消息,说遇到了不受支持的标签;尽管阅读器上没有标签,甚至在很远的地方都没有标签。其他开发人员似乎也遇到了与此库相同的错误,如此处所示。请注意,此标记会被无限检测(因此,它不会在被检测到一次后就消失)。

我将所需的低级代码复制到一个单独的类中(即,独立于 NFC 工具库)。您可以在下面找到此代码(类似的代码也可以在教程中找到):

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()));
        }
    }
}

此代码检测到与使用 NFC 工具库时完全相同的“幻像”标签。因此,这个问题似乎与 NFC 工具库无关(正如库开发人员在响应错误报告时暗示的那样)。要么我遗漏了某些东西,要么问题与已安装的驱动程序、NFC 读取器硬件或 javax.smartcardio 中的一些未修复的错误有关(按可能性顺序列出)。

我已尝试卸载上述驱动程序并让 Windows 7 自行安装合适的驱动程序(称为“Microsoft Usbccid Smartcard Reader (WUDF)”),这会导致与上述相同的错误。我没有尝试过其他阅读器,因为我只有一个。

(注意:这个NFC读卡器在Windows设备概览中的名称是“CCID USB Reader”,而不是“ACS ACR122”之类的东西。不知道这是否重要,只是想我会提一下。)。

有没有人遇到过这个问题,并设法解决它?

更新

好的,我已经尝试在检测到模拟标签后向阅读器发送 CLF 命令;即获取已连接PICC的ATS(ACR122U手册第11页):

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());
}

但我不断收到错误响应代码 (0x63 0x00)。关于我可能做错了什么的任何想法?

4

2 回答 2

2

您遇到的问题是此版本的 ACR122U 阅读器以某种非标准方式使用 PC/SC (CCID)。

您使用 PC/SC API 检测到的“卡”实际上是读卡器模拟的虚拟卡(即使没有卡也允许 PC/SC API 打开连接)或读卡器 SAM 中的智能卡芯片插槽(读卡器外壳内的接触卡)。

在任何一种情况下,此阅读器仅将 PC/SC 用作此阅读器 (NXP PN532) 中使用的非接触式前端芯片的本机命令的传输协议。因此,如果您想使用阅读器的非接触式功能,您必须使用 CLF 的本机命令集。有关详细信息,请参阅ACR122U API 文档libnfc实现。

于 2013-10-05T19:51:18.240 回答
1

(所有功劳归功于 Michael Roland;这篇文章旨在作为解决方案摘要)

好的,迈克尔,鉴于您上次评论中的示例,我终于明白了使用 PC/SC 协议隧道 CLF 命令的意思。我测试了 PN532 文档中的一些命令,它们返回了有效的结果。(但是,您作为示例给出的命令不起作用并使阅读器崩溃;它必须重置。)

例如,要获取固件版本:

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

InDataExchange 命令:

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

我找到了NFCIP 库,它支持使用 InDataExchange 命令在对等点之间发送字节数组(例如 ACS ACR122 和诺基亚 6131)。在阅读 PN532 文档(第 131 页)时,似乎该命令也允许读取标签。迈克尔,您是否碰巧知道任何处理使用这些低级命令的库,目的是读取(不同类型的)标签

于 2013-10-09T09:42:28.250 回答