RIM Crypto API: Adding New Smart Card Driver Readers

This tutorial explains the steps involved in adding a new smart card reader driver to the SmartCard API. A "smart card reader driver" refers to a pair of classes: one class representing a physical smart card reader, and the other class representing a communications session with a physical smart card reader. A new driver is implemented by extending the two abstract classes: SmartCardReader and SmartCardReaderSession.

The following sections outline and illustrate the requirements for each.

Extending SmartCardReader

A SmartCardReader object represents a physical smart card reader. The first step in creating a new smart card reader driver is to implement a subclass extending SmartCardReader. The UI functionality is implemented in the base class, and subclasses should not need to do this.

The following code example illustrates the abstract methods that must be implemented.

    public class MySmartCardReader extends SmartCardReader
    {
    
	/**
	 * This method returns the appropriate subclass of SmartCardReaderSession,
	 * used to establish a communications session with the smart card reader.
	 * This method throws SmartCardNoReaderPresentException if the reader is not present or attached, and
	 * throws SmartCardIOException if there was a communications problem.
	 **/ 
    	protected SmartCardReaderSession openSessionImpl() throws SmartCardException
    	{
            return new RIMSmartCardReaderSession( this );
    	}
		
    	/**
    	 * This method returns true if the reader is attached, and false otherwise.
    	 * The implementation of this function must not call openSession().
    	 **/
    	public boolean isReaderPresentImpl() throws SmartCardException
    	{
            //details specific to each reader
            //See the documentation for your reader API.
            return false;
    	}

	/**
	 * Returns true if a smartcard is present in the reader, and false otherwise.
	 * Should return false when there is not reader present.
	 * The implementation of this function must not call openSession().
	 **/
	public boolean isSmartCardPresentImpl() throws SmartCardException
	{
            //details specific to each reader
            //See the documentation for your reader API.
            return false;
	}

	/**
	 * Some readers may recognize when a card is inserted or removed.
	 * This method may return true if this functionality is supported by the reader,
	 * and must return false otherwise.
	 **/
	public boolean isInsertionRemovalDetectableImpl()
	{
            return true;
	}

	/**
	 * This method returns a label associated with the kind of smart card reader.
	 * The string should not include the words "smart card reader", as this method will
	 * be used to generate strings such as ( "Please insert your %s smart card reader", getLabel() )
	 **/ 
	public String getLabelImpl()
	{
            return "Rim smart card reader";
	}

	/**
	 * This method returns the type of the reader, eg "Serial Port".
   	 * A session does not need to be open to get a valid response from this method.
	 **/
	public String getTypeImpl()
	{
           return "Serial Port";
	}

        /**
         * Allows the driver to indicate if they support displaying settings.
         * If this method returns true, then the method displaySettings maybe called
         * to show settings to the user.
         **/
        protected boolean isDisplaySettingsAvailableImpl( Object context )
        {
            // If the driver supports displaying setting return true, otherwise return false.
            return true; 
        }

        /**
         * Allows the driver to display some settings or properties.
         * This method will be invoked from the smart card options screen when
         * the user selects the driver and chooses to view the settings of that driver.
         * 
         * This method could be called from the event thread. The driver should not block
         * the event thread for long periods of time.
         **/
        protected void displaySettingsImpl( Object context )
        {
           //Display Settings
        }
    }

Extending SmartCardReaderSession

A SmartCardReaderSession object represents a communications session with a physical smartcard reader. Over the communications session, APDUs ("application protocol data units") may be exchanged with the reader and the smart card to provide the desired functionality. A subclass extending SmartCardReaderSession must be implemented when creating a new smart card reader driver. The subclass may provide any additional functions appropriate to the application. Again, the UI functionality is implemented in the base class, and subclasses should not need to do this.

The following code example illustrates the abstract methods to be implemented.

    public class MySmartCardReaderSession extends SmartCardReaderSession
    {
    
 	/**
 	 * The constructor creates a new SmartCardReaderSession.
 	 * Parameter smartCardReader refers to the SmartCardReader object associated with this session.
	 **/	
        protected RIMSmartCardReaderSession( SmartCardReader reader )
	{
            super( reader );
	}

	/** This method closes this session with the smart card reader. **/ 
	protected void closeImpl() { //Do any cleanup; details specific to each reader //See the documentation for your reader API. }

  	/**
   	 * This method transmits an APDU (Application Protocol Data Unit) to the reader, and blocks waiting for a response.
   	 **/
	public void sendAPDUImpl( CommandAPDU commandAPDU, ResponseAPDU responseAPDU ) throws SmartCardException
	{
    	    //Details specific to each reader.
    	    //See the documentation for your reader API.
   	}

  	/**
   	 * This method returns the AnswerToReset provided by the physical smartcard present in the reader.
  	 * This method throws SmartCardNoCardPresentException if a smartcard is not found in the reader.
  	 **/   
	public AnswerToReset getAnswerToResetImpl() throws SmartCardException
	{
	    //Details specific to each reader.
	    //See the documentation for your reader API.
            return null;
	}
 
        /** 
         * Attempts to negotate a new protocol with the smartcard if desired. The reader and the
         * smartcard should negotiate the best protocol that both support. 
         * 
         */
        public void negotiateProtocolImpl( SmartCardCapabilities cardCapabilities ) throws SmartCardException
        {
            //Details specific to each reader.
            //See the documentation for your reader API.
        }
    }