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