blob: 85a21d2c02ce9f5b3d4d2eebb4d059b07727eb63 [file] [log] [blame]
Jian Li09596002016-07-15 17:46:49 +09001/*
2 * Copyright 2016-present 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 */
16package org.onosproject.lisp.msg.types;
17
Jian Lia7b394d2016-08-21 23:11:46 +090018import io.netty.buffer.ByteBuf;
19import org.onosproject.lisp.msg.exceptions.LispParseError;
20import org.onosproject.lisp.msg.exceptions.LispReaderException;
GUNiba871702016-08-22 21:06:02 +090021import org.onosproject.lisp.msg.exceptions.LispWriterException;
Jian Lia7b394d2016-08-21 23:11:46 +090022
Jian Li09596002016-07-15 17:46:49 +090023import java.util.Objects;
24
25import static com.google.common.base.MoreObjects.toStringHelper;
Jian Lia7b394d2016-08-21 23:11:46 +090026import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.*;
Jian Li09596002016-07-15 17:46:49 +090027
28/**
29 * LISP Canonical Address Formatted address class.
Jian Lic7e20a52016-07-18 19:03:49 +090030 *
Jian Li8fc2d2f2016-08-08 14:43:53 +090031 * <pre>
32 * {@literal
Jian Lic7e20a52016-07-18 19:03:49 +090033 * 0 1 2 3
34 * 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
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * | AFI = 16387 | Rsvd1 | Flags |
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | Type | Rsvd2 | Length |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li8fc2d2f2016-08-08 14:43:53 +090040 * }</pre>
Jian Li09596002016-07-15 17:46:49 +090041 */
42public class LispLcafAddress extends LispAfiAddress {
43
Jian Lia7b394d2016-08-21 23:11:46 +090044 private final LispCanonicalAddressFormatEnum lcafType;
45 private final byte reserved1;
46 private final byte reserved2;
47 private final byte flag;
48 private final short length;
Jian Li09596002016-07-15 17:46:49 +090049
50 /**
51 * Initializes LCAF address.
52 *
53 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +090054 * @param reserved1 reserved1 field
55 * @param reserved2 reserved2 field
56 * @param flag flag field
57 * @param length length field
Jian Li09596002016-07-15 17:46:49 +090058 */
Jian Lic7e20a52016-07-18 19:03:49 +090059 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090060 byte reserved1, byte reserved2, byte flag, short length) {
Jian Li09596002016-07-15 17:46:49 +090061 super(AddressFamilyIdentifierEnum.LCAF);
62 this.lcafType = lcafType;
Jian Lic7e20a52016-07-18 19:03:49 +090063 this.reserved1 = reserved1;
64 this.reserved2 = reserved2;
65 this.flag = flag;
66 this.length = length;
67 }
68
69 /**
70 * Initializes LCAF address.
71 *
72 * @param lcafType LCAF type
73 * @param reserved2 reserved2 field
74 * @param flag flag field
75 * @param length length field
76 */
77 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090078 byte reserved2, byte flag, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +090079 super(AddressFamilyIdentifierEnum.LCAF);
80 this.lcafType = lcafType;
81 this.reserved2 = reserved2;
82 this.flag = flag;
83 this.length = length;
84 this.reserved1 = 0;
85 }
86
87 /**
88 * Initializes LCAF address.
89 *
90 * @param lcafType LCAF type
91 * @param reserved2 reserved2 field
92 * @param length length field
93 */
94 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090095 byte reserved2, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +090096 super(AddressFamilyIdentifierEnum.LCAF);
97 this.lcafType = lcafType;
98 this.reserved2 = reserved2;
99 this.length = length;
100 this.reserved1 = 0;
101 this.flag = 0;
102 }
103
104 /**
105 * Initializes LCAF address.
106 *
107 * @param lcafType LCAF type
108 * @param reserved2 reserved2 field
109 */
110 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, byte reserved2) {
111 super(AddressFamilyIdentifierEnum.LCAF);
112 this.lcafType = lcafType;
113 this.reserved2 = reserved2;
114 this.reserved1 = 0;
115 this.flag = 0;
116 this.length = 0;
117 }
118
119 /**
120 * Initializes LCAF address.
121 *
122 * @param lcafType LCAF type
Jian Lia7b394d2016-08-21 23:11:46 +0900123 * @param length length field
124 */
125 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, short length) {
126 super(AddressFamilyIdentifierEnum.LCAF);
127 this.lcafType = lcafType;
128 this.reserved1 = 0;
129 this.reserved2 = 0;
130 this.flag = 0;
131 this.length = length;
132 }
133
134 /**
135 * Initializes LCAF address.
136 *
137 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900138 */
139 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType) {
140 super(AddressFamilyIdentifierEnum.LCAF);
141 this.lcafType = lcafType;
142 this.reserved1 = 0;
143 this.reserved2 = 0;
144 this.flag = 0;
145 this.length = 0;
Jian Li09596002016-07-15 17:46:49 +0900146 }
147
148 /**
149 * Obtains LCAF type.
150 *
151 * @return LCAF type
152 */
153 public LispCanonicalAddressFormatEnum getType() {
154 return lcafType;
155 }
156
157 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900158 * Obtains LCAF reserved1 value.
Jian Li09596002016-07-15 17:46:49 +0900159 *
Jian Lic7e20a52016-07-18 19:03:49 +0900160 * @return LCAF reserved1 value
Jian Li09596002016-07-15 17:46:49 +0900161 */
Jian Lic7e20a52016-07-18 19:03:49 +0900162 public byte getReserved1() {
163 return reserved1;
164 }
165
166 /**
167 * Obtains LCAF reserved2 value.
168 *
169 * @return LCAF reserved2 value
170 */
171 public byte getReserved2() {
172 return reserved2;
173 }
174
175 /**
176 * Obtains LCAF flag value.
177 *
178 * @return LCAF flag value
179 */
180 public byte getFlag() {
181 return flag;
182 }
183
184 /**
185 * Obtains LCAF length value.
186 *
187 * @return LCAF length value
188 */
Jian Lia7b394d2016-08-21 23:11:46 +0900189 public short getLength() {
Jian Lic7e20a52016-07-18 19:03:49 +0900190 return length;
Jian Li09596002016-07-15 17:46:49 +0900191 }
192
Jian Lia7b394d2016-08-21 23:11:46 +0900193 /**
194 * Deserializes common fields from byte buffer.
195 *
196 * @param byteBuf byte buffer
197 * @return LispLcafAddress with filled common data fields
198 */
199 public static LispLcafAddress deserializeCommon(ByteBuf byteBuf) {
200
201 // reserved1 -> 8 bits
202 byte reserved1 = (byte) byteBuf.readUnsignedByte();
203
204 // flags -> 8 bits
205 byte flag = (byte) byteBuf.readUnsignedByte();
206
207 // LCAF type -> 8 bits
208 byte lcafType = (byte) byteBuf.readUnsignedByte();
209
210 // reserved2 -> 8bits
211 byte reserved2 = (byte) byteBuf.readUnsignedByte();
212
213 // length -> 16 bits
214 short length = (short) byteBuf.readUnsignedShort();
215
216 return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
217 reserved1, reserved2, flag, length);
218 }
219
GUNiba871702016-08-22 21:06:02 +0900220 /**
221 * Serializes common fields to byte buffer.
222 *
223 * @param byteBuf byte buffer
224 * @param address LISP LCAF address instance
225 */
226 public static void serializeCommon(ByteBuf byteBuf, LispLcafAddress address) {
227 byteBuf.writeByte(address.getReserved1());
228 byteBuf.writeByte(address.getFlag());
229 byteBuf.writeByte(address.getType().getLispCode());
230 byteBuf.writeByte(address.getReserved2());
231 byteBuf.writeShort(address.getLength());
232 }
233
Jian Li09596002016-07-15 17:46:49 +0900234 @Override
235 public int hashCode() {
Jian Lid56f97e2016-07-19 15:48:15 +0900236 return Objects.hash(lcafType, reserved1, reserved2, flag, length);
Jian Li09596002016-07-15 17:46:49 +0900237 }
238
239 @Override
240 public boolean equals(Object obj) {
241 if (this == obj) {
242 return true;
243 }
244
245 if (obj instanceof LispLcafAddress) {
246 final LispLcafAddress other = (LispLcafAddress) obj;
247 return Objects.equals(this.lcafType, other.lcafType) &&
Jian Lic7e20a52016-07-18 19:03:49 +0900248 Objects.equals(this.reserved1, other.reserved1) &&
249 Objects.equals(this.reserved2, other.reserved2) &&
250 Objects.equals(this.flag, other.flag) &&
251 Objects.equals(this.length, other.length);
Jian Li09596002016-07-15 17:46:49 +0900252 }
253 return false;
254 }
255
256 @Override
257 public String toString() {
258 return toStringHelper(this)
259 .add("lcafType", lcafType)
Jian Lic7e20a52016-07-18 19:03:49 +0900260 .add("reserved1", reserved1)
261 .add("reserved2", reserved2)
262 .add("flag", flag)
263 .add("length", length)
Jian Li09596002016-07-15 17:46:49 +0900264 .toString();
265 }
Jian Lia7b394d2016-08-21 23:11:46 +0900266
267 protected static class LcafAddressBuilder<T> {
268
269 protected byte reserved1;
270 protected byte flag;
271 protected byte lcafType;
272 protected byte reserved2;
273 protected short length;
274
275 /**
276 * Sets reserved1 value.
277 *
278 * @param reserved1 reserved1 value
279 * @return LcafAddressBuilder object
280 */
281 public T withReserved1(byte reserved1) {
282 this.reserved1 = reserved1;
283 return (T) this;
284 }
285
286 /**
287 * Sets flag.
288 *
289 * @param flag flag boolean
290 * @return LcafAddressBuilder object
291 */
292 public T withFlag(byte flag) {
293 this.flag = flag;
294 return (T) this;
295 }
296
297 /**
298 * Sets LCAF type.
299 *
300 * @param lcafType LCAF type
301 * @return LcafAddressBuilder object
302 */
303 public T withLcafType(byte lcafType) {
304 this.lcafType = lcafType;
305 return (T) this;
306 }
307
308 /**
309 * Sets reserved2 value.
310 *
311 * @param reserved2 reserved2 value
312 * @return LcafAddressBuilder object
313 */
314 public T withReserved2(byte reserved2) {
315 this.reserved2 = reserved2;
316 return (T) this;
317 }
318
319 /**
320 * Sets length value.
321 *
322 * @param length length value
323 * @return LcafAddressBuilder object
324 */
325 public T withLength(short length) {
326 this.length = length;
327 return (T) this;
328 }
329
330 /**
331 * Builds LispLcafAddress object.
332 *
333 * @return LispLcafAddress instance
334 */
335 public LispLcafAddress build() {
336 return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
337 reserved1, reserved2, flag, length);
338 }
339 }
340
GUNiba871702016-08-22 21:06:02 +0900341 /**
342 * LISP LCAF reader class.
343 */
Jian Lia7b394d2016-08-21 23:11:46 +0900344 public static class LcafAddressReader implements LispAddressReader<LispLcafAddress> {
345
346 private static final int LCAF_TYPE_FIELD_INDEX = 4;
347
348 @Override
349 public LispLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
350
351 int index = byteBuf.readerIndex();
352
353 // LCAF type -> 8 bits
354 byte lcafType = (byte) byteBuf.getUnsignedByte(index + LCAF_TYPE_FIELD_INDEX);
355
356 if (lcafType == APPLICATION_DATA.getLispCode()) {
357 return new LispAppDataLcafAddress.AppDataLcafAddressReader().readFrom(byteBuf);
358 }
359
360 if (lcafType == LIST.getLispCode()) {
361 return new LispListLcafAddress.ListLcafAddressReader().readFrom(byteBuf);
362 }
363
364 if (lcafType == SEGMENT.getLispCode()) {
365 return new LispSegmentLcafAddress.SegmentLcafAddressReader().readFrom(byteBuf);
366 }
367
368 if (lcafType == SOURCE_DEST.getLispCode()) {
369 return new LispSourceDestLcafAddress.SourceDestLcafAddressReader().readFrom(byteBuf);
370 }
371
372 return null;
373 }
374 }
GUNiba871702016-08-22 21:06:02 +0900375
376 /**
377 * LISP LCAF address writer class.
378 */
379 public static class LcafAddressWriter implements LispAddressWriter<LispLcafAddress> {
380
381 @Override
382 public void writeTo(ByteBuf byteBuf, LispLcafAddress address) throws LispWriterException {
383 switch (address.getType()) {
384 case APPLICATION_DATA:
385 new LispAppDataLcafAddress.AppDataLcafAddressWriter().writeTo(byteBuf,
386 (LispAppDataLcafAddress) address);
387 break;
388 case LIST:
389 new LispListLcafAddress.ListLcafAddressWriter().writeTo(byteBuf,
390 (LispListLcafAddress) address);
391 break;
392 case SEGMENT:
393 new LispSegmentLcafAddress.SegmentLcafAddressWriter().writeTo(byteBuf,
394 (LispSegmentLcafAddress) address);
395 break;
396 case SOURCE_DEST:
397 new LispSourceDestLcafAddress.SourceDestLcafAddressWriter().writeTo(byteBuf,
398 (LispSourceDestLcafAddress) address);
399 break;
400 default: break; // TODO: need to log warning message
401 }
402 }
403 }
Jian Li09596002016-07-15 17:46:49 +0900404}