fixed the LINC-OE behaviour. Handshaker behaviours must use
sendHandshakeMessage during the handshake rather than sendMsg.

Change-Id: I50b3da2c592f77dd786da68d42e5dc289407cd37
diff --git a/drivers/src/main/java/org/onosproject/driver/handshaker/DefaultSwitchHandShaker.java b/drivers/src/main/java/org/onosproject/driver/handshaker/DefaultSwitchHandShaker.java
index c9455a0..21c59e6 100644
--- a/drivers/src/main/java/org/onosproject/driver/handshaker/DefaultSwitchHandShaker.java
+++ b/drivers/src/main/java/org/onosproject/driver/handshaker/DefaultSwitchHandShaker.java
@@ -45,7 +45,7 @@
         if (factory().getVersion() == OFVersion.OF_10) {
             OFFlowAdd.Builder fmBuilder = factory().buildFlowAdd();
             fmBuilder.setPriority(LOWEST_PRIORITY);
-            sendMsg(fmBuilder.build());
+            sendHandshakeMessage(fmBuilder.build());
         }
     }
 
diff --git a/drivers/src/main/java/org/onosproject/driver/handshaker/OFCorsaSwitchDriver.java b/drivers/src/main/java/org/onosproject/driver/handshaker/OFCorsaSwitchDriver.java
index da26a49..05c907e 100644
--- a/drivers/src/main/java/org/onosproject/driver/handshaker/OFCorsaSwitchDriver.java
+++ b/drivers/src/main/java/org/onosproject/driver/handshaker/OFCorsaSwitchDriver.java
@@ -64,7 +64,7 @@
                 .setXid(barrierXid).build();
 
 
-        sendMsg(Collections.singletonList(barrier));
+        sendHandshakeMessage(barrier);
 
     }
 
diff --git a/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitchImplLINC13.java b/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitchImplLINC13.java
index d294e56..2c0749c 100644
--- a/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitchImplLINC13.java
+++ b/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitchImplLINC13.java
@@ -64,9 +64,6 @@
 
     @Override
     public boolean isDriverHandshakeComplete() {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
         return driverHandshakeComplete.get();
     }
 
@@ -161,7 +158,7 @@
                          "message " +
                          "{}",
                  circuitPortsRequest.toString());
-        this.sendMsg(Collections.<OFMessage>singletonList(circuitPortsRequest));
+        this.sendHandshakeMessage(circuitPortsRequest);
     }
 
     @Override
diff --git a/drivers/src/main/java/org/onosproject/driver/handshaker/OFSwitchImplCPqD13.java b/drivers/src/main/java/org/onosproject/driver/handshaker/OFSwitchImplCPqD13.java
index 1c9e66a..483bbda 100644
--- a/drivers/src/main/java/org/onosproject/driver/handshaker/OFSwitchImplCPqD13.java
+++ b/drivers/src/main/java/org/onosproject/driver/handshaker/OFSwitchImplCPqD13.java
@@ -222,7 +222,7 @@
                 .build();
         msglist.add(getAC);
 
-        sendMsg(msglist);
+        msglist.stream().forEach(m -> sendHandshakeMessage(m));
     }
 
     private void decodeAsyncGetReply(OFAsyncGetReply rep) {
@@ -245,21 +245,21 @@
         OFMessage gtf = factory.buildTableFeaturesStatsRequest()
                 .setXid(getNextTransactionId())
                 .build();
-        sendMsg(gtf);
+        sendHandshakeMessage(gtf);
     }
 
     private void sendGroupFeaturesRequest() throws IOException {
         OFMessage gfr = factory.buildGroupFeaturesStatsRequest()
                 .setXid(getNextTransactionId())
                 .build();
-        sendMsg(gfr);
+        sendHandshakeMessage(gfr);
     }
 
     private void sendGroupDescRequest() throws IOException {
         OFMessage gdr = factory.buildGroupDescStatsRequest()
                 .setXid(getNextTransactionId())
                 .build();
-        sendMsg(gdr);
+        sendHandshakeMessage(gdr);
     }
 
     /*Create L2 interface groups for all physical ports
@@ -290,12 +290,12 @@
                         .setGroupType(OFGroupType.INDIRECT)
                         .setXid(getNextTransactionId())
                         .build();
+                sendHandshakeMessage(gmAdd);
                 msglist.add(gmAdd);
                 l2groups.put(pnum, gl2);
             }
         }
         log.debug("Creating {} L2 groups in sw {}", msglist.size(), getStringId());
-        sendMsg(msglist);
     }
 
     private int getVlanConfig(int portnum) {
@@ -394,9 +394,10 @@
                     .setGroupType(OFGroupType.INDIRECT)
                     .setXid(getNextTransactionId())
                     .build();
-            msglist.add(gmAdd);
+            sendHandshakeMessage(gmAdd);
+
         }
-        sendMsg(msglist);
+
         log.debug("Creating {} L3 groups in sw {}", msglist.size(), getStringId());
     }
 
@@ -407,7 +408,7 @@
      * instead of the IP ttl
      */
     private void setL25Groups() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
+
         for (OFGroup gl2 : l2groups.values()) {
             int gnum = gl2.getGroupNumber();
             int portnum = gnum & 0x0000ffff;
@@ -445,11 +446,12 @@
                         .setGroupType(OFGroupType.INDIRECT)
                         .setXid(getNextTransactionId())
                         .build();
-                msglist.add(gmAdd);
+                sendHandshakeMessage(gmAdd);
+
             }
         }
-        sendMsg(msglist);
-        log.debug("Creating {} MPLS groups in sw {}", msglist.size(), getStringId());
+
+        log.debug("Created MPLS groups in sw {}", getStringId());
     }
 
     /* Using ECMP groups
@@ -560,13 +562,14 @@
                         .setHardTimeout(0)
                         .setXid(getNextTransactionId())
                         .build();
-                msglist.add(flowEntry);
+                sendHandshakeMessage(flowEntry);
+
             }
         }
         // table-vlan has no table-miss entry, and so packets that miss are
         // essentially dropped
-        sendMsg(msglist);
-        log.debug("Adding {} vlan-rules in sw {}", msglist.size(), getStringId());
+
+        log.debug("Added vlan-rules in sw {}", getStringId());
     }
 
     private void populateTableTMac() throws IOException {
@@ -617,7 +620,7 @@
         List<OFMessage> msglist = new ArrayList<OFMessage>(2);
         msglist.add(ipEntry);
         msglist.add(mplsEntry);
-        sendMsg(msglist);
+        msglist.stream().forEach(m -> sendHandshakeMessage(m));
     }
 
     private List<String> getMyIps() { // send to controller
@@ -762,10 +765,10 @@
                     .setHardTimeout(0)
                     .setXid(getNextTransactionId())
                     .build();
-            msglist.add(myIpEntry);
+            sendHandshakeMessage(myIpEntry);
+
         }
-        sendMsg(msglist);
-        log.debug("Adding {} my-ip-rules in sw {}", msglist.size(), getStringId());
+        log.debug("Added {} my-ip-rules in sw {}", getStringId());
     }
 
     private void populateMySubnets() throws IOException {
@@ -804,11 +807,10 @@
                     .setHardTimeout(0)
                     .setXid(getNextTransactionId())
                     .build();
-            msglist.add(myIpEntry);
+            sendHandshakeMessage(myIpEntry);
+
         }
-        sendMsg(msglist);
-        log.debug("Adding {} subnet-ip-rules in sw {}", msglist.size(), getStringId());
-        msglist.clear();
+        log.debug("Added subnet-ip-rules in sw {}", getStringId());
     }
 
     private void populateRoutes() throws IOException {
@@ -948,10 +950,10 @@
                     .setHardTimeout(0)
                     .setXid(getNextTransactionId())
                     .build();
+            sendHandshakeMessage(myMetaEntry);
             msglist.add(myMetaEntry);
 
         }
-        sendMsg(msglist);
         log.debug("Adding {} next-hop-router-rules in sw {}", msglist.size(),
                 getStringId());
 
@@ -1007,9 +1009,9 @@
                     .setHardTimeout(0)
                     .setXid(getNextTransactionId())
                     .build();
-            msglist.add(myIpEntry);
+            sendHandshakeMessage(myIpEntry);
         }
-        sendMsg(msglist);
+
         log.debug("Adding {} next-hop-host-rules in sw {}", msglist.size(), getStringId());
     }
 
@@ -1081,9 +1083,10 @@
                     .setHardTimeout(0)
                     .setXid(getNextTransactionId())
                     .build();
+            sendHandshakeMessage(myMplsEntry);
             msglist.add(myMplsEntry);
         }
-        sendMsg(msglist);
+
         log.debug("Adding {} mpls-forwarding-rules in sw {}", msglist.size(),
                 getStringId());
 
@@ -1166,7 +1169,7 @@
                 .setXid(getNextTransactionId())
                 .build();
 
-        sendMsg(tableMissEntry);
+        sendHandshakeMessage(tableMissEntry);
     }
 
     private void sendBarrier(boolean finalBarrier) {
@@ -1179,7 +1182,7 @@
                 .setXid(xid)
                 .build();
 
-        sendMsg(br);
+        sendHandshakeMessage(br);
     }
 
     @Override
diff --git a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
index 56d88b5..586deab 100644
--- a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
+++ b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
@@ -136,6 +136,12 @@
                                                    "a non role request message");
     }
 
+    public final void sendHandshakeMessage(OFMessage message) {
+        if (!this.isDriverHandshakeComplete()) {
+            channel.write(Collections.singletonList(message));
+        }
+    }
+
     @Override
     public final boolean isConnected() {
         return this.connected;
diff --git a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
index 365f525..ae3f8db 100644
--- a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
+++ b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
@@ -210,4 +210,12 @@
      */
     void sendRoleRequest(OFMessage message);
 
+    /**
+     * Allows the handshaker behaviour to send messages during the
+     * handshake phase only.
+     *
+     * @param message an OpenFlow message
+     */
+    void sendHandshakeMessage(OFMessage message);
+
 }
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
index 06929d2..ad10783 100644
--- a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
@@ -229,6 +229,10 @@
         }
 
         @Override
+        public void sendHandshakeMessage(OFMessage message) {
+        }
+
+        @Override
         public boolean connectSwitch() {
             return false;
         }