> Odd that this has come up -- I was just looking at Common Lisp and > Scheme implementations, as well as a smattering of Haskellish tools And then there's Haskell... Haskell is like "that girl." You know the one... You never really went steady, but you'd run into her from time to time while knocking around in disreputable joints, usually late at night, every several months or so. She looked so hot, so sleek, so sexy, so expressive, so exotic. You'd end up back at her place and the night would just... take off. A complete blur of hot, sweaty, feverish, delirious, fumbling passion. You'd do things to each other... you'd do things to her, she'd do things to you... things that you're not even sure have names, that you're pretty sure are illegal almost anywhere. Even her kinks have kinks --- and after one of these nights, you'd realize that you yourself had a lot more kinks than you. And it wasn't just physical, it was --- cerebral. Ethereal. Transcendent. But it would all whiz by in a blur, and by morning you'd find yourself lightheaded, a bit confused, and stumbling homeward to your regular gal. Over the next few days and weeks you'd find yourself occasionally drifting away, thinking about her. Haskell. You'd be there, banging away at your regular girl, and find yourself thinking "you know, if I was with Haskell, I'd be doing this completely differently." You'd think "I could be doing so much bigger and better stuff with Haskell." Now, your regular girl, she's not as exotic as Haskell. Pretty, maybe, if you're lucky. (Perhaps your regular girlfriend's name is Python. ;-) But not nearly as --- weird. Wild. Cool. Exciting. Don't get me wrong --- your girl, she's wonderful. You've got a wonderful relationship. She's --- comfortable. You can bang away at her all day and night. She's accommodating. Easy going. You work well together. But --- confidentially --- she's, well, maybe just a little bit boring. You'd catch yourself thinking these things, and the guilty pangs would get to you... You'd quash the thoughts, buckle down, and get back to banging away. Comfortable... there's a lot to be said for that, ya know? Comfortable... just keep telling yourself that. Months would go by. Late some night you'd find yourself out, disreputable places again. Maybe that hacker bar, LtU. Somebody'd slip you an URL for some renegade paper, you know, one of *those* papers. You'd run into Haskell again. And the whole thing starts over. Eventually, you're going to get the ultimatum. Haskell's ultimately just like any other girl on some level; she needs commitment. Eventually, after one night of wild, feverish, kinky, abstract passion, she's going to say to you: "All these times, and you don't understand me at all! You know, you're going to have to get serious, mister! I've got needs, too. You're going to have to get serious about my monads, or that's the last time you're going to play with them! Got it?" ...and then, you've got to make The Choice. Chances are, you're going to go back to your regular gal. Haskell's just too much for any one man, probably. She leaves a trail of broken, brainy, embittered PhDs and former programmers behind her. She ruins you for the RealWorld. You can ride a while, but you probably can't go the distance with her. Go back to your regular gal and try not to think too much about what you've seen. Done. Felt. Thought. Maybe you can salvage a little happiness; but it'll be hard. After all... you've tasted Haskell. She's not like anything else.
Just notes, remarks, tips & tricks about programming, GSM, JavaCard etc.
9 Feb 2011
And then there's Haskell...
27 Jan 2011
How to calculate MIFARE password
The calculation of MIFARE password (MF_password) has described in Philips Application Note AN02105. It is generated based on Key A and Key B as showed below:
As you can see it is 3DES algo. The start value is 8 bytes with value 00h.
The keys DKeyA and DKeyB are derived from MIFARE Key A and Key B keys of respective MIFARE sector. But Key A and Key B are 6 bytes long. To be able to use them as 3DES keys the following conventions have defined:
Representation of the MIFARE Sector Trailer:
Representation of bits of the MIFARE Key (each consists of 6 bytes):
| BYTE 5 MSB | BYTE 4 | BYTE 3 | BYTE 2 | BYTE 1 | BYTE 0 LSB | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| K57 | … | K50 | K47 | … | K40 | K37 | … | K30 | K27 | … | K20 | K17 | … | K10 | K07 | … | K00 |
The 6 bytes MIFARE key will be mapped to the 64 bit 3DES keys DKeyB in the following way:
| DES KEY BYTE | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 |
|---|---|---|---|---|---|---|---|---|
| 7 | K56 | K55 | K54 | K53 | K52 | K51 | K50 | P |
| 6 | K46 | K45 | K44 | K43 | K42 | K41 | K40 | P |
| 5 | K36 | K35 | K34 | K33 | K32 | K31 | K30 | P |
| 4 | K26 | K25 | K24 | K23 | K22 | K21 | K20 | P |
| 3 | K16 | K15 | K14 | K13 | K12 | K11 | K10 | P |
| 2 | K06 | K05 | K04 | K03 | K02 | K01 | K00 | P |
| 1 | 0 | K57 | K47 | K37 | K27 | K17 | K07 | P |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | P |
P in BIT 0 means Parity Bit (not checked).
DKeyA will be generated in the same manner according to below table:
| DES KEY BYTE | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 |
|---|---|---|---|---|---|---|---|---|
| 7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | P |
| 6 | 0 | K07 | K17 | K27 | K37 | K47 | K57 | P |
| 5 | K56 | K55 | K54 | K53 | K52 | K51 | K50 | P |
| 4 | K46 | K45 | K44 | K43 | K42 | K41 | K40 | P |
| 3 | K36 | K35 | K34 | K33 | K32 | K31 | K30 | P |
| 2 | K26 | K25 | K24 | K23 | K22 | K21 | K20 | P |
| 1 | K16 | K15 | K14 | K13 | K12 | K11 | K10 | P |
| 0 | K06 | K05 | K04 | K03 | K02 | K01 | K00 | P |
Some examples:
- Initial value: 00 00 00 00 00 00 00 00
- The DES parity bits are regarded as 0
| MIFARE KEYS (LSB -> MSB) | 3DES KEYS (LSB –> MSB) | MF_PASSWORD (LSB –> MSB) | ||
|---|---|---|---|---|
| Key A | FF FF FF FF FF FF | DKeyA | FE FE FE FE FE FE 7E 00 | 0B 54 57 07 45 FE 3A E7 |
| Key B | FF FF FF FF FF FF | DKeyB | 00 7E FE FE FE FE FE FE | |
| Key A | A0 A1 A2 A3 A4 A5 | DKeyA | 40 42 44 46 48 4A 7E 00 | 8C 7F 46 D7 6C E0 12 66 |
| Key B | B0 B1 B2 B3 B4 B5 | DKeyB | 00 7E 60 62 64 66 68 6A | |
14 Jan 2011
Advanced JavaCard debugging. (The story of one debug)
Well, the problem which I've encountered was the SIM Toolkit (STK) applet with a couple of menu entries. On the real card when you select one of menu entry applet silently exits instead of sending SMS. Checking source code of the applet was not helped. So the only way to debug was loading applet to Software Simulator.
Ok, if no other way, I've compiled the most similar configuration of simulator to real card, created file system, loaded applet. I’ve connected Mobile Phone Simulator to OS Simulator and start browsing menu. When I’ve selected menu item which doesn’t work JCRE log has the following:
// Byte code dump, some part has skippedBy checking the source code of JCRE of the OS I’ve found that “reason 5” is No Resources. Checking available volatile and non volatile memory, it seems there is enough memory. From the dump I couldn’t figure out what was wrong. So no clue!
CAP[1] - 0x4aac11: SAND
CAP[1] - 0x4aac12: SADD
CAP[1] - 0x4aac13: S2B
CAP[1] - 0x4aac14: BASTORE
CAP[1] - 0x4aac15: ALOAD_0
CAP[1] - 0x4aac16: SCONST_5
CAP[1] - 0x4aac17: SCONST_0
CAP[1] - 0x4aac18: INVOKESTATIC [0x1c 0x24]
LIB[7] - 0x4987eb: SCONST_5
LIB[7] - 0x4987ec: SLOAD_0
LIB[7] - 0x4987ed: INVOKESTATIC [0x1c 0x17]
Calling nativeMethod[51] - javacard/security/CryptoException/algorithmCheck(BS)V
0x498802: RETURN - returns: V0x0
LIB[7] - 0x4987f0: NEW [0x1c 0x18]
total number of effective EEPROM writing = 0xbc
total number of requested atomic update = 0x1e6
number EEPROM writing saved thanks NVL = 0x4f6
Exception: VM; SystemException; reason: 5
< INVALID exceptions java.lang for >INTP Exception jump to dispatch loop
total number of effective EEPROM writing = 0xbc
total number of requested atomic update = 0x1e6
number EEPROM writing saved thanks NVL = 0x4f6
Next step to analyze applet bytecode. Fortunately Gemalto Developer Suite has utility called “Cap File Utility”. I dumped applet and searched the exact consequence of commands from dump of JCRE. After a while I found in the applet dump the following:
method_info[8] // @04b4= {
// Some part skipped
/*0f31*/ sand
/*0f32*/ sadd
/*0f33*/ s2b
/*0f34*/ bastore
/*0f35*/ L124: aload_0
/*0f36*/ sconst_5
/*0f37*/ sconst_0
/*0f38*/ invokestatic 57
/*0f3b*/ putfield_a 26
/*0f3d*/ getfield_a_this 26
/*0f3f*/ getfield_a_this 23
/*0f41*/ sload 10
}
Pay attention to /*0f38*/ invokestatic 57. It is last call from the applet before switching to system libraries. So, it has to be something wrong with this call. But how to find what exactly it is calling. Here we have to check Component_Pool from the dump:
.Constant_Pool {So here it is – static method 57. It is referencing to external package. By checking ImportComponent I’ve found the right one. Here I have to mention that 0x84,0x1,0x00 means:
// some part skipped
/* 00e4, 57 */CONSTANT_StaticMethodRef : external: 0x84,0x1,0x0
// some part skipped
}
- 0x84 – is 5th package in ImportComponent section due to numbering starts from 0x80
- 0x1 – is the class number
- 0x0 is method number
.ImportComponent = {Now we know what is AID of the imported package: a0.00.00.00.62.02.01. It is standard package javacardx.security. To figure out what is class 1 and method 0 we have to dump javacrdx.security.exp file. Below is extract from dump:
// some part skipped, it is 5th package due to 1st one has reference 0x80
package_info = {
minor_version : 2
major_version : 1
AID_length : 7
AID : a0.00.00.00.62.02.01
}
// some part skipped }
class_info { // javacardx/crypto/CipherSo now we know which method raises exception. It is getInstance() method of Cipher class. In the source code of the applet getInstance() method has called as follows:
u1 token : 1 <== Class identification number
u2 access_flags : 10000000001b
u2 name_index : 57
u2 export_supers_count : 1
// some parts skipped
export_methods {
method_info { // getInstance
u1 token : 0 <== Method identification number
u2 access_flags : 11001b
u2 name_index : 42
u2 descriptor_index : 43
}
// some parts skipped
}
myCipher = Cipher.getInstance( Cipher.ALG_DES_ECB_NOPAD, false );According to specification JavaCard API:
getInstance
public static final Cipher getInstance(byte algorithm, boolean externalAccess) throws CryptoException
- Creates a
Cipherobject instance of the selected algorithm. -
- Parameters:
algorithm- the desired Cipher algorithm. Valid codes listed in ALG_ .. constants above, for example,ALG_DES_CBC_NOPAD.externalAccess-trueindicates that the instance will be shared among multiple applet instances and that theCipherinstance will also be accessed (via aShareableinterface) when the owner of theCipherinstance is not the currently selected applet. Iftruethe implementation must not allocate CLEAR_ON_DESELECT transient space for internal data.- Returns:
- the
Cipherobject instance of the requested algorithm - Throws:
CryptoException- with the following reason codes:CryptoException.NO_SUCH_ALGORITHMif the requested algorithm is not supported or shared access mode is not supported.
- Parameters:
Et Voila! Issue is in externalAccess. We have to set it true, as STK applets are not explicitly selected applets by SELECT APPLICATION. They are triggered by SIM Toolkit Events.
So, changing to true externalAccess parameter has solved issue.
5 Jan 2011
LTE Basics
I’ve found the good introduction to LTE from network perspective. Enjoy.
10 Dec 2010
How to access to MIFARE memory
It specifies MemoryAccess interface and Memory class.
oMemAccess = Memory.getMemoryAccessInstance(Memory.MEMORY_TYPE_MIFARE
, null
, (short)0);
Memory.getMemoryAccessInstance() method has the following parameters:
- memoryType - the desired external memory subsystem. Could be MEMORY_TYPE_MIFARE or MEMORY_TYPE_EXTENDED_STORE.
- memorySize - the array containing the desired size in bytes, if applicable, in the external memory subsystem. This parameter is ignored for MIFARE memory type.
- memorySizeOffset - the offset within the memorySize array where the 32 bit memory size number in bytes is specified. This parameter is ignored.
oMemAccess.writeData(
dataToWrite // the source data byte array
, (short) 0 // the byte offset in data buffer
, (short) dataToWrite.length // the length of data
, thisCardPwdArray // the byte array containing the
// key (password)
, (short)0 // the byte offset into the key
// array where the key data begins
, (short) thisCardPwdArray.length // the length in bytes of key
, (short) (blocknum / 4) // sector number
, blocknum) // block number
- Absolute mode where block number accepts values 0..63 and sector number will be ignored.
- Relative mode where block number accepts values 0..4 and sector number must be correctly set according to MIFARE memory layout.
oMemAccess.readData(
readBuf // destination buffer
, (short) 0 // offset in destination buffer
, thisCardPwdArray // key (password) array
, (short)0 // offset in key array
, (short) thisCardPwdArray.length // key length
, (short)secnum // sector number
, (short)blocknum // block number
, DATA_LEN) // number of bytes to read
All parameters have the same meaning as in writeData() method.
One additional remark: if the password to access MIFARE memory is incorrect there is no retry mechanism. You have to start from the beginning. The reason why it has implemented like that is absence of key counter like in PIN key.
3 Dec 2010
Usage of dynamic/diversified data during applet installation
But first let me explain what is dynamic/diversified data is. It is pretty simple. If you are reading some file during applet installation and this file content is different from one card to another you are using dynamic data. As an example of such kind of data could be ICCID or IMSI of the card. The diversified data is the kind of data in the file where you have some master key and for each card you have some generation mechanism which will guarantee uniqueness of each card.
Okay, I do hope it is clear what is dynamic/diversified data is. Now back to the subject of this post. The main message of it is:
Do not use any dynamic/diversified data during your applet installation!
Now let me explain why. Most of the (if not all) SmartCard manufacturers are not using regular APDU commands to personalize each card as it is time consuming. Just imagine how much time it will take to produce card by creation of each file with CREATE FILE APDU and then to update its content by UPDATE BINARY/UPDATE RECORD APDU commands if your speed limited with PPS. As each command involves SmartCard Operating System to treat it, to verify all security conditions, to perform required operation. When you have to produce millions of cards per day it is unacceptable. This is why the card production process was splitted to 2 stages:
- Master card creation
- Daughter card creation
Master card was created only once for each type of the SmartCard profile and for its creation regular APDU commands were used. Afterwards by special mechanism all dynamic parts which are specific for each card were determined and separated from static part and card memory dumped.
Then for daughter card creation (these is actually cards which will be produced in larges amount) this memory dump is used i.e. instead of sending each APDU command one by one and pushing OS to treat them, production writes directly to card memory. And then the small part which is unique for the each card will be personalized by regular APDU. That is much faster.
And if you use dynamic data during applet installation it will force your applet installation command to move to dynamic part which is slowing down production process. Moreover it is quite difficult to recognize if your applet is really using dynamic data. If it is just reads it to store inside the applet, the automatic mechanism of detection may not trigger, because memory will be the same. It means if by automatic mechanism your applet is considered as static, your applet will get incorrect data as static part is located before dynamic part.
So, what is the solution if you really need to use dynamic data? Implement it other way round:
- Post process personalization of the applet by special commands
- Get necessary information in runtime
- etc.
22 Nov 2010
How mobile phone and SIM card setup connection or why sometime mobile phone rejects SIM Card?
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:
- Cold Reset (RST)
- SIM Card answers ATR (Answer-to-Reset)
- PPS negotiation
- Data exchange
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:
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:
| 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 | - | - |
| 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 |
- 9 = b1001 –> Fi = 512 (from the Table 7)
- 6 = b0110 –> Di = 32 (from the Table 8)
The minimum delay between two characters has to be 12 etu i.e.:
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:
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
- 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
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.





