VOL-1139 Reboot works. Refactored disable/enable and up/down indications handling to be consistent with existing broadcom handler.
Change-Id: I38ae1ccf6030d77a2f9bf4bef239ca899403522b
diff --git a/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu.py b/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu.py
index c0e32cf..1559cfa 100644
--- a/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu.py
+++ b/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu.py
@@ -33,6 +33,7 @@
from common.frameio.frameio import hexify
from voltha.extensions.omci.openomci_agent import OpenOMCIAgent, OpenOmciAgentDefaults
from voltha.extensions.omci.omci_me import *
+from voltha.extensions.omci.database.mib_db_dict import MibDbVolatileDict
from omci.brcm_capabilities_task import BrcmCapabilitiesTask
from omci.brcm_get_mds_task import BrcmGetMdsTask
from omci.brcm_mib_sync import BrcmMibSynchronizer
@@ -73,6 +74,7 @@
self.broadcom_omci = deepcopy(OpenOmciAgentDefaults)
self.broadcom_omci['mib-synchronizer']['state-machine'] = BrcmMibSynchronizer
+ self.broadcom_omci['mib-synchronizer']['database'] = MibDbVolatileDict
#self.broadcom_omci['mib-synchronizer']['tasks']['get-mds'] = BrcmGetMdsTask
#self.broadcom_omci['mib-synchronizer']['tasks']['mib-audit'] = BrcmGetMdsTask
self.broadcom_omci['omci-capabilities']['tasks']['get-capabilities'] = BrcmCapabilitiesTask
diff --git a/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py b/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
index 242c706..b561feb 100644
--- a/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
+++ b/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
@@ -40,8 +40,10 @@
from voltha.extensions.omci.onu_configuration import OMCCVersion
from voltha.extensions.omci.onu_device_entry import OnuDeviceEvents, \
OnuDeviceEntry, IN_SYNC_KEY
+from voltha.extensions.omci.tasks.omci_modify_request import OmciModifyRequest
from voltha.extensions.omci.omci_me import *
from voltha.adapters.brcm_openomci_onu.omci.brcm_mib_download_task import BrcmMibDownloadTask
+from voltha.adapters.brcm_openomci_onu.omci.brcm_uni_lock_task import BrcmUniLockTask
from voltha.adapters.brcm_openomci_onu.onu_gem_port import *
from voltha.adapters.brcm_openomci_onu.onu_tcont import *
from voltha.adapters.brcm_openomci_onu.pon_port import *
@@ -177,6 +179,7 @@
device.root = True
device.vendor = 'Broadcom'
device.connect_status = ConnectStatus.REACHABLE
+ device.oper_status = OperStatus.DISCOVERED
self.adapter_agent.update_device(device)
self._pon = PonPort.create(self, self._pon_port_number)
@@ -187,8 +190,6 @@
parent_device = self.adapter_agent.get_device(device.parent_id)
self.logical_device_id = parent_device.parent_id
- device = self.adapter_agent.get_device(device.id)
- device.oper_status = OperStatus.DISCOVERED
self.adapter_agent.update_device(device)
self.log.debug('set-device-discovered')
@@ -235,11 +236,20 @@
except Exception as e:
self.log.exception("exception-updating-port",e=e)
+ @inlineCallbacks
def delete(self, device):
- self.log.debug('function-entry', device=device)
- self.log.info('delete-onu - Not implemented yet')
- # The device is already deleted in delete_v_ont_ani(). No more
- # handling needed here
+ self.log.info('delete-onu', device=device)
+
+ parent_device = self.adapter_agent.get_device(device.parent_id)
+ if parent_device.type == 'openolt':
+ parent_adapter = registry('adapter_loader').get_agent(parent_device.adapter).adapter
+ self.log.debug('parent-adapter-delete-onu', onu_device=device,
+ parent_device=parent_device,
+ parent_adapter=parent_adapter)
+ try:
+ parent_adapter.delete_child_device(parent_device.id, device)
+ except AttributeError:
+ self.log.debug('parent-device-delete-child-not-implemented')
@inlineCallbacks
def update_flow_table(self, device, flows):
@@ -486,25 +496,22 @@
self.log.debug('function-entry', data=data)
self._onu_indication = data
- onu_device = self.adapter_agent.get_device(self.device_id)
-
- if onu_device.oper_status == OperStatus.DISCOVERED and data.oper_state == 'up':
- if self._dev_info_loaded == True:
- self.log.debug('reenabling-openomci-statemachine')
- reactor.callLater(0, self.reenable(onu_device))
- else:
- self.log.debug('starting-openomci-statemachine')
- self._subscribe_to_events()
- reactor.callLater(1, self._onu_omci_device.start)
+ self.log.debug('starting-openomci-statemachine')
+ self._subscribe_to_events()
+ reactor.callLater(1, self._onu_omci_device.start)
def update_interface(self, data):
self.log.debug('function-entry', data=data)
onu_device = self.adapter_agent.get_device(self.device_id)
- if onu_device.oper_status == OperStatus.DISCOVERED and data.oper_state == 'down':
+ if data.oper_state == 'down':
self.log.debug('stopping-openomci-statemachine')
- reactor.callLater(0, self.disable(onu_device))
+ reactor.callLater(0, self._onu_omci_device.stop)
+ self.disable_ports(onu_device)
+ onu_device.connect_status = ConnectStatus.UNREACHABLE
+ onu_device.oper_status = OperStatus.DISCOVERED
+ self.adapter_agent.update_device(onu_device)
else:
self.log.debug('not-changing-openomci-statemachine')
@@ -515,6 +522,7 @@
self.log.debug('stopping-openomci-statemachine')
reactor.callLater(0, self._onu_omci_device.stop)
+ self.disable_ports(onu_device)
# TODO: im sure there is more to do here
@@ -608,29 +616,35 @@
def disable(self, device):
self.log.debug('function-entry', device=device)
try:
- self.log.info('sending-admin-state-lock-towards-device', device=device)
+ self.log.info('sending-uni-lock-towards-device', device=device)
- #TODO: Create uni lock/unlock omci task
+ def stop_anyway(reason):
+ # proceed with disable regardless if we could reach the onu. for example onu is unplugged
+ self.log.debug('stopping-openomci-statemachine')
+ reactor.callLater(0, self._onu_omci_device.stop)
+ self.disable_ports(device)
+ device.oper_status = OperStatus.UNKNOWN
+ device.connect_status = ConnectStatus.UNREACHABLE
+ self.adapter_agent.update_device(device)
- # Stop up OpenOMCI state machines for this device
- reactor.callLater(0, self._onu_omci_device.stop)
-
- device = self.adapter_agent.get_device(device.id)
- # Disable all ports on that device
- self.adapter_agent.disable_all_ports(self.device_id)
+ # lock all the unis
+ task = BrcmUniLockTask(self.omci_agent, self.device_id, lock=True)
+ self._deferred = self._onu_omci_device.task_runner.queue_task(task)
+ self._deferred.addCallbacks(stop_anyway, stop_anyway)
+ '''
+ # Disable in parent device (OLT)
parent_device = self.adapter_agent.get_device(device.parent_id)
- logical_device_id = parent_device.parent_id
- assert logical_device_id
- # Mark OF PORT STATE DOWN
- ports = self.adapter_agent.get_ports(device.id, Port.ETHERNET_UNI)
- for port in ports:
- state = OFPPS_LINK_DOWN
- port_id = 'uni-{}'.format(port.port_no)
- # TODO: move to UniPort
- self.update_logical_port(logical_device_id, port_id, state)
- device.oper_status = OperStatus.UNKNOWN
- device.connect_status = ConnectStatus.UNREACHABLE
- self.adapter_agent.update_device(device)
+
+ if parent_device.type == 'openolt':
+ parent_adapter = registry('adapter_loader').get_agent(parent_device.adapter).adapter
+ self.log.info('parent-adapter-disable-onu', onu_device=device,
+ parent_device=parent_device,
+ parent_adapter=parent_adapter)
+ try:
+ parent_adapter.disable_child_device(parent_device.id, device)
+ except AttributeError:
+ self.log.debug('parent-device-disable-child-not-implemented')
+ '''
except Exception as e:
log.exception('exception-in-onu-disable', exception=e)
@@ -638,23 +652,11 @@
def reenable(self, device):
self.log.debug('function-entry', device=device)
try:
- self.log.info('sending-admin-state-unlock-towards-device', device=device)
-
# Start up OpenOMCI state machines for this device
+ # this will ultimately resync mib and unlock unis on successful redownloading the mib
+ self.log.debug('restarting-openomci-statemachine')
self._subscribe_to_events()
reactor.callLater(1, self._onu_omci_device.start)
-
- #TODO: Create uni lock/unlock omci task
-
- device = self.adapter_agent.get_device(device.id)
- # Re-enable the ports on that device
- self.adapter_agent.enable_all_ports(device.id)
- parent_device = self.adapter_agent.get_device(device.parent_id)
- logical_device_id = parent_device.parent_id
- assert logical_device_id
- device.oper_status = OperStatus.ACTIVE
- device.connect_status = ConnectStatus.REACHABLE
- self.adapter_agent.update_device(device)
except Exception as e:
log.exception('exception-in-onu-reenable', exception=e)
@@ -666,24 +668,18 @@
self.log.error("device-unreacable")
returnValue(None)
- #TODO: Create reboot omci task
+ def success(_results):
+ self.log.info('reboot-success', _results=_results)
+ self.disable_ports(device)
+ device.connect_status = ConnectStatus.UNREACHABLE
+ device.oper_status = OperStatus.DISCOVERED
+ self.adapter_agent.update_device(device)
- response = None
- if response is not None:
- omci_response = response.getfieldval("omci_message")
- success_code = omci_response.getfieldval("success_code")
- if success_code == 0:
- self.log.debug("reboot-command-processed-successfully")
- # Update the device connection and operation status
- device = self.adapter_agent.get_device(self.device_id)
- device.connect_status = ConnectStatus.UNREACHABLE
- device.oper_status = OperStatus.DISCOVERED
- self.adapter_agent.update_device(device)
- self.disable_ports(device)
- else:
- self.log.error("reboot-failed", success_code=success_code)
- else:
- self.log.error("error-in-processing-reboot-response")
+ def failure(_reason):
+ self.log.info('reboot-failure', _reason=_reason)
+
+ self._deferred = self._onu_omci_device.reboot()
+ self._deferred.addCallbacks(success, failure)
def disable_ports(self, onu_device):
self.log.info('disable-ports', device_id=self.device_id,
@@ -771,14 +767,13 @@
omci = self._onu_omci_device
in_sync = omci.mib_db_in_sync
+ device = self.adapter_agent.get_device(self.device_id)
+ device.reason = 'discovery-mibsync-complete'
+ self.adapter_agent.update_device(device)
+
if not self._dev_info_loaded:
self.log.info('loading-device-data-from-mib', in_sync=in_sync, already_loaded=self._dev_info_loaded)
- device = self.adapter_agent.get_device(self.device_id)
- device.oper_status = OperStatus.ACTIVE
- device.connect_status = ConnectStatus.REACHABLE
- device.reason = 'discovery-mibsync-complete'
-
omci_dev = self._onu_omci_device
config = omci_dev.configuration
@@ -866,6 +861,12 @@
def success(_results):
self.log.info('mib-download-success', _results=_results)
+ device = self.adapter_agent.get_device(self.device_id)
+ device.reason = 'initial-mib-downloaded'
+ device.oper_status = OperStatus.ACTIVE
+ device.connect_status = ConnectStatus.REACHABLE
+ self.enable_ports(device)
+ self.adapter_agent.update_device(device)
self._mib_download_task = None
def failure(_reason):
diff --git a/voltha/adapters/brcm_openomci_onu/omci/brcm_mib_download_task.py b/voltha/adapters/brcm_openomci_onu/omci/brcm_mib_download_task.py
index 52f9142..2c9c961 100644
--- a/voltha/adapters/brcm_openomci_onu/omci/brcm_mib_download_task.py
+++ b/voltha/adapters/brcm_openomci_onu/omci/brcm_mib_download_task.py
@@ -15,7 +15,6 @@
import structlog
from common.frameio.frameio import hexify
-from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPS_LINK_DOWN
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks, returnValue, TimeoutError, failure
from voltha.extensions.omci.omci_me import *
@@ -203,14 +202,6 @@
# And re-enable the UNIs if needed
yield self.enable_uni(self._uni_port, False)
- # If here, we are done. Set the openflow port live
- # TODO: move to UniPort
- self._handler.update_logical_port(self._handler.logical_device_id,
- self._uni_port.port_id_name(), OFPPS_LIVE)
- device = self._handler.adapter_agent.get_device(self.device_id)
-
- device.reason = 'initial-mib-downloaded'
- self._handler.adapter_agent.update_device(device)
self.deferred.callback('initial-download-success')
except TimeoutError as e:
diff --git a/voltha/adapters/brcm_openomci_onu/omci/brcm_uni_lock_task.py b/voltha/adapters/brcm_openomci_onu/omci/brcm_uni_lock_task.py
new file mode 100644
index 0000000..6866cba
--- /dev/null
+++ b/voltha/adapters/brcm_openomci_onu/omci/brcm_uni_lock_task.py
@@ -0,0 +1,112 @@
+#
+# Copyright 2018 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from voltha.extensions.omci.tasks.task import Task
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, failure, returnValue
+from voltha.extensions.omci.omci_defs import ReasonCodes, EntityOperations
+from voltha.extensions.omci.omci_me import PptpEthernetUniFrame
+
+RC = ReasonCodes
+OP = EntityOperations
+
+
+class BrcmUniLockException(Exception):
+ pass
+
+
+class BrcmUniLockTask(Task):
+ """
+ Lock or unlock all discovered UNI/PPTP on the ONU
+ """
+ task_priority = 200
+ name = "Broadcom UNI Lock Task"
+
+ def __init__(self, omci_agent, device_id, lock=True, priority=task_priority):
+ """
+ Class initialization
+
+ :param omci_agent: (OmciAdapterAgent) OMCI Adapter agent
+ :param device_id: (str) ONU Device ID
+ :param lock: (bool) If true administratively lock all the UNI. If false unlock
+ :param priority: (int) OpenOMCI Task priority (0..255) 255 is the highest
+ """
+ super(BrcmUniLockTask, self).__init__(BrcmUniLockTask.name,
+ omci_agent,
+ device_id,
+ priority=priority,
+ exclusive=False)
+ self._device = omci_agent.get_device(device_id)
+ self._lock = lock
+ self._results = None
+ self._local_deferred = None
+ self._config = self._device.configuration
+
+ def cancel_deferred(self):
+ super(BrcmUniLockTask, self).cancel_deferred()
+
+ d, self._local_deferred = self._local_deferred, None
+ try:
+ if d is not None and not d.called:
+ d.cancel()
+ except:
+ pass
+
+ def stop_if_not_running(self):
+ if not self.running:
+ raise BrcmUniLockException('UNI Lock Task was cancelled')
+
+ def start(self):
+ """
+ Start UNI/PPTP Lock/Unlock Task
+ """
+ super(BrcmUniLockTask, self).start()
+ self._local_deferred = reactor.callLater(0, self.perform_lock)
+
+ @inlineCallbacks
+ def perform_lock(self):
+ """
+ Perform the lock/unlock
+ """
+ self.log.info('setting-uni-lock-state', lock=self._lock)
+
+ try:
+ state = 1 if self._lock else 0
+
+ pptp = self._config.pptp_entities
+
+ for key, value in pptp.iteritems():
+ msg = PptpEthernetUniFrame(key,
+ attributes=dict(administrative_state=state))
+ frame = msg.set()
+ self.log.debug('openomci-msg', msg=msg)
+ results = yield self._device.omci_cc.send(frame)
+ self.stop_if_not_running()
+
+ status = results.fields['omci_message'].fields['success_code']
+ self.log.info('response-status', status=status)
+
+ # Success?
+ if status in (RC.Success.value, RC.InstanceExists):
+ self.log.debug('set-lock-uni', uni=key, value=value, lock=self._lock)
+ else:
+ self.log.warn('cannot-set-lock-uni', uni=key, value=value, lock=self._lock)
+
+ self.deferred.callback(self)
+
+ except Exception as e:
+ self.log.exception('setting-uni-lock-state', e=e)
+ self.deferred.errback(failure.Failure(e))
+
diff --git a/voltha/extensions/omci/onu_device_entry.py b/voltha/extensions/omci/onu_device_entry.py
index 40f2678..d3fd68b 100644
--- a/voltha/extensions/omci/onu_device_entry.py
+++ b/voltha/extensions/omci/onu_device_entry.py
@@ -470,7 +470,7 @@
def reboot(self,
flags=RebootFlags.Reboot_Unconditionally,
- timeout=OmciRebootRequest.DEFAULT_PRIORITY):
+ timeout=OmciRebootRequest.DEFAULT_REBOOT_TIMEOUT):
"""
Request a reboot of the ONU
diff --git a/voltha/extensions/omci/tasks/reboot_task.py b/voltha/extensions/omci/tasks/reboot_task.py
index ba4c290..8cbf808 100644
--- a/voltha/extensions/omci/tasks/reboot_task.py
+++ b/voltha/extensions/omci/tasks/reboot_task.py
@@ -45,10 +45,12 @@
"""
task_priority = Task.MAX_PRIORITY
name = "ONU OMCI Reboot Task"
+ # adopt the global default
+ DEFAULT_REBOOT_TIMEOUT = DEFAULT_OMCI_TIMEOUT
def __init__(self, omci_agent, device_id,
flags=RebootFlags.Reboot_Unconditionally,
- timeout=DEFAULT_OMCI_TIMEOUT):
+ timeout=DEFAULT_REBOOT_TIMEOUT):
"""
Class initialization