1 package org.jscsi.target.scsi.modeSense; 2 3 4 import java.nio.ByteBuffer; 5 6 import org.jscsi.target.scsi.ISerializable; 7 import org.jscsi.target.util.BitManip; 8 9 10 /** 11 * MODE PAGEs are sent in response to successful <code>MODE SENSE</code> SCSI commands. There are two different, 12 * command-specific formats for MODE PAGEs - the PAGE_0 FORMAT and the SUB-PAGE FORMAT, represented by the non-abstract 13 * children of this class, {@link Page_0FormatModePage} and {@link SubPageFormatModePage}, respectively. 14 * 15 * @author Andreas Ergenzinger 16 */ 17 public abstract class ModePage implements ISerializable { 18 19 /** 20 * This value plus {@link #pageLength} equals the length in bytes of a MODE PAGE using the SUB-PAGE FORMAT. 21 */ 22 private static final int SUB_PAGE_FORMAT_PAGE_LENGTH_MODIFIER = 4; 23 24 /** 25 * This value plus {@link #pageLength} equals the length in bytes of a MODE PAGE using the PAGE_0 FORMAT. 26 */ 27 private static final int PAGE_0_FORMAT_PAGE_LENGTH_MODIFIER = 2; 28 29 /** 30 * When using the MODE SENSE command, a parameters saveable (PS) bit set to one indicates that the mode page may be 31 * saved by the logical unit in a nonvolatile, vendor specific location. A PS bit set to zero indicates that the 32 * device server is not able to save the supporte parameters. When using the MODE SELECT command, the PS bit is 33 * reserved. 34 */ 35 private final boolean parametersSaveable; 36 37 /** 38 * A SubPage Format (SPF) bit set to <code>false</code>/zero indicates that the page_0 mode page format is being 39 * used. A SPF bit set to <code>true</code>/one indicates that the sub_page mode page format is being used. 40 */ 41 private final boolean subPageFormat; 42 43 /** 44 * Specifies what kind of information is contained in the MODE PAGE. 45 */ 46 private final int pageCode; 47 48 /** 49 * The number of bytes following the PAGE LENGTH field. 50 */ 51 protected final int pageLength; 52 53 /** 54 * This value plus {@link #pageLength} equals the length in bytes of the MODE PAGE. 55 */ 56 private final int pageLengthModifier; 57 58 /** 59 * The abstract constructor. 60 * 61 * @param parametersSaveable value of the PARAMETERS SAVEABLE bit 62 * @param subPageFormat <code>true</code> if and only if the SUB-PAGE FORMAT is to be used 63 * @param pageCode specifies the kind of information is contained in the MODE PAGE 64 * @param pageLength the value of the PAGE LENGTH field 65 */ 66 public ModePage (final boolean parametersSaveable, final boolean subPageFormat, final int pageCode, final int pageLength) { 67 this.parametersSaveable = parametersSaveable; 68 this.subPageFormat = subPageFormat; 69 if (subPageFormat) 70 pageLengthModifier = SUB_PAGE_FORMAT_PAGE_LENGTH_MODIFIER; 71 else 72 pageLengthModifier = PAGE_0_FORMAT_PAGE_LENGTH_MODIFIER; 73 this.pageCode = pageCode; 74 this.pageLength = pageLength; 75 } 76 77 public final void serialize (final ByteBuffer byteBuffer, final int index) { 78 // serialize first byte 79 // (for convenience reasons from least significant to most significant 80 // field) 81 byte b = (byte) pageCode;// PAGE CODE 82 b = BitManip.getByteWithBitSet(b, 6, subPageFormat);// SPF 83 b = BitManip.getByteWithBitSet(b, 7, parametersSaveable);// PS 84 byteBuffer.position(index); 85 byteBuffer.put(b); 86 // serialize remaining fields 87 serializeSubPageCode(byteBuffer, index); 88 serializePageLength(byteBuffer, index); 89 serializeModeParameters(byteBuffer, index); 90 } 91 92 /** 93 * This method serializes the SUBPAGE CODE field, if the mode page format says this field exists (only for the 94 * sub_page mode page format). 95 * 96 * @param buffer where to insert the serialized object representation 97 * @param index the position of the first byte of the serialized object in the {@link ByteBuffer} 98 */ 99 protected abstract void serializeSubPageCode (final ByteBuffer buffer, final int index); 100 101 /** 102 * Serializes the PAGE LENGTH field. 103 * 104 * @param buffer where to insert the serialized object representation 105 * @param index the position of the first byte of the serialized object in the {@link ByteBuffer} 106 */ 107 protected abstract void serializePageLength (final ByteBuffer buffer, final int index); 108 109 /** 110 * @param buffer where to insert the serialized object representation 111 * @param index the position of the first byte of the serialized object in the {@link ByteBuffer} 112 */ 113 protected abstract void serializeModeParameters (final ByteBuffer buffer, final int index); 114 115 public final int size () { 116 return pageLength + pageLengthModifier; 117 } 118 }