/**
* Copyright (c) 2012, University of Konstanz, Distributed Systems Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University of Konstanz nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jscsi.parser;
import com.carrotsearch.hppc.ByteObjectOpenHashMap;
/**
* <h1>OperationCode</h1>
* <p>
* This enumeration defines all valid operation codes, which are conform to iSCSI Protocol (RFC 3720).
* <p>
* <table border="1">
* <tr>
* <td>0x00</td>
* <td>NOP-Out</td>
* </tr>
* <tr>
* <td>0x01</td>
* <td>SCSI Command (encapsulates a SCSI Command Descriptor Block)</td>
* </tr>
* <tr>
* <td>0x02</td>
* <td>SCSI Task Management function request</td>
* </tr>
* <tr>
* <td>0x03</td>
* <td>Login Request</td>
* </tr>
* <tr>
* <td>0x04</td>
* <td>Text Request</td>
* </tr>
* <tr>
* <td>0x05</td>
* <td>SCSI Data-Out (for WRITE operations)</td>
* </tr>
* <tr>
* <td>0x06</td>
* <td>Logout Request</td>
* </tr>
* <tr>
* <td>0x10</td>
* <td>SNACK Request</td>
* </tr>
* <tr>
* <td>0x1c-0x1e</td>
* <td>Vendor specific codes</td>
* </tr>
* <tr>
* <td>0x20</td>
* <td>NOP-In</td>
* </tr>
* <tr>
* <td>0x21</td>
* <td>SCSI Response - contains SCSI status and possibly sense information or other response information.</td>
* </tr>
* <tr>
* <td>0x22</td>
* <td>SCSI Task Management function response</td>
* </tr>
* <tr>
* <td>0x23</td>
* <td>Login Response</td>
* </tr>
* <tr>
* <td>0x24</td>
* <td>Text Response</td>
* </tr>
* <tr>
* <td>0x25</td>
* <td>SCSI Data-In - for READ operations.</td>
* </tr>
* <tr>
* <td>0x26</td>
* <td>Logout Response</td>
* </tr>
* <tr>
* <td>0x31</td>
* <td>Ready To Transfer (R2T) - sent by target when it is ready to receive data.</td>
* </tr>
* <tr>
* <td>0x32</td>
* <td>Asynchronous Message - sent by target to indicate certain special conditions.</td>
* </tr>
* <tr>
* <td>0x3c-0x3e</td>
* <td>Vendor specific codes</td>
* </tr>
* <tr>
* <td>0x3f</td>
* <td>Reject</td>
* </tr>
* </table>
* <p>
* Not Supported: 0x1c-0x1e Vendor specific codes
*
* @author Volker Wildi
*/
public enum OperationCode {
// --------------------------------------------------------------------------
// The initiator operation codes
// --------------------------------------------------------------------------
/**
* This request/response pair may be used by an initiator and target as a
* "ping" mechanism to verify that a connection/session is still active and
* all of its components are operational. Such a ping may be triggered by
* the initiator or target. The triggering party indicates that it wants a
* reply by setting a value different from the default <code>0xffffffff</code> in the corresponding
* Initiator/Target Transfer
* Tag. NOP-In/NOP-Out may also be used "unidirectional" to convey to the
* initiator/target command, status or data counter values when there is no
* other "carrier" and there is a need to update the initiator/ target.
*/
NOP_OUT((byte)0x00),
/**
* This request carries the SCSI CDB and all the other SCSI execute command
* procedure call (see [SAM2]) IN arguments such as task attributes,
* Expected Data Transfer Length for one or both transfer directions (the
* latter for bidirectional commands), and Task Tag (as part of the I_T_L_x
* nexus). The I_T_L nexus is derived by the initiator and target from the
* LUN field in the request and the I_T nexus is implicit in the session
* identification. In addition, the SCSI-command PDU carries information
* required for the proper operation of the iSCSI protocol - the command
* sequence number ( <code>CmdSN</code>) for the session and the expected
* status number ( <code>ExpStatSN</code>) for the connection. All or part
* of the SCSI output (write) data associated with the SCSI command may be
* sent as part of the SCSI-Command PDU as a data segment.
*/
SCSI_COMMAND((byte)0x01),
/**
* The Task Management function request provides an initiator with a way to
* explicitly control the execution of one or more SCSI Tasks or iSCSI
* functions. The PDU carries a function identifier (which task management
* function to perform) and enough information to unequivocally identify the
* task or task-set on which to perform the action, even if the task(s) to
* act upon has not yet arrived or has been discarded due to an error. The
* referenced tag identifies an individual task if the function refers to an
* individual task. The I_T_L nexus identifies task sets. In iSCSI the I_T_L
* nexus is identified by the LUN and the session identification (the
* session identifies an I_T nexus). For task sets, the <code>CmdSN</code> of the Task Management
* function request helps identify the tasks upon
* which to act, namely all tasks associated with a LUN and having a CmdSN
* preceding the Task Management function request <code>CmdSN</code>. For a
* Task Management function, the coordination between responses to the tasks
* affected and the Task Management function response is done by the target.
*/
SCSI_TM_REQUEST((byte)0x02),
/**
* Login Requests and Responses are used exclusively during the Login Phase
* of each connection to set up the session and connection parameters. (The
* Login Phase consists of a sequence of login requests and responses
* carrying the same Initiator Task Tag.) A connection is identified by an
* arbitrarily selected connection-ID (<code>CID</code>) that is unique
* within a session. Similar to the Text Requests and Responses, Login
* Requests/Responses carry key=value text information with a simple syntax
* in the data segment. The Login Phase proceeds through several stages
* (security negotiation, operational parameter negotiation) that are
* selected with two binary coded fields in the header -- the
* "current stage" (<code>CSG</code>) and the "next stage" (<code>NSG</code> ) with the appearance of
* the latter being signaled by the "transit" flag
* (<code>T</code>). The first Login Phase of a session plays a special
* role, called the leading login, which determines some header fields
* (e.g., the version number, the maximum number of connections, and the
* session identification). The CmdSN initial value is also set by the
* leading login. StatSN for each connection is initiated by the connection
* login. A login request may indicate an implied logout (cleanup) of the
* connection to be logged in (a connection restart) by using the same
* Connection ID (CID) as an existing connection, as well as the same
* session identifying elements of the session to which the old connection
* was associated.
*/
LOGIN_REQUEST((byte)0x03),
/**
* Text requests and responses are designed as a parameter negotiation
* vehicle and as a vehicle for future extension. In the data segment, Text
* Requests/Responses carry text information using a simple "key=value"
* syntax. Text Request/Responses may form extended sequences using the same
* Initiator Task Tag. The initiator uses the F (Final) flag bit in the text
* request header to indicate its readiness to terminate a sequence. The
* target uses the F (Final) flag bit in the text response header to
* indicate its consent to sequence termination. Text Request and Responses
* also use the Target Transfer Tag to indicate continuation of an operation
* or a new beginning. A target that wishes to continue an operation will
* set the Target Transfer Tag in a Text Response to a value different from
* the default 0xffffffff. An initiator willing to continue will copy this
* value into the Target Transfer Tag of the next Text Request. If the
* initiator wants to restart the current target negotiation (start fresh)
* will set the Target Transfer Tag to 0xffffffff. Although a complete
* exchange is always started by the initiator, specific parameter
* negotiations may be initiated by the initiator or target.
*/
TEXT_REQUEST((byte)0x04),
/**
* SCSI Data-Out and SCSI Data-In are the main vehicles by which SCSI data
* payload is carried between initiator and target. Data payload is
* associated with a specific SCSI command through the Initiator Task Tag.
* For target convenience, outgoing solicited data also carries a Target
* Transfer Tag (copied from R2T) and the LUN. Each PDU contains the payload
* length and the data offset relative to the buffer address contained in
* the SCSI execute command procedure call. In each direction, the data
* transfer is split into "sequences". An end-of-sequence is indicated by
* the F bit. An outgoing sequence is either unsolicited (only the first
* sequence can be unsolicited) or consists of all the Data-Out PDUs sent in
* response to an R2T. Input sequences are built to enable the direction
* switching for bidirectional commands. For input, the target may request
* positive acknowledgement of input data. This is limited to sessions that
* support error recovery and is implemented through the A bit in the SCSI
* Data-In PDU header. Data-In and Data-Out PDUs also carry the DataSN to
* enable the initiator and target to detect missing PDUs (discarded due to
* an error). In addition, StatSN is carried by the Data-In PDUs. To enable
* a SCSI command to be processed while involving a minimum number of
* messages, the last SCSI Data-In PDU passed for a command may also contain
* the status if the status indicates termination with no exceptions (no
* sense or response involved).
*/
SCSI_DATA_OUT((byte)0x05),
/**
* Logout Requests and Responses are used for the orderly closing of
* connections for recovery or maintenance. The logout request may be issued
* following a target prompt (through an asynchronous message) or at an
* initiators initiative. When issued on the connection to be logged out, no
* other request may follow it.
*/
LOGOUT_REQUEST((byte)0x06),
/**
* With the SNACK Request, the initiator requests retransmission of
* numbered-responses or data from the target. A single SNACK request covers
* a contiguous set of missing items, called a run, of a given type of
* items. The type is indicated in a type field in the PDU header. The run
* is composed of an initial item (StatSN, DataSN, R2TSN) and the number of
* missed Status, Data, or R2T PDUs. For long Data-In sequences, the target
* may request (at predefined minimum intervals) a positive acknowledgement
* for the data sent. A SNACK request with a type field that indicates ACK
* and the number of Data-In PDUs acknowledged conveys this positive
* acknowledgement.
*/
SNACK_REQUEST((byte)0x10),
// --------------------------------------------------------------------------
// The target operation codes
// --------------------------------------------------------------------------
/**
* This request/response pair may be used by an initiator and target as a
* "ping" mechanism to verify that a connection/session is still active and
* all of its components are operational. Such a ping may be triggered by
* the initiator or target. The triggering party indicates that it wants a
* reply by setting a value different from the default 0xffffffff in the
* corresponding Initiator/Target Transfer Tag. NOP-In/NOP-Out may also be
* used "unidirectional" to convey to the initiator/target command, status
* or data counter values when there is no other "carrier" and there is a
* need to update the initiator/ target.
*/
NOP_IN((byte)0x20),
/**
* The SCSI-Response carries all the SCSI execute-command procedure call
* (see [SAM2]) OUT arguments and the SCSI execute-command procedure call
* return value. The SCSI-Response contains the residual counts from the
* operation, if any, an indication of whether the counts represent an
* overflow or an underflow, and the SCSI status if the status is valid or a
* response code (a non-zero return value for the execute-command procedure
* call) if the status is not valid. For a valid status that indicates that
* the command has been processed, but resulted in an exception (e.g., a
* SCSI CHECK CONDITION), the PDU data segment contains the associated sense
* data. The use of Autosense ([SAM2]) is REQUIRED by iSCSI. Some data
* segment content may also be associated (in the data segment) with a
* non-zero response code. In addition, the SCSI-Response PDU carries
* information required for the proper operation of the iSCSI protocol:
* <ul>
* <li>The number of Data-In PDUs that a target has sent (to enable the initiator to check that all
* have arrived).</li>
* <li>StatSN - the Status Sequence Number on this connection</li>
* <li>ExpCmdSN - the next Expected Command Sequence Number at the target.</li>
* <li>MaxCmdSN - the maximum CmdSN acceptable at the target from this initiator.</li>
* </ul>
*/
SCSI_RESPONSE((byte)0x21),
/**
* The Task Management function response carries an indication of function
* completion for a Task Management function request including how it was
* completed (response and qualifier) and additional information for failure
* responses. After the Task Management response indicates Task Management
* function completion, the initiator will not receive any additional
* responses from the affected tasks.
*/
SCSI_TM_RESPONSE((byte)0x22),
/**
* Login Requests and Responses are used exclusively during the Login Phase
* of each connection to set up the session and connection parameters. (The
* Login Phase consists of a sequence of login requests and responses
* carrying the same Initiator Task Tag.) A connection is identified by an
* arbitrarily selected connection-ID (<code>CID</code>) that is unique
* within a session. Similar to the Text Requests and Responses, Login
* Requests/Responses carry key=value text information with a simple syntax
* in the data segment. The Login Phase proceeds through several stages
* (security negotiation, operational parameter negotiation) that are
* selected with two binary coded fields in the header -- the
* "current stage" (<code>CSG</code>) and the "next stage" (<code>NSG</code> ) with the appearance of
* the latter being signaled by the "transit" flag
* (<code>T</code>). The first Login Phase of a session plays a special
* role, called the leading login, which determines some header fields
* (e.g., the version number, the maximum number of connections, and the
* session identification). The CmdSN initial value is also set by the
* leading login. StatSN for each connection is initiated by the connection
* login. A login request may indicate an implied logout (cleanup) of the
* connection to be logged in (a connection restart) by using the same
* Connection ID (<code>CID</code>) as an existing connection, as well as
* the same session identifying elements of the session to which the old
* connection was associated.
*/
LOGIN_RESPONSE((byte)0x23),
/**
* Text requests and responses are designed as a parameter negotiation
* vehicle and as a vehicle for future extension. In the data segment, Text
* Requests/Responses carry text information using a simple "key=value"
* syntax. Text Request/Responses may form extended sequences using the same
* Initiator Task Tag. The initiator uses the <code>F</code> (Final) flag
* bit in the text request header to indicate its readiness to terminate a
* sequence. The target uses the <code>F</code> (Final) flag bit in the text
* response header to indicate its consent to sequence termination. Text
* Request and Responses also use the Target Transfer Tag to indicate
* continuation of an operation or a new beginning. A target that wishes to
* continue an operation will set the Target Transfer Tag in a Text Response
* to a value different from the default <code>0xffffffff</code>. An
* initiator willing to continue will copy this value into the Target
* Transfer Tag of the next Text Request. If the initiator wants to restart
* the current target negotiation (start fresh) will set the Target Transfer
* Tag to <code>0xffffffff</code>. Although a complete exchange is always
* started by the initiator, specific parameter negotiations may be
* initiated by the initiator or target.
*/
TEXT_RESPONSE((byte)0x24),
/**
* SCSI Data-Out and SCSI Data-In are the main vehicles by which SCSI data
* payload is carried between initiator and target. Data payload is
* associated with a specific SCSI command through the Initiator Task Tag.
* For target convenience, outgoing solicited data also carries a Target
* Transfer Tag (copied from R2T) and the LUN. Each PDU contains the payload
* length and the data offset relative to the buffer address contained in
* the SCSI execute command procedure call. In each direction, the data
* transfer is split into "sequences". An end-of-sequence is indicated by
* the F bit. An outgoing sequence is either unsolicited (only the first
* sequence can be unsolicited) or consists of all the Data-Out PDUs sent in
* response to an R2T. Input sequences are built to enable the direction
* switching for bidirectional commands. For input, the target may request
* positive acknowledgement of input data. This is limited to sessions that
* support error recovery and is implemented through the A bit in the SCSI
* Data-In PDU header. Data-In and Data-Out PDUs also carry the DataSN to
* enable the initiator and target to detect missing PDUs (discarded due to
* an error). In addition, StatSN is carried by the Data-In PDUs. To enable
* a SCSI command to be processed while involving a minimum number of
* messages, the last SCSI Data-In PDU passed for a command may also contain
* the status if the status indicates termination with no exceptions (no
* sense or response involved).
*/
SCSI_DATA_IN((byte)0x25),
/**
* Logout Requests and Responses are used for the orderly closing of
* connections for recovery or maintenance. The Logout Response indicates
* that the connection or session cleanup is completed and no other
* responses will arrive on the connection (if received on the logging out
* connection). In addition, the Logout Response indicates how long the
* target will continue to hold resources for recovery (e.g., command
* execution that continues on a new connection) in the text key Time2Retain
* and how long the initiator must wait before proceeding with recovery in
* the text key Time2Wait.
*/
LOGOUT_RESPONSE((byte)0x26),
/**
* R2T is the mechanism by which the SCSI target "requests" the initiator
* for output data. R2T specifies to the initiator the offset of the
* requested data relative to the buffer address from the execute command
* procedure call and the length of the solicited data. To help the SCSI
* target associate the resulting Data-Out with an R2T, the R2T carries a
* Target Transfer Tag that will be copied by the initiator in the solicited
* SCSI Data-Out PDUs. There are no protocol specific requirements with
* regard to the value of these tags, but it is assumed that together with
* the LUN, they will enable the target to associate data with an R2T. R2T
* also carries information required for proper operation of the iSCSI
* protocol, such as:
* <ul>
* <li>R2TSN (to enable an initiator to detect a missing R2T)</li>
* <li>StatSN</li>
* <li>ExpCmdSN</li>
* <li>MaxCmdSN</li>
* </ul>
*/
R2T((byte)0x31),
/**
* Asynchronous Messages are used to carry SCSI asynchronous events (AEN)
* and iSCSI asynchronous messages. When carrying an AEN, the event details
* are reported as sense data in the data segment.
*/
ASYNC_MESSAGE((byte)0x32),
/**
* Reject enables the target to report an iSCSI error condition (e.g.,
* protocol, unsupported option) that uses a Reason field in the PDU header
* and includes the complete header of the bad PDU in the Reject PDU data
* segment.
*/
REJECT((byte)0x3F);
private final byte value;
private static ByteObjectOpenHashMap<OperationCode> mapping;
static {
OperationCode.mapping = new ByteObjectOpenHashMap<OperationCode>(values().length);
for (OperationCode s : values()) {
OperationCode.mapping.put(s.value, s);
}
}
private OperationCode(final byte newValue) {
value = newValue;
}
/**
* Returns the value of this enumeration.
*
* @return The value of this enumeration.
*/
public final byte value() {
return value;
}
/**
* Returns the constant defined for the given <code>value</code>.
*
* @param value
* The value to search for.
* @return The constant defined for the given <code>value</code>. Or <code>null</code>, if this value is
* not defined by this
* enumeration.
*/
public static final OperationCode valueOf(final byte value) {
return OperationCode.mapping.get(value);
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
}