blob: 9c75b3a6e2dd0b9bdb479c83c9f00cc1054e2dbb [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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;
25import org.onosproject.pcepio.types.PcepObjectHeader;
26import org.onosproject.pcepio.types.PcepValueType;
27import org.onosproject.pcepio.types.SymbolicPathNameTlv;
28import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
31import com.google.common.base.MoreObjects;
32
33/**
34 * Provides PCEP SRP obejct.
35 */
36public class PcepSrpObjectVer1 implements PcepSrpObject {
37
38 /*
39 * ref : draft-ietf-pce-stateful-pce-10, section : 7.2
40 0 1 2 3
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 | Flags |R|
46 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 | SRP-ID-number |
48 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 | |
50 // Optional TLVs //
51 | |
52 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53
54 */
55 protected static final Logger log = LoggerFactory.getLogger(PcepSrpObjectVer1.class);
56
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;
63
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);
66
67 private PcepObjectHeader srpObjHeader;
68 private static int flags;
69 private boolean bRFlag;
70 private int srpId;
71
72 //Optional TLV
73 private LinkedList<PcepValueType> llOptionalTlv;
74 public static final byte BBIT_SET = 1;
75 public static final byte BBIT_RESET = 0;
76
77 /**
78 * Constructor to initialize member variables.
79 *
80 * @param srpObjHeader srp object header
81 * @param bRFlag R flag
82 * @param srpID srp Id
83 * @param llOptionalTlv list of optional tlv
84 */
85 public PcepSrpObjectVer1(PcepObjectHeader srpObjHeader, boolean bRFlag, int srpID,
86 LinkedList<PcepValueType> llOptionalTlv) {
87
88 this.srpObjHeader = srpObjHeader;
89 this.bRFlag = bRFlag;
90 this.srpId = srpID;
91 this.llOptionalTlv = llOptionalTlv;
92 }
93
94 /**
95 * sets the SRP object header.
96 *
97 * @param obj srp object header
98 */
99 public void setSrpObjHeader(PcepObjectHeader obj) {
100 this.srpObjHeader = obj;
101 }
102
103 @Override
104 public void setSrpID(int srpID) {
105 this.srpId = srpID;
106 }
107
108 @Override
109 public void setRFlag(boolean bRFlag) {
110 this.bRFlag = bRFlag;
111 }
112
113 /**
114 * Returns SRP object header.
115 *
116 * @return srpObjHeader
117 */
118 public PcepObjectHeader getSrpObjHeader() {
119 return this.srpObjHeader;
120 }
121
122 @Override
123 public int getSrpID() {
124 return this.srpId;
125 }
126
127 @Override
128 public boolean getRFlag() {
129 return this.bRFlag;
130 }
131
132 @Override
133 public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
134 this.llOptionalTlv = llOptionalTlv;
135
136 }
137
138 @Override
139 public LinkedList<PcepValueType> getOptionalTlv() {
140 return this.llOptionalTlv;
141 }
142
143 /**
144 * Reads from channel buffer and returns instance of PCEP SRP object.
145 *
146 * @param cb of channel buffer.
147 * @return PCEP SRP object
148 * @throws PcepParseException when srp object is not received in channel buffer
149 */
150 public static PcepSrpObject read(ChannelBuffer cb) throws PcepParseException {
151
152 log.debug("SrpObject::read");
153 PcepObjectHeader srpObjHeader;
154 boolean bRFlag;
155
156 int srpID;
157 int flags;
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700158 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700159
160 srpObjHeader = PcepObjectHeader.read(cb);
161
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700162 if (srpObjHeader.getObjClass() != SRP_OBJ_CLASS) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700163 throw new PcepParseException("SRP object expected. But received " + srpObjHeader.getObjClass());
164 }
165
166 //take only SrpObject buffer.
167 ChannelBuffer tempCb = cb.readBytes(srpObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
168 flags = tempCb.readInt();
Phanendra Mandaf346ea82015-09-04 15:21:39 -0700169 bRFlag = 0 < flags;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700170 srpID = tempCb.readInt();
171
172 llOptionalTlv = parseOptionalTlv(tempCb);
173
174 return new PcepSrpObjectVer1(srpObjHeader, bRFlag, srpID, llOptionalTlv);
175 }
176
177 @Override
178 public int write(ChannelBuffer cb) throws PcepParseException {
179
180 int objStartIndex = cb.writerIndex();
181
182 //write common header
183 int objLenIndex = srpObjHeader.write(cb);
184
185 //write Flags
186 byte bFlag;
187
188 bFlag = (bRFlag) ? BBIT_SET : BBIT_RESET;
189
190 cb.writeInt(bFlag);
191
192 //write SrpId
193 cb.writeInt(srpId);
194
195 // Add optional TLV
196 if (!packOptionalTlv(cb)) {
197 throw new PcepParseException("Failed to write srp tlv to channel buffer.");
198 }
199
200 //now write SRP Object Length
201 cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
202
203 return cb.writerIndex();
204 }
205
206 /**
207 * Parse Optional TLvs from the channel buffer.
208 *
209 * @param cb of type channel buffer
210 * @return list of optional tlvs
211 * @throws PcepParseException when unsupported tlv is received in srp object
212 */
213 public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
214
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700215 LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700216
217 while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {
218
219 PcepValueType tlv;
220 short hType = cb.readShort();
221 short hLength = cb.readShort();
222
223 switch (hType) {
224
225 case SymbolicPathNameTlv.TYPE:
226 tlv = SymbolicPathNameTlv.read(cb, hLength);
227 cb.skipBytes(hLength);
228 break;
229
230 default:
231 throw new PcepParseException("Unsupported TLV received in SRP Object.");
232 }
233
234 // Check for the padding
235 int pad = hLength % 4;
236 if (0 < pad) {
237 pad = 4 - pad;
238 if (pad <= cb.readableBytes()) {
239 cb.skipBytes(pad);
240 }
241 }
242 llOutOptionalTlv.add(tlv);
243 }
244
245 return llOutOptionalTlv;
246 }
247
248 /**
249 * Writes optional tlvs to channel buffer.
250 *
251 * @param cb of type channel buffer
252 * @return true if writing optional tlv to channel buffer is success.
253 */
254 protected boolean packOptionalTlv(ChannelBuffer cb) {
255
256 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
257
258 while (listIterator.hasNext()) {
259 PcepValueType tlv = listIterator.next();
260
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700261 if (tlv == null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700262 log.debug("tlv is null from OptionalTlv list");
263 continue;
264 }
265 tlv.write(cb);
266
267 // need to take care of padding
268 int pad = tlv.getLength() % 4;
269
270 if (0 != pad) {
271 pad = 4 - pad;
272 for (int i = 0; i < pad; ++i) {
273 cb.writeByte((byte) 0);
274 }
275 }
276 }
277
278 return true;
279 }
280
281 /**
282 * Builder class for PCEP srp Object.
283 */
284 public static class Builder implements PcepSrpObject.Builder {
285 private boolean bIsHeaderSet = false;
286 private boolean bIsSrpIdset = false;
287 private boolean bIsRFlagSet = false;
288
289 private PcepObjectHeader srpObjHeader;
290 private int srpId;
291 private boolean bRFlag;
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700292 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700293
294 private boolean bIsPFlagSet = false;
295 private boolean bPFlag;
296
297 private boolean bIsIFlagSet = false;
298 private boolean bIFlag;
299
300 @Override
301 public PcepSrpObject build() throws PcepParseException {
302 PcepObjectHeader srpObjHeader = this.bIsHeaderSet ? this.srpObjHeader : DEFAULT_SRP_OBJECT_HEADER;
303
304 boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_RFLAG;
305
306 if (!this.bIsSrpIdset) {
307 throw new PcepParseException("SrpID not set while building SRP Object.");
308 }
309
310 if (bIsPFlagSet) {
311 srpObjHeader.setPFlag(bPFlag);
312 }
313
314 if (bIsIFlagSet) {
315 srpObjHeader.setIFlag(bIFlag);
316 }
317
318 return new PcepSrpObjectVer1(srpObjHeader, bRFlag, this.srpId, this.llOptionalTlv);
319 }
320
321 @Override
322 public PcepObjectHeader getSrpObjHeader() {
323 return this.srpObjHeader;
324 }
325
326 @Override
327 public Builder setSrpObjHeader(PcepObjectHeader obj) {
328 this.srpObjHeader = obj;
329 this.bIsHeaderSet = true;
330 return this;
331 }
332
333 @Override
334 public int getSrpID() {
335 return this.srpId;
336 }
337
338 @Override
339 public Builder setSrpID(int srpID) {
340 this.srpId = srpID;
341 this.bIsSrpIdset = true;
342 return this;
343 }
344
345 @Override
346 public boolean getRFlag() {
347 return this.bRFlag;
348 }
349
350 @Override
351 public Builder setRFlag(boolean bRFlag) {
352 this.bRFlag = bRFlag;
353 this.bIsRFlagSet = true;
354 return this;
355 }
356
357 @Override
358 public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
359 this.llOptionalTlv = llOptionalTlv;
360 return this;
361 }
362
363 @Override
364 public LinkedList<PcepValueType> getOptionalTlv() {
365 return this.llOptionalTlv;
366 }
367
368 @Override
369 public Builder setPFlag(boolean value) {
370 this.bPFlag = value;
371 this.bIsPFlagSet = true;
372 return this;
373 }
374
375 @Override
376 public Builder setIFlag(boolean value) {
377 this.bIFlag = value;
378 this.bIsIFlagSet = true;
379 return this;
380 }
381
382 }
383
384 @Override
385 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700386 return MoreObjects.toStringHelper(getClass())
387 .add("RFlag", bRFlag)
388 .add("SRPID", srpId)
389 .add("OptionalTlvList", llOptionalTlv)
390 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700391 }
392}