[ONOS-2359]Implementation of PCEP LabelReserve message

Change-Id: Ie74340f5fe5e93d9bb277dd3551ba175ac74494c
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java
new file mode 100644
index 0000000..fce29a1
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java
@@ -0,0 +1,370 @@
+/*

+ * 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.PcepLabelRangeObject;

+import org.onosproject.pcepio.types.PathSetupTypeTlv;

+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;

+

+public class PcepLabelRangeObjectVer1 implements PcepLabelRangeObject {

+

+    /*

+     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01, section : 7.2

+            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

+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+           | label type    | range size                                    |

+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+           |                        label base                             |

+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+           |                                                               |

+           //                      Optional TLVs                           //

+           |                                                               |

+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+                               LABEL-RANGE Object

+     */

+    protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeObjectVer1.class);

+

+    public static final byte LABEL_RANGE_OBJ_TYPE = 1;

+    public static final byte LABEL_RANGE_OBJ_CLASS = 60; //to be defined

+    public static final byte LABEL_RANGE_OBJECT_VERSION = 1;

+    public static final short LABEL_RANGE_OBJ_MINIMUM_LENGTH = 12;

+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;

+    //P flag and I flag must be set to 0

+    static final PcepObjectHeader DEFAULT_LABELRANGE_OBJECT_HEADER = new PcepObjectHeader(LABEL_RANGE_OBJ_CLASS,

+            LABEL_RANGE_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,

+            LABEL_RANGE_OBJ_MINIMUM_LENGTH);

+

+    private PcepObjectHeader labelRangeObjHeader;

+    private byte labelType;

+    private int rangeSize;

+    private int labelBase;

+    //Optional TLV

+    private LinkedList<PcepValueType> llOptionalTlv;

+

+    /**

+     * Constructor to initialize parameters for PCEP label range object.

+     *

+     * @param labelRangeObjHeader label range object header

+     * @param labelType label type

+     * @param rangeSize range size

+     * @param labelBase label base

+     * @param llOptionalTlv list of optional tlvs

+     */

+    public PcepLabelRangeObjectVer1(PcepObjectHeader labelRangeObjHeader, byte labelType, int rangeSize, int labelBase,

+            LinkedList<PcepValueType> llOptionalTlv) {

+        this.labelRangeObjHeader = labelRangeObjHeader;

+        this.labelType = labelType;

+        this.rangeSize = rangeSize;

+        this.llOptionalTlv = llOptionalTlv;

+        this.labelBase = labelBase;

+    }

+

+    @Override

+    public void setLabelRangeObjHeader(PcepObjectHeader obj) {

+        this.labelRangeObjHeader = obj;

+    }

+

+    @Override

+    public void setLabelType(byte labelType) {

+        this.labelType = labelType;

+    }

+

+    @Override

+    public void setRangeSize(int rangeSize) {

+        this.rangeSize = rangeSize;

+    }

+

+    @Override

+    public void setLabelBase(int labelBase) {

+        this.labelBase = labelBase;

+    }

+

+    @Override

+    public PcepObjectHeader getLabelRangeObjHeader() {

+        return this.labelRangeObjHeader;

+    }

+

+    @Override

+    public byte getLabelType() {

+        return this.labelType;

+    }

+

+    @Override

+    public int getRangeSize() {

+        return this.rangeSize;

+    }

+

+    @Override

+    public int getLabelBase() {

+        return this.labelBase;

+    }

+

+    /**

+     * Reads from the channel buffer and returns object of  PcepLabelRangeObject.

+     *

+     * @param cb of type channel buffer

+     * @return object of  PcepLabelRangeObject

+     * @throws PcepParseException when fails to read from channel buffer

+     */

+    public static PcepLabelRangeObject read(ChannelBuffer cb) throws PcepParseException {

+

+        PcepObjectHeader labelRangeObjHeader;

+        byte labelType;

+        int rangeSize;

+        int labelBase;

+

+        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();

+

+        labelRangeObjHeader = PcepObjectHeader.read(cb);

+

+        //take only LabelRangeObject buffer.

+        ChannelBuffer tempCb = cb.readBytes(labelRangeObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);

+        int temp = 0;

+        temp = tempCb.readInt();

+        rangeSize = temp & 0x00FFFFFF;

+        labelType = (byte) (temp >> 24);

+        labelBase = tempCb.readInt();

+        llOptionalTlv = parseOptionalTlv(tempCb);

+        return new PcepLabelRangeObjectVer1(labelRangeObjHeader, labelType, rangeSize, labelBase, llOptionalTlv);

+    }

+

+    @Override

+    public int write(ChannelBuffer cb) throws PcepParseException {

+

+        int objStartIndex = cb.writerIndex();

+

+        //write common header

+        int objLenIndex = labelRangeObjHeader.write(cb);

+        int temp = 0;

+        temp = labelType;

+        temp = temp << 24;

+        temp = temp | rangeSize;

+        cb.writeInt(temp);

+

+        // Add optional TLV

+        if (!packOptionalTlv(cb)) {

+            throw new PcepParseException("Error while writing Optional tlv.");

+        }

+

+        //now write LabelRange Object Length

+        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));

+        return cb.writerIndex() - objStartIndex;

+    }

+

+    /**

+     * Returns list of optional tlvs.

+     *

+     * @param cb of type channle buffer

+     * @return list of optional tlvs

+     * @throws PcepParseException whne fails to parse list of optional tlvs

+     */

+    public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {

+

+        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();

+

+        while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {

+

+            PcepValueType tlv;

+            int iValue;

+            short hType = cb.readShort();

+            short hLength = cb.readShort();

+

+            switch (hType) {

+

+            case PathSetupTypeTlv.TYPE:

+                iValue = cb.readInt();

+                tlv = new PathSetupTypeTlv(iValue);

+                break;

+

+            default:

+                throw new PcepParseException("Unsupported TLV in LabelRange Object.");

+            }

+

+            // Check for the padding

+            int pad = hLength % 4;

+            if (0 < pad) {

+                pad = 4 - pad;

+                if (pad <= cb.readableBytes()) {

+                    cb.skipBytes(pad);

+                }

+            }

+            llOutOptionalTlv.add(tlv);

+        }

+        return llOutOptionalTlv;

+    }

+

+    /**

+     * Pack optional tlvs.

+     *

+     * @param cb of channel buffer

+     * @return true

+     */

+    protected boolean packOptionalTlv(ChannelBuffer cb) {

+

+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();

+

+        while (listIterator.hasNext()) {

+            PcepValueType tlv = listIterator.next();

+

+            if (null == tlv) {

+                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 true;

+    }

+

+    /**

+     * Builder class for PCEP label range object.

+     */

+    public static class Builder implements PcepLabelRangeObject.Builder {

+        private boolean bIsHeaderSet = false;

+        private boolean bIsLabelType = false;

+        private boolean bIsRangeSize = false;

+        private boolean bIsLabelBase = false;

+

+        byte labelType;

+        int rangeSize;

+        int labelBase;

+        private boolean bIsPFlagSet = false;

+        private boolean bPFlag;

+

+        private boolean bIsIFlagSet = false;

+        private boolean bIFlag;

+        private PcepObjectHeader labelRangeObjHeader;

+

+        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();

+

+        @Override

+        public PcepLabelRangeObject build() throws PcepParseException {

+            PcepObjectHeader labelRangeObjHeader = this.bIsHeaderSet ? this.labelRangeObjHeader

+                    : DEFAULT_LABELRANGE_OBJECT_HEADER;

+

+            if (!this.bIsLabelType) {

+                throw new PcepParseException("LabelType NOT Set while building label range object.");

+            }

+

+            if (!this.bIsRangeSize) {

+                throw new PcepParseException("RangeSize NOT Set while building label range object.");

+            }

+

+            if (!this.bIsLabelBase) {

+                throw new PcepParseException("LabelBase NOT Set while building label range object.");

+            }

+

+            if (bIsPFlagSet) {

+                labelRangeObjHeader.setPFlag(bPFlag);

+            }

+

+            if (bIsIFlagSet) {

+                labelRangeObjHeader.setIFlag(bIFlag);

+            }

+            return new PcepLabelRangeObjectVer1(labelRangeObjHeader, this.labelType, this.rangeSize, this.labelBase,

+                    this.llOptionalTlv);

+        }

+

+        @Override

+        public PcepObjectHeader getLabelRangeObjHeader() {

+            return this.labelRangeObjHeader;

+        }

+

+        @Override

+        public Builder setLabelRangeObjHeader(PcepObjectHeader obj) {

+            this.labelRangeObjHeader = obj;

+            this.bIsHeaderSet = true;

+            return this;

+        }

+

+        @Override

+        public byte getLabelType() {

+            return this.labelType;

+        }

+

+        @Override

+        public Builder setLabelType(byte labelType) {

+            this.labelType = labelType;

+            this.bIsLabelType = true;

+            return this;

+        }

+

+        @Override

+        public int getRangeSize() {

+            return this.rangeSize;

+        }

+

+        @Override

+        public Builder setRangeSize(int rangeSize) {

+            this.rangeSize = rangeSize;

+            this.bIsRangeSize = true;

+            return this;

+        }

+

+        @Override

+        public int getLabelBase() {

+            return this.labelBase;

+        }

+

+        @Override

+        public Builder setLabelBase(int labelBase) {

+            this.labelBase = labelBase;

+            this.bIsLabelBase = true;

+            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("LabelType", labelType).add("rangeSize", rangeSize)

+                .add("labelBase", labelBase).add("optionalTlvList", llOptionalTlv).toString();

+    }

+}

diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeResvMsgVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeResvMsgVer1.java
new file mode 100644
index 0000000..2b6b9c8
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeResvMsgVer1.java
@@ -0,0 +1,189 @@
+/*
+ * 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.PcepLabelRange;
+import org.onosproject.pcepio.protocol.PcepLabelRangeResvMsg;
+import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.protocol.PcepMessageWriter;
+import org.onosproject.pcepio.protocol.PcepType;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+class PcepLabelRangeResvMsgVer1 implements PcepLabelRangeResvMsg {
+
+    // Pcep version: 1
+
+    /*
+       The format of a PCLRResv message is as follows:
+
+               PCLRResv Message>::= <Common Header>
+                                    <label-range>
+          Where:
+
+               <label-range> ::= <SRP>
+                                 <labelrange-list>
+
+          Where
+               <labelrange-list>::=<LABEL-RANGE>[<labelrange-list>]
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeResvMsgVer1.class);
+
+    public static final byte PACKET_VERSION = 1;
+    // LabelRangeResvMsgMinLength = COMMON-HEADER(4)+SrpObjMinLentgh(12)+LABEL-RANGE-MIN-LENGTH(12)
+    public static final int PACKET_MINIMUM_LENGTH = 28;
+    public static final PcepType MSG_TYPE = PcepType.LABEL_RANGE_RESERV;
+    //<label-range>
+    PcepLabelRange labelRange;
+
+    public static final PcepLabelRangeResvMsgVer1.Reader READER = new Reader();
+
+    //Reader reads LabelRangeResv Message from the channel.
+    static class Reader implements PcepMessageReader<PcepLabelRangeResvMsg> {
+
+        @Override
+        public PcepLabelRangeResvMsg readFrom(ChannelBuffer cb) throws PcepParseException {
+
+            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException("Channel buffer has less readable bytes than Packet minimum length.");
+            }
+            // fixed value property version == 1
+            byte version = cb.readByte();
+            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
+            if (version != PACKET_VERSION) {
+                throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), got=" + version);
+            }
+            // fixed value property type == 15
+            byte type = cb.readByte();
+            if (type != MSG_TYPE.getType()) {
+                throw new PcepParseException("Wrong type. Expected=PcepType.LABEL_RANGE_RESERV(15), got=" + type);
+            }
+            short length = cb.readShort();
+            if (length < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException("Wrong length.Expected to be >= " + PACKET_MINIMUM_LENGTH + ", is: "
+                        + length);
+            }
+            // parse <label-range>
+            PcepLabelRange labelRange = PcepLabelRangeVer1.read(cb);
+            return new PcepLabelRangeResvMsgVer1(labelRange);
+        }
+    }
+
+    /**
+     * Constructor to initialize PCEP label range.
+     *
+     * @param labelRange PCEP label range
+     */
+    PcepLabelRangeResvMsgVer1(PcepLabelRange labelRange) {
+        this.labelRange = labelRange;
+    }
+
+    /**
+     * Builder class for PCEP label range reserve message.
+     */
+    static class Builder implements PcepLabelRangeResvMsg.Builder {
+
+        PcepLabelRange labelRange = new PcepLabelRangeVer1();
+
+        @Override
+        public PcepVersion getVersion() {
+            return PcepVersion.PCEP_1;
+        }
+
+        @Override
+        public PcepType getType() {
+            return PcepType.LABEL_RANGE_RESERV;
+        }
+
+        @Override
+        public PcepLabelRangeResvMsg build() {
+            return new PcepLabelRangeResvMsgVer1(this.labelRange);
+        }
+
+        @Override
+        public PcepLabelRange getLabelRange() {
+            return this.labelRange;
+        }
+
+        @Override
+        public Builder setLabelRange(PcepLabelRange labelRange) {
+            this.labelRange = labelRange;
+            return this;
+        }
+    }
+
+    @Override
+    public void writeTo(ChannelBuffer cb) throws PcepParseException {
+        WRITER.write(cb, this);
+    }
+
+    static final Writer WRITER = new Writer();
+
+    //Writer writes LabelRangeResv Message to the channel.
+    static class Writer implements PcepMessageWriter<PcepLabelRangeResvMsgVer1> {
+
+        @Override
+        public void write(ChannelBuffer cb, PcepLabelRangeResvMsgVer1 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 will be set after calculating length, but currently set it as 0.
+            int msgLenIndex = cb.writerIndex();
+
+            cb.writeShort((short) 0);
+            //write Label Range
+            message.labelRange.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 PcepLabelRange getLabelRange() {
+        return this.labelRange;
+    }
+
+    @Override
+    public void setLabelRange(PcepLabelRange lr) {
+        this.labelRange = lr;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("labelRange", labelRange).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java
new file mode 100644
index 0000000..f2498ae
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.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.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.PcepLabelRange;

+import org.onosproject.pcepio.protocol.PcepLabelRangeObject;

+import org.onosproject.pcepio.protocol.PcepSrpObject;

+import org.slf4j.Logger;

+import org.slf4j.LoggerFactory;

+

+import com.google.common.base.MoreObjects;

+

+/**

+ * Provides PCEP Label Range.

+ */

+public class PcepLabelRangeVer1 implements PcepLabelRange {

+

+    protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeVer1.class);

+

+    /*

+        <label-range> ::= <SRP>

+                          <labelrange-list>

+        Where

+                <labelrange-list>::=<LABEL-RANGE>[<labelrange-list>]

+     */

+

+    // PCEP SRP Object

+    private PcepSrpObject srpObject;

+    //<labelrange-list> of type PcepLabelRangeObject.

+    private LinkedList<PcepLabelRangeObject> llLabelRangeList;

+

+    /**

+     * Default Constructor.

+     */

+    public PcepLabelRangeVer1() {

+        srpObject = null;

+        llLabelRangeList = null;

+    }

+

+    /**

+     * Constructor to initialize objects.

+     *

+     * @param srpObj PCEP Srp object.

+     * @param llLabelRangeList list of PcepLabelRangeObject.

+     */

+    PcepLabelRangeVer1(PcepSrpObject srpObj, LinkedList<PcepLabelRangeObject> llLabelRangeList) {

+        this.srpObject = srpObj;

+        this.llLabelRangeList = llLabelRangeList;

+    }

+

+    @Override

+    public PcepSrpObject getSrpObject() {

+        return srpObject;

+    }

+

+    @Override

+    public void setSrpObject(PcepSrpObject srpObject) {

+        this.srpObject = srpObject;

+

+    }

+

+    @Override

+    public LinkedList<PcepLabelRangeObject> getLabelRangeList() {

+        return llLabelRangeList;

+    }

+

+    @Override

+    public void setLabelRangeList(LinkedList<PcepLabelRangeObject> ll) {

+        this.llLabelRangeList = ll;

+    }

+

+    /**

+     * Reads channel buffer and returns object of PcepLabelRange.

+     *

+     * @param cb of type channel buffer.

+     * @return object of PcepLabelRange

+     * @throws PcepParseException when fails to read from channel buffer

+     */

+    public static PcepLabelRange read(ChannelBuffer cb) throws PcepParseException {

+

+        //parse and store SRP mandatory object

+        PcepSrpObject srpObj = null;

+        srpObj = PcepSrpObjectVer1.read(cb);

+        if (srpObj == null) {

+            throw new PcepParseException("Exception while parsing srp object");

+        }

+

+        LinkedList<PcepLabelRangeObject> llLabelRangeList = new LinkedList<PcepLabelRangeObject>();

+        boolean bFoundLabelRangeObj = false;

+        while (0 < cb.readableBytes()) {

+            //parse and store <labelrange-list>

+            PcepLabelRangeObject lrObj;

+            lrObj = PcepLabelRangeObjectVer1.read(cb);

+            if (lrObj == null) {

+                throw new PcepParseException("Exception while parsing label range object");

+            } else {

+                llLabelRangeList.add(lrObj);

+                bFoundLabelRangeObj = true;

+            }

+        }

+

+        if (!bFoundLabelRangeObj) {

+            throw new PcepParseException("At least one LABEL-RANGE MUST be present.");

+        }

+        return new PcepLabelRangeVer1(srpObj, llLabelRangeList);

+    }

+

+    @Override

+    public int write(ChannelBuffer cb) throws PcepParseException {

+        //write Object header

+        int objStartIndex = cb.writerIndex();

+

+        //write <SRP>

+        int objLenIndex = srpObject.write(cb);

+

+        if (objLenIndex <= 0) {

+            throw new PcepParseException("bjectLength is " + objLenIndex);

+        }

+

+        //write <labelrange-list>

+        ListIterator<PcepLabelRangeObject> listIterator = llLabelRangeList.listIterator();

+        while (listIterator.hasNext()) {

+            listIterator.next().write(cb);

+        }

+

+        //Update object length now

+        int length = cb.writerIndex() - objStartIndex;

+        // As per RFC the length of object should be

+        // multiples of 4

+        int pad = length % 4;

+        if (pad != 0) {

+            pad = 4 - pad;

+            for (int i = 0; i < pad; i++) {

+                cb.writeByte((byte) 0);

+            }

+            length = length + pad;

+        }

+        cb.setShort(objLenIndex, (short) length);

+        return length;

+    }

+

+    @Override

+    public String toString() {

+        return MoreObjects.toStringHelper(getClass()).add("srpObject", srpObject)

+                .add("LabelRangeList", llLabelRangeList).toString();

+    }

+}

diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathSetupTypeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathSetupTypeTlv.java
new file mode 100644
index 0000000..19e2b5b
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathSetupTypeTlv.java
@@ -0,0 +1,146 @@
+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;

+

+/**

+ * Provides PcepSetup type tlv.

+ */

+public class PathSetupTypeTlv implements PcepValueType {

+

+    /*

+       Reference : draft-sivabalan-pce-lsp-setup-type-02.

+

+         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                        |

+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+         | Reserved                                      | PST           |

+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

+

+                     Figure 1: PATH-SETUP-TYPE TLV

+

+     */

+    protected static final Logger log = LoggerFactory.getLogger(PathSetupTypeTlv.class);

+

+    public static final short TYPE = 0; //TODO : need to reassign the value as per RFC

+    public static final short LENGTH = 4;

+

+    private final byte pst;

+    private final int rawValue;

+    private final boolean isRawValueSet;

+

+    /**

+     * Constructor to initialize parameters for path setup type tlv.

+     *

+     * @param rawValue parameter for path setup type tlv

+     */

+    public PathSetupTypeTlv(final int rawValue) {

+        this.rawValue = rawValue;

+        this.isRawValueSet = true;

+        this.pst = (byte) rawValue;

+    }

+

+    /**

+     * Constructor to initialize pst.

+     *

+     * @param pst PST

+     */

+    public PathSetupTypeTlv(byte pst) {

+        this.pst = pst;

+        this.rawValue = 0;

+        this.isRawValueSet = false;

+    }

+

+    /**

+     * Returns Object of path setup type tlv.

+     *

+     * @param raw parameter for path setup type tlv

+     * @return object of PathSetupTypeTlv

+     */

+    public static PathSetupTypeTlv of(final int raw) {

+        return new PathSetupTypeTlv(raw);

+    }

+

+    @Override

+    public PcepVersion getVersion() {

+        return PcepVersion.PCEP_1;

+    }

+

+    /**

+     * Returns parameters for path setup type tlv.

+     *

+     * @return parameters for path setup type tlv

+     */

+    public int getInt() {

+        return rawValue;

+    }

+

+    /**

+     * Returns the pst value.

+     *

+     * @return pst value

+     */

+    public byte getPst() {

+        return pst;

+    }

+

+    @Override

+    public short getType() {

+        return TYPE;

+    }

+

+    @Override

+    public short getLength() {

+        return LENGTH;

+    }

+

+    @Override

+    public int hashCode() {

+        return Objects.hash(pst);

+    }

+

+    @Override

+    public boolean equals(Object obj) {

+        if (this == obj) {

+            return true;

+        }

+        if (obj instanceof PathSetupTypeTlv) {

+            PathSetupTypeTlv other = (PathSetupTypeTlv) obj;

+            return Objects.equals(this.pst, other.pst);

+        }

+        return false;

+    }

+

+    @Override

+    public int write(ChannelBuffer c) {

+        int iLenStartIndex = c.writerIndex();

+        c.writeShort(TYPE);

+        c.writeShort(LENGTH);

+        c.writeInt(pst);

+        return c.writerIndex() - iLenStartIndex;

+    }

+

+    /**

+     * Returns the object of type PathSetupTypeTlv.

+     *

+     * @param c is type Channel buffer

+     * @return object of PathSetupTypeTlv

+     */

+    public static PathSetupTypeTlv read(ChannelBuffer c) {

+        return PathSetupTypeTlv.of(c.readInt());

+    }

+

+    @Override

+    public String toString() {

+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("PST", pst)

+                .toString();

+    }

+}