我使用Java智能卡IO框架开发了一个主机应用程序。主机应用程序向卡发送读取命令,正在等待接收响应
在这个过程中,会发生超时(超时值由我定义)
我想当超时发生时,读取过程将停止。我的问题是如何做到这一点
-目前,主机应用程序使用基本通道连接到卡。我试图关闭此频道,但遇到异常java.lang.IllegalStateException: Cannot close basic logical channel
-我还试图通过调用channel = card.openLogicalChannel();
打开一个逻辑通道,但当主机发送读取命令时,它收到SW 6D00
-指令代码不支持或无效
-我还试图通过呼叫card.disconnect()
断开终端和卡的连接,但我得到了异常
javax.smartcardio.CardException: sun.security.smartcardio.PCSCException: WINDOWS_ERROR_INVALID_HANDLE
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:219)
at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:90)
at ISO.ISO7816.readRecords(ISO7816.java:234)
at javasmartcardio.UI.PTCMainFrame$9.run(PTCMainFrame.java:343)
at java.lang.Thread.run(Thread.java:745)
Caused by: sun.security.smartcardio.PCSCException: WINDOWS_ERROR_INVALID_HANDLE
at sun.security.smartcardio.PCSC.SCardTransmit(Native Method)
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:189)
我试着关闭这个频道,但没成功
java.lang.IllegalStateException: Cannot close basic logical channel
ISO/IEC 7816-4第9页:
基本通道应永久可用,即不能关闭。其通道编号为零
我还试图通过调用
channel = card.openLogicalChannel();
打开一个逻辑通道,但当主机发送读取命令时接收SW6D00 - Instruction code not support or invalid.
我想您会因为调用openLogicalChannel()
方法而收到0x9000
。如果是这样,您必须首先在逻辑通道上选择小程序,然后发送READ命令。要在要发送READ命令的新逻辑通道上选择小程序,只需在select APDU命令的CLA
部分的低半字节中指定通道编号。(即0X A4 04 00 <AID Len> <AID>
而不是00 A4 04 00 <AID Len> <AID>
-X是逻辑信道号)。
另一种方式是,在基本通道上选择小程序,并在另一个通道上为同一个小程序发送读取命令是不正确的。当您使用Manage Channel
APDU命令打开逻辑通道时,该通道上所选的小程序是卡的默认选定小程序(而不是您已经选择的小程序)。
关于这个例外,我想是与你的读者有关。
我建议你:
- 打开基本逻辑通道以外的逻辑通道
- 在该逻辑通道上选择您的小程序
- 通过该逻辑通道发送读取命令
- 超时后关闭此逻辑通道
- 跳到1