title: Querying Javacard Applet in Netbeans using APDUs
body: <p>I am a newbie in javacard applet development for smart cards. I got the classic applet code that almost all documents reference. However, I am failing to run or query the card (<em>running these operations</em> verify,credit,debit,getbalance) using command APDUs in netbeans. Could you kindly share the commands sniplet with a success response.</p>
  
  <pre><code>package classicapplet1;
  
  //package com.sun.javacard.samples.wallet;
  
  import javacard.framework.*;
  
  public class Wallet extends Applet {
  
  // codes of CLA byte in the command APDUs
  
  final static byte Wallet_CLA = (byte) 0xB0;
  
  // codes of INS byte in the command APDUs
  
  final static byte VERIFY = (byte) 0x20;
  
  final static byte CREDIT = (byte) 0x30;
  
  final static byte DEBIT = (byte) 0x40;
  
  final static byte GET_BALANCE = (byte) 0x50;
  
  // maximum wallet balance
  
  final static short MAX_BALANCE = 10000;
  
  // maximum transaction amount
  
  final static byte MAX_TRANSACTION_AMOUNT = 100;
  
  // maximum number of incorrect tries before the
  
  // PIN is blocked
  
  final static byte PIN_TRY_LIMIT = (byte) 0x03;
  
  // maximum size PIN
  
  final static byte MAX_PIN_SIZE = (byte) 0x08;
  
  // Applet-specific status words:
  
  final static short SW_VERIFICATION_FAILED = 0x6300;
  
  final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
  
  final static short SW_INVALID_TRANSACTION_AMOUNT = 0x6A83;
  
  final static short SW_EXCEED_MAXIMUM_BALANCE = 0x6A84;
  
  final static short SW_NEGATIVE_BALANCE = 0x6A85;
  
  // instance variables declaration
  
  OwnerPIN pin;
  
  short balance;
  
  /**
   * 
   * called by the JCRE to create an applet instance
   */
  
  public static void install(byte[] bArray, short bOffset, byte bLength) {
  
      // create a Wallet applet instance
  
      new Wallet(bArray, bOffset, bLength);
  } // end of install method
  
  /**
   * 
   * private constructor — called by the install method to
   * 
   * instantiate a Wallet instance
   */
  
  
  private Wallet(byte[] bArray, short bOffset, byte bLength) {
  
      pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
  
      // bArray contains the PIN initialization value
  
      pin.update(bArray, bOffset, bLength);
  
      // register the applet instance with the JCRE
  
      register();
  
  } // end of the constructor
  
  /**
   * 
   * initialize the applet when it is selected
   */
  
  public boolean select() {
  
      // the applet declines to be selected
  
      // if the pin is blocked
  
      if (pin.getTriesRemaining() == 0)
  
          return false;
  
      return true;
  
  } // end of select method
  
  /**
   * 
   * perform any cleanup and bookkeeping tasks before
   * 
   * the applet is deselected
   */
  
  public void deselect() {
  
      // reset the pin
  
      pin.reset();
  
  }
  
  /**
   * 
   * process APDUs
   */
  
  public void process(APDU apdu) {
  
      // APDU object carries a byte array (buffer) to
  
      // transfer incoming and outgoing APDU header
  
      // and data bytes between the card and the host
  
      // at this point, only the first five bytes
  
      // [CLA, INS, P1, P2, P3] are available in
  
      // the APDU buffer
  
      byte[] buffer = apdu.getBuffer();
  
      // return if the APDU is the applet SELECT command
  
      if (selectingApplet())
  
          return;
  
      // verify the CLA byte
  
      if (buffer[ISO7816.OFFSET_CLA] != Wallet_CLA)
  
          ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
  
      // check the INS byte to decide which service method to call
  
      switch (buffer[ISO7816.OFFSET_INS]) {
  
      case GET_BALANCE:
          getBalance(apdu);
          return;
  
      case DEBIT:
          debit(apdu);
          return;
  
      case CREDIT:
          credit(apdu);
          return;
  
      case VERIFY:
          verify(apdu);
          return;
  
      default:
          ISOException.throwIt
  
          (ISO7816.SW_INS_NOT_SUPPORTED);
  
      }
  
  } // end of process method
  
  /**
   * 
   * add money to the wallet
   */
  
  private void credit(APDU apdu) {
  
      // verify authentication
  
      if (!pin.isValidated())
  
          ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
  
      byte[] buffer = apdu.getBuffer();
  
      // get the number of bytes in the
  
      // data field of the command APDU
  
      byte numBytes = buffer[ISO7816.OFFSET_LC];
  
      // recieve data
  
      // data are read into the apdu buffer
  
      // at the offset ISO7816.OFFSET_CDATA
  
      byte byteRead = (byte) (apdu.setIncomingAndReceive());
  
      // error if the number of data bytes
  
      // read does not match the number in the Lc byte
  
      if ((numBytes != 1) || (byteRead != 1))
  
          ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  
      // get the credit amount
  
      byte creditAmount = buffer[ISO7816.OFFSET_CDATA];
  
      // check the credit amount
  
      if ((creditAmount &gt; MAX_TRANSACTION_AMOUNT) || (creditAmount &lt; 0))
  
          ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
  
      // check the new balance
  
      if ((short) (balance + creditAmount) &gt; MAX_BALANCE)
  
          ISOException.throwIt(SW_EXCEED_MAXIMUM_BALANCE);
  
      // credit the amount
  
      balance = (short) (balance + creditAmount);
  
      return;
  
  } // end of deposit method
  
  /**
   * 
   * withdraw money from the wallet
   */
  
  private void debit(APDU apdu) {
  
      // verify authentication
  
      if (!pin.isValidated())
  
          ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
  
      byte[] buffer = apdu.getBuffer();
  
      byte numBytes = (byte) (buffer[ISO7816.OFFSET_LC]);
  
      byte byteRead = (byte) (apdu.setIncomingAndReceive());
  
      if ((numBytes != 1) || (byteRead != 1))
  
          ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  
      // get debit amount
  
      byte debitAmount = buffer[ISO7816.OFFSET_CDATA];
  
      // check debit amount
  
      if ((debitAmount &gt; MAX_TRANSACTION_AMOUNT)
  
      || (debitAmount &lt; 0))
  
          ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
  
      // check the new balance
  
      if ((short) (balance - debitAmount) &lt; (short) 0)
  
          ISOException.throwIt(SW_NEGATIVE_BALANCE);
  
      balance = (short) (balance - debitAmount);
  
  } // end of debit method
  
  /**
   * 
   * the method returns the wallet’s balance
   */
  
  private void getBalance(APDU apdu) {
  
      byte[] buffer = apdu.getBuffer();
  
      // for(short i=0;i&lt;buffer.length;i++)
  
      // {
  
      // System.out.println((byte)buffer[i]);
  
      // }
  
      // System.out.println((short)0);
  
      // inform the JCRE that the applet has data to return
  
      short le = apdu.setOutgoing();
  
      // set the actual number of the outgoing data bytes
  
      apdu.setOutgoingLength((byte) 2);
  
      // write the balance into the APDU buffer at the offset 0
  
      Util.setShort(buffer, (short) 0, balance);
  
      // send the 2-byte balance at the offset
  
      // 0 in the apdu buffer
  
      apdu.sendBytes((short) 0, (short) 2);
  
  } // end of getBalance method
  
  /**
   * 
   * verify the PIN
   */
  
  private void verify(APDU apdu) {
  
      byte[] buffer = apdu.getBuffer();
  
      // receive the PIN data for validation.
  
      byte byteRead = (byte) (apdu.setIncomingAndReceive());
  
      // check pin
  
      // the PIN data is read into the APDU buffer
  
      // starting at the offset ISO7816.OFFSET_CDATA
  
      // the PIN data length = byteRead
  
      if (pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead) == false)
  
          ISOException.throwIt(SW_VERIFICATION_FAILED);
  
  } // end of verify method
  
  }
  </code></pre>