如何从SIM卡应用程序中存储SIM卡中的数据?

时间:2012-03-02 12:11:04

标签: applet javacard apdu sim-card

我正在写一张SIM卡小程序,我需要将数据存储在SIM卡上。

但我没有这样做。 我找到了一个例子并使用它,但数据在模拟器重启时总是消失。 我使用“cmdPUTDATA(apdu);”保存数据的方法,我使用“cmdGETDATA(apdu);”保存数据的方法。

这是我的代码和回复;

     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 个答案:

答案 0 :(得分:0)

模拟器重新启动时?通常,Java Card模拟器会将持久性和瞬态内存保留在RAM中。使用重置(请求ATR)而不是停止模拟器执行“卡撕裂”。

答案 1 :(得分:0)

构造函数方法和我的其他方法在这里。在“beginTransaction”和“commitTransaction”代码之间,转到EEPROM persitent数据。但它只运行经典applet(java卡api 3.0),它不运行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();
}