public synchronized List<CardTerminal> list(State state) throws CardException { // System.out.println("list"); if (state == null) { throw new NullPointerException(); } try { String[] readerNames = SCardListReaders(contextId); List<CardTerminal> list = new ArrayList<CardTerminal>(readerNames.length); if (stateMap == null) { // If waitForChange() has never been called, treat event // queries as status queries. if (state == CARD_INSERTION) { state = CARD_PRESENT; } else if (state == CARD_REMOVAL) { state = CARD_ABSENT; } } for (String readerName : readerNames) { CardTerminal terminal = implGetTerminal(readerName); ReaderState readerState; switch (state) { case ALL: list.add(terminal); break; case CARD_PRESENT: if (terminal.isCardPresent()) { list.add(terminal); } break; case CARD_ABSENT: if (terminal.isCardPresent() == false) { list.add(terminal); } break; case CARD_INSERTION: readerState = stateMap.get(readerName); if ((readerState != null) && readerState.isInsertion()) { list.add(terminal); } break; case CARD_REMOVAL: readerState = stateMap.get(readerName); if ((readerState != null) && readerState.isRemoval()) { list.add(terminal); } break; default: throw new CardException("Unknown state: " + state); } } return Collections.unmodifiableList(list); } catch (PCSCException e) { throw new CardException("list() failed", e); } }
static List<CardTerminal> waitForCards( List<? extends CardTerminal> terminals, long timeout, boolean wantPresent) throws CardException { // System.out.println("waitForCards"); // the argument sanity checks are performed in // javax.smartcardio.TerminalFactory or TerminalImpl long thisTimeout; if (timeout == 0) { timeout = TIMEOUT_INFINITE; thisTimeout = TIMEOUT_INFINITE; } else { // if timeout is not infinite, do the initial call that retrieves // the status with a 0 timeout. Otherwise, we might get incorrect // timeout exceptions (seen on Solaris with PC/SC shim) thisTimeout = 0; } String[] names = new String[terminals.size()]; int i = 0; for (CardTerminal terminal : terminals) { if (terminal instanceof TerminalImpl == false) { throw new IllegalArgumentException( "Invalid terminal type: " + terminal.getClass().getName()); } TerminalImpl impl = (TerminalImpl) terminal; names[i++] = impl.name; } int[] status = new int[names.length]; Arrays.fill(status, SCARD_STATE_UNAWARE); try { while (true) { // note that we pass "timeout" on each native PC/SC call // that means that if we end up making multiple (more than 2) // calls, we might wait too long. // for now assume that is unlikely and not a problem. status = SCardGetStatusChange(contextId, thisTimeout, status, names); thisTimeout = timeout; List<CardTerminal> results = null; for (i = 0; i < names.length; i++) { boolean nowPresent = (status[i] & SCARD_STATE_PRESENT) != 0; if (nowPresent == wantPresent) { if (results == null) { results = new ArrayList<CardTerminal>(); } results.add(implGetTerminal(names[i])); } } if (results != null) { return Collections.unmodifiableList(results); } } } catch (PCSCException e) { if (e.code == SCARD_E_TIMEOUT) { return Collections.emptyList(); } else { throw new CardException("waitForCard() failed", e); } } }