902226e93a9cd167a8c0296eb0d17483e0e4c578
[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 org.jboss.netty.buffer.ChannelBuffer;
20 import org.onosproject.pcepio.exceptions.PcepParseException;
21 import org.onosproject.pcepio.protocol.PcepMessageReader;
22 import org.onosproject.pcepio.protocol.PcepMessageWriter;
23 import org.onosproject.pcepio.protocol.PcepOpenMsg;
24 import org.onosproject.pcepio.protocol.PcepOpenObject;
25 import org.onosproject.pcepio.protocol.PcepType;
26 import org.onosproject.pcepio.protocol.PcepVersion;
27 import org.onosproject.pcepio.types.PcepErrorDetailInfo;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import com.google.common.base.MoreObjects;
32
33 /**
34  * Provides PCEP open message.
35  */
36 public class PcepOpenMsgVer1 implements PcepOpenMsg {
37
38     /*
39      * <Open Message>::= <Common Header> <OPEN>
40      0                   1                   2                   3
41      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
42     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43     | Ver |  Flags  |  Message-Type |       Message-Length          |
44     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45     | Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
46     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47     | Ver |   Flags |   Keepalive   |  DeadTimer    |      SID      |
48     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49     |                                                               |
50     //                       Optional TLVs                         //
51     |                                                               |
52     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53      */
54
55     protected static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class);
56
57     public static final byte PACKET_VERSION = 1;
58     public static final int PACKET_MINIMUM_LENGTH = 12;
59     public static final PcepType MSG_TYPE = PcepType.OPEN;
60     private PcepOpenObject pcepOpenObj;
61
62     public static final PcepOpenMsgVer1.Reader READER = new Reader();
63
64     /**
65      * Constructor to initialize PcepOpenObject.
66      *
67      * @param pcepOpenObj PCEP-OPEN-OBJECT
68      */
69     public PcepOpenMsgVer1(PcepOpenObject pcepOpenObj) {
70         this.pcepOpenObj = pcepOpenObj;
71     }
72
73     @Override
74     public PcepOpenObject getPcepOpenObject() {
75         return this.pcepOpenObj;
76     }
77
78     @Override
79     public void setPcepOpenObject(PcepOpenObject pcepOpenObj) {
80         this.pcepOpenObj = pcepOpenObj;
81     }
82
83     @Override
84     public PcepVersion getVersion() {
85         return PcepVersion.PCEP_1;
86     }
87
88     @Override
89     public PcepType getType() {
90         return MSG_TYPE;
91     }
92
93     /**
94      * Reader class for reading PCEP open message from channel buffer.
95      */
96     public static class Reader implements PcepMessageReader<PcepOpenMsg> {
97
98         @Override
99         public PcepOpenMsg readFrom(ChannelBuffer cb) throws PcepParseException {
100
101             if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
102                 throw new PcepParseException("Packet size is less than the minimum length.");
103             }
104
105             byte version = cb.readByte();
106             version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
107             if (version != PACKET_VERSION) {
108                 log.error("[readFrom] Invalid version: " + version);
109                 throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_1);
110             }
111             // fixed value property type == 1
112             byte type = cb.readByte();
113
114             if (type != MSG_TYPE.getType()) {
115                 log.error("[readFrom] Unexpected type: " + type);
116                 throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_1);
117             }
118             int length = cb.readShort();
119             if (length < PACKET_MINIMUM_LENGTH) {
120                 throw new PcepParseException(
121                         "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length);
122             }
123             return new PcepOpenMsgVer1(PcepOpenObjectVer1.read(cb));
124         }
125     }
126
127     /**
128      * Builder class for PCEP open message.
129      */
130     static class Builder implements PcepOpenMsg.Builder {
131
132         private PcepOpenObject pcepOpenObj;
133
134         @Override
135         public PcepOpenMsg build() throws PcepParseException {
136             if (!(pcepOpenObj instanceof PcepOpenObjectVer1)) {
137                 throw new NullPointerException("PcepOpenObject is null.");
138             }
139             return new PcepOpenMsgVer1(pcepOpenObj);
140         }
141
142         @Override
143         public PcepVersion getVersion() {
144             return PcepVersion.PCEP_1;
145         }
146
147         @Override
148         public PcepType getType() {
149             return PcepType.OPEN;
150         }
151
152         @Override
153         public PcepOpenObject getPcepOpenObj() {
154             return this.pcepOpenObj;
155         }
156
157         @Override
158         public Builder setPcepOpenObj(PcepOpenObject obj) {
159             this.pcepOpenObj = obj;
160             return this;
161         }
162     }
163
164     @Override
165     public void writeTo(ChannelBuffer cb) throws PcepParseException {
166         WRITER.write(cb, this);
167     }
168
169     public static final Writer WRITER = new Writer();
170
171     /**
172      * Writer class for writing PCEP opne message to channel buffer.
173      */
174     public static class Writer implements PcepMessageWriter<PcepOpenMsgVer1> {
175
176         @Override
177         public void write(ChannelBuffer cb, PcepOpenMsgVer1 message) throws PcepParseException {
178             int startIndex = cb.writerIndex();
179             // first 3 bits set to version
180             cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
181             // message type
182             cb.writeByte(MSG_TYPE.getType());
183             // length is length of variable message, will be updated at the end
184             // Store the position of message
185             // length in buffer
186
187             int msgLenIndex = cb.writerIndex();
188             cb.writeShort(0);
189
190             message.getPcepOpenObject().write(cb);
191
192             // update message length field
193             int iLength = cb.writerIndex() - startIndex;
194             cb.setShort(msgLenIndex, (short) iLength);
195         }
196     }
197
198     @Override
199     public String toString() {
200         return MoreObjects.toStringHelper(getClass())
201                 .add("OpenObject", pcepOpenObj)
202                 .toString();
203     }
204 }