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.PcepLspaObject;
25 import org.onosproject.pcepio.types.PcepObjectHeader;
26 import org.onosproject.pcepio.types.PcepValueType;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 import com.google.common.base.MoreObjects;
33 * Provides PCEP label Object .
35 public class PcepLspaObjectVer1 implements PcepLspaObject {
37 /* LSPA Object Body Format
40 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
41 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 | Setup Prio | Holding Prio | Flags |L| Reserved |
49 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 protected static final Logger log = LoggerFactory.getLogger(PcepLspaObjectVer1.class);
58 public static final byte LSPA_OBJ_TYPE = 1;
59 public static final byte LSPA_OBJ_CLASS = 9;
60 public static final byte LSPA_OBJECT_VERSION = 1;
61 public static final short LSPA_OBJ_MINIMUM_LENGTH = 20;
62 public static final int OBJECT_HEADER_LENGTH = 4;
64 static final PcepObjectHeader DEFAULT_LSPA_OBJECT_HEADER = new PcepObjectHeader(LSPA_OBJ_CLASS, LSPA_OBJ_TYPE,
65 PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, LSPA_OBJ_MINIMUM_LENGTH);
67 public static final int SETUP_PRIORITY_SHIFT_VALUE = 24;
68 public static final int HOLD_PRIORITY_SHIFT_VALUE = 16;
69 public static final int BFLAG_SHIFT_VALUE = 8;
70 public static final int LFLAG_SET = 1;
71 public static final int LFLAG_RESET = 0;
72 private PcepObjectHeader lspaObjHeader;
73 private int iExcludeAny;
74 private int iIncludeAny;
75 private int iIncludeAll;
76 private byte cSetupPriority;
77 private byte cHoldPriority;
78 private boolean bLFlag;
79 private LinkedList<PcepValueType> llOptionalTlv; //Optional TLV
82 * Constructor to initialize member variables.
84 * @param lspaObjHeader lspa object header
85 * @param bLFlag b l flag
86 * @param iExcludeAny excludeAny value
87 * @param iIncludeAny includeAny value
88 * @param iIncludeAll includeAll value
89 * @param cSetupPriority setup priority value
90 * @param cHoldPriority hold priority value
91 * @param llOptionalTlv list of optional tlv
93 public PcepLspaObjectVer1(PcepObjectHeader lspaObjHeader, boolean bLFlag, int iExcludeAny, int iIncludeAny,
94 int iIncludeAll, byte cSetupPriority, byte cHoldPriority, LinkedList<PcepValueType> llOptionalTlv) {
96 this.lspaObjHeader = lspaObjHeader;
98 this.iExcludeAny = iExcludeAny;
99 this.iIncludeAny = iIncludeAny;
100 this.iIncludeAll = iIncludeAll;
101 this.cSetupPriority = cSetupPriority;
102 this.cHoldPriority = cHoldPriority;
103 this.llOptionalTlv = llOptionalTlv;
107 * Sets Object Header.
109 * @param obj lspa object header
111 public void setLspaObjHeader(PcepObjectHeader obj) {
112 this.lspaObjHeader = obj;
116 public void setExcludeAny(int iExcludeAny) {
117 this.iExcludeAny = iExcludeAny;
121 public void setIncludeAny(int iIncludeAny) {
122 this.iIncludeAny = iIncludeAny;
126 public void setSetupPriority(byte cSetupPriority) {
127 this.cSetupPriority = cSetupPriority;
131 public void setHoldPriority(byte cHoldPriority) {
132 this.cHoldPriority = cHoldPriority;
136 public void setLFlag(boolean bLFlag) {
137 this.bLFlag = bLFlag;
141 * Returns lspa Object Header.
143 * @return lspa Object Header
145 public PcepObjectHeader getLspaObjHeader() {
146 return this.lspaObjHeader;
150 public int getExcludeAny() {
151 return this.iExcludeAny;
155 public int getIncludeAny() {
156 return this.iIncludeAny;
160 public int getIncludeAll() {
161 return this.iIncludeAll;
165 public byte getSetupPriority() {
166 return this.cSetupPriority;
170 public byte getHoldPriority() {
171 return this.cHoldPriority;
175 public boolean getLFlag() {
180 public void setIncludeAll(int value) {
181 this.iIncludeAll = value;
186 public LinkedList<PcepValueType> getOptionalTlv() {
187 return this.llOptionalTlv;
191 public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
192 this.llOptionalTlv = llOptionalTlv;
197 * Reads channel buffer and returns object of PcepLspaObject.
199 * @param cb of type channel buffer.
200 * @return object of PcepLspaObject
201 * @throws PcepParseException while parsing lspa object from channel buffer
203 public static PcepLspaObject read(ChannelBuffer cb) throws PcepParseException {
205 log.debug("LspaObject::read");
206 PcepObjectHeader lspaObjHeader;
216 LinkedList<PcepValueType> llOptionalTlv;
218 lspaObjHeader = PcepObjectHeader.read(cb);
220 //take only Lspa Object buffer.
221 ChannelBuffer tempCb = cb.readBytes(lspaObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
222 iExcludeAny = tempCb.readInt();
223 iIncludeAny = tempCb.readInt();
224 iIncludeAll = tempCb.readInt();
225 cSetupPriority = tempCb.readByte();
226 cHoldPriority = tempCb.readByte();
227 flags = tempCb.readByte();
230 bLFlag = (flags & (byte) LFLAG_SET) == LFLAG_SET;
232 llOptionalTlv = parseOptionalTlv(tempCb);
234 return new PcepLspaObjectVer1(lspaObjHeader, bLFlag, iExcludeAny, iIncludeAny, iIncludeAll, cSetupPriority,
235 cHoldPriority, llOptionalTlv);
239 public int write(ChannelBuffer cb) throws PcepParseException {
241 //write Object header
242 int objStartIndex = cb.writerIndex();
244 int objLenIndex = lspaObjHeader.write(cb);
246 if (objLenIndex <= 0) {
247 throw new PcepParseException("Failed to write lspa object header. Index " + objLenIndex);
250 cb.writeInt(iExcludeAny);
251 cb.writeInt(iIncludeAny);
252 cb.writeInt(iIncludeAll);
254 int iTemp = cSetupPriority << SETUP_PRIORITY_SHIFT_VALUE;
255 iTemp = iTemp | (cHoldPriority << HOLD_PRIORITY_SHIFT_VALUE);
257 bFlag = (bLFlag) ? (byte) LFLAG_SET : LFLAG_RESET;
258 iTemp = iTemp | (bFlag << BFLAG_SHIFT_VALUE);
262 if (!packOptionalTlv(cb)) {
263 throw new PcepParseException("Faild to write lspa objects tlv to channel buffer");
266 short length = (short) (cb.writerIndex() - objStartIndex);
268 lspaObjHeader.setObjLen(length); //will be helpful during print().
270 //As per RFC the length of object should be multiples of 4
271 short pad = (short) (length % 4);
274 pad = (short) (4 - pad);
275 for (int i = 0; i < pad; i++) {
276 cb.writeByte((byte) 0);
278 length = (short) (length + pad);
280 cb.setShort(objLenIndex, length);
281 return cb.writerIndex();
285 * Parse list of optional tlvs.
287 * @param cb channel buffer
288 * @return list of optional tlvs.
289 * @throws PcepParseException when fails to parse optional tlv list.
291 public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
293 LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<>();
295 return llOutOptionalTlv;
299 * Writes optional tlvs to channel buffer.
301 * @param cb channel buffer
304 protected boolean packOptionalTlv(ChannelBuffer cb) {
308 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
309 while (listIterator.hasNext()) {
310 PcepValueType tlv = listIterator.next();
312 log.debug("Warning: tlv is null from OptionalTlv list");
315 hTlvType = tlv.getType();
316 hTlvLength = tlv.getLength();
317 if (0 == hTlvLength) {
318 log.debug("Warning: invalid length in tlv of OptionalTlv list");
322 cb.writeShort(hTlvType);
323 cb.writeShort(hTlvLength);
326 //TODO: optional TLV for LSPA to be added
329 log.debug("Warning: PcepLspaObject: unknown tlv");
332 // As per RFC the length of object should
334 int pad = hTlvLength % 4;
338 if (pad <= cb.readableBytes()) {
347 * Builder class for PCEP lspa object.
349 public static class Builder implements PcepLspaObject.Builder {
350 private boolean bIsHeaderSet = false;
352 private PcepObjectHeader lspaObjHeader;
354 private boolean bLFlag;
355 private int iExcludeAny;
356 private boolean bIsExcludeAnySet = false;
357 private int iIncludeAny;
358 private boolean bIsIncludeAnySet = false;
359 private int iIncludeAll;
360 private boolean bIsIncludeAllSet = false;
361 private byte cSetupPriority;
362 private boolean bIsSetupPrioritySet = false;
363 private byte cHoldPriority;
364 private boolean bIsHoldPrioritySet = false;
365 private LinkedList<PcepValueType> llOptionalTlv;
367 private boolean bIsPFlagSet = false;
368 private boolean bPFlag;
370 private boolean bIsIFlagSet = false;
371 private boolean bIFlag;
374 public PcepLspaObject build() throws PcepParseException {
376 PcepObjectHeader lspaObjHeader = this.bIsHeaderSet ? this.lspaObjHeader : DEFAULT_LSPA_OBJECT_HEADER;
378 if (!this.bIsExcludeAnySet) {
379 throw new PcepParseException("ExcludeAny NOT Set while building PcepLspaObject.");
381 if (!this.bIsIncludeAnySet) {
382 throw new PcepParseException("IncludeAny NOT Set while building PcepLspaObject.");
384 if (!this.bIsIncludeAllSet) {
385 throw new PcepParseException("IncludeAll NOT Set while building PcepLspaObject.");
387 if (!this.bIsSetupPrioritySet) {
388 throw new PcepParseException("Setup Priority NOT Set while building PcepLspaObject.");
390 if (!this.bIsHoldPrioritySet) {
391 throw new PcepParseException("Hold Priority NOT Set while building PcepLspaObject.");
395 lspaObjHeader.setPFlag(bPFlag);
399 lspaObjHeader.setIFlag(bIFlag);
402 return new PcepLspaObjectVer1(lspaObjHeader, bLFlag, iExcludeAny, iIncludeAny, iIncludeAll, cSetupPriority,
403 cHoldPriority, llOptionalTlv);
407 public PcepObjectHeader getLspaObjHeader() {
408 return this.lspaObjHeader;
412 public Builder setLspaObjHeader(PcepObjectHeader obj) {
413 this.lspaObjHeader = obj;
414 this.bIsHeaderSet = true;
419 public boolean getLFlag() {
424 public Builder setLFlag(boolean value) {
430 public int getExcludeAny() {
431 return this.iExcludeAny;
435 public Builder setExcludeAny(int value) {
436 this.iExcludeAny = value;
437 this.bIsExcludeAnySet = true;
442 public int getIncludeAny() {
443 return this.iIncludeAny;
447 public Builder setIncludeAny(int value) {
448 this.iIncludeAny = value;
449 this.bIsIncludeAnySet = true;
454 public int getIncludeAll() {
455 return this.iIncludeAll;
459 public Builder setIncludeAll(int value) {
460 this.iIncludeAll = value;
461 this.bIsIncludeAllSet = true;
466 public byte getSetupPriority() {
467 return this.cSetupPriority;
471 public Builder setSetupPriority(byte value) {
472 this.cSetupPriority = value;
473 this.bIsSetupPrioritySet = true;
478 public byte getHoldPriority() {
479 return this.cHoldPriority;
483 public Builder setHoldPriority(byte value) {
484 this.cHoldPriority = value;
485 this.bIsHoldPrioritySet = true;
490 public LinkedList<PcepValueType> getOptionalTlv() {
491 return this.llOptionalTlv;
495 public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
496 this.llOptionalTlv = llOptionalTlv;
502 public Builder setPFlag(boolean value) {
504 this.bIsPFlagSet = true;
509 public Builder setIFlag(boolean value) {
511 this.bIsIFlagSet = true;
518 public String toString() {
519 return MoreObjects.toStringHelper(getClass())
520 .add("LFlag", bLFlag)
521 .add("SetupPriority", cSetupPriority)
522 .add("HoldPriority", cHoldPriority)
523 .add("IncludeAll", iIncludeAll)
524 .add("IncludeAny", iIncludeAny)
525 .add("ExcludeAny", iExcludeAny)
526 .add("OptionalTlvList", llOptionalTlv)