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();
    }

enter image description here

有帮助吗?

解决方案 2

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();
}

其他提示

When the simulator restarts? Normally Java Card simulators keep both persistent and transient memory in RAM. Use reset (requesting ATR) instead of stopping the simulator to perform a "card tear".

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top