VOL-1110: ADTRAN_ONU: Support of OpenOMCI reboot task

Change-Id: I8822e57d07a8ce1b5c85930c1efc39b35604ca8d
diff --git a/voltha/adapters/adtran_onu/adtran_onu.py b/voltha/adapters/adtran_onu/adtran_onu.py
index 81a5f9a..1f7f366 100755
--- a/voltha/adapters/adtran_onu/adtran_onu.py
+++ b/voltha/adapters/adtran_onu/adtran_onu.py
@@ -40,7 +40,7 @@
                                                device_handler_class=AdtranOnuHandler,
                                                name='adtran_onu',
                                                vendor='Adtran, Inc.',
-                                               version='0.10',
+                                               version='0.11',
                                                device_type='adtran_onu',
                                                vendor_id='ADTN')
         # Customize OpenOMCI for Adtran ONUs
diff --git a/voltha/adapters/adtran_onu/adtran_onu_handler.py b/voltha/adapters/adtran_onu/adtran_onu_handler.py
index e6598a3..cdefaa0 100644
--- a/voltha/adapters/adtran_onu/adtran_onu_handler.py
+++ b/voltha/adapters/adtran_onu/adtran_onu_handler.py
@@ -37,8 +37,8 @@
 from voltha.extensions.omci.omci_me import *
 
 _ = third_party
-_MAXIMUM_PORT = 128          # PON and UNI ports
-_ONU_REBOOT_MIN = 60
+_MAXIMUM_PORT = 128       # PON and UNI ports
+_ONU_REBOOT_MIN = 90      # IBONT 602 takes about 3 minutes
 _ONU_REBOOT_RETRY = 10
 
 
@@ -72,7 +72,6 @@
         self._port_number_pool = IndexPool(_MAXIMUM_PORT, 1)
 
         self._olt_created = False   # True if deprecated method of OLT creating DA is used
-        self._is_mock = False
 
     def __str__(self):
         return "AdtranOnuHandler: {}".format(self.device_id)
@@ -123,10 +122,6 @@
             # TODO: Anything else
 
     @property
-    def is_mock(self):
-        return self._is_mock        # Not pointing to real hardware
-
-    @property
     def olt_created(self):
         return self._olt_created    # ONU was created with deprecated 'child_device_detected' call
 
@@ -155,6 +150,10 @@
         return self._pon
 
     @property
+    def pon_ports(self):
+        return [self._pon]
+
+    @property
     def _next_port_number(self):
         return self._port_number_pool.get_next()
 
@@ -559,24 +558,14 @@
         self.adapter_agent.update_device(device)
 
         # TODO: send alert and clear alert after the reboot
+        try:
+            ######################################################
+            # MIB Reset
+            yield self.openomci.onu_omci_device.reboot(timeout=1)
 
-        if not self.is_mock:
-            from twisted.internet.defer import TimeoutError
-
-            try:
-                ######################################################
-                # MIB Reset - For ADTRAN ONU, we do not get a response
-                #             back (because we are rebooting)
-                pass
-                yield self.openomci.omci_cc.send_reboot(timeout=0.1)
-
-            except TimeoutError:
-                # This is expected
-                returnValue('reboot-in-progress')
-
-            except Exception as e:
-                self.log.exception('send-reboot', e=e)
-                raise
+        except Exception as e:
+            self.log.exception('send-reboot', e=e)
+            raise
 
         # Reboot in progress. A reboot may take up to 3 min 30 seconds
         # Go ahead and pause less than that and start to look
@@ -586,8 +575,7 @@
         self.adapter_agent.update_device(device)
 
         # Disable OpenOMCI
-        self.pon_port.enabled = False
-
+        self.omci.enabled = False
         self._deferred = reactor.callLater(_ONU_REBOOT_MIN,
                                            self._finish_reboot,
                                            previous_oper_status,
@@ -597,20 +585,9 @@
     @inlineCallbacks
     def _finish_reboot(self, previous_oper_status, previous_conn_status,
                        reregister):
-        from common.utils.asleep import asleep
-
-        if not self.is_mock:
-            # TODO: Do a simple poll and call this again if we timeout
-            # _ONU_REBOOT_RETRY
-            yield asleep(180)       # 3 minutes ...
-
-        # Change the operational status back to its previous state.  With a
-        # real OLT the operational state should be the state the device is
-        # after a reboot.
-        # Get the latest device reference
 
         # Restart OpenOMCI
-        self.pon_port.enabled = True
+        self.omci.enabled = True
 
         device = self.adapter_agent.get_device(self.device_id)
 
@@ -786,12 +763,6 @@
         # OpenOMCI cleanup
         self._openomci.delete()
 
-    def _check_for_mock_config(self, data):
-        # Check for MOCK configuration
-        description = data.get('description')
-        if description is not None and 'mock' in description.lower():
-            self._is_mock = True
-
     def on_ont_ani_create(self, ont_ani):
         """
         A new ONT-ani is being created. You can override this method to
@@ -803,8 +774,6 @@
         :return: (dict) Updated ONT-ani dictionary, None if item should be deleted
         """
         self.log.info('ont-ani-create', ont_ani=ont_ani)
-
-        self._check_for_mock_config(ont_ani)
         self.enabled = ont_ani['enabled']
 
         return ont_ani   # Implement in your OLT, if needed
@@ -853,8 +822,6 @@
 
     def on_vont_ani_create(self, vont_ani):
         self.log.info('vont-ani-create', vont_ani=vont_ani)
-
-        self._check_for_mock_config(vont_ani)
         # TODO: look up PON port and update 'upstream-channel-speed'
         return vont_ani   # Implement in your OLT, if needed
 
@@ -879,8 +846,6 @@
     def on_venet_create(self, venet):
         self.log.info('venet-create', venet=venet)
 
-        self._check_for_mock_config(venet)
-
         # TODO: This first set is copied over from BroadCOM ONU. For testing, actual work
         #       is the last 7 lines.  The 'test' code below assumes we have not registered
         #       any UNI ports during 'activate' but we want to create them as the vEnet
@@ -996,8 +961,7 @@
 
         td = self.traffic_descriptors.get(tcont.get('td-ref'))
         traffic_descriptor = td['object'] if td is not None else None
-        tcont['object'] = OnuTCont.create(self, tcont, traffic_descriptor,
-                                          is_mock=self.is_mock)
+        tcont['object'] = OnuTCont.create(self, tcont, traffic_descriptor)
 
         if self._pon is not None:
             self._pon.add_tcont(tcont['object'])
@@ -1079,8 +1043,7 @@
         assert self._pon is not None, 'No PON port'
 
         gem_port['object'] = OnuGemPort.create(self, gem_port,
-                                               self._pon.next_gem_entity_id,
-                                               is_mock=self.is_mock)
+                                               self._pon.next_gem_entity_id)
         self._pon.add_gem_port(gem_port['object'])
         return gem_port
 
diff --git a/voltha/adapters/adtran_onu/omci/adtn_mib_download_task.py b/voltha/adapters/adtran_onu/omci/adtn_mib_download_task.py
index b6fb650..a85372c 100644
--- a/voltha/adapters/adtran_onu/omci/adtn_mib_download_task.py
+++ b/voltha/adapters/adtran_onu/omci/adtn_mib_download_task.py
@@ -407,7 +407,7 @@
             #  EntityID was created prior to this call. This is a set
             #
             #  References:
-            #            - Gem Interwork TPs are set here
+            #            - Gem Interworking TPs are set here
             #
             # TODO: All p-bits currently go to the one and only GEMPORT ID for now
             gem_ports = self._handler.pon_port.gem_ports
diff --git a/voltha/adapters/adtran_onu/omci/adtn_mib_sync.py b/voltha/adapters/adtran_onu/omci/adtn_mib_sync.py
index 21e11d4..0bd7376 100644
--- a/voltha/adapters/adtran_onu/omci/adtn_mib_sync.py
+++ b/voltha/adapters/adtran_onu/omci/adtn_mib_sync.py
@@ -22,7 +22,8 @@
     """
     ADTN_RESYNC_DELAY = 60     # Periodically force a resync
 
-    def __init__(self, agent, device_id, mib_sync_tasks, db):
+    def __init__(self, agent, device_id, mib_sync_tasks, db,
+                 advertise_events=False):
         """
         Class initialization
 
@@ -30,8 +31,10 @@
         :param device_id: (str) ONU Device ID
         :param db: (MibDbVolatileDict) MIB Database
         :param mib_sync_tasks: (dict) Tasks to run
+        :param advertise_events: (bool) Advertise events on OpenOMCI Event Bus
         """
         super(AdtnMibSynchronizer, self).__init__(agent, device_id, mib_sync_tasks, db,
+                                                  advertise_events=advertise_events,
                                                   # states=MibSynchronizer.DEFAULT_STATES,
                                                   # transitions=MibSynchronizer.DEFAULT_TRANSITIONS,
                                                   # initial_state='disabled',
diff --git a/voltha/adapters/adtran_onu/omci/omci.py b/voltha/adapters/adtran_onu/omci/omci.py
index aa1e9c4..0e4791f 100644
--- a/voltha/adapters/adtran_onu/omci/omci.py
+++ b/voltha/adapters/adtran_onu/omci/omci.py
@@ -98,8 +98,6 @@
         self._bridge_initialized = False
         self._in_sync_reached = False
 
-        # TODO: stop h/w sync
-
     def _cancel_deferred(self):
         d1, self._deferred = self._deferred, None
         d2, self._resync_deferred = self._resync_deferred, None
@@ -185,6 +183,12 @@
             assert uni_ports == len(self._handler.uni_ports), \
                 'Expected {} UNI port(s), got {}'.format(len(self._handler.uni_ports), uni_ports)
 
+            # serial_number = omci_dev.configuration.serial_number
+            # self.log.info('serial-number', serial_number=serial_number)
+
+            # Save entity_id of PON ports
+            self._handler.pon_ports[0].entity_id = ani_g.keys()[0]
+
             # Save entity_id for UNI ports
             uni_entity_ids = uni_g.keys()
             uni_entity_ids.sort()
@@ -253,7 +257,7 @@
         bus = self._onu_omci_device.event_bus
         topic = OnuDeviceEntry.event_bus_topic(self._handler.device_id,
                                                OnuDeviceEvents.OmciCapabilitiesEvent)
-        self._capabilities_subscription = bus.subscribe(topic, self.capabilties_handler)
+        self._capabilities_subscription = bus.subscribe(topic, self.capabilities_handler)
 
         # OMCI-CC Connectivity Events (for reachability/heartbeat)
 
@@ -298,7 +302,7 @@
             except Exception as e:
                 self.log.exception('in-sync', e=e)
 
-    def capabilties_handler(self, _topic, _msg):
+    def capabilities_handler(self, _topic, _msg):
         """
         This event occurs after an ONU reaches the In-Sync state and the OMCI ME has
         been queried for supported ME and message types.
@@ -311,13 +315,12 @@
 
             def success(_results):
                 self._mib_download_task = None
-                pass   # TODO.  What's next...
 
             def failure(_reason):
                 self._mib_download_task = None
                 # TODO: Handle failure, retry for now?
                 self._mib_download_deferred = reactor.callLater(_STARTUP_RETRY_WAIT,
-                                                                self.capabilties_handler)
+                                                                self.capabilities_handler)
             self._mib_download_task = AdtnMibDownloadTask(self.omci_agent, self._handler)
             self._mib_download_deferred = self._onu_omci_device.task_runner.queue_task(self._mib_download_task)
             self._mib_download_deferred.addCallbacks(success, failure)
diff --git a/voltha/adapters/adtran_onu/onu_gem_port.py b/voltha/adapters/adtran_onu/onu_gem_port.py
index 03ea477..0e02ead 100644
--- a/voltha/adapters/adtran_onu/onu_gem_port.py
+++ b/voltha/adapters/adtran_onu/onu_gem_port.py
@@ -32,8 +32,7 @@
                  intf_ref=None,
                  untagged=False,
                  name=None,
-                 handler=None,
-                 is_mock=False):
+                 handler=None):
         super(OnuGemPort, self).__init__(gem_id, alloc_id,
                                          encryption=encryption,
                                          omci_transport=omci_transport,
@@ -44,7 +43,6 @@
                                          untagged=untagged,
                                          name=name,
                                          handler=handler)
-        self._is_mock = is_mock
         self._entity_id = entity_id
         self.log = structlog.get_logger(device_id=handler.device_id, gem_id=gem_id)
 
@@ -64,8 +62,7 @@
             self._encryption = value
 
     @staticmethod
-    def create(handler, gem_port, entity_id, is_mock=False):
-
+    def create(handler, gem_port, entity_id):
         return OnuGemPort(gem_port['gemport-id'],
                           None,
                           entity_id,
@@ -74,8 +71,7 @@
                           name=gem_port['name'],
                           traffic_class=gem_port['traffic-class'],
                           handler=handler,
-                          untagged='untagged' in gem_port['name'].lower(),
-                          is_mock=is_mock)
+                          untagged='untagged' in gem_port['name'].lower())
 
     @inlineCallbacks
     def add_to_hardware(self, omci,
@@ -86,9 +82,6 @@
                        tcont_entity_id=tcont_entity_id,
                        ieee_mapper_service_profile_entity_id=ieee_mapper_service_profile_entity_id,
                        gal_enet_profile_entity_id=gal_enet_profile_entity_id)
-        if self._is_mock:
-            returnValue('mock')
-
         try:
             direction = "downstream" if self.multicast else "bi-directional"
             assert not self.multicast, 'MCAST is not supported yet'
@@ -138,9 +131,6 @@
     @inlineCallbacks
     def remove_from_hardware(self, omci):
         self.log.debug('remove-from-hardware',  gem_id=self.gem_id)
-        if self._is_mock:
-            returnValue('mock')
-
         try:
             frame = GemInterworkingTpFrame(self.entity_id).delete()
             results = yield omci.send(frame)
diff --git a/voltha/adapters/adtran_onu/onu_tcont.py b/voltha/adapters/adtran_onu/onu_tcont.py
index e926081..db97810 100644
--- a/voltha/adapters/adtran_onu/onu_tcont.py
+++ b/voltha/adapters/adtran_onu/onu_tcont.py
@@ -24,12 +24,10 @@
     """
     Adtran ONU specific implementation
     """
-    def __init__(self, handler, alloc_id, traffic_descriptor,
-                 name=None, vont_ani=None, is_mock=False):
+    def __init__(self, handler, alloc_id, traffic_descriptor, name=None, vont_ani=None):
         super(OnuTCont, self).__init__(alloc_id, traffic_descriptor,
                                        name=name, vont_ani=vont_ani)
         self._handler = handler
-        self._is_mock = is_mock
         self._entity_id = None
         self.log = structlog.get_logger(device_id=handler.device_id, alloc_id=alloc_id)
 
@@ -38,7 +36,7 @@
         return self._entity_id
 
     @staticmethod
-    def create(handler, tcont, td, is_mock=False):
+    def create(handler, tcont, td):
         assert isinstance(tcont, dict), 'TCONT should be a dictionary'
         assert isinstance(td, TrafficDescriptor), 'Invalid Traffic Descriptor data type'
 
@@ -46,16 +44,13 @@
                         tcont['alloc-id'],
                         td,
                         name=tcont['name'],
-                        vont_ani=tcont['vont-ani'],
-                        is_mock=is_mock)
+                        vont_ani=tcont['vont-ani'])
 
     @inlineCallbacks
     def add_to_hardware(self, omci, tcont_entity_id):
         self.log.debug('add-to-hardware', tcont_entity_id=tcont_entity_id)
 
         self._entity_id = tcont_entity_id
-        if self._is_mock:
-            returnValue('mock')
 
         try:
             frame = TcontFrame(self.entity_id, self.alloc_id).set()
@@ -77,8 +72,6 @@
     @inlineCallbacks
     def remove_from_hardware(self, omci):
         self.log.debug('remove-from-hardware', tcont_entity_id=self.entity_id)
-        if self._is_mock:
-            returnValue('mock')
 
         # Release tcont by setting alloc_id=0xFFFF
         try:
diff --git a/voltha/adapters/adtran_onu/onu_traffic_descriptor.py b/voltha/adapters/adtran_onu/onu_traffic_descriptor.py
index d41d632..894959b 100644
--- a/voltha/adapters/adtran_onu/onu_traffic_descriptor.py
+++ b/voltha/adapters/adtran_onu/onu_traffic_descriptor.py
@@ -24,13 +24,11 @@
     def __init__(self, fixed, assured, maximum,
                  additional=TrafficDescriptor.AdditionalBwEligibility.DEFAULT,
                  best_effort=None,
-                 name=None,
-                 is_mock=False):
+                 name=None):
         super(OnuTrafficDescriptor, self).__init__(fixed, assured, maximum,
                                                    additional=additional,
                                                    best_effort=best_effort,
                                                    name=name)
-        self._is_mock = is_mock
 
     @staticmethod
     def create(traffic_disc):
@@ -56,9 +54,6 @@
     @inlineCallbacks
     def add_to_hardware(self, omci):
 
-        if self._is_mock:
-            returnValue('mock')
-
         results = succeed('TODO: Implement me')
         # from ..adtran_olt_handler import AdtranOltHandler
         #
diff --git a/voltha/adapters/adtran_onu/pon_port.py b/voltha/adapters/adtran_onu/pon_port.py
index 1cfa003..49b2235 100644
--- a/voltha/adapters/adtran_onu/pon_port.py
+++ b/voltha/adapters/adtran_onu/pon_port.py
@@ -32,6 +32,7 @@
         self._deferred = None
         self._port = None
         self._port_number = port_no
+        self._entity_id = None                  # ANI entity ID
         self._next_entity_id = PonPort.MIN_GEM_ENTITY_ID
 
         self._admin_state = AdminState.ENABLED
@@ -98,6 +99,18 @@
             return self._port_number
 
     @property
+    def entity_id(self):
+        """
+        OMCI ANI_G entity ID for port
+        """
+        return self._entity_id
+
+    @entity_id.setter
+    def entity_id(self, value):
+        assert self._entity_id is None, 'Cannot reset the Entity ID'
+        self._entity_id = value
+
+    @property
     def next_gem_entity_id(self):
         entity_id = self._next_entity_id