View Javadoc

1   package org.jscsi.target.connection.stage.fullfeature;
2   
3   
4   import java.io.IOException;
5   import java.security.DigestException;
6   
7   import org.jscsi.exception.InternetSCSIException;
8   import org.jscsi.parser.BasicHeaderSegment;
9   import org.jscsi.parser.ProtocolDataUnit;
10  import org.jscsi.parser.scsi.SCSICommandParser;
11  import org.jscsi.target.connection.phase.TargetFullFeaturePhase;
12  import org.jscsi.target.scsi.IResponseData;
13  import org.jscsi.target.scsi.cdb.InquiryCDB;
14  import org.jscsi.target.scsi.inquiry.PageCode.VitalProductDataPageName;
15  import org.jscsi.target.scsi.inquiry.StandardInquiryData;
16  import org.jscsi.target.scsi.inquiry.SupportedVpdPages;
17  import org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific.FieldPointerSenseKeySpecificData;
18  import org.jscsi.target.settings.SettingsException;
19  import org.jscsi.target.util.Debug;
20  import org.slf4j.Logger;
21  import org.slf4j.LoggerFactory;
22  
23  
24  /**
25   * A stage for processing <code>INQUIRY</code> SCSI commands.
26   * 
27   * @author Andreas Ergenzinger
28   */
29  public class InquiryStage extends TargetFullFeatureStage {
30  
31      private static final Logger LOGGER = LoggerFactory.getLogger(InquiryStage.class);
32  
33      public InquiryStage (TargetFullFeaturePhase targetFullFeaturePhase) {
34          super(targetFullFeaturePhase);
35      }
36  
37      @Override
38      public void execute (ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , SettingsException {
39  
40          final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
41          final SCSICommandParser parser = (SCSICommandParser) bhs.getParser();
42  
43          ProtocolDataUnit responsePdu = null;// the response PDU
44  
45          // get command details in CDB
46          if (LOGGER.isDebugEnabled()) {// print CDB bytes
47              LOGGER.debug("CDB bytes: \n" + Debug.byteBufferToString(parser.getCDB()));
48          }
49  
50          final InquiryCDB cdb = new InquiryCDB(parser.getCDB());
51          final FieldPointerSenseKeySpecificData[] illegalFieldPointers = cdb.getIllegalFieldPointers();
52  
53          if (LOGGER.isDebugEnabled()) {
54              LOGGER.debug("cdb.getAllocationLength() = " + cdb.getAllocationLength());
55              LOGGER.debug("cdb.getEnableVitalProductData() = " + cdb.getEnableVitalProductData());
56              LOGGER.debug("cdb.isNormalACA() = " + cdb.isNormalACA());
57              LOGGER.debug("cdb.getPageCode() = " + cdb.getPageCode());
58              LOGGER.debug("cdb.getPageCode().getVitalProductDataPageName() = " + cdb.getPageCode().getVitalProductDataPageName());
59          }
60  
61          if (illegalFieldPointers != null) {
62              // an illegal request has been made
63              LOGGER.error("illegal INQUIRY request");
64  
65              responsePdu = createFixedFormatErrorPdu(illegalFieldPointers, bhs.getInitiatorTaskTag(), parser.getExpectedDataTransferLength());
66  
67              // send response
68              connection.sendPdu(responsePdu);
69  
70          } else {
71              // PDU is okay
72              // carry out command
73  
74              IResponseData responseData = null;
75  
76              // "If the EVPD bit is set to zero, ...
77              if (!cdb.getEnableVitalProductData()) {
78                  // ... the device server shall return the standard INQUIRY
79                  // data."
80                  responseData = StandardInquiryData.getInstance();
81              } else {
82                  /*
83                   * SCSI initiator is requesting either "device identification" or "supported VPD pages" or this else
84                   * block would not have been entered. (see {@link InquiryCDB#checkIntegrity(ByteBuffer dataSegment)})
85                   */
86                  final VitalProductDataPageName pageName = cdb.getPageCode().getVitalProductDataPageName();
87  
88                  switch (pageName) {// is never null
89                      case SUPPORTED_VPD_PAGES :
90                          responseData = SupportedVpdPages.getInstance();
91                          break;
92                      case DEVICE_IDENTIFICATION :
93                          responseData = session.getTargetServer().getDeviceIdentificationVpdPage();
94                          break;
95                      default :
96                          // The initiator must not request unsupported mode pages.
97                          throw new InternetSCSIException();
98                  }
99              }
100 
101             // send response
102             sendResponse(bhs.getInitiatorTaskTag(), parser.getExpectedDataTransferLength(), responseData);
103            
104         }
105 
106     }
107 
108 }