
org.jscsi.parser.r2t.Ready2TransferParser Maven / Gradle / Ivy
The newest version!
/**
* 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 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.r2t;
import org.jscsi.exception.InternetSCSIException;
import org.jscsi.parser.Constants;
import org.jscsi.parser.ProtocolDataUnit;
import org.jscsi.parser.TargetMessageParser;
import org.jscsi.parser.datasegment.DataSegmentFactory.DataSegmentFormat;
import org.jscsi.utils.Utils;
/**
* This class parses a Ready2Transfer message defined in the iSCSI Standard (RFC3720).
*
* @author Volker Wildi
*/
public final class Ready2TransferParser extends TargetMessageParser {
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/** The Target Transfer Tag. */
private int targetTransferTag;
/**
* The Ready2Transfer Sequence Number.
*/
private int ready2TransferSequenceNumber;
/** The Buffer Offset. */
private int bufferOffset;
/** The Desired Data Transfer Length. */
private int desiredDataTransferLength;
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/**
* Default constructor, creates a new, empty Ready2TransferParser
object.
*
* @param initProtocolDataUnit The reference ProtocolDataUnit
instance, which contains this
* Ready2TransferParser
subclass object.
*/
public Ready2TransferParser (final ProtocolDataUnit initProtocolDataUnit) {
super(initProtocolDataUnit);
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public final String toString () {
final StringBuilder sb = new StringBuilder(Constants.LOG_INITIAL_SIZE);
Utils.printField(sb, "LUN", logicalUnitNumber, 1);
Utils.printField(sb, "TargetTransferTag", targetTransferTag, 1);
sb.append(super.toString());
Utils.printField(sb, "R2TSN", ready2TransferSequenceNumber, 1);
Utils.printField(sb, "Buffer Offset", bufferOffset, 1);
Utils.printField(sb, "Desired Data Transfer Length", desiredDataTransferLength, 1);
return sb.toString();
}
/** {@inheritDoc} */
@Override
public final DataSegmentFormat getDataSegmentFormat () {
return DataSegmentFormat.NONE;
}
/** {@inheritDoc} */
@Override
public final void clear () {
super.clear();
targetTransferTag = 0x00000000;
ready2TransferSequenceNumber = 0x00000000;
bufferOffset = 0x00000000;
desiredDataTransferLength = 0x00000000;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public final boolean incrementSequenceNumber () {
return false;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/**
* The target specifies how many bytes it wants the initiator to send because of this R2T PDU. The target may
* request the data from the initiator in several chunks, not necessarily in the original order of the data. The
* target, therefore, also specifies a Buffer Offset that indicates the point at which the data transfer should
* begin, relative to the beginning of the total data transfer.
*
* @return The buffer offset of this object.
*/
public final int getBufferOffset () {
return bufferOffset;
}
/**
* The Desired Data Transfer Length MUST NOT be 0
and MUST not exceed MaxBurstLength.
*
* @return The desired data transfer length of this object.
* @see #getBufferOffset
*/
public final int getDesiredDataTransferLength () {
return desiredDataTransferLength;
}
/**
* R2TSN is the R2T PDU input PDU number within the command identified by the Initiator Task Tag.
* For bidirectional commands R2T and Data-In PDUs share the input PDU numbering sequence (see Section 3.2.2.3 Data
* Sequencing).
*
* @return The R2T Sequence Number of this object.
*/
public final int getReady2TransferSequenceNumber () {
return ready2TransferSequenceNumber;
}
/**
* The target assigns its own tag to each R2T request that it sends to the initiator. This tag can be used by the
* target to easily identify the data it receives. The Target Transfer Tag and LUN are copied in the outgoing data
* PDUs and are only used by the target. There is no protocol rule about the Target Transfer Tag except that the
* value 0xffffffff
is reserved and MUST NOT be sent by a target in an R2T.
*
* @return The target transfer tag of this object.
*/
public final int getTargetTransferTag () {
return targetTransferTag;
}
public final void setTargetTransferTag (int targetTransferTag) {
this.targetTransferTag = targetTransferTag;
}
public final void setReady2TransferSequenceNumber (int ready2TransferSequenceNumber) {
this.ready2TransferSequenceNumber = ready2TransferSequenceNumber;
}
public final void setBufferOffset (int bufferOffset) {
this.bufferOffset = bufferOffset;
}
public final void setDesiredDataTransferLength (int desiredDataTransferLength) {
this.desiredDataTransferLength = desiredDataTransferLength;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
protected final void deserializeBytes1to3 (final int line) throws InternetSCSIException {
Utils.isReserved(line & Constants.LAST_THREE_BYTES_MASK);
}
/** {@inheritDoc} */
@Override
protected final void deserializeBytes20to23 (final int line) throws InternetSCSIException {
targetTransferTag = line;
}
/** {@inheritDoc} */
@Override
protected final void deserializeBytes36to39 (final int line) throws InternetSCSIException {
ready2TransferSequenceNumber = line;
}
/** {@inheritDoc} */
@Override
protected final void deserializeBytes40to43 (final int line) throws InternetSCSIException {
bufferOffset = line;
}
/** {@inheritDoc} */
@Override
protected final void deserializeBytes44to47 (final int line) throws InternetSCSIException {
desiredDataTransferLength = line;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
protected final void checkIntegrity () throws InternetSCSIException {
String exceptionMessage;
do {
Utils.isReserved(protocolDataUnit.getBasicHeaderSegment().getDataSegmentLength());
Utils.isReserved(protocolDataUnit.getBasicHeaderSegment().getTotalAHSLength());
if (desiredDataTransferLength == 0) {
exceptionMessage = "The DesiredDataTransferLength must not be equal than 0.";
break;
}
if (targetTransferTag == 0xFFFFFFFF) {
exceptionMessage = "The value 0xFFFFFFFF is reserved for the TargetTransferTag.";
break;
}
// message is checked correctly
return;
} while (false);
throw new InternetSCSIException(exceptionMessage);
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
protected final int serializeBytes20to23 () {
return targetTransferTag;
}
/** {@inheritDoc} */
@Override
protected final int serializeBytes36to39 () {
return ready2TransferSequenceNumber;
}
/** {@inheritDoc} */
@Override
protected final int serializeBytes40to43 () {
return bufferOffset;
}
/** {@inheritDoc} */
@Override
protected final int serializeBytes44to47 () {
return desiredDataTransferLength;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy