[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
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecord.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecord.java
new file mode 100644
index 0000000..29ad1bd
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecord.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.lisp.msg.protocols;
+
+import com.google.common.base.Objects;
+import io.netty.buffer.ByteBuf;
+import org.onlab.util.ByteOperator;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.types.LispAfiAddress;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default implementation of LispLocatorRecord.
+ */
+public final class DefaultLispLocatorRecord implements LispLocatorRecord {
+
+ private final byte priority;
+ private final byte weight;
+ private final byte multicastPriority;
+ private final byte multicastWeight;
+ private final boolean localLocator;
+ private final boolean rlocProbed;
+ private final boolean routed;
+ private final LispAfiAddress locatorAfi;
+
+ /**
+ * A private constructor that protects object instantiation from external.
+ *
+ * @param priority uni-cast priority
+ * @param weight uni-cast weight
+ * @param multicastPriority multi-cast priority
+ * @param multicastWeight multi-cast weight
+ * @param localLocator local locator flag
+ * @param rlocProbed RLOC probed flag
+ * @param routed routed flag
+ * @param locatorAfi locator AFI
+ */
+ private DefaultLispLocatorRecord(byte priority, byte weight, byte multicastPriority,
+ byte multicastWeight, boolean localLocator, boolean rlocProbed,
+ boolean routed, LispAfiAddress locatorAfi) {
+ this.priority = priority;
+ this.weight = weight;
+ this.multicastPriority = multicastPriority;
+ this.multicastWeight = multicastWeight;
+ this.localLocator = localLocator;
+ this.rlocProbed = rlocProbed;
+ this.routed = routed;
+ this.locatorAfi = locatorAfi;
+ }
+
+ @Override
+ public byte getPriority() {
+ return priority;
+ }
+
+ @Override
+ public byte getWeight() {
+ return weight;
+ }
+
+ @Override
+ public byte getMulticastPriority() {
+ return multicastPriority;
+ }
+
+ @Override
+ public byte getMulticastWeight() {
+ return multicastWeight;
+ }
+
+ @Override
+ public boolean isLocalLocator() {
+ return localLocator;
+ }
+
+ @Override
+ public boolean isRlocProbed() {
+ return rlocProbed;
+ }
+
+ @Override
+ public boolean isRouted() {
+ return routed;
+ }
+
+ @Override
+ public LispAfiAddress getLocatorAfi() {
+ return locatorAfi;
+ }
+
+ @Override
+ public void writeTo(ByteBuf byteBuf) {
+
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("priority", priority)
+ .add("weight", weight)
+ .add("multi-cast priority", multicastPriority)
+ .add("multi-cast weight", multicastWeight)
+ .add("local locator", localLocator)
+ .add("RLOC probed", rlocProbed)
+ .add("routed", routed)
+ .add("locator AFI", locatorAfi).toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ DefaultLispLocatorRecord that = (DefaultLispLocatorRecord) o;
+ return Objects.equal(priority, that.priority) &&
+ Objects.equal(weight, that.weight) &&
+ Objects.equal(multicastPriority, that.multicastPriority) &&
+ Objects.equal(multicastWeight, that.multicastWeight) &&
+ Objects.equal(localLocator, that.localLocator) &&
+ Objects.equal(rlocProbed, that.rlocProbed) &&
+ Objects.equal(routed, that.routed) &&
+ Objects.equal(locatorAfi, that.locatorAfi);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(priority, weight, multicastPriority,
+ multicastWeight, localLocator, rlocProbed, routed, locatorAfi);
+ }
+
+ public static final class DefaultLocatorRecordBuilder implements LocatorRecordBuilder {
+
+ private byte priority;
+ private byte weight;
+ private byte multicastPriority;
+ private byte multicastWeight;
+ private boolean localLocator;
+ private boolean rlocProbed;
+ private boolean routed;
+ private LispAfiAddress locatorAfi;
+
+ @Override
+ public LocatorRecordBuilder withPriority(byte priority) {
+ this.priority = priority;
+ return this;
+ }
+
+ @Override
+ public LocatorRecordBuilder withWeight(byte weight) {
+ this.weight = weight;
+ return this;
+ }
+
+ @Override
+ public LocatorRecordBuilder withMulticastPriority(byte priority) {
+ this.multicastPriority = priority;
+ return this;
+ }
+
+ @Override
+ public LocatorRecordBuilder withMulticastWeight(byte weight) {
+ this.multicastWeight = weight;
+ return this;
+ }
+
+ @Override
+ public LocatorRecordBuilder withLocalLocator(boolean localLocator) {
+ this.localLocator = localLocator;
+ return this;
+ }
+
+ @Override
+ public LocatorRecordBuilder withRlocProbed(boolean rlocProbed) {
+ this.rlocProbed = rlocProbed;
+ return this;
+ }
+
+ @Override
+ public LocatorRecordBuilder withRouted(boolean routed) {
+ this.routed = routed;
+ return this;
+ }
+
+ @Override
+ public LocatorRecordBuilder withLocatorAfi(LispAfiAddress locatorAfi) {
+ this.locatorAfi = locatorAfi;
+ return this;
+ }
+
+ @Override
+ public LispLocatorRecord build() {
+ return new DefaultLispLocatorRecord(priority, weight, multicastPriority,
+ multicastWeight, localLocator, rlocProbed, routed, locatorAfi);
+ }
+ }
+
+ /**
+ * A LISP message reader for LocatorRecord portion.
+ */
+ public static final class LocatorRecordReader implements LispMessageReader<LispLocatorRecord> {
+
+ private static final int SKIP_UNUSED_FLAG_LENGTH = 1;
+ private static final int LOCAL_LOCATOR_INDEX = 2;
+ private static final int RLOC_PROBED_INDEX = 1;
+ private static final int ROUTED_INDEX = 0;
+
+ @Override
+ public LispLocatorRecord readFrom(ByteBuf byteBuf) throws LispParseError {
+
+ // priority -> 8 bits
+ byte priority = (byte) byteBuf.readUnsignedByte();
+
+ // weight -> 8 bits
+ byte weight = (byte) byteBuf.readUnsignedByte();
+
+ // multi-cast priority -> 8 bits
+ byte multicastPriority = (byte) byteBuf.readUnsignedByte();
+
+ // multi-cast weight -> 8 bits
+ byte multicastWeight = (byte) byteBuf.readUnsignedByte();
+
+ // let's skip unused flags
+ byteBuf.skipBytes(SKIP_UNUSED_FLAG_LENGTH);
+
+ byte flags = byteBuf.readByte();
+
+ // local locator flag -> 1 bit
+ boolean localLocator = ByteOperator.getBit(flags, LOCAL_LOCATOR_INDEX);
+
+ // rloc probe flag -> 1 bit
+ boolean rlocProbed = ByteOperator.getBit(flags, RLOC_PROBED_INDEX);
+
+ // routed flag -> 1 bit
+ boolean routed = ByteOperator.getBit(flags, ROUTED_INDEX);
+
+ // TODO: de-serialize ITR-RLOC AFI and address
+
+ return new DefaultLocatorRecordBuilder()
+ .withPriority(priority)
+ .withWeight(weight)
+ .withMulticastPriority(multicastPriority)
+ .withMulticastWeight(multicastWeight)
+ .withLocalLocator(localLocator)
+ .withRlocProbed(rlocProbed)
+ .withRouted(routed)
+ .build();
+ }
+ }
+}