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