1 package org.jscsi.target.connection.stage.fullfeature;
2
3
4 import static org.jscsi.target.storage.IStorageModule.VIRTUAL_BLOCK_SIZE;
5
6 import java.io.IOException;
7 import java.security.DigestException;
8
9 import org.jscsi.exception.InternetSCSIException;
10 import org.jscsi.parser.BasicHeaderSegment;
11 import org.jscsi.parser.ProtocolDataUnit;
12 import org.jscsi.parser.scsi.SCSICommandParser;
13 import org.jscsi.target.connection.phase.TargetFullFeaturePhase;
14 import org.jscsi.target.scsi.cdb.ModeSense6Cdb;
15 import org.jscsi.target.scsi.modeSense.CachingModePage;
16 import org.jscsi.target.scsi.modeSense.HeaderType;
17 import org.jscsi.target.scsi.modeSense.InformationExceptionsControlModePage;
18 import org.jscsi.target.scsi.modeSense.ModePage;
19 import org.jscsi.target.scsi.modeSense.ModePageCode;
20 import org.jscsi.target.scsi.modeSense.ModeParameterList;
21 import org.jscsi.target.scsi.modeSense.ModeParameterListBuilder;
22 import org.jscsi.target.scsi.modeSense.ShortLogicalBlockDescriptor;
23 import org.jscsi.target.settings.SettingsException;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27
28
29
30
31
32
33 public final class ModeSenseStage extends TargetFullFeatureStage {
34
35 private static final Logger LOGGER = LoggerFactory.getLogger(ModeSenseStage.class);
36
37 public ModeSenseStage (TargetFullFeaturePhase targetFullFeaturePhase) {
38 super(targetFullFeaturePhase);
39 }
40
41 @Override
42 public void execute (final ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , SettingsException {
43
44 final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
45 final SCSICommandParser parser = (SCSICommandParser) bhs.getParser();
46 final ModeSense6Cdb cdb = new ModeSense6Cdb(parser.getCDB());
47
48 if (LOGGER.isDebugEnabled()) {
49 LOGGER.debug(Boolean.toString(cdb.getDisableBlockDescriptors()));
50 LOGGER.debug(cdb.getPageControl().toString());
51 LOGGER.debug(Integer.toString(cdb.getPageCode()));
52 LOGGER.debug(Integer.toString(cdb.getSubpageCode()));
53 LOGGER.debug("cdb.getAllocationLength() = " + cdb.getAllocationLength());
54
55 }
56
57
58
59 final ModePageCode modePageCode = cdb.getModePage();
60
61
62
63
64 ModePage[] modePages = null;
65 if (modePageCode == ModePageCode.INFORMATIONAL_EXCEPTIONS_CONTROL_MODE_PAGE) {
66
67
68 modePages = new ModePage[] { getInformationExceptionsControlModePage() };
69
70 } else if (modePageCode == ModePageCode.CACHING_MODE_PAGE) {
71
72 modePages = new ModePage[] { getCachingModePage() };
73
74 } else if (modePageCode == ModePageCode.RETURN_ALL_MODE_PAGES_ONLY) {
75
76 modePages = new ModePage[] { getInformationExceptionsControlModePage(), getCachingModePage() };
77
78 }
79
80
81 if (modePages != null) {
82
83
84 final ModeParameterListBuilder builder = new ModeParameterListBuilder(HeaderType.MODE_PARAMETER_HEADER_6);
85 builder.setLogicalBlockDescriptors(new ShortLogicalBlockDescriptor(session.getStorageModule().getSizeInBlocks(),
86 VIRTUAL_BLOCK_SIZE));
87 builder.setModePages(modePages);
88 ModeParameterList modeParameterList = ModeParameterList.build(builder);
89
90
91 sendResponse(bhs.getInitiatorTaskTag(),
92 parser.getExpectedDataTransferLength(),
93 modeParameterList);
94
95 } else {
96
97
98
99
100
101 throw new InternetSCSIException();
102 }
103
104 }
105
106 private static final InformationExceptionsControlModePage getInformationExceptionsControlModePage () {
107 return new InformationExceptionsControlModePage(false,
108 false,
109 false,
110 false,
111 true,
112 false,
113 false,
114 0x0,
115 0,
116 0);
117 }
118
119 private static final CachingModePage getCachingModePage () {
120 return new CachingModePage(false,
121 false,
122 true,
123 false,
124 false,
125 true,
126 false,
127 false,
128 true,
129 0x0,
130 0x0,
131 0,
132 0,
133 65535,
134 65535,
135 true,
136 false,
137 false,
138 false,
139 20,
140 0);
141 }
142
143 public boolean canHandle (final ProtocolDataUnit pdu) {
144 final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
145 final SCSICommandParser parser = (SCSICommandParser) bhs.getParser();
146 final ModeSense6Cdb cdb = new ModeSense6Cdb(parser.getCDB());
147 final ModePageCode modePageCode = cdb.getModePage();
148 if (modePageCode == ModePageCode.INFORMATIONAL_EXCEPTIONS_CONTROL_MODE_PAGE) {
149 return true;
150 } else if (modePageCode == ModePageCode.CACHING_MODE_PAGE) {
151 return true;
152 } else if (modePageCode == ModePageCode.RETURN_ALL_MODE_PAGES_ONLY) {
153 return true;
154 } else {
155 return false;
156 }
157 }
158
159 }