Package org.jscsi.target.connection.stage.fullfeature

Source Code of org.jscsi.target.connection.stage.fullfeature.ModeSenseStage

package org.jscsi.target.connection.stage.fullfeature;


import static org.jscsi.target.storage.IStorageModule.VIRTUAL_BLOCK_SIZE;

import java.io.IOException;
import java.security.DigestException;

import org.jscsi.exception.InternetSCSIException;
import org.jscsi.parser.BasicHeaderSegment;
import org.jscsi.parser.ProtocolDataUnit;
import org.jscsi.parser.scsi.SCSICommandParser;
import org.jscsi.target.connection.phase.TargetFullFeaturePhase;
import org.jscsi.target.scsi.cdb.ModeSense6Cdb;
import org.jscsi.target.scsi.modeSense.CachingModePage;
import org.jscsi.target.scsi.modeSense.HeaderType;
import org.jscsi.target.scsi.modeSense.InformationExceptionsControlModePage;
import org.jscsi.target.scsi.modeSense.ModePage;
import org.jscsi.target.scsi.modeSense.ModePageCode;
import org.jscsi.target.scsi.modeSense.ModeParameterList;
import org.jscsi.target.scsi.modeSense.ModeParameterListBuilder;
import org.jscsi.target.scsi.modeSense.ShortLogicalBlockDescriptor;
import org.jscsi.target.settings.SettingsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* A stage for processing <code>MODE SENSE (6)</code> SCSI commands.
*
* @author Andreas Ergenzinger
*/
public final class ModeSenseStage extends TargetFullFeatureStage {

    private static final Logger LOGGER = LoggerFactory.getLogger(ModeSenseStage.class);

    public ModeSenseStage (TargetFullFeaturePhase targetFullFeaturePhase) {
        super(targetFullFeaturePhase);
    }

    @Override
    public void execute (final ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , SettingsException {

        final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
        final SCSICommandParser parser = (SCSICommandParser) bhs.getParser();
        final ModeSense6Cdb cdb = new ModeSense6Cdb(parser.getCDB());

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(Boolean.toString(cdb.getDisableBlockDescriptors()));
            LOGGER.debug(cdb.getPageControl().toString());
            LOGGER.debug(Integer.toString(cdb.getPageCode()));
            LOGGER.debug(Integer.toString(cdb.getSubpageCode()));
            LOGGER.debug("cdb.getAllocationLength() = " + cdb.getAllocationLength());
            // LOGGER.debug(cdb.getModePage());
        }

        // final PageControl pageControl = cdb.getPageControl();//see 8 lines
        // below
        final ModePageCode modePageCode = cdb.getModePage();

        // ModeParameterList and ModeParameterListBuilder common to
        // all supported ModePage requests

        ModePage[] modePages = null;
        if (modePageCode == ModePageCode.INFORMATIONAL_EXCEPTIONS_CONTROL_MODE_PAGE) {
            // TODO this should to be made dynamic wrt. cdb.getPageControl();

            modePages = new ModePage[] { getInformationExceptionsControlModePage() };

        } else if (modePageCode == ModePageCode.CACHING_MODE_PAGE) {

            modePages = new ModePage[] { getCachingModePage() };

        } else if (modePageCode == ModePageCode.RETURN_ALL_MODE_PAGES_ONLY) {

            modePages = new ModePage[] { getInformationExceptionsControlModePage(), getCachingModePage() };

        }// else modeParameterList stays null

        // create and send response PDU
        if (modePages != null) {

            // create ModeParameterList
            final ModeParameterListBuilder builder = new ModeParameterListBuilder(HeaderType.MODE_PARAMETER_HEADER_6);
            builder.setLogicalBlockDescriptors(new ShortLogicalBlockDescriptor(session.getStorageModule().getSizeInBlocks(),// numberOfLogicalBlocks
            VIRTUAL_BLOCK_SIZE));// logicalBlockLength
            builder.setModePages(modePages);
            ModeParameterList modeParameterList = ModeParameterList.build(builder);

            // send response
            sendResponse(bhs.getInitiatorTaskTag(),// initiatorTaskTag,
                    parser.getExpectedDataTransferLength(),// expectedDataTransferLength,
                    modeParameterList);// responseData

        } else {
            /*
             * The initiator has requested a mode sense page which the jSCSI Target cannot provide. This could be
             * answered with an Illegal field in CDB message but, there is no good way to identify the exact field at
             * fault.
             */
            throw new InternetSCSIException();
        }

    }

    private static final InformationExceptionsControlModePage getInformationExceptionsControlModePage () {
        return new InformationExceptionsControlModePage(false,// parametersSaveable
        false,// performance
        false,// enableBackgroundFunction
        false,// enableWarning
        true,// disableExceptionControl
        false,// test
        false,// logErrors
        0x0,// methodOfReportingInformationalExceptionConditions
        0,// intervalTimer
        0);// reportCount
    }

    private static final CachingModePage getCachingModePage () {
        return new CachingModePage(false,// parametersSaveable
        false,// initiatorControl
        true,// abortPrefetch
        false,// cachingAnalysisPermitted
        false,// discontinuity
        true,// sizeEnable
        false,// writebackCacheEnable
        false,// multiplicationFactor
        true,// readCacheDisable
        0x0,// demandReadRetentionPriority
        0x0,// writeRetentionPriority
        0,// disablePrefetchTransferLength
        0,// minimumPrefetch
        65535,// maximumPrefetch
        65535,// maximumPrefetchCeiling
        true,// forceSequentialWrite
        false,// logicalBlockCacheSegmentSize
        false,// disableReadAhead
        false,// nonVolatileCacheDisabled
        20,// numberOfCacheSegments
        0);// cacheSegmentSize
    }

    public boolean canHandle (final ProtocolDataUnit pdu) {
        final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
        final SCSICommandParser parser = (SCSICommandParser) bhs.getParser();
        final ModeSense6Cdb cdb = new ModeSense6Cdb(parser.getCDB());
        final ModePageCode modePageCode = cdb.getModePage();
        if (modePageCode == ModePageCode.INFORMATIONAL_EXCEPTIONS_CONTROL_MODE_PAGE) {
            return true;
        } else if (modePageCode == ModePageCode.CACHING_MODE_PAGE) {
            return true;
        } else if (modePageCode == ModePageCode.RETURN_ALL_MODE_PAGES_ONLY) {
            return true;
        } else {
            return false;
        }
    }

}
TOP

Related Classes of org.jscsi.target.connection.stage.fullfeature.ModeSenseStage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.