Developing the APDU MIDlet

Note: This tutorial provides the commented source code for the APDU MIDlet example. For the source code of the example, see the Source codes for examples section of the library.

To create the MIDlet:

  1. Create the class APDUMIDlet.

  2. Import the required classes and assign the new class to the com.nokia.midp.examples.satsa.apdu package.

    package com.nokia.midp.examples.satsa.apdu;
    
    import java.lang.*;
    import java.io.*; 
    import javax.microedition.io.Connector; 
    import javax.microedition.apdu.APDUConnection; 
    import javax.microedition.midlet.*; 
    import javax.microedition.lcdui.*; 
    
    
  3. Set the variables needed in the class. Set the locator string "apdu:0;target=a0.00.00.00.62.03.01.0c.02.01" that is needed later when you pass a request to Connector’s open() method to request an APDU connection. The string identifies the slot number (0) and the card application identifier (a0.00.00.00.62.03.01.0c.02.01).

    /**
     * APDUMIDlet illustrates the implementation of the SATSA APDU optional package.
     * This midlet establish a connection to the smartcard, sends a sample APDU and 
     * shows the result values on screen.
     */
     
    public class APDUMIDlet extends MIDlet implements CommandListener, Runnable 
    { 
      private final String CardSlot0 = "apdu:0;target=a0.00.00.00.62.03.01.0c.02.01"; 
       
      private APDUConnection cardConnection0;
      private Display display; 
      private Form mainForm; 
      private Command exitCommand, demoCommand, backCommand;
      private Form progressForm; 
    
    
  4. Implement a constructor for the MIDlet. Use the constructor to create the required commands (Exit, Demo, and Back), as well as the form for the basic user interface.

    /** Constructor for the APDUMIDlet. Creates required commands and the form. */
     
      public APDUMIDlet() { 
        exitCommand = new Command("Exit", Command.EXIT, 0); 
        demoCommand = new Command("Demo", Command.SCREEN, 0);
        backCommand = new Command("Back", Command.BACK, 0); 
     
        mainForm = new Form("APDU API Example"); 
        mainForm.append(" Press Demo to open smartcard connection.");
        mainForm.addCommand(exitCommand); 
        mainForm.addCommand(demoCommand); 
        mainForm.setCommandListener(this); 
      } 
       
      public void startApp() { 
        display = Display.getDisplay(this); 
             display.setCurrent(mainForm); 
      } 
       
      public void pauseApp() {} 
         public void destroyApp(boolean unconditional) {} 
       
      public void commandAction(Command c, Displayable s) { 
        if (c == exitCommand) { 
          notifyDestroyed(); 
        } 
        else if (c == demoCommand) { 
          progressForm = new Form("Opening connection ..."); 
          display.setCurrent(progressForm); 
           
          Thread t = new Thread(this); 
          t.start(); 
        } 
        else if (c == backCommand) { 
          display.setCurrent(mainForm); 
        } 
      } 
       
    
  5. Implement the run method.

    Use the Connector.open() method to pass a request to the factory class javax.microedition.io.Connector. The locator string CardSlot0 representing the card application was defined earlier in the class. The class returns an object that is able to exchange data on the connection.

    Use the exchangeAPDU() method to send a command to the card application and receive a response. kCardAPDU refers to the byte array forming the APDU message, which is defined later in this example.

    To close the APDUConnection, call the close() method on the connection.

    Create a new form for the response APDU message.

  public void run() { 
    try { 
      setProgress("Opening card at slot 0"); 
      cardConnection0 = (APDUConnection)Connector.open(CardSlot0); 

      setProgress("Exchanging APDUs with card slot 0"); 

      byte[] response = cardConnection0.exchangeAPDU(kCardAPDU); 

      progressForm.setTitle("Closing connection..."); 
      
      cardConnection0.close(); 
      
      progressForm.setTitle("Done.");

/** Converts bytes to string format. */

      String s="";
      for ( int j=0; j < response.length; j++){
        int tmp = response[j];
        if( tmp < 0 ) tmp += 256;
        String tmps = Integer.toHexString( tmp );
        if( tmps.length() == 1 ) tmps = "0" + tmps;
       	s += tmps + " ";
      }

      Form g = new Form("Response APDU:"); 
      g.append(s); 
      g.addCommand(backCommand); 
      g.setCommandListener(this); 
      display.setCurrent(g); 
    } 
    catch (Exception e) { 
      try { cardConnection0.close(); } catch (Throwable t) {} 
            
      Form f = new Form("Exception"); 
      f.append(e.toString()); 
      f.addCommand(backCommand); 
      f.setCommandListener(this); 
      display.setCurrent(f); 
    } 
  } 
   
  private void setProgress(String s) { 
    StringItem si = new StringItem(null, s); 
    si.setLayout(Item.LAYOUT_2 | Item.LAYOUT_NEWLINE_AFTER); 
    progressForm.append(si); 
  } 
 
/** A sample APDU. */

  private final byte[] kCardAPDU = 
    // Select File EF_ID
    {(byte)0x00, (byte)0xA4, (byte)0x08, (byte)0x00,
     (byte)0x02, (byte)0x00, (byte)0x03 };
    // should return 01 90 00
}