package org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific;
import java.nio.ByteBuffer;
import org.jscsi.target.scsi.cdb.CommandDescriptorBlock;
import org.jscsi.target.util.BitManip;
import org.jscsi.target.util.ReadWrite;
/**
* Field pointer sense-key-specific data is used to indicate that a certain
* field of a received command descriptor block contained an illegal value.
*
* @see CommandDescriptorBlock
* @author Andreas Ergenzinger
*/
public final class FieldPointerSenseKeySpecificData extends SenseKeySpecificData {
/**
* A command data (C/D) bit set to one indicates that the illegal parameter
* is in the CDB. A C/D bit set to zero indicates that the illegal parameter
* is in the data parameters sent by the application client in the Data-Out
* Buffer.
*/
private final boolean commandData;
/**
* A bit pointer valid (BPV) bit set to zero indicates that the value in the
* BIT POINTER field is not valid.
*/
private final boolean bitPointerValid;
/**
* If {@link #bitPointerValid} is <code>true</code>, the BIT POINTER field
* specifies which bit of the byte designated by the FIELD POINTER field is
* in error. When a multiple-bit field is in error, the BIT POINTER field
* shall point to the first bit (i.e., the left-most bit) of the field.
*/
private final int bitPointer;
/**
* The FIELD POINTER field indicates which byte of the CDB or of the
* parameter data was in error. Bytes are numbered starting from zero, as
* shown in the tables describing the commands and parameters. When a
* multiple-byte field is in error, the field pointer shall point to the
* first byte (i.e., the left-most byte) of the field. If several
* consecutive bytes are reserved, each shall be treated as a single-byte
* field.
*/
private final short fieldPointer;
public FieldPointerSenseKeySpecificData(final boolean senseKeySpecificDataValid,
final boolean commandData, final boolean bitPointerValid, final int bitPointer, final int fieldPointer) {
super(senseKeySpecificDataValid);
this.commandData = commandData;
this.bitPointerValid = bitPointerValid;
this.bitPointer = bitPointer;
this.fieldPointer = (short)fieldPointer;
}
@Override
protected void serializeSpecificFields(final ByteBuffer byteBuffer, final int index) {
byte b = byteBuffer.get(index);// SKSV bit has already been set and has
// to be preserved
// command data
b = BitManip.getByteWithBitSet(b, 6, commandData);
// bit pointer valid
b = BitManip.getByteWithBitSet(b, 3, bitPointerValid);
// bit pointer
b &= (bitPointer & 7);
// store first byte
byteBuffer.put(index, b);
// field pointer
ReadWrite.writeTwoByteInt(byteBuffer, fieldPointer, byteBuffer.position());
}
}