net.sf.scuba.smartcards.CardService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scuba-smartcards Show documentation
Show all versions of scuba-smartcards Show documentation
Smart Card Utils for Better Access.
/*
* This file is part of the SCUBA smart card framework.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Copyright (C) 2009 - 2015 The SCUBA team.
*
* $Id: CardService.java 246 2015-04-09 08:13:52Z martijno $
*/
package net.sf.scuba.smartcards;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
/**
* Default abstract service.
* Provides a factory method for creating card services.
* Provides some functionality for observing apdu events.
*
* @author Cees-Bart Breunesse ([email protected])
* @author Martijn Oostdijk ([email protected])
* @author Pim Vullers ([email protected])
*
* @version $Revision: 246 $
*/
public abstract class CardService implements Serializable {
private static final long serialVersionUID = 5618527358158494957L;
static protected final int SESSION_STOPPED_STATE = 0;
static protected final int SESSION_STARTED_STATE = 1;
private static final Map objectToServiceMap;
static {
objectToServiceMap = new HashMap();
objectToServiceMap.put("javax.smartcardio.CardTerminal", "net.sf.scuba.smartcards.TerminalCardService");
objectToServiceMap.put("sun.security.smartcardio.TerminalImpl", "net.sf.scuba.smartcards.TerminalCardService");
objectToServiceMap.put("android.nfc.tech.IsoDep", "net.sf.scuba.smartcards.IsoDepCardService");
}
/** The apduListeners. */
private Collection apduListeners;
/*
* @ invariant state == SESSION_STOPPED_STATE || state ==
* SESSION_STARTED_STATE;
*/
protected int state;
/**
* Creates a card service.
*
* @param object some platform object responsible for transporting the APDU.
*
* @return a card service
*/
public static CardService getInstance(Object object) {
if (object == null) { throw new IllegalArgumentException(); }
Class> objectClass = object.getClass();
String objectClassName = objectClass.getCanonicalName();
for (Entry entry: objectToServiceMap.entrySet()) {
String targetObjectClassName = entry.getKey();
try {
Class> targetObjectClass = Class.forName(targetObjectClassName);
String serviceClassName = entry.getValue();
if (targetObjectClass.isInstance(object)) {
try {
Class> cardServiceClass = Class.forName(serviceClassName);
return (CardService)cardServiceClass.getConstructor(targetObjectClass).newInstance(object);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
} catch (ClassNotFoundException cnfe) {
continue;
}
}
throw new IllegalArgumentException("Could not find a CardService for object of class \"" + objectClassName + "\"");
}
/*
* FIXME: visibility? -- MO
*/
/**
* Creates a new service.
*/
public CardService() {
apduListeners = new HashSet();
state = SESSION_STOPPED_STATE;
}
/**
* Adds a listener.
*
* @param l the listener to add
*/
public void addAPDUListener(APDUListener l) {
if (apduListeners != null) { apduListeners.add(l); }
}
/**
* Removes the listener l
, if present.
*
* @param l the listener to remove
*/
public void removeAPDUListener(APDUListener l) {
if (apduListeners != null) { apduListeners.remove(l); }
}
/**
* Notifies listeners about APDU event.
*
* @param count number of APDUs sent previously
* @param capdu command APDU
* @param rapdu response APDU
*/
protected void notifyExchangedAPDU(int count, CommandAPDU capdu, ResponseAPDU rapdu) {
if (apduListeners == null || apduListeners.size() < 1) { return; }
APDUEvent event = new APDUEvent(this, "RAW", count, capdu, rapdu);
for (APDUListener listener: apduListeners) {
listener.exchangedAPDU(event);
}
}
/**
* Opens a session with the card. Selects a reader. Connects to the card.
* Notifies any interested apduListeners.
*
* @throws CardServiceException on error
*/
/*
* @ requires state == SESSION_STOPPED_STATE;
* @ ensures state == SESSION_STARTED_STATE;
*/
public abstract void open() throws CardServiceException;
/**
* Whether there is a session started with the card.
*
* @return a boolean indicating whether sessions has started
*/
/*
* @ ensures \result == (state == SESSION_STARTED_STATE);
*/
public abstract boolean isOpen();
/**
* Sends an apdu to the card. Notifies any interested apduListeners.
*
* This method does not throw a CardServiceException if the ResponseAPDU
* is status word indicating error.
*
* @param apdu the command apdu to send
*
* @return the response from the card, including the status word
*
* @throws CardServiceException if the card operation failed
*/
/*
* @ requires state == SESSION_STARTED_STATE;
* @ ensures state == SESSION_STARTED_STATE;
*/
public abstract ResponseAPDU transmit(CommandAPDU apdu) throws CardServiceException;
public abstract byte[] getATR() throws CardServiceException;
/**
* Whether extended length APDUs are supported.
*
* @return a boolean indicating whether extended length APDUs are supported
*/
public boolean isExtendedAPDULengthSupported() {
return false;
}
/**
* Closes the session with the card. Disconnects from the card and reader.
* Notifies any interested apduListeners.
*/
/*
* @ requires state == SESSION_STARTED_STATE;
* @ ensures state == SESSION_STOPPED_STATE;
*/
public abstract void close();
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy