Coverage Report - org.jscsi.target.scsi.inquiry.StandardInquiryData
 
Classes in this File Line Coverage Branch Coverage Complexity
StandardInquiryData
0%
0/25
0%
0/6
1.6
 
 1  
 package org.jscsi.target.scsi.inquiry;
 2  
 
 3  
 
 4  
 import java.nio.ByteBuffer;
 5  
 
 6  
 import org.jscsi.target.scsi.IResponseData;
 7  
 import org.jscsi.target.scsi.cdb.ScsiOperationCode;
 8  
 
 9  
 
 10  
 /**
 11  
  * The standard inquiry data, sent as a response to an {@link ScsiOperationCode#INQUIRY} command.
 12  
  * <p>
 13  
  * This class uses the singleton pattern since the returned standard inquiry data will always be the same.
 14  
  * <p>
 15  
  * Not all fields in the serialized form of the singleton have a corresponding member variable, only those fields
 16  
  * containing ASCII information.
 17  
  * 
 18  
  * @author Andreas Ergenzinger
 19  
  */
 20  
 public final class StandardInquiryData implements IResponseData {
 21  
 
 22  
     /**
 23  
      * The total length of the serialized Standard Inquiry Data.
 24  
      */
 25  
     private static final int SIZE = 36;
 26  
 
 27  
     private static final String VENDOR_ID = "disyUKon";
 28  
     private static final int VENDOR_ID_FIELD_POSITION = 8;
 29  
     private static final int VENDOR_ID_FIELD_LENGTH = 8;
 30  
 
 31  
     private static final String PRODUCT_ID = "jSCSI Target";
 32  
     private static final int PRODUCT_ID_FIELD_POSITION = 16;
 33  
     private static final int PRODUCT_ID_FIELD_LENGTH = 16;
 34  
 
 35  
     private static final String PRODUCT_REVISION_LEVEL = "1.00";
 36  
     private static final int PRODUCT_REVISION_LEVEL_FIELD_POSITION = 32;
 37  
     private static final int PRODUCT_REVISION_LEVEL_FIELD_LENGTH = 4;
 38  
 
 39  
     /**
 40  
      * The singleton.
 41  
      */
 42  
     private static StandardInquiryData instance;
 43  
 
 44  0
     private StandardInquiryData () {
 45  
         // singleton pattern
 46  0
     }
 47  
 
 48  
     /**
 49  
      * Returns the one and only {@link StandardInquiryData} object.
 50  
      * 
 51  
      * @return the one and only {@link StandardInquiryData} object
 52  
      */
 53  
     public static StandardInquiryData getInstance () {
 54  0
         if (instance == null) instance = new StandardInquiryData();
 55  0
         return instance;
 56  
     }
 57  
 
 58  
     public void serialize (ByteBuffer byteBuffer, int index) {
 59  
 
 60  
         // *** byte 0 ****
 61  
         /*
 62  
          * Peripheral qualifier (3 most significant bits of byte 0): 000b A peripheral device having the specified
 63  
          * peripheral device type is connected to this logical unit. If the device server is unable to determine whether
 64  
          * or not a peripheral device is connected, it also shall use this peripheral qualifier. This peripheral
 65  
          * qualifier does not mean that the peripheral device connected to the logical unit is ready for access.
 66  
          * Peripheral Device Type (5 least significant bits of byte 0): 00000b direct access block device Therefore no
 67  
          * need to change anything.
 68  
          */
 69  0
         byteBuffer.position(index);
 70  0
         byteBuffer.put((byte) 0);
 71  
 
 72  
         // *** byte 1 ***
 73  
         /*
 74  
          * RMB bit (bit 7): 0 A removable medium (RMB) bit set to zero indicates that the medium is not removable.
 75  
          * (remaining bits are RESERVED)
 76  
          */
 77  0
         byteBuffer.put((byte) 0);
 78  
 
 79  
         // *** byte 2 ***
 80  
         /*
 81  
          * version: 0x05 The device complies to the SPC3 and respective ANSI standard
 82  
          */
 83  0
         byteBuffer.put((byte) 0x05);
 84  
 
 85  
         // *** byte 3 - flags ***
 86  
         /*
 87  
          * (bits 7 and 6 are obsolete) NORMACA (bit 5): 0 A NORMACA (normal auto contingency allegiance) bit set to zero
 88  
          * indicates that the device server does not support a NACA bit set to one and does not support the ACA task
 89  
          * attribute. HISUP (bit 4): 0 A hierarchical support (HISUP) bit set to zero indicates the SCSI target device
 90  
          * does not use the hierarchical addressing model to assign LUNs to logical units. RESPONSE DATA FORMAT (bits
 91  
          * 3-0): 0010b RESPONSE DATA FORMAT: SPC3
 92  
          */
 93  0
         byteBuffer.put((byte) 2);// 0000 0010b
 94  
 
 95  
         // *** byte 4 ***
 96  
         /*
 97  
          * n - 4 = 35 - 4 = 31 The ADDITIONAL LENGTH field indicates the length in bytes of the remaining standard
 98  
          * INQUIRY data.
 99  
          */
 100  0
         byteBuffer.put((byte) 31);
 101  
 
 102  
         // *** byte 5 ***
 103  
         /*
 104  
          * SSCS (bit 7): 0 An SCC Supported bit set to zero indicates that the SCSI target device does not contain an
 105  
          * embedded storage array controller component. ACC (bit 6): 0 An ACC bit set to zero indicates that no access
 106  
          * controls coordinator may be addressed through this logical unit. TGPS field (bits 5 and 4): 00b The contents
 107  
          * of the target port group support (TPGS) indicate the support for asymmetric logical unit access. The SCSI
 108  
          * target device does not support asymmetric logical unit access or supports a form of asymmetric access that is
 109  
          * vendor specific. Neither the REPORT TARGET GROUPS nor the SET TARGET GROUPS commands is supported. 3PC (bit
 110  
          * 3): 0 A Third-Party Copy (3PC) bit set to zero indicates that the SCSI target device does not support
 111  
          * third-party copy commands such as the EXTENDED COPY command. (bits 2 and 1 are RESERVED) PROTECT (bit 0): 0 A
 112  
          * PROTECT bit set to zero indicates that the logical unit does not support protection information.
 113  
          */
 114  0
         byteBuffer.put((byte) 0);
 115  
 
 116  
         // *** byte 6 ***
 117  
         /*
 118  
          * BQUE (bit 7): The CMDQUE bit and BQUE bit indicate whether the logical unit supports the full task management
 119  
          * model. 1 (and 0) Basic task management model supported. ENCSERV (bit 6): 0 An ENCSERV bit set to zero
 120  
          * indicates that the SCSI target device does not contain an embedded enclosure services component. (bit 5 is
 121  
          * VENDOR SPECIFIC i.e. 0) MULTIP (bit 4): 0 A Multi Port (MULTIP) bit set to zero indicates that this is not a
 122  
          * multi- port (two or more ports) SCSI target device and therefore does not conform to the SCSI multi-port
 123  
          * device requirements found in the applicable standards (e.g., SAM-3, a SCSI transport protocol standard and
 124  
          * possibly provisions of a command standard). MCHNGR (bit 3): 0 The MCHNGR bit is valid only when the RMB bit
 125  
          * is equal to one. A MCHNGR bit set to zero indicates that the SCSI target device does not support commands to
 126  
          * control an attached media changer. (bits 2 and 1 are RESERVED) ADDR16 (bit 0): 0 RESERVED since the SCSI
 127  
          * Parallel Interface transport protocol is not used.
 128  
          */
 129  0
         byteBuffer.put((byte) 128);// 1000 0000b
 130  
 
 131  
         // *** byte 7 ***
 132  
         /*
 133  
          * (bits 7, 6, and 2 are OBSOLETE, bit 0 is VENDOR SPECIFIC) WBUS and SYNC (bits 5 and 4): 00b RESERVED since
 134  
          * the SCSI Parallel Interface transport protocol is not used. LINKED (bit 3): 0 A LINKED bit set to zero
 135  
          * indicates the device server does not support linked commands. CMDQUE (bit 1): 0 The CMDQUE bit and BQUE bit
 136  
          * indicate whether the logical unit supports the full task management model. (see BQUE ,byte 6)
 137  
          */
 138  0
         byteBuffer.put((byte) 0);
 139  
 
 140  
         // *** bytes 8 to 15 ***
 141  
         /*
 142  
          * T10 VENDOR IDENTIFICATION: The T10 VENDOR IDENTIFICATION field contains eight bytes of left-aligned ASCII
 143  
          * data identifying the vendor of the product. The T10 vendor identification shall be one assigned by INCITS,
 144  
          * but obviously that is not the case here. disyUKon
 145  
          */
 146  0
         putString(byteBuffer, VENDOR_ID, index + VENDOR_ID_FIELD_POSITION, VENDOR_ID_FIELD_LENGTH);
 147  
 
 148  
         // *** bytes 16 to 31
 149  
         /*
 150  
          * PRODUCT IDENTIFICATION: The PRODUCT IDENTIFICATION field contains sixteen bytes of left-aligned ASCII data
 151  
          * defined by the vendor.
 152  
          */
 153  0
         putString(byteBuffer, PRODUCT_ID, index + PRODUCT_ID_FIELD_POSITION, PRODUCT_ID_FIELD_LENGTH);
 154  
 
 155  
         // *** bytes 32 to 35 ***
 156  
         /*
 157  
          * PRODUCT REVISION LEVEL: The PRODUCT REVISION LEVEL field contains four bytes of left-aligned ASCII data
 158  
          * defined by the vendor.
 159  
          */
 160  0
         putString(byteBuffer, PRODUCT_REVISION_LEVEL, index + PRODUCT_REVISION_LEVEL_FIELD_POSITION, PRODUCT_REVISION_LEVEL_FIELD_LENGTH);
 161  0
     }
 162  
 
 163  
     /**
 164  
      * Puts up to <i>fieldLength</i> of the passed {@link String} into a {@link ByteBuffer} and fills the remaining
 165  
      * bytes with zeros.
 166  
      * 
 167  
      * @param byteBuffer where the {@link String}'s characters will be copied
 168  
      * @param string contains the characters to copy
 169  
      * @param position where the first character of the {@link String} will be put
 170  
      * @param fieldLength the number of bytes in the {@link ByteBuffer} that will be overwritten
 171  
      */
 172  
     private void putString (final ByteBuffer byteBuffer, final String string, final int position, final int fieldLength) {
 173  
         // set position
 174  0
         byteBuffer.position(position);
 175  
         // put string characters
 176  0
         final int stringLength = Math.min(string.length(), fieldLength);
 177  0
         for (int i = 0; i < stringLength; ++i)
 178  0
             byteBuffer.put((byte) string.charAt(i));
 179  
         // clear remaining remaining bytes
 180  0
         for (int i = stringLength; i < fieldLength; ++i)
 181  0
             byteBuffer.put((byte) 0);
 182  0
     }
 183  
 
 184  
     public int size () {
 185  0
         return SIZE;
 186  
     }
 187  
 }