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.PcepSrpObject;
25 import org.onosproject.pcepio.types.PcepObjectHeader;
26 import org.onosproject.pcepio.types.PcepValueType;
27 import org.onosproject.pcepio.types.SymbolicPathNameTlv;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 import com.google.common.base.MoreObjects;
34 * Provides PCEP SRP obejct.
36 public class PcepSrpObjectVer1 implements PcepSrpObject {
39 * ref : draft-ietf-pce-stateful-pce-10, section : 7.2
41 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
42 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 | Object-Class | OT |Res|P|I| Object Length (bytes) |
44 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 protected static final Logger log = LoggerFactory.getLogger(PcepSrpObjectVer1.class);
57 public static final byte SRP_OBJ_TYPE = 1;
58 public static final byte SRP_OBJ_CLASS = 33;
59 public static final byte SRP_OBJECT_VERSION = 1;
60 public static final short SRP_OBJ_MINIMUM_LENGTH = 12;
61 public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
62 public static final boolean DEFAULT_RFLAG = false;
64 static final PcepObjectHeader DEFAULT_SRP_OBJECT_HEADER = new PcepObjectHeader(SRP_OBJ_CLASS, SRP_OBJ_TYPE,
65 PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, SRP_OBJ_MINIMUM_LENGTH);
67 private PcepObjectHeader srpObjHeader;
68 private static int flags;
69 private boolean bRFlag;
73 private LinkedList<PcepValueType> llOptionalTlv;
74 public static final byte BBIT_SET = 1;
75 public static final byte BBIT_RESET = 0;
78 * Constructor to initialize member variables.
80 * @param srpObjHeader srp object header
81 * @param bRFlag R flag
83 * @param llOptionalTlv list of optional tlv
85 public PcepSrpObjectVer1(PcepObjectHeader srpObjHeader, boolean bRFlag, int srpID,
86 LinkedList<PcepValueType> llOptionalTlv) {
88 this.srpObjHeader = srpObjHeader;
91 this.llOptionalTlv = llOptionalTlv;
95 * sets the SRP object header.
97 * @param obj srp object header
99 public void setSrpObjHeader(PcepObjectHeader obj) {
100 this.srpObjHeader = obj;
104 public void setSrpID(int srpID) {
109 public void setRFlag(boolean bRFlag) {
110 this.bRFlag = bRFlag;
114 * Returns SRP object header.
116 * @return srpObjHeader
118 public PcepObjectHeader getSrpObjHeader() {
119 return this.srpObjHeader;
123 public int getSrpID() {
128 public boolean getRFlag() {
133 public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
134 this.llOptionalTlv = llOptionalTlv;
139 public LinkedList<PcepValueType> getOptionalTlv() {
140 return this.llOptionalTlv;
144 * Reads from channel buffer and returns instance of PCEP SRP object.
146 * @param cb of channel buffer.
147 * @return PCEP SRP object
148 * @throws PcepParseException when srp object is not received in channel buffer
150 public static PcepSrpObject read(ChannelBuffer cb) throws PcepParseException {
152 log.debug("SrpObject::read");
153 PcepObjectHeader srpObjHeader;
158 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
160 srpObjHeader = PcepObjectHeader.read(cb);
162 if (srpObjHeader.getObjClass() != SRP_OBJ_CLASS) {
163 throw new PcepParseException("SRP object expected. But received " + srpObjHeader.getObjClass());
166 //take only SrpObject buffer.
167 ChannelBuffer tempCb = cb.readBytes(srpObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
168 flags = tempCb.readInt();
170 srpID = tempCb.readInt();
172 llOptionalTlv = parseOptionalTlv(tempCb);
174 return new PcepSrpObjectVer1(srpObjHeader, bRFlag, srpID, llOptionalTlv);
178 public int write(ChannelBuffer cb) throws PcepParseException {
180 int objStartIndex = cb.writerIndex();
182 //write common header
183 int objLenIndex = srpObjHeader.write(cb);
188 bFlag = (bRFlag) ? BBIT_SET : BBIT_RESET;
196 if (!packOptionalTlv(cb)) {
197 throw new PcepParseException("Failed to write srp tlv to channel buffer.");
200 //now write SRP Object Length
201 cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
203 return cb.writerIndex();
207 * Parse Optional TLvs from the channel buffer.
209 * @param cb of type channel buffer
210 * @return list of optional tlvs
211 * @throws PcepParseException when unsupported tlv is received in srp object
213 public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
215 LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<>();
217 while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {
220 short hType = cb.readShort();
221 short hLength = cb.readShort();
225 case SymbolicPathNameTlv.TYPE:
226 tlv = SymbolicPathNameTlv.read(cb, hLength);
227 cb.skipBytes(hLength);
231 throw new PcepParseException("Unsupported TLV received in SRP Object.");
234 // Check for the padding
235 int pad = hLength % 4;
238 if (pad <= cb.readableBytes()) {
242 llOutOptionalTlv.add(tlv);
245 return llOutOptionalTlv;
249 * Writes optional tlvs to channel buffer.
251 * @param cb of type channel buffer
252 * @return true if writing optional tlv to channel buffer is success.
254 protected boolean packOptionalTlv(ChannelBuffer cb) {
256 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
258 while (listIterator.hasNext()) {
259 PcepValueType tlv = listIterator.next();
262 log.debug("tlv is null from OptionalTlv list");
267 // need to take care of padding
268 int pad = tlv.getLength() % 4;
272 for (int i = 0; i < pad; ++i) {
273 cb.writeByte((byte) 0);
282 * Builder class for PCEP srp Object.
284 public static class Builder implements PcepSrpObject.Builder {
285 private boolean bIsHeaderSet = false;
286 private boolean bIsSrpIdset = false;
287 private boolean bIsRFlagSet = false;
289 private PcepObjectHeader srpObjHeader;
291 private boolean bRFlag;
292 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
294 private boolean bIsPFlagSet = false;
295 private boolean bPFlag;
297 private boolean bIsIFlagSet = false;
298 private boolean bIFlag;
301 public PcepSrpObject build() throws PcepParseException {
302 PcepObjectHeader srpObjHeader = this.bIsHeaderSet ? this.srpObjHeader : DEFAULT_SRP_OBJECT_HEADER;
304 boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_RFLAG;
306 if (!this.bIsSrpIdset) {
307 throw new PcepParseException("SrpID not set while building SRP Object.");
311 srpObjHeader.setPFlag(bPFlag);
315 srpObjHeader.setIFlag(bIFlag);
318 return new PcepSrpObjectVer1(srpObjHeader, bRFlag, this.srpId, this.llOptionalTlv);
322 public PcepObjectHeader getSrpObjHeader() {
323 return this.srpObjHeader;
327 public Builder setSrpObjHeader(PcepObjectHeader obj) {
328 this.srpObjHeader = obj;
329 this.bIsHeaderSet = true;
334 public int getSrpID() {
339 public Builder setSrpID(int srpID) {
341 this.bIsSrpIdset = true;
346 public boolean getRFlag() {
351 public Builder setRFlag(boolean bRFlag) {
352 this.bRFlag = bRFlag;
353 this.bIsRFlagSet = true;
358 public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
359 this.llOptionalTlv = llOptionalTlv;
364 public LinkedList<PcepValueType> getOptionalTlv() {
365 return this.llOptionalTlv;
369 public Builder setPFlag(boolean value) {
371 this.bIsPFlagSet = true;
376 public Builder setIFlag(boolean value) {
378 this.bIsIFlagSet = true;
385 public String toString() {
386 return MoreObjects.toStringHelper(getClass())
387 .add("RFlag", bRFlag)
389 .add("OptionalTlvList", llOptionalTlv)