22 Nov 2010

How mobile phone and SIM card setup connection or why sometime mobile phone rejects SIM Card?

A little bit theory
First of all SIM Card is particular application of SmartCard usage hence low level part specified by series of ISO7816 standards. ISO7816-3 standard specifies the following procedure to initiate interaction between card and Interface Device:
  1. Cold Reset (RST)
  2. SIM Card answers ATR (Answer-to-Reset)
  3. PPS negotiation
  4. Data exchange
Let's review each point one by one:
Cold Reset
Cold Reset is sending electrical reset signal to contact C2:

Above picture is showing SIM Card with USB interface which specifies additional contacts like C4, C8, C6 which are not part of ISO standard.
Answer-to-Reset (ATR)
To reset signal SIM card answers sequence of bytes and it’s structure is the following:

The aim of the ATR is declaring to the mobile phone card capabilities.The connection parameters supported by card has been specified in TA1:
TA1 encodes the indicated value of the clock rate conversion integer (Fi), the indicated value of the baud rate adjustment integer (Di) and the maximum value of the frequency supported by the card (f(max.)).
PPS negotiation
For exchanging information, the card and the handset shall agree on transmission protocol and values of transmission parameters. This process called PPS (Protocol and Parameters Selection) negotiation. After that all information exchange has to follow agreed parameters.
All these parameters based on the nominal duration of one moment of the electrical circuit I/O is named “elementary time unit” and denoted etu:


The delay between the leading edges of two consecutive characters shall be at least 12 etu, i.e. the duration of one character, (10±0,2) etu, followed by a guardtime (GT).
The following figure describes it graphically:


Let’s take an example of ATR : 3B9E96801FC78031E073FE211B66D0007A008000FA
Here TA1 byte is 96. Below the trace taken using ContactLAB tracer between mobile phone and SIM Card:
PPS2
As you can see as the result of PPS negotiation mobile phone and card have agreed to the value 96 and frequency is f = 3.84 MHz.
Based on these values we can determine F and D values from the tables provided in ISO7816-3 standard:
Table 7 — Fi and f (max.)
Bits 8 to 5 0000 0001 0010 0011 0100 0101 0110 0111
Fi 372 372 558 744 1116 1488 1860 RFU
f (max.) MHz 4 5 6 8 12 16 20 -

Bits 8 to 5 1000 1001 1010 1011 1100 1101 1110 1111
Fi RFU 512 768 1024 1536 2048 RFU RFU
f (max.) MHz - 5 7,5 10 15 20 - -
Table 8 — Di
Bits 4 to 1 0000 0001 0010 0011 0100 0101 0110 0111
Di RFU 1 2 4 8 16 32 64
Bits 4 to 1 1000 1001 1010 1011 1100 1101 1110 1111
Di 12 20 RFU RFU RFU RFU RFU RFU
As our PPS is 96 we have to split it to MSB and LSB:
  • 9 = b1001 –> Fi = 512 (from the Table 7)
  • 6 = b0110 –> Di = 32 (from the Table 8)
Based on above information we can calculate etu for our case:
image
The minimum delay between two characters has to be 12 etu i.e.:
image
Mobile phone rejects SIM Card
Time to time you have messages like “Insert SIM Card” or “SIM Card failures” even in case of SIM Card is working on another handset. After we knows the theory we can analyze the reasons. Of course it requires some tracer equipment which is able to show precise timing of signals. Personally I am using Micropross or ContactLAB tracers depending on which one is available in my team right now. :)
The principle is pretty easy. You have to check timings of signals in two directions: Mobile phone –> SIM Card and SIM Card –> Mobile phone.
Let’s take an example:
Mobile phone –> SIM Card
Below the trace for APDU in direction Mobile phone –> SIM Card:
Mobile-Card
As you remember “The delay between the leading edges of two consecutive characters shall be at least 12 etu”. In our case 12 etu is 50.04 µS. Now pay attention to the time between 2 cursors (red and blue one). It is 55.150 µS i.e. everything is working well.
You can analyze the response of the card in the same manner and check time. If it is less than 12 etu it means issue on card side which is not respecting ISO standard and vice versa if timing is wrong from mobile phone to the SIM Card issue is in mobile phone.
Et Voila!

JavaCard applets debugging techniques

Debugging JavaCard applets is always difficult. There are different ways of debugging applets:
  • Usage of different simulators
  • Usage of On Card Debugger
  • Applet way of debugging

Let’s review each way one by one.

Simulators
Most of JavaCard development IDEs provides SIM Card Simulator. Two of them are bundled with JavaCard Development Kit. They are CREF and JCWDE. I couldn’t tell too much about them as I’ve never used. Another example is commercial product Developer Suite by Gemalto. It has own different type simulators. Which enables you to debug different applets including Smart Card Web Server (SCWS) servlets and NFC applets.
The simulators are good enough but sometimes you need to debug on real card. The situation when everything is working fine on simulator and not working on the card isn’t rare.
I don’t want to pay a lot attention to simulator as debugging techniques are almost the same as any other application.

On Card Debugger
This is most advanced way of debugging applets but at the same time least available. Each SmartCard manufacturer has own On Card Debugger implementation and usage of it is subject of property. It is not available outside of the manufacturer.
But anyway let me explain general approach of On Card Debugger usage. Most of them are based on Remote Java Debugging. To use it you have to follow below actions:

  • Compile your applet with Debug_Component (Be careful, Debug_Component is only available starting from JavaCard 2.2.1). To be able to do it you have to compile all your classes with debug information and use –debug option during conversion
  • Load applet to the card
  • Setup your favourite development environment for Remote Java Debugging
  • Activate On Card Debugger if needed

I can’t say more on this subject as I have NDA constraints.

Applet way of debugging
This way is most available. The general idea is the same as logging your application steps. I’d like to cover it in details.
There are several ways of applet way of debugging:

  • Throw ISOException.throwIt(0x????) if some verification didn’t pass. As a result you’ll have Status Word for some action of your applet and you can figure out what is going wrong
  • Usage DISPLAY TEXT proactive command to track your applet execution
  • Usage of Shareable interface and communicate with your applet from another one and somehow get execution steps. Here you can use DISPLAY TEXT or you can write to some file.
  • Usage of Debug file directly from your applet. You can write logs to this file
  • You can create your own APDU commands and implement process() method
  • Combination of above steps

Personally I prefer combination of DISPLAY TEXT and creation of own APDUs with implementation of process() method.

Let’s review this method step by step.

The main idea of this debugging techniques is writing specific values to global variables at different part of the code execution and retrieve those values when needed.

With these values we can deduce:

  • The last correctly executed line
  • What kind of exception has thrown and and its reason

We can retrieve those values in 2 different ways:

  • By selection of STK menu
  • By selecting directly applet AID and send appropriate APDU

How can we implement it? We can declare bunch of static variables to store debug values like:

private static byte bDebug1 = (byte)0;
private static byte bDebug2 = (byte)0;
private static byte bDebug3 = (byte)0;
private static byte bDebug4 = (byte)0;
private static byte bDebug5 = (byte)0;
private static byte bDebug6 = (byte)0;

Then we need to implement setDebug() method like:

private static void setDebug( short sDebug )
{
    bDebug1 = (byte) (sDebug >> 8);
    bDebug2 = (byte) sDebug;
}
private static void setDebug( short sDebug, short sDebug2 )
{
    bDebug3 = (byte) (sDebug >> 8);
    bDebug4 = (byte) sDebug;
    bDebug5 = (byte) (sDebug2 >> 8);
    bDebug6 = (byte) sDebug2;
}

Now in our target applet which we have to debug we can use it like:

setDebug((short)0x0102);

Where 0x0102 is some coding which specify whatever you want on some stage of execution.

To retrieve values we have to implement process() method like:

/**
* Method called by the JCRE, once selected
* @param apdu the incoming APDU object
*/
public void process(APDU apdu) {
    /** any APDU command to the applet will send back 6 bytes */
    byte [] baAPDU = apdu.getBuffer();

    baAPDU[ ISO7816.OFFSET_CDATA ] = bDebug1;
    baAPDU[ ISO7816.OFFSET_CDATA + 1 ] = bDebug2;
    baAPDU[ ISO7816.OFFSET_CDATA + 2 ] = bDebug3;
    baAPDU[ ISO7816.OFFSET_CDATA + 3 ] = bDebug4;
    baAPDU[ ISO7816.OFFSET_CDATA + 4 ] = bDebug5;
    baAPDU[ ISO7816.OFFSET_CDATA + 5 ] = bDebug6;

    apdu.setOutgoingAndSend( ISO7816.OFFSET_CDATA, (short) 6 );
}

To retrieve debug information through STK menu we have to implement processToolkit() method:

/**
* Method called by the SIM Toolkit Framework
* @param event the byte representation of the event triggered
*/
public void processToolkit(byte event) {
    try {
        EnvelopeHandler envHdlr = EnvelopeHandler.getTheHandler();

        // Manage the request following the MENU SELECTION event type
        if (event == EVENT_MENU_SELECTION) {
            // Get the selected item
            byte selectedItemId = envHdlr.getItemIdentifier();

            // Perform the required service following the Menu1 selected item
            if (selectedItemId == idMenuDisplayDebug) {
                displayDebug();
            }
        }

        // If required by your applet implement managing
        // UNFORMATTED SMS PP ENV event type and
        // FORMATTED SMS PP event type

       if (event == EVENT_UNFORMATTED_SMS_PP_ENV) {
           unformattedSmsDownloadService();
       }
       if (event == EVENT_FORMATTED_SMS_PP_ENV) {
           formattedSmsDownloadService();
       }
    }
    catch(ArrayIndexOutOfBoundsException aioob) {
        setDebug((short)0x0100, (short)0x1111);
    }
    catch(NullPointerException npe) {
        setDebug((short)0x0200, (short)0x1111);
    }
    catch(SecurityException se) {
        setDebug((short)0x0300, (short)0x1111);
    }
    catch(ISOException ie) {
        setDebug((short)0x0400, ie.getReason());
    }
    catch(SIMViewException sve) {
        setDebug((short)0x0500, sve.getReason());
    }
    catch(ToolkitException te) {
        setDebug((short)0x0600, te.getReason());
    }
    //
    // add here any other exceptions
    //
    catch(Exception e) {
        setDebug((short)0x0700, (short)0x1111);
    }
}

The displayDebug() method could be implemented like:

/**
* Manage the debug menu selection
*/
private void displayDebug() {
// Get the received envelope
ProactiveHandler proHdlr = ProactiveHandler.getTheHandler();

baStringDebug[(short)0] = bDebug1;
baStringDebug[(short)1] = bDebug2;
baStringDebug[(short)2] = bDebug3;
baStringDebug[(short)3] = bDebug4;
baStringDebug[(short)4] = bDebug5;
baStringDebug[(short)5] = bDebug6;

// Display the "Menu3" message text
// Initialize the display text command
proHdlr.initDisplayText((byte) 0x00
, DCS_8_BIT_DATA
, baStringDebug
, (short) 0
,(short) (baStringDebug.length));
proHdlr.send();

return;
}

Happy debug! :)

9 Nov 2010

Uncaught exception and Status Word (SW) 6F00

Okay, you have developed applet and trying to load to smart card (hereafter I'll call it SIM Card as it is one of particular usage of Smart Card). But on last INSTALL AND MAKE SELECTABLE APDU you've received 6F00 Status Word (SW). 6F00 SW is not documented by any standard and generally means something wrong with the card. But based on my own experience most of the time it isn't card issue.

So what could be reason of 6F00?

Answer is very simple. Uncaught exception in your constructor or in install() method.

Below an example:

import sim.toolkit.*;
import javacard.framework.*;

public class DummyApplet extends javacard.framework.Applet implements
        ToolkitInterface, ToolkitConstants {
    
    private static byte[] RAM_Buffer; 

    /**
     * Constructor of the applet
     */
    public DummyApplet() {
        register(bArray, (short) (bOffset + 1), (byte) bArray[bOffset]);
        ToolkitRegistry.getEntry();

    }

    /**
     * Method called by the JCRE at the installation of the applet
     * @param bArray the byte array containing the AID bytes
     * @param bOffset the start of AID bytes in bArray
     * @param bLength the length of the AID bytes in bArray
     */
    public static void install(byte[] bArray, short bOffset, byte bLength) {
        // Create the Java SIM toolkit applet
        DummyApplet dummyApplet = new DummyApplet();
        // Register this applet
        dummyApplet.register(bArray, (short) (bOffset + 1),
                (byte) bArray[bOffset]);

        short offsetCI = (short) (bOffset + bArray[bOffset] + 1);
        short paramIdx = (short) (offsetCI + bArray[offsetCI] + 1);
        short bufLength = Util.getShort(bArray, paramIdx);         

        RAM_Buffer = JCSystem.makeTransientByteArray(bufLength, JCSystem.CLEAR_ON_RESET);
        
    }
   .....
}


Of course this is really dummy applet but it shows typical JavaCard developers mistake. You have to remember that transient memory (RAM) is very limited on SIM Card and your applet is not alone. Some other applets could already took some part of memory. And probability of getting SystemException.NO_TRANSIENT_SPACE on the line:

RAM_Buffer = JCSystem.makeTransientByteArray(bufLength, JCSystem.CLEAR_ON_RESET);

is very high.

Conclusion: You have to try/catch exceptions in constructor and install() method. If you are allocating some memory buffers check available memory before.

Emacs ELPA and Wanderlust

After installation of Wanderlust in Emacs I’ve recognized that package.el has stopped working with message:

Symbol’s function definition is void: mailcap-parse-mailcaps

I did some investigation and figured out that it is conflict between mailcap.el in FLIM package and mailcap.el in Gnus. The first one is not defining mailcap-parse-mailcaps function.

Quick fix is loading mailcap.el from Gnus manually before FLIM loading:

(load-file "C:/emacs/emacs-24.0.50/lisp/gnus/mailcap.el")



I’m not sure that this is correct solution but it seems work.

F# Survival Guide

The subj is good introduction to F# programming but it is only available online.

I’ve created offline versions to print:

Original text available on the site.