如何使用 smartcardio 和 Java 控制 ACR122 上的 LED?
Posted
技术标签:
【中文标题】如何使用 smartcardio 和 Java 控制 ACR122 上的 LED?【英文标题】:How to Control LED on ACR122 using smartcardio and Java? 【发布时间】:2020-04-23 19:44:08 【问题描述】:我正在尝试使用 Java 中的 smartcardio 库(JDK 8、NetBeans 7.4、Windows 10)。我尝试了许多其他库,但都没有成功。
读卡器 (ACS ACR122U) 附带一个 SDK CDROM,但 CD 上没有必要的 .DLL,因此我无法使用 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 at 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 );
【问题讨论】:
您似乎复制了命令中的 INS、P1、P2 和 Lc 字段,删除第一组这些值 我以为第一部分是Pseudo-APDU的一部分,第二部分是指令到读卡器中的控制器芯片的部分。我是从 ACR122U NFC 阅读器 API 文档的阅读器第 6.1 节得到的。 我已经阅读了相同的文档,还检查了***.com/questions/38676069/acr122u-led-controlling 0xff 不是有效的普通类代码,这表示伪 APDU 【参考方案1】:由于 APDU 命令的 cmets 0xff 类对卡无效,这用于让读卡器解释 APDU 而不是将其发送到卡。
不是同一个读者,但这张图很清楚
所以不要尝试通过复制 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
【讨论】:
以上是关于如何使用 smartcardio 和 Java 控制 ACR122 上的 LED?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 RFID 读卡器 (javax.smartcardio) 识别德国身份证?
带有 Java 9 和 ClassPath 的 javax.smartcardio
javax.smartcardio:如何将本机命令发送到 Desfire 卡?
在 Android 上使用 javax.smartcardio 包?