Is anyone can help me out !
For more detail, here is my code, please try and let me know why it don't work on real card if you can.
Many thanks.
Code: Select all
package PTCRecords;
import javacard.framework.*;
public class PTCRecords extends Applet {
// class of instructions
private final static byte CLA = (byte) 0x00;
// instruction codes
private final static byte INS_SELECT = (byte) 0xA4; // select
private final static byte INS_READ_R = (byte) 0xB2; // read record
private final static byte INS_READ_RS = (byte) 0xB3; // read records
// instruction parameters
private final static byte P1_SEL_DF = (byte) 0x04; // select DF
private final static byte P2_SEL_DF = (byte) 0xC0; //
private final static byte P1_SEL_EF = (byte) 0x02; // select EF
private final static byte P2_SEL_EF = (byte) 0xC0; //
private final static byte P1_RD_R16 = (byte) 0x10; // read record #16
private final static byte P1_RD_R8 = (byte) 0x08; // read record #4
private final static byte P1_RD_R5 = (byte) 0x05; // read record #1
private final static byte P2_RD_R = (byte) 0x04; //
private final static byte P1_RD_RS = (byte) 0x00; // read records
private final static byte P2_RD_RS = (byte) 0xFF; //
// EF No.
private final static byte NO_EF0 = (byte) 0x00; // DF
private final static byte NO_EF1 = (byte) 0x01; // EF1
private final static byte NO_EF2 = (byte) 0x02; // EF2
private final static byte NO_EF3 = (byte) 0x03; // EF3
private final static byte NO_EF4 = (byte) 0x04; // EF4
private final static byte NO_EF5 = (byte) 0x05; // EF5
private final static byte NO_EF6 = (byte) 0x06; // EF6
private final static byte NO_EF7 = (byte) 0x07; // EF7
//only for test
private final static short ARRAY_SIZE = 256;
/*
// EF data FID Recordlen MaxRecordNum
private byte [][] dataEF1; // 4001 05 16
private byte [][] dataEF2; // 4002 08 08
private byte [][] dataEF3; // 4003 16 05
private byte [][] dataEF4; // 4004 05 16
private byte [][] dataEF5; // 4005 08 08
private byte [][] dataEF6; // 4006 16 05
private byte [][] dataEF7; // 4007 05 16
*/
private byte[] outBuffer;
// private byte currentEF;
private byte[] currentEF; // hirose 150127
//static byte currentEF;
/**
* Constructor
*/
private PTCRecords(byte[] bArray, short bOffset, byte bLength) {
currentEF = JCSystem.makeTransientByteArray((short)1, JCSystem.CLEAR_ON_DESELECT);
currentEF[0] = NO_EF0; // hirose 150127
// create a transient buffer
outBuffer = new byte[ARRAY_SIZE];
}
public static void install(byte[] bArray, short bOffset, byte bLength)
{
new PTCRecords(bArray, bOffset, bLength).register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
public boolean select() {
return true;
} // select
public void process(APDU apdu) {
//Insert your code here
byte[] buf = apdu.getBuffer();
// the selectingApplet() is used in the applet process method to distinguish
// the SELECT APDU command, which selected this applet, from all other SELECT
// APDU commands. Returns true if this applet is being selected
if (selectingApplet()) {
currentEF[0] = NO_EF0; // hirose 150127
ISOException.throwIt(ISO7816.SW_NO_ERROR);
return;
}
// verify if the applet can accept this APDU message
if (buf[ISO7816.OFFSET_CLA] != CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch (buf[ISO7816.OFFSET_INS]) {
case INS_SELECT:
selectEF(apdu);
break;
case INS_READ_R: // 0xB2: read record
ReadRecord(apdu);
break;
case INS_READ_RS: // 0xB3: read records
//0x00 0xB3 0x00 0xFF
if((buf[ISO7816.OFFSET_P1] == P1_RD_RS)
&& (buf[ISO7816.OFFSET_P2] == P2_RD_RS))
{ // 0x00FF: ReadRecords
ReadRecors(apdu);
} else {
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void selectEF(APDU apdu) {
// select
byte buffer[] = apdu.getBuffer();
currentEF[0] = buffer[ISO7816.OFFSET_CDATA+1];
ISOException.throwIt(ISO7816.SW_NO_ERROR);
}
private void ReadRecord(APDU apdu) {
// ReadRecord
byte buffer[] = apdu.getBuffer();
byte len=0;
byte record=0;
byte cnt=0;
len = buffer[ISO7816.OFFSET_LC];
record = buffer[ISO7816.OFFSET_P1];
switch(currentEF[0]){
case NO_EF1: // EF#1
case NO_EF4: // EF#4
case NO_EF7: // EF#7
if( record > P1_RD_R16){
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
break;
case NO_EF2: // EF#2
case NO_EF5: // EF#5
if( record > P1_RD_R8){
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
break;
case NO_EF3: // EF#3
case NO_EF6: // EF#6
if( record > P1_RD_R5){
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
break;
}
// set data
getData( buffer, (byte)(0), (byte)len , currentEF[0]);
// send data
apdu.setOutgoingAndSend((short) 0, (short) len);
}
private void ReadRecors(APDU apdu) {
byte buffer[] = apdu.getBuffer();
byte lc = 0;
byte idxLen = 0;
byte len = 0;
byte cnt = 0;
if( buffer[ISO7816.OFFSET_CDATA] != 0x53){
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
lc = buffer[ISO7816.OFFSET_LC];
idxLen = buffer[ISO7816.OFFSET_CDATA+1];
if( lc != idxLen+2){
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
for( cnt = 0;cnt<idxLen;cnt+=4){
switch(buffer[(byte)(ISO7816.OFFSET_CDATA+cnt+3)]){
case NO_EF1: // EF#1
case NO_EF4: // EF#4
case NO_EF7: // EF#7
len += 5;
break;
case NO_EF2: // EF#2
case NO_EF5: // EF#5
len += 8;
break;
case NO_EF3: // EF#3
case NO_EF6: // EF#6
len += 16;
break;
}
}
getData( buffer, (byte)(0), (byte)5 , (byte)1);
getData( buffer, (byte)(5), (byte)8 , (byte)2);
getData( buffer, (byte)(5+8), (byte)16 , (byte)3);
getData( buffer, (byte)(5+8+16), (byte)5 , (byte)4);
getData( buffer, (byte)(5*2+8+16), (byte)8 , (byte)5);
getData( buffer, (byte)(5*2+8*2+16), (byte)16 , (byte)6);
getData( buffer, (byte)(5*2+8*2+16*2), (byte)5 , (byte)7);
apdu.setOutgoingAndSend((short)0, (short)6);
}
private void getData( byte buffer[], byte offset, byte len , byte val) {
byte cnt;
for( cnt = offset; cnt < offset + len ; cnt++){
buffer[cnt] = val;
// waits();
}
}
private void waits( ) {
byte i;
for( i=0; i<0x20; i++){
}
}
}