package org.jscsi.target.connection.stage.fullfeature;
import java.io.IOException;
import java.security.DigestException;
import org.jscsi.exception.InternetSCSIException;
import org.jscsi.parser.BasicHeaderSegment;
import org.jscsi.parser.ProtocolDataUnit;
import org.jscsi.parser.scsi.SCSICommandParser;
import org.jscsi.target.connection.phase.TargetFullFeaturePhase;
import org.jscsi.target.scsi.cdb.ReportLunsCDB;
import org.jscsi.target.scsi.cdb.SelectReport;
import org.jscsi.target.scsi.lun.ReportLunsParameterData;
import org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific.FieldPointerSenseKeySpecificData;
import org.jscsi.target.settings.SettingsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A stage for processing <code>REPORT LUNS</code> SCSI commands.
*
* @author Andreas Ergenzinger
*/
public class ReportLunsStage extends TargetFullFeatureStage {
private static final Logger LOGGER = LoggerFactory.getLogger(ReportLunsStage.class);
public ReportLunsStage(TargetFullFeaturePhase targetFullFeaturePhase) {
super(targetFullFeaturePhase);
}
@Override
public void execute(ProtocolDataUnit pdu) throws IOException, InterruptedException,
InternetSCSIException, DigestException, SettingsException {
final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
final SCSICommandParser parser = (SCSICommandParser)bhs.getParser();
ProtocolDataUnit responsePdu = null;// the response PDU
// get command details in CDB
final ReportLunsCDB cdb = new ReportLunsCDB(parser.getCDB());
final FieldPointerSenseKeySpecificData[] illegalFieldPointers = cdb.getIllegalFieldPointers();
if (illegalFieldPointers != null) {
// an illegal request has been made
responsePdu = createFixedFormatErrorPdu(illegalFieldPointers,// senseKeySpecificData
bhs.getInitiatorTaskTag(),// initiatorTaskTag
parser.getExpectedDataTransferLength());// expectedDataTransferLength
// send response
connection.sendPdu(responsePdu);
} else {
// PDU is okay
// carry out command
final SelectReport selectReport = cdb.getSelectReport();
LOGGER.debug("selectReport = " + selectReport);
// there are only well known LUNs
ReportLunsParameterData reportLunsParameterData;
// TODO the switch isn't really needed right now, but maybe in
// future implementations
switch (selectReport) {
case SELECTED_ADDRESSING_METHODS:
case WELL_KNOWN_LUNS_ONLY:
case ALL:
reportLunsParameterData =
new ReportLunsParameterData(session.getTargetServer().getConfig().getLogicalUnitNumber());
break;
default:
throw new InternetSCSIException();
/*
* Unreachable, this case has already been checked in the
* ReportLunsCDB constructor
*/
}
// send response
sendResponse(bhs.getInitiatorTaskTag(),// initiatorTaskTag
parser.getExpectedDataTransferLength(),// expectedDataTransferLength
reportLunsParameterData);// responseData
}
}
}