APDU 在方法上抛出 6F00
APDU throwing 6F00 on a method
我正在尝试从传入的智能卡 APDU 和 return 相同的传入消息中读取数据,同时还将 ASCII 字 "respond " 附加到消息的前面。我正在获得 6F00
状态。我应该如何修复代码?
我的代码:
private void repeat(APDU apdu) {
byte[] buffer = apdu.getBuffer();
apdu.setIncomingAndReceive();
byte[] incomingMsg = getData(buffer);
if ((short) incomingMsg.length != (short) 0) {
apdu.setOutgoing();
// Send back the "respond " + "<incoming message" back
byte[] respMsg = {0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20};
byte[] outgoingMsg = new byte[(short) (incomingMsg.length + respMsg.length)];
ArrayLogic.arrayCopyRepack(respMsg, (short) 0, (short) respMsg.length, outgoingMsg, (short) 0);
ArrayLogic.arrayCopyRepack(incomingMsg, (short) 0, (short) incomingMsg.length, outgoingMsg, (short) respMsg.length);
buffer = outgoingMsg;
apdu.setOutgoingAndSend((short) 0, (short) outgoingMsg.length);
}
}
private byte[] getData(byte[] buffer) {
short msgLen = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
short readPos = 5;
short msgPos = 0;
byte[] msg = new byte[msgLen];
while (msgPos < msgLen) {
msg[msgPos] = buffer[readPos];
readPos++;
msgPos++;
}
return msg;
}
通常,状态词 6F00
表示您的代码抛出未处理的异常。在您的情况下,这可能是同时使用 apdu.setOutgoing()
和 apdu.setOutgoingAndSend()
引起的。您只能切换到出站数据方向一次。因此,apdu.setOutgoing()
和 apdu.setOutgoingAndSend()
的使用是互斥的。事实上,您可能只使用 apdu.setOutgoing*()
方法中的一种。
如果您想使用 apdu.setOutgoing()
,您稍后可以使用 apdu.sendBytes()
或 apdu.sendBytesLong()
发送数据。
您的代码中的其他问题
您的程序中还有其他一些严重的编码问题。
请注意,Java 卡片智能卡不会执行自动垃圾收集。因此,在每次调用您的处理代码时分配新的字节数组(并删除对它们的引用)通常会导致内存泄漏(即您用完了卡的所有内存,因为即使您不再参考它们)。
代码
buffer = outgoingMsg;
apdu.setOutgoingAndSend((short) 0, (short) outgoingMsg.length);
不会像您期望的那样。 setOutgoingAndSend()
(就像 (sendBytes()
) 将从全局 APDU 缓冲区发送字节(即从通过 apdu.getBuffer()
引用的字节数组)。只需将本地 buffer
变量设置为引用另一个字节数组(outgoingMsg
)不会改变全局 APDU 缓冲区。相反,您需要将传出数据复制到 APDU 缓冲区(参见 Util.arrayCopy*()
)。或者,您可以使用 apdu.sendBytesLong()
来指定包含要发送的数据的字节数组。
我正在尝试从传入的智能卡 APDU 和 return 相同的传入消息中读取数据,同时还将 ASCII 字 "respond " 附加到消息的前面。我正在获得 6F00
状态。我应该如何修复代码?
我的代码:
private void repeat(APDU apdu) {
byte[] buffer = apdu.getBuffer();
apdu.setIncomingAndReceive();
byte[] incomingMsg = getData(buffer);
if ((short) incomingMsg.length != (short) 0) {
apdu.setOutgoing();
// Send back the "respond " + "<incoming message" back
byte[] respMsg = {0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20};
byte[] outgoingMsg = new byte[(short) (incomingMsg.length + respMsg.length)];
ArrayLogic.arrayCopyRepack(respMsg, (short) 0, (short) respMsg.length, outgoingMsg, (short) 0);
ArrayLogic.arrayCopyRepack(incomingMsg, (short) 0, (short) incomingMsg.length, outgoingMsg, (short) respMsg.length);
buffer = outgoingMsg;
apdu.setOutgoingAndSend((short) 0, (short) outgoingMsg.length);
}
}
private byte[] getData(byte[] buffer) {
short msgLen = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
short readPos = 5;
short msgPos = 0;
byte[] msg = new byte[msgLen];
while (msgPos < msgLen) {
msg[msgPos] = buffer[readPos];
readPos++;
msgPos++;
}
return msg;
}
通常,状态词 6F00
表示您的代码抛出未处理的异常。在您的情况下,这可能是同时使用 apdu.setOutgoing()
和 apdu.setOutgoingAndSend()
引起的。您只能切换到出站数据方向一次。因此,apdu.setOutgoing()
和 apdu.setOutgoingAndSend()
的使用是互斥的。事实上,您可能只使用 apdu.setOutgoing*()
方法中的一种。
如果您想使用 apdu.setOutgoing()
,您稍后可以使用 apdu.sendBytes()
或 apdu.sendBytesLong()
发送数据。
您的代码中的其他问题
您的程序中还有其他一些严重的编码问题。
请注意,Java 卡片智能卡不会执行自动垃圾收集。因此,在每次调用您的处理代码时分配新的字节数组(并删除对它们的引用)通常会导致内存泄漏(即您用完了卡的所有内存,因为即使您不再参考它们)。
代码
buffer = outgoingMsg; apdu.setOutgoingAndSend((short) 0, (short) outgoingMsg.length);
不会像您期望的那样。
setOutgoingAndSend()
(就像 (sendBytes()
) 将从全局 APDU 缓冲区发送字节(即从通过apdu.getBuffer()
引用的字节数组)。只需将本地buffer
变量设置为引用另一个字节数组(outgoingMsg
)不会改变全局 APDU 缓冲区。相反,您需要将传出数据复制到 APDU 缓冲区(参见Util.arrayCopy*()
)。或者,您可以使用apdu.sendBytesLong()
来指定包含要发送的数据的字节数组。