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.satsa.util;
028:
029: import com.sun.midp.io.j2me.apdu.APDUManager;
030: import com.sun.midp.io.j2me.apdu.Handle;
031:
032: import java.io.IOException;
033:
034: /**
035: * Represents APDU connection to the WIM application.
036: */
037: public class Connection {
038:
039: /*
040: The set of command APDUs used by WIM application is very small.
041: Methods of this class that place data into APDU buffer don't
042: check for buffer overflow.
043: */
044:
045: /** The last response APDU status word. */
046: public int lastSW;
047:
048: /** Temporary buffer for APDU command. */
049: private byte[] command;
050: /** Current offset in the command buffer. */
051: private int offset;
052: /** APDU connection handle. */
053: private Handle h;
054: /** Unit size for the read command */
055: private int unitSize;
056: /** CLAbyte for the send command */
057: private byte CLAbyte;
058:
059: /**
060: * Constructs new connection object.
061: * @param h APDU connection handle.
062: */
063: public Connection(Handle h) {
064: this .h = h;
065: command = new byte[255];
066: }
067:
068: /**
069: * Safely closes the connection.
070: */
071: public void done() {
072: try {
073: if (h != null) {
074: APDUManager.closeConnection(h);
075: }
076: } catch (IOException e) {
077: } // ignore
078: h = null;
079: }
080:
081: /**
082: * Resets command buffer.
083: * @return this connection object
084: */
085: public Connection resetCommand() {
086: offset = 5;
087: return this ;
088: }
089:
090: /**
091: * Places one byte into command buffer.
092: * @param data byte to be placed
093: * @return this connection object
094: */
095: public Connection putByte(int data) {
096: command[offset++] = (byte) data;
097: return this ;
098: }
099:
100: /**
101: * Places short value into the buffer.
102: * @param data value to be placed
103: * @return this connection object
104: */
105: public Connection putShort(int data) {
106: command[offset++] = (byte) (data >> 8);
107: command[offset++] = (byte) data;
108: return this ;
109: }
110:
111: /**
112: * Places the byte sequence into the buffer.
113: * @param data data to be placed
114: * @param off data offset
115: * @param length data length
116: * @return this connection object
117: */
118: public Connection putBytes(byte[] data, int off, int length) {
119: System.arraycopy(data, off, command, offset, length);
120: offset += length;
121: return this ;
122: }
123:
124: /**
125: * Sends the command.
126: * @param INS INS byte for this command.
127: * @param P1P2 APDU parameters value
128: * @return response APDU
129: * @throws IOException if IO error occurs
130: */
131: public byte[] sendCommand(int INS, int P1P2) throws IOException {
132: return sendCommand(INS, P1P2, 240, true);
133: }
134:
135: /**
136: * Sends the command.
137: * @param INS INS byte for this command.
138: * @param P1P2 P1 and P2 values for this command
139: * @param LE response expected length
140: * @param check if true, verify that SW is 0x9000
141: * @return response APDU
142: * @throws IOException if IO error occurs
143: */
144: public byte[] sendCommand(int INS, int P1P2, int LE, boolean check)
145: throws IOException {
146:
147: command[0] = (byte) (CLAbyte | h.channel);
148: command[1] = (byte) INS;
149: command[2] = (byte) (P1P2 >> 8);
150: command[3] = (byte) P1P2;
151: command[4] = (byte) (offset - 5);
152: putByte(LE);
153:
154: byte[] tmp = APDUManager.exchangeAPDU(h, command);
155:
156: lastSW = ((tmp[tmp.length - 2] & 0xff) << 8)
157: | (tmp[tmp.length - 1] & 0xff);
158:
159: if (check && lastSW != 0x9000) {
160: throw new IOException("SW = " + Integer.toHexString(lastSW));
161: }
162: return tmp;
163: }
164:
165: /**
166: * This method returns the ATR received from the card that this
167: * Handle object is used to communicate with.
168: * @return ATR information received from the card at startup or
169: * reset. In case of I/O troubles returns null.
170: */
171: public byte[] getATR() {
172: return h.getATR();
173: }
174:
175: /**
176: * This method returns the FCI received from the card that this
177: * Handle object is used to communicate with.
178: * @return FCI information received from the card at startup or
179: * reset. In case of I/O troubles returns null.
180: */
181: public byte[] getFCI() {
182: return h.getFCI();
183: }
184:
185: /**
186: * This method sets value for the unitSize variable
187: * @param unitSize int Required value.
188: */
189: public void setUnitSize(int unitSize) {
190: this .unitSize = unitSize;
191: }
192:
193: /**
194: * This method sets value for the CLAbyte variable
195: * @param cla byte Required value.
196: */
197: public void setCLAbyte(byte cla) {
198: this.CLAbyte = cla;
199: }
200:
201: }
|