1 package org.jscsi.target.scsi.sense;
2
3
4 import java.nio.ByteBuffer;
5
6 import org.jscsi.target.scsi.cdb.ScsiOperationCode;
7 import org.jscsi.target.scsi.sense.information.FourByteInformation;
8 import org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific.SenseKeySpecificData;
9 import org.jscsi.target.util.BitManip;
10 import org.jscsi.target.util.ReadWrite;
11
12
13
14
15
16
17
18
19 public class FixedFormatSenseData extends SenseData {
20
21
22
23
24 private static final int INFORMATION_FIELD_INDEX = 3;
25
26
27
28
29 private static final int ADDITIONAL_SENSE_LENGTH_INDEX = 7;
30
31
32
33
34 private static final int COMMAND_SPECIFIC_INFORMATION_FIELD_INDEX = 8;
35
36
37
38
39 private static final int ADDITIONAL_SENSE_CODE_INDEX = 12;
40
41
42
43
44 private static final int FIELD_REPLACEABLE_UNIT_CODE_INDEX = 14;
45
46
47
48
49 private static final int SENSE_KEY_SPECIFIC_DATA_INDEX = 15;
50
51
52
53
54 private static final int MIN_SIZE = 18;
55
56
57
58
59 private static final int MIN_ADDITIONAL_SENSE_LENGTH = 10;
60
61
62
63
64
65
66 private final boolean valid;
67
68
69
70
71 private final boolean fileMark;
72
73
74
75
76 private final boolean endOfMedium;
77
78
79
80
81
82 private final boolean incorrectLengthIndicator;
83
84
85
86
87
88 private final FourByteInformation information;
89
90
91
92
93 private final FourByteInformation commandSpecificInformation;
94
95
96
97
98
99
100
101
102
103 private final byte fieldReplaceableUnitCode;
104
105
106
107
108
109
110 private final SenseKeySpecificData senseKeySpecificData;
111
112
113
114
115
116 private final AdditionalSenseBytes additionalSenseBytes;
117
118
119
120
121
122
123
124
125 final private int additionalSenseLength;
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144 public FixedFormatSenseData (final boolean valid, final ErrorType errorType, final boolean fileMark, final boolean endOfMedium, final boolean incorrectLengthIndicator, final SenseKey senseKey, final FourByteInformation information, final FourByteInformation commandSpecificInformation, final AdditionalSenseCodeAndQualifier additionalSenseCodeAndQualifier, final byte fieldReplaceableUnitCode, final SenseKeySpecificData senseKeySpecificData, final AdditionalSenseBytes additionalSenseBytes) {
145 super(errorType, SenseDataFormat.FIXED, senseKey, additionalSenseCodeAndQualifier);
146 this.valid = valid;
147 this.fileMark = fileMark;
148 this.endOfMedium = endOfMedium;
149 this.incorrectLengthIndicator = incorrectLengthIndicator;
150 this.information = information;
151 this.commandSpecificInformation = commandSpecificInformation;
152 this.fieldReplaceableUnitCode = fieldReplaceableUnitCode;
153 this.senseKeySpecificData = senseKeySpecificData;
154 this.additionalSenseBytes = additionalSenseBytes;
155
156 int asl = MIN_ADDITIONAL_SENSE_LENGTH;
157 if (additionalSenseBytes != null) asl += additionalSenseBytes.size();
158 additionalSenseLength = asl;
159 }
160
161 public void serialize (ByteBuffer byteBuffer, int index) {
162
163 byteBuffer.position(index);
164
165
166
167 byte b = (byte) getReponseCodeFor(errorType, SenseDataFormat.FIXED);
168
169 b = BitManip.getByteWithBitSet(b, 7, valid);
170 byteBuffer.put(b);
171
172
173 byteBuffer.put((byte) 0);
174
175
176
177 b = BitManip.getByteWithBitSet((byte) 0, 7, fileMark);
178
179
180 b = BitManip.getByteWithBitSet(b, 6, endOfMedium);
181
182
183 b = BitManip.getByteWithBitSet(b, 5, incorrectLengthIndicator);
184
185
186 b = (byte) (15 & senseKey.getValue());
187 byteBuffer.put(b);
188
189
190
191 if (information != null) information.serialize(byteBuffer, index + INFORMATION_FIELD_INDEX);
192
193
194 byteBuffer.put(index + ADDITIONAL_SENSE_LENGTH_INDEX, (byte) additionalSenseLength);
195
196
197 if (commandSpecificInformation != null) commandSpecificInformation.serialize(byteBuffer, index + COMMAND_SPECIFIC_INFORMATION_FIELD_INDEX);
198
199
200 ReadWrite.writeTwoByteInt(byteBuffer, additionalSenseCodeAndQualifier.getValue(), index + ADDITIONAL_SENSE_CODE_INDEX);
201
202
203 byteBuffer.put(FIELD_REPLACEABLE_UNIT_CODE_INDEX, fieldReplaceableUnitCode);
204
205
206 if (senseKeySpecificData != null) senseKeySpecificData.serialize(byteBuffer, index + SENSE_KEY_SPECIFIC_DATA_INDEX);
207
208
209 if (additionalSenseBytes != null) additionalSenseBytes.serialize(byteBuffer, index + MIN_SIZE);
210 }
211
212 public final int getAdditionalSenseLength () {
213 return additionalSenseLength;
214 }
215
216 public int size () {
217 int size = MIN_SIZE;
218 if (additionalSenseBytes != null) size += additionalSenseBytes.size();
219 return size;
220 }
221 }