如何使用smartcardio和Java控制ACR122上的LED?
How to Control LED on ACR122 using smartcardio and Java?
我正在尝试使用 Java 中的 smartcardio 库(JDK 8、NetBeans 7.4、Windows 10)。我尝试了许多其他库但没有成功。
卡reader (ACS ACR122U) 附带了一张SDK CDROM,但必要的.DLL 不在CD 上,所以我无法使用ACS 库。
由于我的 NFC 设备使用了 nfctools 库不支持的 EEPROM,因此我无法使用 nfctools。
我的代码如下:
package myPackage;
import java.util.List;
import javax.smartcardio.*;
public class Blog {
public static void main(String[] args) {
try {
// Display the list of terminals
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
// Use the first terminal
CardTerminal terminal = terminals.get(0);
// Connect with the card
Card card = terminal.connect("*");
System.out.println("card: " + card);
CardChannel channel = card.getBasicChannel();
// Send Red and Green LED ON command
byte[] cmd1 = {(byte)0xFF, // Pseudo-APDU class
0x00, // INS
0x00, // P1
0x00, // P2
9, // Lc - number of bytes in Payload
(byte)0xFF, // First byte of payload - LED/Buzzer cntrl
0x00, // INS
0x40, // P1
0x0F, // P2 - LED state control
0x04, // Lc
0x00, // 4 byte blink duration control
0x00,
0x00,
0x00 };
CommandAPDU apdu1 = new CommandAPDU( cmd1, // Byte array to use
0, // index to start of msg
14 );// msg length
System.out.println( "apdu1: " + apdu1.toString() );
ResponseAPDU answer1 = channel.transmit( apdu1 );
System.out.println("answer1: " + answer1.toString());
// Get Firmware Version of the reader
byte[] cmd2 = {(byte)0xFF, 0x00, 0x00, 0x00, 5, (byte)0xFF, 0x00, 0x48, 0x00, 0x00 };
CommandAPDU apdu2 = new CommandAPDU( cmd2, 0, 10 );
System.out.println( "apdu2: " + apdu2.toString() );
ResponseAPDU answer2 = channel.transmit( apdu2 );
System.out.println("answer2: " + answer2.toString());
System.out.println();
// Disconnect the card
card.disconnect(false);
} catch(CardException e)
{
System.out.println("Problem: " + e.toString());
}
}
}
失败并出现关于 "apdu must be a least 2 bytes long" 的错误。
run:
Terminals: [PC/SC terminal ACS ACR122 0]
card: PC/SC card in ACS ACR122 0, protocol T=1, state OK
apdu1: CommmandAPDU: 14 bytes, nc=9, ne=0
Exception in thread "main" java.lang.IllegalArgumentException: apdu must be at least 2 bytes long
at javax.smartcardio.ResponseAPDU.check(ResponseAPDU.java:73)
at javax.smartcardio.ResponseAPDU.<init>(ResponseAPDU.java:67)
at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:91)
at myPackage.Blog.main(Blog.java:43)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
对象 apdu1 的长度为 14 个字节,因此我不确定错误消息的含义。
第 43 行是 ResponseAPDU answer1 = channel.transmit( apdu1 );
如注释0xff class of APDU command is not valid for card, this is used to get reader 解释APDU而不是发送给卡
不一样reader但是这张图清楚了
所以不要试图通过复制 INS、P1、P2 和 Lc 字段将一个 APDU 包装在另一个 APDU 中
// Send Red and Green LED ON command
byte[] cmd1 = {(byte)0xFF, // First byte of payload - LED/Buzzer cntrl
0x00, // INS
0x40, // P1
0x0F, // P2 - LED state control
0x04, // Lc
0x00, // 4 byte blink duration control
0x00,
0x00,
0x00 };
CommandAPDU apdu1 = new CommandAPDU( cmd1, // Byte array to use
0, // index to start of msg
9 );// msg length
我正在尝试使用 Java 中的 smartcardio 库(JDK 8、NetBeans 7.4、Windows 10)。我尝试了许多其他库但没有成功。
卡reader (ACS ACR122U) 附带了一张SDK CDROM,但必要的.DLL 不在CD 上,所以我无法使用ACS 库。
由于我的 NFC 设备使用了 nfctools 库不支持的 EEPROM,因此我无法使用 nfctools。
我的代码如下:
package myPackage;
import java.util.List;
import javax.smartcardio.*;
public class Blog {
public static void main(String[] args) {
try {
// Display the list of terminals
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
// Use the first terminal
CardTerminal terminal = terminals.get(0);
// Connect with the card
Card card = terminal.connect("*");
System.out.println("card: " + card);
CardChannel channel = card.getBasicChannel();
// Send Red and Green LED ON command
byte[] cmd1 = {(byte)0xFF, // Pseudo-APDU class
0x00, // INS
0x00, // P1
0x00, // P2
9, // Lc - number of bytes in Payload
(byte)0xFF, // First byte of payload - LED/Buzzer cntrl
0x00, // INS
0x40, // P1
0x0F, // P2 - LED state control
0x04, // Lc
0x00, // 4 byte blink duration control
0x00,
0x00,
0x00 };
CommandAPDU apdu1 = new CommandAPDU( cmd1, // Byte array to use
0, // index to start of msg
14 );// msg length
System.out.println( "apdu1: " + apdu1.toString() );
ResponseAPDU answer1 = channel.transmit( apdu1 );
System.out.println("answer1: " + answer1.toString());
// Get Firmware Version of the reader
byte[] cmd2 = {(byte)0xFF, 0x00, 0x00, 0x00, 5, (byte)0xFF, 0x00, 0x48, 0x00, 0x00 };
CommandAPDU apdu2 = new CommandAPDU( cmd2, 0, 10 );
System.out.println( "apdu2: " + apdu2.toString() );
ResponseAPDU answer2 = channel.transmit( apdu2 );
System.out.println("answer2: " + answer2.toString());
System.out.println();
// Disconnect the card
card.disconnect(false);
} catch(CardException e)
{
System.out.println("Problem: " + e.toString());
}
}
}
失败并出现关于 "apdu must be a least 2 bytes long" 的错误。
run:
Terminals: [PC/SC terminal ACS ACR122 0]
card: PC/SC card in ACS ACR122 0, protocol T=1, state OK
apdu1: CommmandAPDU: 14 bytes, nc=9, ne=0
Exception in thread "main" java.lang.IllegalArgumentException: apdu must be at least 2 bytes long
at javax.smartcardio.ResponseAPDU.check(ResponseAPDU.java:73)
at javax.smartcardio.ResponseAPDU.<init>(ResponseAPDU.java:67)
at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:91)
at myPackage.Blog.main(Blog.java:43)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
对象 apdu1 的长度为 14 个字节,因此我不确定错误消息的含义。
第 43 行是 ResponseAPDU answer1 = channel.transmit( apdu1 );
如注释0xff class of APDU command is not valid for card, this is used to get reader 解释APDU而不是发送给卡
不一样reader但是这张图清楚了
所以不要试图通过复制 INS、P1、P2 和 Lc 字段将一个 APDU 包装在另一个 APDU 中
// Send Red and Green LED ON command
byte[] cmd1 = {(byte)0xFF, // First byte of payload - LED/Buzzer cntrl
0x00, // INS
0x40, // P1
0x0F, // P2 - LED state control
0x04, // Lc
0x00, // 4 byte blink duration control
0x00,
0x00,
0x00 };
CommandAPDU apdu1 = new CommandAPDU( cmd1, // Byte array to use
0, // index to start of msg
9 );// msg length