blob: 3a4e2bd33337be926bfa962a9d6e489d22a32a3b [file] [log] [blame]
bharat saraswalf7364db2015-08-11 13:39:31 +05301/*
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.PcepLspObject;
25import org.onosproject.pcepio.protocol.PcepMessageReader;
26import org.onosproject.pcepio.protocol.PcepMessageWriter;
27import org.onosproject.pcepio.protocol.PcepMsgPath;
28import org.onosproject.pcepio.protocol.PcepSrpObject;
29import org.onosproject.pcepio.protocol.PcepType;
30import org.onosproject.pcepio.protocol.PcepUpdateMsg;
31import org.onosproject.pcepio.protocol.PcepUpdateRequest;
32import org.onosproject.pcepio.protocol.PcepVersion;
33import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
36import com.google.common.base.MoreObjects;
37
38/**
39 * PCEP Update Message: A Path Computation LSP Update Request message
40 * (also referred to as PCUpd message) is a PCEP message sent by a PCE
41 * to a PCC to update attributes of an LSP.
42 */
43
44class PcepUpdateMsgVer1 implements PcepUpdateMsg {
45
46 // Pcep version: 1
47
48 /* The format of the PCUpd message is as follows:
49 * <PCUpd Message> ::= <Common Header>
50 * <update-request-list>
51 * Where:
52 * <update-request-list> ::= <update-request>[<update-request-list>]
53 * <update-request> ::= <SRP>
54 * <LSP>
55 * <path>
56 * Where:
57 * <path> ::= <ERO><attribute-list>
58 * Where:
59 * <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
60 * where:
61 * <attribute-list> ::=[<LSPA>]
62 * [<BANDWIDTH>]
63 * [<metric-list>]
64 * [<IRO>]
65 * <metric-list> ::=<METRIC>[<metric-list>]
66 *
67 * 0 1 2 3
68 * 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
69 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 * | Ver | Flags | Message-Type | Message-Length |
71 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 * | |
73 * // UPDATE REQUEST LIST //
74 * | |
75 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 *
77 * Reference:Internet-Draft-PCEP Extensions-for-Stateful-PCE-10
78 */
79
80 protected static final Logger log = LoggerFactory.getLogger(PcepUpdateMsgVer1.class);
81
82 public static final byte PACKET_VERSION = 1;
83 // UpdateMsgMinLength = SrpObjMinLentgh(12)+LspObjMinLength(8)+EroObjMinLength(12)+ CommonHeaderLength(4)
84 public static final short PACKET_MINIMUM_LENGTH = 36;
85 public static final PcepType MSG_TYPE = PcepType.UPDATE;
86 //Update Request List
87 private LinkedList<PcepUpdateRequest> llUpdateRequestList;
88
89 public static final PcepUpdateMsgVer1.Reader READER = new Reader();
90
91 //Reader reads UpdateMessage from the channel.
92 static class Reader implements PcepMessageReader<PcepUpdateMsg> {
93
94 LinkedList<PcepUpdateRequest> llUpdateRequestList;
95
96 @Override
97 public PcepUpdateMsg readFrom(ChannelBuffer cb) throws PcepParseException {
98
99 if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
100 throw new PcepParseException("Readable bytes is less than update message minimum length");
101 }
102
103 llUpdateRequestList = new LinkedList<PcepUpdateRequest>();
104
105 // fixed value property version == 1
106 byte version = cb.readByte();
107 version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
108 if (version != PACKET_VERSION) {
109 throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), got=" + version);
110 }
111 // fixed value property type == 11
112 byte type = cb.readByte();
113 if (type != MSG_TYPE.getType()) {
114 throw new PcepParseException("Wrong type. Expected=PcepType.UPDATE(11), got=" + type);
115 }
116 short length = cb.readShort();
117 if (length < PACKET_MINIMUM_LENGTH) {
118 throw new PcepParseException("Wrong length. Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: "
119 + length);
120 }
121
122 log.debug("reading update message of length " + length);
123
124 // parse Update Request list
125 if (!parseUpdateRequestList(cb)) {
126 throw new PcepParseException("parsing Update Request List Failed.");
127 }
128
129 return new PcepUpdateMsgVer1(llUpdateRequestList);
130 }
131
132 /**
133 * Parse update request list.
134 *
135 * @param cb of type channel buffer
136 * @return true after parsing Update Request List
137 * @throws PcepParseException while parsing update request list from channel buffer
138 */
139 public boolean parseUpdateRequestList(ChannelBuffer cb) throws PcepParseException {
140
141 /* <update-request-list>
142 * Where:
143 * <update-request-list> ::= <update-request>[<update-request-list>]
144 * <update-request> ::= <SRP>
145 * <LSP>
146 * <path>
147 * Where:
148 * <path> ::= <ERO><attribute-list>
149 * Where:
150 * <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
151 */
152
153 while (0 < cb.readableBytes()) {
154
155 PcepUpdateRequest pceUpdateReq = new PcepUpdateRequestVer1();
156
157 //Read SRP Object and Store it.
158 PcepSrpObject srpObj;
159 srpObj = PcepSrpObjectVer1.read(cb);
160 pceUpdateReq.setSrpObject(srpObj);
161
162 //Read LSP object and Store it.
163 PcepLspObject lspObj;
164 lspObj = PcepLspObjectVer1.read(cb);
165 pceUpdateReq.setLspObject(lspObj);
166
167 // Read Msg Path and store it.
168 PcepMsgPath msgPath = new PcepMsgPathVer1().read(cb);
169 pceUpdateReq.setMsgPath(msgPath);
170
171 llUpdateRequestList.add(pceUpdateReq);
172 }
173 return true;
174 }
175 }
176
177 /**
178 * Constructor to initialize llUpdateRequestList.
179 *
180 * @param llUpdateRequestList list of PcepUpdateRequest.
181 */
182 PcepUpdateMsgVer1(LinkedList<PcepUpdateRequest> llUpdateRequestList) {
183 this.llUpdateRequestList = llUpdateRequestList;
184 }
185
186 /**
187 * builder class for PCPE update message.
188 */
189 static class Builder implements PcepUpdateMsg.Builder {
190
191 // PCEP report message fields
192 LinkedList<PcepUpdateRequest> llUpdateRequestList;
193
194 @Override
195 public PcepVersion getVersion() {
196 return PcepVersion.PCEP_1;
197 }
198
199 @Override
200 public PcepType getType() {
201 return PcepType.UPDATE;
202 }
203
204 @Override
205 public PcepUpdateMsg build() {
206 return new PcepUpdateMsgVer1(this.llUpdateRequestList);
207 }
208
209 @Override
210 public LinkedList<PcepUpdateRequest> getUpdateRequestList() {
211 return this.llUpdateRequestList;
212 }
213
214 @Override
215 public Builder setUpdateRequestList(LinkedList<PcepUpdateRequest> llUpdateRequestList) {
216 this.llUpdateRequestList = llUpdateRequestList;
217 return this;
218 }
219
220 }
221
222 @Override
223 public void writeTo(ChannelBuffer cb) throws PcepParseException {
224 WRITER.write(cb, this);
225 }
226
227 static final Writer WRITER = new Writer();
228
229 //Writer writes UpdateMessage to the channel buffer.
230 static class Writer implements PcepMessageWriter<PcepUpdateMsgVer1> {
231
232 @Override
233 public void write(ChannelBuffer cb, PcepUpdateMsgVer1 message) throws PcepParseException {
234
235 int startIndex = cb.writerIndex();
236 // first 3 bits set to version
237 cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
238 // message type
239 cb.writeByte(MSG_TYPE.getType());
240 /* length is length of variable message, will be updated at the end
241 * Store the position of message
242 * length in buffer
243 */
244 int msgLenIndex = cb.writerIndex();
245
246 cb.writeShort((short) 0);
247 ListIterator<PcepUpdateRequest> listIterator = message.llUpdateRequestList.listIterator();
248
249 while (listIterator.hasNext()) {
250
251 PcepUpdateRequest updateReq = listIterator.next();
252
253 //SRP object is mandatory
254 PcepSrpObject srpObj = updateReq.getSrpObject();
255 srpObj.write(cb);
256
257 //LSP object is mandatory
258 PcepLspObject lspObj = updateReq.getLspObject();
259 lspObj.write(cb);
260
261 //PATH object is mandatory
262 PcepMsgPath msgPath = updateReq.getMsgPath();
263 msgPath.write(cb);
264 }
265
266 // update message length field
267 int length = cb.writerIndex() - startIndex;
268 cb.setShort(msgLenIndex, (short) length);
269 }
270 }
271
272 @Override
273 public PcepVersion getVersion() {
274 return PcepVersion.PCEP_1;
275 }
276
277 @Override
278 public PcepType getType() {
279 return MSG_TYPE;
280 }
281
282 @Override
283 public LinkedList<PcepUpdateRequest> getUpdateRequestList() {
284 return this.llUpdateRequestList;
285 }
286
287 @Override
288 public void setUpdateRequestList(LinkedList<PcepUpdateRequest> llUpdateRequestList) {
289 this.llUpdateRequestList = llUpdateRequestList;
290 }
291
292 @Override
293 public void print() {
294
295 log.debug("PCEP UPDATE MESSAGE");
296 ListIterator<PcepUpdateRequest> listIterator = llUpdateRequestList.listIterator();
297 while (listIterator.hasNext()) {
298 listIterator.next().print();
299 }
300 }
301
302 @Override
303 public String toString() {
304 return MoreObjects.toStringHelper(getClass())
305 .add("Update Request list", llUpdateRequestList)
306 .toString();
307 }
308}