Пример #1
0
  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);
      }
    }
  }