首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过javax.smartcardio读取幻影NFC标签

通过javax.smartcardio读取幻影NFC标签
EN

Stack Overflow用户
提问于 2013-10-05 16:15:48
回答 2查看 5.1K关注 0票数 1

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

首先,我尝试了NFC工具库对NFC标记的高级读写访问。我说遇到了一个不受支持的标记时出错了;尽管阅读器上没有标记,甚至在附近也没有标记。似乎其他开发人员在这个库中也遇到了同样的错误,如这里所示。注意,这个标记是无限检测的(所以,它不会在被检测到一次之后就消失了)。

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

代码语言:javascript
复制
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读取器的名称是“”,而不是"ACS ACR122“或其他相关的东西。不知道这是否重要,我只是想提一下。)

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

更新

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

代码语言:javascript
复制
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());
}

但是我一直得到一个错误响应代码(0x630x00)。对我可能做错了什么有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-05 19:51:18

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

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

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

票数 2
EN

Stack Overflow用户

发布于 2013-10-09 09:42:28

(所有的功劳都归功于迈克尔·罗兰,这篇文章的意思是作为一个解决方案摘要)

好的,Michael,给出最后一个注释中的例子,我终于理解了使用PC/SC协议来隧道CLF命令是什么意思。我测试了PN532文档中的一些命令,它们返回有效的结果。(但是,您作为示例提供的命令不起作用,导致读取器崩溃;必须重置它。)

例如,要获得固件版本:

代码语言:javascript
复制
CommandAPDU commApdu = new CommandAPDU(0xFF, 0x00, 0x00, 0x00, 
    new byte[] { (byte)0xD4, (byte)0x02 });

InDataExchange命令:

代码语言:javascript
复制
CommandAPDU commApdu = new CommandAPDU(0xFF, 0x00, 0x00, 0x00, 
    new byte[] { (byte)0xD4, (byte)0x40, 0x01 });

我找到了NFCIP库,它支持使用InDataExchange命令在对等点之间发送字节数组(例如ACS ACR122和nokia6131)。在阅读PN532文档(第131页)时,该命令似乎也允许读取标记。迈克尔,你知不知道有哪个库用读取(不同类型的)标记来处理这些低级命令。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19199875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档