OpenCard  
 
OCF, the OpenCard Framework is a standard Java framework for working with Smart Cards.  
 
/*
  * Copyright © 1998 Gemplus SCA
  * Av. du Pic de Bertagne - Parc d'Activités de Gémenos
  * BP 100 - 13881 Gémenos CEDEX
  * 
  * "Code derived from the original OpenCard Framework".
  * 
  * Everyone is allowed to redistribute and use this source  (source
  * code)  and binary (object code),  with or  without modification,
  * under some conditions:
  * 
  *  - Everyone  must  retain  and/or  reproduce the above copyright
  *    notice,  and the below  disclaimer of warranty and limitation
  *    of liability  for redistribution and use of these source code
  *    and object code.
  * 
  *  - Everyone  must  ask a  specific prior written permission from
  *    Gemplus to use the name of Gemplus.
  * 
  * DISCLAIMER OF WARRANTY
  * 
  * THIS CODE IS PROVIDED "AS IS",  WITHOUT ANY WARRANTY OF ANY KIND
  * (INCLUDING,  BUT  NOT  LIMITED  TO,  THE IMPLIED  WARRANTIES  OF
  * MERCHANTABILITY  AND FITNESS FOR  A  PARTICULAR PURPOSE)  EITHER
  * EXPRESS OR IMPLIED.  GEMPLUS DOES NOT WARRANT THAT THE FUNCTIONS
  * CONTAINED  IN THIS SOFTWARE WILL MEET THE USER'S REQUIREMENTS OR
  * THAT THE OPERATION OF IT WILL BE UNINTERRUPTED OR ERROR-FREE. NO
  * USE  OF  ANY  CODE  IS  AUTHORIZED  HEREUNDER EXCEPT UNDER  THIS
  * DISCLAIMER.
  * 
  * LIMITATION OF LIABILITY
  * 
  * GEMPLUS SHALL NOT BE LIABLE FOR INFRINGEMENTS OF  THIRD  PARTIES
  * RIGHTS. IN NO EVENTS, UNLESS REQUIRED BY APPLICABLE  LAW,  SHALL
  * GEMPLUS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER  INCLUDING,
  * WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE,
  * COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER DAMAGES OR
  * LOSSES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ALSO,
  * GEMPLUS IS  UNDER NO  OBLIGATION TO MAINTAIN,  CORRECT,  UPDATE, 
  * CHANGE, MODIFY, OR OTHERWISE SUPPORT THIS SOFTWARE.
  */
 
 import opencard.core.terminal.*;
 import opencard.core.util.*;
 import opencard.core.service.*;
 import opencard.opt.util.*;
 
 /**
  * A sample that demonstrates the access to a smard card,
  * obtains a <tt>CardID</tt> object which represents an ATR,
  * then send a SIM-card information request APDU (i.e., <tt>STATUS</tt>)
  *
  * @author  Christophe Muller (Christophe.Muller@research.gemplus.com)
  * @version $Id: SimTest.java,v 1.0 1999/11/29 16:56:48 root Exp root $
  **/
 
 public class SimTest {
 
     public static void main (String [] args) {
 
     System.out.println ("----------------------------------------------");
     System.out.println ("Test of OCF with a SIM card");
     System.out.println ("");
 
     try {
         // Initialize the framework
         SmartCard.start ();
 
         CardRequest cr = new CardRequest ();
         cr.setWaitBehavior (CardRequest.ANYCARD);
         SmartCard sm = SmartCard.waitForCard (cr);
 
         // print the ATR (from demos.samples.GetCardID)
         if (sm != null) {
         CardID cardID = sm.getCardID ();
         printCardID (cardID);
         } else {
         System.out.println ("did not get a SmartCard object!");
         }
 
         // Get a PassThru card service and perform a 'STATUS' command
         PassThruCardService cs = (PassThruCardService)
         sm.getCardService(PassThruCardService.class, true);
 
         CommandAPDU cmd = new CommandAPDU(22);
         cmd.setLength(0);
         cmd.append((byte) 0xa0);
         cmd.append((byte) 0xf2);
         cmd.append((byte) 0x00);
         cmd.append((byte) 0x00);
         cmd.append((byte) 0x16);
 
         System.out.println("Command 'STATUS':");
         System.out.println(cmd.toString());
 
         System.out.println("Sending a 'STATUS' command to the card...");
         ResponseAPDU resp = cs.sendCommandAPDU(cmd);
         System.out.println("Response to 'STATUS' command:");
         System.out.println(resp.toString());
       
         // Shutdown the framework
         SmartCard.shutdown ();
     }
     catch (OpenCardPropertyLoadingException plfe) {
         System.out.println ("OpenCardPropertyLoadingException: ");
         System.out.println (plfe.getMessage () );
     }
     catch (ClassNotFoundException cnfe) {
         System.out.println ("ClassNotFoundException: ");
         System.out.println (cnfe.getMessage () );
     }
     catch (CardServiceException cse) {
         System.out.println ("CardServiceException: ");
         System.out.println (cse.getMessage () );
     }
     catch (CardTerminalException cte) {
         System.out.println ("CardTerminalException: ");
         System.out.println (cte.getMessage () );
     }
 
     System.out.println ("");
     System.out.println ("----------------------------------------------");
     }
 
 
     /**
      * Prints out the information of the <tt>CardID</tt> object passed.
      */
     public static void printCardID (CardID cardID) {
     StringBuffer sb = new StringBuffer("Obtained the following CardID:\n\n");
 
     byte [] atr = cardID.getATR ();
     sb.append (HexString.hexify (atr) ).append ('\n');
     
     appendHistoricals (sb, cardID);
 
     System.out.println(sb);
     }
 
 
     private static void appendHistoricals(StringBuffer sb, CardID cardID) {
     byte[] hist = cardID.getHistoricals();
 
     sb.append("Historicals: ");
     if (hist == null) {
         sb.append("none\n");
     } else {
         sb.append(HexString.hexify(hist)).append('\n');
         sb.append("as a string: ");
         for(int i=0; i<hist.length; i++)
         sb.append((hist[i]<32)? // signed byte extension!
               ' ' : (char)hist[i]);
         sb.append('\n');
     }
     }
 
 
     private static void appendTS(StringBuffer sb, byte ts) {
     sb.append("TS = ").append(HexString.hexify(ts)).append("    ");
     sb.append((ts==(byte)0x3b) ? "direct" : "inverse").append(" convention\n");
     }
 
 
     private static void appendT0(StringBuffer sb, byte t0) {
     sb.append("TS = ").append(HexString.hexify(t0)).append("    ");
     binify(sb, t0);
     sb.append('\n');
     }
 
 
     private static void appendClockrate(StringBuffer sb, byte cr) {
     double[] mhz  = { -1.0, 5.0, 6.0, 8.0, 12.0, 16.0, 20.0, -1.0,
               5.0, 7.5, 10.0, 15.0, 20.0, -1.0, -1.0, -1.0 };
     int[] factors = { -2, 372, 558, 744, 1116, 1488, 1860, -1,
               512, 768, 1024, 1536, 2048, -1, -1, -1 };
     
     int fi = (cr >> 4) & 0xf;
     
     double speed =   mhz  [fi];
     int   factor = factors[fi];
     
     sb.append("Clock speed ");
     if (speed < 0)
         sb.append("???");
     else
         sb.append(speed);
     
     sb.append(" MHz, divided by ");
     if (factor < 0)
         sb.append("???");
     else
         sb.append(factor);
     sb.append('\n');
     }
 
 
     private static void appendBitAdjust(StringBuffer sb, byte b) {
     double[] bra = { -1.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, -1.0,
              12.0, 20.0, 1.0/2, 1.0/4, 1.0/8, 1.0/16, 1.0/32, 1.0/64 };
     int di = b & 0xf;
     
     sb.append("bit rate adjustment ");
     if (bra[di] < 0)
         sb.append("???");
     else
         sb.append(bra[di]);
     sb.append('\n');
     }
 
 
     private static void appendProgCurr(StringBuffer sb, byte b) {
     int[] mpg = { 25, 50, 100, -1 };
     int ii = (b >> 5) & 3;
     
     sb.append("max prog current ");
     if (b < 0)
         sb.append("???");
     else
         sb.append(mpg[ii]).append(" mA");
     sb.append('\n');
     }
 
 
     private static void binify(StringBuffer sb, byte b) {
     for(int i=0; i<8; i++) {
         sb.append((b<0) ? '1' : '0');
         b <<= 1;
     }
     }
 
 }