aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java')
-rw-r--r--framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java506
1 files changed, 506 insertions, 0 deletions
diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java
new file mode 100644
index 00000000..b1c69406
--- /dev/null
+++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepTEObject;
+import org.onosproject.pcepio.types.LocalTENodeDescriptorsTlv;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.RemoteTENodeDescriptorsTlv;
+import org.onosproject.pcepio.types.RoutingUniverseTlv;
+import org.onosproject.pcepio.types.TELinkAttributesTlv;
+import org.onosproject.pcepio.types.TELinkDescriptorsTlv;
+import org.onosproject.pcepio.types.TENodeAttributesTlv;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP TE Object.
+ */
+public class PcepTEObjectVer1 implements PcepTEObject {
+ /*
+ *
+ reference: PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
+ TE Object-Class is [TBD6].
+
+ Two Object-Type values are defined for the TE object:
+
+ o TE Node: TE Object-Type is 1.
+
+ o TE Link: TE Object-Type is 2.
+
+ The format of the TE object body is as follows:
+
+ 0 1 2 3
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Protocol-ID | Flag |R|S|
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | TE-ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // TLVs //
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+ protected static final Logger log = LoggerFactory.getLogger(PcepTEObjectVer1.class);
+
+ public static final byte TE_OBJ_TYPE_NODE_VALUE = 1;
+ public static final byte TE_OBJ_TYPE_LINK_VALUE = 2;
+
+ public static final byte TE_OBJ_CLASS = 101; //TBD6 in RFC.
+ public static final byte TE_OBJECT_VERSION = 1;
+
+ // TE_OBJ_MINIMUM_LENGTH = TEObjectHeaderLen(4)+ TEObjectLen(8)
+ public static final short TE_OBJ_MINIMUM_LENGTH = 12;
+
+ // Signaled ,all default values to be checked.
+ public static final byte DEFAULT_PROTOCOL_ID = 1; //IS-IS Level 1
+ public static final boolean DEFAULT_R_FLAG = false;
+ public static final boolean DEFAULT_S_FLAG = false;
+ public static final int DEFAULT_TE_ID = 0;
+
+ public static final int OBJECT_HEADER_LENGTH = 4;
+ public static final int RIGHT_SHIFT_ONE = 1;
+ public static final int RIGHT_FIRST_FLAG = 0x1;
+ public static final int FLAG_SET_R_FLAG = 0x2;
+ public static final int FLAG_SET_S_FLAG = 0x1;
+ public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+ public static final int MINIMUM_TLV_HEADER_LENGTH = 4;
+
+ public static final PcepObjectHeader DEFAULT_TE_OBJECT_HEADER = new PcepObjectHeader(TE_OBJ_CLASS,
+ TE_OBJ_TYPE_NODE_VALUE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
+ TE_OBJ_MINIMUM_LENGTH);
+
+ private PcepObjectHeader teObjHeader;
+ private byte yProtocolId;
+ // 2-flags
+ private boolean bRFlag;
+ private boolean bSFlag;
+ private int iTEId;
+ // Optional TLV
+ private LinkedList<PcepValueType> llOptionalTlv;
+
+ /**
+ * Constructor to initialize variables.
+ *
+ * @param teObjHeader TE Object header
+ * @param yProtocolId Protocol-ID
+ * @param bRFlag R-flag
+ * @param bSFlag S-flag
+ * @param iTEId TE-ID
+ * @param llOptionalTlv linked list of Optional TLV
+ */
+ public PcepTEObjectVer1(PcepObjectHeader teObjHeader, byte yProtocolId, boolean bRFlag, boolean bSFlag, int iTEId,
+ LinkedList<PcepValueType> llOptionalTlv) {
+
+ this.teObjHeader = teObjHeader;
+ this.yProtocolId = yProtocolId;
+ this.bRFlag = bRFlag;
+ this.bSFlag = bSFlag;
+ this.iTEId = iTEId;
+ this.llOptionalTlv = llOptionalTlv;
+ }
+
+ @Override
+ public PcepObjectHeader getTEObjHeader() {
+ return this.teObjHeader;
+ }
+
+ @Override
+ public void setTEObjHeader(PcepObjectHeader obj) {
+ this.teObjHeader = obj;
+ }
+
+ @Override
+ public byte getProtocolId() {
+ return this.yProtocolId;
+ }
+
+ @Override
+ public void setProtocolId(byte yProtId) {
+ this.yProtocolId = yProtId;
+ }
+
+ @Override
+ public boolean getRFlag() {
+ return this.bRFlag;
+ }
+
+ @Override
+ public void setRFlag(boolean bRFlag) {
+ this.bRFlag = bRFlag;
+ }
+
+ @Override
+ public boolean getSFlag() {
+ return this.bSFlag;
+ }
+
+ @Override
+ public void setSFlag(boolean bSFlag) {
+ this.bSFlag = bSFlag;
+ }
+
+ @Override
+ public int getTEId() {
+ return this.iTEId;
+ }
+
+ @Override
+ public void setTEId(int iTEId) {
+ this.iTEId = iTEId;
+ }
+
+ @Override
+ public LinkedList<PcepValueType> getOptionalTlv() {
+ return this.llOptionalTlv;
+ }
+
+ @Override
+ public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+ this.llOptionalTlv = llOptionalTlv;
+ }
+
+ /**
+ * Reads from the channel buffer and returns Object of PcepTEObject.
+ *
+ * @param cb of type channel buffer
+ * @return Object of PcepTEObject
+ * @throws PcepParseException if mandatory fields are missing
+ */
+ public static PcepTEObject read(ChannelBuffer cb) throws PcepParseException {
+ log.debug("read");
+
+ PcepObjectHeader teObjHeader;
+ byte yProtocolId;
+ // 2-flags
+ boolean bRFlag;
+ boolean bSFlag;
+ int iTEId;
+ LinkedList<PcepValueType> llOptionalTlv;
+
+ teObjHeader = PcepObjectHeader.read(cb);
+
+ //take only TEObject buffer.
+ ChannelBuffer tempCb = cb.readBytes(teObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+
+ yProtocolId = tempCb.readByte();
+ //ignore first two bytes of Flags
+ tempCb.readShort();
+
+ Integer iTemp = (int) tempCb.readByte(); //read 3rd byte Flag
+ bSFlag = (iTemp & FLAG_SET_S_FLAG) == FLAG_SET_S_FLAG;
+ bRFlag = (iTemp & FLAG_SET_R_FLAG) == FLAG_SET_R_FLAG;
+
+ iTEId = tempCb.readInt();
+
+ // parse optional TLV
+ llOptionalTlv = parseOptionalTlv(tempCb);
+
+ return new PcepTEObjectVer1(teObjHeader, yProtocolId, bRFlag, bSFlag, iTEId, llOptionalTlv);
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) throws PcepParseException {
+
+ //write Object header
+ int objStartIndex = cb.writerIndex();
+ int objLenIndex = teObjHeader.write(cb);
+
+ if (objLenIndex <= 0) {
+ throw new PcepParseException("ObjectLength Index is " + objLenIndex);
+ }
+
+ //write Protocol ID
+ cb.writeByte(this.yProtocolId);
+
+ //write Flag
+ cb.writeShort(0);
+
+ byte bTemp = 0;
+ if (bSFlag) {
+ bTemp = FLAG_SET_S_FLAG;
+ }
+
+ if (bRFlag) {
+ bTemp = (byte) (bTemp | FLAG_SET_R_FLAG);
+ }
+ cb.writeByte(bTemp);
+
+ //write TEId
+ cb.writeInt(iTEId);
+
+ // Add optional TLV
+ packOptionalTlv(cb);
+
+ //Update object length now
+ int length = cb.writerIndex() - objStartIndex;
+
+ //will be helpful during print().
+ teObjHeader.setObjLen((short) length);
+
+ cb.setShort(objLenIndex, (short) length);
+
+ return cb.writerIndex();
+ }
+
+ /**
+ * Returns Linked list of PCEP Value Type.
+ *
+ * @param cb of channel buffer
+ * @return Linked list of PCEP Value Type
+ * @throws PcepParseException if mandatory fields are missing
+ */
+ protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
+
+ LinkedList<PcepValueType> llOutOptionalTlv;
+
+ llOutOptionalTlv = new LinkedList<>();
+
+ while (MINIMUM_TLV_HEADER_LENGTH <= cb.readableBytes()) {
+
+ PcepValueType tlv;
+ short hType = cb.readShort();
+ short hLength = cb.readShort();
+ long lValue = 0;
+
+ switch (hType) {
+
+ case RoutingUniverseTlv.TYPE:
+ lValue = cb.readLong();
+ tlv = new RoutingUniverseTlv(lValue);
+ break;
+ case LocalTENodeDescriptorsTlv.TYPE:
+ tlv = LocalTENodeDescriptorsTlv.read(cb, hLength);
+ break;
+ case RemoteTENodeDescriptorsTlv.TYPE:
+ tlv = RemoteTENodeDescriptorsTlv.read(cb, hLength);
+ break;
+ case TELinkDescriptorsTlv.TYPE:
+ tlv = TELinkDescriptorsTlv.read(cb, hLength);
+ break;
+ case TENodeAttributesTlv.TYPE:
+ tlv = TENodeAttributesTlv.read(cb, hLength);
+ break;
+ case TELinkAttributesTlv.TYPE:
+ tlv = TELinkAttributesTlv.read(cb, hLength);
+ break;
+ default:
+ throw new PcepParseException("Unsupported TLV type :" + hType);
+ }
+
+ // Check for the padding
+ int pad = hLength % 4;
+ if (0 < pad) {
+ pad = 4 - pad;
+ if (pad <= cb.readableBytes()) {
+ cb.skipBytes(pad);
+ }
+ }
+
+ llOutOptionalTlv.add(tlv);
+ }
+
+ if (0 < cb.readableBytes()) {
+
+ throw new PcepParseException("Optional Tlv parsing error. Extra bytes received.");
+ }
+ return llOutOptionalTlv;
+ }
+
+ /**
+ * Returns the writer index.
+ *
+ * @param cb of type channel buffer
+ * @return the writer index.
+ */
+ protected int packOptionalTlv(ChannelBuffer cb) {
+
+ ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+
+ while (listIterator.hasNext()) {
+ PcepValueType tlv = listIterator.next();
+
+ if (tlv == null) {
+ log.debug("TLV is null from OptionalTlv list");
+ continue;
+ }
+ tlv.write(cb);
+
+ // need to take care of padding
+ int pad = tlv.getLength() % 4;
+
+ if (0 != pad) {
+ pad = 4 - pad;
+ for (int i = 0; i < pad; ++i) {
+ cb.writeByte((byte) 0);
+ }
+ }
+ }
+ return cb.writerIndex();
+ }
+
+ /**
+ * Builder class for PCEP te object.
+ */
+ public static class Builder implements PcepTEObject.Builder {
+ private boolean bIsHeaderSet = false;
+ private boolean bIsProtocolIdSet = false;
+ private boolean bIsRFlagSet = false;
+ private boolean bIsSFlagSet = false;
+ private boolean bIsTEIdSet = false;
+
+ private PcepObjectHeader teObjHeader;
+ private byte yProtocolId;
+ private boolean bRFlag;
+ private boolean bSFlag;
+ private int iTEId;
+ private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
+
+ private boolean bIsPFlagSet = false;
+ private boolean bPFlag;
+
+ private boolean bIsIFlagSet = false;
+ private boolean bIFlag;
+
+ @Override
+ public PcepTEObject build() {
+ PcepObjectHeader teObjHeader = this.bIsHeaderSet ? this.teObjHeader : DEFAULT_TE_OBJECT_HEADER;
+
+ byte yProtocolId = this.bIsProtocolIdSet ? this.yProtocolId : DEFAULT_PROTOCOL_ID;
+ boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_R_FLAG;
+ boolean bSFlag = this.bIsSFlagSet ? this.bSFlag : DEFAULT_S_FLAG;
+ int iTEId = this.bIsTEIdSet ? this.iTEId : DEFAULT_TE_ID;
+
+ if (bIsPFlagSet) {
+ teObjHeader.setPFlag(bPFlag);
+ }
+
+ if (bIsIFlagSet) {
+ teObjHeader.setIFlag(bIFlag);
+ }
+
+ return new PcepTEObjectVer1(teObjHeader, yProtocolId, bRFlag, bSFlag, iTEId, llOptionalTlv);
+
+ }
+
+ @Override
+ public PcepObjectHeader getTEObjHeader() {
+ return this.teObjHeader;
+ }
+
+ @Override
+ public Builder setTEObjHeader(PcepObjectHeader obj) {
+ this.teObjHeader = obj;
+ this.bIsHeaderSet = true;
+ return this;
+ }
+
+ @Override
+ public byte getProtocolId() {
+ return this.yProtocolId;
+ }
+
+ @Override
+ public Builder setProtocolId(byte yProtId) {
+ this.yProtocolId = yProtId;
+ this.bIsProtocolIdSet = true;
+ return this;
+ }
+
+ @Override
+ public boolean getRFlag() {
+ return this.bRFlag;
+ }
+
+ @Override
+ public Builder setRFlag(boolean bRFlag) {
+ this.bRFlag = bRFlag;
+ this.bIsRFlagSet = true;
+ return this;
+ }
+
+ @Override
+ public boolean getSFlag() {
+ return this.bSFlag;
+ }
+
+ @Override
+ public Builder setSFlag(boolean bSFlag) {
+ this.bSFlag = bSFlag;
+ this.bIsSFlagSet = true;
+ return this;
+ }
+
+ @Override
+ public int getTEId() {
+ return this.iTEId;
+ }
+
+ @Override
+ public Builder setTEId(int iTEId) {
+ this.iTEId = iTEId;
+ this.bIsTEIdSet = true;
+ return this;
+ }
+
+ @Override
+ public LinkedList<PcepValueType> getOptionalTlv() {
+ return this.llOptionalTlv;
+ }
+
+ @Override
+ public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+ this.llOptionalTlv = llOptionalTlv;
+ return this;
+ }
+
+ @Override
+ public Builder setPFlag(boolean value) {
+ this.bPFlag = value;
+ this.bIsPFlagSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setIFlag(boolean value) {
+ this.bIFlag = value;
+ this.bIsIFlagSet = true;
+ return this;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("ObjectHeader", teObjHeader)
+ .add("ProtocolId", yProtocolId)
+ .add("RFlag", (bRFlag) ? 1 : 0)
+ .add("SFlag", (bSFlag) ? 1 : 0)
+ .add("TeId", iTEId)
+ .add("OptionalTlv", llOptionalTlv)
+ .toString();
+ }
+}