Jian Li
Committed by Gerrit Code Review

[ONOS-4718] Initial implementation of LISP control msg deserializer

- Add LispLocatorRecord interface along with
  DefaultLispLocatorRecord class and unit test class
- Add deserialization logic for four LISP control message classes
  and two auxiliary classes
- Add ByteOperator utility to ease the bit access and manipulation
  for byte data type

Change-Id: I68edf6877a0ebb52260296fc556e0690b795a845
Showing 20 changed files with 976 additions and 42 deletions
1 +/*
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 + */
16 +package org.onosproject.lisp.msg.protocols;
17 +
18 +import com.google.common.base.Objects;
19 +import io.netty.buffer.ByteBuf;
20 +import org.onlab.util.ByteOperator;
21 +import org.onosproject.lisp.msg.exceptions.LispParseError;
22 +import org.onosproject.lisp.msg.types.LispAfiAddress;
23 +
24 +import static com.google.common.base.MoreObjects.toStringHelper;
25 +
26 +/**
27 + * Default implementation of LispLocatorRecord.
28 + */
29 +public final class DefaultLispLocatorRecord implements LispLocatorRecord {
30 +
31 + private final byte priority;
32 + private final byte weight;
33 + private final byte multicastPriority;
34 + private final byte multicastWeight;
35 + private final boolean localLocator;
36 + private final boolean rlocProbed;
37 + private final boolean routed;
38 + private final LispAfiAddress locatorAfi;
39 +
40 + /**
41 + * A private constructor that protects object instantiation from external.
42 + *
43 + * @param priority uni-cast priority
44 + * @param weight uni-cast weight
45 + * @param multicastPriority multi-cast priority
46 + * @param multicastWeight multi-cast weight
47 + * @param localLocator local locator flag
48 + * @param rlocProbed RLOC probed flag
49 + * @param routed routed flag
50 + * @param locatorAfi locator AFI
51 + */
52 + private DefaultLispLocatorRecord(byte priority, byte weight, byte multicastPriority,
53 + byte multicastWeight, boolean localLocator, boolean rlocProbed,
54 + boolean routed, LispAfiAddress locatorAfi) {
55 + this.priority = priority;
56 + this.weight = weight;
57 + this.multicastPriority = multicastPriority;
58 + this.multicastWeight = multicastWeight;
59 + this.localLocator = localLocator;
60 + this.rlocProbed = rlocProbed;
61 + this.routed = routed;
62 + this.locatorAfi = locatorAfi;
63 + }
64 +
65 + @Override
66 + public byte getPriority() {
67 + return priority;
68 + }
69 +
70 + @Override
71 + public byte getWeight() {
72 + return weight;
73 + }
74 +
75 + @Override
76 + public byte getMulticastPriority() {
77 + return multicastPriority;
78 + }
79 +
80 + @Override
81 + public byte getMulticastWeight() {
82 + return multicastWeight;
83 + }
84 +
85 + @Override
86 + public boolean isLocalLocator() {
87 + return localLocator;
88 + }
89 +
90 + @Override
91 + public boolean isRlocProbed() {
92 + return rlocProbed;
93 + }
94 +
95 + @Override
96 + public boolean isRouted() {
97 + return routed;
98 + }
99 +
100 + @Override
101 + public LispAfiAddress getLocatorAfi() {
102 + return locatorAfi;
103 + }
104 +
105 + @Override
106 + public void writeTo(ByteBuf byteBuf) {
107 +
108 + }
109 +
110 + @Override
111 + public String toString() {
112 + return toStringHelper(this)
113 + .add("priority", priority)
114 + .add("weight", weight)
115 + .add("multi-cast priority", multicastPriority)
116 + .add("multi-cast weight", multicastWeight)
117 + .add("local locator", localLocator)
118 + .add("RLOC probed", rlocProbed)
119 + .add("routed", routed)
120 + .add("locator AFI", locatorAfi).toString();
121 + }
122 +
123 + @Override
124 + public boolean equals(Object o) {
125 + if (this == o) {
126 + return true;
127 + }
128 + if (o == null || getClass() != o.getClass()) {
129 + return false;
130 + }
131 + DefaultLispLocatorRecord that = (DefaultLispLocatorRecord) o;
132 + return Objects.equal(priority, that.priority) &&
133 + Objects.equal(weight, that.weight) &&
134 + Objects.equal(multicastPriority, that.multicastPriority) &&
135 + Objects.equal(multicastWeight, that.multicastWeight) &&
136 + Objects.equal(localLocator, that.localLocator) &&
137 + Objects.equal(rlocProbed, that.rlocProbed) &&
138 + Objects.equal(routed, that.routed) &&
139 + Objects.equal(locatorAfi, that.locatorAfi);
140 + }
141 +
142 + @Override
143 + public int hashCode() {
144 + return Objects.hashCode(priority, weight, multicastPriority,
145 + multicastWeight, localLocator, rlocProbed, routed, locatorAfi);
146 + }
147 +
148 + public static final class DefaultLocatorRecordBuilder implements LocatorRecordBuilder {
149 +
150 + private byte priority;
151 + private byte weight;
152 + private byte multicastPriority;
153 + private byte multicastWeight;
154 + private boolean localLocator;
155 + private boolean rlocProbed;
156 + private boolean routed;
157 + private LispAfiAddress locatorAfi;
158 +
159 + @Override
160 + public LocatorRecordBuilder withPriority(byte priority) {
161 + this.priority = priority;
162 + return this;
163 + }
164 +
165 + @Override
166 + public LocatorRecordBuilder withWeight(byte weight) {
167 + this.weight = weight;
168 + return this;
169 + }
170 +
171 + @Override
172 + public LocatorRecordBuilder withMulticastPriority(byte priority) {
173 + this.multicastPriority = priority;
174 + return this;
175 + }
176 +
177 + @Override
178 + public LocatorRecordBuilder withMulticastWeight(byte weight) {
179 + this.multicastWeight = weight;
180 + return this;
181 + }
182 +
183 + @Override
184 + public LocatorRecordBuilder withLocalLocator(boolean localLocator) {
185 + this.localLocator = localLocator;
186 + return this;
187 + }
188 +
189 + @Override
190 + public LocatorRecordBuilder withRlocProbed(boolean rlocProbed) {
191 + this.rlocProbed = rlocProbed;
192 + return this;
193 + }
194 +
195 + @Override
196 + public LocatorRecordBuilder withRouted(boolean routed) {
197 + this.routed = routed;
198 + return this;
199 + }
200 +
201 + @Override
202 + public LocatorRecordBuilder withLocatorAfi(LispAfiAddress locatorAfi) {
203 + this.locatorAfi = locatorAfi;
204 + return this;
205 + }
206 +
207 + @Override
208 + public LispLocatorRecord build() {
209 + return new DefaultLispLocatorRecord(priority, weight, multicastPriority,
210 + multicastWeight, localLocator, rlocProbed, routed, locatorAfi);
211 + }
212 + }
213 +
214 + /**
215 + * A LISP message reader for LocatorRecord portion.
216 + */
217 + public static final class LocatorRecordReader implements LispMessageReader<LispLocatorRecord> {
218 +
219 + private static final int SKIP_UNUSED_FLAG_LENGTH = 1;
220 + private static final int LOCAL_LOCATOR_INDEX = 2;
221 + private static final int RLOC_PROBED_INDEX = 1;
222 + private static final int ROUTED_INDEX = 0;
223 +
224 + @Override
225 + public LispLocatorRecord readFrom(ByteBuf byteBuf) throws LispParseError {
226 +
227 + // priority -> 8 bits
228 + byte priority = (byte) byteBuf.readUnsignedByte();
229 +
230 + // weight -> 8 bits
231 + byte weight = (byte) byteBuf.readUnsignedByte();
232 +
233 + // multi-cast priority -> 8 bits
234 + byte multicastPriority = (byte) byteBuf.readUnsignedByte();
235 +
236 + // multi-cast weight -> 8 bits
237 + byte multicastWeight = (byte) byteBuf.readUnsignedByte();
238 +
239 + // let's skip unused flags
240 + byteBuf.skipBytes(SKIP_UNUSED_FLAG_LENGTH);
241 +
242 + byte flags = byteBuf.readByte();
243 +
244 + // local locator flag -> 1 bit
245 + boolean localLocator = ByteOperator.getBit(flags, LOCAL_LOCATOR_INDEX);
246 +
247 + // rloc probe flag -> 1 bit
248 + boolean rlocProbed = ByteOperator.getBit(flags, RLOC_PROBED_INDEX);
249 +
250 + // routed flag -> 1 bit
251 + boolean routed = ByteOperator.getBit(flags, ROUTED_INDEX);
252 +
253 + // TODO: de-serialize ITR-RLOC AFI and address
254 +
255 + return new DefaultLocatorRecordBuilder()
256 + .withPriority(priority)
257 + .withWeight(weight)
258 + .withMulticastPriority(multicastPriority)
259 + .withMulticastWeight(multicastWeight)
260 + .withLocalLocator(localLocator)
261 + .withRlocProbed(rlocProbed)
262 + .withRouted(routed)
263 + .build();
264 + }
265 + }
266 +}
...@@ -131,7 +131,7 @@ public final class DefaultLispMapNotify implements LispMapNotify { ...@@ -131,7 +131,7 @@ public final class DefaultLispMapNotify implements LispMapNotify {
131 private short keyId; 131 private short keyId;
132 private byte[] authenticationData; 132 private byte[] authenticationData;
133 private byte recordCount; 133 private byte recordCount;
134 - private List<LispMapRecord> mapRecords = Lists.newArrayList(); 134 + private List<LispMapRecord> mapRecords;
135 135
136 @Override 136 @Override
137 public LispType getType() { 137 public LispType getType() {
...@@ -163,8 +163,8 @@ public final class DefaultLispMapNotify implements LispMapNotify { ...@@ -163,8 +163,8 @@ public final class DefaultLispMapNotify implements LispMapNotify {
163 } 163 }
164 164
165 @Override 165 @Override
166 - public NotifyBuilder addRecord(LispMapRecord record) { 166 + public NotifyBuilder withMapRecords(List<LispMapRecord> mapRecords) {
167 - this.mapRecords.add(record); 167 + this.mapRecords = ImmutableList.copyOf(mapRecords);
168 return this; 168 return this;
169 } 169 }
170 170
...@@ -180,9 +180,46 @@ public final class DefaultLispMapNotify implements LispMapNotify { ...@@ -180,9 +180,46 @@ public final class DefaultLispMapNotify implements LispMapNotify {
180 */ 180 */
181 private static class NotifyReader implements LispMessageReader<LispMapNotify> { 181 private static class NotifyReader implements LispMessageReader<LispMapNotify> {
182 182
183 + private static final int RESERVED_SKIP_LENGTH = 3;
184 +
183 @Override 185 @Override
184 public LispMapNotify readFrom(ByteBuf byteBuf) throws LispParseError { 186 public LispMapNotify readFrom(ByteBuf byteBuf) throws LispParseError {
185 - return null; 187 +
188 + if (byteBuf.readerIndex() != 0) {
189 + return null;
190 + }
191 +
192 + // skip first three bytes as they represent type and reserved fields
193 + byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
194 +
195 + // record count -> 8 bits
196 + byte recordCount = (byte) byteBuf.readUnsignedByte();
197 +
198 + // nonce -> 64 bits
199 + long nonce = byteBuf.readLong();
200 +
201 + // keyId -> 16 bits
202 + short keyId = byteBuf.readShort();
203 +
204 + // authenticationDataLength -> 16 bits
205 + short authLength = byteBuf.readShort();
206 +
207 + // authenticationData -> depends on the authenticationDataLength
208 + byte[] authData = new byte[authLength];
209 + byteBuf.readBytes(authData);
210 +
211 + List<LispMapRecord> mapRecords = Lists.newArrayList();
212 + for (int i = 0; i < recordCount; i++) {
213 + mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf));
214 + }
215 +
216 + return new DefaultNotifyBuilder()
217 + .withRecordCount(recordCount)
218 + .withNonce(nonce)
219 + .withKeyId(keyId)
220 + .withAuthenticationData(authData)
221 + .withMapRecords(mapRecords)
222 + .build();
186 } 223 }
187 } 224 }
188 } 225 }
......
...@@ -16,10 +16,15 @@ ...@@ -16,10 +16,15 @@
16 package org.onosproject.lisp.msg.protocols; 16 package org.onosproject.lisp.msg.protocols;
17 17
18 import com.google.common.base.Objects; 18 import com.google.common.base.Objects;
19 +import com.google.common.collect.ImmutableList;
20 +import com.google.common.collect.Lists;
19 import io.netty.buffer.ByteBuf; 21 import io.netty.buffer.ByteBuf;
22 +import org.onlab.util.ByteOperator;
20 import org.onosproject.lisp.msg.exceptions.LispParseError; 23 import org.onosproject.lisp.msg.exceptions.LispParseError;
21 import org.onosproject.lisp.msg.types.LispAfiAddress; 24 import org.onosproject.lisp.msg.types.LispAfiAddress;
22 25
26 +import java.util.List;
27 +
23 import static com.google.common.base.MoreObjects.toStringHelper; 28 import static com.google.common.base.MoreObjects.toStringHelper;
24 29
25 /** 30 /**
...@@ -34,6 +39,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { ...@@ -34,6 +39,7 @@ public final class DefaultLispMapRecord implements LispMapRecord {
34 private final boolean authoritative; 39 private final boolean authoritative;
35 private final short mapVersionNumber; 40 private final short mapVersionNumber;
36 private final LispAfiAddress eidPrefixAfi; 41 private final LispAfiAddress eidPrefixAfi;
42 + private final List<LispLocatorRecord> locatorRecords;
37 43
38 /** 44 /**
39 * A private constructor that protects object instantiation from external. 45 * A private constructor that protects object instantiation from external.
...@@ -48,7 +54,8 @@ public final class DefaultLispMapRecord implements LispMapRecord { ...@@ -48,7 +54,8 @@ public final class DefaultLispMapRecord implements LispMapRecord {
48 */ 54 */
49 private DefaultLispMapRecord(int recordTtl, int locatorCount, byte maskLength, 55 private DefaultLispMapRecord(int recordTtl, int locatorCount, byte maskLength,
50 LispMapReplyAction action, boolean authoritative, 56 LispMapReplyAction action, boolean authoritative,
51 - short mapVersionNumber, LispAfiAddress eidPrefixAfi) { 57 + short mapVersionNumber, LispAfiAddress eidPrefixAfi,
58 + List<LispLocatorRecord> locatorRecords) {
52 this.recordTtl = recordTtl; 59 this.recordTtl = recordTtl;
53 this.locatorCount = locatorCount; 60 this.locatorCount = locatorCount;
54 this.maskLength = maskLength; 61 this.maskLength = maskLength;
...@@ -56,6 +63,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { ...@@ -56,6 +63,7 @@ public final class DefaultLispMapRecord implements LispMapRecord {
56 this.authoritative = authoritative; 63 this.authoritative = authoritative;
57 this.mapVersionNumber = mapVersionNumber; 64 this.mapVersionNumber = mapVersionNumber;
58 this.eidPrefixAfi = eidPrefixAfi; 65 this.eidPrefixAfi = eidPrefixAfi;
66 + this.locatorRecords = locatorRecords;
59 } 67 }
60 68
61 @Override 69 @Override
...@@ -94,6 +102,16 @@ public final class DefaultLispMapRecord implements LispMapRecord { ...@@ -94,6 +102,16 @@ public final class DefaultLispMapRecord implements LispMapRecord {
94 } 102 }
95 103
96 @Override 104 @Override
105 + public List<LispLocatorRecord> getLocators() {
106 + return ImmutableList.copyOf(locatorRecords);
107 + }
108 +
109 + @Override
110 + public void writeTo(ByteBuf byteBuf) {
111 +
112 + }
113 +
114 + @Override
97 public String toString() { 115 public String toString() {
98 return toStringHelper(this) 116 return toStringHelper(this)
99 .add("record TTL", recordTtl) 117 .add("record TTL", recordTtl)
...@@ -102,7 +120,9 @@ public final class DefaultLispMapRecord implements LispMapRecord { ...@@ -102,7 +120,9 @@ public final class DefaultLispMapRecord implements LispMapRecord {
102 .add("action", action) 120 .add("action", action)
103 .add("authoritative", authoritative) 121 .add("authoritative", authoritative)
104 .add("mapVersionNumber", mapVersionNumber) 122 .add("mapVersionNumber", mapVersionNumber)
105 - .add("EID prefix AFI address", eidPrefixAfi).toString(); 123 + .add("EID prefix AFI address", eidPrefixAfi)
124 + .add("locator records", locatorRecords).toString();
125 +
106 } 126 }
107 127
108 @Override 128 @Override
...@@ -120,13 +140,14 @@ public final class DefaultLispMapRecord implements LispMapRecord { ...@@ -120,13 +140,14 @@ public final class DefaultLispMapRecord implements LispMapRecord {
120 Objects.equal(action, that.action) && 140 Objects.equal(action, that.action) &&
121 Objects.equal(authoritative, that.authoritative) && 141 Objects.equal(authoritative, that.authoritative) &&
122 Objects.equal(mapVersionNumber, that.mapVersionNumber) && 142 Objects.equal(mapVersionNumber, that.mapVersionNumber) &&
123 - Objects.equal(eidPrefixAfi, that.eidPrefixAfi); 143 + Objects.equal(eidPrefixAfi, that.eidPrefixAfi) &&
144 + Objects.equal(locatorRecords, that.locatorRecords);
124 } 145 }
125 146
126 @Override 147 @Override
127 public int hashCode() { 148 public int hashCode() {
128 return Objects.hashCode(recordTtl, locatorCount, maskLength, action, 149 return Objects.hashCode(recordTtl, locatorCount, maskLength, action,
129 - authoritative, mapVersionNumber, eidPrefixAfi); 150 + authoritative, mapVersionNumber, eidPrefixAfi, locatorRecords);
130 } 151 }
131 152
132 public static final class DefaultMapRecordBuilder implements MapRecordBuilder { 153 public static final class DefaultMapRecordBuilder implements MapRecordBuilder {
...@@ -138,6 +159,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { ...@@ -138,6 +159,7 @@ public final class DefaultLispMapRecord implements LispMapRecord {
138 private boolean authoritative; 159 private boolean authoritative;
139 private short mapVersionNumber; 160 private short mapVersionNumber;
140 private LispAfiAddress eidPrefixAfi; 161 private LispAfiAddress eidPrefixAfi;
162 + private List<LispLocatorRecord> locatorRecords;
141 163
142 @Override 164 @Override
143 public MapRecordBuilder withRecordTtl(int recordTtl) { 165 public MapRecordBuilder withRecordTtl(int recordTtl) {
...@@ -182,20 +204,66 @@ public final class DefaultLispMapRecord implements LispMapRecord { ...@@ -182,20 +204,66 @@ public final class DefaultLispMapRecord implements LispMapRecord {
182 } 204 }
183 205
184 @Override 206 @Override
207 + public MapRecordBuilder withLocators(List<LispLocatorRecord> records) {
208 + this.locatorRecords = ImmutableList.copyOf(records);
209 + return this;
210 + }
211 +
212 + @Override
185 public LispMapRecord build() { 213 public LispMapRecord build() {
186 return new DefaultLispMapRecord(recordTtl, locatorCount, maskLength, 214 return new DefaultLispMapRecord(recordTtl, locatorCount, maskLength,
187 - action, authoritative, mapVersionNumber, eidPrefixAfi); 215 + action, authoritative, mapVersionNumber, eidPrefixAfi, locatorRecords);
188 } 216 }
189 } 217 }
190 218
191 /** 219 /**
192 - * A private LISP message reader for MapRecord portion. 220 + * A LISP message reader for MapRecord portion.
193 */ 221 */
194 - private static class RecordReader implements LispMessageReader<LispMapRecord> { 222 + public static final class MapRecordReader implements LispMessageReader<LispMapRecord> {
223 +
224 + private static final int AUTHORITATIVE_INDEX = 4;
225 + private static final int RESERVED_SKIP_LENGTH = 1;
195 226
196 @Override 227 @Override
197 public LispMapRecord readFrom(ByteBuf byteBuf) throws LispParseError { 228 public LispMapRecord readFrom(ByteBuf byteBuf) throws LispParseError {
198 - return null; 229 +
230 + // Record TTL -> 32 bits
231 + int recordTtl = byteBuf.readInt();
232 +
233 + // Locator count -> 8 bits
234 + int locatorCount = byteBuf.readUnsignedShort();
235 +
236 + // EID mask length -> 8 bits
237 + byte maskLength = (byte) byteBuf.readUnsignedByte();
238 +
239 + // TODO: need to de-serialize LispMapReplyAction
240 +
241 + byte actionWithFlag = byteBuf.readByte();
242 +
243 + // authoritative flag -> 1 bit
244 + boolean authoritative = ByteOperator.getBit(actionWithFlag, AUTHORITATIVE_INDEX);
245 +
246 + // let's skip the reserved field
247 + byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
248 +
249 + // Map version number -> 12 bits, we treat Rsvd field is all zero
250 + short mapVersionNumber = (short) byteBuf.readUnsignedShort();
251 +
252 + // TODO: need to de-serialize EID AFI address
253 +
254 + List<LispLocatorRecord> locators = Lists.newArrayList();
255 + for (int i = 0; i < locatorCount; i++) {
256 + locators.add(new DefaultLispLocatorRecord.LocatorRecordReader().readFrom(byteBuf));
257 + }
258 +
259 + return new DefaultMapRecordBuilder()
260 + .withRecordTtl(recordTtl)
261 + .withLocatorCount(locatorCount)
262 + .withMaskLength(maskLength)
263 + .withAuthoritative(authoritative)
264 + .withMapVersionNumber(mapVersionNumber)
265 + .withLocators(locators)
266 + .build();
199 } 267 }
200 } 268 }
201 } 269 }
......
...@@ -19,6 +19,7 @@ import com.google.common.base.Objects; ...@@ -19,6 +19,7 @@ import com.google.common.base.Objects;
19 import com.google.common.collect.ImmutableList; 19 import com.google.common.collect.ImmutableList;
20 import com.google.common.collect.Lists; 20 import com.google.common.collect.Lists;
21 import io.netty.buffer.ByteBuf; 21 import io.netty.buffer.ByteBuf;
22 +import org.onlab.util.ByteOperator;
22 import org.onlab.util.ImmutableByteSequence; 23 import org.onlab.util.ImmutableByteSequence;
23 import org.onosproject.lisp.msg.exceptions.LispParseError; 24 import org.onosproject.lisp.msg.exceptions.LispParseError;
24 25
...@@ -155,7 +156,7 @@ public final class DefaultLispMapRegister implements LispMapRegister { ...@@ -155,7 +156,7 @@ public final class DefaultLispMapRegister implements LispMapRegister {
155 private short keyId; 156 private short keyId;
156 private byte[] authenticationData; 157 private byte[] authenticationData;
157 private byte recordCount; 158 private byte recordCount;
158 - private final List<LispMapRecord> mapRecords = Lists.newArrayList(); 159 + private List<LispMapRecord> mapRecords;
159 private boolean proxyMapReply; 160 private boolean proxyMapReply;
160 private boolean wantMapNotify; 161 private boolean wantMapNotify;
161 162
...@@ -201,8 +202,8 @@ public final class DefaultLispMapRegister implements LispMapRegister { ...@@ -201,8 +202,8 @@ public final class DefaultLispMapRegister implements LispMapRegister {
201 } 202 }
202 203
203 @Override 204 @Override
204 - public RegisterBuilder addRecord(LispMapRecord record) { 205 + public RegisterBuilder withMapRecords(List<LispMapRecord> mapRecords) {
205 - this.mapRecords.add(record); 206 + this.mapRecords = ImmutableList.copyOf(mapRecords);
206 return this; 207 return this;
207 } 208 }
208 209
...@@ -218,9 +219,58 @@ public final class DefaultLispMapRegister implements LispMapRegister { ...@@ -218,9 +219,58 @@ public final class DefaultLispMapRegister implements LispMapRegister {
218 */ 219 */
219 private static class RegisterReader implements LispMessageReader<LispMapRegister> { 220 private static class RegisterReader implements LispMessageReader<LispMapRegister> {
220 221
222 + private static final int PROXY_MAP_REPLY_INDEX = 3;
223 + private static final int WANT_MAP_NOTIFY_INDEX = 0;
224 + private static final int RESERVED_SKIP_LENGTH = 1;
225 +
221 @Override 226 @Override
222 public LispMapRegister readFrom(ByteBuf byteBuf) throws LispParseError { 227 public LispMapRegister readFrom(ByteBuf byteBuf) throws LispParseError {
223 - return null; 228 +
229 + if (byteBuf.readerIndex() != 0) {
230 + return null;
231 + }
232 +
233 + // proxyMapReply -> 1 bit
234 + boolean proxyMapReplyFlag = ByteOperator.getBit(byteBuf.readByte(), PROXY_MAP_REPLY_INDEX);
235 +
236 + // let's skip the reserved field
237 + byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
238 +
239 + byte reservedWithFlag = byteBuf.readByte();
240 +
241 + // wantMapReply -> 1 bit
242 + boolean wantMapNotifyFlag = ByteOperator.getBit(reservedWithFlag, WANT_MAP_NOTIFY_INDEX);
243 +
244 + // record count -> 8 bits
245 + byte recordCount = (byte) byteBuf.readUnsignedByte();
246 +
247 + // nonce -> 64 bits
248 + long nonce = byteBuf.readLong();
249 +
250 + // keyId -> 16 bits
251 + short keyId = byteBuf.readShort();
252 +
253 + // authenticationDataLength -> 16 bits
254 + short authLength = byteBuf.readShort();
255 +
256 + // authenticationData -> depends on the authenticationDataLength
257 + byte[] authData = new byte[authLength];
258 + byteBuf.readBytes(authData);
259 +
260 + List<LispMapRecord> mapRecords = Lists.newArrayList();
261 + for (int i = 0; i < recordCount; i++) {
262 + mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf));
263 + }
264 +
265 + return new DefaultRegisterBuilder()
266 + .withIsProxyMapReply(proxyMapReplyFlag)
267 + .withIsWantMapNotify(wantMapNotifyFlag)
268 + .withRecordCount(recordCount)
269 + .withNonce(nonce)
270 + .withKeyId(keyId)
271 + .withAuthenticationData(authData)
272 + .withMapRecords(mapRecords)
273 + .build();
224 } 274 }
225 } 275 }
226 } 276 }
......
...@@ -17,6 +17,7 @@ package org.onosproject.lisp.msg.protocols; ...@@ -17,6 +17,7 @@ package org.onosproject.lisp.msg.protocols;
17 17
18 import com.google.common.base.Objects; 18 import com.google.common.base.Objects;
19 import io.netty.buffer.ByteBuf; 19 import io.netty.buffer.ByteBuf;
20 +import org.onlab.util.ByteOperator;
20 import org.onosproject.lisp.msg.exceptions.LispParseError; 21 import org.onosproject.lisp.msg.exceptions.LispParseError;
21 22
22 import static com.google.common.base.MoreObjects.toStringHelper; 23 import static com.google.common.base.MoreObjects.toStringHelper;
...@@ -176,9 +177,47 @@ public final class DefaultLispMapReply implements LispMapReply { ...@@ -176,9 +177,47 @@ public final class DefaultLispMapReply implements LispMapReply {
176 */ 177 */
177 private static class ReplyReader implements LispMessageReader<LispMapReply> { 178 private static class ReplyReader implements LispMessageReader<LispMapReply> {
178 179
180 + private static final int PROBE_INDEX = 3;
181 + private static final int ETR_INDEX = 2;
182 + private static final int SECURITY_INDEX = 1;
183 + private static final int RESERVED_SKIP_LENGTH = 2;
184 +
179 @Override 185 @Override
180 public LispMapReply readFrom(ByteBuf byteBuf) throws LispParseError { 186 public LispMapReply readFrom(ByteBuf byteBuf) throws LispParseError {
181 - return null; 187 +
188 + if (byteBuf.readerIndex() != 0) {
189 + return null;
190 + }
191 +
192 + byte typeWithFlags = byteBuf.readByte();
193 +
194 + // probe -> 1 bit
195 + boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX);
196 +
197 + // etr -> 1bit
198 + boolean etr = ByteOperator.getBit(typeWithFlags, ETR_INDEX);
199 +
200 + // security -> 1 bit
201 + boolean security = ByteOperator.getBit(typeWithFlags, SECURITY_INDEX);
202 +
203 + // skip two bytes as they represent reserved fields
204 + byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
205 +
206 + // record count -> 8 bits
207 + byte recordCount = (byte) byteBuf.readUnsignedByte();
208 +
209 + // nonce -> 64 bits
210 + long nonce = byteBuf.readLong();
211 +
212 + // TODO: need to de-serialize EID-RLOC records
213 +
214 + return new DefaultReplyBuilder()
215 + .withIsProbe(probe)
216 + .withIsEtr(etr)
217 + .withIsSecurity(security)
218 + .withRecordCount(recordCount)
219 + .withNonce(nonce)
220 + .build();
182 } 221 }
183 } 222 }
184 } 223 }
......
...@@ -19,6 +19,7 @@ import com.google.common.base.Objects; ...@@ -19,6 +19,7 @@ import com.google.common.base.Objects;
19 import com.google.common.collect.ImmutableList; 19 import com.google.common.collect.ImmutableList;
20 import com.google.common.collect.Lists; 20 import com.google.common.collect.Lists;
21 import io.netty.buffer.ByteBuf; 21 import io.netty.buffer.ByteBuf;
22 +import org.onlab.util.ByteOperator;
22 import org.onosproject.lisp.msg.exceptions.LispParseError; 23 import org.onosproject.lisp.msg.exceptions.LispParseError;
23 import org.onosproject.lisp.msg.types.LispAfiAddress; 24 import org.onosproject.lisp.msg.types.LispAfiAddress;
24 25
...@@ -227,7 +228,6 @@ public final class DefaultLispMapRequest implements LispMapRequest { ...@@ -227,7 +228,6 @@ public final class DefaultLispMapRequest implements LispMapRequest {
227 return this; 228 return this;
228 } 229 }
229 230
230 -
231 @Override 231 @Override
232 public RequestBuilder withIsSmr(boolean smr) { 232 public RequestBuilder withIsSmr(boolean smr) {
233 this.smr = smr; 233 this.smr = smr;
...@@ -265,14 +265,14 @@ public final class DefaultLispMapRequest implements LispMapRequest { ...@@ -265,14 +265,14 @@ public final class DefaultLispMapRequest implements LispMapRequest {
265 } 265 }
266 266
267 @Override 267 @Override
268 - public RequestBuilder addItrRloc(LispAfiAddress itrRloc) { 268 + public RequestBuilder withItrRlocs(List<LispAfiAddress> itrRlocs) {
269 - this.itrRlocs.add(itrRloc); 269 + this.itrRlocs = ImmutableList.copyOf(itrRlocs);
270 return this; 270 return this;
271 } 271 }
272 272
273 @Override 273 @Override
274 - public RequestBuilder addEidRecord(LispEidRecord record) { 274 + public RequestBuilder withEidRecords(List<LispEidRecord> records) {
275 - this.eidRecords.add(record); 275 + this.eidRecords = ImmutableList.copyOf(records);
276 return this; 276 return this;
277 } 277 }
278 278
...@@ -288,9 +288,69 @@ public final class DefaultLispMapRequest implements LispMapRequest { ...@@ -288,9 +288,69 @@ public final class DefaultLispMapRequest implements LispMapRequest {
288 */ 288 */
289 private static class RequestReader implements LispMessageReader<LispMapRequest> { 289 private static class RequestReader implements LispMessageReader<LispMapRequest> {
290 290
291 + private static final int AUTHORITATIVE_INDEX = 3;
292 + private static final int MAP_DATA_PRESENT_INDEX = 2;
293 + private static final int PROBE_INDEX = 1;
294 + private static final int SMR_INDEX = 0;
295 + private static final int PITR_INDEX = 7;
296 + private static final int SMR_INVOKED_INDEX = 6;
297 +
291 @Override 298 @Override
292 public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError { 299 public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError {
293 - return null; 300 +
301 + if (byteBuf.readerIndex() != 0) {
302 + return null;
303 + }
304 +
305 + byte typeWithFlags = byteBuf.readByte();
306 +
307 + // authoritative -> 1 bit
308 + boolean authoritative = ByteOperator.getBit(typeWithFlags, AUTHORITATIVE_INDEX);
309 +
310 + // mapDataPresent -> 1 bit
311 + boolean mapDataPresent = ByteOperator.getBit(typeWithFlags, MAP_DATA_PRESENT_INDEX);
312 +
313 + // probe -> 1 bit
314 + boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX);
315 +
316 + // smr -> 1 bit
317 + boolean smr = ByteOperator.getBit(typeWithFlags, SMR_INDEX);
318 +
319 + byte reservedWithFlags = byteBuf.readByte();
320 +
321 + // pitr -> 1 bit
322 + boolean pitr = ByteOperator.getBit(reservedWithFlags, PITR_INDEX);
323 +
324 + // smrInvoked -> 1 bit
325 + boolean smrInvoked = ByteOperator.getBit(reservedWithFlags, SMR_INVOKED_INDEX);
326 +
327 + // let's skip reserved field, only obtains ITR counter value
328 + // assume that first 3 bits are all set as 0,
329 + // remain 5 bits represent Itr Rloc Counter (IRC)
330 + int irc = byteBuf.readUnsignedShort();
331 +
332 + // record count -> 8 bits
333 + int recordCount = byteBuf.readUnsignedShort();
334 +
335 + // nonce -> 64 bits
336 + long nonce = byteBuf.readLong();
337 +
338 + // TODO: de-serialize source EID AFI and address
339 +
340 + // TODO: de-serialize ITR-RLOC AFI and address
341 +
342 + // TODO: de-serialize EID-RECORD
343 +
344 + return new DefaultRequestBuilder()
345 + .withIsAuthoritative(authoritative)
346 + .withIsMapDataPresent(mapDataPresent)
347 + .withIsProbe(probe)
348 + .withIsSmr(smr)
349 + .withIsPitr(pitr)
350 + .withIsSmrInvoked(smrInvoked)
351 + .withNonce(nonce)
352 + .withRecordCount((byte) recordCount)
353 + .build();
294 } 354 }
295 } 355 }
296 } 356 }
......
...@@ -61,9 +61,20 @@ public final class LispEidRecord { ...@@ -61,9 +61,20 @@ public final class LispEidRecord {
61 */ 61 */
62 private static class EidRecordReader implements LispMessageReader<LispEidRecord> { 62 private static class EidRecordReader implements LispMessageReader<LispEidRecord> {
63 63
64 + private static final int RESERVED_SKIP_LENGTH = 1;
65 +
64 @Override 66 @Override
65 public LispEidRecord readFrom(ByteBuf byteBuf) throws LispParseError { 67 public LispEidRecord readFrom(ByteBuf byteBuf) throws LispParseError {
66 - return null; 68 +
69 + // let's skip the reserved field
70 + byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
71 +
72 + short maskLength = (short) byteBuf.readUnsignedShort();
73 +
74 + // TODO: need to de-serialize AFI address
75 + LispAfiAddress prefix = null;
76 +
77 + return new LispEidRecord((byte) maskLength, prefix);
67 } 78 }
68 } 79 }
69 } 80 }
......
1 +/*
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 + */
16 +package org.onosproject.lisp.msg.protocols;
17 +
18 +import io.netty.buffer.ByteBuf;
19 +import org.onosproject.lisp.msg.types.LispAfiAddress;
20 +
21 +/**
22 + * LISP locator record section which is part of LISP map record.
23 + */
24 +public interface LispLocatorRecord {
25 +
26 + /**
27 + * Obtains priority value.
28 + *
29 + * @return priority value
30 + */
31 + byte getPriority();
32 +
33 + /**
34 + * Obtains weight value.
35 + *
36 + * @return weight value
37 + */
38 + byte getWeight();
39 +
40 + /**
41 + * Obtains multi-cast priority value.
42 + *
43 + * @return multi-cast priority value
44 + */
45 + byte getMulticastPriority();
46 +
47 + /**
48 + * Obtains multi-cast weight value.
49 + *
50 + * @return multi-cast weight value
51 + */
52 + byte getMulticastWeight();
53 +
54 + /**
55 + * Obtains local locator flag.
56 + *
57 + * @return local locator flag
58 + */
59 + boolean isLocalLocator();
60 +
61 + /**
62 + * Obtains RLOC probed flag.
63 + *
64 + * @return RLOC probed flag
65 + */
66 + boolean isRlocProbed();
67 +
68 + /**
69 + * Obtains routed flag.
70 + *
71 + * @return routed flag
72 + */
73 + boolean isRouted();
74 +
75 + /**
76 + * Obtains locator AFI.
77 + *
78 + * @return locator AFI
79 + */
80 + LispAfiAddress getLocatorAfi();
81 +
82 + /**
83 + * Writes LISP message object into communication channel.
84 + *
85 + * @param byteBuf byte buffer
86 + */
87 + void writeTo(ByteBuf byteBuf);
88 +
89 + /**
90 + * A builder of LISP locator record.
91 + */
92 + interface LocatorRecordBuilder {
93 +
94 + /**
95 + * Sets priority value.
96 + *
97 + * @param priority priority
98 + * @return LocatorRecordBuilder object
99 + */
100 + LocatorRecordBuilder withPriority(byte priority);
101 +
102 + /**
103 + * Sets weight value.
104 + *
105 + * @param weight weight
106 + * @return LocatorRecordBuilder object
107 + */
108 + LocatorRecordBuilder withWeight(byte weight);
109 +
110 + /**
111 + * Sets multi-cast priority value.
112 + *
113 + * @param priority priority
114 + * @return LocatorRecordBuilder object
115 + */
116 + LocatorRecordBuilder withMulticastPriority(byte priority);
117 +
118 + /**
119 + * Sets multi-cast weight value.
120 + *
121 + * @param weight weight
122 + * @return LocatorRecordBuilder object
123 + */
124 + LocatorRecordBuilder withMulticastWeight(byte weight);
125 +
126 + /**
127 + * Sets local locator flag.
128 + *
129 + * @param localLocator local locator flag
130 + * @return LocatorRecordBuilder object
131 + */
132 + LocatorRecordBuilder withLocalLocator(boolean localLocator);
133 +
134 + /**
135 + * Sets RLOC probed flag.
136 + *
137 + * @param rlocProbed RLOC probed flag
138 + * @return LocatorRecordBuilder object
139 + */
140 + LocatorRecordBuilder withRlocProbed(boolean rlocProbed);
141 +
142 + /**
143 + * Sets routed flag.
144 + *
145 + * @param routed routed flag
146 + * @return LocatorRecordBuilder object
147 + */
148 + LocatorRecordBuilder withRouted(boolean routed);
149 +
150 + /**
151 + * Sets locator AFI.
152 + *
153 + * @param locatorAfi locator AFI
154 + * @return LocatorRecordBuilder object
155 + */
156 + LocatorRecordBuilder withLocatorAfi(LispAfiAddress locatorAfi);
157 +
158 + /**
159 + * Builds locator record.
160 + *
161 + * @return locator record instance
162 + */
163 + LispLocatorRecord build();
164 + }
165 +}
...@@ -129,12 +129,12 @@ public interface LispMapNotify extends LispMessage { ...@@ -129,12 +129,12 @@ public interface LispMapNotify extends LispMessage {
129 NotifyBuilder withAuthenticationData(byte[] authenticationData); 129 NotifyBuilder withAuthenticationData(byte[] authenticationData);
130 130
131 /** 131 /**
132 - * Adds a new record to record list. 132 + * Sets a collection of map records.
133 * 133 *
134 - * @param record record 134 + * @param mapRecords a collection of map records
135 - * @return NotifyBuilder object 135 + * @return RegisterBuilder object
136 */ 136 */
137 - NotifyBuilder addRecord(LispMapRecord record); 137 + NotifyBuilder withMapRecords(List<LispMapRecord> mapRecords);
138 138
139 /** 139 /**
140 * Builds LISP map notify message. 140 * Builds LISP map notify message.
......
...@@ -15,8 +15,11 @@ ...@@ -15,8 +15,11 @@
15 */ 15 */
16 package org.onosproject.lisp.msg.protocols; 16 package org.onosproject.lisp.msg.protocols;
17 17
18 +import io.netty.buffer.ByteBuf;
18 import org.onosproject.lisp.msg.types.LispAfiAddress; 19 import org.onosproject.lisp.msg.types.LispAfiAddress;
19 20
21 +import java.util.List;
22 +
20 /** 23 /**
21 * LISP record section which is part of LISP map register message. 24 * LISP record section which is part of LISP map register message.
22 */ 25 */
...@@ -72,6 +75,20 @@ public interface LispMapRecord { ...@@ -72,6 +75,20 @@ public interface LispMapRecord {
72 LispAfiAddress getEidPrefixAfi(); 75 LispAfiAddress getEidPrefixAfi();
73 76
74 /** 77 /**
78 + * Obtains a collection of locator records.
79 + *
80 + * @return a collection of locator records
81 + */
82 + List<LispLocatorRecord> getLocators();
83 +
84 + /**
85 + * Writes LISP message object into communication channel.
86 + *
87 + * @param byteBuf byte buffer
88 + */
89 + void writeTo(ByteBuf byteBuf);
90 +
91 + /**
75 * A builder of LISP map record. 92 * A builder of LISP map record.
76 */ 93 */
77 interface MapRecordBuilder { 94 interface MapRecordBuilder {
...@@ -133,6 +150,14 @@ public interface LispMapRecord { ...@@ -133,6 +150,14 @@ public interface LispMapRecord {
133 MapRecordBuilder withEidPrefixAfi(LispAfiAddress prefix); 150 MapRecordBuilder withEidPrefixAfi(LispAfiAddress prefix);
134 151
135 /** 152 /**
153 + * Sets a collection of locator records.
154 + *
155 + * @param records a collection of locator records
156 + * @return MapRecordBuilder object
157 + */
158 + MapRecordBuilder withLocators(List<LispLocatorRecord> records);
159 +
160 + /**
136 * Builds map record. 161 * Builds map record.
137 * 162 *
138 * @return map record instance 163 * @return map record instance
......
...@@ -159,12 +159,12 @@ public interface LispMapRegister extends LispMessage { ...@@ -159,12 +159,12 @@ public interface LispMapRegister extends LispMessage {
159 RegisterBuilder withAuthenticationData(byte[] authenticationData); 159 RegisterBuilder withAuthenticationData(byte[] authenticationData);
160 160
161 /** 161 /**
162 - * Adds a new record to record list. 162 + * Sets a collection of map records.
163 * 163 *
164 - * @param record record 164 + * @param mapRecords a collection of map records
165 * @return RegisterBuilder object 165 * @return RegisterBuilder object
166 */ 166 */
167 - RegisterBuilder addRecord(LispMapRecord record); 167 + RegisterBuilder withMapRecords(List<LispMapRecord> mapRecords);
168 168
169 /** 169 /**
170 * Builds LISP map register message. 170 * Builds LISP map register message.
......
...@@ -210,20 +210,20 @@ public interface LispMapRequest extends LispMessage { ...@@ -210,20 +210,20 @@ public interface LispMapRequest extends LispMessage {
210 RequestBuilder withSourceEid(LispAfiAddress sourceEid); 210 RequestBuilder withSourceEid(LispAfiAddress sourceEid);
211 211
212 /** 212 /**
213 - * Adds ITR RLOC into RLOC collection. 213 + * Sets a collection of ITR RLOCs.
214 * 214 *
215 - * @param itrRloc ITR RLOC 215 + * @param itrRlocs a collection of ITR RLOCs
216 * @return RequestBuilder object 216 * @return RequestBuilder object
217 */ 217 */
218 - RequestBuilder addItrRloc(LispAfiAddress itrRloc); 218 + RequestBuilder withItrRlocs(List<LispAfiAddress> itrRlocs);
219 219
220 /** 220 /**
221 - * Adds EID record into record collection. 221 + * Sets a collection of EID records.
222 * 222 *
223 - * @param record EID record 223 + * @param records a collection of EID records
224 * @return RequestBuilder object 224 * @return RequestBuilder object
225 */ 225 */
226 - RequestBuilder addEidRecord(LispEidRecord record); 226 + RequestBuilder withEidRecords(List<LispEidRecord> records);
227 227
228 /** 228 /**
229 * Builds LISP map request message. 229 * Builds LISP map request message.
......
1 +/*
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 + */
16 +package org.onosproject.lisp.msg.protocols;
17 +
18 +import com.google.common.testing.EqualsTester;
19 +import org.junit.Before;
20 +import org.junit.Test;
21 +
22 +import static org.hamcrest.MatcherAssert.assertThat;
23 +import static org.hamcrest.Matchers.is;
24 +
25 +/**
26 + * Unit tests for DefaultLispLocatorRecord class.
27 + */
28 +public final class DefaultLispLocatorRecordTest {
29 +
30 + private LispLocatorRecord record1;
31 + private LispLocatorRecord sameAsRecord1;
32 + private LispLocatorRecord record2;
33 +
34 + @Before
35 + public void setup() {
36 +
37 + LispLocatorRecord.LocatorRecordBuilder builder1 =
38 + new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder();
39 +
40 + record1 = builder1
41 + .withPriority((byte) 0x01)
42 + .withWeight((byte) 0x01)
43 + .withMulticastPriority((byte) 0x01)
44 + .withMulticastWeight((byte) 0x01)
45 + .withLocalLocator(true)
46 + .withRlocProbed(false)
47 + .withRouted(true)
48 + .build();
49 +
50 + LispLocatorRecord.LocatorRecordBuilder builder2 =
51 + new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder();
52 +
53 + sameAsRecord1 = builder2
54 + .withPriority((byte) 0x01)
55 + .withWeight((byte) 0x01)
56 + .withMulticastPriority((byte) 0x01)
57 + .withMulticastWeight((byte) 0x01)
58 + .withLocalLocator(true)
59 + .withRlocProbed(false)
60 + .withRouted(true)
61 + .build();
62 +
63 + LispLocatorRecord.LocatorRecordBuilder builder3 =
64 + new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder();
65 +
66 + record2 = builder3
67 + .withPriority((byte) 0x02)
68 + .withWeight((byte) 0x02)
69 + .withMulticastPriority((byte) 0x02)
70 + .withMulticastWeight((byte) 0x02)
71 + .withLocalLocator(false)
72 + .withRlocProbed(true)
73 + .withRouted(false)
74 + .build();
75 + }
76 +
77 + @Test
78 + public void testEquality() {
79 + new EqualsTester()
80 + .addEqualityGroup(record1, sameAsRecord1)
81 + .addEqualityGroup(record2).testEquals();
82 + }
83 +
84 + @Test
85 + public void testConstruction() {
86 + DefaultLispLocatorRecord record = (DefaultLispLocatorRecord) record1;
87 +
88 + assertThat(record.getPriority(), is((byte) 0x01));
89 + assertThat(record.getWeight(), is((byte) 0x01));
90 + assertThat(record.getMulticastPriority(), is((byte) 0x01));
91 + assertThat(record.getMulticastWeight(), is((byte) 0x01));
92 + assertThat(record.isLocalLocator(), is(true));
93 + assertThat(record.isRlocProbed(), is(false));
94 + assertThat(record.isRouted(), is(true));
95 + }
96 +}
...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; ...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is;
25 /** 25 /**
26 * Unit tests for DefaultLispMapNotify class. 26 * Unit tests for DefaultLispMapNotify class.
27 */ 27 */
28 -public class DefaultLispMapNotifyTest { 28 +public final class DefaultLispMapNotifyTest {
29 29
30 private LispMapNotify notify1; 30 private LispMapNotify notify1;
31 private LispMapNotify sameAsNotify1; 31 private LispMapNotify sameAsNotify1;
......
...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; ...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is;
25 /** 25 /**
26 * Unit tests for DefaultLispMapRecord class. 26 * Unit tests for DefaultLispMapRecord class.
27 */ 27 */
28 -public class DefaultLispMapRecordTest { 28 +public final class DefaultLispMapRecordTest {
29 29
30 private LispMapRecord record1; 30 private LispMapRecord record1;
31 private LispMapRecord sameAsRecord1; 31 private LispMapRecord sameAsRecord1;
......
...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; ...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is;
25 /** 25 /**
26 * Unit tests for DefaultLispMapRegister class. 26 * Unit tests for DefaultLispMapRegister class.
27 */ 27 */
28 -public class DefaultLispMapRegisterTest { 28 +public final class DefaultLispMapRegisterTest {
29 29
30 private LispMapRegister register1; 30 private LispMapRegister register1;
31 private LispMapRegister sameAsRegister1; 31 private LispMapRegister sameAsRegister1;
......
...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; ...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is;
25 /** 25 /**
26 * Unit tests for DefaultLispMapReply class. 26 * Unit tests for DefaultLispMapReply class.
27 */ 27 */
28 -public class DefaultLispMapReplyTest { 28 +public final class DefaultLispMapReplyTest {
29 29
30 private LispMapReply reply1; 30 private LispMapReply reply1;
31 private LispMapReply sameAsReply1; 31 private LispMapReply sameAsReply1;
......
...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; ...@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is;
25 /** 25 /**
26 * Unit tests for DefaultLispMapRequest class. 26 * Unit tests for DefaultLispMapRequest class.
27 */ 27 */
28 -public class DefaultLispMapRequestTest { 28 +public final class DefaultLispMapRequestTest {
29 29
30 private LispMapRequest request1; 30 private LispMapRequest request1;
31 private LispMapRequest sameAsRequest1; 31 private LispMapRequest sameAsRequest1;
......
1 +/*
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 + */
16 +package org.onlab.util;
17 +
18 +/**
19 + * Provide a set of byte operations.
20 + */
21 +public final class ByteOperator {
22 +
23 + /**
24 + * Private constructor which prevents from external instantiation.
25 + */
26 + private ByteOperator() {
27 +
28 + }
29 +
30 + /**
31 + * Obtains a specific bit value from a byte with given index number.
32 + *
33 + * @param value byte value
34 + * @param index index number
35 + * @return a specific bit value from a byte
36 + */
37 + public static boolean getBit(byte value, int index) {
38 + // the length of byte should always be positive whiles less than 8
39 + if (index > 7 || index < 0) {
40 + return false;
41 + }
42 +
43 + int bitMask = getHex((int) Math.pow(2, index));
44 + return (value & bitMask) == bitMask;
45 + }
46 +
47 + /**
48 + * Converts boolean value into bit.
49 + *
50 + * @param value boolean value
51 + * @param bit bit value
52 + * @return converted bit value
53 + */
54 + public static byte toBit(boolean value, int bit) {
55 + return (byte) (value ? bit : 0x00);
56 + }
57 +
58 + /**
59 + * Convert decimal integer into hex integer.
60 + *
61 + * @param decimal decimal formatted integer
62 + * @return hex formatted integer
63 + */
64 + private static int getHex(int decimal) {
65 + return Integer.valueOf(String.valueOf(decimal), 16);
66 + }
67 +}
1 +/*
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 + */
16 +package org.onlab.util;
17 +
18 +import org.junit.Test;
19 +
20 +import static org.hamcrest.Matchers.is;
21 +import static org.junit.Assert.assertThat;
22 +
23 +/**
24 + * Unit tests for ByteOperator.
25 + */
26 +public class ByteOperatorTest {
27 +
28 + @Test
29 + public void testGetBit() {
30 + byte eight = 0x08;
31 + assertThat(ByteOperator.getBit(eight, 0), is(false));
32 + assertThat(ByteOperator.getBit(eight, 1), is(false));
33 + assertThat(ByteOperator.getBit(eight, 2), is(false));
34 + assertThat(ByteOperator.getBit(eight, 3), is(true));
35 + assertThat(ByteOperator.getBit(eight, 4), is(false));
36 + assertThat(ByteOperator.getBit(eight, 5), is(false));
37 + assertThat(ByteOperator.getBit(eight, 6), is(false));
38 + assertThat(ByteOperator.getBit(eight, 7), is(false));
39 +
40 + byte one = 0x01;
41 + assertThat(ByteOperator.getBit(one, 0), is(true));
42 + assertThat(ByteOperator.getBit(one, 1), is(false));
43 + assertThat(ByteOperator.getBit(one, 2), is(false));
44 + assertThat(ByteOperator.getBit(one, 3), is(false));
45 + assertThat(ByteOperator.getBit(one, 4), is(false));
46 + assertThat(ByteOperator.getBit(one, 5), is(false));
47 + assertThat(ByteOperator.getBit(one, 6), is(false));
48 + assertThat(ByteOperator.getBit(one, 7), is(false));
49 + }
50 +}