package de.spline.uves.ndef; import javacard.framework.*; public class ReadBinaryRequest extends Request { static byte insbyte = Ndef.INS_READ_BINARY; // constant container static final byte[] capabilityContainer = {(byte) 0x00, (byte) 0x0F, // size of cc (byte) 0x20, // mapping version 2.0 (byte) 0xFF, (byte) 0xFF, // maximum le (TODO: get from manual) (byte) 0x00, (byte) 0xFF, // maximum lc (TODO: get from manual) (byte) 0x04, (byte) 0x06, // extended ndef file (TLV header) (byte) 0x00, (byte) 0x01, // file identifier (byte) 0xFF, (byte) 0xFF, // maximum file length (byte) 0x00, // read access condition [any] (byte) 0xFF // write access condition [none] }; public boolean isApplicable(APDU apdu, State state) { byte buffer[] = apdu.getBuffer(); if (super.isApplicable(apdu, state)) { if (state.application == State.EF_SELECTED) { return true; } } return false; } public State process(APDU apdu, State state) { byte buffer[] = apdu.getBuffer(); if (state.ef == ContainerSelectRequest.CAPABILITY_CONTAINER_EF) { short offset = (short) (buffer[ISO7816.OFFSET_P1] << 8 + buffer[ISO7816.OFFSET_P2]); byte offset_byte3; short le = 0; if (0x0000 <= offset && offset <= 0x7FFF) { // short offset le = buffer[ISO7816.OFFSET_CDATA]; // Todo: proper le decoding apdu.setOutgoing(); apdu.setOutgoingLength(le); sendCapabilityContainer(buffer, offset, le); apdu.sendBytes((short) 0, le); } else if (offset == 0x0000 && // long offsets buffer[ISO7816.OFFSET_CDATA] == 5 && buffer[ISO7816.OFFSET_CDATA + 1] == 0x54 && buffer[ISO7816.OFFSET_CDATA + 2] == 0x03) { offset = (short) (buffer[ISO7816.OFFSET_CDATA + 1] << 8 | buffer[ISO7816.OFFSET_CDATA + 2]); offset_byte3 = buffer[ISO7816.OFFSET_CDATA + 3]; le = buffer[ISO7816.OFFSET_CDATA + 5]; // Todo: proper le decoding // feature not supported yet ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } else { // invalid encoded offset ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } } else { ISOException.throwIt(ISO7816.SW_FILE_INVALID); } return state; } protected short sendCapabilityContainer(byte[] buffer, short offset, short length) { return Util.arrayCopyNonAtomic(capabilityContainer, offset, buffer, (short) 0, length); } }