org.eclipse.keyple.calypso.transaction.SamResourceManager Maven / Gradle / Ivy
/* **************************************************************************************
* Copyright (c) 2020 Calypso Networks Association https://www.calypsonet-asso.org/
*
* See the NOTICE file(s) distributed with this work for additional information
* regarding copyright ownership.
*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
************************************************************************************** */
package org.eclipse.keyple.calypso.transaction;
import static org.eclipse.keyple.calypso.command.sam.SamRevision.AUTO;
import org.eclipse.keyple.calypso.exception.CalypsoNoSamResourceAvailableException;
import org.eclipse.keyple.core.card.selection.CardResource;
import org.eclipse.keyple.core.card.selection.CardSelection;
import org.eclipse.keyple.core.card.selection.SelectionsResult;
import org.eclipse.keyple.core.service.Reader;
import org.eclipse.keyple.core.service.exception.KeypleAllocationReaderException;
import org.eclipse.keyple.core.service.exception.KeypleException;
import org.eclipse.keyple.core.service.exception.KeypleReaderException;
/**
* Management of SAM resources:
*
* Provides methods fot the allocation/deallocation of SAM resources
*/
public abstract class SamResourceManager {
public enum AllocationMode {
BLOCKING,
NON_BLOCKING
}
/**
* Allocate a SAM resource from the specified SAM group.
*
*
In the case where the allocation mode is BLOCKING, this method will wait until a SAM
* resource becomes free and then return the reference to the allocated resource. However, the
* BLOCKING mode will wait a maximum time defined in milliseconds by MAX_BLOCKING_TIME.
*
*
In the case where the allocation mode is NON_BLOCKING and no SAM resource is available, this
* method will return an exception.
*
*
If the samGroup argument is null, the first available SAM resource will be selected and
* returned regardless of its group.
*
* @param allocationMode the blocking/non-blocking mode
* @param samIdentifier the targeted SAM identifier
* @return a SAM resource
* @throws CalypsoNoSamResourceAvailableException if no resource is available
* @throws KeypleReaderException if a reader error occurs
* @throws KeypleAllocationReaderException if reader allocation fails
*/
public abstract CardResource allocateSamResource(
AllocationMode allocationMode, SamIdentifier samIdentifier);
/**
* Free a previously allocated SAM resource.
*
* @param samResource the SAM resource reference to free
*/
public abstract void freeSamResource(CardResource samResource);
/**
* Create a SAM resource from the provided SAM reader.
*
* Proceed with the SAM selection and combine the SAM reader and the Calypso SAM resulting from
* the selection.
*
* @param samReader the SAM reader with which the APDU exchanges will be done.
* @return a {@link CardResource}
* @throws CalypsoNoSamResourceAvailableException if an error occurs while doing the selection
*/
protected SamResourceManagerDefault.ManagedSamResource createSamResource(Reader samReader) {
CardSelection samSelection = new CardSelection();
/* Prepare selector */
samSelection.prepareSelection(
new SamSelectionRequest(
SamSelector.builder()
.samIdentifier(SamIdentifier.builder().samRevision(AUTO).build())
.build()));
SelectionsResult selectionsResult = null;
try {
selectionsResult = samSelection.processExplicitSelection(samReader);
} catch (KeypleException e) {
throw new CalypsoNoSamResourceAvailableException("Failed to select a SAM");
}
if (!selectionsResult.hasActiveSelection()) {
throw new CalypsoNoSamResourceAvailableException("Unable to open a logical channel for SAM!");
}
CalypsoSam calypsoSam = (CalypsoSam) selectionsResult.getActiveSmartCard();
return new SamResourceManagerDefault.ManagedSamResource(samReader, calypsoSam);
}
}