blob: b88a1a4604b2b1c0a1878c37af60abfa5cfc9c8e [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07003 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package org.onosproject.pcepio.protocol.ver1;
18
19import java.util.LinkedList;
20import java.util.ListIterator;
21
22import org.jboss.netty.buffer.ChannelBuffer;
23import org.onosproject.pcepio.exceptions.PcepParseException;
24import org.onosproject.pcepio.protocol.PcepSrpObject;
Priyanka B21f4b732016-03-21 20:54:12 +053025import org.onosproject.pcepio.types.PathSetupTypeTlv;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070026import org.onosproject.pcepio.types.PcepObjectHeader;
27import org.onosproject.pcepio.types.PcepValueType;
28import org.onosproject.pcepio.types.SymbolicPathNameTlv;
29import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
32import com.google.common.base.MoreObjects;
33
34/**
35 * Provides PCEP SRP obejct.
36 */
37public class PcepSrpObjectVer1 implements PcepSrpObject {
38
39 /*
40 * ref : draft-ietf-pce-stateful-pce-10, section : 7.2
41 0 1 2 3
42 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
43 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 | Object-Class | OT |Res|P|I| Object Length (bytes) |
45 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Avantika-Huawei7c14e662016-05-16 19:13:34 +053046 | Flags |S|R|
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070047 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 | SRP-ID-number |
49 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 | |
51 // Optional TLVs //
52 | |
53 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54
55 */
56 protected static final Logger log = LoggerFactory.getLogger(PcepSrpObjectVer1.class);
57
58 public static final byte SRP_OBJ_TYPE = 1;
59 public static final byte SRP_OBJ_CLASS = 33;
60 public static final byte SRP_OBJECT_VERSION = 1;
61 public static final short SRP_OBJ_MINIMUM_LENGTH = 12;
62 public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
Avantika-Huawei7c14e662016-05-16 19:13:34 +053063 public static final boolean FLAG_DEFAULT_VALUE = false;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070064
65 static final PcepObjectHeader DEFAULT_SRP_OBJECT_HEADER = new PcepObjectHeader(SRP_OBJ_CLASS, SRP_OBJ_TYPE,
66 PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, SRP_OBJ_MINIMUM_LENGTH);
67
68 private PcepObjectHeader srpObjHeader;
69 private static int flags;
70 private boolean bRFlag;
Avantika-Huawei7c14e662016-05-16 19:13:34 +053071 private boolean bSFlag;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070072 private int srpId;
73
74 //Optional TLV
75 private LinkedList<PcepValueType> llOptionalTlv;
76 public static final byte BBIT_SET = 1;
77 public static final byte BBIT_RESET = 0;
78
79 /**
80 * Constructor to initialize member variables.
81 *
82 * @param srpObjHeader srp object header
83 * @param bRFlag R flag
Avantika-Huawei7c14e662016-05-16 19:13:34 +053084 * @param bSFlag S (sync) flag
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070085 * @param srpID srp Id
86 * @param llOptionalTlv list of optional tlv
87 */
Avantika-Huawei7c14e662016-05-16 19:13:34 +053088 public PcepSrpObjectVer1(PcepObjectHeader srpObjHeader, boolean bRFlag, boolean bSFlag, int srpID,
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070089 LinkedList<PcepValueType> llOptionalTlv) {
90
91 this.srpObjHeader = srpObjHeader;
92 this.bRFlag = bRFlag;
Avantika-Huawei7c14e662016-05-16 19:13:34 +053093 this.bSFlag = bSFlag;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070094 this.srpId = srpID;
95 this.llOptionalTlv = llOptionalTlv;
96 }
97
98 /**
99 * sets the SRP object header.
100 *
101 * @param obj srp object header
102 */
103 public void setSrpObjHeader(PcepObjectHeader obj) {
104 this.srpObjHeader = obj;
105 }
106
107 @Override
108 public void setSrpID(int srpID) {
109 this.srpId = srpID;
110 }
111
112 @Override
113 public void setRFlag(boolean bRFlag) {
114 this.bRFlag = bRFlag;
115 }
116
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530117 @Override
118 public void setSFlag(boolean bSFlag) {
119 this.bSFlag = bSFlag;
120 }
121
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700122 /**
123 * Returns SRP object header.
124 *
125 * @return srpObjHeader
126 */
127 public PcepObjectHeader getSrpObjHeader() {
128 return this.srpObjHeader;
129 }
130
131 @Override
132 public int getSrpID() {
133 return this.srpId;
134 }
135
136 @Override
137 public boolean getRFlag() {
138 return this.bRFlag;
139 }
140
141 @Override
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530142 public boolean getSFlag() {
143 return this.bSFlag;
144 }
145
146 @Override
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700147 public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
148 this.llOptionalTlv = llOptionalTlv;
149
150 }
151
152 @Override
153 public LinkedList<PcepValueType> getOptionalTlv() {
154 return this.llOptionalTlv;
155 }
156
157 /**
158 * Reads from channel buffer and returns instance of PCEP SRP object.
159 *
160 * @param cb of channel buffer.
161 * @return PCEP SRP object
162 * @throws PcepParseException when srp object is not received in channel buffer
163 */
164 public static PcepSrpObject read(ChannelBuffer cb) throws PcepParseException {
165
166 log.debug("SrpObject::read");
167 PcepObjectHeader srpObjHeader;
168 boolean bRFlag;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530169 boolean bSFlag;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700170
171 int srpID;
172 int flags;
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700173 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700174
175 srpObjHeader = PcepObjectHeader.read(cb);
176
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700177 if (srpObjHeader.getObjClass() != SRP_OBJ_CLASS) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700178 throw new PcepParseException("SRP object expected. But received " + srpObjHeader.getObjClass());
179 }
180
181 //take only SrpObject buffer.
182 ChannelBuffer tempCb = cb.readBytes(srpObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
183 flags = tempCb.readInt();
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530184 bRFlag = 0 < (flags & 0x1);
185 bSFlag = 0 < ((flags >> 1) & 0x1);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700186 srpID = tempCb.readInt();
187
188 llOptionalTlv = parseOptionalTlv(tempCb);
189
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530190 return new PcepSrpObjectVer1(srpObjHeader, bRFlag, bSFlag, srpID, llOptionalTlv);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700191 }
192
193 @Override
194 public int write(ChannelBuffer cb) throws PcepParseException {
195
196 int objStartIndex = cb.writerIndex();
197
198 //write common header
199 int objLenIndex = srpObjHeader.write(cb);
200
201 //write Flags
202 byte bFlag;
203
204 bFlag = (bRFlag) ? BBIT_SET : BBIT_RESET;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530205 bFlag |= (((bSFlag) ? BBIT_SET : BBIT_RESET) << 1);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700206
207 cb.writeInt(bFlag);
208
209 //write SrpId
210 cb.writeInt(srpId);
211
212 // Add optional TLV
213 if (!packOptionalTlv(cb)) {
214 throw new PcepParseException("Failed to write srp tlv to channel buffer.");
215 }
216
217 //now write SRP Object Length
218 cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
219
220 return cb.writerIndex();
221 }
222
223 /**
224 * Parse Optional TLvs from the channel buffer.
225 *
226 * @param cb of type channel buffer
227 * @return list of optional tlvs
228 * @throws PcepParseException when unsupported tlv is received in srp object
229 */
230 public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
231
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700232 LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700233
234 while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {
235
236 PcepValueType tlv;
237 short hType = cb.readShort();
238 short hLength = cb.readShort();
239
240 switch (hType) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700241 case SymbolicPathNameTlv.TYPE:
Priyanka B21f4b732016-03-21 20:54:12 +0530242 if (cb.readableBytes() < hLength) {
243 throw new PcepParseException("Length is not valid in SymbolicPathNameTlv");
244 }
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700245 tlv = SymbolicPathNameTlv.read(cb, hLength);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700246 break;
Priyanka B21f4b732016-03-21 20:54:12 +0530247 case PathSetupTypeTlv.TYPE:
248 if (cb.readableBytes() != PathSetupTypeTlv.LENGTH) {
249 throw new PcepParseException("Length is not valid in PathSetupTypeTlv");
250 }
251 tlv = PathSetupTypeTlv.of(cb.readInt());
252 break;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700253 default:
254 throw new PcepParseException("Unsupported TLV received in SRP Object.");
255 }
256
257 // Check for the padding
258 int pad = hLength % 4;
259 if (0 < pad) {
260 pad = 4 - pad;
261 if (pad <= cb.readableBytes()) {
262 cb.skipBytes(pad);
263 }
264 }
265 llOutOptionalTlv.add(tlv);
266 }
267
268 return llOutOptionalTlv;
269 }
270
271 /**
272 * Writes optional tlvs to channel buffer.
273 *
274 * @param cb of type channel buffer
275 * @return true if writing optional tlv to channel buffer is success.
276 */
277 protected boolean packOptionalTlv(ChannelBuffer cb) {
278
279 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
280
281 while (listIterator.hasNext()) {
282 PcepValueType tlv = listIterator.next();
283
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700284 if (tlv == null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700285 log.debug("tlv is null from OptionalTlv list");
286 continue;
287 }
288 tlv.write(cb);
289
290 // need to take care of padding
291 int pad = tlv.getLength() % 4;
292
293 if (0 != pad) {
294 pad = 4 - pad;
295 for (int i = 0; i < pad; ++i) {
296 cb.writeByte((byte) 0);
297 }
298 }
299 }
300
301 return true;
302 }
303
304 /**
305 * Builder class for PCEP srp Object.
306 */
307 public static class Builder implements PcepSrpObject.Builder {
308 private boolean bIsHeaderSet = false;
309 private boolean bIsSrpIdset = false;
310 private boolean bIsRFlagSet = false;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530311 private boolean bIsSFlagSet = false;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700312
313 private PcepObjectHeader srpObjHeader;
314 private int srpId;
315 private boolean bRFlag;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530316 private boolean bSFlag;
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700317 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700318
319 private boolean bIsPFlagSet = false;
320 private boolean bPFlag;
321
322 private boolean bIsIFlagSet = false;
323 private boolean bIFlag;
324
325 @Override
326 public PcepSrpObject build() throws PcepParseException {
327 PcepObjectHeader srpObjHeader = this.bIsHeaderSet ? this.srpObjHeader : DEFAULT_SRP_OBJECT_HEADER;
328
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530329 boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : FLAG_DEFAULT_VALUE;
330 boolean bSFlag = this.bIsSFlagSet ? this.bSFlag : FLAG_DEFAULT_VALUE;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700331
332 if (!this.bIsSrpIdset) {
333 throw new PcepParseException("SrpID not set while building SRP Object.");
334 }
335
336 if (bIsPFlagSet) {
337 srpObjHeader.setPFlag(bPFlag);
338 }
339
340 if (bIsIFlagSet) {
341 srpObjHeader.setIFlag(bIFlag);
342 }
343
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530344 return new PcepSrpObjectVer1(srpObjHeader, bRFlag, bSFlag, this.srpId, this.llOptionalTlv);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700345 }
346
347 @Override
348 public PcepObjectHeader getSrpObjHeader() {
349 return this.srpObjHeader;
350 }
351
352 @Override
353 public Builder setSrpObjHeader(PcepObjectHeader obj) {
354 this.srpObjHeader = obj;
355 this.bIsHeaderSet = true;
356 return this;
357 }
358
359 @Override
360 public int getSrpID() {
361 return this.srpId;
362 }
363
364 @Override
365 public Builder setSrpID(int srpID) {
366 this.srpId = srpID;
367 this.bIsSrpIdset = true;
368 return this;
369 }
370
371 @Override
372 public boolean getRFlag() {
373 return this.bRFlag;
374 }
375
376 @Override
377 public Builder setRFlag(boolean bRFlag) {
378 this.bRFlag = bRFlag;
379 this.bIsRFlagSet = true;
380 return this;
381 }
382
383 @Override
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530384 public boolean getSFlag() {
385 return this.bSFlag;
386 }
387
388 @Override
389 public Builder setSFlag(boolean bSFlag) {
390 this.bSFlag = bSFlag;
391 this.bIsSFlagSet = true;
392 return this;
393 }
394
395 @Override
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700396 public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
397 this.llOptionalTlv = llOptionalTlv;
398 return this;
399 }
400
401 @Override
402 public LinkedList<PcepValueType> getOptionalTlv() {
403 return this.llOptionalTlv;
404 }
405
406 @Override
407 public Builder setPFlag(boolean value) {
408 this.bPFlag = value;
409 this.bIsPFlagSet = true;
410 return this;
411 }
412
413 @Override
414 public Builder setIFlag(boolean value) {
415 this.bIFlag = value;
416 this.bIsIFlagSet = true;
417 return this;
418 }
419
420 }
421
422 @Override
423 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700424 return MoreObjects.toStringHelper(getClass())
425 .add("RFlag", bRFlag)
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530426 .add("SFlag", bSFlag)
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700427 .add("SRPID", srpId)
428 .add("OptionalTlvList", llOptionalTlv)
429 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700430 }
431}