blob: f043af50dbb62f29abcf49bf331de5d909fb9289 [file] [log] [blame]
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +05301/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.pcepio.protocol.ver1;
18
19import java.util.LinkedList;
20import java.util.ListIterator;
21
22import org.jboss.netty.buffer.ChannelBuffer;
23import org.onosproject.pcepio.exceptions.PcepParseException;
24import org.onosproject.pcepio.protocol.PcepOpenObject;
25import org.onosproject.pcepio.protocol.PcepType;
26import org.onosproject.pcepio.protocol.PcepVersion;
27import org.onosproject.pcepio.types.GmplsCapabilityTlv;
Priyanka B21f4b732016-03-21 20:54:12 +053028import org.onosproject.pcepio.types.NodeAttributesTlv;
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +053029import org.onosproject.pcepio.types.PceccCapabilityTlv;
30import org.onosproject.pcepio.types.PcepLabelDbVerTlv;
31import org.onosproject.pcepio.types.PcepObjectHeader;
32import org.onosproject.pcepio.types.PcepValueType;
Priyanka B21f4b732016-03-21 20:54:12 +053033import org.onosproject.pcepio.types.SrPceCapabilityTlv;
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +053034import org.onosproject.pcepio.types.StatefulLspDbVerTlv;
35import org.onosproject.pcepio.types.StatefulPceCapabilityTlv;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053036import org.onosproject.pcepio.types.LsCapabilityTlv;
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +053037import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
40import com.google.common.base.MoreObjects;
41
Phanendra Manda51fb9c22015-09-01 16:17:41 +053042/**
43 * Provides PCEP open object.
44 */
45public class PcepOpenObjectVer1 implements PcepOpenObject {
46
47 /*
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +053048 message format.
49 0 1 2 3
50 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
51 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 | Object-Class | OT |Res|P|I| Object Length (bytes) |
53 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 | Ver | Flags | Keepalive | DeadTimer | SID |
55 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 | |
57 // Optional TLVs //
58 | |
59 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60
61 The OPEN Object format
Phanendra Manda51fb9c22015-09-01 16:17:41 +053062 */
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +053063 protected static final Logger log = LoggerFactory.getLogger(PcepOpenObjectVer1.class);
64
65 public static final PcepType MSG_TYPE = PcepType.OPEN;
66 public static final byte OPEN_OBJECT_VERSION = 1;
67 public static final byte OPEN_OBJ_TYPE = 1;
68 public static final byte OPEN_OBJ_CLASS = 1;
69 public static final byte DEFAULT_KEEPALIVE_TIME = 30;
70 public static final byte DEFAULT_DEAD_TIME = 120;
71 public static final short OPEN_OBJ_MINIMUM_LENGTH = 8;
72 public static final int DEFAULT_GMPLS_CAPABILITY_TLV_IVALUE = 0X0;
73 public static final int DEFAULT_STATEFUL_PCE_CAPABILITY_TLV_IVALUE = 0xf;
74 public static final int DEFAULT_PCECC_CAPABILITY_TLV_IVALUE = 0x7;
75 public static final int DEFAULT_PCEP_LABEL_DB_VER_TLV_IVALUE = 0X0;
76
77 public static final PcepObjectHeader DEFAULT_OPEN_HEADER = new PcepObjectHeader(OPEN_OBJ_CLASS, OPEN_OBJ_TYPE,
78 PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, OPEN_OBJ_MINIMUM_LENGTH);
79
80 private PcepObjectHeader openObjHeader;
81 private byte keepAliveTime;
82 private byte deadTime;
83 private byte sessionId;
84 private LinkedList<PcepValueType> llOptionalTlv;
85
86 /**
87 * Default constructor.
88 */
89 public PcepOpenObjectVer1() {
90 this.openObjHeader = null;
91 this.keepAliveTime = 0;
92 this.deadTime = 0;
93 this.sessionId = 0;
94 this.llOptionalTlv = null;
95 }
96
97 /**
98 * Constructor to initialize all member variables.
99 *
100 * @param openObjHeader Open Object Header
101 * @param keepAliveTime Keepalive timer value
102 * @param deadTime Dead timer value
103 * @param sessionID session id
104 * @param llOptionalTlv Optional TLV
105 */
106 public PcepOpenObjectVer1(PcepObjectHeader openObjHeader, byte keepAliveTime, byte deadTime, byte sessionID,
107 LinkedList<PcepValueType> llOptionalTlv) {
108 this.openObjHeader = openObjHeader;
109 this.keepAliveTime = keepAliveTime;
110 this.deadTime = deadTime;
111 this.sessionId = sessionID;
112 this.llOptionalTlv = llOptionalTlv;
113 }
114
115 @Override
116 public PcepObjectHeader getOpenObjHeader() {
117 return this.openObjHeader;
118 }
119
120 @Override
121 public void setOpenObjHeader(PcepObjectHeader obj) {
122 this.openObjHeader = obj;
123 }
124
125 @Override
126 public byte getKeepAliveTime() {
127 return this.keepAliveTime;
128 }
129
130 @Override
131 public void setKeepAliveTime(byte value) {
132 this.keepAliveTime = value;
133 }
134
135 @Override
136 public PcepVersion getVersion() {
137 return PcepVersion.PCEP_1;
138 }
139
140 @Override
141 public byte getDeadTime() {
142 return this.deadTime;
143 }
144
145 @Override
146 public void setDeadTime(byte value) {
147 this.deadTime = value;
148 }
149
150 @Override
151 public byte getSessionId() {
152 return this.sessionId;
153 }
154
155 @Override
156 public void setSessionId(byte value) {
157 this.sessionId = value;
158 }
159
160 @Override
161 public LinkedList<PcepValueType> getOptionalTlv() {
162 return this.llOptionalTlv;
163 }
164
165 @Override
166 public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
167 this.llOptionalTlv = llOptionalTlv;
168 }
169
170 /**
171 * Reads from channel buffer and returns object of PcepOpenObject.
172 *
173 * @param cb of type channel buffer
174 * @return object of PcepOpenObject
175 * @throws PcepParseException if mandatory fields are missing
176 */
177 public static PcepOpenObject read(ChannelBuffer cb) throws PcepParseException {
178
179 PcepObjectHeader openObjHeader;
180 byte version;
181 byte keepAliveTime;
182 byte deadTime;
183 byte sessionID;
184 LinkedList<PcepValueType> llOptionalTlv;
185
186 openObjHeader = PcepObjectHeader.read(cb);
187 version = cb.readByte();
188 version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
189 if (version != OPEN_OBJECT_VERSION) {
190 throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
191 }
192 /* Keepalive */
193 keepAliveTime = cb.readByte();
194
195 /* DeadTimer */
196 deadTime = cb.readByte();
197
198 /* SID */
199 sessionID = cb.readByte();
200
201 // Optional TLV
202 llOptionalTlv = parseOptionalTlv(cb);
203
204 return new PcepOpenObjectVer1(openObjHeader, keepAliveTime, deadTime, sessionID, llOptionalTlv);
205 }
206
207 /**
208 * Returns linkedlist of optional tlvs.
209 *
210 * @param cb of type channel buffer
211 * @return llOptionalTlv Optional TLV
212 * @throws PcepParseException if mandatory fields are missing
213 */
214 protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
215
216 LinkedList<PcepValueType> llOptionalTlv;
217
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700218 llOptionalTlv = new LinkedList<>();
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530219
220 while (4 <= cb.readableBytes()) {
221 PcepValueType tlv;
222 short hType = cb.readShort();
223 short hLength = cb.readShort();
224
225 switch (hType) {
226 case GmplsCapabilityTlv.TYPE:
227 log.debug("GmplsCapabilityTlv");
228 if (GmplsCapabilityTlv.LENGTH != hLength) {
229 throw new PcepParseException("Invalid length received for Gmpls_Capability_Tlv.");
230 }
231 int iValue = cb.readInt();
232 tlv = new GmplsCapabilityTlv(iValue);
233 break;
234 case StatefulPceCapabilityTlv.TYPE:
235 log.debug("StatefulPceCapabilityTlv");
236 if (StatefulPceCapabilityTlv.LENGTH != hLength) {
237 throw new PcepParseException("Invalid length received for StatefulPceCapabilityTlv.");
238 }
239 tlv = StatefulPceCapabilityTlv.read(cb);
240 break;
241 case PceccCapabilityTlv.TYPE:
242 log.debug("PceccCapabilityTlv");
243 if (PceccCapabilityTlv.LENGTH != hLength) {
244 throw new PcepParseException("Invalid length for PceccCapabilityTlv.");
245 }
246 iValue = cb.readInt();
247 tlv = new PceccCapabilityTlv(iValue);
248 break;
249 case StatefulLspDbVerTlv.TYPE:
250 log.debug("StatefulLspDbVerTlv");
251 if (StatefulLspDbVerTlv.LENGTH != hLength) {
252 throw new PcepParseException("Invalid length received for StatefulLspDbVerTlv.");
253 }
254 long lValue = cb.readLong();
255 tlv = new StatefulLspDbVerTlv(lValue);
256 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530257 case LsCapabilityTlv.TYPE:
258 log.debug("LsCapabilityTlv");
259 if (LsCapabilityTlv.LENGTH != hLength) {
260 throw new PcepParseException("Invalid length received for LsCapabilityTlv.");
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530261 }
262 iValue = cb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530263 tlv = new LsCapabilityTlv(iValue);
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530264 break;
265 case PcepLabelDbVerTlv.TYPE:
266 log.debug("PcepLabelDbVerTlv");
267 if (PcepLabelDbVerTlv.LENGTH != hLength) {
268 throw new PcepParseException("Invalid length received for PcepLabelDbVerTlv.");
269 }
270 lValue = cb.readLong();
271 tlv = new PcepLabelDbVerTlv(lValue);
272 break;
Priyanka B21f4b732016-03-21 20:54:12 +0530273 case NodeAttributesTlv.TYPE:
274 log.debug("NodeAttributesTlv");
275 if (cb.readableBytes() < hLength) {
276 throw new PcepParseException("Invalid length for NodeAttributesTlv.");
277 }
278 tlv = NodeAttributesTlv.read(cb.readBytes(hLength), hLength);
279 break;
280 case SrPceCapabilityTlv.TYPE:
281 log.debug("SrPceCapabilityTlv");
282 if (SrPceCapabilityTlv.LENGTH != hLength) {
283 throw new PcepParseException("Invalid length received for SrPceCapabilityTlv.");
284 }
285 tlv = SrPceCapabilityTlv.read(cb);
286 break;
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530287 default:
288 log.debug("Unsupported TLV: " + hType);
289 cb.skipBytes(hLength);
290 continue;
291 }
292
293 llOptionalTlv.add(tlv);
294 }
295
296 if (0 < cb.readableBytes()) {
297 throw new PcepParseException("Optional Tlv parsing error. Extra bytes received.");
298 }
299
300 return llOptionalTlv;
301 }
302
303 @Override
304 public int write(ChannelBuffer cb) throws PcepParseException {
305
306 int objStartIndex = cb.writerIndex();
307
308 //write common header
309 int objLenIndex = openObjHeader.write(cb);
310
311 if (objLenIndex <= 0) {
312 throw new PcepParseException("Unable to write Open object header.");
313 }
314
315 cb.writeByte((byte) (OPEN_OBJECT_VERSION << PcepMessageVer1.SHIFT_FLAG));
316 cb.writeByte(this.keepAliveTime);
317 cb.writeByte(this.deadTime);
318 cb.writeByte(this.sessionId);
319
320 //Pack optional TLV
321 packOptionalTlv(cb);
322
323 //now write OPEN Object Length
324 int length = cb.writerIndex() - objStartIndex;
325 cb.setShort(objLenIndex, (short) length);
326 //will be helpful during print().
327 this.openObjHeader.setObjLen((short) length);
328
329 return length;
330 }
331
332 /**
333 * Returns writer index.
334 *
335 * @param cb of type channel buffer.
336 * @return writer index
337 */
338 protected int packOptionalTlv(ChannelBuffer cb) {
339 int startIndex = cb.writerIndex();
340
341 LinkedList<PcepValueType> llOptionalTlv = this.llOptionalTlv;
342 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
343 while (listIterator.hasNext()) {
344 PcepValueType tlv = listIterator.next();
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700345 if (tlv == null) {
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530346 log.debug("TLV is null from OptionalTlv list");
347 continue;
348 }
349
350 tlv.write(cb);
351
352 // need to take care of padding
353 int pad = tlv.getLength() % 4;
354
355 if (0 != pad) {
356 pad = 4 - pad;
357 for (int i = 0; i < pad; ++i) {
358 cb.writeByte((byte) 0);
359 }
360 }
361 }
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530362 return cb.writerIndex() - startIndex;
363 }
364
Phanendra Manda51fb9c22015-09-01 16:17:41 +0530365 /**
366 * Builder class for PCPE open object.
367 */
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530368 public static class Builder implements PcepOpenObject.Builder {
369 // Pcep open message fields
370 private boolean bIsHeaderSet = false;
371 private PcepObjectHeader openObjHeader;
372 private boolean bIsKeepAliveTimeSet = false;
373 private byte keepAliveTime;
374 private boolean bIsDeadTimeSet = false;
375 private byte deadTime;
376 private boolean bIsSessionIDSet = false;
377 private byte sessionID;
378 private boolean bIsOptionalTlvSet = false;
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700379 private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530380
381 private boolean bIsPFlagSet = false;
382 private boolean bPFlag;
383
384 private boolean bIsIFlagSet = false;
385 private boolean bIFlag;
386
387 @Override
388 public PcepOpenObject build() throws PcepParseException {
389 PcepObjectHeader openObjHeader = this.bIsHeaderSet ? this.openObjHeader : DEFAULT_OPEN_HEADER;
390 byte keepAliveTime = this.bIsKeepAliveTimeSet ? this.keepAliveTime : DEFAULT_KEEPALIVE_TIME;
391 byte deadTime = this.bIsDeadTimeSet ? this.deadTime : DEFAULT_DEAD_TIME;
392
393 if (!this.bIsSessionIDSet) {
394 throw new PcepParseException("SessionID is not set (mandatory)");
395 }
396 if (!this.bIsOptionalTlvSet) {
397 //Add tlv to list
398 //Add GmplsCapabilityTlv
399 PcepValueType tlv;
400 int iValue = DEFAULT_GMPLS_CAPABILITY_TLV_IVALUE;
401 tlv = new GmplsCapabilityTlv(iValue);
402 this.llOptionalTlv.add(tlv);
403
404 //Add StatefulPceCapabilityTlv
405 iValue = DEFAULT_STATEFUL_PCE_CAPABILITY_TLV_IVALUE;
406 tlv = new StatefulPceCapabilityTlv(iValue);
407 this.llOptionalTlv.add(tlv);
408
409 }
410
411 if (bIsPFlagSet) {
412 openObjHeader.setPFlag(bPFlag);
413 }
414
415 if (bIsIFlagSet) {
416 openObjHeader.setIFlag(bIFlag);
417 }
418
419 return new PcepOpenObjectVer1(openObjHeader, keepAliveTime, deadTime, this.sessionID, this.llOptionalTlv);
420 }
421
422 @Override
423 public PcepObjectHeader getOpenObjHeader() {
424 return this.openObjHeader;
425 }
426
427 @Override
428 public Builder setOpenObjHeader(PcepObjectHeader obj) {
429 this.openObjHeader = obj;
430 this.bIsHeaderSet = true;
431 return this;
432 }
433
434 @Override
435 public byte getKeepAliveTime() {
436 return this.keepAliveTime;
437 }
438
439 @Override
440 public Builder setKeepAliveTime(byte value) {
441 this.keepAliveTime = value;
442 this.bIsKeepAliveTimeSet = true;
443 return this;
444 }
445
446 @Override
447 public byte getDeadTime() {
448 return this.deadTime;
449 }
450
451 @Override
452 public Builder setDeadTime(byte value) {
453 this.deadTime = value;
454 this.bIsDeadTimeSet = true;
455 return this;
456 }
457
458 @Override
459 public byte getSessionId() {
460 return this.sessionID;
461 }
462
463 @Override
464 public Builder setSessionId(byte value) {
465 this.sessionID = value;
466 this.bIsSessionIDSet = true;
467 return this;
468 }
469
470 @Override
471 public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
472 this.llOptionalTlv = llOptionalTlv;
473 this.bIsOptionalTlvSet = true;
474 return this;
475 }
476
477 @Override
478 public LinkedList<PcepValueType> getOptionalTlv() {
479 return this.llOptionalTlv;
480 }
481
482 @Override
483 public Builder setPFlag(boolean value) {
484 this.bPFlag = value;
485 this.bIsPFlagSet = true;
486 return this;
487 }
488
489 @Override
490 public Builder setIFlag(boolean value) {
491 this.bIFlag = value;
492 this.bIsIFlagSet = true;
493 return this;
494 }
495 }
496
497 @Override
498 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700499 return MoreObjects.toStringHelper(getClass())
500 .add("ObjectHeader", openObjHeader)
501 .add("Keepalive", keepAliveTime)
502 .add("DeadTimer", deadTime)
503 .add("SessionId", sessionId)
504 .add("OptionalTlv", llOptionalTlv)
505 .toString();
Mahesh Poojary S5afd06c2015-08-21 14:51:04 +0530506 }
507}