/****************************************************************************
* Copyright (C) 2012 HS Coburg.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
* This file is part of the Open eCard App.
*
* GNU General Public License Usage
* This file may be used under the terms of the GNU General Public
* License version 3.0 as published by the Free Software Foundation
* and appearing in the file LICENSE.GPL included in the packaging of
* this file. Please review the following information to ensure the
* GNU General Public License version 3.0 requirements will be met:
* http://www.gnu.org/copyleft/gpl.html.
*
* Other Usage
* Alternatively, this file may be used in accordance with the terms
* and conditions contained in a signed written agreement between
* you and ecsec GmbH.
*
***************************************************************************/
package org.openecard.scio;
import android.content.Context;
import android.nfc.NfcAdapter;
import android.nfc.NfcManager;
import android.nfc.tech.IsoDep;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import javax.annotation.Nonnull;
import org.openecard.common.ifd.scio.NoSuchTerminal;
import org.openecard.common.ifd.scio.SCIOErrorCode;
import org.openecard.common.ifd.scio.SCIOException;
import org.openecard.common.ifd.scio.SCIOTerminal;
import org.openecard.common.ifd.scio.SCIOTerminals;
import org.openecard.common.ifd.scio.SCIOTerminals.State;
import org.openecard.common.ifd.scio.TerminalState;
import org.openecard.common.ifd.scio.TerminalWatcher;
/**
* NFC implementation of smartcardio's CardTerminals interface.
*
* @author Dirk Petrautzki
* @author Daniel Nemmert
*/
public class NFCCardTerminals implements SCIOTerminals {
@Override
public List<SCIOTerminal> list(State arg0) throws SCIOException {
List<SCIOTerminal> list = new ArrayList<SCIOTerminal>() {};
list.add(NFCCardTerminal.getInstance());
return list;
}
@Override
public List<SCIOTerminal> list() throws SCIOException {
return list(State.ALL);
}
@Override
public SCIOTerminal getTerminal(@Nonnull String name) throws NoSuchTerminal {
return new NFCCardTerminal();
}
@Override
public TerminalWatcher getWatcher() throws SCIOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
private static class NFCCardWatcher implements TerminalWatcher {
private final NFCCardTerminals terminal;
private final NFCCardTerminal androidT;
protected IsoDep isodep;
private NFCCard nfcCard;
NfcManager manager;
NfcAdapter adapter;
Context context;
public NFCCardWatcher(NFCCardTerminals terminal, NFCCardTerminal androidT) {
this.terminal = terminal;
this.androidT = androidT;
}
private Queue<StateChangeEvent> pendingEvents;
private Collection<String> terminals;
private Collection<String> cardPresent;
private boolean isEnabled;
@Override
public SCIOTerminals getTerminals() {
return terminal;
}
@Override
public List<TerminalState> start() throws SCIOException {
ArrayList<TerminalState> result = new ArrayList<>();
if (pendingEvents != null) {
throw new IllegalStateException("Trying to initialize already initialized watcher instance");
}
pendingEvents = new LinkedList<>();
terminals = new HashSet<>();
cardPresent = new HashSet<>();
// Check if NFC Adapter is present and enabled
manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
adapter = manager.getDefaultAdapter();
isEnabled = adapter.isEnabled();
String name = androidT.getName();
terminals.add(name);
if (adapter == null) {
String msg = "No NFC Adapter on this Android Device";
throw new SCIOException(msg, SCIOErrorCode.SCARD_E_NO_READERS_AVAILABLE);
} else if (! isEnabled) {
throw new SCIOException("NFC Adapter not enabled", SCIOErrorCode.SCARD_E_NO_SERVICE);
} else if (adapter != null && adapter.isEnabled()) {
if (nfcCard.isodep.isConnected()) {
//List<SCIOTerminal> androidTerm = terminal.list(State.ALL);
cardPresent.add(name);
result.add(new TerminalState(name, true));
} else {
result.add(new TerminalState(name, false));
}
}
return result;
}
@Override
public StateChangeEvent waitForChange() throws SCIOException {
return waitForChange(0);
}
@Override
public StateChangeEvent waitForChange(long timeout) throws SCIOException {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
if (pendingEvents == null) {
throw new IllegalStateException("Calling wait on uninitialized watcher instance.");
}
StateChangeEvent nextEvent = pendingEvents.poll();
return null;
}
}
}