[ONOS-4718] Initial implementation of LISP control msg serializer
Change-Id: Ia068e1b158f05dd70839cb1020f15dc66b0142a0
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
index 05cc7f5..30eba1f 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
@@ -22,10 +22,13 @@
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import java.util.Arrays;
import java.util.List;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.MapRecordWriter;
/**
* Default LISP map notify message class.
@@ -34,6 +37,7 @@
private final long nonce;
private final short keyId;
+ private final short authDataLength;
private final byte[] authenticationData;
private final byte recordCount;
private final List<LispMapRecord> mapRecords;
@@ -47,10 +51,12 @@
* @param recordCount record count number
* @param mapRecords a collection of map records
*/
- private DefaultLispMapNotify(long nonce, short keyId, byte[] authenticationData,
- byte recordCount, List<LispMapRecord> mapRecords) {
+ private DefaultLispMapNotify(long nonce, short keyId, short authDataLength,
+ byte[] authenticationData, byte recordCount,
+ List<LispMapRecord> mapRecords) {
this.nonce = nonce;
this.keyId = keyId;
+ this.authDataLength = authDataLength;
this.authenticationData = authenticationData;
this.recordCount = recordCount;
this.mapRecords = mapRecords;
@@ -73,26 +79,31 @@
@Override
public long getNonce() {
- return this.nonce;
+ return nonce;
}
@Override
public byte getRecordCount() {
- return this.recordCount;
+ return recordCount;
}
@Override
public short getKeyId() {
- return this.keyId;
+ return keyId;
+ }
+
+ @Override
+ public short getAuthDataLength() {
+ return authDataLength;
}
@Override
public byte[] getAuthenticationData() {
- return ImmutableByteSequence.copyFrom(this.authenticationData).asArray();
+ return ImmutableByteSequence.copyFrom(authenticationData).asArray();
}
@Override
- public List<LispMapRecord> getLispRecords() {
+ public List<LispMapRecord> getMapRecords() {
return ImmutableList.copyOf(mapRecords);
}
@@ -103,6 +114,8 @@
.add("nonce", nonce)
.add("recordCount", recordCount)
.add("keyId", keyId)
+ .add("authentication data length", authDataLength)
+ .add("authentication data", authenticationData)
.add("mapRecords", mapRecords).toString();
}
@@ -118,18 +131,20 @@
return Objects.equal(nonce, that.nonce) &&
Objects.equal(recordCount, that.recordCount) &&
Objects.equal(keyId, that.keyId) &&
+ Objects.equal(authDataLength, that.authDataLength) &&
Objects.equal(authenticationData, that.authenticationData);
}
@Override
public int hashCode() {
- return Objects.hashCode(nonce, recordCount, keyId, authenticationData);
+ return Objects.hashCode(nonce, recordCount, keyId, authDataLength, authenticationData);
}
public static final class DefaultNotifyBuilder implements NotifyBuilder {
private long nonce;
private short keyId;
+ private short authDataLength;
private byte[] authenticationData;
private byte recordCount;
private List<LispMapRecord> mapRecords;
@@ -158,6 +173,12 @@
}
@Override
+ public NotifyBuilder withAuthDataLength(short authDataLength) {
+ this.authDataLength = authDataLength;
+ return this;
+ }
+
+ @Override
public NotifyBuilder withAuthenticationData(byte[] authenticationData) {
this.authenticationData = authenticationData;
return this;
@@ -171,15 +192,15 @@
@Override
public LispMapNotify build() {
- return new DefaultLispMapNotify(nonce, keyId, authenticationData,
- recordCount, mapRecords);
+ return new DefaultLispMapNotify(nonce, keyId, authDataLength,
+ authenticationData, recordCount, mapRecords);
}
}
/**
- * A private LISP message reader for MapNotify message.
+ * A LISP message reader for MapNotify message.
*/
- private static class NotifyReader implements LispMessageReader<LispMapNotify> {
+ public static final class NotifyReader implements LispMessageReader<LispMapNotify> {
private static final int RESERVED_SKIP_LENGTH = 3;
@@ -218,9 +239,64 @@
.withRecordCount(recordCount)
.withNonce(nonce)
.withKeyId(keyId)
+ .withAuthDataLength(authLength)
.withAuthenticationData(authData)
.withMapRecords(mapRecords)
.build();
}
}
+
+ /**
+ * A LISP message reader for MapNotify message.
+ */
+ public static final class NotifyWriter implements LispMessageWriter<LispMapNotify> {
+
+ private static final int NOTIFY_MSG_TYPE = 4;
+ private static final int NOTIFY_SHIFT_BIT = 4;
+
+ private static final int UNUSED_ZERO = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispMapNotify message) throws LispWriterException {
+
+ // specify LISP message type
+ byte msgType = (byte) (NOTIFY_MSG_TYPE << NOTIFY_SHIFT_BIT);
+ byteBuf.writeByte(msgType);
+
+ // reserved field
+ byteBuf.writeShort((short) UNUSED_ZERO);
+
+ // record count
+ byteBuf.writeByte(message.getRecordCount());
+
+ // nonce
+ byteBuf.writeLong(message.getNonce());
+
+ // keyId
+ byteBuf.writeShort(message.getKeyId());
+
+ // authentication data length in octet
+ byteBuf.writeShort(message.getAuthDataLength());
+
+ // authentication data
+ byte[] data = message.getAuthenticationData();
+ byte[] clone;
+ if (data != null) {
+ clone = data.clone();
+ Arrays.fill(clone, (byte) UNUSED_ZERO);
+ }
+
+ byteBuf.writeBytes(data);
+
+ // TODO: need to implement MAC authentication mechanism
+
+ // serialize map records
+ MapRecordWriter writer = new MapRecordWriter();
+ List<LispMapRecord> records = message.getMapRecords();
+
+ for (int i = 0; i < records.size(); i++) {
+ writer.writeTo(byteBuf, records.get(i));
+ }
+ }
+ }
}