/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.smartcardio.*;
/**
* CardChannel implementation.
*
* @since 1.6
* @author Andreas Sterbenz
*/
// the card this channel is associated with
// the channel number, 0 for the basic logical channel
private final int channel;
// whether this channel has been closed. only logical channels can be closed
private volatile boolean isClosed;
}
void checkClosed() {
card.checkState();
if (isClosed) {
throw new IllegalStateException("Logical channel has been closed");
}
}
return card;
}
public int getChannelNumber() {
checkClosed();
return channel;
}
private static void checkManageChannel(byte[] b) {
if (b.length < 4) {
throw new IllegalArgumentException
("Command APDU must be at least 4 bytes long");
}
if ((b[0] >= 0) && (b[1] == 0x70)) {
throw new IllegalArgumentException
("Manage channel command not allowed, use openLogicalChannel()");
}
}
checkClosed();
return new ResponseAPDU(responseBytes);
}
checkClosed();
throw new NullPointerException();
}
if (response.isReadOnly()) {
throw new ReadOnlyBufferException();
}
throw new IllegalArgumentException
("command and response must not be the same object");
}
throw new IllegalArgumentException
("Insufficient space in response buffer");
}
return responseBytes.length;
}
private final static boolean t0GetResponse =
getBooleanProperty("sun.security.smartcardio.t0GetResponse", true);
private final static boolean t1GetResponse =
getBooleanProperty("sun.security.smartcardio.t1GetResponse", true);
private final static boolean t1StripLe =
getBooleanProperty("sun.security.smartcardio.t1StripLe", false);
return def;
}
return true;
return false;
} else {
throw new IllegalArgumentException
(name + " must be either 'true' or 'false'");
}
}
return b2;
}
return res;
}
// note that we modify the 'command' array in some cases, so it must
// be a copy of the application provided data.
try {
throw new CardException
("Extended length forms not supported for T=0");
}
if (lc != 0) {
if (n == lc + 6) {
n--;
}
} else {
if (n == lc + 9) {
n -= 2;
}
}
}
int k = 0;
while (true) {
if (++k >= 32) {
throw new CardException("Could not obtain response");
}
byte[] response = SCardTransmit
// see ISO 7816/2005, 5.1.3
// Resend command using SW2 as short Le field
continue;
}
// Issue a GET RESPONSE command with the same CLA
// using SW2 as short Le field
if (rn > 2) {
}
n = 5;
continue;
}
}
break;
}
return result;
} catch (PCSCException e) {
card.handleError(e);
throw new CardException(e);
}
}
}
}
}
if (cla < 0) {
// proprietary class format, cannot set or check logical channel
// for now, just return
return;
}
// classes 001x xxxx is reserved for future use in ISO, ignore
return;
}
// see ISO 7816/2005, table 2 and 3
if (channel <= 3) {
// mask of bits 7, 1, 0 (channel number)
// 0xbc == 1011 1100
} else if (channel <= 19) {
// mask of bits 7, 3, 2, 1, 0 (channel number)
// 0xbc == 1011 0000
} else {
}
}
if (getChannelNumber() == 0) {
throw new IllegalStateException("Cannot close basic logical channel");
}
if (isClosed) {
return;
}
try {
}
} catch (PCSCException e) {
card.handleError(e);
throw new CardException("Could not close channel", e);
} finally {
isClosed = true;
}
}
}
}