blob: 60d14b07def78d062a7a335b885b715e38cb08e1 [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001/*
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
17package org.onosproject.pcepio.protocol.ver1;
18
19import java.util.LinkedList;
20import java.util.ListIterator;
21
22import org.jboss.netty.buffer.ChannelBuffer;
23import org.onosproject.pcepio.exceptions.PcepParseException;
24import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
25import org.onosproject.pcepio.protocol.PcepAttribute;
26import org.onosproject.pcepio.protocol.PcepEndPointsObject;
27import org.onosproject.pcepio.protocol.PcepEroObject;
28import org.onosproject.pcepio.protocol.PcepInitiateMsg;
29import org.onosproject.pcepio.protocol.PcepLspObject;
30import org.onosproject.pcepio.protocol.PcepMessageReader;
31import org.onosproject.pcepio.protocol.PcepMessageWriter;
32import org.onosproject.pcepio.protocol.PcepSrpObject;
33import org.onosproject.pcepio.protocol.PcepType;
34import org.onosproject.pcepio.protocol.PcepVersion;
35import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
37
38import com.google.common.base.MoreObjects;
39
40/**
41 * Provides PCEP initiate message.
42 */
43class 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
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -070090 llPcInitiatedLspRequestList = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070091
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
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700129 if (cb == null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700130 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();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700255 if (srpObj != null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700256 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();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700264 if (lspObj != null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700265 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();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700278 if (endPointObj != null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700279 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();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700286 if (eroObj != null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700287 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();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700294 if (pcepAttribute != null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700295 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() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700328 return MoreObjects.toStringHelper(getClass())
329 .add("PcInitiaitedLspRequestList", llPcInitiatedLspRequestList)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700330 .toString();
331 }
332}