[ONOS-4718] Initial implementation of LISP address serializer

Change-Id: I71e1923f6daf1abdf2bf9798a9e421c81926a45c
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/exceptions/LispWriterException.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/exceptions/LispWriterException.java
new file mode 100644
index 0000000..6c07d8d
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/exceptions/LispWriterException.java
@@ -0,0 +1,57 @@
+/*
+ * 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.exceptions;
+
+/**
+ * LISP address or message writer exception.
+ */
+public class LispWriterException extends Exception {
+
+    /**
+     * Constructor for LispWriterException.
+     */
+    public LispWriterException() {
+        super();
+    }
+
+    /**
+     * Constructor for LispWriterException with message and cause parameters.
+     *
+     * @param message exception message
+     * @param cause   throwable cause
+     */
+    public LispWriterException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructor for LispWriterException with message parameter.
+     *
+     * @param message exception message
+     */
+    public LispWriterException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor for LispWriterException with cause parameter.
+     *
+     * @param cause throwable cause
+     */
+    public LispWriterException(final Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressReader.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressReader.java
index 7a1f4fc..fe6b313 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressReader.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressReader.java
@@ -30,6 +30,7 @@
      * @param byteBuf byte buffer
      * @return LISP address type instance
      * @throws LispParseError LISP address parse error
+     * @throws LispReaderException LISP reader exception
      */
     T readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException;
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressWriter.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressWriter.java
new file mode 100644
index 0000000..299f57a
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressWriter.java
@@ -0,0 +1,35 @@
+/*
+ * 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.types;
+
+import io.netty.buffer.ByteBuf;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+
+/**
+ * An interface for serializing LISP address.
+ */
+public interface LispAddressWriter<T> {
+
+    /**
+     * Writes from LISP address object and serialize to byte buffer.
+     *
+     * @param byteBuf byte buffer
+     * @param address LISP address type instance
+     * @throws LispWriterException Lisp writer exception
+     */
+    void writeTo(ByteBuf byteBuf, T address) throws LispWriterException;
+
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAfiAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAfiAddress.java
index 006413b..1d88008 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAfiAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAfiAddress.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
 import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -74,6 +75,9 @@
         return true;
     }
 
+    /**
+     * AFI address reader class.
+     */
     public static class AfiAddressReader implements LispAddressReader<LispAfiAddress> {
 
         @Override
@@ -114,4 +118,36 @@
             return null;
         }
     }
+
+    /**
+     * AFI address writer class.
+     */
+    public static class AfiAddressWriter implements LispAddressWriter<LispAfiAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispAfiAddress address) throws LispWriterException {
+            switch (address.getAfi()) {
+                case IP:
+                    new LispIpAddress.IpAddressWriter().writeTo(byteBuf, (LispIpv4Address) address);
+                    break;
+                case IP6:
+                    new LispIpAddress.IpAddressWriter().writeTo(byteBuf, (LispIpv6Address) address);
+                    break;
+                case DISTINGUISHED_NAME:
+                    new LispDistinguishedNameAddress.DistinguishedNameAddressWriter().writeTo(byteBuf,
+                            (LispDistinguishedNameAddress) address);
+                    break;
+                case MAC:
+                    new LispMacAddress.MacAddressWriter().writeTo(byteBuf, (LispMacAddress) address);
+                    break;
+                case LCAF:
+                    new LispLcafAddress.LcafAddressWriter().writeTo(byteBuf, (LispLcafAddress) address);
+                    break;
+                case AS:
+                    new LispAsAddress.AsAddressWriter().writeTo(byteBuf, (LispAsAddress) address);
+                    break;
+                default: break; // TODO: need log warning message
+            }
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAppDataLcafAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAppDataLcafAddress.java
index b1b6fda..284ebe4 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAppDataLcafAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAppDataLcafAddress.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
 import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.nio.ByteBuffer;
 import java.util.Objects;
@@ -364,4 +365,29 @@
             return buffer.getInt();
         }
     }
+
+    /**
+     * Application data LCAF address writer class.
+     */
+    public static class AppDataLcafAddressWriter
+            implements LispAddressWriter<LispAppDataLcafAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispAppDataLcafAddress address)
+                throws LispWriterException {
+
+            LispLcafAddress.serializeCommon(byteBuf, address);
+
+            // TODO: need to handle TOS
+
+            byteBuf.writeByte(address.getProtocol());
+            byteBuf.writeShort(address.getLocalPortLow());
+            byteBuf.writeShort(address.getLocalPortHigh());
+            byteBuf.writeShort(address.getRemotePortLow());
+            byteBuf.writeShort(address.getRemotePortHigh());
+
+            AfiAddressWriter writer = new LispAfiAddress.AfiAddressWriter();
+            writer.writeTo(byteBuf, address.getAddress());
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAsAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAsAddress.java
index 28fa729..f792715 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAsAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAsAddress.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
 import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -88,4 +89,15 @@
             throw new LispReaderException("Unimplemented method");
         }
     }
+
+    /**
+     * Autonomous system address writer class.
+     */
+    public static class AsAddressWriter implements LispAddressWriter<LispAsAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispAsAddress address) throws LispWriterException {
+            throw new LispWriterException("Unimplemented method");
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispDistinguishedNameAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispDistinguishedNameAddress.java
index e0d631f..77f1c08 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispDistinguishedNameAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispDistinguishedNameAddress.java
@@ -17,6 +17,7 @@
 
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -92,4 +93,20 @@
             return new LispDistinguishedNameAddress(sb.toString());
         }
     }
+
+    /**
+     * Distinguished name address writer class.
+     */
+    public static class DistinguishedNameAddressWriter
+                        implements LispAddressWriter<LispDistinguishedNameAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispDistinguishedNameAddress address) throws LispWriterException {
+            String distinguishedName = address.getDistinguishedName();
+            byte[] nameBytes = distinguishedName.getBytes();
+            for (int i = 0; i < nameBytes.length; i++) {
+                byteBuf.writeChar(nameBytes[i]);
+            }
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpAddress.java
index 29d0b70..14d4949 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpAddress.java
@@ -19,6 +19,7 @@
 import org.onlab.packet.IpAddress;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
 import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 /**
  * IP address that is used by LISP Locator.
@@ -63,7 +64,7 @@
     }
 
     /**
-     * IP Address reader class.
+     * IP address reader class.
      */
     public static class IpAddressReader implements LispAddressReader<LispIpAddress> {
 
@@ -82,4 +83,20 @@
             return null;
         }
     }
+
+    /**
+     * IP address writer class.
+     */
+    public static class IpAddressWriter implements LispAddressWriter<LispIpAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispIpAddress address) throws LispWriterException {
+            if (address.getAddress().isIp4()) {
+                new LispIpv4Address.Ipv4AddressWriter().writeTo(byteBuf, (LispIpv4Address) address);
+            }
+            if (address.getAddress().isIp6()) {
+                new LispIpv6Address.Ipv6AddressWriter().writeTo(byteBuf, (LispIpv6Address) address);
+            }
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpv4Address.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpv4Address.java
index 1cc5829..a0df8d8 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpv4Address.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpv4Address.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onlab.packet.IpAddress;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -74,4 +75,16 @@
             return new LispIpv4Address(ipAddress);
         }
     }
+
+    /**
+     * IPv4 address writer class.
+     */
+    public static class Ipv4AddressWriter implements LispAddressWriter<LispIpv4Address> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispIpv4Address address) throws LispWriterException {
+            byte[] ipByte = address.getAddress().getIp4Address().toOctets();
+            byteBuf.writeBytes(ipByte);
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpv6Address.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpv6Address.java
index f2eccaa..ed3ad43 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpv6Address.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispIpv6Address.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onlab.packet.IpAddress;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -74,4 +75,16 @@
             return new LispIpv6Address(ipAddress);
         }
     }
+
+    /**
+     * Ipv6 address writer class.
+     */
+    public static class Ipv6AddressWriter implements LispAddressWriter<LispIpv6Address> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispIpv6Address address) throws LispWriterException {
+            byte[] ipByte = address.getAddress().getIp6Address().toOctets();
+            byteBuf.writeBytes(ipByte);
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispLcafAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispLcafAddress.java
index e6c6c1f..85a21d2 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispLcafAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispLcafAddress.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
 import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -216,6 +217,20 @@
                                     reserved1, reserved2, flag, length);
     }
 
+    /**
+     * Serializes common fields to byte buffer.
+     *
+     * @param byteBuf byte buffer
+     * @param address LISP LCAF address instance
+     */
+    public static void serializeCommon(ByteBuf byteBuf, LispLcafAddress address) {
+        byteBuf.writeByte(address.getReserved1());
+        byteBuf.writeByte(address.getFlag());
+        byteBuf.writeByte(address.getType().getLispCode());
+        byteBuf.writeByte(address.getReserved2());
+        byteBuf.writeShort(address.getLength());
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(lcafType, reserved1, reserved2, flag, length);
@@ -323,6 +338,9 @@
         }
     }
 
+    /**
+     * LISP LCAF reader class.
+     */
     public static class LcafAddressReader implements LispAddressReader<LispLcafAddress> {
 
         private static final int LCAF_TYPE_FIELD_INDEX = 4;
@@ -354,4 +372,33 @@
             return null;
         }
     }
+
+    /**
+     * LISP LCAF address writer class.
+     */
+    public static class LcafAddressWriter implements LispAddressWriter<LispLcafAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispLcafAddress address) throws LispWriterException {
+            switch (address.getType()) {
+                case APPLICATION_DATA:
+                    new LispAppDataLcafAddress.AppDataLcafAddressWriter().writeTo(byteBuf,
+                            (LispAppDataLcafAddress) address);
+                    break;
+                case LIST:
+                    new LispListLcafAddress.ListLcafAddressWriter().writeTo(byteBuf,
+                            (LispListLcafAddress) address);
+                    break;
+                case SEGMENT:
+                    new LispSegmentLcafAddress.SegmentLcafAddressWriter().writeTo(byteBuf,
+                            (LispSegmentLcafAddress) address);
+                    break;
+                case SOURCE_DEST:
+                    new LispSourceDestLcafAddress.SourceDestLcafAddressWriter().writeTo(byteBuf,
+                            (LispSourceDestLcafAddress) address);
+                    break;
+                default: break; // TODO: need to log warning message
+            }
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispListLcafAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispListLcafAddress.java
index fd33119..3552b45 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispListLcafAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispListLcafAddress.java
@@ -19,6 +19,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
 import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.List;
 import java.util.Objects;
@@ -134,4 +135,22 @@
                                            lcafAddress.getFlag(), ImmutableList.of(ipv4, ipv6));
         }
     }
+
+    /**
+     * List LCAF address writer class.
+     */
+    public static class ListLcafAddressWriter implements LispAddressWriter<LispListLcafAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispListLcafAddress address) throws LispWriterException {
+
+            LispLcafAddress.serializeCommon(byteBuf, address);
+
+            LispIpv4Address.Ipv4AddressWriter v4Writer = new LispIpv4Address.Ipv4AddressWriter();
+            LispIpv6Address.Ipv6AddressWriter v6Writer = new LispIpv6Address.Ipv6AddressWriter();
+
+            v4Writer.writeTo(byteBuf, (LispIpv4Address) address.getAddresses().get(0));
+            v6Writer.writeTo(byteBuf, (LispIpv6Address) address.getAddresses().get(1));
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispMacAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispMacAddress.java
index ba789b6..6828581 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispMacAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispMacAddress.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onlab.packet.MacAddress;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -88,4 +89,16 @@
             return new LispMacAddress(macAddress);
         }
     }
+
+    /**
+     * MAC address writer class.
+     */
+    public static class MacAddressWriter implements LispAddressWriter<LispMacAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispMacAddress address) throws LispWriterException {
+            byte[] macByte = address.getAddress().toBytes();
+            byteBuf.writeBytes(macByte);
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispNoAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispNoAddress.java
index 592250d..a8894eb 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispNoAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispNoAddress.java
@@ -17,6 +17,7 @@
 
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 /**
  * No address.
@@ -40,4 +41,15 @@
             return new LispNoAddress();
         }
     }
+
+    /**
+     * LISP no address writer class.
+     */
+    public static class NoAddressWriter implements LispAddressWriter<LispNoAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispNoAddress address) throws LispWriterException {
+
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispSegmentLcafAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispSegmentLcafAddress.java
index 6f2cc22..8405695 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispSegmentLcafAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispSegmentLcafAddress.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
 import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -212,4 +213,21 @@
                     .build();
         }
     }
+
+    /**
+     * Segment LCAF address writer class.
+     */
+    public static class SegmentLcafAddressWriter
+            implements LispAddressWriter<LispSegmentLcafAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispSegmentLcafAddress address)
+                throws LispWriterException {
+
+            LispLcafAddress.serializeCommon(byteBuf, address);
+
+            byteBuf.writeInt(address.getInstanceId());
+            new LispIpAddress.IpAddressWriter().writeTo(byteBuf, (LispIpAddress) address.getAddress());
+        }
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispSourceDestLcafAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispSourceDestLcafAddress.java
index 9da4a18..80dd538 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispSourceDestLcafAddress.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispSourceDestLcafAddress.java
@@ -18,6 +18,7 @@
 import io.netty.buffer.ByteBuf;
 import org.onosproject.lisp.msg.exceptions.LispParseError;
 import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import java.util.Objects;
 
@@ -200,7 +201,7 @@
         /**
          * Sets destination address prefix.
          *
-         * @param dstPrefix
+         * @param dstPrefix destination prefix
          * @return SourceDestAddressBuilder object
          */
         public SourceDestAddressBuilder withDstPrefix(LispAfiAddress dstPrefix) {
@@ -283,4 +284,25 @@
                     .build();
         }
     }
+
+    /**
+     * SourceDest LCAF address writer class.
+     */
+    public static class SourceDestLcafAddressWriter
+            implements LispAddressWriter<LispSourceDestLcafAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispSourceDestLcafAddress address)
+                throws LispWriterException {
+
+            LispLcafAddress.serializeCommon(byteBuf, address);
+
+            byteBuf.writeShort(address.getReserved());
+            byteBuf.writeByte(address.getSrcMaskLength());
+            byteBuf.writeByte(address.getDstMaskLength());
+            AfiAddressWriter writer = new LispAfiAddress.AfiAddressWriter();
+            writer.writeTo(byteBuf, address.getSrcPrefix());
+            writer.writeTo(byteBuf, address.getDstPrefix());
+        }
+    }
 }