Bugfix: handle LISP map-request message that is encapsulated in ECM

Change-Id: If7ed64f4999719d2d13cd2f5c59bcaf920157bfe
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
index 136831a..d628838 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
@@ -19,10 +19,12 @@
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.handler.timeout.IdleState;
 import io.netty.handler.timeout.IdleStateEvent;
+import org.onosproject.lisp.msg.protocols.LispEncapsulatedControl;
 import org.onosproject.lisp.msg.protocols.LispMapNotify;
 import org.onosproject.lisp.msg.protocols.LispMapRegister;
-import org.onosproject.lisp.msg.protocols.LispMapReply;
 import org.onosproject.lisp.msg.protocols.LispMapRequest;
+import org.onosproject.lisp.msg.protocols.LispMapReply;
+import org.onosproject.lisp.msg.protocols.LispMessage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -37,6 +39,11 @@
     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
 
+        // first we need to check whether this is an ECM
+        if (msg instanceof LispEncapsulatedControl) {
+            msg = extractMapRequest((LispEncapsulatedControl) msg);
+        }
+
         if (msg instanceof LispMapRegister) {
             LispMapServer mapServer = new LispMapServer();
             LispMapNotify mapNotify =
@@ -79,4 +86,14 @@
         log.warn(cause.getMessage());
         ctx.close();
     }
+
+    /**
+     * Extracts LISP message from encapsulated control message.
+     *
+     * @param ecm Encapsulated Control Message
+     * @return extracted LISP message
+     */
+    private LispMessage extractMapRequest(LispEncapsulatedControl ecm) {
+        return ecm.getControlMessage();
+    }
 }
diff --git a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMessageDecoderTest.java b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMessageDecoderTest.java
index 5e9be94..b808ef1 100644
--- a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMessageDecoderTest.java
+++ b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMessageDecoderTest.java
@@ -52,7 +52,7 @@
 
         // fill up message payload
         // second byte denotes the number of RLOCs
-        byte[] messageData = {0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+        byte[] messageData = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
         byte[] eidData = {0x0, 0x1, 0x0, 0x0, 0x0, 0x0};
         byte[] rlocData = {0x0, 0x1, 0x0, 0x0, 0x0, 0x0};
         buffer.writeBytes(messageData);
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
index 34ec469..110fe3e 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
@@ -29,9 +29,8 @@
 
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
 import static org.onosproject.lisp.msg.protocols.LispEidRecord.EidRecordWriter;
+import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
 
 /**
  * Default LISP map request message class.
@@ -280,7 +279,6 @@
         @Override
         public LispMapRequest build() {
 
-            checkNotNull(sourceEid, "Must have a source EID");
             checkArgument((itrRlocs != null) && (itrRlocs.size() > 0), "Must have an ITR RLOC entry");
 
             return new DefaultLispMapRequest(nonce, sourceEid, itrRlocs, eidRecords,
@@ -344,7 +342,7 @@
 
             // deserialize a collection of RLOC addresses
             List<LispAfiAddress> itrRlocs = Lists.newArrayList();
-            for (int i = 0; i < irc; i++) {
+            for (int i = 0; i < irc + 1; i++) {
                 itrRlocs.add(new LispAfiAddress.AfiAddressReader().readFrom(byteBuf));
             }
 
@@ -433,7 +431,7 @@
             byteBuf.writeByte((byte) (pitr + smrInvoked));
 
             // ITR Rloc count
-            byteBuf.writeByte((byte) message.getItrRlocs().size());
+            byteBuf.writeByte((byte) message.getItrRlocs().size() - 1);
 
             // record count
             byteBuf.writeByte(message.getEids().size());
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMessageReaderFactory.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMessageReaderFactory.java
index 2798cc9..4bb47af 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMessageReaderFactory.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMessageReaderFactory.java
@@ -41,7 +41,7 @@
         LispMessageReader reader;
 
         LispType type = LispType.valueOf(
-                (short) (buffer.getByte(0) >> TYPE_SHIFT_BIT));
+                (short) (buffer.getUnsignedByte(0) >> TYPE_SHIFT_BIT));
 
         switch (type) {
             case LISP_MAP_REQUEST:
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 aba3475..7f67277 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
@@ -89,6 +89,11 @@
             // AFI code -> 16 bits
             short afiCode = (short) byteBuf.getUnsignedShort(index);
 
+            // handle no address
+            if (afiCode == NO_ADDRESS.getIanaCode()) {
+                byteBuf.readUnsignedShort();
+            }
+
             // handle IPv4 and IPv6 address
             if (afiCode == IP4.getIanaCode() ||
                 afiCode == IP6.getIanaCode()) {