2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onosproject.pcepio.protocol.ver1;
19 import java.util.LinkedList;
20 import java.util.ListIterator;
22 import org.jboss.netty.buffer.ChannelBuffer;
23 import org.onosproject.pcepio.exceptions.PcepParseException;
24 import org.onosproject.pcepio.protocol.PcepLspObject;
25 import org.onosproject.pcepio.protocol.PcepMessageReader;
26 import org.onosproject.pcepio.protocol.PcepMessageWriter;
27 import org.onosproject.pcepio.protocol.PcepMsgPath;
28 import org.onosproject.pcepio.protocol.PcepSrpObject;
29 import org.onosproject.pcepio.protocol.PcepType;
30 import org.onosproject.pcepio.protocol.PcepUpdateMsg;
31 import org.onosproject.pcepio.protocol.PcepUpdateRequest;
32 import org.onosproject.pcepio.protocol.PcepVersion;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 import com.google.common.base.MoreObjects;
39 * Provides PCEP update message.
42 class PcepUpdateMsgVer1 implements PcepUpdateMsg {
46 /* The format of the PCUpd message is as follows:
47 * <PCUpd Message> ::= <Common Header>
48 * <update-request-list>
50 * <update-request-list> ::= <update-request>[<update-request-list>]
51 * <update-request> ::= <SRP>
55 * <path> ::= <ERO><attribute-list>
57 * <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
59 * <attribute-list> ::=[<LSPA>]
63 * <metric-list> ::=<METRIC>[<metric-list>]
66 * 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
67 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68 * | Ver | Flags | Message-Type | Message-Length |
69 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 * // UPDATE REQUEST LIST //
73 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 * Reference:Internet-Draft-PCEP Extensions-for-Stateful-PCE-10
78 protected static final Logger log = LoggerFactory.getLogger(PcepUpdateMsgVer1.class);
80 public static final byte PACKET_VERSION = 1;
81 // UpdateMsgMinLength = SrpObjMinLentgh(12)+LspObjMinLength(8)+EroObjMinLength(12)+ CommonHeaderLength(4)
82 public static final short PACKET_MINIMUM_LENGTH = 36;
83 public static final PcepType MSG_TYPE = PcepType.UPDATE;
85 private LinkedList<PcepUpdateRequest> llUpdateRequestList;
87 public static final PcepUpdateMsgVer1.Reader READER = new Reader();
90 * Reader reads UpdateMessage from the channel.
92 static class Reader implements PcepMessageReader<PcepUpdateMsg> {
94 LinkedList<PcepUpdateRequest> llUpdateRequestList;
97 public PcepUpdateMsg readFrom(ChannelBuffer cb) throws PcepParseException {
99 if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
100 throw new PcepParseException("Readable bytes is less than update message minimum length");
103 llUpdateRequestList = new LinkedList<>();
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);
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);
116 short length = cb.readShort();
117 if (length < PACKET_MINIMUM_LENGTH) {
118 throw new PcepParseException("Wrong length. Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: "
122 log.debug("reading update message of length " + length);
124 // parse Update Request list
125 if (!parseUpdateRequestList(cb)) {
126 throw new PcepParseException("parsing Update Request List Failed.");
129 return new PcepUpdateMsgVer1(llUpdateRequestList);
133 * Parse update request list.
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
139 public boolean parseUpdateRequestList(ChannelBuffer cb) throws PcepParseException {
141 /* <update-request-list>
143 * <update-request-list> ::= <update-request>[<update-request-list>]
144 * <update-request> ::= <SRP>
148 * <path> ::= <ERO><attribute-list>
150 * <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
153 while (0 < cb.readableBytes()) {
155 PcepUpdateRequest pceUpdateReq = new PcepUpdateRequestVer1();
157 //Read SRP Object and Store it.
158 PcepSrpObject srpObj;
159 srpObj = PcepSrpObjectVer1.read(cb);
160 pceUpdateReq.setSrpObject(srpObj);
162 //Read LSP object and Store it.
163 PcepLspObject lspObj;
164 lspObj = PcepLspObjectVer1.read(cb);
165 pceUpdateReq.setLspObject(lspObj);
167 // Read Msg Path and store it.
168 PcepMsgPath msgPath = new PcepMsgPathVer1().read(cb);
169 pceUpdateReq.setMsgPath(msgPath);
171 llUpdateRequestList.add(pceUpdateReq);
178 * Constructor to initialize llUpdateRequestList.
180 * @param llUpdateRequestList list of PcepUpdateRequest.
182 PcepUpdateMsgVer1(LinkedList<PcepUpdateRequest> llUpdateRequestList) {
183 this.llUpdateRequestList = llUpdateRequestList;
187 * Builder class for PCPE update message.
189 static class Builder implements PcepUpdateMsg.Builder {
191 // PCEP report message fields
192 LinkedList<PcepUpdateRequest> llUpdateRequestList;
195 public PcepVersion getVersion() {
196 return PcepVersion.PCEP_1;
200 public PcepType getType() {
201 return PcepType.UPDATE;
205 public PcepUpdateMsg build() {
206 return new PcepUpdateMsgVer1(this.llUpdateRequestList);
210 public LinkedList<PcepUpdateRequest> getUpdateRequestList() {
211 return this.llUpdateRequestList;
215 public Builder setUpdateRequestList(LinkedList<PcepUpdateRequest> llUpdateRequestList) {
216 this.llUpdateRequestList = llUpdateRequestList;
223 public void writeTo(ChannelBuffer cb) throws PcepParseException {
224 WRITER.write(cb, this);
227 static final Writer WRITER = new Writer();
230 * Writer writes UpdateMessage to the channel buffer.
232 static class Writer implements PcepMessageWriter<PcepUpdateMsgVer1> {
235 public void write(ChannelBuffer cb, PcepUpdateMsgVer1 message) throws PcepParseException {
237 int startIndex = cb.writerIndex();
238 // first 3 bits set to version
239 cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
241 cb.writeByte(MSG_TYPE.getType());
242 /* length is length of variable message, will be updated at the end
243 * Store the position of message
246 int msgLenIndex = cb.writerIndex();
248 cb.writeShort((short) 0);
249 ListIterator<PcepUpdateRequest> listIterator = message.llUpdateRequestList.listIterator();
251 while (listIterator.hasNext()) {
253 PcepUpdateRequest updateReq = listIterator.next();
255 //SRP object is mandatory
256 PcepSrpObject srpObj = updateReq.getSrpObject();
259 //LSP object is mandatory
260 PcepLspObject lspObj = updateReq.getLspObject();
263 //PATH object is mandatory
264 PcepMsgPath msgPath = updateReq.getMsgPath();
268 // update message length field
269 int length = cb.writerIndex() - startIndex;
270 cb.setShort(msgLenIndex, (short) length);
275 public PcepVersion getVersion() {
276 return PcepVersion.PCEP_1;
280 public PcepType getType() {
285 public LinkedList<PcepUpdateRequest> getUpdateRequestList() {
286 return this.llUpdateRequestList;
290 public void setUpdateRequestList(LinkedList<PcepUpdateRequest> llUpdateRequestList) {
291 this.llUpdateRequestList = llUpdateRequestList;
295 public String toString() {
296 return MoreObjects.toStringHelper(getClass())
297 .add("UpdateRequestList", llUpdateRequestList)