i am writing a sim card applet and i need to store data on sim card.
but i didnt do it. i found an example and use it but data disappear always when simulator restart. i use "cmdPUTDATA(apdu);" method for save data and i use "cmdGETDATA(apdu);" method for save data.
here is my code and response;
public void process(APDU apdu) {
byte[] buffer = apdu.getBuffer();
if (apdu.isISOInterindustryCLA()) {
if (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4)) {
return;
}
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch (buffer[ISO7816.OFFSET_INS]) {
case INS_GET_BALANCE:
getBalance(apdu);
return;
case INS_CREDIT:
credit(apdu);
return;
case INS_CHARGE:
charge(apdu);
return;
// case INS_SELECT: // it is a SELECT FILE instruction
// cmdSELECT(apdu);
// break;
// case INS_VERIFY: // it is a VERIFY instruction
// cmdVERIFY(apdu);
// break;
// case INS_PUTDATA: // it is a PUT DATA instruction
// cmdPUTDATA(apdu);
// break;
// case INS_GETDATA: // it is a GET DATA instruction
// cmdGETDATA(apdu);
// break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
// @TransactionType(REQUIRED)
//synchronized
private void credit(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte numBytes = buffer[ISO7816.OFFSET_LC];
byte byteRead = (byte) (apdu.setIncomingAndReceive());
if ((numBytes != 2) || (byteRead != 2)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
short creditAmount = (short) ((short) (buffer[ISO7816.OFFSET_CDATA] << (short) 8) | (buffer[ISO7816.OFFSET_CDATA + 1]));
if ((creditAmount > MAX_BALANCE) || (creditAmount < (short) 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
if ((short) (balance + creditAmount) > MAX_BALANCE) {
ISOException.throwIt(SW_MAX_BALANCE_EXCEEDED);
}
JCSystem.beginTransaction();
balance = (short) (balance + creditAmount);
JCSystem.commitTransaction();
}
private void getBalance(APDU apdu) {
byte[] buffer = apdu.getBuffer();
buffer[0] = (byte) (balance >> (short) 8);
buffer[1] = (byte) (balance & (short) 0x00FF);
//apdu.setOutgoingLength((byte) 2);
//apdu.sendBytes((short) 0, (short) 2);
apdu.setOutgoingAndSend((short)0, (short)2);
}
private void charge(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte numBytes = buffer[ISO7816.OFFSET_LC];
byte byteRead = (byte) (apdu.setIncomingAndReceive());
if ((numBytes != 2) || (byteRead != 2)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
short chargeAmount = (short) ((short) (buffer[ISO7816.OFFSET_CDATA] << (short) 8) | (buffer[ISO7816.OFFSET_CDATA + 1]));
if ((chargeAmount > MAX_BALANCE) || (chargeAmount < (short) 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
if ((short) (balance - chargeAmount) < 0) {
ISOException.throwIt(SW_MIN_BALANCE_EXCEEDED);
}
JCSystem.beginTransaction();
balance = (short) (balance - chargeAmount);
JCSystem.commitTransaction();
}
constructor method and my other method is here. between the "beginTransaction" and "commitTransaction" code, goto EEPROM persitent data. But it run only classic applet(java card api 3.0), it doesnt run Extendet Applet.
private Akbil_Classic(byte[] bArray, short bOffset, byte bLength) {
memory = new byte[SIZE_MEMORY];
}
private void charge(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte numBytes = buffer[ISO7816.OFFSET_LC];
byte byteRead = (byte) (apdu.setIncomingAndReceive());
if ((numBytes != 2) || (byteRead != 2)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
short chargeAmount = (short) ((short) (buffer[ISO7816.OFFSET_CDATA] << (short) 8) | (buffer[ISO7816.OFFSET_CDATA + 1]));
if ((chargeAmount > MAX_BALANCE) || (chargeAmount < (short) 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
if ((short) (balance + chargeAmount) > MAX_BALANCE) {
ISOException.throwIt(SW_MAX_BALANCE_EXCEEDED);
}
JCSystem.beginTransaction();
balance = (short) (balance - chargeAmount);
JCSystem.commitTransaction();
}