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.cardreader;
028:
029: import java.io.IOException;
030:
031: /**
032: * Device driver for the real card reader.
033: */
034: public class PlatformCardDevice extends CardDevice {
035:
036: /**
037: * Initializes the device.
038: *
039: * @throws IOException If a device initialization failed.
040: * @throws CardDeviceException If a configuration initialization failed.
041: */
042: public void init() throws IOException, CardDeviceException {
043:
044: if (!init0()) {
045: String err_msg = getErrorMessage0();
046: if (err_msg != null)
047: throw new IOException(err_msg);
048: else
049: throw new IOException("Init failed");
050: }
051: }
052:
053: /**
054: * Closes the device.
055: * No exceptions thrown to avoid mess in exception handlers trying
056: * to clean up and close the device.
057: */
058: public void close() {
059: finalize0();
060: }
061:
062: /**
063: * Performs platform lock of the device. This is intended to make
064: * sure that no other native application
065: * uses the same device during a transaction.
066: *
067: * @throws IOException If a device locking failed.
068: */
069: public void lock() throws IOException {
070:
071: if (!lock0()) {
072: String err_msg = getErrorMessage0();
073: if (err_msg != null)
074: throw new IOException(err_msg);
075: else
076: throw new IOException("Lock failed");
077: }
078: }
079:
080: /**
081: * Unlocks the device.
082: *
083: * @throws IOException If a device unlocking failed.
084: */
085: public void unlock() throws IOException {
086:
087: if (!unlock0()) {
088: String err_msg = getErrorMessage0();
089: if (err_msg != null)
090: throw new IOException(err_msg);
091: else
092: throw new IOException("Unlock failed");
093: }
094: }
095:
096: /**
097: * Gets number of slots on a device.
098: *
099: * @return Number of slots on a device. In case of error
100: * returns 0.
101: */
102: public int getSlotCount() {
103: return getSlotCount0();
104: }
105:
106: /**
107: * Checks if this slot is SAT slot.
108: *
109: * @param slotNumber Slot number
110: * @return <code>true</code> if the slot is dedicated for SAT,
111: * <code>false</code> otherwise
112: * @throws IOException If an error occured.
113: */
114: public boolean isSatSlot(int slotNumber) throws IOException {
115: int result = isSatSlot0(slotNumber);
116: if (result == -1) {
117: String err_msg = getErrorMessage0();
118: if (err_msg != null)
119: throw new IOException(err_msg);
120: else
121: throw new IOException("isSAT failed");
122: }
123: return result != 0;
124: }
125:
126: /**
127: * Selects the current slot for the subsequent transfer operations.
128: * For the one-slot devices the default slot number is 0.
129: *
130: * @param slot Slot number
131: * @throws IOException If a slot selection failed.
132: */
133: public void selectSlot(int slot) throws IOException {
134:
135: if (!selectSlot0(slot)) {
136: String err_msg = getErrorMessage0();
137: if (err_msg != null)
138: throw new IOException(err_msg);
139: else
140: throw new IOException("SelectSlot failed");
141: }
142: }
143:
144: /**
145: * Performs reset of device.
146: *
147: * @param atr ATR bytes
148: * @return Length of ATR
149: * @throws IOException If a reset failed.
150: */
151: public int cmdReset(byte[] atr) throws IOException {
152: int bytes_read;
153:
154: if ((bytes_read = reset0(atr)) < 0) {
155: String err_msg = getErrorMessage0();
156: if (err_msg != null)
157: throw new IOException(err_msg);
158: else
159: throw new IOException("reset failed");
160: }
161: return bytes_read;
162: }
163:
164: /**
165: * Performs data transfer to the device.
166: *
167: * @param request Request bytes
168: * @param response Response bytes
169: * @return Length of response
170: * @throws IOException If a data transfer failed.
171: */
172: public int cmdXfer(byte[] request, byte[] response)
173: throws IOException {
174: int bytes_read;
175:
176: if ((bytes_read = cmdXfer0(request, response)) < 0) {
177: String err_msg = getErrorMessage0();
178: if (err_msg != null)
179: throw new IOException(err_msg);
180: else
181: throw new IOException("cmdXfer failed");
182: }
183: return bytes_read;
184: }
185:
186: /**
187: * Checks if the card in the selected slot was changed
188: * since last call or since last reset.
189: * Always called after any transfer operation, so
190: * implementation can check and store that status during
191: * this operation.
192: *
193: * @return true if was changed, false otherwise.
194: * @throws IOException If something fails.
195: */
196: public boolean isCardChanged() throws IOException {
197: int result = checkCardMovement0();
198: if (result < 0) {
199: String err_msg = getErrorMessage0();
200: if (err_msg != null)
201: throw new IOException(err_msg);
202: else
203: throw new IOException(
204: "Checking of card movement failed");
205: }
206: if (result == 0) {
207: return false;
208: } else {
209: return true;
210: }
211: }
212:
213: /**
214: * Initializes the device.
215: *
216: * @return true if successful, false otherwise
217: * @throws CardDeviceException If a configuration failed.
218: */
219: private native boolean init0() throws CardDeviceException;
220:
221: /**
222: * Finalizes the device.
223: */
224: private native void finalize0();
225:
226: /**
227: * Locks the device.
228: *
229: * @return true if successful, false otherwise
230: */
231: private native boolean lock0();
232:
233: /**
234: * Unlocks the device.
235: *
236: * @return true if successful, false otherwise
237: */
238: private native boolean unlock0();
239:
240: /**
241: * Gets number of slots on a device.
242: *
243: * @return Number of slots on a device. In case of error
244: * returns 0.
245: */
246: private native int getSlotCount0();
247:
248: /**
249: * Checks if this slot is SAT slot.
250: *
251: * @param slotNumber Slot number
252: * @return <code> 1</code> if the slot is dedicated for SAT,
253: * <code> 0</code> if not,
254: * <code>-1</code> if any error occured
255: */
256: private native int isSatSlot0(int slotNumber);
257:
258: /**
259: * Selects the current slot for the subsequent transfer operations.
260: * For the one-slot devices the default slot number is 0.
261: *
262: * @param slotIndex Slot number
263: * @return true if successful, false otherwise
264: */
265: private native boolean selectSlot0(int slotIndex);
266:
267: /**
268: * Performs reset of device.
269: * Fills diven array with ATR bytes.
270: *
271: * @param atr ATR bytes
272: * @return Length of ATR if successful, < 0 otherwise
273: */
274: private native int reset0(byte[] atr);
275:
276: /**
277: * Performs data transfer to the device.
278: *
279: * @param request Request bytes
280: * @param response Response bytes
281: * @return Length of response if successful, < 0 otherwise
282: */
283: private native int cmdXfer0(byte[] request, byte[] response);
284:
285: /**
286: * Checks if the card in the selected slot was changed
287: * since last call or since last reset.
288: * Called after any transfer operation, so
289: * implementation can check and store that status during
290: * this operation.
291: *
292: * @return 0 if no movements has happened,
293: * > 0 if the card was changed,
294: * < 0 if an error occured.
295: */
296: private native int checkCardMovement0();
297:
298: /**
299: * Retrives last error message.
300: *
301: * @return Error message as String
302: */
303: private native String getErrorMessage0();
304: }
|