[ONOS-2344]Implementation of PCEP report messages.
Change-Id: I9258a34ad7b09a583dcd0e56f90a36958c3acb34
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java
new file mode 100644
index 0000000..8ab6470
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2014 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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepInterLayerObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/*
+ * 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Reserved |N|I|
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+public class PcepInterLayerObjectVer1 implements PcepInterLayerObject {
+
+ protected static final Logger log = LoggerFactory.getLogger(PcepInterLayerObjectVer1.class);
+
+ public static final byte INTER_LAYER_OBJ_TYPE = 1;
+ public static final byte INTER_LAYER_OBJ_CLASS = 18;
+ public static final byte INTER_LAYER_OBJECT_VERSION = 1;
+ public static final short INTER_LAYER_OBJ_MINIMUM_LENGTH = 8;
+ public static final boolean DEFAULT_IFLAG = false;
+ public static final boolean DEFAULT_NFLAG = false;
+ public static final int OBJECT_HEADER_LENGTH = 4;
+ public static final int NFLAG_SHIFT_VALUE = 0x02;
+ public static final int IFLAG_SHIFT_VALUE = 0x01;
+ public static final int FLAGS_SET_VALUE = 1;
+
+ static final PcepObjectHeader DEFAULT_INTER_LAYER_OBJECT_HEADER = new PcepObjectHeader(INTER_LAYER_OBJ_CLASS,
+ INTER_LAYER_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
+ INTER_LAYER_OBJ_MINIMUM_LENGTH);
+
+ private PcepObjectHeader interLayerObjHeader;
+ private boolean bNFlag;
+ private boolean bIFlag;
+
+ /**
+ * Constructor to initialize all parameters for Pcep Inter Layer Object.
+ *
+ * @param interLayerObjHeader inter layer object header
+ * @param bNFlag N flag
+ * @param bIFlag I flag
+ */
+ public PcepInterLayerObjectVer1(PcepObjectHeader interLayerObjHeader, boolean bNFlag, boolean bIFlag) {
+
+ this.interLayerObjHeader = interLayerObjHeader;
+ this.bNFlag = bNFlag;
+ this.bIFlag = bIFlag;
+ }
+
+ /**
+ * Sets Object Header.
+ *
+ * @param obj object header
+ */
+ public void setInterLayerObjHeader(PcepObjectHeader obj) {
+ this.interLayerObjHeader = obj;
+ }
+
+ @Override
+ public void setbNFlag(boolean bNFlag) {
+ this.bNFlag = bNFlag;
+ }
+
+ @Override
+ public void setbIFlag(boolean bIFlag) {
+ this.bIFlag = bIFlag;
+ }
+
+ /**
+ * Returns object header.
+ *
+ * @return inter Layer Object Header
+ */
+ public PcepObjectHeader getInterLayerObjHeader() {
+ return this.interLayerObjHeader;
+ }
+
+ @Override
+ public boolean getbNFlag() {
+ return this.bNFlag;
+ }
+
+ @Override
+ public boolean getbIFlag() {
+ return this.bIFlag;
+ }
+
+ /**
+ * Reads channel buffer and returns object of PcepInterLayerObject.
+ *
+ * @param cb of type channel buffer
+ * @return object of PcepInterLayerObject
+ * @throws PcepParseException when fails to read from channel buffer
+ */
+ public static PcepInterLayerObject read(ChannelBuffer cb) throws PcepParseException {
+
+ PcepObjectHeader interLayerObjHeader;
+ boolean bNFlag;
+ boolean bIFlag;
+
+ interLayerObjHeader = PcepObjectHeader.read(cb);
+
+ //take only InterLayerObject buffer.
+ ChannelBuffer tempCb = cb.readBytes(interLayerObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+
+ int iTemp = tempCb.readInt();
+ bIFlag = ((iTemp & (byte) IFLAG_SHIFT_VALUE) == FLAGS_SET_VALUE) ? true : false;
+ bNFlag = ((iTemp & (byte) NFLAG_SHIFT_VALUE) == FLAGS_SET_VALUE) ? true : false;
+
+ return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag);
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) throws PcepParseException {
+
+ //write Object header
+ int objStartIndex = cb.writerIndex();
+
+ int objLenIndex = interLayerObjHeader.write(cb);
+
+ if (objLenIndex <= 0) {
+ throw new PcepParseException(" ObjectLength Index is " + objLenIndex);
+ }
+
+ int iTemp = 0;
+
+ if (bIFlag) {
+ iTemp = iTemp | (byte) IFLAG_SHIFT_VALUE;
+ }
+ if (bNFlag) {
+ iTemp = iTemp | (byte) NFLAG_SHIFT_VALUE;
+ }
+
+ cb.writeInt(iTemp);
+
+ //Update object length now
+ int length = cb.writerIndex() - objStartIndex;
+ //will be helpful during print().
+ interLayerObjHeader.setObjLen((short) length);
+ cb.setShort(objLenIndex, (short) length);
+
+ objLenIndex = cb.writerIndex();
+ return objLenIndex;
+ }
+
+ /**
+ * Builder class for PCEP inter layer object.
+ */
+ public static class Builder implements PcepInterLayerObject.Builder {
+
+ private boolean bIsHeaderSet = false;
+ private boolean bIsNFlagset = false;
+ private boolean bIsIFlagset = false;
+
+ private PcepObjectHeader interLayerObjHeader;
+ private boolean bNFlag;
+ private boolean bIFlag;
+
+ private boolean bIsPFlagSet = false;
+ private boolean bPFalg;
+
+ private boolean bIsIFlagSet = false;
+ private boolean iFlag;
+
+ @Override
+ public PcepInterLayerObject build() {
+ PcepObjectHeader interLayerObjHeader = this.bIsHeaderSet ? this.interLayerObjHeader
+ : DEFAULT_INTER_LAYER_OBJECT_HEADER;
+
+ boolean bNFlag = this.bIsNFlagset ? this.bNFlag : DEFAULT_NFLAG;
+ boolean bIFlag = this.bIsIFlagset ? this.bIFlag : DEFAULT_IFLAG;
+
+ if (bIsPFlagSet) {
+ interLayerObjHeader.setPFlag(bPFalg);
+ }
+
+ if (bIsIFlagSet) {
+ interLayerObjHeader.setIFlag(iFlag);
+ }
+ return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag);
+ }
+
+ @Override
+ public PcepObjectHeader getInterLayerObjHeader() {
+ return this.interLayerObjHeader;
+ }
+
+ @Override
+ public Builder setInterLayerObjHeader(PcepObjectHeader obj) {
+ this.interLayerObjHeader = obj;
+ this.bIsHeaderSet = true;
+ return this;
+ }
+
+ @Override
+ public boolean getbNFlag() {
+ return this.bNFlag;
+ }
+
+ @Override
+ public Builder setbNFlag(boolean value) {
+ this.bNFlag = value;
+ this.bIsNFlagset = true;
+ return this;
+ }
+
+ @Override
+ public boolean getbIFlag() {
+ return this.bIFlag;
+ }
+
+ @Override
+ public Builder setbIFlag(boolean value) {
+ this.bIFlag = value;
+ this.bIsIFlagset = true;
+ return this;
+ }
+
+ @Override
+ public Builder setPFlag(boolean value) {
+ this.bPFalg = value;
+ this.bIsPFlagSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setIFlag(boolean value) {
+ this.iFlag = value;
+ this.bIsIFlagSet = true;
+ return this;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass()).add("IFlag", bIFlag).add("NFlag", bNFlag).toString();
+ }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepReportMsgVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepReportMsgVer1.java
new file mode 100644
index 0000000..7ae69f7
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepReportMsgVer1.java
@@ -0,0 +1,298 @@
+/*
+ * 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.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.protocol.PcepMessageWriter;
+import org.onosproject.pcepio.protocol.PcepReportMsg;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.protocol.PcepStateReport;
+import org.onosproject.pcepio.protocol.PcepType;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+class PcepReportMsgVer1 implements PcepReportMsg {
+
+ // Pcep version: 1
+
+ /*
+ * The format of the PCRpt message is as follows:
+ * <PCRpt Message> ::= <Common Header>
+ * <state-report-list>
+ *Where:
+ * <state-report-list> ::= <state-report>[<state-report-list>]
+ * <state-report> ::= [<SRP>]
+ * <LSP>
+ * <path>
+ * Where:
+ * <path> ::= <ERO><attribute-list>[<RRO>]
+ * Where:
+ * <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
+ * where:
+ * <attribute-list> ::=[<LSPA>]
+ * [<BANDWIDTH>]
+ * [<metric-list>]
+ * [<IRO>]
+ * <metric-list> ::=<METRIC>[<metric-list>]
+ */
+ protected static final Logger log = LoggerFactory.getLogger(PcepReportMsgVer1.class);
+
+ public static final byte PACKET_VERSION = 1;
+ //PACKET_MINIMUM_LENGTH = CommonHeaderLen(4)+LspObjMinLen(8)+EroObjMinLen(12)
+ public static final int PACKET_MINIMUM_LENGTH = 24;
+ public static final PcepType MSG_TYPE = PcepType.REPORT;
+ public static final byte REPORT_OBJ_TYPE = 1;
+ //Optional TLV
+ private LinkedList<PcepStateReport> llStateReportList;
+
+ public static final PcepReportMsgVer1.Reader READER = new Reader();
+
+ static class Reader implements PcepMessageReader<PcepReportMsg> {
+
+ LinkedList<PcepStateReport> llStateReportList;
+
+ @Override
+ public PcepReportMsg readFrom(ChannelBuffer cb) throws PcepParseException {
+
+ if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
+ throw new PcepParseException("Received packet size " + cb.readableBytes()
+ + " is less than the expected size: " + PACKET_MINIMUM_LENGTH);
+ }
+ llStateReportList = new LinkedList<PcepStateReport>();
+ byte version = cb.readByte();
+ version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
+
+ if (version != PACKET_VERSION) {
+ throw new PcepParseException(" Invalid version: " + version);
+ }
+
+ byte type = cb.readByte();
+
+ if (type != MSG_TYPE.getType()) {
+ throw new PcepParseException("Unexpected type: " + type);
+ }
+
+ short length = cb.readShort();
+
+ if (length < PACKET_MINIMUM_LENGTH) {
+ throw new PcepParseException("Wrong length. Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: "
+ + length);
+ }
+ // parse state report list
+ parseStateReportList(cb);
+ return new PcepReportMsgVer1(llStateReportList);
+ }
+
+ // Parse State Report list
+ public void parseStateReportList(ChannelBuffer cb) throws PcepParseException {
+
+ /*
+ <state-report-list>
+ Where:
+ <state-report-list> ::= <state-report>[<state-report-list>]
+ <state-report> ::= [<SRP>]
+ <LSP>
+ <path>
+ Where:
+ <path> ::= <ERO><attribute-list>[<RRO>]
+ Where:
+ <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
+
+ */
+
+ while (0 < cb.readableBytes()) {
+
+ PcepStateReport pcestateReq = new PcepStateReportVer1();
+
+ /*
+ * SRP is optional
+ * Check whether SRP Object is available, if yes store it.
+ * First read common object header and check the Object Class whether it is SRP or LSP
+ * If it is LSP then store only LSP. So, SRP is optional. then read path and store.
+ * If it is SRP then store SRP and then read LSP, path and store them.
+ */
+
+ //mark the reader index to reset
+ cb.markReaderIndex();
+ PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+
+ byte yObjectClass = tempObjHeader.getObjClass();
+ byte yObjectType = tempObjHeader.getObjType();
+
+ //reset reader index
+ cb.resetReaderIndex();
+ //If SRP present then store it.
+ if ((PcepSrpObjectVer1.SRP_OBJ_CLASS == yObjectClass)
+ && (PcepSrpObjectVer1.SRP_OBJ_TYPE == yObjectType)) {
+ PcepSrpObject srpObj;
+ srpObj = PcepSrpObjectVer1.read(cb);
+ pcestateReq.setSrpObject(srpObj);
+ }
+
+ //store LSP object
+ PcepLspObject lspObj;
+ lspObj = PcepLspObjectVer1.read(cb);
+ pcestateReq.setLspObject(lspObj);
+
+ //store path
+ PcepStateReport.PcepMsgPath msgPath = new PcepStateReportVer1().new PcepMsgPath().read(cb);
+ pcestateReq.setMsgPath(msgPath);
+
+ llStateReportList.add(pcestateReq);
+ }
+ }
+ }
+
+ /**
+ * Constructor to initialize State Report List.
+ *
+ * @param llStateReportList list of type Pcep state report
+ */
+ PcepReportMsgVer1(LinkedList<PcepStateReport> llStateReportList) {
+ this.llStateReportList = llStateReportList;
+ }
+
+ /**
+ * Builder class for PCEP Report message.
+ */
+ static class Builder implements PcepReportMsg.Builder {
+ // Pcep report message fields
+ LinkedList<PcepStateReport> llStateReportList;
+
+ @Override
+ public PcepVersion getVersion() {
+ return PcepVersion.PCEP_1;
+ }
+
+ @Override
+ public PcepType getType() {
+ return PcepType.REPORT;
+ }
+
+ @Override
+ public PcepReportMsg build() {
+ return new PcepReportMsgVer1(this.llStateReportList);
+ }
+
+ @Override
+ public LinkedList<PcepStateReport> getStateReportList() {
+ return this.llStateReportList;
+ }
+
+ @Override
+ public Builder setStateReportList(LinkedList<PcepStateReport> ll) {
+ this.llStateReportList = ll;
+ return this;
+ }
+ }
+
+ @Override
+ public void writeTo(ChannelBuffer cb) throws PcepParseException {
+ WRITER.write(cb, this);
+ }
+
+ static final Writer WRITER = new Writer();
+
+ static class Writer implements PcepMessageWriter<PcepReportMsgVer1> {
+
+ @Override
+ public void write(ChannelBuffer cb, PcepReportMsgVer1 message) throws PcepParseException {
+
+ int startIndex = cb.writerIndex();
+
+ // first 3 bits set to version
+ cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
+
+ // message type
+ cb.writeByte(MSG_TYPE.getType());
+
+ // length is length of variable message, will be updated at the end
+ // Store the position of message
+ // length in buffer
+ int msgLenIndex = cb.writerIndex();
+
+ cb.writeShort((short) 0);
+ ListIterator<PcepStateReport> listIterator = message.llStateReportList.listIterator();
+
+ while (listIterator.hasNext()) {
+
+ PcepStateReport stateRpt = listIterator.next();
+ PcepSrpObject srpObj = stateRpt.getSrpObject();
+
+ //SRP object is optional
+ if (null != srpObj) {
+ srpObj.write(cb);
+ }
+
+ //LSP object is mandatory
+ PcepLspObject lspObj = stateRpt.getLspObject();
+ if (lspObj == null) {
+ throw new PcepParseException("LSP Object is mandatory object for PcRpt message.");
+ } else {
+ lspObj.write(cb);
+ }
+
+ //path is mandatory
+ PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
+ if (msgPath == null) {
+ throw new PcepParseException("Message path is mandatory object for PcRpt message.");
+ } else {
+ msgPath.write(cb);
+ }
+ }
+
+ // update message length field
+ int length = cb.writerIndex() - startIndex;
+ cb.setShort(msgLenIndex, (short) length);
+ }
+ }
+
+ @Override
+ public PcepVersion getVersion() {
+ return PcepVersion.PCEP_1;
+ }
+
+ @Override
+ public PcepType getType() {
+ return MSG_TYPE;
+ }
+
+ @Override
+ public LinkedList<PcepStateReport> getStateReportList() {
+ return this.llStateReportList;
+ }
+
+ @Override
+ public void setStateReportList(LinkedList<PcepStateReport> ll) {
+ this.llStateReportList = ll;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass()).add("StateReportList", llStateReportList).toString();
+ }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRroObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRroObjectVer1.java
new file mode 100644
index 0000000..7ce38ab
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRroObjectVer1.java
@@ -0,0 +1,340 @@
+/*
+ * 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.PcepRroObject;
+import org.onosproject.pcepio.types.IPv4SubObject;
+import org.onosproject.pcepio.types.IPv6SubObject;
+import org.onosproject.pcepio.types.LabelSubObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/*
+ * rfc3209
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Object-Class | OT |Res|P|I| Object Length (bytes) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ // (Subobjects) //
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Each subobject has its own Length
+ field. The length contains the total length of the subobject in
+ bytes, including the Type and Length fields. The length MUST always
+ be a multiple of 4, and at least 4.
+
+ An empty RRO with no subobjects is considered illegal.
+ Three kinds of subobjects are currently defined.
+
+ Subobject 1: IPv4 address
+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Length | IPv4 address (4 bytes) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IPv4 address (continued) | Prefix Length | Flags |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Subobject 2: IPv6 address
+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Length | IPv6 address (16 bytes) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IPv6 address (continued) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IPv6 address (continued) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IPv6 address (continued) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IPv6 address (continued) | Prefix Length | Flags |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Subobject 3, Label
+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Length | Flags | C-Type |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Contents of Label Object |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ */
+public class PcepRroObjectVer1 implements PcepRroObject {
+
+ protected static final Logger log = LoggerFactory.getLogger(PcepRroObjectVer1.class);
+
+ public static final byte RRO_OBJ_TYPE = 1;
+ public static final byte RRO_OBJ_CLASS = 8;
+ public static final byte RRO_OBJECT_VERSION = 1;
+ public static final short RRO_OBJ_MINIMUM_LENGTH = 12;
+ public static final int OBJECT_HEADER_LENGTH = 4;
+ public static final int YTYPE_SHIFT_VALUE = 0x7F;
+
+ static final PcepObjectHeader DEFAULT_RRO_OBJECT_HEADER = new PcepObjectHeader(RRO_OBJ_CLASS, RRO_OBJ_TYPE,
+ PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RRO_OBJ_MINIMUM_LENGTH);
+
+ private short rroObjType = 0;
+ private byte length;
+ private byte prefixLength;
+ private byte resvd;
+ PcepObjectHeader rroObjHeader;
+ private LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+ /**
+ * Reset variables.
+ */
+ public PcepRroObjectVer1() {
+ this.rroObjHeader = null;
+ this.rroObjType = 0;
+ this.length = 0;
+ }
+
+ /**
+ * constructor to initialize parameters for RRO object.
+ *
+ * @param rroObjHeader RRO object header
+ * @param llSubObjects list of sub objects
+ */
+ public PcepRroObjectVer1(PcepObjectHeader rroObjHeader, LinkedList<PcepValueType> llSubObjects) {
+ this.rroObjHeader = rroObjHeader;
+ this.llSubObjects = llSubObjects;
+ }
+
+ /**
+ * Returns PCEP RRO Object Header.
+ *
+ * @return rroObjHeader RRO Object header
+ */
+ public PcepObjectHeader getRroObjHeader() {
+ return this.rroObjHeader;
+ }
+
+ /**
+ * Sets PCEP RRO Object Header.
+ *
+ * @param obj Object header
+ */
+ public void setRroObjHeader(PcepObjectHeader obj) {
+ this.rroObjHeader = obj;
+ }
+
+ @Override
+ public LinkedList<PcepValueType> getSubObjects() {
+ return this.llSubObjects;
+ }
+
+ @Override
+ public void setSubObjects(LinkedList<PcepValueType> llSubObjects) {
+ this.llSubObjects = llSubObjects;
+ }
+
+ /**
+ * Reads the channel buffer and returns object of PcepRroObject.
+ *
+ * @param cb of type channel buffer
+ * @return object of PcepRroObject
+ * @throws PcepParseException when fails to read from channel buffer
+ */
+ public static PcepRroObject read(ChannelBuffer cb) throws PcepParseException {
+
+ PcepObjectHeader rroObjHeader;
+ LinkedList<PcepValueType> llSubObjects;
+ rroObjHeader = PcepObjectHeader.read(cb);
+
+ //take only RroObject buffer.
+ ChannelBuffer tempCb = cb.readBytes(rroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+ llSubObjects = parseSubObjects(tempCb);
+
+ return new PcepRroObjectVer1(rroObjHeader, llSubObjects);
+ }
+
+ /**
+ * Returns list of sub objects.
+ *
+ * @param cb of type channel buffer
+ * @return list of sub objects
+ * @throws PcepParseException when fails to parse list of sub objects
+ */
+ protected static LinkedList<PcepValueType> parseSubObjects(ChannelBuffer cb) throws PcepParseException {
+
+ LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+ while (0 < cb.readableBytes()) {
+
+ //check the Type of the Sub objects
+ byte yType = cb.readByte();
+ yType = (byte) (yType & (YTYPE_SHIFT_VALUE));
+ byte hLength = cb.readByte();
+
+ PcepValueType subObj;
+
+ switch (yType) {
+
+ case IPv4SubObject.TYPE:
+ subObj = IPv4SubObject.read(cb);
+ break;
+ case IPv6SubObject.TYPE:
+ byte[] ipv6Value = new byte[IPv6SubObject.VALUE_LENGTH];
+ cb.readBytes(ipv6Value, 0, IPv6SubObject.VALUE_LENGTH);
+ subObj = new IPv6SubObject(ipv6Value);
+ break;
+ case LabelSubObject.TYPE:
+ subObj = LabelSubObject.read(cb);
+ break;
+ default:
+ throw new PcepParseException(" Unexpected sub object. Type: " + (int) yType);
+ }
+ // Check for the padding
+ int pad = hLength % 4;
+ if (0 < pad) {
+ pad = 4 - pad;
+ if (pad <= cb.readableBytes()) {
+ cb.skipBytes(pad);
+ }
+ }
+ llSubObjects.add(subObj);
+ }
+
+ return llSubObjects;
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) throws PcepParseException {
+ //write Object header
+ int objStartIndex = cb.writerIndex();
+
+ int objLenIndex = rroObjHeader.write(cb);
+
+ if (objLenIndex <= 0) {
+ throw new PcepParseException(" object Length Index" + objLenIndex);
+ }
+
+ ListIterator<PcepValueType> listIterator = llSubObjects.listIterator();
+
+ while (listIterator.hasNext()) {
+ listIterator.next().write(cb);
+ }
+
+ //Update object length now
+ int length = cb.writerIndex() - objStartIndex;
+ cb.setShort(objLenIndex, (short) length);
+ //will be helpful during print().
+ rroObjHeader.setObjLen((short) length);
+
+ //As per RFC the length of object should be multiples of 4
+ int pad = length % 4;
+
+ if (0 != pad) {
+ pad = 4 - pad;
+ for (int i = 0; i < pad; i++) {
+ cb.writeByte((byte) 0);
+ }
+ length = length + pad;
+ }
+ objLenIndex = cb.writerIndex();
+ return objLenIndex;
+ }
+
+ /**
+ * Builder class for PCEP RRO object.
+ */
+ public static class Builder implements PcepRroObject.Builder {
+ private boolean bIsHeaderSet = false;
+
+ private PcepObjectHeader rroObjHeader;
+ LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+ private boolean bIsPFlagSet = false;
+ private boolean bPFlag;
+
+ private boolean bIsIFlagSet = false;
+ private boolean bIFlag;
+
+ @Override
+ public PcepRroObject build() {
+
+ PcepObjectHeader rroObjHeader = this.bIsHeaderSet ? this.rroObjHeader : DEFAULT_RRO_OBJECT_HEADER;
+
+ if (bIsPFlagSet) {
+ rroObjHeader.setPFlag(bPFlag);
+ }
+
+ if (bIsIFlagSet) {
+ rroObjHeader.setIFlag(bIFlag);
+ }
+ return new PcepRroObjectVer1(rroObjHeader, this.llSubObjects);
+ }
+
+ @Override
+ public PcepObjectHeader getRroObjHeader() {
+ return this.rroObjHeader;
+ }
+
+ @Override
+ public Builder setRroObjHeader(PcepObjectHeader obj) {
+ this.rroObjHeader = obj;
+ this.bIsHeaderSet = true;
+ return this;
+ }
+
+ @Override
+ public LinkedList<PcepValueType> getSubObjects() {
+ return this.llSubObjects;
+ }
+
+ @Override
+ public Builder setSubObjects(LinkedList<PcepValueType> llSubObjects) {
+ this.llSubObjects = llSubObjects;
+ 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("SubObjects", llSubObjects).toString();
+ }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepStateReportVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepStateReportVer1.java
new file mode 100644
index 0000000..22a7f88
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepStateReportVer1.java
@@ -0,0 +1,426 @@
+/*
+ * 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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepAttribute;
+import org.onosproject.pcepio.protocol.PcepBandwidthObject;
+import org.onosproject.pcepio.protocol.PcepEroObject;
+import org.onosproject.pcepio.protocol.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepRroObject;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.protocol.PcepStateReport;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provide the State Report for the Pcep Report Message.
+ * Reference :PCE extensions for stateful draft-ietf-pce-stateful-pce-10.
+ */
+public class PcepStateReportVer1 implements PcepStateReport {
+ /*
+ * <state-report> ::= [<SRP>]
+ <LSP>
+ <path>
+ Where:
+ <path> ::= <ERO><attribute-list>[<RRO>]
+ */
+
+ protected static final Logger log = LoggerFactory.getLogger(PcepStateReport.class);
+
+ public static final int OBJECT_HEADER_LENGTH = 4;
+
+ /**
+ * Provides PCEP Message path for report message.
+ */
+ public class PcepMsgPath implements PcepStateReport.PcepMsgPath {
+
+ /*
+ * <path> ::= <ERO><attribute-list>[<RRO>]
+ */
+
+ //PcepEroObject
+ private PcepEroObject eroObj;
+ private boolean isEroObjectSet;
+ //PcepAttribute List
+ private PcepAttribute attrList;
+ private boolean isAttributeListSet;
+ //PcepRroObject
+ private PcepRroObject rroObj;
+ private boolean isRroObjectSet;
+ private PcepBandwidthObject bandwidth;
+ private boolean isBandwidthObjectSet;
+
+ /**
+ * Constructor to reset the parameters.
+ */
+ public PcepMsgPath() {
+ eroObj = null;
+ attrList = null;
+ rroObj = null;
+ this.isEroObjectSet = false;
+ this.isAttributeListSet = false;
+ this.isRroObjectSet = false;
+ this.isBandwidthObjectSet = false;
+ }
+
+ /**
+ * Constructor to initialize the parameters from PCEP Message path.
+ *
+ * @param eroObj PCEP ERO Object
+ * @param attrList PCEP Attribute
+ * @param rroObj PCEP Rro Object
+ */
+ public PcepMsgPath(PcepEroObject eroObj, PcepAttribute attrList, PcepRroObject rroObj,
+ PcepBandwidthObject bandwidth) {
+
+ this.eroObj = eroObj;
+ this.attrList = attrList;
+ this.rroObj = rroObj;
+ this.bandwidth = bandwidth;
+ if (null == rroObj) {
+ this.isRroObjectSet = false;
+ } else {
+ this.isRroObjectSet = true;
+ }
+ if (null == eroObj) {
+ this.isEroObjectSet = false;
+ } else {
+ this.isEroObjectSet = true;
+ }
+ if (null == attrList) {
+ this.isAttributeListSet = false;
+ } else {
+ this.isAttributeListSet = true;
+ }
+ if (null == bandwidth) {
+ this.isBandwidthObjectSet = false;
+ } else {
+ this.isBandwidthObjectSet = true;
+ }
+ }
+
+ /**
+ * Returns PcepEroObject.
+ *
+ * @return eroObj PCEP ERO Object
+ */
+ @Override
+ public PcepEroObject getEroObject() {
+ return this.eroObj;
+ }
+
+ /**
+ * Returns PCEP Attribute.
+ *
+ * @return attrList Attribute list
+ */
+ @Override
+ public PcepAttribute getPcepAttribute() {
+ return this.attrList;
+ }
+
+ /**
+ * Returns PcepRroObject.
+ *
+ * @return rroObj PCEP RRO Object
+ */
+ @Override
+ public PcepRroObject getRroObject() {
+ return this.rroObj;
+ }
+
+ @Override
+ public PcepBandwidthObject getBandwidthObject() {
+ return this.bandwidth;
+ }
+
+ @Override
+ public void setEroObject(PcepEroObject eroObj) {
+ this.eroObj = eroObj;
+ }
+
+ @Override
+ public void setPcepAttribute(PcepAttribute attrList) {
+ this.attrList = attrList;
+ }
+
+ @Override
+ public void setRroObject(PcepRroObject rroObj) {
+ this.rroObj = rroObj;
+ }
+
+ @Override
+ public void setBandwidthObject(PcepBandwidthObject bandwidth) {
+ this.bandwidth = bandwidth;
+ }
+
+ /**
+ * Reads all the Objects for PCEP Message Path.
+ *
+ * @param bb of type channel buffer
+ * @return PCEP Message path
+ * @throws PcepParseException when fails to read pcep message path
+ */
+ @Override
+ public PcepMsgPath read(ChannelBuffer bb) throws PcepParseException {
+
+ PcepEroObject eroObj;
+ PcepAttribute attrList;
+ PcepRroObject rroObj = null;
+ PcepBandwidthObject bandwidth = null;
+
+ eroObj = PcepEroObjectVer1.read(bb);
+ attrList = PcepAttributeVer1.read(bb);
+
+ boolean bBreakWhile = false;
+ while (0 < bb.readableBytes()) {
+
+ if (bb.readableBytes() < OBJECT_HEADER_LENGTH) {
+ break;
+ }
+ bb.markReaderIndex();
+ PcepObjectHeader tempObjHeader = PcepObjectHeader.read(bb);
+ bb.resetReaderIndex();
+ byte yObjClass = tempObjHeader.getObjClass();
+
+ switch (yObjClass) {
+ case PcepRroObjectVer1.RRO_OBJ_CLASS:
+ rroObj = PcepRroObjectVer1.read(bb);
+ break;
+ case PcepInterLayerObjectVer1.INTER_LAYER_OBJ_CLASS:
+ bb.skipBytes(tempObjHeader.getObjLen());
+ break;
+ case PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS:
+ bandwidth = PcepBandwidthObjectVer1.read(bb);
+ break;
+ default:
+ //Otherthan above objects handle those objects in caller.
+ bBreakWhile = true;
+ break;
+ }
+ if (bBreakWhile) {
+ break;
+ }
+ }
+ return new PcepMsgPath(eroObj, attrList, rroObj, bandwidth);
+ }
+
+ /**
+ * Writes all the objects for PCEP message path.
+ *
+ * @param bb of type channel buffer.
+ * @return object length index
+ * @throws PcepParseException when fails to write to channel buffer
+ */
+ @Override
+ public int write(ChannelBuffer bb) throws PcepParseException {
+ int iLenStartIndex = bb.writerIndex();
+
+ //write Object header
+ if (this.isEroObjectSet) {
+ this.eroObj.write(bb);
+ } else {
+ throw new PcepParseException("Ero object is not set in path");
+ }
+
+ if (this.isAttributeListSet) {
+ this.attrList.write(bb);
+ }
+
+ // RRO is optional check and read
+ if (this.isRroObjectSet) {
+ this.rroObj.write(bb);
+ // bandwidth should come along with RRO.
+ if (this.isBandwidthObjectSet) {
+ this.bandwidth.write(bb);
+ }
+ }
+ return bb.writerIndex() - iLenStartIndex;
+ }
+
+ @Override
+ public String toString() {
+ ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+ if (attrList instanceof PcepAttribute) {
+ toStrHelper.add("AttributeList", attrList);
+ }
+ if (rroObj instanceof PcepRroObjectVer1) {
+ toStrHelper.add("RroObject", rroObj);
+ }
+ if (bandwidth instanceof PcepBandwidthObjectVer1) {
+ toStrHelper.add("bandwidthObject", bandwidth);
+ }
+ return toStrHelper.toString();
+ }
+ }
+
+ //SRP Object
+ private PcepSrpObject srpObject;
+ //LSP Object
+ private PcepLspObject lspObject;
+ //PcepMsgPath
+ private PcepStateReport.PcepMsgPath msgPath;
+
+ /**
+ * Constructor to reset objects.
+ */
+ public PcepStateReportVer1() {
+ this.srpObject = null;
+ this.lspObject = null;
+ this.msgPath = null;
+ }
+
+ public PcepStateReportVer1(PcepSrpObject srpObject, PcepLspObject lspObject, PcepStateReport.PcepMsgPath msgPath) {
+ this.srpObject = srpObject;
+ this.lspObject = lspObject;
+ this.msgPath = msgPath;
+ }
+
+ @Override
+ public PcepSrpObject getSrpObject() {
+ return srpObject;
+ }
+
+ @Override
+ public PcepLspObject getLspObject() {
+ return lspObject;
+ }
+
+ @Override
+ public PcepStateReport.PcepMsgPath getMsgPath() {
+ return msgPath;
+ }
+
+ @Override
+ public void setSrpObject(PcepSrpObject srpObj) {
+ this.srpObject = srpObj;
+ }
+
+ @Override
+ public void setLspObject(PcepLspObject lspObject) {
+ this.lspObject = lspObject;
+ }
+
+ @Override
+ public void setMsgPath(PcepStateReport.PcepMsgPath msgPath) {
+ this.msgPath = msgPath;
+ }
+
+ /**
+ * Builder class for PCEP state report.
+ */
+ public static class Builder implements PcepStateReport.Builder {
+
+ private boolean bIsSRPObjectSet = false;
+ private boolean bIsLSPObjectSet = false;
+ private boolean bIsPcepMsgPathSet = false;
+
+ //PCEP SRP Object
+ private PcepSrpObject srpObject;
+ //PCEP LSP Object
+ private PcepLspObject lspObject;
+ //PCEP Attribute list
+ private PcepStateReport.PcepMsgPath msgPath;
+
+ @Override
+ public PcepStateReport build() throws PcepParseException {
+
+ //PCEP SRP Object
+ PcepSrpObject srpObject = null;
+ //PCEP LSP Object
+ PcepLspObject lspObject = null;
+ //PCEP Attribute list
+ PcepStateReport.PcepMsgPath msgPath = null;
+
+ if (this.bIsSRPObjectSet) {
+ srpObject = this.srpObject;
+ }
+
+ if (!this.bIsLSPObjectSet) {
+ throw new PcepParseException(" LSP Object NOT Set while building PcepStateReport.");
+ } else {
+ lspObject = this.lspObject;
+ }
+ if (!this.bIsPcepMsgPathSet) {
+ throw new PcepParseException(" Message Path NOT Set while building PcepStateReport.");
+ } else {
+ msgPath = this.msgPath;
+ }
+
+ return new PcepStateReportVer1(srpObject, lspObject, msgPath);
+ }
+
+ @Override
+ public PcepSrpObject getSrpObject() {
+ return this.srpObject;
+ }
+
+ @Override
+ public PcepLspObject getLspObject() {
+ return this.lspObject;
+ }
+
+ @Override
+ public PcepStateReport.PcepMsgPath getMsgPath() {
+ return this.msgPath;
+ }
+
+ @Override
+ public Builder setSrpObject(PcepSrpObject srpobj) {
+ this.srpObject = srpobj;
+ this.bIsSRPObjectSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setLspObject(PcepLspObject lspObject) {
+ this.lspObject = lspObject;
+ this.bIsLSPObjectSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setMsgPath(PcepStateReport.PcepMsgPath msgPath) {
+ this.msgPath = msgPath;
+ this.bIsPcepMsgPathSet = true;
+ return this;
+ }
+ }
+
+ @Override
+ public String toString() {
+ ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+ if (this.srpObject instanceof PcepSrpObject) {
+ toStrHelper.add("SrpObject", srpObject);
+ }
+ if (this.lspObject instanceof PcepLspObject) {
+ toStrHelper.add("LspObject", lspObject);
+ }
+ if (this.msgPath instanceof PcepStateReport.PcepMsgPath) {
+ toStrHelper.add("MsgPath", msgPath);
+ }
+ return toStrHelper.toString();
+ }
+}
\ No newline at end of file
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LabelSubObject.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LabelSubObject.java
new file mode 100644
index 0000000..9815e43
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LabelSubObject.java
@@ -0,0 +1,166 @@
+/*
+ * 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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * LabelSubObject: Provides a LabelSubObject.
+ */
+public class LabelSubObject implements PcepValueType {
+
+ /* Reference : RFC 3209
+ * LABEL Sub Object
+ *
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Length | Flags | C-Type |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Contents of Label Object |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ protected static final Logger log = LoggerFactory.getLogger(LabelSubObject.class);
+
+ public static final short TYPE = 0x03;
+ public static final short LENGTH = 8;
+ private final byte flags;
+ private final byte cType;
+ private final int contents;
+
+ /**
+ * constructor to initialize parameters for LabelSubObject.
+ *
+ * @param flags flags
+ * @param cType C-Type
+ * @param contents Contents of label object
+ */
+ public LabelSubObject(byte flags, byte cType, int contents) {
+ this.flags = flags;
+ this.cType = cType;
+ this.contents = contents;
+ }
+
+ /**
+ * Return an object of LabelSubObject.
+ *
+ * @param flags flags
+ * @param cType C-type
+ * @param contents contents of label objects
+ * @return object of LabelSubObject
+ */
+ public static LabelSubObject of(byte flags, byte cType, int contents) {
+ return new LabelSubObject(flags, cType, contents);
+ }
+
+ /**
+ * Returns Flags.
+ *
+ * @return flags
+ */
+ public byte getFlags() {
+ return flags;
+ }
+
+ /**
+ * Returns cType.
+ *
+ * @return cType
+ */
+ public byte getCtype() {
+ return cType;
+ }
+
+ /**
+ * Returns contents.
+ *
+ * @return contents
+ */
+ public int getContents() {
+ return contents;
+ }
+
+ @Override
+ public PcepVersion getVersion() {
+ return PcepVersion.PCEP_1;
+ }
+
+ @Override
+ public short getType() {
+ return TYPE;
+ }
+
+ @Override
+ public short getLength() {
+ return LENGTH;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(flags, cType, contents);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof LabelSubObject) {
+ LabelSubObject other = (LabelSubObject) obj;
+ return Objects.equals(this.flags, other.flags) && Objects.equals(this.cType, other.cType)
+ && Objects.equals(this.contents, other.contents);
+ }
+ return false;
+ }
+
+ @Override
+ public int write(ChannelBuffer c) {
+ int iStartIndex = c.writerIndex();
+ c.writeShort(TYPE);
+ c.writeShort(LENGTH);
+ c.writeByte(flags);
+ c.writeByte(cType);
+ c.writeByte(contents);
+ return c.writerIndex() - iStartIndex;
+ }
+
+ /**
+ * Reads the channel buffer and returns object of LabelSubObject.
+ *
+ * @param c type of channel buffer
+ * @return object of LabelSubObject
+ */
+ public static PcepValueType read(ChannelBuffer c) {
+ byte flags = c.readByte();
+ byte cType = c.readByte();
+ int contents = c.readInt();
+ return new LabelSubObject(flags, cType, contents);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass()).add("type", TYPE).add("Length", LENGTH).add("flags", flags)
+ .add("C-type", cType).add("contents", contents).toString();
+ }
+}