[VOL-1036] Initial implementation of device lifecycle management

Change-Id: I5aa58fdcbcd852f6f5eef35d48f25f76e20c0418
diff --git a/adapters/iadapter.py b/adapters/iadapter.py
index c6ea3ca..3388d5a 100644
--- a/adapters/iadapter.py
+++ b/adapters/iadapter.py
@@ -83,12 +83,16 @@
         raise NotImplementedError()
 
     def get_ofp_device_info(self, device):
-        log.debug('get_ofp_device_info', device_id=device.id)
-        return self.devices_handlers[device.id].get_ofp_device_info(device)
+        log.debug('get_ofp_device_info_start', device_id=device.id)
+        ofp_device_info = self.devices_handlers[device.id].get_ofp_device_info(device)
+        log.debug('get_ofp_device_info_ends', device_id=device.id)
+        return ofp_device_info
 
     def get_ofp_port_info(self, device, port_no):
-        log.debug('get_ofp_port_info', device_id=device.id, port_no=port_no)
-        return self.devices_handlers[device.id].get_ofp_port_info(device, port_no)
+        log.debug('get_ofp_port_info_start', device_id=device.id, port_no=port_no)
+        ofp_port_info = self.devices_handlers[device.id].get_ofp_port_info(device, port_no)
+        log.debug('get_ofp_port_info_ends', device_id=device.id, port_no=port_no)
+        return ofp_port_info
 
     def adopt_device(self, device):
         log.debug('adopt_device', device_id=device.id)
@@ -105,7 +109,8 @@
 
     def disable_device(self, device):
         log.info('disable-device', device_id=device.id)
-        reactor.callLater(0, self.devices_handlers[device.id].disable)
+        reactor.callLater(1, self.devices_handlers[device.id].disable)
+        log.debug('disable_device_done', device_id=device.id)
         return device
 
     def reenable_device(self, device):
diff --git a/adapters/kafka/adapter_request_facade.py b/adapters/kafka/adapter_request_facade.py
index 74ed934..2517a31 100644
--- a/adapters/kafka/adapter_request_facade.py
+++ b/adapters/kafka/adapter_request_facade.py
@@ -82,17 +82,17 @@
         d = Device()
         if device:
             device.Unpack(d)
-            return (True, self.adapter.adopt_device(d))
+            return True, self.adapter.adopt_device(d)
         else:
-            return (False, d)
+            return False, d
 
     def get_ofp_device_info(self, device):
         d = Device()
         if device:
             device.Unpack(d)
-            return (True, self.adapter.get_ofp_device_info(d))
+            return True, self.adapter.get_ofp_device_info(d)
         else:
-            return (False, d)
+            return False, d
 
     def get_ofp_port_info(self, device, port_no):
         d = Device()
@@ -104,7 +104,7 @@
         p = IntType()
         port_no.Unpack(p)
 
-        return (True, self.adapter.get_ofp_port_info(d, p.val))
+        return True, self.adapter.get_ofp_port_info(d, p.val)
 
 
     def reconcile_device(self, device):
@@ -114,10 +114,20 @@
         return self.adapter.abandon_device(device)
 
     def disable_device(self, device):
-        return self.adapter.disable_device(device)
+        d = Device()
+        if device:
+            device.Unpack(d)
+            return True, self.adapter.disable_device(d)
+        else:
+            return False, d
 
     def reenable_device(self, device):
-        return self.adapter.reenable_device(device)
+        d = Device()
+        if device:
+            device.Unpack(d)
+            return True, self.adapter.reenable_device(d)
+        else:
+            return False, d
 
     def reboot_device(self, device):
         d = Device()
diff --git a/adapters/kafka/core_proxy.py b/adapters/kafka/core_proxy.py
index bcc4239..32a4c9d 100644
--- a/adapters/kafka/core_proxy.py
+++ b/adapters/kafka/core_proxy.py
@@ -32,18 +32,18 @@
 from adapters.common.utils.id_generation import create_cluster_logical_device_ids
 from adapters.interface import IAdapterInterface
 from adapters.protos import third_party
-from adapters.protos.device_pb2 import Device, Port, PmConfigs
+from adapters.protos.device_pb2 import Device, Port, Ports, PmConfigs
 from adapters.protos.events_pb2 import AlarmEvent, AlarmEventType, \
     AlarmEventSeverity, AlarmEventState, AlarmEventCategory
 from adapters.protos.events_pb2 import KpiEvent
 from adapters.protos.voltha_pb2 import DeviceGroup, LogicalDevice, \
-    LogicalPort, AdminState, OperStatus, AlarmFilterRuleKey, CoreInstance
+    LogicalPort, AlarmFilterRuleKey, CoreInstance
 from adapters.common.utils.registry import registry, IComponent
 from adapters.common.utils.id_generation import create_cluster_device_id
 import re
 from adapters.interface import ICoreSouthBoundInterface
 from adapters.protos.core_adapter_pb2 import StrType, BoolType, IntType
-from adapters.protos.common_pb2 import ID
+from adapters.protos.common_pb2 import ID, ConnectStatus, OperStatus
 from google.protobuf.message import Message
 from adapters.common.utils.deferred_utils import DeferredWithTimeout, TimeOutError
 
@@ -159,8 +159,17 @@
     # def add_device(self, device):
     #     raise NotImplementedError()
 
+    @wrap_request(Ports)
+    @inlineCallbacks
     def get_ports(self, device_id, port_type):
-        raise NotImplementedError()
+        id = ID()
+        id.id = device_id
+        p_type = IntType()
+        p_type.val = port_type
+        res = yield self.invoke(rpc="GetPorts",
+                                device_id=id,
+                                port_type=p_type)
+        returnValue(res)
 
     def get_child_devices(self, parent_device_id):
         raise NotImplementedError()
@@ -231,20 +240,18 @@
     def device_state_update(self, device_id,
                                    oper_status=None,
                                    connect_status=None):
-
         id = ID()
         id.id = device_id
         o_status = IntType()
-        if oper_status:
+        if oper_status or oper_status==OperStatus.UNKNOWN:
             o_status.val = oper_status
         else:
             o_status.val = -1
         c_status = IntType()
-        if connect_status:
+        if connect_status or connect_status==ConnectStatus.UNKNOWN:
             c_status.val = connect_status
         else:
             c_status.val = -1
-        a_status = IntType()
 
         res = yield self.invoke(rpc="DeviceStateUpdate",
                                 device_id=id,
@@ -254,34 +261,52 @@
 
     @wrap_request(None)
     @inlineCallbacks
+    def port_state_update(self,
+                          device_id,
+                          port_type,
+                          port_no,
+                          oper_status):
+        id = ID()
+        id.id = device_id
+        pt = IntType()
+        pt.val = port_type
+        pNo = IntType()
+        pNo.val = port_no
+        o_status = IntType()
+        o_status.val = oper_status
+
+        res = yield self.invoke(rpc="PortStateUpdate",
+                                device_id=id,
+                                port_type=pt,
+                                port_no=pNo,
+                                oper_status=o_status)
+        returnValue(res)
+
+
+
+    @wrap_request(None)
+    @inlineCallbacks
     def child_devices_state_update(self, parent_device_id,
                                    oper_status=None,
-                                   connect_status=None,
-                                   admin_state=None):
+                                   connect_status=None):
 
         id = ID()
         id.id = parent_device_id
         o_status = IntType()
-        if oper_status:
+        if oper_status or oper_status==OperStatus.UNKNOWN:
             o_status.val = oper_status
         else:
             o_status.val = -1
         c_status = IntType()
-        if connect_status:
+        if connect_status or connect_status==ConnectStatus.UNKNOWN:
             c_status.val = connect_status
         else:
             c_status.val = -1
-        a_status = IntType()
-        if admin_state:
-            a_status.val = admin_state
-        else:
-            a_status.val = -1
 
         res = yield self.invoke(rpc="child_devices_state_update",
                                 parent_device_id=id,
                                 oper_status=o_status,
-                                connect_status=c_status,
-                                admin_state=a_status)
+                                connect_status=c_status)
         returnValue(res)
 
 
diff --git a/adapters/ponsim_olt/ponsim_olt.py b/adapters/ponsim_olt/ponsim_olt.py
index 5e096b4..95bafaa 100644
--- a/adapters/ponsim_olt/ponsim_olt.py
+++ b/adapters/ponsim_olt/ponsim_olt.py
@@ -25,7 +25,7 @@
 import structlog
 from scapy.layers.l2 import Ether, Dot1Q
 from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks
+from twisted.internet.defer import inlineCallbacks, returnValue
 from grpc._channel import _Rendezvous
 
 from adapters.common.frameio.frameio import BpfProgramFilter, hexify
@@ -245,11 +245,10 @@
 
             self.log.info('grpc-channel-closed')
 
+    @inlineCallbacks
     def _get_nni_port(self):
-        ports = self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_NNI)
-        if ports:
-            # For now, we use on one NNI port
-            return ports[0]
+        ports = yield self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_NNI)
+        returnValue(ports)
 
     @inlineCallbacks
     def activate(self, device):
@@ -272,7 +271,8 @@
             device.vendor = 'ponsim'
             device.model = 'n/a'
             device.serial_number = device.host_and_port
-            device.connect_status = ConnectStatus.REACHABLE
+            device.mac_address = "AA:BB:CC:DD:EE:FF"
+            # device.connect_status = ConnectStatus.REACHABLE
             yield self.adapter_agent.device_update(device)
 
             # Now set the initial PM configuration for this device
@@ -288,7 +288,7 @@
                 port_no=info.nni_port,
                 label='NNI facing Ethernet port',
                 type=Port.ETHERNET_NNI,
-                admin_state=AdminState.ENABLED,
+                # admin_state=AdminState.ENABLED,
                 oper_status=OperStatus.ACTIVE
             )
             self.nni_port = nni_port
@@ -297,10 +297,11 @@
                 port_no=1,
                 label='PON port',
                 type=Port.PON_OLT,
-                admin_state=AdminState.ENABLED,
+                # admin_state=AdminState.ENABLED,
                 oper_status=OperStatus.ACTIVE
             ))
-            yield self.adapter_agent.device_state_update(device.id, oper_status=OperStatus.ACTIVE)
+
+            yield self.adapter_agent.device_state_update(device.id, connect_status=ConnectStatus.REACHABLE, oper_status=OperStatus.ACTIVE)
 
             # register ONUS
             self.log.info('onu-found', onus=info.onus, len=len(info.onus))
@@ -319,7 +320,7 @@
 
             # TODO
             # Start collecting stats from the device after a brief pause
-            # self.start_kpi_collection(device.id)
+            self.start_kpi_collection(device.id)
         except Exception as e:
             log.exception("Exception-activating", e=e)
 
@@ -577,138 +578,69 @@
         log.info('self-test-device', device=device.id)
         raise NotImplementedError()
 
+
+    @inlineCallbacks
     def disable(self):
         self.log.info('disabling', device_id=self.device_id)
 
         self.stop_kpi_collection()
 
-        # Get the latest device reference
-        device = self.adapter_agent.get_device(self.device_id)
-
-        # Update the operational status to UNKNOWN
-        device.oper_status = OperStatus.UNKNOWN
-        device.connect_status = ConnectStatus.UNREACHABLE
-        self.adapter_agent.device_update(device)
-
-        # Remove the logical device
-        logical_device = self.adapter_agent.get_logical_device(
-            self.logical_device_id)
-        self.adapter_agent.delete_logical_device(logical_device)
-
-        # Disable all child devices first
-        self.adapter_agent.update_child_devices_state(self.device_id,
-                                                      admin_state=AdminState.DISABLED)
-
-        # Remove the peer references from this device
-        self.adapter_agent.delete_all_peer_references(self.device_id)
-
-        # Set all ports to disabled
-        self.adapter_agent.disable_all_ports(self.device_id)
+        # Update the operational status to UNKNOWN and connection status to UNREACHABLE
+        yield self.adapter_agent.device_state_update(self.device_id, oper_status=OperStatus.UNKNOWN, connect_status=ConnectStatus.UNREACHABLE)
 
         self.close_channel()
         self.log.info('disabled-grpc-channel')
 
-        #  Update the logice device mapping
-        if self.logical_device_id in \
-                self.adapter.logical_device_id_to_root_device_id:
-            del self.adapter.logical_device_id_to_root_device_id[
-                self.logical_device_id]
-
         # TODO:
         # 1) Remove all flows from the device
         # 2) Remove the device from ponsim
 
-        self.log.info('disabled', device_id=device.id)
+        self.log.info('disabled', device_id=self.device_id)
 
+    @inlineCallbacks
     def reenable(self):
         self.log.info('re-enabling', device_id=self.device_id)
 
-        # Get the latest device reference
-        device = self.adapter_agent.get_device(self.device_id)
-
         # Set the ofp_port_no and nni_port in case we bypassed the reconcile
         # process if the device was in DISABLED state on voltha restart
         if not self.ofp_port_no and not self.nni_port:
-            stub = ponsim_pb2.PonSimStub(self.get_channel())
+            yield self.get_channel()
+            stub = ponsim_pb2.PonSimStub(self.channel)
             info = stub.GetDeviceInfo(Empty())
             log.info('got-info', info=info)
             self.ofp_port_no = info.nni_port
-            self.nni_port = self._get_nni_port()
+            ports = yield self._get_nni_port()
+            # For ponsim, we are using only 1 NNI port
+            if ports.items:
+                self.nni_port = ports.items[0]
 
-        # Update the connect status to REACHABLE
-        device.connect_status = ConnectStatus.REACHABLE
-        self.adapter_agent.device_update(device)
+        # Update the state of the NNI port
+        yield self.adapter_agent.port_state_update(self.device_id,
+                                                   port_type=Port.ETHERNET_NNI,
+                                                   port_no=self.ofp_port_no,
+                                                   oper_status=OperStatus.ACTIVE)
 
-        # Set all ports to enabled
-        self.adapter_agent.enable_all_ports(self.device_id)
+        # Update the state of the PON port
+        yield self.adapter_agent.port_state_update(self.device_id,
+                                                   port_type=Port.PON_OLT,
+                                                   port_no=1,
+                                                   oper_status=OperStatus.ACTIVE)
 
-        ld = LogicalDevice(
-            # not setting id and datapth_id will let the adapter agent pick id
-            desc=ofp_desc(
-                hw_desc='simulated pon',
-                sw_desc='simulated pon',
-                serial_num=uuid4().hex,
-                dp_desc='n/a'
-            ),
-            switch_features=ofp_switch_features(
-                n_buffers=256,  # TODO fake for now
-                n_tables=2,  # TODO ditto
-                capabilities=(  # TODO and ditto
-                        OFPC_FLOW_STATS
-                        | OFPC_TABLE_STATS
-                        | OFPC_PORT_STATS
-                        | OFPC_GROUP_STATS
-                )
-            ),
-            root_device_id=device.id
-        )
-        mac_address = "AA:BB:CC:DD:EE:FF"
-        ld_initialized = self.adapter_agent.create_logical_device(ld,
-                                                                  dpid=mac_address)
-        cap = OFPPF_1GB_FD | OFPPF_FIBER
-        self.adapter_agent.add_logical_port(ld_initialized.id, LogicalPort(
-            id='nni',
-            ofp_port=ofp_port(
-                port_no=self.ofp_port_no,
-                hw_addr=mac_str_to_tuple(
-                    '00:00:00:00:00:%02x' % self.ofp_port_no),
-                name='nni',
-                config=0,
-                state=OFPPS_LIVE,
-                curr=cap,
-                advertised=cap,
-                peer=cap,
-                curr_speed=OFPPF_1GB_FD,
-                max_speed=OFPPF_1GB_FD
-            ),
-            device_id=device.id,
-            device_port_no=self.nni_port.port_no,
-            root_port=True
-        ))
+        # Set the operational state of the device to ACTIVE and connect status to REACHABLE
+        yield self.adapter_agent.device_state_update(self.device_id,
+                                                     connect_status=ConnectStatus.REACHABLE,
+                                                     oper_status=OperStatus.ACTIVE)
 
-        device = self.adapter_agent.get_device(device.id)
-        device.parent_id = ld_initialized.id
-        device.oper_status = OperStatus.ACTIVE
-        self.adapter_agent.device_update(device)
-        self.logical_device_id = ld_initialized.id
+        # TODO: establish frame grpc-stream
+        # yield reactor.callInThread(self.rcv_grpc)
 
-        # Reenable all child devices
-        self.adapter_agent.update_child_devices_state(device.id,
-                                                      admin_state=AdminState.ENABLED)
+        self.start_kpi_collection(self.device_id)
 
-        # establish frame grpc-stream
-        reactor.callInThread(self.rcv_grpc)
-
-        self.start_kpi_collection(device.id)
-
-        self.log.info('re-enabled', device_id=device.id)
+        self.log.info('re-enabled', device_id=self.device_id)
 
     def delete(self):
         self.log.info('deleting', device_id=self.device_id)
 
-        # Remove all child devices
-        self.adapter_agent.delete_all_child_devices(self.device_id)
-
         self.close_channel()
         self.log.info('disabled-grpc-channel')
 
@@ -725,7 +657,7 @@
             try:
                 # Step 1: gather metrics from device
                 port_metrics = \
-                    self.pm_metrics.collect_port_metrics(self.get_channel())
+                    self.pm_metrics.collect_port_metrics(self.channel)
 
                 # Step 2: prepare the KpiEvent for submission
                 # we can time-stamp them here (or could use time derived from OLT
diff --git a/adapters/ponsim_onu/ponsim_onu.py b/adapters/ponsim_onu/ponsim_onu.py
index 7e35c7f..d1b2e27 100644
--- a/adapters/ponsim_onu/ponsim_onu.py
+++ b/adapters/ponsim_onu/ponsim_onu.py
@@ -20,7 +20,7 @@
 
 import sys
 import structlog
-from twisted.internet.defer import DeferredQueue, inlineCallbacks
+from twisted.internet.defer import DeferredQueue, inlineCallbacks, returnValue
 from adapters.common.utils.asleep import asleep
 
 from adapters.iadapter import OnuAdapter
@@ -92,10 +92,10 @@
         device.root = False
         device.vendor = 'ponsim'
         device.model = 'n/a'
-        device.connect_status = ConnectStatus.REACHABLE
+        # device.connect_status = ConnectStatus.REACHABLE
         yield self.adapter_agent.device_update(device)
 
-        # register physical ports
+    # register physical ports
         self.uni_port = Port(
             port_no=2,
             label='UNI facing Ethernet port',
@@ -119,7 +119,7 @@
         self.adapter_agent.port_created(device.id, self.uni_port)
         self.adapter_agent.port_created(device.id, self.pon_port)
 
-        yield self.adapter_agent.device_state_update(device.id, oper_status=OperStatus.ACTIVE)
+        yield self.adapter_agent.device_state_update(device.id, connect_status=ConnectStatus.REACHABLE, oper_status=OperStatus.ACTIVE)
 
 
     def get_ofp_port_info(self, device, port_no):
@@ -147,17 +147,27 @@
             )
         )
 
-    def _get_uni_port(self):
-        ports = self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_UNI)
-        if ports:
-            # For now, we use on one uni port
-            return ports[0]
+    # def _get_uni_port(self):
+    #     ports = self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_UNI)
+    #     if ports:
+    #         # For now, we use on one uni port
+    #         return ports[0]
 
+    @inlineCallbacks
+    def _get_uni_port(self):
+        ports = yield self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_UNI)
+        returnValue(ports)
+
+    @inlineCallbacks
     def _get_pon_port(self):
-        ports = self.adapter_agent.get_ports(self.device_id, Port.PON_ONU)
-        if ports:
-            # For now, we use on one uni port
-            return ports[0]
+        ports = yield self.adapter_agent.get_ports(self.device_id, Port.PON_ONU)
+        returnValue(ports)
+
+    # def _get_pon_port(self):
+    #     ports = self.adapter_agent.get_ports(self.device_id, Port.PON_ONU)
+    #     if ports:
+    #         # For now, we use on one uni port
+    #         return ports[0]
 
     def reconcile(self, device):
         self.log.info('reconciling-ONU-device-starts')
@@ -250,114 +260,104 @@
         log.info('self-test-device', device=device.id)
         raise NotImplementedError()
 
+
+    @inlineCallbacks
     def disable(self):
         self.log.info('disabling', device_id=self.device_id)
 
-        # Get the latest device reference
-        device = self.adapter_agent.get_device(self.device_id)
-
-        # Disable all ports on that device
-        self.adapter_agent.disable_all_ports(self.device_id)
-
         # Update the device operational status to UNKNOWN
-        device.oper_status = OperStatus.UNKNOWN
-        device.connect_status = ConnectStatus.UNREACHABLE
-        self.adapter_agent.update_device(device)
-
-        # Remove the uni logical port from the OLT, if still present
-        parent_device = self.adapter_agent.get_device(device.parent_id)
-        assert parent_device
-        logical_device_id = parent_device.parent_id
-        assert logical_device_id
-        port_no = device.proxy_address.channel_id
-        port_id = 'uni-{}'.format(port_no)
-        try:
-            port = self.adapter_agent.get_logical_port(logical_device_id,
-                                                       port_id)
-            self.adapter_agent.delete_logical_port(logical_device_id, port)
-        except KeyError:
-            self.log.info('logical-port-not-found', device_id=self.device_id,
-                          portid=port_id)
-
-        # Remove pon port from parent
-        self.pon_port = self._get_pon_port()
-        self.adapter_agent.delete_port_reference_from_parent(self.device_id,
-                                                             self.pon_port)
-
-        # Just updating the port status may be an option as well
-        # port.ofp_port.config = OFPPC_NO_RECV
-        # yield self.adapter_agent.update_logical_port(logical_device_id,
-        #                                             port)
-        # Unregister for proxied message
-        self.adapter_agent.unregister_for_proxied_messages(
-            device.proxy_address)
+        yield self.adapter_agent.device_state_update(self.device_id, oper_status=OperStatus.UNKNOWN, connect_status=ConnectStatus.UNREACHABLE)
 
         # TODO:
         # 1) Remove all flows from the device
         # 2) Remove the device from ponsim
 
-        self.log.info('disabled', device_id=device.id)
+        self.log.info('disabled', device_id=self.device_id)
 
+    @inlineCallbacks
     def reenable(self):
         self.log.info('re-enabling', device_id=self.device_id)
         try:
             # Get the latest device reference
-            device = self.adapter_agent.get_device(self.device_id)
+            # device = self.adapter_agent.get_device(self.device_id)
 
             # First we verify that we got parent reference and proxy info
-            assert device.parent_id
-            assert device.proxy_address.device_id
-            assert device.proxy_address.channel_id
+            # assert device.parent_id
+            # assert device.proxy_address.device_id
+            # assert device.proxy_address.channel_id
 
             # Re-register for proxied messages right away
-            self.proxy_address = device.proxy_address
-            self.adapter_agent.register_for_proxied_messages(
-                device.proxy_address)
+            # self.proxy_address = device.proxy_address
+            # self.adapter_agent.register_for_proxied_messages(
+            #     device.proxy_address)
 
-            # Re-enable the ports on that device
-            self.adapter_agent.enable_all_ports(self.device_id)
+            # Refresh the port reference - we only use one port for now
+            ports = yield self._get_uni_port()
+            self.log.info('re-enabling-uni-ports', ports=ports)
+            if ports.items:
+                self.uni_port = ports.items[0]
 
-            # Refresh the port reference
-            self.uni_port = self._get_uni_port()
-            self.pon_port = self._get_pon_port()
+            ports = yield self._get_pon_port()
+            self.log.info('re-enabling-pon-ports', ports=ports)
+            if ports.items:
+                self.pon_port = ports.items[0]
+
+            # Update the state of the UNI port
+            yield self.adapter_agent.port_state_update(self.device_id,
+                                                   port_type=Port.ETHERNET_UNI,
+                                                   port_no=self.uni_port.port_no,
+                                                   oper_status=OperStatus.ACTIVE)
+
+            # Update the state of the PON port
+            yield self.adapter_agent.port_state_update(self.device_id,
+                                                   port_type=Port.PON_ONU,
+                                                   port_no=self.pon_port.port_no,
+                                                   oper_status=OperStatus.ACTIVE)
+
+
+            # # Re-enable the ports on that device
+            # self.adapter_agent.enable_all_ports(self.device_id)
+
 
             # Add the pon port reference to the parent
-            self.adapter_agent.add_port_reference_to_parent(device.id,
-                                                            self.pon_port)
+            # self.adapter_agent.add_port_reference_to_parent(device.id,
+            #                                                 self.pon_port)
 
             # Update the connect status to REACHABLE
-            device.connect_status = ConnectStatus.REACHABLE
-            self.adapter_agent.update_device(device)
+            # device.connect_status = ConnectStatus.REACHABLE
+            # self.adapter_agent.update_device(device)
 
             # re-add uni port to logical device
-            parent_device = self.adapter_agent.get_device(device.parent_id)
-            logical_device_id = parent_device.parent_id
-            assert logical_device_id
-            port_no = device.proxy_address.channel_id
-            cap = OFPPF_1GB_FD | OFPPF_FIBER
-            self.adapter_agent.add_logical_port(logical_device_id, LogicalPort(
-                id='uni-{}'.format(port_no),
-                ofp_port=ofp_port(
-                    port_no=port_no,
-                    hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % port_no),
-                    name='uni-{}'.format(port_no),
-                    config=0,
-                    state=OFPPS_LIVE,
-                    curr=cap,
-                    advertised=cap,
-                    peer=cap,
-                    curr_speed=OFPPF_1GB_FD,
-                    max_speed=OFPPF_1GB_FD
-                ),
-                device_id=device.id,
-                device_port_no=self.uni_port.port_no
-            ))
+            # parent_device = self.adapter_agent.get_device(device.parent_id)
+            # logical_device_id = parent_device.parent_id
+            # assert logical_device_id
+            # port_no = device.proxy_address.channel_id
+            # cap = OFPPF_1GB_FD | OFPPF_FIBER
+            # self.adapter_agent.add_logical_port(logical_device_id, LogicalPort(
+            #     id='uni-{}'.format(port_no),
+            #     ofp_port=ofp_port(
+            #         port_no=port_no,
+            #         hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % port_no),
+            #         name='uni-{}'.format(port_no),
+            #         config=0,
+            #         state=OFPPS_LIVE,
+            #         curr=cap,
+            #         advertised=cap,
+            #         peer=cap,
+            #         curr_speed=OFPPF_1GB_FD,
+            #         max_speed=OFPPF_1GB_FD
+            #     ),
+            #     device_id=device.id,
+            #     device_port_no=self.uni_port.port_no
+            # ))
 
-            device = self.adapter_agent.get_device(device.id)
-            device.oper_status = OperStatus.ACTIVE
-            self.adapter_agent.update_device(device)
+            # device = self.adapter_agent.get_device(device.id)
+            # device.oper_status = OperStatus.ACTIVE
+            # self.adapter_agent.update_device(device)
 
-            self.log.info('re-enabled', device_id=device.id)
+            yield self.adapter_agent.device_state_update(self.device_id, oper_status=OperStatus.ACTIVE, connect_status=ConnectStatus.REACHABLE)
+
+            self.log.info('re-enabled', device_id=self.device_id)
         except Exception, e:
             self.log.exception('error-reenabling', e=e)