@Override
public ProtocolDataUnit check (final Connection pConnection) throws InterruptedException , IOException , InternetSCSIException {
ProtocolDataUnit responsePdu;
final BasicHeaderSegment bhs = new ProtocolDataUnitFactory().create(false, true, OperationCode.SCSI_TM_REQUEST, "None", "None").getBasicHeaderSegment();
final InitiatorMessageParser parser = (InitiatorMessageParser) bhs.getParser();
final FieldPointerSenseKeySpecificData fp = new FieldPointerSenseKeySpecificData(true,// senseKeySpecificDataValid
true,// commandData (i.e. invalid field in CDB)
false,// bitPointerValid
0,// bitPointer, reserved since invalid
0);// fieldPointer to the SCSI OpCode field
final FieldPointerSenseKeySpecificData[] fpArray = new FieldPointerSenseKeySpecificData[] { fp };
// create the whole sense data
FixedFormatSenseData senseData = new FixedFormatSenseData(false,// valid
ErrorType.CURRENT,// error type
false,// file mark
false,// end of medium
false,// incorrect length indicator
SenseKey.ILLEGAL_REQUEST,// sense key
new FourByteInformation(),// information
new FourByteInformation(),// command specific information
AdditionalSenseCodeAndQualifier.INVALID_FIELD_IN_CDB,// additional sense
// code and
// qualifier
(byte) 0,// field replaceable unit code
fpArray[0],// sense key specific data, only report
// first problem
new AdditionalSenseBytes());// additional sense bytes
// keep only the part of the sense data that will be sent
final ScsiResponseDataSegment dataSegment = new ScsiResponseDataSegment(senseData, parser.getExpectedStatusSequenceNumber());
final int senseDataSize = senseData.size();
// calculate residuals and flags
final int residualCount = Math.abs(parser.getExpectedStatusSequenceNumber() - senseDataSize);
final boolean residualOverflow = parser.getExpectedStatusSequenceNumber() < senseDataSize;
final boolean residualUnderflow = parser.getExpectedStatusSequenceNumber() > senseDataSize;
// create and return PDU
responsePdu = TargetPduFactory.createSCSIResponsePdu(false,// bidirectionalReadResidualOverflow
false,// bidirectionalReadResidualUnderflow
residualOverflow,// residualOverflow
residualUnderflow,// residualUnderflow,
SCSIResponseParser.ServiceResponse.COMMAND_COMPLETED_AT_TARGET,// response,
SCSIStatus.CHECK_CONDITION,// status,
bhs.getInitiatorTaskTag(),// initiatorTaskTag,
0,// snackTag
0,// expectedDataSequenceNumber
0,// bidirectionalReadResidualCount
residualCount,// residualCount
dataSegment);// data segment
return responsePdu;
}
}, // FormatUnitStage checker
new Checker() {
@Override
public ProtocolDataUnit check (final Connection pConnection) throws InterruptedException , IOException , InternetSCSIException {
ProtocolDataUnit responsePdu;
final BasicHeaderSegment bhs = new ProtocolDataUnitFactory().create(false, true, OperationCode.SCSI_COMMAND, "None", "None").getBasicHeaderSegment();
final SCSICommandParser parser = (SCSICommandParser) bhs.getParser();
// Taken from the stage
final int residualCount = Math.abs(parser.getExpectedDataTransferLength() - 0);
final boolean residualOverflow = parser.getExpectedDataTransferLength() < 0;
final boolean residualUnderflow = parser.getExpectedDataTransferLength() > 0;
responsePdu = TargetPduFactory.createSCSIResponsePdu(false,// bidirectionalReadResidualOverflow
false,// bidirectionalReadResidualUnderflow
residualOverflow,// residualOverflow,
residualUnderflow,// residualUnderflow,