Avoiding NPE by checking for segment router configuration during sub-driver handshake.
Adding a config file used for 10 switch SR demo.

Change-Id: I3122cdadee2ef73df489550370ef738423a6ab4f
diff --git a/conf/sr-ecmp10-demo.conf b/conf/sr-ecmp10-demo.conf
new file mode 100644
index 0000000..4d972c2
--- /dev/null
+++ b/conf/sr-ecmp10-demo.conf
@@ -0,0 +1,224 @@
+{
+  "comment": " 10 router 3 city topology description and configuration",
+  "restrictSwitches": true,
+  "restrictLinks": true,
+
+  "switchConfig":
+             [
+               { "nodeDpid": "00:01", "name": "SFO-ER1", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.1/32",
+                             "routerMac": "00:00:01:01:01:80",
+                             "nodeSid": 101,
+                             "isEdgeRouter" : true,
+                             "subnets": [
+                                         { "portNo": 1, "subnetIp": "10.0.1.128/24" }
+                                         ]
+                             }
+                 },
+
+               { "nodeDpid": "00:02", "name": "SFO-CR2", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.2/32",
+                             "routerMac": "00:00:02:02:02:80",
+                             "nodeSid": 102,
+                             "isEdgeRouter" : false,
+                             "adjacencySids": [
+                                               { "adjSid": 12453 , "ports": [ 2 ,3 ] }
+                                               ]
+                             }
+                 },
+
+               { "nodeDpid": "00:03", "name": "SFO-CR3", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.3/32",
+                             "routerMac": "00:00:03:03:03:80",
+                             "nodeSid": 103,
+                             "isEdgeRouter" : false
+		           }
+                 },
+
+		{ "nodeDpid": "00:04", "name": "Dallas-CR4", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.4/32",
+                             "routerMac": "00:00:04:04:04:80",
+                             "nodeSid": 104,
+                             "isEdgeRouter" : false
+                           }
+                 },
+
+		{ "nodeDpid": "00:05", "name": "Dallas-CR5", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.5/32",
+                             "routerMac": "00:00:05:05:05:80",
+                             "nodeSid": 105,
+                             "isEdgeRouter" : false
+                           }
+                 },
+
+		{ "nodeDpid": "00:06", "name": "Dallas-ER6", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.6/32",
+                             "routerMac": "00:00:07:07:07:80",
+                             "nodeSid": 106,
+                             "isEdgeRouter" : true,
+                             "subnets": [
+                                         { "portNo": 1, "subnetIp": "7.7.7.128/24" }
+                                         ]
+                             }
+                 },
+
+		{ "nodeDpid": "00:07", "name": "NewYork-ER7", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.7/32",
+                             "routerMac": "00:00:00:00:07:80",
+                             "nodeSid": 107,
+                             "isEdgeRouter" : true,
+                             "adjacencySids": [
+                                               { "adjSid": 12345 , "ports": [ 2 ,3 ] }
+                                               ],
+                             "subnets": [
+                                         { "portNo": 1, "subnetIp": "10.1.1.128/24" }
+                                         ]
+                             }
+                 },
+
+		{ "nodeDpid": "00:08", "name": "NewYork-CR8", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.8/32",
+                             "routerMac": "00:00:00:00:08:80",
+                             "nodeSid": 108,
+                             "isEdgeRouter" : false,
+                             "adjacencySids": [
+                                               { "adjSid": 88888, "ports": [ 3, 6, 4 ] }
+                                               ]
+
+                             } 
+                 },
+	
+		{ "nodeDpid": "00:09", "name": "NewYork-CR9", "type": "Router_SR", "allowed": true,
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.9/32",
+                             "routerMac": "00:00:00:00:09:80",
+                             "nodeSid": 109,
+                             "isEdgeRouter" : false
+                            }
+                 },
+
+		{ "nodeDpid": "00:0a", "name": "NewYork-ER10", "type": "Router_SR", "allowed": true,        
+                 "latitude": 80.80, "longitude": 90.10,
+                 "params": { "routerIp": "192.168.0.10/32",
+                             "routerMac": "00:00:00:00:0a:80",
+                             "nodeSid": 110,
+                             "isEdgeRouter" : true,
+                             "subnets": [
+                                         { "portNo": 1, "subnetIp": "10.1.2.128/24" }
+                                         ]
+                             }                 
+		}
+
+               ],
+
+  "linkConfig":[
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "01", "nodeDpid2": "02",
+                  "params": { "port1": 2, "port2": 1 }
+                  },
+
+               { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "01", "nodeDpid2": "03",
+                  "params": { "port1": 3, "port2": 1 }
+                  },
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "02", "nodeDpid2": "03",
+                  "params": { "port1": 2, "port2": 2 }
+                  },
+
+		{ "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "02", "nodeDpid2": "05",
+                  "params": { "port1": 3, "port2": 1 }
+                  },
+
+		{ "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "03", "nodeDpid2": "04",
+                  "params": { "port1": 3, "port2": 1 }
+                  },
+
+		{ "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "04", "nodeDpid2": "05",
+                  "params": { "port1": 2, "port2": 2 }
+                  },
+
+		{ "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "04", "nodeDpid2": "06",
+                  "params": { "port1": 3, "port2": 2 }
+                  },
+
+		{ "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "05", "nodeDpid2": "06",
+                  "params": { "port1": 3, "port2": 3 }
+                  },
+
+		{ "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "07", "nodeDpid2": "08",
+                  "params": { "port1": 2, "port2": 1 }
+                  },
+                  
+
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "09", "nodeDpid2": "0a",
+                  "params": { "port1": 2, "port2": 2}
+                  },
+
+		{ "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "02", "nodeDpid2": "09",
+                  "params": { "port1": 4, "port2": 3 }
+                  },
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "02", "nodeDpid2": "08",
+                  "params": { "port1": 5, "port2": 3 }
+                  },
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "05", "nodeDpid2": "08",
+                  "params": { "port1": 4, "port2": 4 }
+                  },
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "08", "nodeDpid2": "0a",
+                  "params": { "port1": 5, "port2": 3}
+                  },
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "09", "nodeDpid2": "07",
+                  "params": { "port1": 4, "port2": 3}
+                  },		
+		
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "09", "nodeDpid2": "08",
+                  "params": { "port1": 1, "port2": 2}
+                  },		
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "01", "nodeDpid2": "03",
+                  "params": { "port1": 4, "port2": 4}
+                  },		
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "02", "nodeDpid2": "08",
+                  "params": { "port1": 6, "port2": 6}
+                  },		
+
+                { "type": "pktLink", "allowed": true,
+                  "nodeDpid1": "09", "nodeDpid2": "05",
+                  "params": { "port1": 5, "port2": 5}
+                  }
+
+	
+	]	
+
+}
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java
index 382513e..fa1e517 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java
@@ -185,7 +185,6 @@
     // OFSwitchImplBase
     // *****************************
 
-
     /* (non-Javadoc)
      * @see java.lang.Object#toString()
      */
@@ -238,139 +237,6 @@
         return driverState.toString();
     }
 
-    public void removePortFromGroups(PortNumber port) {
-        log.debug("removePortFromGroups: Remove port {} from Switch {}",
-                port, getStringId());
-        HashSet<NeighborSet> portNSSet = portNeighborSetMap.get(port);
-        if (portNSSet == null)
-        {
-            /* No Groups are created with this port yet */
-            log.warn("removePortFromGroups: No groups exist with Switch {} port {}",
-                            getStringId(), port);
-            return;
-        }
-        log.debug("removePortFromGroups: Neighborsets that the port {} is part"
-                + "of on Switch {} are {}",
-                port, getStringId(), portNSSet);
-
-        for (NeighborSet ns : portNSSet) {
-            /* Delete the first matched bucket */
-            EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
-            if (portEcmpInfo == null) {
-                /* No groups present for this neighbor set */
-                continue;
-            }
-            Iterator<BucketInfo> it = portEcmpInfo.buckets.iterator();
-            log.debug("removePortFromGroups: Group {} on Switch {} has {} buckets",
-                    portEcmpInfo.groupId, getStringId(),
-                    portEcmpInfo.buckets.size());
-            while (it.hasNext()) {
-                BucketInfo bucket = it.next();
-                if (bucket.outport.equals(port)) {
-                    it.remove();
-                }
-            }
-            log.debug("removePortFromGroups: Modifying Group on Switch {} "
-                    + "and Neighborset {} with {}",
-                    getStringId(), ns, portEcmpInfo);
-            modifyEcmpGroup(portEcmpInfo);
-        }
-        /* Don't delete the entry from portNeighborSetMap because
-          * when the port is up again this info is needed
-          */
-        return;
-    }
-
-    public void addPortToGroups(PortNumber port) {
-        log.debug("addPortToGroups: Add port {} to Switch {}",
-                port, getStringId());
-        if (!portEnabled((int) (port.value())))
-        {
-            log.warn("addPortToGroups: Switch {} port {} is not ACTIVE",
-                    getStringId(), port);
-            return;
-        }
-        HashSet<NeighborSet> portNSSet = portNeighborSetMap.get(port);
-        if (portNSSet == null) {
-            /* Unknown Port  */
-            log.warn("addPortToGroups: Switch {} port {} is unknown or "
-                    + "there were no groups existing with the neighbor dpid"
-                    + "that it is reachable through this port",
-                    getStringId(), port);
-            return;
-        }
-        log.debug("addPortToGroups: Neighborsets that the port {} is part"
-                + "of on Switch {} are {}",
-                port, getStringId(), portNSSet);
-
-        Dpid neighborDpid = portToNeighbors.get(port);
-        for (NeighborSet ns : portNSSet) {
-            EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
-            /* Find if this port is already part of any bucket
-             * in this group
-             * NOTE: This is needed because in some cases
-             * (such as for configured network nodes), both driver and
-             * application detect the network elements and creates the
-             * buckets in the same group. This check is to avoid
-             * duplicate bucket creation in such scenarios
-             */
-            List<BucketInfo> buckets = null;
-
-            if (portEcmpInfo != null) {
-                buckets = portEcmpInfo.buckets;
-                if (buckets == null) {
-                    buckets = new ArrayList<BucketInfo>();
-                    portEcmpInfo.buckets = buckets;
-                } else {
-                    Iterator<BucketInfo> it = buckets.iterator();
-                    boolean matchingBucketExist = false;
-                    while (it.hasNext()) {
-                        BucketInfo bucket = it.next();
-                        if (bucket.outport.equals(port)) {
-                            matchingBucketExist = true;
-                            break;
-                        }
-                    }
-                    if (matchingBucketExist) {
-                        log.warn("addPortToGroups: On Switch {} duplicate "
-                                + "portAdd is called for port {} with buckets {}",
-                                getStringId(), port, buckets);
-                        continue;
-                    }
-                }
-            }
-            else
-            {
-                /* The group is getting created for the first time
-                 * for this neighborset
-                 */
-                buckets = new ArrayList<BucketInfo>();
-            }
-            BucketInfo b = new BucketInfo(neighborDpid,
-                    MacAddress.of(srConfig.getRouterMac()),
-                    getNeighborRouterMacAddress(neighborDpid, ns.getOutPktType()),
-                    port,
-                    ns.getEdgeLabel(), true, -1);
-            buckets.add(b);
-            if (portEcmpInfo != null) {
-                log.debug("addPortToGroups: Modifying Group on Switch {} "
-                        + "and Neighborset {} with {}",
-                        getStringId(), ns, portEcmpInfo);
-                modifyEcmpGroup(portEcmpInfo);
-            }
-            else {
-                int groupId = groupid.incrementAndGet();
-                portEcmpInfo = new EcmpInfo(groupId, OFGroupType.SELECT, buckets);
-                log.debug("addPortToGroups: Creating Group on Switch {} "
-                        + "and Neighborset {} with {}",
-                        getStringId(), ns, portEcmpInfo);
-                setEcmpGroup(portEcmpInfo);
-            }
-
-        }
-        return;
-    }
-
     @Override
     public OrderedCollection<PortChangeEvent> processOFPortStatus(OFPortStatus ps) {
         OrderedCollection<PortChangeEvent> events = super.processOFPortStatus(ps);
@@ -420,7 +286,10 @@
             break;
         case SET_TABLE_MISS_ENTRIES:
             driverState = DriverState.SET_TABLE_VLAN_TMAC;
-            getNetworkConfig();
+            boolean isConfigured = getNetworkConfig();
+            if (!isConfigured) {
+                return; // this will result in a handshake timeout
+            }
             populateTableVlan();
             populateTableTMac();
             sendHandshakeBarrier();
@@ -651,16 +520,20 @@
         write(tableMissEntry, null);
     }
 
-    private void getNetworkConfig() {
+    private boolean getNetworkConfig() {
         INetworkConfigService ncs = floodlightProvider.getNetworkConfigService();
         SwitchConfigStatus scs = ncs.checkSwitchConfig(new Dpid(getId()));
-        if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
-            srConfig = (SegmentRouterConfig) scs.getSwitchConfig();
-            isEdgeRouter = srConfig.isEdgeRouter();
-        } else {
-            log.error("Switch not configured as Segment-Router");
+        if (scs.getConfigState() != NetworkConfigState.ACCEPT_ADD) {
+            log.error("Switch {} is not configured as Segment-Router.. aborting",
+                    getStringId());
+            return false;
         }
-
+        srConfig = (SegmentRouterConfig) scs.getSwitchConfig();
+        if (srConfig == null) {
+            log.error("Switch {} configuration is null.. aborting", getStringId());
+            return false;
+        }
+        isEdgeRouter = srConfig.isEdgeRouter();
         List<LinkConfig> linkConfigList = ncs.getConfiguredAllowedLinks();
         setNeighbors(linkConfigList);
 
@@ -668,6 +541,7 @@
             List<SwitchConfig> switchList = ncs.getConfiguredAllowedSwitches();
             getAllNodeSegmentIds(switchList);
         }
+        return true;
     }
 
     private void populateTableVlan() throws IOException {
@@ -2049,6 +1923,139 @@
         return publishAttributes;
     }
 
+    public void removePortFromGroups(PortNumber port) {
+        log.debug("removePortFromGroups: Remove port {} from Switch {}",
+                port, getStringId());
+        HashSet<NeighborSet> portNSSet = portNeighborSetMap.get(port);
+        if (portNSSet == null)
+        {
+            /* No Groups are created with this port yet */
+            log.warn("removePortFromGroups: No groups exist with Switch {} port {}",
+                    getStringId(), port);
+            return;
+        }
+        log.debug("removePortFromGroups: Neighborsets that the port {} is part"
+                + "of on Switch {} are {}",
+                port, getStringId(), portNSSet);
+
+        for (NeighborSet ns : portNSSet) {
+            /* Delete the first matched bucket */
+            EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
+            if (portEcmpInfo == null) {
+                /* No groups present for this neighbor set */
+                continue;
+            }
+            Iterator<BucketInfo> it = portEcmpInfo.buckets.iterator();
+            log.debug("removePortFromGroups: Group {} on Switch {} has {} buckets",
+                    portEcmpInfo.groupId, getStringId(),
+                    portEcmpInfo.buckets.size());
+            while (it.hasNext()) {
+                BucketInfo bucket = it.next();
+                if (bucket.outport.equals(port)) {
+                    it.remove();
+                }
+            }
+            log.debug("removePortFromGroups: Modifying Group on Switch {} "
+                    + "and Neighborset {} with {}",
+                    getStringId(), ns, portEcmpInfo);
+            modifyEcmpGroup(portEcmpInfo);
+        }
+        /* Don't delete the entry from portNeighborSetMap because
+          * when the port is up again this info is needed
+          */
+        return;
+    }
+
+    public void addPortToGroups(PortNumber port) {
+        log.debug("addPortToGroups: Add port {} to Switch {}",
+                port, getStringId());
+        if (!portEnabled((int) (port.value())))
+        {
+            log.warn("addPortToGroups: Switch {} port {} is not ACTIVE",
+                    getStringId(), port);
+            return;
+        }
+        HashSet<NeighborSet> portNSSet = portNeighborSetMap.get(port);
+        if (portNSSet == null) {
+            /* Unknown Port  */
+            log.warn("addPortToGroups: Switch {} port {} is unknown or "
+                    + "there were no groups existing with the neighbor dpid"
+                    + "that it is reachable through this port",
+                    getStringId(), port);
+            return;
+        }
+        log.debug("addPortToGroups: Neighborsets that the port {} is part"
+                + "of on Switch {} are {}",
+                port, getStringId(), portNSSet);
+
+        Dpid neighborDpid = portToNeighbors.get(port);
+        for (NeighborSet ns : portNSSet) {
+            EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
+            /* Find if this port is already part of any bucket
+             * in this group
+             * NOTE: This is needed because in some cases
+             * (such as for configured network nodes), both driver and
+             * application detect the network elements and creates the
+             * buckets in the same group. This check is to avoid
+             * duplicate bucket creation in such scenarios
+             */
+            List<BucketInfo> buckets = null;
+
+            if (portEcmpInfo != null) {
+                buckets = portEcmpInfo.buckets;
+                if (buckets == null) {
+                    buckets = new ArrayList<BucketInfo>();
+                    portEcmpInfo.buckets = buckets;
+                } else {
+                    Iterator<BucketInfo> it = buckets.iterator();
+                    boolean matchingBucketExist = false;
+                    while (it.hasNext()) {
+                        BucketInfo bucket = it.next();
+                        if (bucket.outport.equals(port)) {
+                            matchingBucketExist = true;
+                            break;
+                        }
+                    }
+                    if (matchingBucketExist) {
+                        log.warn("addPortToGroups: On Switch {} duplicate "
+                                + "portAdd is called for port {} with buckets {}",
+                                getStringId(), port, buckets);
+                        continue;
+                    }
+                }
+            }
+            else
+            {
+                /* The group is getting created for the first time
+                 * for this neighborset
+                 */
+                buckets = new ArrayList<BucketInfo>();
+            }
+            BucketInfo b = new BucketInfo(neighborDpid,
+                    MacAddress.of(srConfig.getRouterMac()),
+                    getNeighborRouterMacAddress(neighborDpid, ns.getOutPktType()),
+                    port,
+                    ns.getEdgeLabel(), true, -1);
+            buckets.add(b);
+            if (portEcmpInfo != null) {
+                log.debug("addPortToGroups: Modifying Group on Switch {} "
+                        + "and Neighborset {} with {}",
+                        getStringId(), ns, portEcmpInfo);
+                modifyEcmpGroup(portEcmpInfo);
+            }
+            else {
+                int groupId = groupid.incrementAndGet();
+                portEcmpInfo = new EcmpInfo(groupId, OFGroupType.SELECT, buckets);
+                log.debug("addPortToGroups: Creating Group on Switch {} "
+                        + "and Neighborset {} with {}",
+                        getStringId(), ns, portEcmpInfo);
+                setEcmpGroup(portEcmpInfo);
+            }
+
+        }
+        return;
+    }
+
     // *****************************
     // Unused
     // *****************************