我的同事和我正在尝试创建一个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代码一起使用,我们将不胜感激,可以向我们指出其他代码示例,或者让我们进一步了解我们做错了什么。
谢谢大家。
答案 0 :(得分:3)
HID OMNIKEY 5427 CK是符合PC / SC(CCID)标准的智能卡读卡器。您尝试使用的库适用于EPC RFID阅读器。但是,该Omnikey读卡器可通过PC / SC访问。当前的Oracle Java支持使用Java SmartcardIO API访问PC / SC智能卡读卡器。
答案 1 :(得分:1)
我认为您使用的代码不兼容,因为它看起来使用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写成键盘,就像条形码扫描仪一样。您将无法通过键盘输入和读卡器进行分析,也无法从卡内存中读取或写入数据,但根据应用程序的实现情况,它可能对您有用。
答案 2 :(得分:1)
我知道这是一个非常老的问题,因为我在任何地方都没有找到可用的示例命令,因此,使用以下代码可以获得卡的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);