60d14b07def78d062a7a335b885b715e38cb08e1
[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.PcInitiatedLspRequest;
25 import org.onosproject.pcepio.protocol.PcepAttribute;
26 import org.onosproject.pcepio.protocol.PcepEndPointsObject;
27 import org.onosproject.pcepio.protocol.PcepEroObject;
28 import org.onosproject.pcepio.protocol.PcepInitiateMsg;
29 import org.onosproject.pcepio.protocol.PcepLspObject;
30 import org.onosproject.pcepio.protocol.PcepMessageReader;
31 import org.onosproject.pcepio.protocol.PcepMessageWriter;
32 import org.onosproject.pcepio.protocol.PcepSrpObject;
33 import org.onosproject.pcepio.protocol.PcepType;
34 import org.onosproject.pcepio.protocol.PcepVersion;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import com.google.common.base.MoreObjects;
39
40 /**
41  * Provides PCEP initiate message.
42  */
43 class PcepInitiateMsgVer1 implements PcepInitiateMsg {
44
45     protected static final Logger log = LoggerFactory.getLogger(PcepInitiateMsgVer1.class);
46
47     // Ref : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03, section 5.1
48     /*      <PCInitiate Message>             ::= <Common Header>
49      *                                           <PCE-initiated-lsp-list>
50      *    Where:
51      *      <PCE-initiated-lsp-list>          ::= <PCE-initiated-lsp-request>[<PCE-initiated-lsp-list>]
52      *      <PCE-initiated-lsp-request>       ::= (<PCE-initiated-lsp-instantiation>|<PCE-initiated-lsp-deletion>)
53      *      <PCE-initiated-lsp-instantiation> ::= <SRP>
54      *                                            <LSP>
55      *                                            <END-POINTS>
56      *                                            <ERO>
57      *                                            [<attribute-list>]
58      *     <PCE-initiated-lsp-deletion>      ::= <SRP>
59      *                                           <LSP>
60      */
61
62     static final byte PACKET_VERSION = 1;
63     /* considering LspDelete Request PcInitiate msg will contain
64      * common header
65      * srp object
66      * lsp object
67      * so min length for this can be
68      * PACKET_MINIMUM_LENGTH = CommonHeaderLen(4)+SrpObjectMinLen(12)+LspObjectMinLen(8)
69      */
70     public static final short PACKET_MINIMUM_LENGTH = 24;
71     public static final short MINIMUM_COMMON_HEADER_LENGTH = 4;
72     public static final PcepType MSG_TYPE = PcepType.INITIATE;
73     private LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
74     public static final PcepInitiateMsgVer1.Reader READER = new Reader();
75
76     /**
77      * Reader class for reading of Pcep initiate message from channel buffer.
78      */
79     static class Reader implements PcepMessageReader<PcepInitiateMsg> {
80
81         LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
82
83         @Override
84         public PcepInitiateMsg readFrom(ChannelBuffer cb) throws PcepParseException {
85
86             if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
87                 return null;
88             }
89
90             llPcInitiatedLspRequestList = new LinkedList<>();
91
92             byte version = cb.readByte();
93             version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
94             if (version != PACKET_VERSION) {
95                 throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), received=" + version);
96             }
97             byte type = cb.readByte();
98             if (type != MSG_TYPE.getType()) {
99                 throw new PcepParseException("Wrong type. Expected=PcepType.INITIATE(12), recived=" + type);
100             }
101             short length = cb.readShort();
102
103             if (length < PACKET_MINIMUM_LENGTH) {
104                 throw new PcepParseException("Wrong length. Initiate message length expected to be >= "
105                         + PACKET_MINIMUM_LENGTH + ", but received=" + length);
106             }
107
108             log.debug("reading PcInitiate message of length " + length);
109
110             // parse Start initiate/deletion list
111             if (!parsePcInitiatedLspRequestList(cb)) {
112                 throw new PcepParseException("Parsing PCE-initiated-lsp-Request-list failed");
113             }
114
115             return new PcepInitiateMsgVer1(llPcInitiatedLspRequestList);
116         }
117
118         /**
119          * To parse PcInitiatedLspRequestList from PcInitiate Message.
120          *
121          * @param cb of type channel buffer
122          * @return true if parsing PcInitiatedLspRequestList is success, false otherwise
123          * @throws PcepParseException while parsing from channel buffer
124          */
125         public boolean parsePcInitiatedLspRequestList(ChannelBuffer cb) throws PcepParseException {
126
127             boolean isDelLspRequest = false;
128
129             if (cb == null) {
130                 throw new PcepParseException("Channel buffer is empty");
131             }
132
133             while (0 < cb.readableBytes()) {
134                 PcInitiatedLspRequest pceInitLspReq = new PcInitiatedLspRequestVer1();
135
136                 //store SRP object
137                 PcepSrpObject srpObj;
138                 srpObj = PcepSrpObjectVer1.read(cb);
139                 pceInitLspReq.setSrpObject(srpObj);
140                 isDelLspRequest = srpObj.getRFlag();
141
142                 //store LSP object
143                 PcepLspObject lspObj;
144                 lspObj = PcepLspObjectVer1.read(cb);
145                 pceInitLspReq.setLspObject(lspObj);
146
147                 /* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects
148                  * so if R bit is not set then we should read for Ero and EndPoint objects also.
149                  */
150                 if (!isDelLspRequest) {
151
152                     //store EndPoint object
153                     PcepEndPointsObject endPointObj;
154                     endPointObj = PcepEndPointsObjectVer1.read(cb);
155                     pceInitLspReq.setEndPointsObject(endPointObj);
156
157                     //store ERO object
158                     PcepEroObject eroObj;
159                     eroObj = PcepEroObjectVer1.read(cb);
160                     pceInitLspReq.setEroObject(eroObj);
161
162                     if (cb.readableBytes() > MINIMUM_COMMON_HEADER_LENGTH) {
163                         pceInitLspReq.setPcepAttribute(PcepAttributeVer1.read(cb));
164                     }
165                 }
166                 llPcInitiatedLspRequestList.add(pceInitLspReq);
167             }
168             return true;
169         }
170     }
171
172     /**
173      * Constructor to initialize PcInitiatedLspRequest.
174      *
175      * @param llPcInitiatedLspRequestList list of PcInitiatedLspRequest
176      */
177     PcepInitiateMsgVer1(LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList) {
178
179         if (llPcInitiatedLspRequestList == null) {
180             throw new NullPointerException("PcInitiatedLspRequestList cannot be null.");
181         }
182         this.llPcInitiatedLspRequestList = llPcInitiatedLspRequestList;
183     }
184
185     /**
186      * Builder class for PCEP initiate message.
187      */
188     static class Builder implements PcepInitiateMsg.Builder {
189
190         // Pcep initiate message fields
191         LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
192
193         @Override
194         public PcepVersion getVersion() {
195             return PcepVersion.PCEP_1;
196         }
197
198         @Override
199         public PcepType getType() {
200             return PcepType.INITIATE;
201         }
202
203         @Override
204         public PcepInitiateMsg build() {
205             return new PcepInitiateMsgVer1(this.llPcInitiatedLspRequestList);
206         }
207
208         @Override
209         public LinkedList<PcInitiatedLspRequest> getPcInitiatedLspRequestList() {
210             return this.llPcInitiatedLspRequestList;
211         }
212
213         @Override
214         public Builder setPcInitiatedLspRequestList(LinkedList<PcInitiatedLspRequest> ll) {
215             this.llPcInitiatedLspRequestList = ll;
216             return this;
217         }
218     }
219
220     @Override
221     public void writeTo(ChannelBuffer cb) throws PcepParseException {
222         WRITER.write(cb, this);
223     }
224
225     static final Writer WRITER = new Writer();
226
227     /**
228      * Writer class for writing pcep initiate message to channel buffer.
229      */
230     static class Writer implements PcepMessageWriter<PcepInitiateMsgVer1> {
231
232         @Override
233         public void write(ChannelBuffer cb, PcepInitiateMsgVer1 message) throws PcepParseException {
234
235             boolean isDelLspRequest = false;
236             int startIndex = cb.writerIndex();
237             // first 3 bits set to version
238             cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
239             // message type 0xC
240             cb.writeByte(MSG_TYPE.getType());
241             // length is length of variable message, will be updated at the end
242             // Store the position of message
243             // length in buffer
244             int msgLenIndex = cb.writerIndex();
245             cb.writeShort(0);
246
247             ListIterator<PcInitiatedLspRequest> listIterator = message.llPcInitiatedLspRequestList.listIterator();
248
249             while (listIterator.hasNext()) {
250
251                 PcInitiatedLspRequest listReq = listIterator.next();
252
253                 //Srp Object is mandatory
254                 PcepSrpObject srpObj = listReq.getSrpObject();
255                 if (srpObj != null) {
256                     isDelLspRequest = srpObj.getRFlag();
257                     srpObj.write(cb);
258                 } else {
259                     throw new PcepParseException("SRP Object is mandatory for PcInitiate message.");
260                 }
261
262                 //LSP Object is mandatory
263                 PcepLspObject lspObj = listReq.getLspObject();
264                 if (lspObj != null) {
265                     lspObj.write(cb);
266                 } else {
267                     throw new PcepParseException("LSP Object is mandatory for PcInitiate message.");
268                 }
269
270                 /* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects
271                  * so if R bit is not set then we should read for Ero and EndPoint objects also.
272                  */
273
274                 if (!isDelLspRequest) {
275
276                     //EndPoints object is mandatory
277                     PcepEndPointsObject endPointObj = listReq.getEndPointsObject();
278                     if (endPointObj != null) {
279                         endPointObj.write(cb);
280                     } else {
281                         throw new PcepParseException("End points Object is mandatory for PcInitiate message.");
282                     }
283
284                     //Ero object is mandatory
285                     PcepEroObject eroObj = listReq.getEroObject();
286                     if (eroObj != null) {
287                         eroObj.write(cb);
288                     } else {
289                         throw new PcepParseException("ERO Object is mandatory for PcInitiate message.");
290                     }
291
292                     //PcepAttribute is optional
293                     PcepAttribute pcepAttribute = listReq.getPcepAttribute();
294                     if (pcepAttribute != null) {
295                         pcepAttribute.write(cb);
296                     }
297                 }
298             }
299
300             // PCInitiate message length field
301             int length = cb.writerIndex() - startIndex;
302             cb.setShort(msgLenIndex, (short) length);
303         }
304     }
305
306     @Override
307     public PcepVersion getVersion() {
308         return PcepVersion.PCEP_1;
309     }
310
311     @Override
312     public PcepType getType() {
313         return MSG_TYPE;
314     }
315
316     @Override
317     public LinkedList<PcInitiatedLspRequest> getPcInitiatedLspRequestList() {
318         return this.llPcInitiatedLspRequestList;
319     }
320
321     @Override
322     public void setPcInitiatedLspRequestList(LinkedList<PcInitiatedLspRequest> ll) {
323         this.llPcInitiatedLspRequestList = ll;
324     }
325
326     @Override
327     public String toString() {
328         return MoreObjects.toStringHelper(getClass())
329                 .add("PcInitiaitedLspRequestList", llPcInitiatedLspRequestList)
330                 .toString();
331     }
332 }