ICC.java
//---------------------------------------------------------------------------------------
// Useful tools for high level commands to the smart card
// file:    ICC.java
// used by: ScanCmds.java
// For comments see header of ScanCmds.java.
//---------------------------------------------------------------------------------------

package scpack;

import java.util.*;
import opencard.core.service.*;
import opencard.core.terminal.*;
import opencard.opt.util.*;

public class ICC {
  static final int IFD_TIMEOUT = 0;      // unit: seconds
  static final int MAX_ATR_LEN = 32;     // maximum length of the ATR
  static final int MAX_APDU_SIZE = 250;  // maximum length of a APDU in byte
  static final int CAPDU_CLA = 0;        // index of class within a command APDU
  static final int CAPDU_INS = 1;        // index of instruction within a command APDU
  static final int RAPDU_SW1 = 0;        // index of SW1 within a response APDU without data

  // return value of some internal methods
  static final byte CLA_NOT_FOUND = 1;
  static final byte INS_NOT_FOUND = 2;
  static final byte INS_FOUND     = 3;

  // coding and description of typical smart cards commands
  static final byte[] NOTSCAN_INS = {(byte)0x02, (byte)0x07};  // not scanned instructions

  private PassThruCardService ptcs;

  // dummy case 1 command
  // CLA || INS || P1 || P2 || P3
  static final byte[] CMD_DUMMY = {(byte)0x00, (byte)0x00,
                                   (byte)0x00, (byte)0x00, (byte)0x00 };

  // Returncode '6Exx': class not supported
  static final byte RC_CLA_NOT_SUPPORTED = (byte) 0x6E;
  // Returncode '6Dxx': instruction not supported
  static final byte RC_INS_NOT_SUPPORTED = (byte) 0x6D;
  // Returncode '68xx': function in class byte not supported  ???
  static final byte RC_CLA_FCT_NOT_SUPPORTED = (byte) 0x68;

  /** set properties for OCF, PC/SC and PassThruCardServce and activates the smart card
   *  @return ATR as byte string in hexadecimal coding
   */
  public byte[] start() {
    byte[] atr = new byte[MAX_ATR_LEN];

    // get and set system properties for OCF, PC/SC and PassThruCardServce
    Properties sysProps = System.getProperties();
    sysProps.put ("OpenCard.terminals", "com.ibm.opencard.terminal.pcsc10.Pcsc10CardTerminalFactory");
    sysProps.put ("OpenCard.services", "opencard.opt.util.PassThruCardServiceFactory");
    try {
      SmartCard.start();
      CardRequest cr = new CardRequest(CardRequest.ANYCARD, null, PassThruCardService.class);
      cr.setTimeout(IFD_TIMEOUT);                 // set timeout for IFD
      SmartCard sc = SmartCard.waitForCard(cr);   // wait for ICC in the IFD
      if (sc != null) {  // no error occured, a smart card is in the terminal
        ptcs = (PassThruCardService) sc.getCardService(PassThruCardService.class, true);
        CardID cardID = sc.getCardID();
        atr = cardID.getATR();
      } // if
    } // try
    catch (Exception e) {
      System.err.println("caught exception '" + e.getClass() + "' - " + e.getMessage() );
    } // catch
    return atr;
  } // start

  /** deactivate the smart card
   */
  public static void stop() {
    try {
      SmartCard.shutdown();
    } // try
    catch (Exception e) {
      System.err.println("caught exception '" + e.getClass() + "' - " + e.getMessage() );
      System.exit(0);
    } // catch
  } // stop


  /** send a command to the smart card
   *  @param  cla class byte of the command
   *  @param  ins instruction byte of the command
   *  @return evaluated return code of the command
   */
  public byte sendCmd(int cla, int ins) {
    byte sw1 = 0;

    CommandAPDU command = new CommandAPDU(MAX_APDU_SIZE);  // create APDU buffer and set size
    command.setLength(0);
    command.append(CMD_DUMMY);
    command.setByte(CAPDU_CLA, cla);   // set first page to write the pattern ????
    command.setByte(CAPDU_INS, ins);    // set last page to write the pattern

    try {
      if (ScanCmds.DEBUG == true) {
        ScanCmds.showText ("\tDebug: " + ScanCmds.formatCmdAPDU(command.getBytes(), command.getLength()) + "\n"); // command APDU
      } //if
      ResponseAPDU response = ptcs.sendCommandAPDU(command);
      sw1 = (byte) response.getByte(RAPDU_SW1);
      if (ScanCmds.DEBUG == true) {
        ScanCmds.showText ("\tDebug: " + ScanCmds.formatRspAPDU(response.getBytes(),response.getLength()) + "\n");  // response APDU
      } // if
    } // try
    catch (Exception e) {
      System.err.println("caught exception '" + e.getClass() + "' - " + e.getMessage() );
      System.exit(0);
    } // catch

    if ((byte) sw1 == (byte) RC_CLA_NOT_SUPPORTED) {
      return CLA_NOT_FOUND;
    } // if
    if ((byte) sw1 == (byte) RC_INS_NOT_SUPPORTED) {
      return INS_NOT_FOUND;
    } // if
    return INS_FOUND;
  } // sendCmd

} // class
//---------------------------------------------------------------------------------------




ICC.java