blob: fbbba2772d34f4e21d66159d7d0ac1993107228d [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001package org.onosproject.pcepio.protocol.ver1;
2
3import java.util.LinkedList;
4
5import org.jboss.netty.buffer.ChannelBuffer;
6import org.onosproject.pcepio.exceptions.PcepParseException;
7import org.onosproject.pcepio.protocol.PcepErrorInfo;
8import org.onosproject.pcepio.protocol.PcepErrorMsg;
9import org.onosproject.pcepio.protocol.PcepErrorObject;
10import org.onosproject.pcepio.protocol.PcepMessageReader;
11import org.onosproject.pcepio.protocol.PcepMessageWriter;
12import org.onosproject.pcepio.protocol.PcepOpenObject;
13import org.onosproject.pcepio.protocol.PcepType;
14import org.onosproject.pcepio.protocol.PcepVersion;
15import org.onosproject.pcepio.types.ErrorObjListWithOpen;
16import org.onosproject.pcepio.types.PcepObjectHeader;
17import org.slf4j.Logger;
18import org.slf4j.LoggerFactory;
19
20import com.google.common.base.MoreObjects;
21import com.google.common.base.MoreObjects.ToStringHelper;
22
23/**
24 * Provides PCEP Error Message.
25 */
26public class PcepErrorMsgVer1 implements PcepErrorMsg {
27
28 /*
29 * PCE Error message format.
30
31 <PCErr Message> ::= <Common Header>
32 ( <error-obj-list> [<Open>] ) | <error>
33 [<error-list>]
34
35 <error-obj-list> ::=<PCEP-ERROR>[<error-obj-list>]
36
37 <error> ::=[<request-id-list> | <te-id-list>]
38 <error-obj-list>
39
40 <request-id-list> ::=<RP>[<request-id-list>]
41
42 <te-id-list> ::=<TE>[<te-id-list>]
43
44 <error-list> ::=<error>[<error-list>]
45 */
46
47 protected static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class);
48 public static final byte PACKET_VERSION = 1;
49 public static final int PACKET_MINIMUM_LENGTH = 12;
50 public static final PcepType MSG_TYPE = PcepType.ERROR;
51
52 //Below either one should be present.
53 private ErrorObjListWithOpen errObjListWithOpen; //optional ( <error-obj-list> [<Open>] )
54 private PcepErrorInfo errInfo; //optional <error> [<error-list>]
55
56 public static final PcepErrorMsgVer1.Reader READER = new Reader();
57
58 /**
59 * constructor to initialize variables.
60 */
61 public PcepErrorMsgVer1() {
62 errObjListWithOpen = null;
63 errInfo = null;
64 }
65
66 /**
67 * Constructor to initialize variables.
68 *
69 * @param errObjListWithOpen error-object-list with open object
70 * @param errInfo error information
71 */
72 public PcepErrorMsgVer1(ErrorObjListWithOpen errObjListWithOpen, PcepErrorInfo errInfo) {
73 this.errObjListWithOpen = errObjListWithOpen;
74 this.errInfo = errInfo;
75 }
76
77 /**
78 * Reader class for reading PCEP error Message from channel buffer.
79 */
80 public static class Reader implements PcepMessageReader<PcepErrorMsg> {
81
82 ErrorObjListWithOpen errObjListWithOpen;
83 PcepErrorInfo errInfo;
84 PcepObjectHeader tempObjHeader;
85
86 @Override
87 public PcepErrorMsg readFrom(ChannelBuffer cb) throws PcepParseException {
88
89 errObjListWithOpen = null;
90 errInfo = null;
91 tempObjHeader = null;
92
93 if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
94 throw new PcepParseException("Packet size is less than the minimum length.");
95 }
96
97 byte version = cb.readByte();
98 version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
99 if (version != PACKET_VERSION) {
100 throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
101 }
102 // fixed value property type == 1
103 byte type = cb.readByte();
104 if (type != MSG_TYPE.getType()) {
105 throw new PcepParseException("Wrong type: Expected=PcepType.ERROR(6), got=" + type);
106 }
107 int length = cb.readShort();
108 if (length < PACKET_MINIMUM_LENGTH) {
109 throw new PcepParseException(
110 "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length);
111 }
112
113 //parse <PCErr Message>
114 parsePCErrMsg(cb);
115
116 // If other than RP or TE or PCEP-ERROR present then it is error.
117 if (0 < cb.readableBytes()) {
118 PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
119 throw new PcepParseException("Unexpected Object found. Object Class : " + tempObjHeader.getObjClass());
120 }
121
122 return new PcepErrorMsgVer1(errObjListWithOpen, errInfo);
123 }
124
125 /**
126 * Parsing PCErr Message.
127 *
128 * @param cb channel buffer.
129 * @throws PcepParseException if mandatory fields are missing
130 * output: this.errObjListWithOpen, this.errInfo
131 */
132 public void parsePCErrMsg(ChannelBuffer cb) throws PcepParseException {
133 //If PCEP-ERROR list is followed by OPEN Object then store into ErrorObjListWithOpen.
134 // ( <error-obj-list> [<Open>]
135 //If PCEP-ERROR list is followed by RP or TE Object then store into errInfo. <error> [<error-list>]
136 //If only PCEP-ERROR list is present then store into ErrorObjListWithOpen.
137 PcepObjectHeader tempObjHeader;
138 LinkedList<PcepErrorObject> llErrObjList;
139
140 if (0 >= cb.readableBytes()) {
141 throw new PcepParseException("PCEP-ERROR message came with empty objects.");
142 }
143
144 //parse PCEP-ERROR list
145 llErrObjList = new LinkedList<PcepErrorObject>();
146 tempObjHeader = parseErrorObjectList(llErrObjList, cb);
147
148 //check whether OPEN-OBJECT is present.
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700149 if ((tempObjHeader != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700150 && (tempObjHeader.getObjClass() == PcepOpenObjectVer1.OPEN_OBJ_CLASS)) {
151
152 if (llErrObjList.isEmpty()) {
153 throw new PcepParseException("<error-obj-list> should be present if OPEN-OBJECT exists");
154 }
155
156 PcepOpenObject pcepOpenObj = PcepOpenObjectVer1.read(cb);
157 this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList, pcepOpenObj);
158
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700159 } else if ((tempObjHeader != null) //check whether RP or TE Object is present.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700160 && ((tempObjHeader.getObjClass() == PcepRPObjectVer1.RP_OBJ_CLASS)
161 || (tempObjHeader.getObjClass() == PcepTEObjectVer1.TE_OBJ_CLASS))) {
162
163 this.errInfo = new PcepErrorInfoVer1(null, null, llErrObjList);
164 this.errInfo.read(cb);
165
166 } else if ((null != llErrObjList) && (!llErrObjList.isEmpty())) {
167 //If only PCEP-ERROR list is present then store it in errObjListWithOpen.
168 this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList);
169 } else {
170 throw new PcepParseException("Empty PCEP-ERROR message.");
171 }
172 }
173
174 /**
175 * Parse error-obj-list.
176 *
177 * @param llErrObjList error object list output
178 * @param cb channel buffer input
179 * @throws PcepParseException if mandatory fields are missing
180 * @return error object header
181 */
182 public PcepObjectHeader parseErrorObjectList(LinkedList<PcepErrorObject> llErrObjList, ChannelBuffer cb)
183 throws PcepParseException {
184 PcepObjectHeader tempObjHeader = null;
185
186 while (0 < cb.readableBytes()) {
187 cb.markReaderIndex();
188 tempObjHeader = PcepObjectHeader.read(cb);
189 cb.resetReaderIndex();
190 if (tempObjHeader.getObjClass() == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
191 llErrObjList.add(PcepErrorObjectVer1.read(cb));
192 } else {
193 break;
194 }
195 }
196 return tempObjHeader;
197 }
198 }
199
200 /**
201 * Builder class for PCEP error message.
202 */
203 public static class Builder implements PcepErrorMsg.Builder {
204 // Pcep error message fields
205
206 private ErrorObjListWithOpen errObjListWithOpen = null; //optional ( <error-obj-list> [<Open>] )
207 private PcepErrorInfo errInfo = null; //optional <error> [<error-list>]
208
209 @Override
210 public PcepVersion getVersion() {
211 return PcepVersion.PCEP_1;
212 }
213
214 @Override
215 public PcepType getType() {
216 return PcepType.ERROR;
217 }
218
219 @Override
220 public PcepErrorMsg build() {
221 return new PcepErrorMsgVer1(this.errObjListWithOpen, this.errInfo);
222 }
223
224 @Override
225 public ErrorObjListWithOpen getErrorObjListWithOpen() {
226 return this.errObjListWithOpen;
227 }
228
229 @Override
230 public Builder setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
231 this.errObjListWithOpen = errObjListWithOpen;
232 return this;
233 }
234
235 @Override
236 public PcepErrorInfo getPcepErrorInfo() {
237 return this.errInfo;
238 }
239
240 @Override
241 public Builder setPcepErrorInfo(PcepErrorInfo errInfo) {
242 this.errInfo = errInfo;
243 return this;
244 }
245 }
246
247 @Override
248 public void writeTo(ChannelBuffer cb) throws PcepParseException {
249 WRITER.write(cb, this);
250 }
251
252 public static final Writer WRITER = new Writer();
253
254 /**
255 * Writer class for writing PCEP error Message to channel buffer.
256 */
257 static class Writer implements PcepMessageWriter<PcepErrorMsgVer1> {
258 @Override
259 public void write(ChannelBuffer cb, PcepErrorMsgVer1 message) throws PcepParseException {
260 int startIndex = cb.writerIndex();
261 // first 3 bits set to version
262 cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
263 // message type 0xC
264 cb.writeByte(MSG_TYPE.getType());
265 // length is length of variable message, will be updated at the end
266 // Store the position of message
267 // length in buffer
268 int msgLenIndex = cb.writerIndex();
269 cb.writeShort(0);
270 ErrorObjListWithOpen errObjListWithOpen = message.getErrorObjListWithOpen();
271 PcepErrorInfo errInfo = message.getPcepErrorInfo();
272
273 // write ( <error-obj-list> [<Open>] ) if exists.
274 // otherwise write <error> [<error-list>]
275
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700276 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700277 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
278 errObjListWithOpen.write(cb);
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700279 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700280 errInfo.write(cb);
281 } else {
282 throw new PcepParseException("Empty PCEP-ERROR message.");
283 }
284 // PcepErrorMessage message length field
285 int length = cb.writerIndex() - startIndex;
286 cb.setShort(msgLenIndex, (short) length);
287 }
288 }
289
290 @Override
291 public PcepVersion getVersion() {
292 return PcepVersion.PCEP_1;
293 }
294
295 @Override
296 public PcepType getType() {
297 return MSG_TYPE;
298 }
299
300 @Override
301 public ErrorObjListWithOpen getErrorObjListWithOpen() {
302 return this.errObjListWithOpen;
303 }
304
305 @Override
306 public void setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
307 this.errObjListWithOpen = errObjListWithOpen;
308 }
309
310 @Override
311 public PcepErrorInfo getPcepErrorInfo() {
312 return this.errInfo;
313 }
314
315 @Override
316 public void setPcepErrorInfo(PcepErrorInfo errInfo) {
317 this.errInfo = errInfo;
318 }
319
320 /**
321 * Return list of Error types.
322 *
323 * @return error types list
324 */
325 public LinkedList<Integer> getErrorType() {
326 LinkedList<Integer> llErrorType = new LinkedList<Integer>();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700327 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700328 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
329 llErrorType = errObjListWithOpen.getErrorType();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700330 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700331 llErrorType = errInfo.getErrorType();
332 }
333
334 return llErrorType;
335 }
336
337 /**
338 * Return list of Error values.
339 *
340 * @return error value list
341 */
342 public LinkedList<Integer> getErrorValue() {
343 LinkedList<Integer> llErrorValue = new LinkedList<Integer>();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700344 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700345 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
346 llErrorValue = errObjListWithOpen.getErrorValue();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700347 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700348 llErrorValue = errInfo.getErrorValue();
349 }
350
351 return llErrorValue;
352 }
353
354 @Override
355 public String toString() {
356 ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
357
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700358 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700359 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
360 toStrHelper.add("ErrorObjectListWithOpen", errObjListWithOpen);
361 }
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700362 if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700363 toStrHelper.add("ErrorInfo", errInfo);
364 }
365
366 return toStrHelper.toString();
367 }
368}