Search in sources :

Example 1 with SlotStatusType

use of iso.std.iso_iec._24727.tech.schema.SlotStatusType in project open-ecard by ecsec.

the class IfdEventRunner method fireEvents.

private void fireEvents(@Nonnull List<IFDStatusType> diff) {
    for (IFDStatusType term : diff) {
        String ifdName = term.getIFDName();
        // find out if the terminal is new, or only a slot got updated
        IFDStatusType oldTerm = getCorresponding(ifdName, currentState);
        boolean terminalAdded = oldTerm == null;
        IFDCapabilitiesType slotCapabilities = getCapabilities(ifdName);
        if (terminalAdded) {
            // TERMINAL ADDED
            // make copy of term
            oldTerm = new IFDStatusType();
            oldTerm.setIFDName(ifdName);
            oldTerm.setConnected(true);
            // add to current list
            currentState.add(oldTerm);
            // create event
            ConnectionHandleType h = makeConnectionHandle(ifdName, null, slotCapabilities);
            LOG.debug("Found a terminal added event ({}).", ifdName);
            env.getEventDispatcher().notify(EventType.TERMINAL_ADDED, new IfdEventObject(h));
        }
        // check each slot
        for (SlotStatusType slot : term.getSlotStatus()) {
            SlotStatusType oldSlot = getCorresponding(slot.getIndex(), oldTerm.getSlotStatus());
            boolean cardPresent = slot.isCardAvailable();
            boolean cardWasPresent = oldSlot != null && oldSlot.isCardAvailable();
            if (cardPresent && !cardWasPresent) {
                // CARD INSERTED
                // copy slot and add to list
                SlotStatusType newSlot = oldSlot;
                if (newSlot == null) {
                    newSlot = new SlotStatusType();
                    oldTerm.getSlotStatus().add(newSlot);
                }
                newSlot.setIndex(slot.getIndex());
                newSlot.setCardAvailable(true);
                newSlot.setATRorATS(slot.getATRorATS());
                // create event
                LOG.debug("Found a card insert event ({}).", ifdName);
                LOG.info("Card with ATR={} inserted.", ByteUtils.toHexString(slot.getATRorATS()));
                ConnectionHandleType handle = makeUnknownCardHandle(ifdName, newSlot, slotCapabilities);
                env.getEventDispatcher().notify(EventType.CARD_INSERTED, new IfdEventObject(handle));
                try {
                    SingleThreadChannel ch = cm.openMasterChannel(ifdName);
                    if (evtManager.isRecognize()) {
                        String proto = ch.getChannel().getCard().getProtocol().toUri();
                        evtManager.threadPool.submit(new Recognizer(env, handle, proto));
                    }
                } catch (NoSuchTerminal | SCIOException ex) {
                    LOG.error("Failed to connect card, nevertheless sending CARD_INSERTED event.", ex);
                }
            } else if (!terminalAdded && !cardPresent && cardWasPresent) {
                // this makes only sense when the terminal was already there
                // CARD REMOVED
                // remove slot entry
                BigInteger idx = oldSlot.getIndex();
                Iterator<SlotStatusType> it = oldTerm.getSlotStatus().iterator();
                while (it.hasNext()) {
                    SlotStatusType next = it.next();
                    if (idx.equals(next.getIndex())) {
                        it.remove();
                        break;
                    }
                }
                LOG.debug("Found a card removed event ({}).", ifdName);
                ConnectionHandleType h = makeConnectionHandle(ifdName, idx, slotCapabilities);
                env.getEventDispatcher().notify(EventType.CARD_REMOVED, new IfdEventObject(h));
            }
        }
        // terminal removed event comes after card removed events
        boolean terminalPresent = term.isConnected();
        if (!terminalPresent) {
            // TERMINAL REMOVED
            Iterator<IFDStatusType> it = currentState.iterator();
            while (it.hasNext()) {
                IFDStatusType toDel = it.next();
                if (toDel.getIFDName().equals(term.getIFDName())) {
                    it.remove();
                }
            }
            ConnectionHandleType h = makeConnectionHandle(ifdName, null, slotCapabilities);
            LOG.debug("Found a terminal removed event ({}).", ifdName);
            env.getEventDispatcher().notify(EventType.TERMINAL_REMOVED, new IfdEventObject(h));
        }
    }
}
Also used : ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) NoSuchTerminal(org.openecard.common.ifd.scio.NoSuchTerminal) SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) IFDCapabilitiesType(iso.std.iso_iec._24727.tech.schema.IFDCapabilitiesType) Iterator(java.util.Iterator) BigInteger(java.math.BigInteger) IFDStatusType(iso.std.iso_iec._24727.tech.schema.IFDStatusType) SlotStatusType(iso.std.iso_iec._24727.tech.schema.SlotStatusType) IfdEventObject(org.openecard.common.event.IfdEventObject)

Example 2 with SlotStatusType

use of iso.std.iso_iec._24727.tech.schema.SlotStatusType in project open-ecard by ecsec.

the class EventWatcher method convert.

@Nonnull
private IFDStatusType convert(@Nonnull TerminalState next) {
    IFDStatusType result = new IFDStatusType();
    result.setIFDName(next.getName());
    result.setConnected(true);
    SlotStatusType slot = new SlotStatusType();
    result.getSlotStatus().add(slot);
    slot.setIndex(BigInteger.ZERO);
    slot.setCardAvailable(next.isCardPresent());
    return result;
}
Also used : IFDStatusType(iso.std.iso_iec._24727.tech.schema.IFDStatusType) SlotStatusType(iso.std.iso_iec._24727.tech.schema.SlotStatusType) Nonnull(javax.annotation.Nonnull)

Example 3 with SlotStatusType

use of iso.std.iso_iec._24727.tech.schema.SlotStatusType in project open-ecard by ecsec.

the class EventWatcher method createEmptySlot.

private static SlotStatusType createEmptySlot() {
    SlotStatusType slot = new SlotStatusType();
    slot.setCardAvailable(false);
    slot.setIndex(BigInteger.ZERO);
    return slot;
}
Also used : SlotStatusType(iso.std.iso_iec._24727.tech.schema.SlotStatusType)

Example 4 with SlotStatusType

use of iso.std.iso_iec._24727.tech.schema.SlotStatusType in project open-ecard by ecsec.

the class EventWatcher method clone.

@Nonnull
private static IFDStatusType clone(@Nonnull IFDStatusType orig) {
    IFDStatusType newStat = new IFDStatusType();
    newStat.setIFDName(orig.getIFDName());
    newStat.setConnected(orig.isConnected());
    for (SlotStatusType next : orig.getSlotStatus()) {
        newStat.getSlotStatus().add(clone(next));
    }
    return newStat;
}
Also used : IFDStatusType(iso.std.iso_iec._24727.tech.schema.IFDStatusType) SlotStatusType(iso.std.iso_iec._24727.tech.schema.SlotStatusType) Nonnull(javax.annotation.Nonnull)

Example 5 with SlotStatusType

use of iso.std.iso_iec._24727.tech.schema.SlotStatusType in project open-ecard by ecsec.

the class IFD method wait.

@Override
public WaitResponse wait(Wait parameters) {
    WaitResponse response;
    // you thought of a different IFD obviously
    if (!ByteUtils.compare(ctxHandle, parameters.getContextHandle())) {
        String msg = "Invalid context handle specified.";
        Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_CONTEXT_HANDLE, msg);
        response = WSHelper.makeResponse(WaitResponse.class, r);
        return response;
    }
    // get timeout value
    BigInteger timeout = parameters.getTimeOut();
    if (timeout == null) {
        timeout = BigInteger.valueOf(Long.MAX_VALUE);
    }
    if (timeout.signum() == -1 || timeout.signum() == 0) {
        String msg = "Invalid timeout value given, must be strictly positive.";
        Result r = WSHelper.makeResultUnknownError(msg);
        response = WSHelper.makeResponse(WaitResponse.class, r);
        return response;
    }
    long timeoutL;
    try {
        timeoutL = (long) timeout.doubleValue();
    } catch (ArithmeticException ex) {
        LOG.warn("Too big timeout value give, shortening to Long.MAX_VALUE.");
        timeoutL = Long.MAX_VALUE;
    }
    ChannelHandleType callback = parameters.getCallback();
    // callback is only useful with a protocol termination point
    if (callback != null && callback.getProtocolTerminationPoint() == null) {
        callback = null;
    }
    // if callback, generate session id
    String sessionId = null;
    if (callback != null) {
        ChannelHandleType newCallback = new ChannelHandleType();
        newCallback.setBinding(callback.getBinding());
        newCallback.setPathSecurity(callback.getPathSecurity());
        newCallback.setProtocolTerminationPoint(callback.getProtocolTerminationPoint());
        sessionId = ValueGenerators.genBase64Session();
        newCallback.setSessionIdentifier(sessionId);
        callback = newCallback;
    }
    try {
        EventWatcher watcher = new EventWatcher(cm, timeoutL, callback);
        List<IFDStatusType> initialState = watcher.start();
        // get expected status or initial status for all if none specified
        List<IFDStatusType> expectedState = parameters.getIFDStatus();
        if (expectedState.isEmpty()) {
            expectedState = initialState;
        } else {
            for (IFDStatusType s : expectedState) {
                // check that ifdname is present, needed for comparison
                if (s.getIFDName() == null) {
                    String msg = "IFD in a request IFDStatus not known.";
                    Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.Terminal.UNKNOWN_IFD, msg);
                    response = WSHelper.makeResponse(WaitResponse.class, r);
                    return response;
                }
                // check that at least one slot entry is present
                if (s.getSlotStatus().isEmpty()) {
                    // assume an empty one
                    SlotStatusType slot = new SlotStatusType();
                    slot.setCardAvailable(false);
                    slot.setIndex(BigInteger.ZERO);
                    s.getSlotStatus().add(slot);
                }
            }
        }
        watcher.setExpectedState(expectedState);
        // create the future and fire
        FutureTask<List<IFDStatusType>> future = new FutureTask<>(watcher);
        if (watcher.isAsync()) {
            // add future to async wait list
            asyncWaitThreads.put(sessionId, future);
            // finally run this darn thingy
            threadPool.execute(future);
            // prepare result with session id in it
            response = WSHelper.makeResponse(WaitResponse.class, WSHelper.makeResultOK());
            response.setSessionIdentifier(sessionId);
            return response;
        } else {
            // run wait in a future so it can be easily interrupted
            syncWaitThread = future;
            threadPool.execute(future);
            // get results from the future
            List<IFDStatusType> events = future.get();
            // prepare response
            response = WSHelper.makeResponse(WaitResponse.class, WSHelper.makeResultOK());
            response.getIFDEvent().addAll(events);
            return response;
        }
    } catch (SCIOException ex) {
        String msg = "Unknown SCIO error occured during wait call.";
        LOG.warn(msg, ex);
        Result r = WSHelper.makeResultUnknownError(msg);
        response = WSHelper.makeResponse(WaitResponse.class, r);
        return response;
    } catch (ExecutionException ex) {
        // this is the exception from within the future
        Throwable cause = ex.getCause();
        if (cause instanceof SCIOException) {
            String msg = "Unknown SCIO error occured during wait call.";
            LOG.warn(msg, cause);
            Result r = WSHelper.makeResultUnknownError(msg);
            response = WSHelper.makeResponse(WaitResponse.class, r);
        } else {
            String msg = "Unknown error during wait call.";
            LOG.error(msg, cause);
            Result r = WSHelper.makeResultUnknownError(msg);
            response = WSHelper.makeResponse(WaitResponse.class, r);
        }
        return response;
    } catch (InterruptedException ex) {
        String msg = "Wait interrupted by another thread.";
        LOG.warn(msg, ex);
        Result r = WSHelper.makeResultUnknownError(msg);
        response = WSHelper.makeResponse(WaitResponse.class, r);
        return response;
    }
}
Also used : SCIOException(org.openecard.common.ifd.scio.SCIOException) ChannelHandleType(iso.std.iso_iec._24727.tech.schema.ChannelHandleType) WaitResponse(iso.std.iso_iec._24727.tech.schema.WaitResponse) Result(oasis.names.tc.dss._1_0.core.schema.Result) FutureTask(java.util.concurrent.FutureTask) BigInteger(java.math.BigInteger) IFDStatusType(iso.std.iso_iec._24727.tech.schema.IFDStatusType) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) SlotStatusType(iso.std.iso_iec._24727.tech.schema.SlotStatusType) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

SlotStatusType (iso.std.iso_iec._24727.tech.schema.SlotStatusType)12 IFDStatusType (iso.std.iso_iec._24727.tech.schema.IFDStatusType)9 BigInteger (java.math.BigInteger)4 Nonnull (javax.annotation.Nonnull)4 SCIOException (org.openecard.common.ifd.scio.SCIOException)4 ArrayList (java.util.ArrayList)3 NoSuchTerminal (org.openecard.common.ifd.scio.NoSuchTerminal)3 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)2 SingleThreadChannel (org.openecard.ifd.scio.wrapper.SingleThreadChannel)2 ChannelHandleType (iso.std.iso_iec._24727.tech.schema.ChannelHandleType)1 GetStatus (iso.std.iso_iec._24727.tech.schema.GetStatus)1 GetStatusResponse (iso.std.iso_iec._24727.tech.schema.GetStatusResponse)1 IFDCapabilitiesType (iso.std.iso_iec._24727.tech.schema.IFDCapabilitiesType)1 WaitResponse (iso.std.iso_iec._24727.tech.schema.WaitResponse)1 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 ExecutionException (java.util.concurrent.ExecutionException)1 FutureTask (java.util.concurrent.FutureTask)1 Result (oasis.names.tc.dss._1_0.core.schema.Result)1