[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/DefaultLispMapRegister.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
index 7f75181..abaf3c8 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
@@ -23,11 +23,14 @@
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;
+
/**
* Default LISP map register message class.
*/
@@ -35,6 +38,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;
@@ -52,12 +56,13 @@
* @param proxyMapReply proxy map reply flag
* @param wantMapNotify want map notify flag
*/
- private DefaultLispMapRegister(long nonce, short keyId,
+ private DefaultLispMapRegister(long nonce, short keyId, short authDataLength,
byte[] authenticationData, byte recordCount,
List<LispMapRecord> mapRecords,
boolean proxyMapReply, boolean wantMapNotify) {
this.nonce = nonce;
this.keyId = keyId;
+ this.authDataLength = authDataLength;
this.authenticationData = authenticationData;
this.recordCount = recordCount;
this.mapRecords = mapRecords;
@@ -106,6 +111,11 @@
}
@Override
+ public short getAuthDataLength() {
+ return authDataLength;
+ }
+
+ @Override
public byte[] getAuthenticationData() {
return ImmutableByteSequence.copyFrom(this.authenticationData).asArray();
}
@@ -122,6 +132,8 @@
.add("nonce", nonce)
.add("recordCount", recordCount)
.add("keyId", keyId)
+ .add("authentication data length", authDataLength)
+ .add("authentication data", authenticationData)
.add("mapRecords", mapRecords)
.add("proxyMapReply", proxyMapReply)
.add("wantMapNotify", wantMapNotify).toString();
@@ -140,6 +152,7 @@
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) &&
Objects.equal(proxyMapReply, that.proxyMapReply) &&
Objects.equal(wantMapNotify, that.wantMapNotify);
@@ -147,14 +160,15 @@
@Override
public int hashCode() {
- return Objects.hashCode(nonce, recordCount, keyId, authenticationData,
- proxyMapReply, wantMapNotify);
+ return Objects.hashCode(nonce, recordCount, keyId, authDataLength,
+ authenticationData, proxyMapReply, wantMapNotify);
}
public static final class DefaultRegisterBuilder implements RegisterBuilder {
private long nonce;
private short keyId;
+ private short authDataLength;
private byte[] authenticationData;
private byte recordCount;
private List<LispMapRecord> mapRecords;
@@ -191,6 +205,12 @@
}
@Override
+ public RegisterBuilder withAuthDataLength(short authDataLength) {
+ this.authDataLength = authDataLength;
+ return this;
+ }
+
+ @Override
public RegisterBuilder withKeyId(short keyId) {
this.keyId = keyId;
return this;
@@ -210,15 +230,15 @@
@Override
public LispMapRegister build() {
- return new DefaultLispMapRegister(nonce, keyId, authenticationData,
- recordCount, mapRecords, proxyMapReply, wantMapNotify);
+ return new DefaultLispMapRegister(nonce, keyId, authDataLength,
+ authenticationData, recordCount, mapRecords, proxyMapReply, wantMapNotify);
}
}
/**
- * A private LISP message reader for MapRegister message.
+ * A LISP message reader for MapRegister message.
*/
- private static class RegisterReader implements LispMessageReader<LispMapRegister> {
+ public static final class RegisterReader implements LispMessageReader<LispMapRegister> {
private static final int PROXY_MAP_REPLY_INDEX = 3;
private static final int WANT_MAP_NOTIFY_INDEX = 0;
@@ -274,4 +294,78 @@
.build();
}
}
+
+ /**
+ * LISP map register message writer class.
+ */
+ public static class RegisterWriter implements LispMessageWriter<LispMapRegister> {
+
+ private static final int REGISTER_MSG_TYPE = 3;
+ private static final int REGISTER_SHIFT_BIT = 4;
+
+ private static final int PROXY_MAP_REPLY_SHIFT_BIT = 3;
+
+ private static final int ENABLE_BIT = 1;
+ private static final int DISABLE_BIT = 0;
+
+ private static final int UNUSED_ZERO = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispMapRegister message) throws LispWriterException {
+
+ // specify LISP message type
+ byte msgType = (byte) (REGISTER_MSG_TYPE << REGISTER_SHIFT_BIT);
+
+ // proxy map reply flag
+ byte proxyMapReply = DISABLE_BIT;
+ if (message.isProxyMapReply()) {
+ proxyMapReply = (byte) (ENABLE_BIT << PROXY_MAP_REPLY_SHIFT_BIT);
+ }
+
+ byteBuf.writeByte(msgType + proxyMapReply);
+
+ // fill zero into reserved field
+ byteBuf.writeByte((short) UNUSED_ZERO);
+
+ // want map notify flag
+ byte wantMapNotify = DISABLE_BIT;
+ if (message.isWantMapNotify()) {
+ wantMapNotify = (byte) ENABLE_BIT;
+ }
+
+ byteBuf.writeByte(wantMapNotify);
+
+ // 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
+ DefaultLispMapRecord.MapRecordWriter writer = new DefaultLispMapRecord.MapRecordWriter();
+ List<LispMapRecord> records = message.getMapRecords();
+
+ for (int i = 0; i < records.size(); i++) {
+ writer.writeTo(byteBuf, records.get(i));
+ }
+ }
+ }
}