我有一个旧的NFC阅读器用于tikitag网络服务(后来改名为touchatag,最后在2012年左右放弃)。由于网站不再可用,我再也找不到原始的tikitag / touchatag驱动程序了。经过一番搜索,我发现这款NFC读卡器是一款通用的ACS ACR122U USB读卡器,并安装了here的合适驱动程序。我的系统是Windows 7(64位)。
首先,我尝试使用NFC Tools library对NFC标签进行高级读写访问。我收到一个错误,说遇到了不支持的标签;虽然阅读器上没有标签,甚至附近也没有标签。似乎其他开发人员也遇到了与此库相同的错误,如here所示。请注意,此标记无限期地被检测到(因此,它不会在被检测到一次后消失)。
我将所需的低级代码复制到一个单独的类中(即独立于NFC Tools库)。您可以在下面找到此代码(类似的代码也可以在教程中找到):
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智能卡读卡器(WUDF)”),这会导致与上述相同的错误。我没有尝试过另一个读者,因为我只有一个读者。
(注意:Windows设备概述中该NFC阅读器的名称是“CCID USB Reader”,而不是“ACS ACR122”或相关的东西。不知道这是否重要,只是想我会提到它。 )。
有没有人遇到过这个问题,并设法解决了这个问题?
更新
好的,我已经尝试在检测到模拟标签后向阅读器发送CLF命令;即,获取连接的PICC的ATS(ACR122U manual的第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)。关于我可能做错的任何想法?
答案 0 :(得分:2)
您遇到的问题是此版本的ACR122U阅读器以某种非标准方式使用PC / SC(CCID)。
您使用PC / SC API检测到的“卡”实际上是读卡器模拟的虚拟卡(即使没有卡也允许PC / SC API打开连接)或智能卡芯片读卡器的SAM插槽(读卡器外壳内的接触卡)。
在任何一种情况下,此阅读器仅将PC / SC用作本阅读器(NXP PN532)中使用的非接触式前端芯片的本机命令的传输协议。因此,如果要使用阅读器的非接触式功能,则必须使用CLF的本机命令集。有关详细信息,请参阅ACR122U API documentation或libnfc实施。
答案 1 :(得分: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 library,它支持使用InDataExchange命令在对等体之间发送字节数组(例如ACS ACR122和Nokia 6131)。阅读PN532文档(p.131)时,似乎此命令也允许读取标签。 Michael,您是否碰巧知道任何处理的库使用这些低级命令,目标是读取(不同类型的)标签?