configurable xranc bind address and cleanup functions
diff --git a/src/main/java/org.onosproject.xran/controller/Controller.java b/src/main/java/org.onosproject.xran/controller/Controller.java
index 946a1bd..e8caacc 100644
--- a/src/main/java/org.onosproject.xran/controller/Controller.java
+++ b/src/main/java/org.onosproject.xran/controller/Controller.java
@@ -25,6 +25,7 @@
 import io.netty.channel.sctp.nio.NioSctpServerChannel;
 import io.netty.handler.logging.LogLevel;
 import io.netty.handler.logging.LoggingHandler;
+import org.onlab.packet.IpAddress;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -40,6 +41,7 @@
     private EventLoopGroup workerGroup;
     private ChannelFuture channel;
     private int port = 8007;
+    private IpAddress bindAddress = IpAddress.valueOf("0.0.0.0");
     private boolean isRunning = false;
 
     /**
@@ -58,7 +60,7 @@
                     );
                 }
             });
-            channel = b.bind(this.port).sync();
+            channel = b.bind(this.bindAddress.toInetAddress(), this.port).sync();
         } catch (Exception e) {
             log.warn(e.getMessage());
             e.printStackTrace();
@@ -83,25 +85,28 @@
 
     /**
      * Initialize controller and start SCTP server.
-     *
-     * @param deviceAgent device agent
+     *  @param deviceAgent device agent
      * @param hostAgent   host agent
      * @param packetAgent packet agent
+     * @param xrancIp
      * @param port        port of server
      */
-    public void start(XranDeviceAgent deviceAgent, XranHostAgent hostAgent, XranPacketProcessor packetAgent, int port) {
-        if (isRunning && this.port != port) {
+    public void start(XranDeviceAgent deviceAgent, XranHostAgent hostAgent, XranPacketProcessor packetAgent,
+                      IpAddress xrancIp, int port) {
+        if (isRunning && (this.port != port || !this.bindAddress.equals(xrancIp))) {
             stop();
             this.deviceAgent = deviceAgent;
             this.hostAgent = hostAgent;
             this.packetAgent = packetAgent;
             this.port = port;
+            this.bindAddress = xrancIp;
             run();
         } else if (!isRunning) {
             this.deviceAgent = deviceAgent;
             this.hostAgent = hostAgent;
             this.packetAgent = packetAgent;
             this.port = port;
+            this.bindAddress = xrancIp;
             run();
             isRunning = true;
         }
diff --git a/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java b/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
index 47af1f1..0aac291 100644
--- a/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
+++ b/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
@@ -209,19 +209,45 @@
 
     @Deactivate
     public void deactivate() {
-        controller.stop();
-
         deviceService.removeListener(deviceListener);
         hostService.removeListener(hostListener);
-
-        legitCells.clear();
-
         configService.removeListener(configListener);
         registry.unregisterConfigFactory(xranConfigFactory);
 
+        cleanup();
+
         log.info("XRAN Controller Stopped");
     }
 
+    private void cleanup() {
+        xranStore.getuenodes().forEach(ue -> {
+            for (XranHostListener l : xranHostListeners) {
+                l.hostRemoved(((RnibUe) ue).getHostId());
+            }
+        });
+
+        xranStore.getcellnodes().forEach(cell -> {
+            for (XranDeviceListener l : xranDeviceListeners) {
+                l.deviceRemoved(deviceId(uri(((RnibCell) cell).getEcgi())));
+            }
+        });
+
+        controller.stop();
+
+        legitCells.clear();
+        hoMap.clear();
+        rrmcellMap.clear();
+        scellAddMap.clear();
+        contextUpdateMap.clear();
+        ueIdQueue.clear();
+        xranDeviceListeners.clear();
+        xranHostListeners.clear();
+
+        cellMap = null;
+        ueMap = null;
+        linkMap = null;
+    }
+
     @Override
     public SynchronousQueue<String> sendHORequest(RnibLink linkT, RnibLink linkS) throws InterruptedException {
         ECGI ecgiT = linkT.getLinkId().getEcgi(),
@@ -838,7 +864,8 @@
 
         /**
          * Handle Cellconfigreport.
-         * @param report CellConfigReport
+         *
+         * @param report  CellConfigReport
          * @param version String version ID
          */
         private void handleCellconfigreport(CellConfigReport report, String version) {
@@ -852,8 +879,9 @@
 
         /**
          * Handle Ueadmissionrequest.
+         *
          * @param ueAdmissionRequest UEAdmissionRequest
-         * @param ctx ChannelHandlerContext
+         * @param ctx                ChannelHandlerContext
          * @throws IOException IO Exception
          */
         private void handleUeadmissionrequest(UEAdmissionRequest ueAdmissionRequest, ChannelHandlerContext ctx)
@@ -870,8 +898,9 @@
 
         /**
          * Handle UEAdmissionStatus.
+         *
          * @param ueAdmissionStatus UEAdmissionStatus
-         * @param ctx ChannelHandlerContext
+         * @param ctx               ChannelHandlerContext
          */
         private void handleAdmissionstatus(UEAdmissionStatus ueAdmissionStatus, ChannelHandlerContext ctx) {
             RnibUe ue = ueMap.get(ueAdmissionStatus.getEcgi(), ueAdmissionStatus.getCrnti());
@@ -901,8 +930,9 @@
 
         /**
          * Handle UEContextUpdate.
+         *
          * @param ueContextUpdate UEContextUpdate
-         * @param ctx ChannelHandlerContext
+         * @param ctx             ChannelHandlerContext
          */
         private void handleUecontextupdate(UEContextUpdate ueContextUpdate, ChannelHandlerContext ctx) {
             EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair
@@ -933,6 +963,7 @@
 
         /**
          * Handle UEReconfigInd.
+         *
          * @param ueReconfigInd UEReconfigInd
          */
         private void handleUereconfigind(UEReconfigInd ueReconfigInd) {
@@ -949,6 +980,7 @@
 
         /**
          * Handle UEReleaseInd.
+         *
          * @param ueReleaseInd UEReleaseInd
          */
         private void handleUereleaseind(UEReleaseInd ueReleaseInd) {
@@ -975,8 +1007,9 @@
 
         /**
          * Handle BearerAdmissionRequest.
+         *
          * @param bearerAdmissionRequest BearerAdmissionRequest
-         * @param ctx ChannelHandlerContext
+         * @param ctx                    ChannelHandlerContext
          * @throws IOException IO Exception
          */
         private void handleBeareradmissionrequest(BearerAdmissionRequest bearerAdmissionRequest,
@@ -1000,6 +1033,7 @@
 
         /**
          * Handle BearerReleaseInd.
+         *
          * @param bearerReleaseInd
          */
         private void handleBearerreleaseind(BearerReleaseInd bearerReleaseInd) {
@@ -1023,6 +1057,7 @@
 
         /**
          * Handle HOFailure.
+         *
          * @param hoFailure HOFailure
          * @throws InterruptedException ueIdQueue interruption
          */
@@ -1041,8 +1076,9 @@
 
         /**
          * Handle HOComplete.
+         *
          * @param hoComplete HOComplete
-         * @param ctx ChannelHandlerContext
+         * @param ctx        ChannelHandlerContext
          */
         private void handleHocomplete(HOComplete hoComplete, ChannelHandlerContext ctx) {
             EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair.valueOf(hoComplete.getEcgiT(),
@@ -1070,6 +1106,7 @@
 
         /**
          * Handle RXSigMeasReport.
+         *
          * @param rxSigMeasReport RXSigMeasReport
          */
         private void handleRxsigmeasreport(RXSigMeasReport rxSigMeasReport) {
@@ -1117,6 +1154,7 @@
 
         /**
          * Handle RadioMeasReportPerUE.
+         *
          * @param radioMeasReportPerUE RadioMeasReportPerUE
          */
         private void handleRadionmeasreportperue(RadioMeasReportPerUE radioMeasReportPerUE) {
@@ -1161,6 +1199,7 @@
 
         /**
          * Handle SchedMeasReportPerUE.
+         *
          * @param schedMeasReportPerUE SchedMeasReportPerUE
          */
         private void handleSchedmeasreportperue(SchedMeasReportPerUE schedMeasReportPerUE) {
@@ -1197,6 +1236,7 @@
 
         /**
          * Handle SchedMeasReportPerCell.
+         *
          * @param schedMeasReportPerCell SchedMeasReportPerCell
          */
         private void handleSchedmeasreportpercell(SchedMeasReportPerCell schedMeasReportPerCell) {
@@ -1215,6 +1255,7 @@
 
         /**
          * Handle PDCPMeasReportPerUe.
+         *
          * @param pdcpMeasReportPerUe PDCPMeasReportPerUe
          */
         private void handlePdcpmeasreportperue(PDCPMeasReportPerUe pdcpMeasReportPerUe) {
@@ -1240,6 +1281,7 @@
 
         /**
          * Handle UECapabilityInfo.
+         *
          * @param capabilityInfo UECapabilityInfo
          */
         private void handleCapabilityinfo(UECapabilityInfo capabilityInfo) {
@@ -1253,8 +1295,9 @@
 
         /**
          * Handle UECapabilityEnquiry.
+         *
          * @param ueCapabilityEnquiry UECapabilityEnquiry
-         * @param ctx ChannelHandlerContext
+         * @param ctx                 ChannelHandlerContext
          * @throws IOException IO Exception
          */
         private void handleUecapabilityenquiry(UECapabilityEnquiry ueCapabilityEnquiry, ChannelHandlerContext ctx)
@@ -1266,6 +1309,7 @@
 
         /**
          * Handle ScellAddStatus.
+         *
          * @param scellAddStatus ScellAddStatus
          */
         private void handleScelladdstatus(ScellAddStatus scellAddStatus) {
@@ -1298,6 +1342,7 @@
 
         /**
          * Handle RRMConfigStatus.
+         *
          * @param rrmConfigStatus RRMConfigStatus
          */
         private void handleRrmconfigstatus(RRMConfigStatus rrmConfigStatus) {
@@ -1314,6 +1359,7 @@
 
         /**
          * Handle TrafficSplitConfig.
+         *
          * @param trafficSplitConfig TrafficSplitConfig
          */
         private void handleTrafficSplitConfig(TrafficSplitConfig trafficSplitConfig) {
@@ -1411,7 +1457,7 @@
 
             legitCells.putAll(xranConfig.activeCellSet());
 
-            controller.start(deviceAgent, hostAgent, packetAgent, xranConfig.getXrancPort());
+            controller.start(deviceAgent, hostAgent, packetAgent, xranConfig.getXrancIp(), xranConfig.getXrancPort());
         }
     }
 }
diff --git a/src/main/java/org.onosproject.xran/identifiers/ContextUpdateHandler.java b/src/main/java/org.onosproject.xran/identifiers/ContextUpdateHandler.java
index d1fcfcf..4212044 100644
--- a/src/main/java/org.onosproject.xran/identifiers/ContextUpdateHandler.java
+++ b/src/main/java/org.onosproject.xran/identifiers/ContextUpdateHandler.java
@@ -42,10 +42,11 @@
      * @return boolean to check context update was for admissionStatus packet or HOComplete packet
      */
     public boolean setContextUpdate(UEContextUpdate contextUpdate) {
-        this.contextUpdate = contextUpdate;
+        synchronized (this) {
+            this.contextUpdate = contextUpdate;
 
-        return admissionStatus != null || hoComplete != null;
-
+            return admissionStatus != null || hoComplete != null;
+        }
     }
 
     /**
@@ -62,9 +63,11 @@
      * @return boolean contextUpdate exists or not
      */
     public boolean setAdmissionStatus(UEAdmissionStatus admissionStatus) {
-        this.admissionStatus = admissionStatus;
+        synchronized (this) {
+            this.admissionStatus = admissionStatus;
 
-        return contextUpdate != null;
+            return contextUpdate != null;
+        }
     }
 
     /**
@@ -81,15 +84,19 @@
      * @return boolean contextUpdate exists or not
      */
     public boolean setHoComplete(HOComplete hoComplete) {
-        this.hoComplete = hoComplete;
+        synchronized (this) {
+            this.hoComplete = hoComplete;
 
-        return contextUpdate != null;
+            return contextUpdate != null;
+        }
     }
 
     public void reset() {
-        this.hoComplete = null;
-        this.admissionStatus = null;
-        this.contextUpdate = null;
+        synchronized (this) {
+            this.hoComplete = null;
+            this.admissionStatus = null;
+            this.contextUpdate = null;
+        }
     }
 
     @Override
diff --git a/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java b/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java
index 9a1a259..f7e2c07 100644
--- a/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java
+++ b/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java
@@ -65,7 +65,6 @@
     private ConcurrentMap<Long, RnibUe> ueMap = new ConcurrentHashMap<>();
     private ConcurrentMap<Object, RnibSlice> sliceMap = new ConcurrentHashMap<>();
     private XranController controller;
-
     private IdGenerator ueIdGenerator;
 
     @Activate
@@ -80,6 +79,12 @@
 
     @Deactivate
     public void deactivate() {
+        linkMap.clear();
+        cellMap.clear();
+        ueMap.clear();
+        sliceMap.clear();
+        controller = null;
+        ueIdGenerator = null;
         log.info("XRAN Default Store Stopped");
     }
 
@@ -99,7 +104,6 @@
                         .filter(k -> k.getEcgi().equals(ecgi))
                         .map(v -> linkMap.get(v))
                         .collect(Collectors.toList()));
-
         return list;
     }
 
diff --git a/src/main/java/org.onosproject.xran/impl/XranConfig.java b/src/main/java/org.onosproject.xran/impl/XranConfig.java
index e334892..ef83194 100644
--- a/src/main/java/org.onosproject.xran/impl/XranConfig.java
+++ b/src/main/java/org.onosproject.xran/impl/XranConfig.java
@@ -47,6 +47,8 @@
 
     private static final String IP_ADDR = "ip_addr";
 
+    private static final String XRANC_IP = "xranc_bind_ip";
+
     private static final String XRANC_PORT = "xranc_port";
 
     private static final String XRANC_CELLCONFIG_INTERVAL = "xranc_cellconfigrequest_interval_seconds";
@@ -115,6 +117,13 @@
     }
 
     /**
+     * Get IP where the Controller binds to.
+     *
+     * @return IP address in configuration
+     */
+    public IpAddress getXrancIp() { return IpAddress.valueOf(object.get(XRANC_IP).asText()); }
+
+    /**
      * Get port for xRAN controller server to bind to from configuration.
      *
      * @return port number
diff --git a/xran-cfg.json b/xran-cfg.json
index 099ad19..e2f4dec 100644
--- a/xran-cfg.json
+++ b/xran-cfg.json
@@ -6,26 +6,22 @@
           {
             "plmn_id": "000001",
             "eci": "00000010",
-            "ip_addr": "10.10.10.1"
+            "ip_addr": "1.1.1.2"
           },
           {
             "plmn_id": "000002",
             "eci": "00000020",
-            "ip_addr": "172.16.27.100"
-          },
-          {
-            "plmn_id": "000003",
-            "eci": "00000030",
             "ip_addr": "1.1.1.3"
           }
         ],
         "l2_meas_report_interval_ms": 5000,
         "rx_signal_meas_report_interval_ms": 7000,
         "xranc_cellconfigrequest_interval_seconds": 10,
+        "xranc_bind_ip": "1.1.1.1",
         "xranc_port": 7891,
         "admission_success": true,
         "bearer_success": true,
-        "no_meas_link_removal_ms": 10000,
+        "no_meas_link_removal_ms": 1000000,
         "idle_ue_removal_ms": 1,
         "nb_response_timeout_ms": 10000
       }