2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onosproject.pcepio.protocol.ver1;
19 import java.util.LinkedList;
20 import java.util.ListIterator;
22 import org.jboss.netty.buffer.ChannelBuffer;
23 import org.onosproject.pcepio.exceptions.PcepParseException;
24 import org.onosproject.pcepio.protocol.PcepOpenObject;
25 import org.onosproject.pcepio.protocol.PcepType;
26 import org.onosproject.pcepio.protocol.PcepVersion;
27 import org.onosproject.pcepio.types.GmplsCapabilityTlv;
28 import org.onosproject.pcepio.types.PceccCapabilityTlv;
29 import org.onosproject.pcepio.types.PcepLabelDbVerTlv;
30 import org.onosproject.pcepio.types.PcepObjectHeader;
31 import org.onosproject.pcepio.types.PcepValueType;
32 import org.onosproject.pcepio.types.StatefulLspDbVerTlv;
33 import org.onosproject.pcepio.types.StatefulPceCapabilityTlv;
34 import org.onosproject.pcepio.types.TedCapabilityTlv;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 import com.google.common.base.MoreObjects;
41 * Provides PCEP open object.
43 public class PcepOpenObjectVer1 implements PcepOpenObject {
48 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
49 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 | Object-Class | OT |Res|P|I| Object Length (bytes) |
51 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 | Ver | Flags | Keepalive | DeadTimer | SID |
53 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 The OPEN Object format
61 protected static final Logger log = LoggerFactory.getLogger(PcepOpenObjectVer1.class);
63 public static final PcepType MSG_TYPE = PcepType.OPEN;
64 public static final byte OPEN_OBJECT_VERSION = 1;
65 public static final byte OPEN_OBJ_TYPE = 1;
66 public static final byte OPEN_OBJ_CLASS = 1;
67 public static final byte DEFAULT_KEEPALIVE_TIME = 30;
68 public static final byte DEFAULT_DEAD_TIME = 120;
69 public static final short OPEN_OBJ_MINIMUM_LENGTH = 8;
70 public static final int DEFAULT_GMPLS_CAPABILITY_TLV_IVALUE = 0X0;
71 public static final int DEFAULT_STATEFUL_PCE_CAPABILITY_TLV_IVALUE = 0xf;
72 public static final int DEFAULT_PCECC_CAPABILITY_TLV_IVALUE = 0x7;
73 public static final int DEFAULT_PCEP_LABEL_DB_VER_TLV_IVALUE = 0X0;
75 public static final PcepObjectHeader DEFAULT_OPEN_HEADER = new PcepObjectHeader(OPEN_OBJ_CLASS, OPEN_OBJ_TYPE,
76 PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, OPEN_OBJ_MINIMUM_LENGTH);
78 private PcepObjectHeader openObjHeader;
79 private byte keepAliveTime;
80 private byte deadTime;
81 private byte sessionId;
82 private LinkedList<PcepValueType> llOptionalTlv;
85 * Default constructor.
87 public PcepOpenObjectVer1() {
88 this.openObjHeader = null;
89 this.keepAliveTime = 0;
92 this.llOptionalTlv = null;
96 * Constructor to initialize all member variables.
98 * @param openObjHeader Open Object Header
99 * @param keepAliveTime Keepalive timer value
100 * @param deadTime Dead timer value
101 * @param sessionID session id
102 * @param llOptionalTlv Optional TLV
104 public PcepOpenObjectVer1(PcepObjectHeader openObjHeader, byte keepAliveTime, byte deadTime, byte sessionID,
105 LinkedList<PcepValueType> llOptionalTlv) {
106 this.openObjHeader = openObjHeader;
107 this.keepAliveTime = keepAliveTime;
108 this.deadTime = deadTime;
109 this.sessionId = sessionID;
110 this.llOptionalTlv = llOptionalTlv;
114 public PcepObjectHeader getOpenObjHeader() {
115 return this.openObjHeader;
119 public void setOpenObjHeader(PcepObjectHeader obj) {
120 this.openObjHeader = obj;
124 public byte getKeepAliveTime() {
125 return this.keepAliveTime;
129 public void setKeepAliveTime(byte value) {
130 this.keepAliveTime = value;
134 public PcepVersion getVersion() {
135 return PcepVersion.PCEP_1;
139 public byte getDeadTime() {
140 return this.deadTime;
144 public void setDeadTime(byte value) {
145 this.deadTime = value;
149 public byte getSessionId() {
150 return this.sessionId;
154 public void setSessionId(byte value) {
155 this.sessionId = value;
159 public LinkedList<PcepValueType> getOptionalTlv() {
160 return this.llOptionalTlv;
164 public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
165 this.llOptionalTlv = llOptionalTlv;
169 * Reads from channel buffer and returns object of PcepOpenObject.
171 * @param cb of type channel buffer
172 * @return object of PcepOpenObject
173 * @throws PcepParseException if mandatory fields are missing
175 public static PcepOpenObject read(ChannelBuffer cb) throws PcepParseException {
177 PcepObjectHeader openObjHeader;
182 LinkedList<PcepValueType> llOptionalTlv;
184 openObjHeader = PcepObjectHeader.read(cb);
185 version = cb.readByte();
186 version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
187 if (version != OPEN_OBJECT_VERSION) {
188 throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
191 keepAliveTime = cb.readByte();
194 deadTime = cb.readByte();
197 sessionID = cb.readByte();
200 llOptionalTlv = parseOptionalTlv(cb);
202 return new PcepOpenObjectVer1(openObjHeader, keepAliveTime, deadTime, sessionID, llOptionalTlv);
206 * Returns linkedlist of optional tlvs.
208 * @param cb of type channel buffer
209 * @return llOptionalTlv Optional TLV
210 * @throws PcepParseException if mandatory fields are missing
212 protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
214 LinkedList<PcepValueType> llOptionalTlv;
216 llOptionalTlv = new LinkedList<>();
218 while (4 <= cb.readableBytes()) {
220 short hType = cb.readShort();
221 short hLength = cb.readShort();
224 case GmplsCapabilityTlv.TYPE:
225 log.debug("GmplsCapabilityTlv");
226 if (GmplsCapabilityTlv.LENGTH != hLength) {
227 throw new PcepParseException("Invalid length received for Gmpls_Capability_Tlv.");
229 int iValue = cb.readInt();
230 tlv = new GmplsCapabilityTlv(iValue);
232 case StatefulPceCapabilityTlv.TYPE:
233 log.debug("StatefulPceCapabilityTlv");
234 if (StatefulPceCapabilityTlv.LENGTH != hLength) {
235 throw new PcepParseException("Invalid length received for StatefulPceCapabilityTlv.");
237 tlv = StatefulPceCapabilityTlv.read(cb);
239 case PceccCapabilityTlv.TYPE:
240 log.debug("PceccCapabilityTlv");
241 if (PceccCapabilityTlv.LENGTH != hLength) {
242 throw new PcepParseException("Invalid length for PceccCapabilityTlv.");
244 iValue = cb.readInt();
245 tlv = new PceccCapabilityTlv(iValue);
247 case StatefulLspDbVerTlv.TYPE:
248 log.debug("StatefulLspDbVerTlv");
249 if (StatefulLspDbVerTlv.LENGTH != hLength) {
250 throw new PcepParseException("Invalid length received for StatefulLspDbVerTlv.");
252 long lValue = cb.readLong();
253 tlv = new StatefulLspDbVerTlv(lValue);
255 case TedCapabilityTlv.TYPE:
256 log.debug("TedCapabilityTlv");
257 if (TedCapabilityTlv.LENGTH != hLength) {
258 throw new PcepParseException("Invalid length received for TedCapabilityTlv.");
260 iValue = cb.readInt();
261 tlv = new TedCapabilityTlv(iValue);
263 case PcepLabelDbVerTlv.TYPE:
264 log.debug("PcepLabelDbVerTlv");
265 if (PcepLabelDbVerTlv.LENGTH != hLength) {
266 throw new PcepParseException("Invalid length received for PcepLabelDbVerTlv.");
268 lValue = cb.readLong();
269 tlv = new PcepLabelDbVerTlv(lValue);
272 log.debug("Unsupported TLV: " + hType);
273 cb.skipBytes(hLength);
277 llOptionalTlv.add(tlv);
280 if (0 < cb.readableBytes()) {
281 throw new PcepParseException("Optional Tlv parsing error. Extra bytes received.");
284 return llOptionalTlv;
288 public int write(ChannelBuffer cb) throws PcepParseException {
290 int objStartIndex = cb.writerIndex();
292 //write common header
293 int objLenIndex = openObjHeader.write(cb);
295 if (objLenIndex <= 0) {
296 throw new PcepParseException("Unable to write Open object header.");
299 cb.writeByte((byte) (OPEN_OBJECT_VERSION << PcepMessageVer1.SHIFT_FLAG));
300 cb.writeByte(this.keepAliveTime);
301 cb.writeByte(this.deadTime);
302 cb.writeByte(this.sessionId);
307 //now write OPEN Object Length
308 int length = cb.writerIndex() - objStartIndex;
309 cb.setShort(objLenIndex, (short) length);
310 //will be helpful during print().
311 this.openObjHeader.setObjLen((short) length);
317 * Returns writer index.
319 * @param cb of type channel buffer.
320 * @return writer index
322 protected int packOptionalTlv(ChannelBuffer cb) {
323 int startIndex = cb.writerIndex();
325 LinkedList<PcepValueType> llOptionalTlv = this.llOptionalTlv;
326 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
327 while (listIterator.hasNext()) {
328 PcepValueType tlv = listIterator.next();
330 log.debug("TLV is null from OptionalTlv list");
336 // need to take care of padding
337 int pad = tlv.getLength() % 4;
341 for (int i = 0; i < pad; ++i) {
342 cb.writeByte((byte) 0);
346 return cb.writerIndex() - startIndex;
350 * Builder class for PCPE open object.
352 public static class Builder implements PcepOpenObject.Builder {
353 // Pcep open message fields
354 private boolean bIsHeaderSet = false;
355 private PcepObjectHeader openObjHeader;
356 private boolean bIsKeepAliveTimeSet = false;
357 private byte keepAliveTime;
358 private boolean bIsDeadTimeSet = false;
359 private byte deadTime;
360 private boolean bIsSessionIDSet = false;
361 private byte sessionID;
362 private boolean bIsOptionalTlvSet = false;
363 private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
365 private boolean bIsPFlagSet = false;
366 private boolean bPFlag;
368 private boolean bIsIFlagSet = false;
369 private boolean bIFlag;
372 public PcepOpenObject build() throws PcepParseException {
373 PcepObjectHeader openObjHeader = this.bIsHeaderSet ? this.openObjHeader : DEFAULT_OPEN_HEADER;
374 byte keepAliveTime = this.bIsKeepAliveTimeSet ? this.keepAliveTime : DEFAULT_KEEPALIVE_TIME;
375 byte deadTime = this.bIsDeadTimeSet ? this.deadTime : DEFAULT_DEAD_TIME;
377 if (!this.bIsSessionIDSet) {
378 throw new PcepParseException("SessionID is not set (mandatory)");
380 if (!this.bIsOptionalTlvSet) {
382 //Add GmplsCapabilityTlv
384 int iValue = DEFAULT_GMPLS_CAPABILITY_TLV_IVALUE;
385 tlv = new GmplsCapabilityTlv(iValue);
386 this.llOptionalTlv.add(tlv);
388 //Add StatefulPceCapabilityTlv
389 iValue = DEFAULT_STATEFUL_PCE_CAPABILITY_TLV_IVALUE;
390 tlv = new StatefulPceCapabilityTlv(iValue);
391 this.llOptionalTlv.add(tlv);
396 openObjHeader.setPFlag(bPFlag);
400 openObjHeader.setIFlag(bIFlag);
403 return new PcepOpenObjectVer1(openObjHeader, keepAliveTime, deadTime, this.sessionID, this.llOptionalTlv);
407 public PcepObjectHeader getOpenObjHeader() {
408 return this.openObjHeader;
412 public Builder setOpenObjHeader(PcepObjectHeader obj) {
413 this.openObjHeader = obj;
414 this.bIsHeaderSet = true;
419 public byte getKeepAliveTime() {
420 return this.keepAliveTime;
424 public Builder setKeepAliveTime(byte value) {
425 this.keepAliveTime = value;
426 this.bIsKeepAliveTimeSet = true;
431 public byte getDeadTime() {
432 return this.deadTime;
436 public Builder setDeadTime(byte value) {
437 this.deadTime = value;
438 this.bIsDeadTimeSet = true;
443 public byte getSessionId() {
444 return this.sessionID;
448 public Builder setSessionId(byte value) {
449 this.sessionID = value;
450 this.bIsSessionIDSet = true;
455 public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
456 this.llOptionalTlv = llOptionalTlv;
457 this.bIsOptionalTlvSet = true;
462 public LinkedList<PcepValueType> getOptionalTlv() {
463 return this.llOptionalTlv;
467 public Builder setPFlag(boolean value) {
469 this.bIsPFlagSet = true;
474 public Builder setIFlag(boolean value) {
476 this.bIsIFlagSet = true;
482 public String toString() {
483 return MoreObjects.toStringHelper(getClass())
484 .add("ObjectHeader", openObjHeader)
485 .add("Keepalive", keepAliveTime)
486 .add("DeadTimer", deadTime)
487 .add("SessionId", sessionId)
488 .add("OptionalTlv", llOptionalTlv)