f4000509aa3962b44fa7fbb28e3d43b3f244ab17
[onosfw.git] /
1 /*
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
17 package org.onosproject.pcepio.protocol.ver1;
18
19 import java.util.LinkedList;
20 import java.util.ListIterator;
21
22 import org.jboss.netty.buffer.ChannelBuffer;
23 import org.onosproject.pcepio.exceptions.PcepParseException;
24 import org.onosproject.pcepio.protocol.PcepLspaObject;
25 import org.onosproject.pcepio.types.PcepObjectHeader;
26 import org.onosproject.pcepio.types.PcepValueType;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import com.google.common.base.MoreObjects;
31
32 /**
33  * Provides PCEP label Object .
34  */
35 public class PcepLspaObjectVer1 implements PcepLspaObject {
36
37     /* LSPA Object Body Format
38
39     0                   1                   2                   3
40     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
41     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42     |                       Exclude-any                             |
43     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44     |                       Include-any                             |
45     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46     |                       Include-all                             |
47     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48     |  Setup Prio   |  Holding Prio |     Flags   |L|   Reserved    |
49     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50     |                                                               |
51     |                      Optional TLVs                            |
52     |                                                               |
53     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54      */
55
56     protected static final Logger log = LoggerFactory.getLogger(PcepLspaObjectVer1.class);
57
58     public static final byte LSPA_OBJ_TYPE = 1;
59     public static final byte LSPA_OBJ_CLASS = 9;
60     public static final byte LSPA_OBJECT_VERSION = 1;
61     public static final short LSPA_OBJ_MINIMUM_LENGTH = 20;
62     public static final int OBJECT_HEADER_LENGTH = 4;
63
64     static final PcepObjectHeader DEFAULT_LSPA_OBJECT_HEADER = new PcepObjectHeader(LSPA_OBJ_CLASS, LSPA_OBJ_TYPE,
65             PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, LSPA_OBJ_MINIMUM_LENGTH);
66
67     public static final int SETUP_PRIORITY_SHIFT_VALUE = 24;
68     public static final int HOLD_PRIORITY_SHIFT_VALUE = 16;
69     public static final int BFLAG_SHIFT_VALUE = 8;
70     public static final int LFLAG_SET = 1;
71     public static final int LFLAG_RESET = 0;
72     private PcepObjectHeader lspaObjHeader;
73     private int iExcludeAny;
74     private int iIncludeAny;
75     private int iIncludeAll;
76     private byte cSetupPriority;
77     private byte cHoldPriority;
78     private boolean bLFlag;
79     private LinkedList<PcepValueType> llOptionalTlv; //Optional TLV
80
81     /**
82      * Constructor to initialize member variables.
83      *
84      * @param lspaObjHeader lspa object header
85      * @param bLFlag b l flag
86      * @param iExcludeAny excludeAny value
87      * @param iIncludeAny includeAny value
88      * @param iIncludeAll includeAll value
89      * @param cSetupPriority setup priority value
90      * @param cHoldPriority hold priority value
91      * @param llOptionalTlv list of optional tlv
92      */
93     public PcepLspaObjectVer1(PcepObjectHeader lspaObjHeader, boolean bLFlag, int iExcludeAny, int iIncludeAny,
94             int iIncludeAll, byte cSetupPriority, byte cHoldPriority, LinkedList<PcepValueType> llOptionalTlv) {
95
96         this.lspaObjHeader = lspaObjHeader;
97         this.bLFlag = bLFlag;
98         this.iExcludeAny = iExcludeAny;
99         this.iIncludeAny = iIncludeAny;
100         this.iIncludeAll = iIncludeAll;
101         this.cSetupPriority = cSetupPriority;
102         this.cHoldPriority = cHoldPriority;
103         this.llOptionalTlv = llOptionalTlv;
104     }
105
106     /**
107      * Sets Object Header.
108      *
109      * @param obj lspa object header
110      */
111     public void setLspaObjHeader(PcepObjectHeader obj) {
112         this.lspaObjHeader = obj;
113     }
114
115     @Override
116     public void setExcludeAny(int iExcludeAny) {
117         this.iExcludeAny = iExcludeAny;
118     }
119
120     @Override
121     public void setIncludeAny(int iIncludeAny) {
122         this.iIncludeAny = iIncludeAny;
123     }
124
125     @Override
126     public void setSetupPriority(byte cSetupPriority) {
127         this.cSetupPriority = cSetupPriority;
128     }
129
130     @Override
131     public void setHoldPriority(byte cHoldPriority) {
132         this.cHoldPriority = cHoldPriority;
133     }
134
135     @Override
136     public void setLFlag(boolean bLFlag) {
137         this.bLFlag = bLFlag;
138     }
139
140     /**
141      * Returns lspa Object Header.
142      *
143      * @return lspa Object Header
144      */
145     public PcepObjectHeader getLspaObjHeader() {
146         return this.lspaObjHeader;
147     }
148
149     @Override
150     public int getExcludeAny() {
151         return this.iExcludeAny;
152     }
153
154     @Override
155     public int getIncludeAny() {
156         return this.iIncludeAny;
157     }
158
159     @Override
160     public int getIncludeAll() {
161         return this.iIncludeAll;
162     }
163
164     @Override
165     public byte getSetupPriority() {
166         return this.cSetupPriority;
167     }
168
169     @Override
170     public byte getHoldPriority() {
171         return this.cHoldPriority;
172     }
173
174     @Override
175     public boolean getLFlag() {
176         return this.bLFlag;
177     }
178
179     @Override
180     public void setIncludeAll(int value) {
181         this.iIncludeAll = value;
182
183     }
184
185     @Override
186     public LinkedList<PcepValueType> getOptionalTlv() {
187         return this.llOptionalTlv;
188     }
189
190     @Override
191     public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
192         this.llOptionalTlv = llOptionalTlv;
193
194     }
195
196     /**
197      * Reads channel buffer and returns object of PcepLspaObject.
198      *
199      * @param cb of type channel buffer.
200      * @return object of PcepLspaObject
201      * @throws PcepParseException while parsing lspa object from channel buffer
202      */
203     public static PcepLspaObject read(ChannelBuffer cb) throws PcepParseException {
204
205         log.debug("LspaObject::read");
206         PcepObjectHeader lspaObjHeader;
207         int iExcludeAny;
208         int iIncludeAny;
209         int iIncludeAll;
210         byte cSetupPriority;
211         byte cHoldPriority;
212         boolean bLFlag;
213         byte flags;
214
215         // Optional TLV
216         LinkedList<PcepValueType> llOptionalTlv;
217
218         lspaObjHeader = PcepObjectHeader.read(cb);
219
220         //take only Lspa Object buffer.
221         ChannelBuffer tempCb = cb.readBytes(lspaObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
222         iExcludeAny = tempCb.readInt();
223         iIncludeAny = tempCb.readInt();
224         iIncludeAll = tempCb.readInt();
225         cSetupPriority = tempCb.readByte();
226         cHoldPriority = tempCb.readByte();
227         flags = tempCb.readByte();
228         tempCb.readByte();
229
230         bLFlag = (flags & (byte) LFLAG_SET) == LFLAG_SET;
231
232         llOptionalTlv = parseOptionalTlv(tempCb);
233
234         return new PcepLspaObjectVer1(lspaObjHeader, bLFlag, iExcludeAny, iIncludeAny, iIncludeAll, cSetupPriority,
235                 cHoldPriority, llOptionalTlv);
236     }
237
238     @Override
239     public int write(ChannelBuffer cb) throws PcepParseException {
240
241         //write Object header
242         int objStartIndex = cb.writerIndex();
243
244         int objLenIndex = lspaObjHeader.write(cb);
245
246         if (objLenIndex <= 0) {
247             throw new PcepParseException("Failed to write lspa object header. Index " + objLenIndex);
248         }
249
250         cb.writeInt(iExcludeAny);
251         cb.writeInt(iIncludeAny);
252         cb.writeInt(iIncludeAll);
253
254         int iTemp = cSetupPriority << SETUP_PRIORITY_SHIFT_VALUE;
255         iTemp = iTemp | (cHoldPriority << HOLD_PRIORITY_SHIFT_VALUE);
256         byte bFlag;
257         bFlag = (bLFlag) ? (byte) LFLAG_SET : LFLAG_RESET;
258         iTemp = iTemp | (bFlag << BFLAG_SHIFT_VALUE);
259         cb.writeInt(iTemp);
260
261         // Add optional TLV
262         if (!packOptionalTlv(cb)) {
263             throw new PcepParseException("Faild to write lspa objects tlv to channel buffer");
264         }
265
266         short length = (short) (cb.writerIndex() - objStartIndex);
267
268         lspaObjHeader.setObjLen(length); //will be helpful during print().
269
270         //As per RFC the length of object should be multiples of 4
271         short pad = (short) (length % 4);
272
273         if (pad != 0) {
274             pad = (short) (4 - pad);
275             for (int i = 0; i < pad; i++) {
276                 cb.writeByte((byte) 0);
277             }
278             length = (short) (length + pad);
279         }
280         cb.setShort(objLenIndex, length);
281         return cb.writerIndex();
282     }
283
284     /**
285      * Parse list of optional tlvs.
286      *
287      * @param cb channel buffer
288      * @return list of optional tlvs.
289      * @throws PcepParseException when fails to parse optional tlv list.
290      */
291     public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
292
293         LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<>();
294
295         return llOutOptionalTlv;
296     }
297
298     /**
299      * Writes optional tlvs to channel buffer.
300      *
301      * @param cb channel buffer
302      * @return true
303      */
304     protected boolean packOptionalTlv(ChannelBuffer cb) {
305         int hTlvType;
306         int hTlvLength;
307
308         ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
309         while (listIterator.hasNext()) {
310             PcepValueType tlv = listIterator.next();
311             if (tlv == null) {
312                 log.debug("Warning: tlv is null from OptionalTlv list");
313                 continue;
314             }
315             hTlvType = tlv.getType();
316             hTlvLength = tlv.getLength();
317             if (0 == hTlvLength) {
318                 log.debug("Warning: invalid length in tlv of OptionalTlv list");
319                 continue;
320             }
321
322             cb.writeShort(hTlvType);
323             cb.writeShort(hTlvLength);
324
325             switch (hTlvType) {
326             //TODO: optional TLV for LSPA to be added
327
328             default:
329                 log.debug("Warning: PcepLspaObject: unknown tlv");
330             }
331
332             // As per RFC the length of object should
333             // be multiples of 4
334             int pad = hTlvLength % 4;
335
336             if (0 < pad) {
337                 pad = 4 - pad;
338                 if (pad <= cb.readableBytes()) {
339                     cb.skipBytes(pad);
340                 }
341             }
342         }
343         return true;
344     }
345
346     /**
347      * Builder class for PCEP lspa object.
348      */
349     public static class Builder implements PcepLspaObject.Builder {
350         private boolean bIsHeaderSet = false;
351
352         private PcepObjectHeader lspaObjHeader;
353
354         private boolean bLFlag;
355         private int iExcludeAny;
356         private boolean bIsExcludeAnySet = false;
357         private int iIncludeAny;
358         private boolean bIsIncludeAnySet = false;
359         private int iIncludeAll;
360         private boolean bIsIncludeAllSet = false;
361         private byte cSetupPriority;
362         private boolean bIsSetupPrioritySet = false;
363         private byte cHoldPriority;
364         private boolean bIsHoldPrioritySet = false;
365         private LinkedList<PcepValueType> llOptionalTlv;
366
367         private boolean bIsPFlagSet = false;
368         private boolean bPFlag;
369
370         private boolean bIsIFlagSet = false;
371         private boolean bIFlag;
372
373         @Override
374         public PcepLspaObject build() throws PcepParseException {
375
376             PcepObjectHeader lspaObjHeader = this.bIsHeaderSet ? this.lspaObjHeader : DEFAULT_LSPA_OBJECT_HEADER;
377
378             if (!this.bIsExcludeAnySet) {
379                 throw new PcepParseException("ExcludeAny NOT Set while building PcepLspaObject.");
380             }
381             if (!this.bIsIncludeAnySet) {
382                 throw new PcepParseException("IncludeAny NOT Set while building PcepLspaObject.");
383             }
384             if (!this.bIsIncludeAllSet) {
385                 throw new PcepParseException("IncludeAll NOT Set while building PcepLspaObject.");
386             }
387             if (!this.bIsSetupPrioritySet) {
388                 throw new PcepParseException("Setup Priority NOT Set while building PcepLspaObject.");
389             }
390             if (!this.bIsHoldPrioritySet) {
391                 throw new PcepParseException("Hold Priority NOT Set while building PcepLspaObject.");
392             }
393
394             if (bIsPFlagSet) {
395                 lspaObjHeader.setPFlag(bPFlag);
396             }
397
398             if (bIsIFlagSet) {
399                 lspaObjHeader.setIFlag(bIFlag);
400             }
401
402             return new PcepLspaObjectVer1(lspaObjHeader, bLFlag, iExcludeAny, iIncludeAny, iIncludeAll, cSetupPriority,
403                     cHoldPriority, llOptionalTlv);
404         }
405
406         @Override
407         public PcepObjectHeader getLspaObjHeader() {
408             return this.lspaObjHeader;
409         }
410
411         @Override
412         public Builder setLspaObjHeader(PcepObjectHeader obj) {
413             this.lspaObjHeader = obj;
414             this.bIsHeaderSet = true;
415             return this;
416         }
417
418         @Override
419         public boolean getLFlag() {
420             return this.bLFlag;
421         }
422
423         @Override
424         public Builder setLFlag(boolean value) {
425             this.bLFlag = value;
426             return this;
427         }
428
429         @Override
430         public int getExcludeAny() {
431             return this.iExcludeAny;
432         }
433
434         @Override
435         public Builder setExcludeAny(int value) {
436             this.iExcludeAny = value;
437             this.bIsExcludeAnySet = true;
438             return this;
439         }
440
441         @Override
442         public int getIncludeAny() {
443             return this.iIncludeAny;
444         }
445
446         @Override
447         public Builder setIncludeAny(int value) {
448             this.iIncludeAny = value;
449             this.bIsIncludeAnySet = true;
450             return this;
451         }
452
453         @Override
454         public int getIncludeAll() {
455             return this.iIncludeAll;
456         }
457
458         @Override
459         public Builder setIncludeAll(int value) {
460             this.iIncludeAll = value;
461             this.bIsIncludeAllSet = true;
462             return this;
463         }
464
465         @Override
466         public byte getSetupPriority() {
467             return this.cSetupPriority;
468         }
469
470         @Override
471         public Builder setSetupPriority(byte value) {
472             this.cSetupPriority = value;
473             this.bIsSetupPrioritySet = true;
474             return this;
475         }
476
477         @Override
478         public byte getHoldPriority() {
479             return this.cHoldPriority;
480         }
481
482         @Override
483         public Builder setHoldPriority(byte value) {
484             this.cHoldPriority = value;
485             this.bIsHoldPrioritySet = true;
486             return this;
487         }
488
489         @Override
490         public LinkedList<PcepValueType> getOptionalTlv() {
491             return this.llOptionalTlv;
492         }
493
494         @Override
495         public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
496             this.llOptionalTlv = llOptionalTlv;
497
498             return this;
499         }
500
501         @Override
502         public Builder setPFlag(boolean value) {
503             this.bPFlag = value;
504             this.bIsPFlagSet = true;
505             return this;
506         }
507
508         @Override
509         public Builder setIFlag(boolean value) {
510             this.bIFlag = value;
511             this.bIsIFlagSet = true;
512             return this;
513         }
514
515     }
516
517     @Override
518     public String toString() {
519         return MoreObjects.toStringHelper(getClass())
520                 .add("LFlag", bLFlag)
521                 .add("SetupPriority", cSetupPriority)
522                 .add("HoldPriority", cHoldPriority)
523                 .add("IncludeAll", iIncludeAll)
524                 .add("IncludeAny", iIncludeAny)
525                 .add("ExcludeAny", iExcludeAny)
526                 .add("OptionalTlvList", llOptionalTlv)
527                 .toString();
528     }
529 }