package org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific;
import java.nio.ByteBuffer;
import org.jscsi.target.scsi.ISerializable;
import org.jscsi.target.scsi.sense.SenseData;
import org.jscsi.target.scsi.sense.SenseKey;
import org.jscsi.target.util.BitManip;
/**
* SENSE-KEY-SPECIFIC DATA further defines the reason for a CHECK CONDITION SCSI
* response status.
* <p>
* The definition of the SENSE KEY SPECIFIC field is determined by the value of the enclosing sense data's
* {@link SenseData#senseKey} field.
*
* <table border="1">
* <tr>
* <th>Sense Key</th>
* <th>Sense Key Specific Field Definition</th>
* </tr>
* <tr>
* <td>{@link SenseKey#ILLEGAL_REQUEST}</td>
* <td>Field Pointer (see {@link FieldPointerSenseKeySpecificData})</td>
* </tr>
* <tr>
* <td>{@link SenseKey#HARDWARE_ERROR},<br>
* {@link SenseKey#MEDIUM_ERROR}, or<br>
* {@link SenseKey#RECOVERED_ERROR}</td>
* <td>Actual Retry Count (see {@link ActualRetryCountSenseKeySpecificData})</td>
* </tr>
* <tr>
* <td>{@link SenseKey#NO_SENSE} or<br>
* {@link SenseKey#NOT_READY}</td>
* <td>Progress Indication (see {@link ProgressIndicationSenseKeySpecificData})</td>
* </tr>
* <tr>
* <td>{@link SenseKey#COPY_ABORTED}</td>
* <td>Segment Pointer (see {@link SegmentPointerSenseKeySpecificData})</td>
* </tr>
* <tr>
* <td>All other Sense Keys</td>
* <td>The sense key specific sense data descriptor shall not<br>
* appear in the descriptor format sense data and the<br>
* SKSV (Sense Key Specific Field Valid) bit shall be set to<br>
* zero in the fixed format sense data.</td>
* </tr>
* </table>
*
* @author Andreas Ergenzinger
*/
public abstract class SenseKeySpecificData implements ISerializable {
/**
* The serialized length in bytes of SENSE-KEY-SPECIFIC DATA.
*/
public static final int SIZE = 3;
/**
* <code>true</code> if and only if the information fields of this data
* object are valid.
*/
protected final boolean senseKeySpecificDataValid;
/**
* The absctract constructor.
*
* @param senseKeySpecificDataValid
* <code>true</code> if and only if the information fields of
* this data object are valid
*/
public SenseKeySpecificData(final boolean senseKeySpecificDataValid) {
this.senseKeySpecificDataValid = senseKeySpecificDataValid;
}
/**
* Serializes the fields common to all sense-key-specific data.
*
* @param byteBuffer
* where the serialized fields will be stored
* @param index
* the position of the first byte of the sense data descriptor in
* the {@link ByteBuffer}
*/
private final void serializeCommonFields(final ByteBuffer byteBuffer, final int index) {
byteBuffer.position(index);
byte b = 0;
if (senseKeySpecificDataValid)
b = BitManip.getByteWithBitSet(b, 7, true);// set MSB to 1
byteBuffer.put(b);
}
/**
* Serializes all fields which are not common to all sense-key-specific
* data, which means those that are sub-type-specific.
*
* @param byteBuffer
* where the serialized fields will be stored
* @param index
* the position of the first byte of the sense data descriptor in
* the {@link ByteBuffer}
*/
protected abstract void serializeSpecificFields(ByteBuffer byteBuffer, final int index);
public void serialize(ByteBuffer byteBuffer, int index) {
serializeCommonFields(byteBuffer, index);
serializeSpecificFields(byteBuffer, index);
}
public int size() {
return SIZE;
}
}