use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.
the class IFD method destroyChannel.
@Override
public DestroyChannelResponse destroyChannel(DestroyChannel parameters) {
try {
DestroyChannelResponse destroyChannelResponse = new DestroyChannelResponse();
byte[] slotHandle = parameters.getSlotHandle();
SingleThreadChannel channel = cm.getSlaveChannel(slotHandle);
TerminalInfo termInfo = new TerminalInfo(cm, channel);
// check if it is PACE and try to perform native implementation
// get pace capabilities
List<PACECapabilities.PACECapability> paceCapabilities = termInfo.getPACECapabilities();
if (paceCapabilities.contains(PACECapabilities.PACECapability.DestroyPACEChannel)) {
ExecutePACERequest execPaceReq = new ExecutePACERequest(ExecutePACERequest.Function.DestroyPACEChannel);
byte[] reqData = execPaceReq.toBytes();
LOG.debug("executeCtrlCode request: {}", ByteUtils.toHexString(reqData));
// execute pace
Map<Integer, Integer> features = termInfo.getFeatureCodes();
byte[] resData = channel.transmitControlCommand(features.get(PCSCFeatures.EXECUTE_PACE), reqData);
LOG.debug("Response of executeCtrlCode: {}", ByteUtils.toHexString(resData));
// evaluate response
ExecutePACEResponse execPaceRes = new ExecutePACEResponse(resData);
if (execPaceRes.isError()) {
destroyChannelResponse = WSHelper.makeResponse(DestroyChannelResponse.class, execPaceRes.getResult());
}
}
channel.removeSecureMessaging();
if (destroyChannelResponse.getResult() == null) {
Result r = new Result();
r.setResultMajor(ECardConstants.Major.OK);
destroyChannelResponse.setResult(r);
}
return destroyChannelResponse;
} catch (Throwable t) {
return WSHelper.makeResponse(DestroyChannelResponse.class, WSHelper.makeResult(t));
}
}
use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.
the class IFD method connect.
@Override
public ConnectResponse connect(Connect parameters) {
try {
ConnectResponse response;
// check if the requested handle is valid
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(ConnectResponse.class, r);
return response;
} else {
try {
String name = parameters.getIFDName();
// make sure the slot is connected before attemting to get a slave channel
cm.openMasterChannel(name);
byte[] slotHandle = cm.openSlaveChannel(name).p1;
SingleThreadChannel ch = cm.getSlaveChannel(slotHandle);
// make connection exclusive
Boolean exclusive = parameters.isExclusive();
if (exclusive != null && exclusive == true) {
BeginTransaction transact = new BeginTransaction();
transact.setSlotHandle(slotHandle);
BeginTransactionResponse resp = beginTransaction(transact);
if (resp.getResult().getResultMajor().equals(ECardConstants.Major.ERROR)) {
// destroy channel, when not successful here
ch.shutdown();
response = WSHelper.makeResponse(ConnectResponse.class, resp.getResult());
return response;
}
}
// connection established, return result
response = WSHelper.makeResponse(ConnectResponse.class, WSHelper.makeResultOK());
response.setSlotHandle(slotHandle);
return response;
} catch (NoSuchTerminal | NullPointerException ex) {
String msg = "The requested terminal does not exist.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.Terminal.UNKNOWN_IFD, msg);
response = WSHelper.makeResponse(ConnectResponse.class, r);
LOG.warn(msg, ex);
return response;
} catch (IllegalStateException ex) {
String msg = "No card available in the requested terminal.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.Terminal.NO_CARD, msg);
response = WSHelper.makeResponse(ConnectResponse.class, r);
LOG.warn(msg, ex);
return response;
} catch (SCIOException ex) {
String msg = "Unknown error in the underlying SCIO implementation.";
Result r = WSHelper.makeResultUnknownError(msg);
response = WSHelper.makeResponse(ConnectResponse.class, r);
LOG.warn(msg, ex);
return response;
}
}
} catch (Exception ex) {
LOG.warn(ex.getMessage(), ex);
throwThreadKillException(ex);
return WSHelper.makeResponse(ConnectResponse.class, WSHelper.makeResult(ex));
}
}
use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.
the class IFD method disconnect.
@Override
public synchronized DisconnectResponse disconnect(Disconnect parameters) {
try {
DisconnectResponse response;
if (!hasContext()) {
String msg = "Context not initialized.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
response = WSHelper.makeResponse(DisconnectResponse.class, r);
return response;
}
try {
byte[] handle = parameters.getSlotHandle();
SingleThreadChannel ch = cm.getSlaveChannel(handle);
cm.closeSlaveChannel(handle);
// process actions
SCIOCard card = ch.getChannel().getCard();
ActionType action = parameters.getAction();
if (ActionType.RESET == action) {
String ifdName = card.getTerminal().getName();
SingleThreadChannel master = cm.getMasterChannel(ifdName);
HandlerBuilder builder = HandlerBuilder.create();
ConnectionHandleType cHandleIn = builder.setCardType(ECardConstants.UNKNOWN_CARD).setCardIdentifier(card.getATR().getBytes()).setContextHandle(ctxHandle).setIfdName(ifdName).setSlotIdx(BigInteger.ZERO).buildConnectionHandle();
builder = HandlerBuilder.create();
ConnectionHandleType cHandleRm = builder.setContextHandle(ctxHandle).setIfdName(ifdName).setSlotIdx(BigInteger.ZERO).buildConnectionHandle();
try {
master.reconnect();
evManager.resetCard(cHandleRm, cHandleIn, card.getProtocol().toUri());
} catch (IllegalStateException ex) {
LOG.warn("Card reconnect failed, trying to establish new card connection.", ex);
cm.closeMasterChannel(ifdName);
LOG.debug("Master channel closed successfully.");
try {
cm.getMasterChannel(ifdName);
LOG.debug("New card connection established successfully.");
evManager.resetCard(cHandleRm, cHandleIn, card.getProtocol().toUri());
} catch (NoSuchTerminal ex2) {
LOG.error("No terminal present anymore.", ex);
}
}
}
// TODO: take care of other actions (probably over ControlIFD)
// the default is to not disconnect the card, because all existing connections would be broken
response = WSHelper.makeResponse(DisconnectResponse.class, WSHelper.makeResultOK());
return response;
} catch (NoSuchChannel ex) {
String msg = "No card available in the requested terminal.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
response = WSHelper.makeResponse(DisconnectResponse.class, r);
LOG.warn(msg, ex);
return response;
} catch (SCIOException ex) {
String msg = "Unknown error in the underlying SCIO implementation.";
Result r = WSHelper.makeResultUnknownError(msg);
response = WSHelper.makeResponse(DisconnectResponse.class, r);
LOG.warn(msg, ex);
return response;
}
} catch (Exception ex) {
LOG.warn(ex.getMessage(), ex);
throwThreadKillException(ex);
return WSHelper.makeResponse(DisconnectResponse.class, WSHelper.makeResult(ex));
}
}
use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.
the class IFD method endTransaction.
@Override
public EndTransactionResponse endTransaction(EndTransaction parameters) {
try {
EndTransactionResponse response;
if (!hasContext()) {
String msg = "Context not initialized.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
response = WSHelper.makeResponse(EndTransactionResponse.class, r);
return response;
}
try {
byte[] handle = parameters.getSlotHandle();
SingleThreadChannel ch = cm.getSlaveChannel(handle);
ch.endExclusive();
} catch (NoSuchChannel | IllegalStateException ex) {
String msg = "No card with transaction available in the requested terminal.";
Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
response = WSHelper.makeResponse(EndTransactionResponse.class, r);
LOG.warn(msg, ex);
return response;
} catch (SCIOException ex) {
String msg = "Unknown error in the underlying SCIO implementation.";
Result r = WSHelper.makeResultUnknownError(msg);
response = WSHelper.makeResponse(EndTransactionResponse.class, r);
LOG.warn(msg, ex);
return response;
}
response = WSHelper.makeResponse(EndTransactionResponse.class, WSHelper.makeResultOK());
return response;
} catch (Exception ex) {
LOG.warn(ex.getMessage(), ex);
throwThreadKillException(ex);
return WSHelper.makeResponse(EndTransactionResponse.class, WSHelper.makeResult(ex));
}
}
use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.
the class EventWatcher method updateState.
private void updateState(TerminalWatcher.StateChangeEvent event) {
String name = event.getTerminal();
if (event.getState() == TerminalWatcher.EventType.TERMINAL_ADDED) {
currentState.add(createEmptyState(name));
} else {
Iterator<IFDStatusType> it = currentState.iterator();
while (it.hasNext()) {
IFDStatusType next = it.next();
SlotStatusType slot = next.getSlotStatus().get(0);
if (next.getIFDName().equals(name)) {
switch(event.getState()) {
case CARD_INSERTED:
try {
SingleThreadChannel ch = cm.openMasterChannel(name);
slot.setCardAvailable(true);
slot.setATRorATS(ch.getChannel().getCard().getATR().getBytes());
} catch (NoSuchTerminal | SCIOException ex) {
LOG.error("Failed to open master channel for terminal '" + name + "'.", ex);
slot.setCardAvailable(false);
cm.closeMasterChannel(name);
}
break;
case CARD_REMOVED:
cm.closeMasterChannel(name);
slot.setCardAvailable(false);
break;
case TERMINAL_REMOVED:
// just in case
slot.setCardAvailable(false);
next.setConnected(false);
break;
}
// no need to look any further
break;
}
}
}
}
Aggregations