/*
*
*
* Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program 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.
*
* This program 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 at /legal/license.txt).
*
* 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 or visit www.sun.com if you need additional
* information or have any questions.
*/
package com.sun.satsa.util;
import com.sun.midp.io.j2me.apdu.APDUManager;
import com.sun.midp.io.j2me.apdu.Handle;
import java.io.IOException;
/**
* Represents APDU connection to the WIM application.
*/
public class Connection {
/*
The set of command APDUs used by WIM application is very small.
Methods of this class that place data into APDU buffer don't
check for buffer overflow.
*/
/** The last response APDU status word. */
public int lastSW;
/** Temporary buffer for APDU command. */
private byte[] command;
/** Current offset in the command buffer. */
private int offset;
/** APDU connection handle. */
private Handle h;
/** Unit size for the read command */
private int unitSize;
/** CLAbyte for the send command */
private byte CLAbyte;
/**
* Constructs new connection object.
* @param h APDU connection handle.
*/
public Connection(Handle h) {
this.h = h;
command = new byte[255];
}
/**
* Safely closes the connection.
*/
public void done() {
try {
if (h != null) {
APDUManager.closeConnection(h);
}
} catch (IOException e) {} // ignore
h = null;
}
/**
* Resets command buffer.
* @return this connection object
*/
public Connection resetCommand() {
offset = 5;
return this;
}
/**
* Places one byte into command buffer.
* @param data byte to be placed
* @return this connection object
*/
public Connection putByte(int data) {
command[offset++] = (byte) data;
return this;
}
/**
* Places short value into the buffer.
* @param data value to be placed
* @return this connection object
*/
public Connection putShort(int data) {
command[offset++] = (byte) (data >> 8);
command[offset++] = (byte) data;
return this;
}
/**
* Places the byte sequence into the buffer.
* @param data data to be placed
* @param off data offset
* @param length data length
* @return this connection object
*/
public Connection putBytes(byte[] data, int off, int length) {
System.arraycopy(data, off, command, offset, length);
offset += length;
return this;
}
/**
* Sends the command.
* @param INS INS byte for this command.
* @param P1P2 APDU parameters value
* @return response APDU
* @throws IOException if IO error occurs
*/
public byte[] sendCommand(int INS, int P1P2) throws IOException {
return sendCommand(INS, P1P2, 240, true);
}
/**
* Sends the command.
* @param INS INS byte for this command.
* @param P1P2 P1 and P2 values for this command
* @param LE response expected length
* @param check if true, verify that SW is 0x9000
* @return response APDU
* @throws IOException if IO error occurs
*/
public byte[] sendCommand(int INS, int P1P2, int LE, boolean check)
throws IOException {
command[0] = (byte) (CLAbyte | h.channel);
command[1] = (byte) INS;
command[2] = (byte) (P1P2 >> 8);
command[3] = (byte) P1P2;
command[4] = (byte) (offset - 5);
putByte(LE);
byte[] tmp = APDUManager.exchangeAPDU(h, command);
lastSW = ((tmp[tmp.length - 2] & 0xff) << 8) |
(tmp[tmp.length - 1] & 0xff);
if (check && lastSW != 0x9000) {
throw new IOException("SW = " + Integer.toHexString(lastSW));
}
return tmp;
}
/**
* This method returns the ATR received from the card that this
* Handle object is used to communicate with.
* @return ATR information received from the card at startup or
* reset. In case of I/O troubles returns null.
*/
public byte[] getATR() {
return h.getATR();
}
/**
* This method returns the FCI received from the card that this
* Handle object is used to communicate with.
* @return FCI information received from the card at startup or
* reset. In case of I/O troubles returns null.
*/
public byte[] getFCI() {
return h.getFCI();
}
/**
* This method sets value for the unitSize variable
* @param unitSize int Required value.
*/
public void setUnitSize(int unitSize) {
this.unitSize = unitSize;
}
/**
* This method sets value for the CLAbyte variable
* @param cla byte Required value.
*/
public void setCLAbyte(byte cla) {
this.CLAbyte = cla;
}
}
|