FileDocCategorySizeDatePackage
A.javaAPI DocJava Card14308Wed Mar 22 21:07:24 GMT 2006com.sun.javacard.samples.odSample.packageA

A

public class A extends Applet
package AID 0xA0 0x00 0x00 0x00 0x62 0x03 0x01 0x0C 0x07 0x01 applet AID - 0xA0 0x00 0x00 0x00 0x62 0x03 0x01 0x0C 0x07 0x01 0x01 This applet used to demonstrate object deletion mechanism and also to monitor memory usage as other packages/applets get added/deleted

Fields Summary
public static final byte
A_CLA
public static short
ST_ERROR_BAD_TRANSIENT_MEM_DESELECT
public static short
ST_ERROR_BAD_TRANSIENT_MEM_DESELECT_ELEMENT
public static short
ST_ERROR_BAD_TRANSIENT_MEM_RESET
public static short
ST_ERROR_BAD_TRANSIENT_MEM_RESET_ELEMENT
public static short
ST_ERROR_MEM_MATCH_OBJECTS
public static short
ST_ERROR_MEM_MATCH_TRANSIENT_DESELECT_OBJECTS
public static short
ST_ERROR_TRANSIENT_DESELECT_OBJECTS_EXIST
public static short
ST_ERROR_TRANSIENT_RESET_OBJECTS_EXIST
public static short
ST_ERROR_MEM_MATCH_TRANSIENT_RESET_OBJECTS
public static short
ST_ERROR_MEM_MATCH_ALL_ATTRIBUTES
public static short
ST_ERROR_MEM_MATCH_INITIAL
public static short
ST_ERROR_MEM_MATCH_BEFORE_PACK
public static short
ST_ERROR_APPLET_AID_NOT_FOUND
public static short
ST_ERROR_SHAREABLE_NOT_FOUND
public static short
ST_ERROR_TRANSIENT_DESELECT_MEM_NOT_RETURNED
public static short
ST_ERROR_TRANSIENT_RESET_MEM_NOT_RETURNED
public static short
SUCCESS
public static byte[]
BApp1AID
short
initialMemUsage
short
initialTransientDeselectMem
short
initialTransientResetMem
short
objectRefMemUsage
short
transientDeselectUninitializedMemUsage
short
transientDeselectMemUsage
short
transientResetUninitializedMemUsage
short
transientResetMemUsage
ATreeNode
left
ATreeNode
right
static ATreeNode
sleft
static ATreeNode
sright
Object[]
transientDeselectMem
Object[]
transientResetMem
Shareable
BApp1Ref
private static final short
NUM_OBJECTS
private static final short
MAX_TREE_DEPTH
static final byte
SETUP_PERSISTENT
static final byte
SETUP_TRANSIENT
static final byte
REQUEST_OD
static final byte
REMOVE_TREES
static final byte
ANALYZE_REMOVE_TREES
static final byte
ANALYZE_TRANSIENT_DESELECT_MEM
static final byte
ANALYZE_TRANSIENT_RESET_MEM
static final byte
REMOVE_ALL_ATTRIBUTES
static final byte
ANALYZE_REMOVE_ALL_ATTRIBUTES
static final byte
CAPTURE_INITIAL_MEM
static final byte
COMPARE_INITIAL_MEM
static final byte
GET_SHAREABLE_REF
static final byte
LOSE_REF_BAPP1
Constructors Summary
private A()
Constructor. Calls register and captures the initial memory usage

    //capture initial persistant memory available
    register();
    initialMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
  
Methods Summary
private voidanalyzeRemoveAllAttributes()
method analyzes if all transient and persistent memory have been returned to the memory manager. It is called after the card has been reset.

    //now the memory should have gone back to initial mem
    short tempMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);    
    if(tempMem!=initialMemUsage){
      ISOException.throwIt(ST_ERROR_MEM_MATCH_ALL_ATTRIBUTES);
    }

	//test if all transient reset and deselect memory is returned
	if(initialTransientResetMem!=
	   JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET))		
		ISOException.throwIt(ST_ERROR_TRANSIENT_RESET_MEM_NOT_RETURNED);
	
	
	if(initialTransientDeselectMem!=
	   JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT))
		ISOException.throwIt(ST_ERROR_TRANSIENT_DESELECT_MEM_NOT_RETURNED);
  
private voidanalyzeRemoveTrees()
method verifies if all memory pointed to the persistent objects was collected

	  short tempMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
	  if(tempMem!=transientResetMemUsage){
		  //error. not all memory collected
		  ISOException.throwIt(transientResetMemUsage);		  
		  //ISOException.throwIt(ST_ERROR_MEM_MATCH_OBJECTS);		  
	  }
	  //verify all other objs pointed to by the DESELECT array are intact
	  short ret=verifyTransientDeselect();
	  if(ret!=SUCCESS)
		  ISOException.throwIt(ret);

	  //verify all objects pointed to by the RESET array are intact
	  ret=verifyTransientReset();
	  if(ret!=SUCCESS)
		  ISOException.throwIt(ret);
  
private voidanalyzeTransientDeselectMem()
this method should be called after deselecting and selecting

    //by this point the arrays must have had there values nulled and references
    //to all transientarrayelements lost. Object deletion mechanism here would have deleted
    //all transientarrayelement objects pointed to by deselect array

    //verify objects pointed to by DESELECT array are gone
	  short ret=verifyTransientDeselect();
	  if(ret!=ST_ERROR_BAD_TRANSIENT_MEM_DESELECT_ELEMENT)
		  ISOException.throwIt(ST_ERROR_TRANSIENT_DESELECT_OBJECTS_EXIST);

    //verify persistent memory collected for all objects
    short tempMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);    
    if(tempMem!=(short)(transientResetMemUsage+
						(transientDeselectUninitializedMemUsage-transientDeselectMemUsage))){
      //error. not all memory collected
		ISOException.throwIt( ST_ERROR_MEM_MATCH_TRANSIENT_DESELECT_OBJECTS);
    }

    //verify all objects pointed to by the RESET array are intact
    ret=verifyTransientReset();
	if(ret!=SUCCESS)
		ISOException.throwIt(ret);
  
private voidanalyzeTransientResetMem()
this method should be called after card was reset. It analyzes if all persistent memory has been returned including the memory used by objects in the transient reset array.

    //by now card should have been reset

    //verify objects pointed to by RESET array are gone
    short ret=verifyTransientReset();
    if(ret!=ST_ERROR_BAD_TRANSIENT_MEM_RESET_ELEMENT)
		ISOException.throwIt(ST_ERROR_TRANSIENT_RESET_OBJECTS_EXIST);

    //verify memory is collected for all objects
    short tempMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);    
    if(tempMem!=(short)((transientDeselectUninitializedMemUsage-transientDeselectMemUsage)+
						(transientResetUninitializedMemUsage))){
		//not all memory returned
		ISOException.throwIt( ST_ERROR_MEM_MATCH_TRANSIENT_RESET_OBJECTS);
    }
  
private voidcaptureInitialMem()
method captures the current memory used by compareWithInitial() to check if memis same.

    initialMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
  
private voidcompareWithInitial()
method compares the current memory with initialMemUsage and throws exception if not the same

    short curr=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
    if(curr!=initialMemUsage)
      ISOException.throwIt( ST_ERROR_MEM_MATCH_INITIAL);
  
private voidgetShareableRef()
method gets a shareable reference to BApp1 (Applet B instance 1) to verify that we cannot delete it

		AID bApp1AID=JCSystem.lookupAID(BApp1AID,(short)0,(byte)BApp1AID.length);
		if(bApp1AID==null)
			ISOException.throwIt(ST_ERROR_APPLET_AID_NOT_FOUND);
		//get the ref
		BApp1Ref=(Shareable)(JCSystem.getAppletShareableInterfaceObject(bApp1AID,(byte)0));
		if(BApp1Ref==null)
			ISOException.throwIt(ST_ERROR_SHAREABLE_NOT_FOUND);
	
public static voidinstall(byte[] bArr, short bOffset, byte bLength)
method instantiates aninstance of A


	     	 
	      
		new A();
	
private voidloseBAppRef()
method sets the BApp1 referenc to null

		BApp1Ref=null;
		JCSystem.requestObjectDeletion();
	
public voidprocess(APDU apdu)
method processes the APDU commands passed to this applet instance. It dispatches the request by calling the appropriate method and returning appropriate result

    byte buffer[]=apdu.getBuffer();
    // check SELECT APDU command
    if ((buffer[ISO7816.OFFSET_CLA] == 0) &&
		(buffer[ISO7816.OFFSET_INS] == (byte)(0xA4))){
		return;
    }
    short ret=0;
    short tempMem=0;
    switch (buffer[ISO7816.OFFSET_INS]){
    case SETUP_TRANSIENT:
      setupTransient();
	  break;
    case SETUP_PERSISTENT:
      setupPersistent();
	  break;
    case REQUEST_OD:
      requestOD();
	  break;
    case REMOVE_TREES:
      removeTrees();
      break;
    case ANALYZE_REMOVE_TREES:
		analyzeRemoveTrees();
		break;
    case ANALYZE_TRANSIENT_DESELECT_MEM:
		//this must be called after deselecting and selecting
		analyzeTransientDeselectMem();	
		break;
    case ANALYZE_TRANSIENT_RESET_MEM:
      //called after applet reset
      analyzeTransientResetMem();
	  break;
    case REMOVE_ALL_ATTRIBUTES:
      removeAllAttributes();
      break;
    case ANALYZE_REMOVE_ALL_ATTRIBUTES:
      analyzeRemoveAllAttributes();
	  break;
    case CAPTURE_INITIAL_MEM:
      captureInitialMem();
      break;
    case COMPARE_INITIAL_MEM:
		//Assumes captureInitialMem has been called
		compareWithInitial();
		break;
	case GET_SHAREABLE_REF:
		getShareableRef();
		break;
	case LOSE_REF_BAPP1:
		loseBAppRef();
		break;
    default:
      ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    }
  
private voidremoveAllAttributes()
method sets attributes pointing to the two types of transient arrays to null. This creates garbage objects to be deleted. Method also requests for object deletion

		//set all attributes to null
		transientDeselectMem=null;
		transientResetMem=null;
		JCSystem.requestObjectDeletion();
	
private voidremoveTrees()
method sets the persistent object references to null

    //remove the trees from both static and non-static trees
    left=null;
	right=null;
	sleft=null;
	sright=null;
  
private voidrequestOD()
request object deletion facility to delete objects that are not reachable

    JCSystem.requestObjectDeletion();
  
private voidsetupPersistent()
method sets up the persistent objects by calling setupTrees() and captures the memory available

    //setup object references
    setupTrees();
    objectRefMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
  
private voidsetupTransient()
method sets up the transient objects and captures available memory of different kinds at various stages.

    //get initial memory available for persistent and transient memory
    initialMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
	initialTransientDeselectMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
	initialTransientResetMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);	

    //setup CLEAR_ON_DESELECT memory
    transientDeselectMem=JCSystem.makeTransientObjectArray(NUM_OBJECTS,JCSystem.CLEAR_ON_DESELECT);
    transientDeselectUninitializedMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
    for(short i=0;i<NUM_OBJECTS;i++)
      transientDeselectMem[i]=new TransientArrayElement(i);
    transientDeselectMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
    
    //setup CL_ON_RESET memory
	transientResetMem=JCSystem.makeTransientObjectArray(NUM_OBJECTS,JCSystem.CLEAR_ON_RESET);
    transientResetUninitializedMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
    for(short i=0;i<NUM_OBJECTS;i++)
      transientResetMem[i]=new TransientArrayElement(i);
    transientResetMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
  
private voidsetupTrees()
method sets up tree of objects. Two are statically referenced.

    left=new ATreeNode((short)0,MAX_TREE_DEPTH);
    right=new ATreeNode((short)0,MAX_TREE_DEPTH);
    sleft=new ATreeNode((short)0,MAX_TREE_DEPTH);
    sright=new ATreeNode((short)0,MAX_TREE_DEPTH);
  
private shortverifyTransientDeselect()
verify the transient structures of type CLEAR_ON_DESELECT are intact

    if(transientDeselectMem==null)
      return ST_ERROR_BAD_TRANSIENT_MEM_DESELECT;
    for(short i=0;i<transientDeselectMem.length;i++){
      if(transientDeselectMem[i]==null ||
	 ((TransientArrayElement)transientDeselectMem[i]).data!=i)
	return ST_ERROR_BAD_TRANSIENT_MEM_DESELECT_ELEMENT;
    }
    return SUCCESS;
  
private shortverifyTransientReset()
verify the transient structures of type CLEAR_ON_RESET are intact

    if(transientResetMem==null)
      return ST_ERROR_BAD_TRANSIENT_MEM_RESET;
    for(short i=0;i<transientResetMem.length;i++){
      if(transientResetMem[i]==null ||
	 ((TransientArrayElement)transientResetMem[i]).data!=i)
	return ST_ERROR_BAD_TRANSIENT_MEM_RESET_ELEMENT;
    }
    return SUCCESS;