package de.spline.uves.ndef;
import javacard.framework.*;
/** Implementation of NDEF (Nfc Data Exchange Format) as JavaCard applet. This Applets allows to send
* static data (set at compile time) to an NDEF enabled reader (eg. Android Smartphones). An example
* application is the transmissions of links over NFC.
*
* @author Yves Müller
* @version 0.0.1
*
* This code is released in 2014 under the WTFPL (Version 2)
*/
public class Ndef extends Applet {
// constants for instructions
static final byte INS_READ_BINARY = (byte) 0xB0;
// mutable state of applet
private State state;
protected Request handlers[] = {new SelectRequest()};
protected Ndef() {
register();
}
/**
* Installs this applet.
*
* @param bArray the array containing installation parameters
* @param bOffset the starting offset in bArray
* @param bLength the length in bytes of the parameter data in bArray
*/
public static void install(byte[] bArray, short bOffset, byte bLength) {
new Ndef();
}
// TODO: add javadoc
/* protected short processReadBinary(byte[] buffer) {
if (state == EF_SELECTED && ef == 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
return sendCapabilityContainer(buffer, offset, 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 0;
}*/
/**
* Process incoming APDU messages from the reader.
*
* @see APDU
* @param apdu the incoming APDU
* @exception ISOException with the response bytes per ISO 7816-4
*/
public void process(APDU apdu) {
short recivedNow = apdu.setIncomingAndReceive();
byte buffer[] = apdu.getBuffer();
short responseLength = 0;
Request handler = null;
for (byte i = 0; i < handlers.length; i++) {
if (handlers[i].isApplicable(apdu, state)) {
handler = handlers[i];
}
}
if (handler == null) {
state.application = State.IDLE;
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
} else {
state = handler.process(apdu, state);
}
}
// validate class
/* if (buffer[ISO7816.OFFSET_CLA] != ISO7816.CLA_ISO7816) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
if (handler[0].isApplicable(apdu)) {
processSelect(buffer);
apdu.setOutgoing();
apdu.setOutgoingLength(responseLength);
} else {
// dispatch by instruction
switch (buffer[ISO7816.OFFSET_INS]) {
case ISO7816.INS_SELECT:
processSelect(buffer);
apdu.setOutgoing();
apdu.setOutgoingLength(responseLength);
break;
case INS_READ_BINARY:
responseLength = processReadBinary(buffer);
apdu.setOutgoing();
apdu.setOutgoingLength(responseLength);
break;
case (byte)0x90:
apdu.setOutgoing();
apdu.setOutgoingLength((short)3);
buffer[0] = state;
buffer[1] = (byte)(ef >> 8);
buffer[2] = (byte)(ef);
apdu.sendBytes((short)0, (short)3);
break;
default: // unkown instruction
state = IDLE;
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}*/
}