View Javadoc

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 }