APDUMIDlet.java

/**
 * Copyright (c) 2011 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia 
Corporation.
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners.
 * See LICENSE.TXT for license information.
 */

package com.nokia.example.satsa.apdu;

import javax.microedition.io.Connector;
import javax.microedition.apdu.APDUConnection;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * 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;

    /** 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);
        }
    }

    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...");

            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) {
            Form f = new Form("Exception");
            f.append(e.toString());
            f.addCommand(backCommand);
            f.setCommandListener(this);
            display.setCurrent(f);
        } finally {
            try {
                cardConnection0.close();
            } catch (Throwable t) {
            }
        }
    }

    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
}