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.PcepTEObject;
25 import org.onosproject.pcepio.types.LocalTENodeDescriptorsTlv;
26 import org.onosproject.pcepio.types.PcepObjectHeader;
27 import org.onosproject.pcepio.types.PcepValueType;
28 import org.onosproject.pcepio.types.RemoteTENodeDescriptorsTlv;
29 import org.onosproject.pcepio.types.RoutingUniverseTlv;
30 import org.onosproject.pcepio.types.TELinkAttributesTlv;
31 import org.onosproject.pcepio.types.TELinkDescriptorsTlv;
32 import org.onosproject.pcepio.types.TENodeAttributesTlv;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 import com.google.common.base.MoreObjects;
39 * Provides PCEP TE Object.
41 public class PcepTEObjectVer1 implements PcepTEObject {
44 reference: PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
45 TE Object-Class is [TBD6].
47 Two Object-Type values are defined for the TE object:
49 o TE Node: TE Object-Type is 1.
51 o TE Link: TE Object-Type is 2.
53 The format of the TE object body is as follows:
56 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
57 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 | Protocol-ID | Flag |R|S|
59 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 protected static final Logger log = LoggerFactory.getLogger(PcepTEObjectVer1.class);
69 public static final byte TE_OBJ_TYPE_NODE_VALUE = 1;
70 public static final byte TE_OBJ_TYPE_LINK_VALUE = 2;
72 public static final byte TE_OBJ_CLASS = 101; //TBD6 in RFC.
73 public static final byte TE_OBJECT_VERSION = 1;
75 // TE_OBJ_MINIMUM_LENGTH = TEObjectHeaderLen(4)+ TEObjectLen(8)
76 public static final short TE_OBJ_MINIMUM_LENGTH = 12;
78 // Signaled ,all default values to be checked.
79 public static final byte DEFAULT_PROTOCOL_ID = 1; //IS-IS Level 1
80 public static final boolean DEFAULT_R_FLAG = false;
81 public static final boolean DEFAULT_S_FLAG = false;
82 public static final int DEFAULT_TE_ID = 0;
84 public static final int OBJECT_HEADER_LENGTH = 4;
85 public static final int RIGHT_SHIFT_ONE = 1;
86 public static final int RIGHT_FIRST_FLAG = 0x1;
87 public static final int FLAG_SET_R_FLAG = 0x2;
88 public static final int FLAG_SET_S_FLAG = 0x1;
89 public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
90 public static final int MINIMUM_TLV_HEADER_LENGTH = 4;
92 public static final PcepObjectHeader DEFAULT_TE_OBJECT_HEADER = new PcepObjectHeader(TE_OBJ_CLASS,
93 TE_OBJ_TYPE_NODE_VALUE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
94 TE_OBJ_MINIMUM_LENGTH);
96 private PcepObjectHeader teObjHeader;
97 private byte yProtocolId;
99 private boolean bRFlag;
100 private boolean bSFlag;
103 private LinkedList<PcepValueType> llOptionalTlv;
106 * Constructor to initialize variables.
108 * @param teObjHeader TE Object header
109 * @param yProtocolId Protocol-ID
110 * @param bRFlag R-flag
111 * @param bSFlag S-flag
113 * @param llOptionalTlv linked list of Optional TLV
115 public PcepTEObjectVer1(PcepObjectHeader teObjHeader, byte yProtocolId, boolean bRFlag, boolean bSFlag, int iTEId,
116 LinkedList<PcepValueType> llOptionalTlv) {
118 this.teObjHeader = teObjHeader;
119 this.yProtocolId = yProtocolId;
120 this.bRFlag = bRFlag;
121 this.bSFlag = bSFlag;
123 this.llOptionalTlv = llOptionalTlv;
127 public PcepObjectHeader getTEObjHeader() {
128 return this.teObjHeader;
132 public void setTEObjHeader(PcepObjectHeader obj) {
133 this.teObjHeader = obj;
137 public byte getProtocolId() {
138 return this.yProtocolId;
142 public void setProtocolId(byte yProtId) {
143 this.yProtocolId = yProtId;
147 public boolean getRFlag() {
152 public void setRFlag(boolean bRFlag) {
153 this.bRFlag = bRFlag;
157 public boolean getSFlag() {
162 public void setSFlag(boolean bSFlag) {
163 this.bSFlag = bSFlag;
167 public int getTEId() {
172 public void setTEId(int iTEId) {
177 public LinkedList<PcepValueType> getOptionalTlv() {
178 return this.llOptionalTlv;
182 public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
183 this.llOptionalTlv = llOptionalTlv;
187 * Reads from the channel buffer and returns Object of PcepTEObject.
189 * @param cb of type channel buffer
190 * @return Object of PcepTEObject
191 * @throws PcepParseException if mandatory fields are missing
193 public static PcepTEObject read(ChannelBuffer cb) throws PcepParseException {
196 PcepObjectHeader teObjHeader;
202 LinkedList<PcepValueType> llOptionalTlv;
204 teObjHeader = PcepObjectHeader.read(cb);
206 //take only TEObject buffer.
207 ChannelBuffer tempCb = cb.readBytes(teObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
209 yProtocolId = tempCb.readByte();
210 //ignore first two bytes of Flags
213 Integer iTemp = (int) tempCb.readByte(); //read 3rd byte Flag
214 bSFlag = (iTemp & FLAG_SET_S_FLAG) == FLAG_SET_S_FLAG;
215 bRFlag = (iTemp & FLAG_SET_R_FLAG) == FLAG_SET_R_FLAG;
217 iTEId = tempCb.readInt();
219 // parse optional TLV
220 llOptionalTlv = parseOptionalTlv(tempCb);
222 return new PcepTEObjectVer1(teObjHeader, yProtocolId, bRFlag, bSFlag, iTEId, llOptionalTlv);
226 public int write(ChannelBuffer cb) throws PcepParseException {
228 //write Object header
229 int objStartIndex = cb.writerIndex();
230 int objLenIndex = teObjHeader.write(cb);
232 if (objLenIndex <= 0) {
233 throw new PcepParseException("ObjectLength Index is " + objLenIndex);
237 cb.writeByte(this.yProtocolId);
244 bTemp = FLAG_SET_S_FLAG;
248 bTemp = (byte) (bTemp | FLAG_SET_R_FLAG);
258 //Update object length now
259 int length = cb.writerIndex() - objStartIndex;
261 //will be helpful during print().
262 teObjHeader.setObjLen((short) length);
264 cb.setShort(objLenIndex, (short) length);
266 return cb.writerIndex();
270 * Returns Linked list of PCEP Value Type.
272 * @param cb of channel buffer
273 * @return Linked list of PCEP Value Type
274 * @throws PcepParseException if mandatory fields are missing
276 protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
278 LinkedList<PcepValueType> llOutOptionalTlv;
280 llOutOptionalTlv = new LinkedList<>();
282 while (MINIMUM_TLV_HEADER_LENGTH <= cb.readableBytes()) {
285 short hType = cb.readShort();
286 short hLength = cb.readShort();
291 case RoutingUniverseTlv.TYPE:
292 lValue = cb.readLong();
293 tlv = new RoutingUniverseTlv(lValue);
295 case LocalTENodeDescriptorsTlv.TYPE:
296 tlv = LocalTENodeDescriptorsTlv.read(cb, hLength);
298 case RemoteTENodeDescriptorsTlv.TYPE:
299 tlv = RemoteTENodeDescriptorsTlv.read(cb, hLength);
301 case TELinkDescriptorsTlv.TYPE:
302 tlv = TELinkDescriptorsTlv.read(cb, hLength);
304 case TENodeAttributesTlv.TYPE:
305 tlv = TENodeAttributesTlv.read(cb, hLength);
307 case TELinkAttributesTlv.TYPE:
308 tlv = TELinkAttributesTlv.read(cb, hLength);
311 throw new PcepParseException("Unsupported TLV type :" + hType);
314 // Check for the padding
315 int pad = hLength % 4;
318 if (pad <= cb.readableBytes()) {
323 llOutOptionalTlv.add(tlv);
326 if (0 < cb.readableBytes()) {
328 throw new PcepParseException("Optional Tlv parsing error. Extra bytes received.");
330 return llOutOptionalTlv;
334 * Returns the writer index.
336 * @param cb of type channel buffer
337 * @return the writer index.
339 protected int packOptionalTlv(ChannelBuffer cb) {
341 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
343 while (listIterator.hasNext()) {
344 PcepValueType tlv = listIterator.next();
347 log.debug("TLV is null from OptionalTlv list");
352 // need to take care of padding
353 int pad = tlv.getLength() % 4;
357 for (int i = 0; i < pad; ++i) {
358 cb.writeByte((byte) 0);
362 return cb.writerIndex();
366 * Builder class for PCEP te object.
368 public static class Builder implements PcepTEObject.Builder {
369 private boolean bIsHeaderSet = false;
370 private boolean bIsProtocolIdSet = false;
371 private boolean bIsRFlagSet = false;
372 private boolean bIsSFlagSet = false;
373 private boolean bIsTEIdSet = false;
375 private PcepObjectHeader teObjHeader;
376 private byte yProtocolId;
377 private boolean bRFlag;
378 private boolean bSFlag;
380 private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
382 private boolean bIsPFlagSet = false;
383 private boolean bPFlag;
385 private boolean bIsIFlagSet = false;
386 private boolean bIFlag;
389 public PcepTEObject build() {
390 PcepObjectHeader teObjHeader = this.bIsHeaderSet ? this.teObjHeader : DEFAULT_TE_OBJECT_HEADER;
392 byte yProtocolId = this.bIsProtocolIdSet ? this.yProtocolId : DEFAULT_PROTOCOL_ID;
393 boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_R_FLAG;
394 boolean bSFlag = this.bIsSFlagSet ? this.bSFlag : DEFAULT_S_FLAG;
395 int iTEId = this.bIsTEIdSet ? this.iTEId : DEFAULT_TE_ID;
398 teObjHeader.setPFlag(bPFlag);
402 teObjHeader.setIFlag(bIFlag);
405 return new PcepTEObjectVer1(teObjHeader, yProtocolId, bRFlag, bSFlag, iTEId, llOptionalTlv);
410 public PcepObjectHeader getTEObjHeader() {
411 return this.teObjHeader;
415 public Builder setTEObjHeader(PcepObjectHeader obj) {
416 this.teObjHeader = obj;
417 this.bIsHeaderSet = true;
422 public byte getProtocolId() {
423 return this.yProtocolId;
427 public Builder setProtocolId(byte yProtId) {
428 this.yProtocolId = yProtId;
429 this.bIsProtocolIdSet = true;
434 public boolean getRFlag() {
439 public Builder setRFlag(boolean bRFlag) {
440 this.bRFlag = bRFlag;
441 this.bIsRFlagSet = true;
446 public boolean getSFlag() {
451 public Builder setSFlag(boolean bSFlag) {
452 this.bSFlag = bSFlag;
453 this.bIsSFlagSet = true;
458 public int getTEId() {
463 public Builder setTEId(int iTEId) {
465 this.bIsTEIdSet = true;
470 public LinkedList<PcepValueType> getOptionalTlv() {
471 return this.llOptionalTlv;
475 public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
476 this.llOptionalTlv = llOptionalTlv;
481 public Builder setPFlag(boolean value) {
483 this.bIsPFlagSet = true;
488 public Builder setIFlag(boolean value) {
490 this.bIsIFlagSet = true;
496 public String toString() {
497 return MoreObjects.toStringHelper(getClass())
498 .add("ObjectHeader", teObjHeader)
499 .add("ProtocolId", yProtocolId)
500 .add("RFlag", (bRFlag) ? 1 : 0)
501 .add("SFlag", (bSFlag) ? 1 : 0)
503 .add("OptionalTlv", llOptionalTlv)