48a337f428a482dd9f06345b9f3ce1d0478304c9
[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.PcepErrorObject;
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 Error Object.
33  */
34 public class PcepErrorObjectVer1 implements PcepErrorObject {
35
36     /*
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     |   Reserved    |      Flags    |   Error-Type  |  Error-value  |
43     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44     |                                                               |
45     //                         Optional TLVs                       //
46     |                                                               |
47     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48      */
49     protected static final Logger log = LoggerFactory.getLogger(PcepErrorObjectVer1.class);
50
51     public static final byte ERROR_OBJ_TYPE = 1;
52     public static final byte ERROR_OBJ_CLASS = 13;
53     public static final byte ERROR_OBJECT_VERSION = 1;
54     //ERROR_OBJ_MINIMUM_LENGTH = CommonHeaderLen(4)+ErrorObjectHeaderLen(4)
55     public static final short ERROR_OBJ_MINIMUM_LENGTH = 8;
56     public static final int OBJECT_HEADER_LENGTH = 4;
57
58     public static final PcepObjectHeader DEFAULT_ERROR_OBJECT_HEADER = new PcepObjectHeader(ERROR_OBJ_CLASS,
59             ERROR_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
60             ERROR_OBJ_MINIMUM_LENGTH);
61
62     private PcepObjectHeader errorObjHeader;
63     private byte yErrorType;
64     private byte yErrorValue;
65     private LinkedList<PcepValueType> llOptionalTlv; // Optional TLV
66
67     /**
68      * Constructor to initialize variables.
69      *
70      * @param errorObjHeader ERROR Object header
71      * @param yErrorType Error Type
72      * @param yErrorValue Error Value
73      * @param llOptionalTlv list of optional TLV
74      */
75
76     public PcepErrorObjectVer1(PcepObjectHeader errorObjHeader, byte yErrorType, byte yErrorValue,
77             LinkedList<PcepValueType> llOptionalTlv) {
78         this.errorObjHeader = errorObjHeader;
79         this.yErrorType = yErrorType;
80         this.yErrorValue = yErrorValue;
81         this.llOptionalTlv = llOptionalTlv;
82     }
83
84     /**
85      * sets Object Header.
86      *
87      * @param obj Error-Object header
88      */
89     public void setLspObjHeader(PcepObjectHeader obj) {
90         this.errorObjHeader = obj;
91     }
92
93     @Override
94     public void setErrorType(byte yErrorType) {
95         this.yErrorType = yErrorType;
96     }
97
98     @Override
99     public void setErrorValue(byte yErrorValue) {
100         this.yErrorValue = yErrorValue;
101     }
102
103     /**
104      * returns object header.
105      *
106      * @return errorObjHeader Error-Object header
107      */
108     public PcepObjectHeader getErrorObjHeader() {
109         return this.errorObjHeader;
110     }
111
112     @Override
113     public int getErrorType() {
114         return this.yErrorType;
115     }
116
117     @Override
118     public byte getErrorValue() {
119         return this.yErrorValue;
120     }
121
122     @Override
123     public LinkedList<PcepValueType> getOptionalTlv() {
124         return this.llOptionalTlv;
125     }
126
127     @Override
128     public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
129         this.llOptionalTlv = llOptionalTlv;
130     }
131
132     /**
133      * Reads from channel buffer and returns object of PcepErrorObject.
134      *
135      * @param cb of channel buffer.
136      * @return object of PCEP-ERROR-OBJECT
137      */
138     public static PcepErrorObject read(ChannelBuffer cb) {
139
140         PcepObjectHeader errorObjHeader;
141         byte yErrorType;
142         byte yErrorValue;
143         LinkedList<PcepValueType> llOptionalTlv;
144
145         errorObjHeader = PcepObjectHeader.read(cb);
146
147         //take only ErrorObject buffer.
148         ChannelBuffer tempCb = cb.readBytes(errorObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
149         tempCb.readByte(); //ignore Reserved
150         tempCb.readByte(); //ignore Flags
151         yErrorType = tempCb.readByte();
152         yErrorValue = tempCb.readByte();
153
154         llOptionalTlv = parseOptionalTlv(tempCb);
155
156         return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv);
157     }
158
159     /**
160      * returns Linked list of optional tlvs.
161      *
162      * @param cb channel buffer.
163      * @return Linked list of optional tlvs
164      */
165     protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) {
166
167         LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<>();
168
169         byte[] yTemp = new byte[cb.readableBytes()];
170         cb.readBytes(yTemp);
171
172         return llOutOptionalTlv;
173     }
174
175     @Override
176     public int write(ChannelBuffer cb) throws PcepParseException {
177
178         //write Object header
179         int objStartIndex = cb.writerIndex();
180
181         int objLenIndex = errorObjHeader.write(cb);
182
183         if (objLenIndex <= 0) {
184             throw new PcepParseException("While writing Error Object Header.");
185         }
186
187         //write Reserved
188         cb.writeByte(0);
189         //write Flags
190         cb.writeByte(0);
191         //write ErrorType and ErrorValue
192         cb.writeByte(this.yErrorType);
193         cb.writeByte(this.yErrorValue);
194
195         // Add optional TLV
196         packOptionalTlv(cb);
197
198         //Update object length now
199         int length = cb.writerIndex() - objStartIndex;
200         //will be helpful during print().
201         errorObjHeader.setObjLen((short) length);
202         // As per RFC the length of object should be
203         // multiples of 4
204         int pad = length % 4;
205         if (pad != 0) {
206             pad = 4 - pad;
207             for (int i = 0; i < pad; i++) {
208                 cb.writeByte((byte) 0);
209             }
210             length = length + pad;
211         }
212
213         cb.setShort(objLenIndex, (short) length);
214         return length;
215     }
216
217     /**
218      * Pack the Optional tlvs.
219      *
220      * @param cb channel buffer.
221      * @return writer index.
222      */
223     protected int packOptionalTlv(ChannelBuffer cb) {
224
225         ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
226         int startIndex = cb.writerIndex();
227         while (listIterator.hasNext()) {
228             PcepValueType tlv = listIterator.next();
229
230             if (tlv == null) {
231                 log.debug("TLV is null from OptionalTlv list");
232                 continue;
233             }
234             tlv.write(cb);
235         }
236
237         return cb.writerIndex() - startIndex;
238     }
239
240     /**
241      * Builder class for PCEP error object.
242      */
243     public static class Builder implements PcepErrorObject.Builder {
244
245         private boolean bIsHeaderSet = false;
246
247         private PcepObjectHeader errorObjHeader;
248         private byte yErrorType;
249         private byte yErrorValue;
250
251         private boolean bIsPFlagSet = false;
252         private boolean bPFlag;
253
254         private boolean bIsIFlagSet = false;
255         private boolean bIFlag;
256
257         private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<>();
258
259         @Override
260         public PcepErrorObject build() {
261
262             PcepObjectHeader errorObjHeader = this.bIsHeaderSet ? this.errorObjHeader : DEFAULT_ERROR_OBJECT_HEADER;
263
264             if (bIsPFlagSet) {
265                 errorObjHeader.setPFlag(bPFlag);
266             }
267
268             if (bIsIFlagSet) {
269                 errorObjHeader.setIFlag(bIFlag);
270             }
271
272             return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv);
273         }
274
275         @Override
276         public PcepObjectHeader getErrorObjHeader() {
277             return this.errorObjHeader;
278         }
279
280         @Override
281         public Builder setErrorObjHeader(PcepObjectHeader obj) {
282             this.errorObjHeader = obj;
283             this.bIsHeaderSet = true;
284             return this;
285         }
286
287         @Override
288         public int getErrorType() {
289             return this.yErrorType;
290         }
291
292         @Override
293         public Builder setErrorType(byte value) {
294             this.yErrorType = value;
295             return this;
296         }
297
298         @Override
299         public byte getErrorValue() {
300             return this.yErrorValue;
301         }
302
303         @Override
304         public Builder setErrorValue(byte value) {
305             this.yErrorValue = value;
306             return this;
307         }
308
309         @Override
310         public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
311             this.llOptionalTlv = llOptionalTlv;
312             return this;
313         }
314
315         @Override
316         public LinkedList<PcepValueType> getOptionalTlv() {
317             return this.llOptionalTlv;
318         }
319
320         @Override
321         public Builder setPFlag(boolean value) {
322             this.bPFlag = value;
323             this.bIsPFlagSet = true;
324             return this;
325         }
326
327         @Override
328         public Builder setIFlag(boolean value) {
329             this.bIFlag = value;
330             this.bIsIFlagSet = true;
331             return this;
332         }
333     }
334
335     @Override
336     public String toString() {
337         return MoreObjects.toStringHelper(getClass())
338                 .add("ObjectHeader", errorObjHeader).add("ErrorType", yErrorType)
339                 .add("ErrorValue", yErrorValue).add("OptionalTlv", llOptionalTlv).toString();
340     }
341 }