繁体   English   中英

如何使用 smartcardio 和 Java 控制 ACR122 上的 LED?

[英]How to Control LED on ACR122 using smartcardio and Java?

我正在尝试使用 Java(JDK 8、NetBeans 7.4、Windows 10)中的 smartcardio 库。 我尝试了许多其他库,但都没有成功。

读卡器(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 必须至少有 2 个字节长”的错误。

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)

object apdu1 的长度为 14 个字节,所以我不确定错误消息的含义。

第 43 行是ResponseAPDU answer1 = channel.transmit( apdu1 );

如评论 0xff class 的 APDU 命令对卡无效,这用于让读卡器解释 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM