[ONOS-5946] Implement LISP signature type

Change-Id: Ifea098d3b2fd1c0b5e24185b537056b9864b935b
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispSignature.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispSignature.java
index 979e987..12dbc5d 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispSignature.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispSignature.java
@@ -15,8 +15,269 @@
  */
 package org.onosproject.lisp.msg.protocols;
 
+import com.google.common.base.Objects;
+import io.netty.buffer.ByteBuf;
+import org.onlab.packet.DeserializationException;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
 /**
  * Default LISP signature class.
  */
-public class DefaultLispSignature implements LispSignature {
+public final class DefaultLispSignature implements LispSignature {
+
+    private final int recordTtl;
+    private final int sigExpiration;
+    private final int sigInception;
+    private final short keyTag;
+    private final short sigLength;
+    private final byte sigAlgorithm;
+    private final int signature;
+
+    /**
+     * A private constructor that protects object instantiation from external.
+     *
+     * @param recordTtl     record time-to-live value
+     * @param sigExpiration signature expiration
+     * @param sigInception  signature inception
+     * @param keyTag        key tag
+     * @param sigLength     signature length
+     * @param sigAlgorithm  signature algorithm
+     * @param signature     signature
+     */
+    private DefaultLispSignature(int recordTtl, int sigExpiration, int sigInception,
+                                 short keyTag, short sigLength, byte sigAlgorithm,
+                                 int signature) {
+        this.recordTtl = recordTtl;
+        this.sigExpiration = sigExpiration;
+        this.sigInception = sigInception;
+        this.keyTag = keyTag;
+        this.sigLength = sigLength;
+        this.sigAlgorithm = sigAlgorithm;
+        this.signature = signature;
+    }
+
+    @Override
+    public int getRecordTtl() {
+        return recordTtl;
+    }
+
+    @Override
+    public int getSigExpiration() {
+        return sigExpiration;
+    }
+
+    @Override
+    public int getSigInception() {
+        return sigInception;
+    }
+
+    @Override
+    public short getKeyTag() {
+        return keyTag;
+    }
+
+    @Override
+    public short getSigLength() {
+        return sigLength;
+    }
+
+    @Override
+    public byte getSigAlgorithm() {
+        return sigAlgorithm;
+    }
+
+    @Override
+    public int getSignature() {
+        return signature;
+    }
+
+    @Override
+    public void writeTo(ByteBuf byteBuf) throws LispWriterException {
+
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("record TTL", recordTtl)
+                .add("signature expiration", sigExpiration)
+                .add("signature inception", sigInception)
+                .add("key tag", keyTag)
+                .add("signature length", sigLength)
+                .add("signature algorithm", sigAlgorithm)
+                .add("signature", signature)
+                .toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        DefaultLispSignature that = (DefaultLispSignature) o;
+        return Objects.equal(recordTtl, that.recordTtl) &&
+                Objects.equal(sigExpiration, that.sigExpiration) &&
+                Objects.equal(sigInception, that.sigInception) &&
+                Objects.equal(keyTag, that.keyTag) &&
+                Objects.equal(sigLength, that.sigLength) &&
+                Objects.equal(sigAlgorithm, that.sigAlgorithm) &&
+                Objects.equal(signature, that.signature);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(recordTtl, sigExpiration, sigInception,
+                                keyTag, sigLength, sigAlgorithm, signature);
+    }
+
+    public static final class DefaultSignatureBuilder implements LispSignature.SignatureBuilder {
+
+        private int recordTtl;
+        private int sigExpiration;
+        private int sigInception;
+        private short keyTag;
+        private short sigLength;
+        private byte sigAlgorithm;
+        private int signature;
+
+        @Override
+        public SignatureBuilder withRecordTtl(int recordTtl) {
+            this.recordTtl = recordTtl;
+            return this;
+        }
+
+        @Override
+        public SignatureBuilder withSigExpiration(int sigExpiration) {
+            this.sigExpiration = sigExpiration;
+            return this;
+        }
+
+        @Override
+        public SignatureBuilder withSigInception(int sigInception) {
+            this.sigInception = sigInception;
+            return this;
+        }
+
+        @Override
+        public SignatureBuilder withKeyTag(short keyTag) {
+            this.keyTag = keyTag;
+            return this;
+        }
+
+        @Override
+        public SignatureBuilder withSigLength(short sigLength) {
+            this.sigLength = sigLength;
+            return this;
+        }
+
+        @Override
+        public SignatureBuilder withSigAlgorithm(byte sigAlgorithm) {
+            this.sigAlgorithm = sigAlgorithm;
+            return this;
+        }
+
+        @Override
+        public SignatureBuilder withSignature(int signature) {
+            this.signature = signature;
+            return this;
+        }
+
+        @Override
+        public LispSignature build() {
+
+            return new DefaultLispSignature(recordTtl, sigExpiration, sigInception,
+                                    keyTag, sigLength, sigAlgorithm, signature);
+        }
+    }
+
+    /**
+     * A LISP reader for Signature section.
+     */
+    public static final class SignatureReader
+                                implements LispMessageReader<LispSignature> {
+
+        private static final int RESERVED_SKIP_LENGTH = 3;
+
+        @Override
+        public LispSignature readFrom(ByteBuf byteBuf) throws LispParseError,
+                                LispReaderException, DeserializationException {
+
+            // record TTL -> 32 bits
+            int recordTtl = byteBuf.readInt();
+
+            // signature expiration -> 32 bits
+            int sigExpiration = byteBuf.readInt();
+
+            // signature inception -> 32 bits
+            int sigInception = byteBuf.readInt();
+
+            // key tag -> 16 bits
+            short keyTag = byteBuf.readShort();
+
+            // signature length -> 16 bits
+            short sigLength = byteBuf.readShort();
+
+            // signature algorithm -> 8 bits
+            byte sigAlgorithm = byteBuf.readByte();
+
+            byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
+
+            // TODO: the size of signature should be determined by sigAlgorithm
+            int signature = byteBuf.readInt();
+
+            return new DefaultSignatureBuilder()
+                            .withRecordTtl(recordTtl)
+                            .withSigExpiration(sigExpiration)
+                            .withSigInception(sigInception)
+                            .withKeyTag(keyTag)
+                            .withSigLength(sigLength)
+                            .withSigAlgorithm(sigAlgorithm)
+                            .withSignature(signature)
+                            .build();
+        }
+    }
+
+    /**
+     * A LISP writer for Signature section.
+     */
+    public static final class SignatureWriter implements LispMessageWriter<LispSignature> {
+
+        private static final int UNUSED_ZERO = 0;
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispSignature message) throws LispWriterException {
+
+            // record TTL
+            byteBuf.writeInt(message.getRecordTtl());
+
+            // signature expiration
+            byteBuf.writeInt(message.getSigExpiration());
+
+            // signature inception
+            byteBuf.writeInt(message.getSigInception());
+
+            // key tag
+            byteBuf.writeShort(message.getKeyTag());
+
+            // signature length
+            byteBuf.writeShort(message.getSigLength());
+
+            // signature algorithm
+            byteBuf.writeByte(message.getSigAlgorithm());
+
+            byteBuf.writeByte(UNUSED_ZERO);
+            byteBuf.writeShort(UNUSED_ZERO);
+
+            // signature
+            // TODO: the size of signature should be determined by sigAlgorithm
+            byteBuf.writeInt(message.getSignature());
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispSignature.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispSignature.java
index 291d9d7..d3bda09 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispSignature.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispSignature.java
@@ -15,6 +15,9 @@
  */
 package org.onosproject.lisp.msg.protocols;
 
+import io.netty.buffer.ByteBuf;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+
 /**
  * LISP signature interface.
  *
@@ -43,5 +46,129 @@
  */
 public interface LispSignature {
 
-    // TODO: need to implement LispSignature
+    /**
+     * Obtains record TTL value.
+     *
+     * @return record TTL value
+     */
+    int getRecordTtl();
+
+    /**
+     * Obtains signature expiration.
+     *
+     * @return signature expiration
+     */
+    int getSigExpiration();
+
+    /**
+     * Obtains signature inception.
+     *
+     * @return signature inception
+     */
+    int getSigInception();
+
+    /**
+     * Obtains key tag.
+     *
+     * @return key tag
+     */
+    short getKeyTag();
+
+    /**
+     * Obtains signature length.
+     *
+     * @return signature length.
+     */
+    short getSigLength();
+
+    /**
+     * Obtains signature algorithm.
+     *
+     * @return signature algorithm
+     */
+    byte getSigAlgorithm();
+
+    /**
+     * Obtains signature.
+     *
+     * @return signature
+     */
+    int getSignature();
+
+    /**
+     * Writes LISP object into communication channel.
+     *
+     * @param byteBuf byte buffer
+     * @throws LispWriterException on error
+     */
+    void writeTo(ByteBuf byteBuf) throws LispWriterException;
+
+    /**
+     * A builder for LISP signature.
+     */
+    interface SignatureBuilder {
+
+        /**
+         * Sets record TTL value.
+         *
+         * @param recordTtl record TTL
+         * @return SignatureBuilder object
+         */
+        SignatureBuilder withRecordTtl(int recordTtl);
+
+        /**
+         * Sets signature expiration.
+         *
+         * @param sigExpiration signature expiration
+         * @return SignatureBuilder object
+         */
+        SignatureBuilder withSigExpiration(int sigExpiration);
+
+        /**
+         * Sets signature inception.
+         *
+         * @param sigInception signature inception
+         * @return SignatureBuilder object
+         */
+        SignatureBuilder withSigInception(int sigInception);
+
+        /**
+         * Sets key tag.
+         *
+         * @param keyTag key tag
+         * @return SignatureBuilder object
+         */
+        SignatureBuilder withKeyTag(short keyTag);
+
+        /**
+         * Sets signature length.
+         *
+         * @param sigLength signature length
+         * @return SignatureBuilder object
+         */
+        SignatureBuilder withSigLength(short sigLength);
+
+        /**
+         * Sets signature algorithm.
+         *
+         * @param sigAlgorithm signature algorithm
+         * @return SignatureBuilder object
+         */
+        SignatureBuilder withSigAlgorithm(byte sigAlgorithm);
+
+        /**
+         * Sets signature.
+         *
+         * @param signature signature
+         * @return SignatureBuilder object
+         */
+        SignatureBuilder withSignature(int signature);
+
+        /**
+         * Builds LISP signature object.
+         *
+         * @return LISP signature object
+         */
+        LispSignature build();
+    }
 }