package de.persosim.simulator.platform;
import static org.globaltester.logging.BasicLogger.TRACE;
import static org.globaltester.logging.BasicLogger.log;
import static org.globaltester.logging.BasicLogger.logException;
import org.globaltester.logging.InfoSource;
import de.persosim.simulator.apdu.ResponseApdu;
import de.persosim.simulator.exception.GeneralException;
import de.persosim.simulator.processing.ProcessingData;
/**
* @author slutters
*
*/
public abstract class Layer implements Iso7816, InfoSource {
protected ProcessingData processingData;
/**
* This method finalizes the layer so it can actually be used. It is to be
* called when the layer is ready to be used.
*/
abstract public void initializeForUse();
/**
* Power-management function. This method is called by the
* {@link PersoSimKernel} to notify each layer of the simulated power on of
* the card.
*
* Default implementation does nothing but logging. Subclasses are expected
* to override this behavior if needed.
*/
public void powerOn() {
log(this, "powerOn, nothing needs to be done for this layer", TRACE);
}
/**
* Power-management function. This method is called by the
* {@link PersoSimKernel} to notify each layer of the simulated power off of
* the card.
*
* Default implementation does nothing but logging. Subclasses are expected
* to override this behavior if needed.
*/
public void powerOff() {
log(this, "powerOff, nothing needs to be done for this layer", TRACE);
}
/**
* Central processing routine for events handed up from a lower layer.
* Actual layer specific processing is done in {@link #processAscending()}
* @param pData processingData collected during processing of the APDU
*/
public final void processAscending(ProcessingData pData) {
try{
this.processingData = pData;
processAscending();
log(this, "successfully processed ascending APDU", TRACE);
} catch(GeneralException e) {
logException(this, e);
//create and propagate response APDU
ResponseApdu resp = new ResponseApdu(e.getStatusWord());
pData.updateResponseAPDU(this, "Generic error handling", resp);
}
}
/**
* Layer specific processing of ascending APDUs.
*
* Default implementation does nothing but logging. Subclasses are expected
* to override this behavior. In order to access the current processingData
* subclasses can rely on the value of {@link #processingData} which is
* guaranteed to be set during execution of this method.
*
*/
public void processAscending() {
log(this, "skipped processing of ascending APDU", TRACE);
}
/**
* Central processing routine for events handed down from a higher layer.
* Actual layer specific processing is done in {@link #processDescending()}
* @param pData processingData collected during processing of the APDU
*/
public final void processDescending(ProcessingData pData) {
try{
this.processingData = pData;
this.processDescending();
} catch(GeneralException e) {
logException(this, e);
//create and propagate response APDU
ResponseApdu resp = new ResponseApdu(e.getStatusWord());
pData.updateResponseAPDU(this, "Generic error handling", resp);
}
}
/**
* Layer specific processing of descending APDUs.
*
* Default implementation does nothing but logging. Subclasses are expected
* to override this behavior. In order to access the current processingData
* subclasses can rely on the value of {@link #processingData} which is
* guaranteed to be set during execution of this method.
*
*/
public void processDescending() {
log(this, "skipped processing of descending APDU", TRACE);
}
/**
* Returns the human readable name of this layer. This identifier should
* allow the reader to distinguish the given layer from other layers as well
* as other implementations.
*
* @return human readable name
*/
public abstract String getLayerName();
@Override
public String getIDString() {
return "Layer " + getLayerName();
}
public ProcessingData getProcessingData() {
return processingData;
}
}