如何使用JCOP专有方法返回可用内存



下面,您可以看到一个程序,它是为在接收到任何APDU命令时返回EEPROM可用内存而编写的:

public class HelloWorld extends Applet {
    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new helloWorld.HelloWorld().register(bArray, (short) (bOffset + 1),
                bArray[bOffset]);
    }
    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }
        getAvailableMem(apdu);
    }
    public void getAvailableMem(APDU apdu){
        byte[] buffer = apdu.getBuffer();
        short[] AvailableMem = {};
        UtilX.getAvailableMemoryInfo(AvailableMem, (short) 0,
                UtilX.MEMORY_TYPE_PERSISTENT);
        for(short i=0;i<(short)AvailableMem.length;i++){
            buffer[i]=(byte)AvailableMem[i];
        }
        apdu.setOutgoingAndSend((short)0, (short)(2*AvailableMem.length));
    }
}

但当我向小程序发送APDU命令时,它会返回0x6F00:

OSC: opensc-tool -s 00a4040006010203040506 -s 00000000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 06
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 00 00
Received (SW1=0x6F, SW2=0x00)

注意,我也尝试了上面的程序和下面的循环:

for(byte i=0;i<(byte)AvailableMem.length;i++){
                buffer[i]=(byte)AvailableMem[i];
            }

它也编译成功!编译器不应该将数组索引的类型限制为仅byte还是仅short吗?为什么它接受这两种类型的索引?

-第二个程序在OpenSCTool中具有相同的输出。怎么了?

您必须将结果存储到一个非零长度的现有数组中:

class MyApplet extends Applet {
short[] shorts = JCSystem.makeTransientShortArray((short)2, JCSystem.CLEAR_ON_RESET);
public void process(APDU apdu) {
    //...
    UtilX.getAvailableMemoryInfo(shorts, (short)0, UtilX.MEMORY_TYPE_PERSISTENT);
    //...
}

您的状态代码6F00是一个未捕获的ArrayIndexOutOfBoundsException实例。

您可以使用两种整数类型作为索引:byteshort,没有真正的区别(当然,对于不超过0x7F的数组)。

从我的一个小程序中取出的示例代码:

在我的课堂开始时的声明

    short[] mem = new short[2];

从流程树内部:

case Cmd.GET_FREE_MEM:
                UtilX.getAvailableMemoryInfo(mem, (short) 0, UtilX.MEMORY_TYPE_PERSISTENT);
                Util.setShort(apdu.getBuffer(), (short) 0, mem[0]);
                Util.setShort(apdu.getBuffer(), (short) 2, mem[1]);
                UtilX.getAvailableMemoryInfo(mem, (short) 0, UtilX.MEMORY_TYPE_TRANSIENT_RESET);
                Util.setShort(apdu.getBuffer(), (short) 4, mem[0]);
                Util.setShort(apdu.getBuffer(), (short) 6, mem[1]);
                apdu.setOutgoingAndSend((short) 0, (short) 8);
                break;

最新更新