blob: ca0a317e85f713ffde8bb10f452a9d193d4c6f28 [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
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 */
Ray Milkey9c9cde42018-01-12 14:22:06 -080056 private static final Logger log = LoggerFactory.getLogger(PcepSrpObjectVer1.class);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070057
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:
Avantika-Huaweifb630482016-08-09 11:42:11 +0530254 // Skip the unknown TLV.
255 cb.skipBytes(hLength);
256 tlv = null;
257 log.info("Received unsupported TLV type :" + hType + " in SRP object.");
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700258 }
259
260 // Check for the padding
261 int pad = hLength % 4;
262 if (0 < pad) {
263 pad = 4 - pad;
264 if (pad <= cb.readableBytes()) {
265 cb.skipBytes(pad);
266 }
267 }
Avantika-Huaweifb630482016-08-09 11:42:11 +0530268
269 if (tlv != null) {
270 llOutOptionalTlv.add(tlv);
271 }
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700272 }
273
274 return llOutOptionalTlv;
275 }
276
277 /**
278 * Writes optional tlvs to channel buffer.
279 *
280 * @param cb of type channel buffer
281 * @return true if writing optional tlv to channel buffer is success.
282 */
283 protected boolean packOptionalTlv(ChannelBuffer cb) {
284
285 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
286
287 while (listIterator.hasNext()) {
288 PcepValueType tlv = listIterator.next();
289
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700290 if (tlv == null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700291 log.debug("tlv is null from OptionalTlv list");
292 continue;
293 }
294 tlv.write(cb);
295
296 // need to take care of padding
297 int pad = tlv.getLength() % 4;
298
299 if (0 != pad) {
300 pad = 4 - pad;
301 for (int i = 0; i < pad; ++i) {
302 cb.writeByte((byte) 0);
303 }
304 }
305 }
306
307 return true;
308 }
309
310 /**
311 * Builder class for PCEP srp Object.
312 */
313 public static class Builder implements PcepSrpObject.Builder {
314 private boolean bIsHeaderSet = false;
315 private boolean bIsSrpIdset = false;
316 private boolean bIsRFlagSet = false;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530317 private boolean bIsSFlagSet = false;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700318
319 private PcepObjectHeader srpObjHeader;
320 private int srpId;
321 private boolean bRFlag;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530322 private boolean bSFlag;
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700323 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700324
325 private boolean bIsPFlagSet = false;
326 private boolean bPFlag;
327
328 private boolean bIsIFlagSet = false;
329 private boolean bIFlag;
330
331 @Override
332 public PcepSrpObject build() throws PcepParseException {
333 PcepObjectHeader srpObjHeader = this.bIsHeaderSet ? this.srpObjHeader : DEFAULT_SRP_OBJECT_HEADER;
334
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530335 boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : FLAG_DEFAULT_VALUE;
336 boolean bSFlag = this.bIsSFlagSet ? this.bSFlag : FLAG_DEFAULT_VALUE;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700337
338 if (!this.bIsSrpIdset) {
339 throw new PcepParseException("SrpID not set while building SRP Object.");
340 }
341
342 if (bIsPFlagSet) {
343 srpObjHeader.setPFlag(bPFlag);
344 }
345
346 if (bIsIFlagSet) {
347 srpObjHeader.setIFlag(bIFlag);
348 }
349
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530350 return new PcepSrpObjectVer1(srpObjHeader, bRFlag, bSFlag, this.srpId, this.llOptionalTlv);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700351 }
352
353 @Override
354 public PcepObjectHeader getSrpObjHeader() {
355 return this.srpObjHeader;
356 }
357
358 @Override
359 public Builder setSrpObjHeader(PcepObjectHeader obj) {
360 this.srpObjHeader = obj;
361 this.bIsHeaderSet = true;
362 return this;
363 }
364
365 @Override
366 public int getSrpID() {
367 return this.srpId;
368 }
369
370 @Override
371 public Builder setSrpID(int srpID) {
372 this.srpId = srpID;
373 this.bIsSrpIdset = true;
374 return this;
375 }
376
377 @Override
378 public boolean getRFlag() {
379 return this.bRFlag;
380 }
381
382 @Override
383 public Builder setRFlag(boolean bRFlag) {
384 this.bRFlag = bRFlag;
385 this.bIsRFlagSet = true;
386 return this;
387 }
388
389 @Override
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530390 public boolean getSFlag() {
391 return this.bSFlag;
392 }
393
394 @Override
395 public Builder setSFlag(boolean bSFlag) {
396 this.bSFlag = bSFlag;
397 this.bIsSFlagSet = true;
398 return this;
399 }
400
401 @Override
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700402 public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
403 this.llOptionalTlv = llOptionalTlv;
404 return this;
405 }
406
407 @Override
408 public LinkedList<PcepValueType> getOptionalTlv() {
409 return this.llOptionalTlv;
410 }
411
412 @Override
413 public Builder setPFlag(boolean value) {
414 this.bPFlag = value;
415 this.bIsPFlagSet = true;
416 return this;
417 }
418
419 @Override
420 public Builder setIFlag(boolean value) {
421 this.bIFlag = value;
422 this.bIsIFlagSet = true;
423 return this;
424 }
425
426 }
427
428 @Override
429 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700430 return MoreObjects.toStringHelper(getClass())
431 .add("RFlag", bRFlag)
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530432 .add("SFlag", bSFlag)
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700433 .add("SRPID", srpId)
434 .add("OptionalTlvList", llOptionalTlv)
435 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700436 }
437}