2013-10-05 151 views
1

我有一個用於tikitag web服務的舊NFC讀取器(後來更名爲touchatag,最後在2012年左右放棄)。由於該網站不再可用,我再也找不到原始的tikitag/touchatag驅動程序。經過一番搜索後,我發現這款NFC讀卡器是一個通用的ACS ACR122U USB讀卡器,並安裝了一個合適的驅動程序here。我的系統是Windows 7(64位)。通過javax.smartcardio讀取幻像NFC標籤

首先,我試着對NFC Tools library進行NFC標籤的高級讀寫訪問。我收到錯誤消息,說遇到了不受支持的標籤;儘管閱讀器上甚至遠程附近都沒有標籤。看起來其他開發者也遇到了與這個庫相同的錯誤,如here所示。注意這個標籤是無限檢測到的(所以它不會在檢測到一次後消失)。

我將所需的低級代碼複製到單獨的類中(即,獨立於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智能卡讀卡器(WUDF)」),這會導致與上述相同的錯誤。我沒有嘗試過另一位讀者,因爲我只有一個。 (注意:Windows設備概述中此NFC讀卡器的名稱是「CCID USB Reader」,而不是「ACS ACR122」或其他相關內容。不知道這是否重要,只是認爲我會提及它)。

有沒有人遇到過這個問題,並設法解決它?

UPDATE

好吧,我試圖發送一個命令CLF對已檢測到的模擬標記之後的閱讀器;即,(11 p中ACR122U manual的。)如果獲取所連接的PICC的ATS:

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)來。關於我可能做錯什麼的想法?

回答

1

您遇到的問題是此版本的ACR122U閱讀器以某種非標準方式使用PC/SC(CCID)。

您使用PC/SC API檢測到的「卡」實際上是讀卡器模擬的虛擬卡(即使沒有卡存在,也允許PC/SC API打開連接)或智能卡芯片在閱讀器的SAM插槽中(接觸卡存在於閱讀器的外殼內)。

無論在哪種情況下,本閱讀器都只使用PC/SC作爲本閱讀器內使用的非接觸式前端芯片(恩智浦PN532)的本機命令的傳輸協議。因此,如果你想使用閱讀器的非接觸式功能,你必須使用CLF的本地命令集。有關更多詳細信息,請參閱ACR122U API documentationlibnfc實施。

+0

聽起來像是非常不標準的使用API​​。令人驚訝的是,這個問題在大約4個小時內得到解答,相比之下 - 從來沒有:) –

+0

感謝您的迅速回復。你是否說Java智能卡API不支持這個特定的NFC閱讀器?奇怪的是,因爲這似乎是一種比較流行的NFC閱讀器。所以,通過將這些(CLF?)命令從ACS文檔發送到NFC閱讀器,我將能夠訪問其功能?無論如何,我假設這些命令不能通過Java發送,因爲這需要打開一個CardChannel到一個檢測到的卡(並且只有模擬或嵌入的卡被檢測到)。 –

+0

不,我不是這麼說的。 Java智能卡IO API支持任何公開PC/SC接口的閱讀器。由於ACR122U是CCID設備,因此可通過PC/SC進行訪問。 –

1

(全部歸功於邁克爾·羅蘭,這個職位是指作爲一個解決方案概要)

好邁克爾,給你最後的評論的例子,我終於明白你使用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文檔時(第131頁),看起來這個命令也允許讀取標籤。邁克爾,你碰巧知道任何圖書館處理使用這些低級命令的目標是閱讀(不同類型)的標籤

+0

呵呵,我提供的命令有一個永久等待(0xFF),所以它只會在閱讀器檢測到卡時返回。 –

+0

邁克爾,根據你最近的評論來看,你似乎有代碼可以使用這個閱讀器讀寫各種類型的標籤;)你是否在意分享你的一些知識? :) –