1 package org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific; 2 3 4 import java.nio.ByteBuffer; 5 6 import org.jscsi.target.scsi.cdb.CommandDescriptorBlock; 7 import org.jscsi.target.util.BitManip; 8 import org.jscsi.target.util.ReadWrite; 9 10 11 /** 12 * Field pointer sense-key-specific data is used to indicate that a certain field of a received command descriptor block 13 * contained an illegal value. 14 * 15 * @see CommandDescriptorBlock 16 * @author Andreas Ergenzinger 17 */ 18 public final class FieldPointerSenseKeySpecificData extends SenseKeySpecificData { 19 20 /** 21 * 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 22 * indicates that the illegal parameter is in the data parameters sent by the application client in the Data-Out 23 * Buffer. 24 */ 25 private final boolean commandData; 26 27 /** 28 * A bit pointer valid (BPV) bit set to zero indicates that the value in the BIT POINTER field is not valid. 29 */ 30 private final boolean bitPointerValid; 31 32 /** 33 * If {@link #bitPointerValid} is <code>true</code>, the BIT POINTER field specifies which bit of the byte 34 * designated by the FIELD POINTER field is in error. When a multiple-bit field is in error, the BIT POINTER field 35 * shall point to the first bit (i.e., the left-most bit) of the field. 36 */ 37 private final int bitPointer; 38 39 /** 40 * The FIELD POINTER field indicates which byte of the CDB or of the parameter data was in error. Bytes are numbered 41 * starting from zero, as shown in the tables describing the commands and parameters. When a multiple-byte field is 42 * in error, the field pointer shall point to the first byte (i.e., the left-most byte) of the field. If several 43 * consecutive bytes are reserved, each shall be treated as a single-byte field. 44 */ 45 private final short fieldPointer; 46 47 public FieldPointerSenseKeySpecificData (final boolean senseKeySpecificDataValid, final boolean commandData, final boolean bitPointerValid, final int bitPointer, final int fieldPointer) { 48 super(senseKeySpecificDataValid); 49 this.commandData = commandData; 50 this.bitPointerValid = bitPointerValid; 51 this.bitPointer = bitPointer; 52 this.fieldPointer = (short) fieldPointer; 53 } 54 55 @Override 56 protected void serializeSpecificFields (final ByteBuffer byteBuffer, final int index) { 57 58 byte b = byteBuffer.get(index);// SKSV bit has already been set and has 59 // to be preserved 60 61 // command data 62 b = BitManip.getByteWithBitSet(b, 6, commandData); 63 64 // bit pointer valid 65 b = BitManip.getByteWithBitSet(b, 3, bitPointerValid); 66 67 // bit pointer 68 b &= (bitPointer & 7); 69 70 // store first byte 71 byteBuffer.put(index, b); 72 73 // field pointer 74 ReadWrite.writeTwoByteInt(byteBuffer, fieldPointer, byteBuffer.position()); 75 } 76 }