| |
"Writing Java Card Applications"
Vol. 9, Issue 9, p. 44
Listing 1
1 package com.vsp.eperson.javacard.applets;
2
3 // AID: 0x01:0x02:0x03:0x04:0x06: 0x0a:0x0b:0x00
4
5 import javacard.framework.*;
6
7 /**
8 * @author Vijay Phagura
9 */
10 public class EPersonApplet extends Applet
11 {
12 // Applet AID: 0x01:0x02:0x03:0x04:0x06: 0x0a:0x0b:0x01
13 // Cmds
14 final static byte CLA = ( byte )0xB0; // CLA
15
16 // Read only cmds
17 final static byte GET_EMPID = ( byte )0x01; // INS
18 final static byte GET_FIRST_NAME = ( byte )0x02; // INS
19 final static byte GET_LAST_NAME = ( byte )0x03; // INS
20 final static byte GET_ALL_INFO = ( byte )0x04; // INS
21
22 // Update cmds
23 final static byte GET_CARD_STATUS = ( byte )0x05; // INS
24 final static byte GET_AMOUNT_DUE = ( byte )0x06; // INS
25 final static byte GET_ALLOWANCE = ( byte )0x07; // INS
26
27 final static byte SET_CARD_STATUS = ( byte )0x08; // INS
28 final static byte SET_AMOUNT_DUE = ( byte )0x09; // INS
29 final static byte SET_ALLOWANCE = ( byte )0x0a; // INS
30
31 // Constants
32 final static short MAX_ID_SIZE = ( short )5;
33 final static short MAX_NAME_SIZE = ( short )10;
34 final static short MAX_AMOUNT_SIZE = ( short )2;
35 final static short MAX_ALLOW_SIZE = ( short )1;
36 final static short All_INFO_SIZE = MAX_ID_SIZE +
37 ( 2 * MAX_NAME_SIZE ) +
38 MAX_AMOUNT_SIZE +
39 MAX_ALLOW_SIZE;
40
41 // Fields
42 byte[] empId = null;
43 byte[] firstName = null;
44 byte[] lastName = null;
45 byte[] allInfo = null;
46
47 boolean active = false; // Card status
48 short amount = 0; // Amount due in dollars
49 byte allow = 0; // Days allowed to pay the dues
50
51
52 /**
53 * Initializes all fields of this applet.
54 *
55 * Example Input:-
56 * EMPID: T1024 = 0x54 0x31 0x30 0x32 0x34
57 * FNAME: John = 0x4a 0x6f 0x68 0x6e 0x00 0x00 0x00 0x00 0x00 0x00
58 * LNAME: Smith = 0x53 0x6d 0x69 0x74 0x68 0x00 0x00 0x00 0x00 0x00
59 * AMOUNT: 257 = 0x01 0x01
60 * ALLOW: 5 = 0x05
61 *
62 * input: 54313032344a6f686e000000000000536d6974680000000000010105
63 * length: 28 bytes(0x1c)
64 *
65 * @param bArray
66 * @param bOffset
67 * @param bLength
68 */
69 private EPersonApplet( byte[] bArray, short bOffset, byte bLength )
70 {
71
72 allInfo = new byte[ All_INFO_SIZE ];
73 empId = new byte[ MAX_ID_SIZE ];
74 firstName = new byte[ MAX_NAME_SIZE ];
75 lastName = new byte[ MAX_NAME_SIZE ];
76 active = true;
77
78 byte[] tmp = new byte[ 2 ];
79 short offset = ( short )( bOffset + bArray[bOffset] + 4 ); // AID+4
bytes
80 Util.arrayCopyNonAtomic( bArray, offset, allInfo, ( short )0,
All_INFO_SIZE );
81 Util.arrayCopyNonAtomic( bArray, offset, empId, ( short )0, MAX_ID_SIZE
);
82 offset += MAX_ID_SIZE;
83 Util.arrayCopyNonAtomic( bArray, offset, firstName, ( short )0,
MAX_NAME_SIZE );
84 offset += MAX_NAME_SIZE;
85 Util.arrayCopyNonAtomic( bArray, offset, lastName, ( short )0,
MAX_NAME_SIZE );
86 offset += MAX_NAME_SIZE;
87 Util.arrayCopyNonAtomic( bArray, offset, tmp, ( short )0,
MAX_AMOUNT_SIZE );
88 offset += MAX_AMOUNT_SIZE;
89 amount = ( short )( ( tmp[ 1 ] << 8 ) | (tmp[ 0 ] & 0xFF));
90
91 Util.arrayCopyNonAtomic( bArray, offset, tmp, ( short )0, MAX_ALLOW_SIZE );
92 offset += MAX_ALLOW_SIZE;
93 allow = tmp[ 0 ];
94
95 register();
96 }
97
98 /**
99 * Installs a new instance of this applet and passes the input to the applet
constructor
100 *
101 * @param bArray
102 * @param bOffset
103 * @param bLength
104 */
105 public static void install( byte[] bArray, short bOffset, byte bLength )
106 {
107 new EPersonApplet( bArray, bOffset, bLength );
108 }
109
110 /**
111 * The process method which processes all cmds.
112 *
113 * @param apdu
114 * @throws ISOException
115 */
116 public void process( APDU apdu ) throws ISOException
117 {
118 byte[] buffer = apdu.getBuffer();
119
120 if ( selectingApplet() )
121 {
122 return;
123 }
124 else if ( buffer[ ISO7816.OFFSET_CLA ] != CLA )
125 {
126 ISOException.throwIt( ISO7816.SW_CLA_NOT_SUPPORTED );
127 }
128
129 switch ( buffer[ ISO7816.OFFSET_INS ] )
130 {
131 case GET_EMPID:
132 getEmpId( apdu );
133 return;
134 case GET_FIRST_NAME:
135 getFirstName( apdu );
136 return;
137 case GET_LAST_NAME:
138 getLastName( apdu );
139 return;
140 case GET_ALL_INFO:
141 getAllInfo( apdu );
142 return;
143 case GET_CARD_STATUS:
144 getCardStatus( apdu );
145 return;
146 case GET_AMOUNT_DUE:
147 getAmountDue( apdu );
148 return;
149 case GET_ALLOWANCE:
150 getAllowance( apdu );
151 return;
152 case SET_CARD_STATUS:
153 setCardStatus( apdu );
154 return;
155 case SET_AMOUNT_DUE:
156 setAmountDue( apdu );
157 return;
158 case SET_ALLOWANCE:
159 setAllowance( apdu );
160 return;
161 default:
162 ISOException.throwIt( ISO7816.SW_INS_NOT_SUPPORTED );
163 }
164 }
165
166 private void setAllowance( APDU apdu )
167 {
168 byte[] buffer = apdu.getBuffer();
169 byte cnt = ( byte )apdu.setIncomingAndReceive();
170 if ( cnt != 1 )
171 {
172 ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
173 }
174 byte tmp = buffer[ ISO7816.OFFSET_CDATA ];
175 allow = tmp;
176 }
177
178 private void setAmountDue( APDU apdu )
179 {
180 byte[] buffer = apdu.getBuffer();
181 byte cnt = ( byte )apdu.setIncomingAndReceive();
182 if ( cnt != 2 )
183 {
184 ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
185 }
186 byte[] tmp = new byte[ MAX_AMOUNT_SIZE ];
187 Util.arrayCopy( buffer, ISO7816.OFFSET_CDATA, tmp, ( short )0,
MAX_AMOUNT_SIZE );
188 amount = ( short )( ( tmp[ 1 ] << 8 ) | (tmp[ 0 ] & 0xFF) );
189 }
190
191 private void setCardStatus( APDU apdu )
192 {
193 byte[] buffer = apdu.getBuffer();
194 byte cnt = ( byte )apdu.setIncomingAndReceive();
195 if ( cnt != 1 )
196 {
197 ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
198 }
199 byte tmp = buffer[ ISO7816.OFFSET_CDATA ];
200 active = ( tmp == 1 ) ? true : false;
201 }
202
203 private void getAllowance( APDU apdu )
204 {
205 byte[] buffer = apdu.getBuffer();
206
207 byte[] st = new byte[ MAX_ALLOW_SIZE ];
208 st[ 0 ] = allow;
209
210 Util.arrayCopy( st, ( short )0, buffer, ( short )0, MAX_ALLOW_SIZE );
211 apdu.setOutgoingAndSend( ( short ) 0, MAX_ALLOW_SIZE);
212
213 }
214
215 private void getAmountDue( APDU apdu )
216 {
217 byte[] buffer = apdu.getBuffer();
218
219 byte[] st = new byte[ MAX_AMOUNT_SIZE ];
220 st[ 0 ] = ( byte )( amount & 0xff );
221 short tmp = ( short )( amount >> 8 );
222 st[ 1 ] = ( byte )( tmp & 0xff );
223
224 Util.arrayCopy( st, ( short )0, buffer, ( short )0, MAX_AMOUNT_SIZE );
225 apdu.setOutgoingAndSend( ( short ) 0, MAX_AMOUNT_SIZE);
226
227 }
228
229 private void getCardStatus( APDU apdu )
230 {
231 byte[] buffer = apdu.getBuffer();
232 byte[] st = new byte[ MAX_ALLOW_SIZE ];
233 st[ 0 ] = ( byte )( ( active == true ) ? 0x01 : 0x00 );
234 Util.arrayCopy( st, ( short )0, buffer, ( short )0, MAX_ALLOW_SIZE );
235 apdu.setOutgoingAndSend( ( short )0, MAX_ALLOW_SIZE );
236 }
237
238 private void getAllInfo( APDU apdu )
239 {
240 byte[] buffer = apdu.getBuffer();
241 short offset = 0;
242 // EmpId
243 Util.arrayCopy( empId, ( short )0, buffer, offset, MAX_ID_SIZE );
244 offset += MAX_ID_SIZE;
245 // First Name
246 Util.arrayCopy( firstName, ( short )0, buffer, offset, MAX_NAME_SIZE );
247 offset += MAX_NAME_SIZE;
248 // Last Name
249 Util.arrayCopy( lastName, ( short )0, buffer, offset, MAX_NAME_SIZE );
250 offset += MAX_NAME_SIZE;
251 // Amount Due
252 byte[] st = new byte[ MAX_AMOUNT_SIZE ];
253 st[ 0 ] = ( byte )( amount & 0xff );
254 short tmp = ( short )( amount >> 8 );
255 st[ 1 ] = ( byte )( tmp & 0xff );
256 Util.arrayCopy( st, ( short )0, buffer, offset, MAX_AMOUNT_SIZE );
257 offset += MAX_AMOUNT_SIZE;
258 // Allowance
259 st[0] = allow;
260 Util.arrayCopy( st, ( short )0, buffer, offset, MAX_ALLOW_SIZE );
261 offset += MAX_ALLOW_SIZE;
262
263 apdu.setOutgoingAndSend( ( short )0, All_INFO_SIZE );
264 }
265
266 private void getLastName( APDU apdu )
267 {
268 byte[] buffer = apdu.getBuffer();
269 Util.arrayCopy( lastName, ( short )0, buffer, ( short )0, MAX_NAME_SIZE
);
270 apdu.setOutgoingAndSend( ( short )0, MAX_NAME_SIZE );
271 }
272
273 private void getFirstName( APDU apdu )
274 {
275 byte[] buffer = apdu.getBuffer();
276 Util.arrayCopy( firstName, ( short )0, buffer, ( short )0,
MAX_NAME_SIZE );
277 apdu.setOutgoingAndSend( ( short )0, MAX_NAME_SIZE );
278 }
279
280 private void getEmpId( APDU apdu )
281 {
282 byte[] buffer = apdu.getBuffer();
283 Util.arrayCopy( empId, ( short )0, buffer, ( short )0, MAX_ID_SIZE );
284 apdu.setOutgoingAndSend( ( short )0, MAX_ID_SIZE );
285 }
286 }
Listing 2
-classdir C:\prgs\egate\classes
-out EXP JCA CAP
-exportpath C:\jc211\api21
-applet 0x01:0x02:0x03:0x04:0x06:0x0a:0x0b:0x01
com.vsp.eperson.javacard.applets.EPersonApplet
com.vsp.eperson.javacard.applets
0x01:0x02:0x03:0x04:0x06:0x0a:0x0b:0x00 1.0
Listing 3
com.sun.javacard.installer.InstallerApplet
0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0x8:0x1
com.vsp.eperson.javacard.applets.EPersonApplet
0x01:0x02:0x03:0x04:0x06:0x0a:0x0b:0x01
Listing 4
powerup;
// Select the installer applet
0x00 0xA4 0x04 0x00 0x09 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F;
// 90 00 = SW_NO_ERROR
// begin installer command
0x80 0xB0 0x00 0x00 0x00 0x7F;
// create EPersonApplet
0x80 0xB8 0x00 0x00 0x19 0x08 0x01 0x02 0x03 0x04 0x06 0x0a 0x0b 0x01 0x0f 0x54
0x31 0x4a 0x6f 0x68 0x6e 0x00 0x53 0x6d 0x69 0x74 0x68 0x01 0x01 0x05 0x00;
// end installer command
0x80 0xBA 0x00 0x00 0x00 0x7F;
// Select EPersonApplet
0x00 0xa4 0x04 0x00 0x08 0x01 0x02 0x03 0x04 0x06 0x0a 0x0b 0x01 0x00;
//Send GET_EMPID cmd
0xb0 0x01 0x00 0x00 0x00 0x00;
//Send GET_FIRST_NAME cmd
0xb0 0x02 0x00 0x00 0x00 0x00;
//Send GET_LAST_NAME cmd
0xb0 0x03 0x00 0x00 0x00 0x00;
//Send GET_ALL_INFO cmd
0xb0 0x04 0x00 0x00 0x00 0x00;
//Send GET_CARD_STATUS cmd
0xb0 0x05 0x00 0x00 0x00 0x00;
//Send GET_AMOUNT cmd
0xb0 0x06 0x00 0x00 0x00 0x00;
//Send GET_ALLOWANCE cmd
0xb0 0x07 0x00 0x00 0x00 0x00;
//Send SET_CARD_STATUS cmd
0xb0 0x08 0x00 0x00 0x01 0x00 0x00;
//Send GET_CARD_STATUS cmd
0xb0 0x05 0x00 0x00 0x00 0x00;
//Send SET_AMOUNT cmd
0xb0 0x09 0x00 0x00 0x02 0x02 0x11 0x00;
//Send GET_AMOUNT cmd
0xb0 0x06 0x00 0x00 0x00 0x00;
//Send GET_INSTALL_DATA cmd
0xb0 0x0b 0x00 0x00 0x00 0x00;
// *** SCRIPT END ***
powerdown;
Listing 5
Java Card 2.1.1 ApduTool (version 1.1)
Copyright (c) 2000 Sun Microsystems, Inc. All rights reserved.
Opening connection to localhost on port 9,025.
Connected.
CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 09, a0, 00, 00, 00, 62, 03, 01, 08, 01, Le:
00, SW1: 90, SW2: 00
CLA: 80, INS: b0, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00
CLA: 80, INS: b8, P1: 00, P2: 00, Lc: 19, 08, 01, 02, 03, 04, 06, 0a, 0b, 01, 0f,
54, 31, 4a, 6f, 68, 6e, 00, 53, 6d, 69, 74, 68, 01, 01, 05, Le: 08, 01, 02, 03,
04, 06, 0a, 0b, 01, SW1: 90, SW2: 00
CLA: 80, INS: ba, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00
CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 08, 01, 02, 03, 04, 06, 0a, 0b, 01, Le: 00,
SW1: 90, SW2: 00
CLA: b0, INS: 01, P1: 00, P2: 00, Lc: 00, Le: 02, 54, 31, SW1: 90, SW2: 00
CLA: b0, INS: 02, P1: 00, P2: 00, Lc: 00, Le: 05, 4a, 6f, 68, 6e, 00, SW1: 90, SW2:
00
CLA: b0, INS: 03, P1: 00, P2: 00, Lc: 00, Le: 05, 53, 6d, 69, 74, 68, SW1: 90, SW2:
00
CLA: b0, INS: 04, P1: 00, P2: 00, Lc: 00, Le: 0f, 54, 31, 4a, 6f, 68, 6e, 00, 53,
6d, 69, 74, 68, 01, 01, 05, SW1: 90, SW2: 00
CLA: b0, INS: 05, P1: 00, P2: 00, Lc: 00, Le: 01, 01, SW1: 90, SW2: 00
CLA: b0, INS: 06, P1: 00, P2: 00, Lc: 00, Le: 02, 01, 01, SW1: 90, SW2: 00
CLA: b0, INS: 07, P1: 00, P2: 00, Lc: 00, Le: 01, 05, SW1: 90, SW2: 00
CLA: b0, INS: 08, P1: 00, P2: 00, Lc: 01, 00, Le: 00, SW1: 90, SW2: 00
CLA: b0, INS: 05, P1: 00, P2: 00, Lc: 00, Le: 01, 00, SW1: 90, SW2: 00
CLA: b0, INS: 09, P1: 00, P2: 00, Lc: 02, 02, 11, Le: 00, SW1: 90, SW2: 00
CLA: b0, INS: 06, P1: 00, P2: 00, Lc: 00, Le: 02, 02, 11, SW1: 90, SW2: 00
CLA: b0, INS: 0b, P1: 00, P2: 00, Lc: 00, Le: 11, 54, 31, 4a, 6f, 68, 6e, 00, 53,
6d, 69, 74, 68, 01, 01, 05, 0f, 0f, SW1: 90, SW2: 00
Listing 6
1 package com.vsp.eperson.javacard.clientside;
2
3 import slb.iop.*;
4
5 /**
6 * @author Vijay Phagura
7 */
8 public class CardProxy implements slb.iop.IOPListener
9 {
10 // Cmds
11 private final static byte CLA = ( byte ) 0xB0; // CLA
12
13 // Read only cmds
14 private final static byte GET_EMPID = ( byte ) 0x01; // INS
15 private final static byte GET_FIRST_NAME = ( byte ) 0x02; // INS
16 private final static byte GET_LAST_NAME = ( byte ) 0x03; // INS
17 private final static byte GET_ALL_INFO = ( byte ) 0x04; // INS
18
19 // Update cmds
20 private final static byte GET_CARD_STATUS = ( byte ) 0x05; // INS
21 private final static byte GET_AMOUNT_DUE = ( byte ) 0x06; // INS
22 private final static byte GET_ALLOWANCE = ( byte ) 0x07; // INS
23
24 private final static byte SET_CARD_STATUS = ( byte ) 0x08; // INS
25 private final static byte SET_AMOUNT_DUE = ( byte ) 0x09; // INS
26 private final static byte SET_ALLOWANCE = ( byte ) 0x0a; // INS
27
28 // Constants
29 private final short[] AID = {0x01, 0x02, 0x03, 0x04, 0x06, 0x0a, 0x0b,
0x01};
30 private final short[] MAC = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F};
31 private final short[] AUTH = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F};
32 private final short[] KEK = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F};
33
34 private final static short MAX_ID_SIZE = ( short ) 5;
35 private final static short MAX_NAME_SIZE = ( short ) 10;
36 private final static short MAX_AMOUNT_SIZE = ( short ) 2;
37 private final static short MAX_ALLOW_SIZE = ( short ) 1;
38 private final static short All_INFO_SIZE = MAX_ID_SIZE + ( 2 * MAX_NAME_SIZE
) + MAX_AMOUNT_SIZE + MAX_ALLOW_SIZE;
39
40
41 // Fields
42 private boolean connected = false;
43 private boolean errorFlag = false;
44 private SmartCard card = null;
45 private String cardReaderName = null;
46 private String error = null;
47
48 // Static Fields
49 private static IOP sIOP = null;
50
51 static
52 {
53 System.loadLibrary( "slbjiop3" );
54
55 sIOP = new IOP();
56 }
57
58
59 public CardProxy( String readerName )
60 {
61 if(sIOP == null) sIOP = new IOP();
62
63 cardReaderName = readerName;
64 card = new SmartCard();
65
66 sIOP.addIOPListener( this );
67
68 // Try to connect if the card is in the reader
69 connect();
70 }
71
72 public String getCardReaderName()
73 {
74 return cardReaderName;
75 }
76
77 public void setCardReaderName( String cardReaderName )
78 {
79 this.cardReaderName = cardReaderName;
80 }
81
82 // Card listener callback operations
83 public void CardRemoved( slb.iop.IOPEvent event )
84 {
85 disconnect();
86 }
87
88 public void CardInserted( slb.iop.IOPEvent event )
89 {
90 connect();
91 }
92
93 public void ReaderRemoved( slb.iop.IOPEvent event )
94 {
95 CardRemoved( event );
96 }
97
98 public void ReaderInserted( slb.iop.IOPEvent event )
99 {
100 CardInserted( event );
101 }
102
103 // House keeping operations
104 public boolean isConnected()
105 {
106 return connected;
107 }
108
109 public boolean isError()
110 {
111 return errorFlag;
112 }
113
114 public String getErrorString()
115 {
116 errorFlag = false;
117 return error;
118 }
119
120 public void disconnect()
121 {
122 sIOP.Disconnect( card);
123 connected = false;
124 }
125
126 public boolean connect()
127 {
128 try
129 {
130 if ( sIOP.Connect( card, cardReaderName ) )
131 {
132 Thread.sleep( 500 );
133
134 if ( card.EstablishSecureChannel( MAC, AUTH, KEK ) )
135 {
136 if ( card.SelectAID( AID ) )
137 {
138 connected = true;
139 }
140 else
141 {
142 System.out.println( "Could not SELECT Application!" );
143 setError();
144 }
145 }
146 else
147 {
148 System.out.println( "Could not ESTABLISH secure channel!"
);
149 setError();
150 }
151 }
152 else
153 {
154 System.out.println( "Could not CONNECT to card!" );
155 setError();
156 }
157 }
158 catch ( slbException e )
159 {
160 e.printStackTrace();
161 }
162 catch ( InterruptedException e )
163 {
164 }
165
166 return connected;
167 }
168
169 // Cmds
170 public String getEmployeeId() throws slbException
171 {
172 int[] in = new int[ 0 ];
173 short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_EMPID & 0xFF ),
0, 0, in, ( int ) MAX_ID_SIZE );
174 setError();
175
176 byte[] bytes = new byte[ out.length ];
177 for ( int i = 0; i < out.length; i++ )
178 {
179 bytes[ i ] = ( byte ) out[ i ];
180 }
181
182 return new String( bytes );
183 }
184
185 public String getFirstName() throws slbException
186 {
187 int[] in = new int[ 0 ];
188 short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_FIRST_NAME &
0xFF ), 0, 0, in, MAX_NAME_SIZE );
189 setError();
190
191 byte[] bytes = new byte[ out.length ];
192 for ( int i = 0; i < out.length; i++ )
193 {
194 bytes[ i ] = ( byte ) out[ i ];
195 }
196
197 return new String( bytes ).trim();
198 }
199
200 public String getLastName() throws slbException
201 {
202 int[] in = new int[ 0 ];
203 short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_LAST_NAME & 0xFF
), 0, 0, in, MAX_NAME_SIZE );
204 setError();
205
206 byte[] bytes = new byte[ out.length ];
207 for ( int i = 0; i < out.length; i++ )
208 {
209 bytes[ i ] = ( byte ) out[ i ];
210 }
211
212 return new String( bytes ).trim();
213 }
214
215 public Employee getAllInfo() throws slbException
216 {
217 int[] in = new int[ 0 ];
218 short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_ALL_INFO & 0xFF
), 0, 0, in, All_INFO_SIZE );
219 setError();
220
221 byte[] bytes = new byte[ out.length ];
222 for ( int i = 0; i < out.length; i++ )
223 {
224 bytes[ i ] = ( byte ) out[ i ];
225 }
226
227 int offset = 0;
228 // Get Emp ID
229 byte[] empId = new byte[ MAX_ID_SIZE ];
230 System.arraycopy( bytes, offset, empId, 0, MAX_ID_SIZE );
231 offset += MAX_ID_SIZE;
232
233 // Get First Name
234 byte[] fName = new byte[ MAX_NAME_SIZE ];
235 System.arraycopy( bytes, offset, fName, 0, MAX_NAME_SIZE );
236 offset += MAX_NAME_SIZE;
237
238 // Get Last Name
239 byte[] lName = new byte[ MAX_NAME_SIZE ];
240 System.arraycopy( bytes, offset, lName, 0, MAX_NAME_SIZE );
241 offset += MAX_NAME_SIZE;
242
243 // Get Amount
244 byte[] amt = new byte[ MAX_AMOUNT_SIZE ];
245 System.arraycopy( bytes, offset, amt, 0, MAX_AMOUNT_SIZE );
246 offset += MAX_AMOUNT_SIZE;
247
248 // Get Allowed Days to pay
249 byte[] dys = new byte[ MAX_ALLOW_SIZE ];
250 System.arraycopy( bytes, offset, dys, 0, MAX_ALLOW_SIZE );
251
252 // Converting
253 String id = new String( empId ).trim();
254 String firstName = new String( fName ).trim();
255 String lastName = new String( lName ).trim();
256 int amount = ( ( amt[ 0 ] << 8 ) | ( amt[ 1 ] & 0xFF ) );
257 int allow = ( dys[ 0 ] & 0xff );
258 int empType = ( id.startsWith( "T" ) ) ? Employee.TEMPORARY_EMPLOYEE :
Employee.PERMANENT_EMPLOYEE;
259
260 return new Employee( id, firstName, lastName, amount, allow, empType );
261 }
262
263 public boolean getCardStatus() throws slbException
264 {
265 int[] in = new int[ 0 ];
266 short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_CARD_STATUS &
0xFF ), 0, 0, in, 1 );
267 setError();
268
269 byte active = 0;
270 active = ( byte ) out[ 0 ];
271
272 return ( active == 1 ) ? true : false;
273 }
274
275 public short getAmountDue() throws slbException
276 {
277 int[] in = new int[ 0 ];
278 short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_AMOUNT_DUE &
0xFF ), 0, 0, in, MAX_AMOUNT_SIZE );
279 setError();
280
281 byte[] bytes = new byte[ out.length ];
282 for ( int i = 0; i < out.length; i++ )
283 {
284 bytes[ i ] = ( byte ) ( out[ i ] & 0xff );
285 }
286
287 return ( short ) ( ( bytes[ 0 ] << 8 ) | ( bytes[ 1 ] & 0xFF ) );
288 }
289
290 public short getAllowedDaysToPay() throws slbException
291 {
292 int[] in = new int[ 0 ];
293 short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_ALLOWANCE & 0xFF
), 0, 0, in, 1 );
294 setError();
295
296 return out[ 0 ];
297 }
298
299 public void setCardStatus( boolean stat ) throws slbException
300 {
301 int[] in = new int[ 1 ];
302 in[ 0 ] = ( stat == true ) ? 0x01 : 0x00;
303 card.SendCardAPDU( ( CLA & 0xFF ), ( SET_CARD_STATUS & 0xFF ), 0, 0,
in, 0 );
304 setError();
305 }
306
307 public void setAmountDue( short amt ) throws slbException
308 {
309 int[] in = new int[ 2 ];
310 in[ 1 ] = amt & 0xff;
311 amt = ( short ) ( amt >> 8 );
312 in[ 0 ] = amt & 0xff;
313
314 card.SendCardAPDU( ( CLA & 0xFF ), ( SET_AMOUNT_DUE & 0xFF ), 0, 0, in,
0 );
315 setError();
316 }
317
318
319 public void setAllowanceDays( short dys ) throws slbException
320 {
321 int[] in = new int[ 1 ];
322 in[ 0 ] = dys & 0xff;
323
324 card.SendCardAPDU( ( CLA & 0xFF ), ( SET_ALLOWANCE & 0xFF ), 0, 0, in,
0 );
325 setError();
326 }
327
328 // Static operations
329 public static String[] ListReaders()
330 {
331 String[] readers = sIOP.ListReaders();
332 return readers;
333 }
334
335 // Private operations
336 private void setError()
337 {
338 int iErrorCode = card.GetLastErrorCode();
339 if ( iErrorCode != 0x9000 )
340 {
341 error = card.GetErrorMessage();
342 errorFlag = true;
343 }
344 }
345
346
347 }
Listing 7
1 package com.vsp.eperson.javacard.clientside;
2
3 import java.util.Date;
4
5 /**
6 * @author Vijay Phagura
7 */
8 public class Employee
9 {
10 private String empId = null;
11 private String firstName = null;
12 private String lastName = null;
13 private Date startDate = new Date();
14 private Date endDate = new Date();
15 private int amountSpentToDate = 0;
16 private int amountDue = 0;
17 private int allowedDaysToPay = 0;
18 private int empType = 0;
19 private String closeReason = null;
20
21 // Constants
22 public final static int NONEMPLOYEE = 0;
23 public final static int PERMANENT_EMPLOYEE = 1;
24 public final static int TEMPORARY_EMPLOYEE = 2;
25 public final static String[] strEmpType = {"NONEMPLOYEE",
26 "PERMANENT_EMPLOYEE",
27 "TEMPORARY_EMPLOYEE"
28 };
29 :
30 :
31 :
32 :
33 :
34 :
35 }
Listing 8
1 package com.vsp.eperson.javacard.clientside;
2
3 import slb.iop.slbException;
4
5 import javax.swing.*;
6
7 /**
8 * @author Vijay Phagura
9 */
10 public class Viewer extends JApplet
11 {
12 private CardProxy card = null;
13 private String[] readerList = null;
14
15 public Viewer()
16 {
17 readerList = CardProxy.ListReaders();
18 card = new CardProxy(readerList[0]);
19 }
20
21
22 public static void main( String[] args )
23 {
24 Viewer vw = new Viewer();
25
26
27 // Wait for connection
28 while(true)
29 {
30 try
31 {
32 Thread.sleep( 100 );
33 System.out.print( "." );
34
35 if(vw.card.isError() )
36 {
37 System.out.println( "Error: " + vw.card.getErrorString());
38 }
39
40 if(!vw.card.isConnected())
41 {
42 continue;
43 }
44 else
45 {
46 // Gets
47 System.out.println( "\nEmpId: " + vw.card.getEmployeeId() );
48 System.out.println( "First Name: " + vw.card.getFirstName()
);
49 System.out.println( "Last Name: " + vw.card.getLastName() );
50 System.out.println( "Card Status: " +
vw.card.getCardStatus() );
51 System.out.println( "Amount Due: " + vw.card.getAmountDue() );
52 System.out.println( "Days Left to Pay: " +
vw.card.getAllowedDaysToPay() );
53
54 // Get all info
55 Employee emp = vw.card.getAllInfo();
56 System.out.println( "Employee: " + emp );
57
58 // Sets
59 vw.card.setAmountDue(( short ) 513);
60 System.out.println( "Amount Due: " + vw.card.getAmountDue()
);
61
62 vw.card.setAllowanceDays( ( short ) 10);
63 System.out.println( "Days Left to Pay: " +
vw.card.getAllowedDaysToPay() );
64 vw.card.setCardStatus(false);
65 System.out.println( "Card Status: " +
vw.card.getCardStatus() );
66
67 vw.card.setCardStatus(true);
68 System.out.println( "Card Status: " +
vw.card.getCardStatus() );
69
70 vw.card.disconnect();
71 System.exit( 0);
72 }
73 }
74 catch ( InterruptedException e )
75 {
76 // Do nothing
77 }
78 catch ( slbException e )
79 {
80 System.out.println( "Exception: " + vw.card.getErrorString() );
81 e.printStackTrace();
82 }
83 }
84
85 }
86 }
87
Listing 9
1 package com.vsp.eperson.javacard.clientside;
2
3 import slb.iop.slbException;
4
5 import javax.swing.*;
6 import java.awt.*;
7
8 /**
9 * @author Anita Phagura
10 */
11 public class Viewer extends JApplet
12 {
13 // Card
14 private CardProxy card = null;
15 private String[] readerList = null;
16
17 // GUI
18 private JPanel topPane = null;
19 private JPanel statusPane = null;
20 private JPanel displayPane = null;
21
22 private JTextField statusTextField = null;
23 private JTextArea empDisplayArea = null;
24
25 // Business
26 private Employee emp = null;
27 private EmployeeDao dao = null;
28 private ConnectorThread connectorThread = null;
29
30 // Constants
31 private static final int SPENDING_LIMIT = 1000;
32 private String spendingLimitMsg = "Passed spending limit";
33 private String contractExpiredMsg = "Contract Expired";
34 private String paymentOverDueMsg = "Payment overdue";
35
36 private String waitingStatus = "Waiting for connection...";
37 private String connectedStatus = "Connected !";
38
39 public void init()
40 {
41 readerList = CardProxy.ListReaders();
42 card = new CardProxy(readerList[0]);
43 dao = new EmployeeDao();
44
45 // Status Panel
46 statusPane = new JPanel();
47 JLabel statusLabel = new JLabel("Status: ");
48 statusPane.add(statusLabel);
49 statusTextField = new JTextField(waitingStatus, 20);
50 statusPane.add( statusTextField);
51
52 // Display Panel
53 displayPane = new JPanel(new BorderLayout( ));
54 JLabel employeeInfoLabel = new JLabel("Employee Info: ");
55 displayPane.add( employeeInfoLabel, BorderLayout.NORTH );
56 empDisplayArea = new JTextArea(20, 10);
57 displayPane.add(new JScrollPane(empDisplayArea), BorderLayout.CENTER);
58
59 // Top Panel
60 topPane = new JPanel(new BorderLayout());
61 topPane.add( displayPane, BorderLayout.CENTER);
62 topPane.add(statusPane, BorderLayout.SOUTH);
63
64 getContentPane().add( topPane);
65
66 validate();
67 }
68
69 public void start()
70 {
71 connectorThread = new ConnectorThread();
72 Thread connector = new Thread(connectorThread);
73 connector.start();
74
75 validate();
76 }
77
78 public void stop()
79 {
80 connectorThread.stopThread();
81 }
82 public void destroy()
83 {
84 card.disconnect();
85 connectorThread.stopThread();
86 }
87
88 // Business Validation
89 private void validateAndDisplayEmployee()
90 {
91 empDisplayArea.selectAll();
92 empDisplayArea.cut();
93 statusTextField.setText( this.connectedStatus);
94
95 try
96 {
97 Employee cardEmp = card.getAllInfo();
98 emp = dao.findEmployee( cardEmp.getEmpId() );
99
100 emp.setAmountDue( cardEmp.getAmountDue() );
101 emp.setAllowedDaysToPay( cardEmp.getAllowedDaysToPay() );
102
103 if( card.getCardStatus() )
104 {
105 // Check contract
106 if(!emp.isContractValid())
107 {
108 card.setCardStatus( false );
109 emp.setCloseReason( contractExpiredMsg );
110 }
111 // Check spending
112 if(emp.getAmountDue() > SPENDING_LIMIT )
113 {
114 card.setCardStatus( false );
115 emp.setCloseReason( spendingLimitMsg );
116 }
117 // Check days
118 if(emp.getAllowedDaysToPay() <= 0)
119 {
120 card.setCardStatus( false );
121 emp.setCloseReason( paymentOverDueMsg );
122 }
123
124 }
125 else
126 {
127 empDisplayArea.append( "WARNING: Employee card has been
deactivated...");
128 }
129
130 // Display the emp object, anyways
131 empDisplayArea.append(emp.toString());
132 dao.updateEmployeeAmounts( emp );
133
134 validate();
135 }
136 catch ( slbException e )
137 {
138 e.printStackTrace();
139 }
140
141 }
142 /**
143 * Inner class
144 */
145 class ConnectorThread implements Runnable
146 {
147 private boolean stop = false;
148
149 public void stopThread()
150 {
151 stop = true;
152 }
153 public void run()
154 {
155 boolean loop = false;
156 while(true)
157 {
158 while(!card.isConnected())
159 {
160 loop = false;
161 try
162 {
163
164 statusTextField.setText( waitingStatus);
165 Thread.sleep(700);
166 }
167 catch ( Exception e )
168 {
169 // Do nothing
170 }
171
172 if(stop)
173 return;
174 }
175
176 if(!loop)
177 {
178 validateAndDisplayEmployee();
179 loop = true;
180 }
181 }
182 }
183
184 }
258 }
|
|