Как использовать собственный метод JCOP для возврата доступной памяти?
Ниже вы видите программу, которая написана для возврата доступной памяти EEPROM при получении любой команды APDU:
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. В чем дело?
2 ответа
Вы должны сохранить результат в существующий массив ненулевой длины:
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
,
Вы можете использовать оба целочисленных типа в качестве индекса: byte
или же short
, реальной разницы нет (конечно, для массивов не длиннее 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;