public void process(APDU apdu) { byte[] buffer = apdu.getBuffer(); if (apdu.isISOInterindustryCLA()) { if (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4)) { return; } else { ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); } } switch (buffer[ISO7816.OFFSET_INS]) { case VALIDATEKEY: validateKey(apdu); return; case TIMETICK: timeTick(apdu); return; case SETCONNECTION: setConnection(); return; case RESETCONNECTION: resetConnection(); return; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } }
// Connection management methods private void timeTick(APDU apdu) { // Updates the area code according to the passed parameter. byte[] buffer = apdu.getBuffer(); byte numBytes = (byte) (buffer[ISO7816.OFFSET_LC]); byte byteRead = (byte) (apdu.setIncomingAndReceive()); if ((numBytes != 2) || (byteRead != 2)) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // get area code short newAreaCode = (short) ((short) (buffer[ISO7816.OFFSET_CDATA] << (short) 8) | (short) (buffer[ISO7816.OFFSET_CDATA + 1] & 0x00FF)); if (newAreaCode != INACTIVE_AREA) { activeAreaCode[0] = newAreaCode; } else { resetConnection(); ISOException.throwIt(SW_NO_NETWORK); } short connectionType = apdu.getProtocol(); byte b = apdu.getCLAChannel(); boolean contactless = false; if ((connectionType & 0xf0) == 0x80 // APDU.PROTOCOL_MEDIA_CONTACTLESS_TYPE_A || (connectionType & 0xf0) == 0x90) { // APDU.PROTOCOL_MEDIA_CONTACTLESS_TYPE_B ){ contactless = true; } // If a connection is active, the user account is debited. // If user runs out of credits, the connection is terminated. if (connectionStatus[0] == CONNECTION_INUSE) { if (AccountAccessor.getAccount() == null) { ISOException.throwIt(SW_NO_ACCOUNT); } if (AccountAccessor.getAccount().debit(activeAreaCode[0], contactless) == false) { resetConnection(); ISOException.throwIt(SW_NEGATIVE_BALANCE); } } }
private void setConnection() { if (AccountAccessor.getAccount() == null) { ISOException.throwIt(SW_NO_ACCOUNT); } if (connectionStatus[0] == CONNECTION_INUSE) { ISOException.throwIt(SW_CONNECTION_BUSY); } if (activeAreaCode[0] == INACTIVE_AREA) { ISOException.throwIt(SW_NO_NETWORK); } // The first time unit is charged at connection setup if (AccountAccessor.getAccount().debit(activeAreaCode[0], false)) { connectionStatus[0] = CONNECTION_INUSE; } else { ISOException.throwIt(SW_NEGATIVE_BALANCE); } }
// Check that the key sent is valid private void validateKey(APDU apdu) { // fake key test byte[] buffer = apdu.getBuffer(); // process extended length apdu short testKey = (short) ((short) (buffer[ISO7816.OFFSET_EXT_CDATA] << (short) 8) | (short) (buffer[ISO7816.OFFSET_EXT_CDATA + 3] & 0x00FF)); if (testKey != (short) 3) ISOException.throwIt(SW_INVALID_KEY); return; // System.out.println("here here"); }