89347f42f662870d4d9f99c3d4b1d5f0de39c412
[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.PcepLabelUpdate;
25 import org.onosproject.pcepio.protocol.PcepLabelUpdateMsg;
26 import org.onosproject.pcepio.protocol.PcepMessageReader;
27 import org.onosproject.pcepio.protocol.PcepMessageWriter;
28 import org.onosproject.pcepio.protocol.PcepType;
29 import org.onosproject.pcepio.protocol.PcepVersion;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import com.google.common.base.MoreObjects;
34
35 /**
36  * Provides PCEP lable update message.
37  */
38 class PcepLabelUpdateMsgVer1 implements PcepLabelUpdateMsg {
39
40     // Pcep version: 1
41
42     /*
43       The format of the PCLabelUpd message:
44
45                   <PCLabelUpd Message>         ::=     <Common Header>
46                                                        <pce-label-update-list>
47                 Where:
48
49                 <pce-label-update-list>        ::=     <pce-label-update>
50                                                        [<pce-label-update-list>]
51                 <pce-label-update>             ::=     (<pce-label-download>|<pce-label-map>)
52
53                 Where:
54                 <pce-label-download>           ::=      <SRP>
55                                                         <LSP>
56                                                         <label-list>
57
58                 <pce-label-map>                 ::=     <SRP>
59                                                         <LABEL>
60                                                         <FEC>
61
62                 <label-list >                   ::=     <LABEL>
63                                                         [<label-list>]
64
65      */
66     protected static final Logger log = LoggerFactory.getLogger(PcepLabelUpdateMsgVer1.class);
67
68     public static final byte PACKET_VERSION = 1;
69
70     //LabelUpdateMsgMinLength = COMMON-HEADER(4)+SrpObjMinLentgh(12)+LabelObjectMinLength(12)+FECType1Object(8)
71     public static final int PACKET_MINIMUM_LENGTH = 36;
72     public static final PcepType MSG_TYPE = PcepType.LABEL_UPDATE;
73     //pce-label-update-list
74     private LinkedList<PcepLabelUpdate> llPcLabelUpdateList;
75
76     static final PcepLabelUpdateMsgVer1.Reader READER = new Reader();
77
78     /**
79      * Reader reads LabelUpdate Message from the channel.
80      */
81     static class Reader implements PcepMessageReader<PcepLabelUpdateMsg> {
82
83         @Override
84         public PcepLabelUpdateMsg readFrom(ChannelBuffer cb) throws PcepParseException {
85
86             if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
87                 throw new PcepParseException("Readable bytes are less than Packet minimum length.");
88             }
89
90             // fixed value property version == 1
91             byte version = cb.readByte();
92             version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
93             if (version != PACKET_VERSION) {
94                 throw new PcepParseException("Wrong version.Expected=PcepVersion.PCEP_1(1), got=" + version);
95             }
96             // fixed value property type == 13
97             byte type = cb.readByte();
98             if (type != MSG_TYPE.getType()) {
99                 throw new PcepParseException("Wrong type. Expected=PcepType.LABEL_UPDATE(13), got=" + type);
100             }
101             short length = cb.readShort();
102             if (length < PACKET_MINIMUM_LENGTH) {
103                 throw new PcepParseException("Wrong length. Expected to be >= " + PACKET_MINIMUM_LENGTH + ", is: "
104                         + length);
105             }
106             // parse <pce-label-download> / <pce-label-map>
107             LinkedList<PcepLabelUpdate> llPcLabelUpdateList = parsePcLabelUpdateList(cb);
108             return new PcepLabelUpdateMsgVer1(llPcLabelUpdateList);
109         }
110
111         /**
112          * Returns list of PCEP Label Update object.
113          *
114          * @param cb of type channel buffer
115          * @return llPcLabelUpdateList list of PCEP label update object
116          * @throws PcepParseException when fails to parse list of PCEP label update object
117          */
118         public LinkedList<PcepLabelUpdate> parsePcLabelUpdateList(ChannelBuffer cb) throws PcepParseException {
119
120             LinkedList<PcepLabelUpdate> llPcLabelUpdateList;
121             llPcLabelUpdateList = new LinkedList<>();
122
123             while (0 < cb.readableBytes()) {
124                 llPcLabelUpdateList.add(PcepLabelUpdateVer1.read(cb));
125             }
126             return llPcLabelUpdateList;
127         }
128     }
129
130     /**
131      * Constructor to initialize PCEP Label Update List.
132      *
133      * @param llPcLabelUpdateList list of PCEP Label Update object
134      */
135     PcepLabelUpdateMsgVer1(LinkedList<PcepLabelUpdate> llPcLabelUpdateList) {
136         this.llPcLabelUpdateList = llPcLabelUpdateList;
137     }
138
139     /**
140      * Builder class for PCEP label update message.
141      */
142     static class Builder implements PcepLabelUpdateMsg.Builder {
143
144         LinkedList<PcepLabelUpdate> llPcLabelUpdateList;
145
146         @Override
147         public PcepVersion getVersion() {
148             return PcepVersion.PCEP_1;
149         }
150
151         @Override
152         public PcepType getType() {
153             return PcepType.LABEL_UPDATE;
154         }
155
156         @Override
157         public PcepLabelUpdateMsg build() {
158             return new PcepLabelUpdateMsgVer1(this.llPcLabelUpdateList);
159         }
160
161         @Override
162         public LinkedList<PcepLabelUpdate> getPcLabelUpdateList() {
163             return this.llPcLabelUpdateList;
164         }
165
166         @Override
167         public Builder setPcLabelUpdateList(LinkedList<PcepLabelUpdate> ll) {
168             this.llPcLabelUpdateList = ll;
169             return this;
170         }
171     }
172
173     @Override
174     public void writeTo(ChannelBuffer cb) throws PcepParseException {
175         WRITER.write(cb, this);
176     }
177
178     static final Writer WRITER = new Writer();
179
180     /**
181      * Writer writes LabelUpdate Message to the channel.
182      */
183     static class Writer implements PcepMessageWriter<PcepLabelUpdateMsgVer1> {
184
185         @Override
186         public void write(ChannelBuffer cb, PcepLabelUpdateMsgVer1 message) throws PcepParseException {
187
188             int startIndex = cb.writerIndex();
189
190             // first 3 bits set to version
191             cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
192
193             // message type
194             cb.writeByte(MSG_TYPE.getType());
195
196             // Length will be set after calculating length, but currently set it as 0.
197             int msgLenIndex = cb.writerIndex();
198
199             cb.writeShort((short) 0);
200             ListIterator<PcepLabelUpdate> listIterator = message.llPcLabelUpdateList.listIterator();
201
202             while (listIterator.hasNext()) {
203                 PcepLabelUpdate labelUpdate = listIterator.next();
204                 labelUpdate.write(cb);
205             }
206
207             // update message length field
208             int length = cb.writerIndex() - startIndex;
209             cb.setShort(msgLenIndex, (short) length);
210         }
211     }
212
213     @Override
214     public PcepVersion getVersion() {
215         return PcepVersion.PCEP_1;
216     }
217
218     @Override
219     public PcepType getType() {
220         return MSG_TYPE;
221     }
222
223     @Override
224     public LinkedList<PcepLabelUpdate> getPcLabelUpdateList() {
225         return this.llPcLabelUpdateList;
226     }
227
228     @Override
229     public void setPcLabelUpdateList(LinkedList<PcepLabelUpdate> ll) {
230         this.llPcLabelUpdateList = ll;
231     }
232
233     @Override
234     public String toString() {
235         return MoreObjects.toStringHelper(getClass())
236                 .add("PcLabelUpdateList", llPcLabelUpdateList)
237                 .toString();
238     }
239 }