/* * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package javax.smartcardio; import java.nio.*; /** * A logical channel connection to a Smart Card. It is used to exchange APDUs * with a Smart Card. * A CardChannel object can be obtained by calling the method * {@linkplain Card#getBasicChannel} or {@linkplain Card#openLogicalChannel}. * * @see Card * @see CommandAPDU * @see ResponseAPDU * * @since 1.6 * @author Andreas Sterbenz * @author JSR 268 Expert Group */ public abstract class CardChannel { /** * Constructs a new CardChannel object. * * <p>This constructor is called by subclasses only. Application should * call the {@linkplain Card#getBasicChannel} and * {@linkplain Card#openLogicalChannel} methods to obtain a CardChannel * object. */ protected CardChannel() { // empty } /** * Returns the Card this channel is associated with. * * @return the Card this channel is associated with */ public abstract Card getCard(); /** * Returns the channel number of this CardChannel. A channel number of * 0 indicates the basic logical channel. * * @return the channel number of this CardChannel. * * @throws IllegalStateException if this channel has been * {@linkplain #close closed} or if the corresponding Card has been * {@linkplain Card#disconnect disconnected}. */ public abstract int getChannelNumber(); /** * Transmits the specified command APDU to the Smart Card and returns the * response APDU. * * <p>The CLA byte of the command APDU is automatically adjusted to * match the channel number of this CardChannel. * * <p>Note that this method cannot be used to transmit * <code>MANAGE CHANNEL</code> APDUs. Logical channels should be managed * using the {@linkplain Card#openLogicalChannel} and {@linkplain * CardChannel#close CardChannel.close()} methods. * * <p>Implementations should transparently handle artifacts * of the transmission protocol. * For example, when using the T=0 protocol, the following processing * should occur as described in ISO/IEC 7816-4: * * <ul> * <li><p>if the response APDU has an SW1 of <code>61</code>, the * implementation should issue a <code>GET RESPONSE</code> command * using <code>SW2</code> as the <code>Le</code>field. * This process is repeated as long as an SW1 of <code>61</code> is * received. The response body of these exchanges is concatenated * to form the final response body. * * <li><p>if the response APDU is <code>6C XX</code>, the implementation * should reissue the command using <code>XX</code> as the * <code>Le</code> field. * </ul> * * <p>The ResponseAPDU returned by this method is the result * after this processing has been performed. * * @param command the command APDU * @return the response APDU received from the card * * @throws IllegalStateException if this channel has been * {@linkplain #close closed} or if the corresponding Card has been * {@linkplain Card#disconnect disconnected}. * @throws IllegalArgumentException if the APDU encodes a * <code>MANAGE CHANNEL</code> command * @throws NullPointerException if command is null * @throws CardException if the card operation failed */ public abstract ResponseAPDU transmit(CommandAPDU command) throws CardException; /** * Transmits the command APDU stored in the command ByteBuffer and receives * the reponse APDU in the response ByteBuffer. * * <p>The command buffer must contain valid command APDU data starting * at <code>command.position()</code> and the APDU must be * <code>command.remaining()</code> bytes long. * Upon return, the command buffer's position will be equal * to its limit; its limit will not have changed. The output buffer * will have received the response APDU bytes. Its position will have * advanced by the number of bytes received, which is also the return * value of this method. * * <p>The CLA byte of the command APDU is automatically adjusted to * match the channel number of this CardChannel. * * <p>Note that this method cannot be used to transmit * <code>MANAGE CHANNEL</code> APDUs. Logical channels should be managed * using the {@linkplain Card#openLogicalChannel} and {@linkplain * CardChannel#close CardChannel.close()} methods. * * <p>See {@linkplain #transmit transmit()} for a discussion of the handling * of response APDUs with the SW1 values <code>61</code> or <code>6C</code>. * * @param command the buffer containing the command APDU * @param response the buffer that shall receive the response APDU from * the card * @return the length of the received response APDU * * @throws IllegalStateException if this channel has been * {@linkplain #close closed} or if the corresponding Card has been * {@linkplain Card#disconnect disconnected}. * @throws NullPointerException if command or response is null * @throws ReadOnlyBufferException if the response buffer is read-only * @throws IllegalArgumentException if command and response are the * same object, if <code>response</code> may not have * sufficient space to receive the response APDU * or if the APDU encodes a <code>MANAGE CHANNEL</code> command * @throws CardException if the card operation failed */ public abstract int transmit(ByteBuffer command, ByteBuffer response) throws CardException; /** * Closes this CardChannel. The logical channel is closed by issuing * a <code>MANAGE CHANNEL</code> command that should use the format * <code>[xx 70 80 0n]</code> where <code>n</code> is the channel number * of this channel and <code>xx</code> is the <code>CLA</code> * byte that encodes this logical channel and has all other bits set to 0. * After this method returns, calling other * methods in this class will raise an IllegalStateException. * * <p>Note that the basic logical channel cannot be closed using this * method. It can be closed by calling {@link Card#disconnect}. * * @throws CardException if the card operation failed * @throws IllegalStateException if this CardChannel represents a * connection the basic logical channel */ public abstract void close() throws CardException; }