7234a467a4ab9ae9b5e77c576bbaeee503de782b
[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 package org.onosproject.pcepio.protocol.ver1;
17
18 import java.util.LinkedList;
19 import java.util.ListIterator;
20
21 import org.jboss.netty.buffer.ChannelBuffer;
22 import org.onosproject.pcepio.exceptions.PcepParseException;
23 import org.onosproject.pcepio.protocol.PcepRPObject;
24 import org.onosproject.pcepio.types.PcepObjectHeader;
25 import org.onosproject.pcepio.types.PcepValueType;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import com.google.common.base.MoreObjects;
30
31 /**
32  * Provides PCEP RP object.
33  */
34 public class PcepRPObjectVer1 implements PcepRPObject {
35
36     /*
37      *  RP Object.
38     0                   1                   2                   3
39     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
40     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41     |                          Flags                    |O|B|R| Pri |
42     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43     |                        Request-ID-number                      |
44     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45     |                                                               |
46     //                      Optional TLVs                          //
47     |                                                               |
48     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49      */
50
51     protected static final Logger log = LoggerFactory.getLogger(PcepRPObjectVer1.class);
52
53     public static final byte RP_OBJ_TYPE = 1;
54     public static final byte RP_OBJ_CLASS = 2;
55     public static final byte RP_OBJECT_VERSION = 1;
56     public static final short RP_OBJ_MINIMUM_LENGTH = 12;
57
58     public static final int DEFAULT_REQUEST_ID_NUM = 0;
59     //Signalled , all default values to be checked.
60     public static final boolean DEFAULT_OFLAG = false;
61     public static final boolean DEFAULT_BFLAG = false;
62     public static final boolean DEFAULT_RFLAG = false;
63     public static final byte DEFAULT_PRIFLAG = 0;
64     public static final int OBJECT_HEADER_LENGTH = 4;
65     public static final int OFLAG_SHIFT_VALUE = 5;
66     public static final int BFLAG_SHIFT_VALUE = 4;
67     public static final int RFLAG_SHIFT_VALUE = 3;
68     public static final int OFLAG_TEMP_SHIFT_VALUE = 0x20;
69     public static final int BFLAG_TEMP_SHIFT_VALUE = 0x10;
70     public static final int RFLAG_TEMP_SHIFT_VALUE = 0x08;
71     public static final int PRIFLAG_TEMP_SHIFT_VALUE = 0x07;
72     public static final int BIT_SET = 1;
73     public static final int BIT_RESET = 0;
74     public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
75
76     public static final PcepObjectHeader DEFAULT_RP_OBJECT_HEADER = new PcepObjectHeader(RP_OBJ_CLASS, RP_OBJ_TYPE,
77             PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RP_OBJ_MINIMUM_LENGTH);
78
79     private PcepObjectHeader rpObjHeader;
80     private int iRequestIdNum;
81     private boolean bOFlag;
82     private boolean bBFlag;
83     private boolean bRFlag;
84     private byte yPriFlag; // 3bytes
85     private LinkedList<PcepValueType> llOptionalTlv;
86
87     /**
88      * Constructor to initialize variables.
89      *
90      * @param rpObjHeader RP-OBJECT header
91      * @param iRequestIdNum Request-ID-number
92      * @param bOFlag O-flag
93      * @param bBFlag B-flag
94      * @param bRFlag R-flag
95      * @param yPriFlag Pri-flag
96      * @param llOptionalTlv linked list of Optional TLV
97      */
98     public PcepRPObjectVer1(PcepObjectHeader rpObjHeader, int iRequestIdNum, boolean bOFlag, boolean bBFlag,
99             boolean bRFlag, byte yPriFlag, LinkedList<PcepValueType> llOptionalTlv) {
100         this.rpObjHeader = rpObjHeader;
101         this.iRequestIdNum = iRequestIdNum;
102         this.bOFlag = bOFlag;
103         this.bBFlag = bBFlag;
104         this.bRFlag = bRFlag;
105         this.yPriFlag = yPriFlag;
106         this.llOptionalTlv = llOptionalTlv;
107     }
108
109     /**
110      * Sets RP Object header.
111      *
112      * @param obj RP Object header
113      */
114     public void setRPObjHeader(PcepObjectHeader obj) {
115         this.rpObjHeader = obj;
116     }
117
118     @Override
119     public void setRequestIdNum(int iRequestIdNum) {
120         this.iRequestIdNum = iRequestIdNum;
121     }
122
123     @Override
124     public void setOFlag(boolean bOFlag) {
125         this.bOFlag = bOFlag;
126     }
127
128     @Override
129     public void setBFlag(boolean bBFlag) {
130         this.bBFlag = bBFlag;
131     }
132
133     @Override
134     public void setRFlag(boolean bRFlag) {
135         this.bRFlag = bRFlag;
136     }
137
138     @Override
139     public void setPriFlag(byte yPriFlag) {
140         this.yPriFlag = yPriFlag;
141     }
142
143     /**
144      * Returns RP Object header.
145      *
146      * @return rpObjHeader
147      */
148     public PcepObjectHeader getRPObjHeader() {
149         return this.rpObjHeader;
150     }
151
152     @Override
153     public int getRequestIdNum() {
154         return this.iRequestIdNum;
155     }
156
157     @Override
158     public boolean getOFlag() {
159         return this.bOFlag;
160     }
161
162     @Override
163     public boolean getBFlag() {
164         return this.bBFlag;
165     }
166
167     @Override
168     public boolean getRFlag() {
169         return this.bRFlag;
170     }
171
172     @Override
173     public byte getPriFlag() {
174         return this.yPriFlag;
175     }
176
177     /**
178      * Reads the channel buffer and returns the object of PcepRPObject.
179      *
180      * @param cb of type channel buffer
181      * @return the object of PcepRPObject
182      * @throws PcepParseException if mandatory fields are missing
183      */
184     public static PcepRPObject read(ChannelBuffer cb) throws PcepParseException {
185         log.debug("read");
186         PcepObjectHeader rpObjHeader;
187         int iRequestIdNum;
188         boolean bOFlag;
189         boolean bBFlag;
190         boolean bRFlag;
191         byte yPriFlag; // 3bytes
192         LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
193
194         rpObjHeader = PcepObjectHeader.read(cb);
195
196         //take only LspObject buffer.
197         ChannelBuffer tempCb = cb.readBytes(rpObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
198
199         int iTemp = tempCb.readInt();
200         yPriFlag = (byte) (iTemp & PRIFLAG_TEMP_SHIFT_VALUE);
201         bOFlag = (iTemp & OFLAG_TEMP_SHIFT_VALUE) == OFLAG_TEMP_SHIFT_VALUE;
202         bBFlag = (iTemp & BFLAG_TEMP_SHIFT_VALUE) == BFLAG_TEMP_SHIFT_VALUE;
203         bRFlag = (iTemp & RFLAG_TEMP_SHIFT_VALUE) == RFLAG_TEMP_SHIFT_VALUE;
204
205         iRequestIdNum = tempCb.readInt();
206
207         // parse optional TLV
208         llOptionalTlv = parseOptionalTlv(tempCb);
209
210         return new PcepRPObjectVer1(rpObjHeader, iRequestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
211     }
212
213     @Override
214     public int write(ChannelBuffer cb) throws PcepParseException {
215
216         //write Object header
217         int objStartIndex = cb.writerIndex();
218
219         int objLenIndex = rpObjHeader.write(cb);
220
221         if (objLenIndex <= 0) {
222             throw new PcepParseException("ObjectLength Index is " + objLenIndex);
223         }
224         int iTemp;
225         iTemp = (yPriFlag);
226
227         iTemp = (bOFlag) ? (iTemp | OFLAG_SHIFT_VALUE) : iTemp;
228         iTemp = (bBFlag) ? (iTemp | BFLAG_SHIFT_VALUE) : iTemp;
229         iTemp = (bRFlag) ? (iTemp | RFLAG_SHIFT_VALUE) : iTemp;
230
231         cb.writeInt(iTemp);
232         cb.writeInt(iRequestIdNum);
233
234         // Add optional TLV
235         packOptionalTlv(cb);
236
237         //Update object length now
238         int length = cb.writerIndex() - objStartIndex;
239
240         //will be helpful during print().
241         rpObjHeader.setObjLen((short) length);
242
243         cb.setShort(objLenIndex, (short) length);
244         return cb.writerIndex();
245     }
246
247     /**
248      * Returns list of optional tlvs.
249      *
250      * @param cb of type channel buffer.
251      * @return llOutOptionalTlv linked list of Optional TLV
252      * @throws PcepParseException if mandatory fields are missing
253      */
254     protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
255
256         LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<>();
257         //Currently no optional TLvs, will be added based on requirements.
258         return llOutOptionalTlv;
259     }
260
261     /**
262      * Returns optional tlvs.
263      *
264      * @param cb of type channel buffer
265      * @return llOptionalTlv linked list of Optional TLV
266      */
267     protected int packOptionalTlv(ChannelBuffer cb) {
268
269         ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
270         while (listIterator.hasNext()) {
271             listIterator.next().write(cb);
272         }
273
274         return cb.writerIndex();
275     }
276
277     /**
278      * Builder class for PCEP rp object.
279      */
280     public static class Builder implements PcepRPObject.Builder {
281
282         private boolean bIsHeaderSet = false;
283         private boolean bIsRequestIdNumSet = false;
284         private boolean bIsOFlagSet = false;
285         private boolean bIsRFlagset = false;
286         private boolean bIsBFlagSet = false;
287         private boolean bIsPriFlagSet = false;
288
289         private PcepObjectHeader rpObjHeader;
290         private int requestIdNum;
291         private boolean bOFlag;
292         private boolean bBFlag;
293         private boolean bRFlag;
294         private byte yPriFlag;
295         private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
296
297         private boolean bIsPFlagSet = false;
298         private boolean bPFlag;
299
300         private boolean bIsIFlagSet = false;
301         private boolean bIFlag;
302
303         @Override
304         public PcepRPObject build() {
305             PcepObjectHeader lspObjHeader = this.bIsHeaderSet ? this.rpObjHeader : DEFAULT_RP_OBJECT_HEADER;
306
307             int requestIdNum = this.bIsRequestIdNumSet ? this.requestIdNum : DEFAULT_REQUEST_ID_NUM;
308             boolean bOFlag = this.bIsOFlagSet ? this.bOFlag : DEFAULT_OFLAG;
309             boolean bBFlag = this.bIsBFlagSet ? this.bBFlag : DEFAULT_BFLAG;
310             boolean bRFlag = this.bIsRFlagset ? this.bRFlag : DEFAULT_RFLAG;
311             byte yPriFlag = this.bIsPriFlagSet ? this.yPriFlag : DEFAULT_PRIFLAG;
312
313             if (bIsPFlagSet) {
314                 lspObjHeader.setPFlag(bPFlag);
315             }
316
317             if (bIsIFlagSet) {
318                 lspObjHeader.setIFlag(bIFlag);
319             }
320
321             return new PcepRPObjectVer1(lspObjHeader, requestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
322         }
323
324         @Override
325         public PcepObjectHeader getRPObjHeader() {
326             return this.rpObjHeader;
327         }
328
329         @Override
330         public Builder setRPObjHeader(PcepObjectHeader obj) {
331             this.rpObjHeader = obj;
332             this.bIsHeaderSet = true;
333             return this;
334         }
335
336         @Override
337         public int getRequestIdNum() {
338             return this.requestIdNum;
339         }
340
341         @Override
342         public Builder setRequestIdNum(int value) {
343             this.requestIdNum = value;
344             this.bIsRequestIdNumSet = true;
345             return this;
346         }
347
348         @Override
349         public Builder setOFlag(boolean value) {
350             this.bOFlag = value;
351             this.bIsOFlagSet = true;
352             return this;
353         }
354
355         @Override
356         public boolean getBFlag() {
357             return this.bBFlag;
358         }
359
360         @Override
361         public Builder setBFlag(boolean value) {
362             this.bBFlag = value;
363             this.bIsBFlagSet = true;
364             return this;
365         }
366
367         @Override
368         public boolean getRFlag() {
369             return this.bRFlag;
370         }
371
372         @Override
373         public Builder setRFlag(boolean value) {
374             this.bRFlag = value;
375             this.bIsRFlagset = true;
376             return this;
377         }
378
379         @Override
380         public byte getPriFlag() {
381             return this.yPriFlag;
382         }
383
384         @Override
385         public Builder setPriFlag(byte value) {
386             this.yPriFlag = value;
387             this.bIsPriFlagSet = true;
388             return this;
389         }
390
391         @Override
392         public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
393             this.llOptionalTlv = llOptionalTlv;
394             return this;
395         }
396
397         @Override
398         public LinkedList<PcepValueType> getOptionalTlv() {
399             return this.llOptionalTlv;
400         }
401
402         @Override
403         public Builder setPFlag(boolean value) {
404             this.bPFlag = value;
405             this.bIsPFlagSet = true;
406             return this;
407         }
408
409         @Override
410         public Builder setIFlag(boolean value) {
411             this.bIFlag = value;
412             this.bIsIFlagSet = true;
413             return this;
414         }
415
416         @Override
417         public boolean getOFlag() {
418             return this.bOFlag;
419         }
420
421     }
422
423     @Override
424     public LinkedList<PcepValueType> getOptionalTlv() {
425         return this.llOptionalTlv;
426     }
427
428     @Override
429     public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
430         this.llOptionalTlv = llOptionalTlv;
431     }
432
433     @Override
434     public String toString() {
435         return MoreObjects.toStringHelper(getClass())
436                 .add("ObjectHeader", rpObjHeader)
437                 .add("OFlag", (bOFlag) ? 1 : 0)
438                 .add("BFlag", (bBFlag) ? 1 : 0)
439                 .add("RFlag", (bRFlag) ? 1 : 0)
440                 .add("PriFlag", yPriFlag)
441                 .add("RequestIdNumber", iRequestIdNum)
442                 .add("OptionalTlv", llOptionalTlv)
443                 .toString();
444     }
445 }