Source Code Cross Referenced for Protocol.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » io » j2me » apdu » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.midp.io.j2me.apdu 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *   
003:         *
004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation.
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt).
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions.
025:         */
026:
027:        package com.sun.midp.io.j2me.apdu;
028:
029:        import javax.microedition.io.*;
030:        import javax.microedition.apdu.*;
031:        import com.sun.midp.midlet.*;
032:        import com.sun.midp.midletsuite.*;
033:        import com.sun.midp.security.SecurityToken;
034:        import com.sun.midp.security.ImplicitlyTrustedClass;
035:        import com.sun.midp.security.Permissions;
036:        import com.sun.cldc.io.ConnectionBaseInterface;
037:        import com.sun.satsa.acl.ACLPermissions;
038:        import com.sun.satsa.acl.AccessControlManager;
039:        import com.sun.satsa.acl.APDUPermissions;
040:        import com.sun.satsa.util.Utils;
041:        import com.sun.satsa.security.SecurityInitializer;
042:
043:        import java.io.*;
044:
045:        /**
046:         * This is the implementation class for APDUConnection interface and provides
047:         * a high-level API to the J2ME applications allowing them to connect and
048:         * communicate with the card applications. An instance of this class is
049:         * created when Connector.open method is called with 'apdu' as protocol. An
050:         * instance of this class is only returned to the calling J2ME application if
051:         * the card application selection is successful. If there are any errors that
052:         * occur during the card application selection, IOException is thrown.
053:         * The application calls <tt>Connector.open</tt> with an APDU URL string and
054:         * obtains a {@link javax.microedition.apdu.APDUConnection} object.
055:         *
056:         */
057:        public class Protocol implements  APDUConnection,
058:                ConnectionBaseInterface, StreamConnection {
059:
060:            /**
061:             * Inner class to request security token from SecurityInitializer.
062:             * SecurityInitializer should be able to check this inner class name.
063:             */
064:            static private class SecurityTrusted implements 
065:                    ImplicitlyTrustedClass {
066:            };
067:
068:            /** This class has a different security domain than the MIDlet suite */
069:            private static SecurityToken classSecurityToken = SecurityInitializer
070:                    .requestToken(new SecurityTrusted());
071:
072:            /**
073:             * This object verifies access rights of the MIDlet.
074:             */
075:            private APDUPermissions verifier;
076:
077:            /**
078:             * This flag is to indicate if this APDU connection is to be used for
079:             * communicating with SAT.
080:             */
081:            private boolean openForSAT;
082:
083:            /**
084:             * Connection handle.
085:             */
086:            private Handle h;
087:
088:            /**
089:             * Opens a connection.
090:             *
091:             * @param name the target of the connection
092:             * @param mode indicates whether the caller
093:             *             intends to write to the connection. Currently,
094:             *             this parameter is ignored.
095:             * @param timeouts indicates whether the caller
096:             *                 wants timeout exceptions. Currently,
097:             *             this parameter is ignored.
098:             * @return this connection
099:             * @throws IOException if the connection is closed or unavailable
100:             * @throws SecurityException if access is restricted by ACL
101:             */
102:            public Connection openPrim(String name, int mode, boolean timeouts)
103:                    throws IOException {
104:
105:                // parse the URI for slot number and target
106:                int slotIndex = name.indexOf(":");
107:                int targetIndex = name.indexOf(";target=");
108:
109:                if (targetIndex < 0) {
110:                    throw new IllegalArgumentException(
111:                            "Target missing in connection URL");
112:                }
113:
114:                int slot;
115:
116:                if (targetIndex == slotIndex + 1) {
117:                    slot = 0;
118:                } else {
119:                    try {
120:                        slot = Integer.parseInt(name.substring(slotIndex + 1,
121:                                targetIndex), 16);
122:                    } catch (NumberFormatException e) {
123:                        throw new IllegalArgumentException(
124:                                "Invalid slot number");
125:                    }
126:                }
127:
128:                String target = name.substring(targetIndex + 8);
129:
130:                boolean isSAT = target.equals("SAT");
131:
132:                // verify MIDlet permissions
133:                MIDletSuite ms = MIDletStateHandler.getMidletStateHandler()
134:                        .getMIDletSuite();
135:                try {
136:                    if (isSAT) {
137:                        ms.checkForPermission(Permissions.APDU_CHANNEL0,
138:                                "apdu:satopen");
139:                    } else {
140:                        ms.checkForPermission(Permissions.APDU_CONNECTION,
141:                                "apdu:open");
142:                    }
143:                } catch (InterruptedException ie) {
144:                    throw new InterruptedIOException(
145:                            "Interrupted while trying to ask the user permission");
146:                }
147:
148:                // open connection
149:
150:                if (isSAT) {
151:                    boolean satSlot;
152:                    try {
153:                        satSlot = APDUManager.isSatSlot(slot);
154:                    } catch (IllegalArgumentException e) {
155:                        satSlot = false;
156:                    }
157:                    if (!satSlot) {
158:                        throw new ConnectionNotFoundException(
159:                                "Invalid slot for SIM");
160:                    }
161:                    h = APDUManager.openSATConnection(slot, classSecurityToken);
162:                    openForSAT = true;
163:                } else {
164:
165:                    APDUManager.checkSlotNumber(slot);
166:
167:                    byte[] apdu = new byte[32];
168:                    apdu[1] = (byte) 0xa4;
169:                    apdu[2] = 4;
170:
171:                    boolean ok;
172:                    try {
173:                        int len = APDUManager.parseDottedBytes(target, apdu, 5);
174:                        apdu[4] = (byte) len;
175:                        apdu[5 + len] = 127;
176:                        ok = len > 4 && len < 17;
177:                    } catch (NullPointerException npe) {
178:                        ok = false;
179:                    } catch (IndexOutOfBoundsException iobe) {
180:                        ok = false;
181:                    } catch (NumberFormatException nfe) {
182:                        ok = false;
183:                    } catch (IllegalArgumentException iae) {
184:                        ok = false;
185:                    }
186:
187:                    if (!ok) {
188:                        throw new IllegalArgumentException("Invalid AID");
189:                    }
190:
191:                    APDUManager.initACL(slot, classSecurityToken);
192:                    verifier = AccessControlManager.getAPDUPermissions(slot,
193:                            apdu, ((MIDletSuiteImpl) ms).getInstallInfo()
194:                                    .getCA());
195:
196:                    h = APDUManager.selectApplication(apdu, slot,
197:                            classSecurityToken);
198:                }
199:                return this ;
200:            }
201:
202:            /**
203:             * Closes the connection.
204:             * @exception IOException  if an I/O error occurs
205:             */
206:            public void close() throws IOException {
207:                /* 
208:                 * IMPL_NOTE: To pass JDTS test 
209:                 * com.sun.satsa.apdu.exchange.interruptedIOClosed next lines 
210:                 * should be uncommented
211:                 */
212:                // try {Thread.sleep(1000); } 
213:                // catch (InterruptedException ignored) {}
214:                if (h != null) {
215:                    Handle w = h;
216:                    h = null;
217:                    APDUManager.closeConnection(w);
218:                }
219:            }
220:
221:            /**
222:             * Exchanges an APDU command with a smart card application.
223:             * Communication to a smart card device is synchronous.
224:             * This method will block until the response has been received
225:             * from the smart card application, or is interrupted.
226:             * The interruption could be due to the card being removed from
227:             * the card access device, the operation may timeout, or the
228:             * connection may be closed from another thread accessing this
229:             * connection.
230:             *
231:             * @param commandAPDU a byte encoded command for the smart card
232:             * application
233:             * @return a byte encoded response to the requested operation
234:             * @exception IOException is thrown if the operation was not
235:             * successful, or if the connection was already closed
236:             * @throws InterruptedIOException if a timeout occurs while
237:             * either trying to send the command or if this <code>Connection</code>
238:             * object is closed during this exchange operation
239:             * @throws NullPointerException if the parameter is null
240:             * @throws SecurityException if the application does not
241:             *         have permission to exchange the message
242:             */
243:            public byte[] exchangeAPDU(byte[] commandAPDU) throws IOException,
244:                    InterruptedIOException {
245:
246:                checkHandle(h);
247:                if (commandAPDU == null || commandAPDU.length < 4) {
248:                    throw new IllegalArgumentException();
249:                }
250:
251:                int nibble = commandAPDU[0] & 0xF0;
252:                boolean channelEncoded = (nibble == 0 || (nibble >= 0x80 && nibble <= 0xA0));
253:
254:                if (channelEncoded) {
255:                    // mask off the channel information
256:                    commandAPDU[0] &= 0xFC;
257:                }
258:
259:                int command = Utils.getInt(commandAPDU, 0);
260:
261:                if (openForSAT) {
262:                    // check if this is an envelope by checking the INS, P1 and
263:                    // P2 which should have values 0xC2, 0 and 0 respectively.
264:                    if ((command & 0xffffff) != 0xC20000) {
265:                        throw new IllegalArgumentException("Non-envelope APDU");
266:                    }
267:                    commandAPDU[0] = (byte) 0x80;
268:                } else {
269:
270:                    int cmd = command >> 8;
271:                    if (cmd == 0xA404 || cmd == 0x7000 || cmd == 0x7080) {
272:                        throw new IllegalArgumentException(
273:                                "Selection or channel management APDUs are not allowed");
274:                    }
275:
276:                    // if channel is non-zero, valid CLA bytes are only:
277:                    // 0x0X, 0x8X, 0x9X or 0xAX i.e. the one that can have
278:                    // the channel information encoded in it
279:                    if (h.channel != 0 && !channelEncoded) {
280:                        throw new IllegalArgumentException(
281:                                "Invalid CLA byte for a non-zero channel");
282:                    }
283:
284:                    // check if allowed by the ACL
285:                    verifier.checkPermission(command);
286:
287:                    if (channelEncoded) {
288:                        // set channel bits in two LSB
289:                        commandAPDU[0] |= h.channel;
290:                    }
291:                }
292:                return APDUManager.exchangeAPDU(h, commandAPDU);
293:            }
294:
295:            /**
296:             * Returns the ATR message sent by smart card in response to the
297:             * reset operation.
298:             * @return the ATR response message, or <code>null</code>
299:             * if there is no message available
300:             */
301:            public byte[] getATR() {
302:                byte[] result = null;
303:                try {
304:                    checkHandle(h);
305:                    result = h.getATR();
306:                } catch (IOException e) {
307:                    result = null;
308:                }
309:                return result;
310:            }
311:
312:            /**
313:             * This method always throw <code>IllegalArgumentException</code>.
314:             * @return An input stream
315:             * @exception IOException  If an I/O error occurs
316:             * @exception IllegalArgumentException  is thrown for all requests
317:             */
318:            public InputStream openInputStream() throws IOException {
319:                throw new IllegalArgumentException("Not supported");
320:            }
321:
322:            /**
323:             * This method always throw <code>IllegalArgumentException</code>.
324:             * @return                 An input stream
325:             * @exception IOException  If an I/O error occurs
326:             * @exception IllegalArgumentException  is thrown for all requests
327:             */
328:            public DataInputStream openDataInputStream() throws IOException {
329:                throw new IllegalArgumentException("Not supported");
330:            }
331:
332:            /**
333:             * This method always throw
334:             * <code>IllegalArgumentException</code>.
335:             * @return                 An output stream
336:             * @exception IOException  If an I/O error occurs
337:             * @exception IllegalArgumentException  is thrown for all requests
338:             */
339:            public OutputStream openOutputStream() throws IOException {
340:                throw new IllegalArgumentException("Not supported");
341:            }
342:
343:            /**
344:             * This method always throw
345:             * <code>IllegalArgumentException</code>.
346:             *
347:             * @return                 An output stream
348:             * @exception IOException  If an I/O error occurs
349:             * @exception IllegalArgumentException  is thrown for all requests
350:             */
351:            public DataOutputStream openDataOutputStream() throws IOException {
352:                throw new IllegalArgumentException("Not supported");
353:            }
354:
355:            /**
356:             * A call to enterPin method pops up a UI that requests the PIN
357:             * from the user. The pinID field indicates which PIN must be
358:             * requested from the user. The user can
359:             * either cancel the request
360:             * or continue. If the user enters the PIN and chooses to continue the
361:             * implementation is responsible
362:             * for presenting the PIN value to the card for verification.
363:             * @param pinID the type of PIN the implementation is suppose to prompt
364:             * the user to enter.
365:             * @return result of PIN verification which is the status word
366:             * recived from the smart card in the form of a byte array. This method
367:             * would return null if the user cancels the request.
368:             * @exception IOException is thrown if the PIN could not be communicated
369:             * with the card due to IO problems such as if the connection was
370:             * closed before the command could be completed successfully.
371:             * @exception InterruptedIOException is thrown if the connection object
372:             * is closed before a reply from the card is received.
373:             * @exception SecurityException is thrown if the J2ME application does
374:             * not have appropriate rights to ask for PIN verification.
375:             */
376:            public byte[] enterPin(int pinID) throws IOException {
377:                return doEnterPin(pinID, 0, ACLPermissions.CMD_VERIFY);
378:            }
379:
380:            /**
381:             * A call to <code>changePin</code> method pops up a UI that requests the
382:             * the user for an old or existing PIN value and the new PIN value
383:             * to change the value of the PIN. The pinID field indicates which PIN is
384:             * to be changed. The user can
385:             * either cancel the request
386:             * or continue. If the user enters the PIN values and chooses to
387:             * continue the
388:             * implementation is responsible
389:             * for presenting the PIN value to the card to the card.
390:             * @param pinID the type of PIN the implementation is suppose to prompt
391:             * the user to change.
392:             * @return result of changing the PIN value which is the status word
393:             * recived from the smart card in the form of a byte array. This method
394:             * would return null if the user cancels the request.
395:             * @exception IOException is thrown if the PIN could not be communicated
396:             * with the card due to IO problems such as if the connection was
397:             * closed before the command could be completed successfully.
398:             * @exception InterruptedIOException is thrown if the connection object
399:             * is closed before a reply from the card is received.
400:             * @exception SecurityException is thrown if the J2ME application does
401:             * not have appropriate rights to ask for changing the PIN value.
402:             */
403:            public byte[] changePin(int pinID) throws IOException {
404:                return doEnterPin(pinID, 0, ACLPermissions.CMD_CHANGE);
405:            }
406:
407:            /**
408:             * A call to <code>disablePin</code> method pops up a UI that requests the
409:             * the user to enter the value for the PIN that is to be disabled.
410:             * The pinID field
411:             * indicates which PIN is to be disabled. The user can
412:             * either cancel the request
413:             * or continue. If the user enters the PIN and chooses to continue the
414:             * implementation is responsible
415:             * for presenting the PIN value to the card to disable PIN.
416:             * @param pinID the type of PIN the implementation is required to prompt
417:             * the user to enter.
418:             * @return result of disabling the PIN value which is the status word
419:             * recived from the smart card in the form of a byte array. This method
420:             * would return null if the user cancels the request.
421:             * @exception IOException is thrown if the PIN could not be communicated
422:             * with the card due to IO problems such as if the connection was
423:             * closed before the command could be completed successfully.
424:             * @exception InterruptedIOException is thrown if the connection object
425:             * is closed before a reply from the card is received.
426:             * @exception SecurityException is thrown if the J2ME application does
427:             * not have appropriate rights to ask for disabling the PIN.
428:             */
429:            public byte[] disablePin(int pinID) throws IOException {
430:                return doEnterPin(pinID, 0, ACLPermissions.CMD_DISABLE);
431:            }
432:
433:            /**
434:             * A call to <code>enablePin</code> method pops up a UI that requests the
435:             * the user to enter the value for the PIN that is to be enabled.
436:             * The pinID field
437:             * indicates which PIN is to be enabled. The user can
438:             * either cancel the request
439:             * or continue. If the user enters the PIN and chooses to continue the
440:             * implementation is responsible
441:             * for presenting the PIN value to the card for enabling the PIN.
442:             * @param pinID the type of PIN the implementation is required to prompt
443:             * the user to enter.
444:             * @return result of enabling the PIN value which is the status word
445:             * recived from the smart card in the form of a byte array. This method
446:             * would return null if the user cancels the request.
447:             * @exception IOException is thrown if the PIN could not be communicated
448:             * with the card due to IO problems such as if the connection was
449:             * closed before the command could be completed successfully.
450:             * @exception InterruptedIOException is thrown if the connection object
451:             * is closed before a reply from the card is received.
452:             * @exception SecurityException is thrown if the J2ME application does
453:             * not have appropriate rights to ask for enabling the PIN.
454:             */
455:            public byte[] enablePin(int pinID) throws IOException {
456:                return doEnterPin(pinID, 0, ACLPermissions.CMD_ENABLE);
457:            }
458:
459:            /**
460:             * This is a high-level method that lets the J2ME application
461:             * ask the user to enter the value for an unblocking PIN,
462:             * and the new value for the blocked PIN and send
463:             * these to the card.
464:             * A call to <code>unblockPin</code> method pops up a UI that requests
465:             * the user to enter the value for the unblocking PIN and the
466:             * new value for the blocked PIN.
467:             * The <code>unblockingPinID</code> field indicates which unblocking
468:             * PIN is to be
469:             * used to unblock the blocked PIN which is indicated by the field
470:             * <code>blockedPinId</code>.
471:             * The unblockingPinID field indicates which PIN is to be unblocked.
472:             * The user can either cancel the request
473:             * or continue. If the user enters the PIN values and chooses to continue,
474:             * the implementation is responsible
475:             * for presenting the PIN values to the card for unblocking the
476:             * blocked PIN.
477:             * If padding is required for either of the PIN values, the
478:             * implementation is responsible for providing appropriate padding.
479:             * @param blockedPinID the Id of PIN that is to be unblocked.
480:             * @param unblockingPinId the Id of unblocking PIN.
481:             * @return result of unblocking the PIN value which is the status word
482:             * received from the smart card in the form of a byte array. This method
483:             * would return null if the user cancels the request.
484:             * @exception IOException is thrown if the PIN could not be communicated
485:             * with the card because the connection was
486:             * closed before this method was called or because
487:             * of communication problems.
488:             * @throws InterruptedIOException can be thrown in any of these situations:
489:             * <ul>
490:             *    <li>if this <code>Connection</code>
491:             *        object is closed during the exchange
492:             *        operation</li>
493:             *     <li>if the card is removed after connection is established and
494:             *         then reinserted, and attempt is made to unblock PIN
495:             *         without re-establishing the connection</li>
496:             * </ul>
497:             * @exception SecurityException is thrown if the J2ME application does
498:             * not have appropriate rights to ask for unblocking the PIN.
499:             */
500:            public byte[] unblockPin(int blockedPinID, int unblockingPinId)
501:                    throws IOException {
502:                return doEnterPin(blockedPinID, unblockingPinId,
503:                        ACLPermissions.CMD_UNBLOCK);
504:            }
505:
506:            /**
507:             * Performs PIN entry operation.
508:             * @param pinID PIN identifier.
509:             * @param uPinID unblocking PIN identifier.
510:             * @param action PIN operation identifier.
511:             * @return result of PIN verification which is the status word
512:             * received from the smart card in the form of a byte array. This method
513:             * would return null if the user cancels the request.
514:             * @exception IOException is thrown if the PIN could not be communicated
515:             * with the card due to IO problems such as if the connection was
516:             * closed before the command could be completed successfully.
517:             * @exception InterruptedIOException is thrown if the connection object
518:             * is closed before a reply from the card is received.
519:             * @exception SecurityException is thrown if the J2ME application does
520:             * not have appropriate rights to ask for PIN verification.
521:             */
522:            private byte[] doEnterPin(int pinID, int uPinID, int action)
523:                    throws IOException {
524:
525:                checkHandle(h);
526:
527:                if (openForSAT) {
528:                    throw new SecurityException();
529:                }
530:
531:                int header = verifier.preparePIN(pinID, uPinID, action);
532:
533:                Object[] pins = verifier.enterPIN(classSecurityToken, action);
534:
535:                if (pins == null) {
536:                    return null;
537:                }
538:
539:                byte[] pin1 = (byte[]) pins[0];
540:                byte[] pin2 = (pins.length == 2) ? (byte[]) pins[1] : null;
541:
542:                int dataSize = pin1.length;
543:                if (pin2 != null) {
544:                    dataSize += pin2.length;
545:                }
546:
547:                byte[] command = new byte[6 + dataSize];
548:
549:                command[0] = (byte) (header >> 24);
550:                command[1] = (byte) (header >> 16);
551:                command[2] = (byte) (header >> 8);
552:                command[3] = (byte) header;
553:                command[4] = (byte) dataSize;
554:                System.arraycopy(pin1, 0, command, 5, pin1.length);
555:
556:                if (pin2 != null) {
557:                    System.arraycopy(pin2, 0, command, 5 + pin1.length,
558:                            pin2.length);
559:                }
560:                command[5 + dataSize] = 0x7f;
561:
562:                byte[] result;
563:                try {
564:                    // CLA can be incompatible with this logical channel
565:                    result = exchangeAPDU(command);
566:                } catch (IllegalArgumentException e) {
567:                    throw new IOException(e.getMessage());
568:                }
569:                byte[] out = new byte[2];
570:                System.arraycopy(result, result.length - 2, out, 0, 2);
571:                return out;
572:            }
573:
574:            /**
575:             * Checks if given handle is still valid.
576:             * @param h Handle to be checked.
577:             * @exception IOException is thrown if connection is closed
578:             * @exception InterruptedIOException is thrown if connection 
579:             * closed and re-established again.
580:             */
581:            private void checkHandle(Handle h) throws IOException {
582:                if (h == null || !h.opened || h.getCardSessionId() == -1) {
583:                    throw new IOException("Connection closed");
584:                }
585:                if (h.getCardSessionId() != h.cardSessionId) {
586:                    throw new InterruptedIOException("Connection closed");
587:                }
588:            }
589:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.