2012-03-02 2 views
1

나는 sim 카드 애플릿을 쓰고 있는데 나는 sim 카드에 데이터를 저장할 필요가있다.어떻게 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

+0

당신의 디자인은 잘못된 것입니다, 당신은 당신이 당신의 방법에있는 것처럼 그렇지 않으면 보인다, (예를 들어,'pin','memory' 필드) 기본적으로 필드 무엇인지에 대한'static' 키워드를 사용할 수 없습니다. –

+0

나는 그것을 http://www.wrankl.de에서 인용했고 내 생각에는 사실이라고 생각했다. –

+0

잘 듣고 싶지 않으면 좋습니다. 기본 클래스 디자인이기 때문에 자바에 대한 경험이있는 모든 사람들이 제가 여기 있는지 확인할 것이며, 리팩터링하면 완벽하게 작동합니다. –

답변

0

생성자 방법과 나의 다른 방법은 여기에 있습니다. "beginTransaction"코드와 "commitTransaction"코드 사이에서 EEPROM의 데이터를 고수하십시오. 하지만 그것은 오직 고전적인 애플릿 (자바 카드 API 3.0)을 실행, 그것은 Extendet 애플릿을 실행하지 않습니다.

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

OK, 거래를 추가했으나 질문과 관련하여 * 아무것도 * 없습니다. –

0

시뮬레이터 다시 시작? 일반적으로 Java Card 시뮬레이터는 지속적 메모리와 일시적인 메모리를 모두 RAM에 유지합니다. "카드 찢김"을 수행하기 위해 시뮬레이터를 중지하는 대신 재설정 (ATR 요청)을 사용하십시오.

+0

그리고 내가 소스 코드를 읽는 중이었습니다 :) –

+0

예, 프로그램을 다시 실행하면 프로그램이 항상 다시 설치됩니다. 그래서 지속적인 데이터가 사라졌습니다. –

+0

그렇다면 답은 정확하고 내 문제는 무엇입니까? 시뮬레이터를 다시 시작한 후에 데이터를 보는 데 문제가있었습니다. 답안의 코드가 어떻게 이것을 수정합니까? –

관련 문제