【问题标题】:How to create RFID application to read HID OMNIKEY 5427 CK如何创建 RFID 应用程序以读取 HID OMNIKEY 5427 CK
【发布时间】:2014-08-21 16:10:43
【问题描述】:

我和我的同事正在尝试创建一个 Java 程序来读取带有 HID OMNIKEY 5427 CK 的卡片。我们以前没有使用 RFID 的经验并检查过: https://support.impinj.com/hc/communities/public/questions/201883748-How-do-I-create-RFID-applications-with-Java-

对于一些示例代码(除此之外我们找不到太多示例代码),我们已经对其进行了改编和使用,但是在运行我们的代码时我们得到了

java.nio.channels.UnresolvedAddressException
at sun.nio.ch.Net.checkAddress(Unknown Source)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at org.apache.mina.transport.socket.nio.SocketConnector.connect(SocketConnector.java:187)
at org.apache.mina.transport.socket.nio.SocketConnector.connect(SocketConnector.java:137)
at org.apache.mina.common.support.BaseIoConnector.connect(BaseIoConnector.java:40)
at org.llrp.ltk.net.LLRPConnector.connect(LLRPConnector.java:135)
at org.llrp.ltk.net.LLRPConnector.connect(LLRPConnector.java:116)
at hellojavaltk.HelloJavaLtk.connect(HelloJavaLtk.java:212)
at hellojavaltk.HelloJavaLtk.run(HelloJavaLtk.java:227)
at hellojavaltk.HelloJavaLtkMain.main(HelloJavaLtkMain.java:9)​

代码基本上是:

public class HelloJavaLtkMain
{
public static void main(String[] args) throws InterruptedException
{
HelloJavaLtk app = new HelloJavaLtk();

System.out.println("Starting reader.");
app.run("HID-OMNIKEY-5427-CK");
Thread.sleep(30000);
System.out.println("Stopping reader.");
app.stop();
System.out.println("Exiting application.");
System.exit(0);
}
}

HelloJavaLtk 是一个实现 LLRPEndpoint 接口的类,基本上是从上面的链接复制粘贴。

所以我们不知道我们是否只是没有通过该运行正确寻址设备(“HID-OMNIKEY-5427-CK”),或者在尝试到达该端点时我们是否应该做一些完全不同的事情。

如果有人能够将 OMNIKEY-5427-CK(或其他读卡器)与 Java 代码一起使用,我们将不胜感激,可以向我们指出其他代码示例或让我们进一步了解我们做错了什么。

谢谢大家。

【问题讨论】:

    标签: java rfid smartcard-reader


    【解决方案1】:

    HID OMNIKEY 5427 CK 是一款符合 PC/SC (CCID) 标准的智能卡读卡器。您尝试使用的库适用于 EPC RFID 阅读器。但是,此 Omnikey 阅读器可通过 PC/SC 访问。当前的 Oracle Java 已内置支持使用 Java SmartcardIO API 访问 PC/SC 智能卡读卡器。

    【讨论】:

    • 谢谢。 javax.smartcardio.* 工作!我们成功连接到 RFID 阅读器并发送返回标签 UID 的 APDU 命令。
    • @Diego Alonso 你能添加更多关于你的解决方案的信息吗?我正在尝试发送transmitAPDU(new CommandAPDU(new byte[]{(byte)0x80, (byte)0xA6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00}));,但接收sun.security.smartcardio.PCSCException: Unknown error 0x1f
    • @Diego:您介意分享您的解决方案吗?我在为omnikey 5427CK 找到正确的APDU 时遇到问题。
    • Skumar,我已经有很长时间没有参与其中了。我相信源代码是共享的here。我不记得是 DDSsmartcardio 还是 SampleLoginWindow。这是某种实验,编码它的人是生物医学工程师。我希望它对您有所帮助,但我不能保证您会在那里找到解决问题的方法。祝你好运。
    【解决方案2】:

    我认为您使用的代码不兼容,因为它看起来适用于 LLRP 协议,并且您的设备支持 CCID 和键盘楔。

    CCID:

    我找不到您设备的文档,但是看起来 CCID 可能使用串行连接工作,如果是这种情况,您可以使用 RXTX 连接到设备 (http://mfizz.com/oss/rxtx-for-java),然后发送命令和阅读它的响应。

    这是一个小例子:

    // change to right port
    CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier("/dev/ttyS0"); 
        if (portIdentifier.isCurrentlyOwned()) {
            throw new RfidReaderUnavailableException();
        } else {
            CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000);
            if (commPort instanceof SerialPort) {
                SerialPort serialPort = (SerialPort) commPort;
                // This details have to match your device configuration or it won't work
                serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
    
                in = serialPort.getInputStream();
                out = serialPort.getOutputStream();
    
                <-- Here you write the commands on out and read the responses from in -->
    
            } else {
                System.out.println("Error: Only serial ports are handled by this.");
            }
       }
    

    如果 CCID 不支持串行通信,他们必须为其提供驱动程序。如果驱动程序不兼容 Java,那么您需要编写一个 JNI 包装器才能在您的 Java 代码中使用它。

    键盘楔子:

    这种模式下的功能可能会被简化为像键盘一样写入卡 ID,就像条形码扫描仪一样。您将无法从键盘输入和读卡器中分辨出来,您也无法从卡内存中读取或写入数据,但它可能对您有用,具体取决于您的应用必须实现的目标。

    【讨论】:

    • 谢谢,虽然我们的读者似乎没有通过串行通信的能力。
    【解决方案3】:

    我知道这是一个非常古老的问题,因为我没有在任何地方找到使用命令的工作示例,使用下面的代码,您可以获得卡的 ATR 和 UID。

    TerminalFactory factory = TerminalFactory.getDefault(); 
    List<CardTerminal> terminals = factory.terminals().list();
    System.out.println("Terminals: " + terminals);
    // get the first terminal
    CardTerminal terminal = terminals.get(0);
    
    // establish a connection with the card
    Card card = terminal.connect("*");
    System.out.println("card: " + card);
    ATR atr = card.getATR();
    System.out.println("Card ATR: " + DatatypeConverter.printHexBinary(atr.getBytes()));
    CardChannel channel = card.getBasicChannel();
    CommandAPDU commandAPDU;
    commandAPDU = new CommandAPDU(new byte[]{(byte) 0xFF,(byte) 0xCA,(byte) 0x00,(byte) 0x00,(byte) 0x00});             
    ResponseAPDU r = channel.transmit(commandAPDU);
    System.out.println("Response: " + r.toString() + ", NR: " + r.getNr());
    String hex = DatatypeConverter.printHexBinary(r.getBytes());
    System.out.println("Response: " + hex);
    System.out.println("Card UID: " + DatatypeConverter.printHexBinary(r.getData()));
    byte[] copyOf = Arrays.copyOf(r.getBytes(), r.getNr());
    System.out.println("Card UID from bytes: " + DatatypeConverter.printHexBinary(copyOf));
    // disconnect
    card.disconnect(false);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      相关资源
      最近更新 更多