VOL-1493 VOL-1454:

Process omci messages. Properly set device state
using new core_proxy api.

Implement and process inter adapter messages.
Start and use openomci state machine.  Update
handler and omci_cc for new core/adapter proxy

Can now successfully mib upload and mib_sync is success

Change-Id: Id2b3e3b700601dad035886544f5b1f5606b146ad
diff --git a/python/Makefile b/python/Makefile
index 03b1684..ec8b91d 100644
--- a/python/Makefile
+++ b/python/Makefile
@@ -123,8 +123,10 @@
 venv: ${VENVDIR}/.built
 
 ${VENVDIR}/.built:
-	@ virtualenv ${VENVDIR}
-	@ . ${VENVDIR}/bin/activate && \
+	virtualenv -v ${VENVDIR}
+	# these are just symlinks to the other folders in the venv.  this makes it appear as if there are duplicate definitions in PYTHONPATH.  venv bug?
+	rm ${VENVDIR}/local/bin ${VENVDIR}/local/lib ${VENVDIR}/local/include
+	. ${VENVDIR}/bin/activate && \
 	    pip install --upgrade pip; \
 	    if ! pip install -r requirements.txt; \
 	    then \
@@ -139,7 +141,7 @@
 	cp ../../pyvoltha/dist/*.tar.gz pyvoltha/dist/
 	mkdir -p voltha-protos/dist
 	cp ../../voltha-protos/dist/*.tar.gz voltha-protos/dist/
-	@ . ${VENVDIR}/bin/activate && \
+	. ${VENVDIR}/bin/activate && \
 	    pip install pyvoltha/dist/*.tar.gz && \
 	    pip install voltha-protos/dist/*.tar.gz
 endif
diff --git a/python/adapters/brcm_openomci_onu/brcm_openomci_onu.py b/python/adapters/brcm_openomci_onu/brcm_openomci_onu.py
index ca90ac4..77a1920 100644
--- a/python/adapters/brcm_openomci_onu/brcm_openomci_onu.py
+++ b/python/adapters/brcm_openomci_onu/brcm_openomci_onu.py
@@ -59,8 +59,8 @@
 
     def __init__(self, core_proxy, adapter_proxy, config):
         log.debug('function-entry', config=config)
+        self.core_proxy = core_proxy
         self.adapter_proxy = adapter_proxy
-        self.adapter_agent = core_proxy
         self.config = config
         self.descriptor = Adapter(
             id=self.name,
@@ -86,7 +86,8 @@
     def omci_agent(self):
         if not hasattr(self, '_omci_agent') or self._omci_agent is None:
             log.debug('creating-omci-agent')
-            self._omci_agent = OpenOMCIAgent(self.adapter_agent,
+            self._omci_agent = OpenOMCIAgent(self.core_proxy,
+                                             self.adapter_proxy,
                                              support_classes=self.broadcom_omci)
         return self._omci_agent
 
@@ -238,6 +239,13 @@
         else:
             log.error("device-not-found")
 
+    def process_inter_adapter_message(self, msg):
+        log.debug('process-inter-adapter-message', msg=msg)
+        # Unpack the header to know which device needs to handle this message
+        if msg.header:
+            handler = self.devices_handlers[msg.header.to_device_id]
+            handler.process_inter_adapter_message(msg)
+
     def create_interface(self, device, data):
         log.debug('create-interface', device_id=device.id)
         if device.id in self.devices_handlers:
diff --git a/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py b/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
index 84b4751..278a752 100644
--- a/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
+++ b/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
@@ -18,7 +18,6 @@
 Broadcom OpenOMCI OLT/ONU adapter handler.
 """
 
-import json
 import ast
 import structlog
 
@@ -38,6 +37,8 @@
 from pyvoltha.common.config.config_backend import EtcdStore
 from voltha_protos.common_pb2 import OperStatus, ConnectStatus, AdminState
 from voltha_protos.openflow_13_pb2 import OFPXMC_OPENFLOW_BASIC, ofp_port
+from voltha_protos.inter_container_pb2 import InterAdapterMessageType, InterAdapterOmciMessage
+from voltha_protos.openolt_pb2 import OnuIndication
 from pyvoltha.adapters.extensions.omci.onu_configuration import OMCCVersion
 from pyvoltha.adapters.extensions.omci.onu_device_entry import OnuDeviceEvents, \
     OnuDeviceEntry, IN_SYNC_KEY
@@ -66,7 +67,8 @@
         self.log = structlog.get_logger(device_id=device_id)
         self.log.debug('function-entry')
         self.adapter = adapter
-        self.adapter_agent = adapter.adapter_agent
+        self.core_proxy = adapter.core_proxy
+        self.adapter_proxy = adapter.adapter_proxy
         self.parent_adapter = None
         self.parent_id = None
         self.device_id = device_id
@@ -182,9 +184,7 @@
             self.log.info('activating-new-onu')
             # populate what we know.  rest comes later after mib sync
             device.root = False
-            device.vendor = 'Broadcom'
-            device.connect_status = ConnectStatus.REACHABLE
-            device.oper_status = OperStatus.DISCOVERED
+            device.vendor = 'OpenONU'
             device.reason = 'activating-onu'
 
             # TODO NEW CORE:  Need to either get logical device id from core or use regular device id
@@ -193,7 +193,11 @@
             #self.logical_device_id = parent_device.parent_id
             #assert self.logical_device_id, 'Invalid logical device ID'
 
-            yield self.adapter_agent.device_update(device)
+            yield self.core_proxy.device_update(device)
+
+            yield self.core_proxy.device_state_update(device.id, oper_status=OperStatus.DISCOVERED,
+                                                         connect_status=ConnectStatus.REACHABLE)
+
 
             self.log.debug('set-device-discovered')
 
@@ -207,17 +211,17 @@
                 'heartbeat': self.heartbeat,
                 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
             }
-            self.pm_metrics = OnuPmMetrics(self.adapter_agent, self.device_id,
+            self.pm_metrics = OnuPmMetrics(self.core_proxy, self.device_id,
                                            self.logical_device_id, grouped=True,
                                            freq_override=False, **kwargs)
             pm_config = self.pm_metrics.make_proto()
             self._onu_omci_device.set_pm_config(self.pm_metrics.omci_pm.openomci_interval_pm)
             self.log.info("initial-pm-config", pm_config=pm_config)
-            yield self.adapter_agent.device_pm_config_update(pm_config, init=True)
+            yield self.core_proxy.device_pm_config_update(pm_config, init=True)
 
             ############################################################################
             # Setup Alarm handler
-            self.alarms = AdapterAlarms(self.adapter_agent, device.id, self.logical_device_id)
+            self.alarms = AdapterAlarms(self.core_proxy, device.id, self.logical_device_id)
             # Note, ONU ID and UNI intf set in add_uni_port method
             self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.alarms,
                                                                       ani_ports=[self._pon])
@@ -279,13 +283,14 @@
         self._pon.add_peer(self.parent_id, self._pon_port_number)
         self.log.debug('adding-pon-port-to-agent', pon=self._pon.get_port())
 
-        yield self.adapter_agent.port_created(device.id, self._pon.get_port())
+        yield self.core_proxy.port_created(device.id, self._pon.get_port())
 
         self.log.debug('added-pon-port-to-agent', pon=self._pon.get_port())
 
         # Create and start the OpenOMCI ONU Device Entry for this ONU
         self._onu_omci_device = self.omci_agent.add_device(self.device_id,
-                                                           self.adapter_agent,
+                                                           self.core_proxy,
+                                                           self.adapter_proxy,
                                                            support_classes=self.adapter.broadcom_omci,
                                                            custom_me_map=self.adapter.custom_me_entities())
         # Port startup
@@ -626,31 +631,58 @@
         self.tx_id += 1
         return self.tx_id
 
-    # TODO: Actually conform to or create a proper interface.
-    # this and the other functions called from the olt arent very clear.
-    # Called each time there is an onu "up" indication from the olt handler
-    def create_interface(self, data):
-        self.log.debug('function-entry', data=data)
-        self._onu_indication = data
+    def process_inter_adapter_message(self, request):
+        self.log.debug('process-inter-adapter-message', msg=request)
+        try:
+            if request.header.type == InterAdapterMessageType.OMCI_REQUEST:
+                omci_msg = InterAdapterOmciMessage()
+                request.body.Unpack(omci_msg)
+                self.log.debug('inter-adapter-recv-omci', omci_msg=omci_msg)
 
-        onu_device = self.adapter_agent.get_device(self.device_id)
+                self.receive_message(omci_msg.message)
+
+            elif request.header.type == InterAdapterMessageType.ONU_IND_REQUEST:
+                onu_indication = OnuIndication()
+                request.body.Unpack(onu_indication)
+                self.log.debug('inter-adapter-recv-onu-ind', onu_indication=onu_indication)
+
+                if onu_indication.oper_state == "up":
+                    self.create_interface(onu_indication)
+                elif onu_indication.oper_state == "down":
+                    self.update_interface(onu_indication)
+                else:
+                    self.log.error("unknown-onu-indication", onu_indication=onu_indication)
+
+            else:
+                self.log.error("inter-adapter-unhandled-type", request=request)
+
+        except Exception as e:
+            self.log.exception("error-processing-inter-adapter-message", e=e)
+
+    # Called each time there is an onu "up" indication from the olt handler
+    @inlineCallbacks
+    def create_interface(self, onu_indication):
+        self.log.debug('function-entry', onu_indication=onu_indication)
+        self._onu_indication = onu_indication
+
+        onu_device = yield self.core_proxy.get_device(self.device_id)
 
         self.log.debug('starting-openomci-statemachine')
         self._subscribe_to_events()
         reactor.callLater(1, self._onu_omci_device.start)
         onu_device.reason = "starting-openomci"
-        self.adapter_agent.update_device(onu_device)
+        yield self.core_proxy.device_update(onu_device)
         self._heartbeat.enabled = True
 
     # Currently called each time there is an onu "down" indication from the olt handler
     # TODO: possibly other reasons to "update" from the olt?
-    def update_interface(self, data):
-        self.log.debug('function-entry', data=data)
-        oper_state = data.get('oper_state', None)
+    @inlineCallbacks
+    def update_interface(self, onu_indication):
+        self.log.debug('function-entry', onu_indication=onu_indication)
 
-        onu_device = self.adapter_agent.get_device(self.device_id)
+        onu_device = yield self.core_proxy.get_device(self.device_id)
 
-        if oper_state == 'down':
+        if onu_indication.oper_state == 'down':
             self.log.debug('stopping-openomci-statemachine')
             reactor.callLater(0, self._onu_omci_device.stop)
 
diff --git a/python/adapters/brcm_openomci_onu/main.py b/python/adapters/brcm_openomci_onu/main.py
index 6521ba7..d0eadcb 100755
--- a/python/adapters/brcm_openomci_onu/main.py
+++ b/python/adapters/brcm_openomci_onu/main.py
@@ -360,6 +360,8 @@
                 core_proxy=self.core_proxy, adapter_proxy=self.adapter_proxy,
                 config=config)
 
+            self.adapter.start()
+
             openonu_request_handler = AdapterRequestFacade(adapter=self.adapter,
                                                            core_proxy=self.core_proxy)
 
diff --git a/python/adapters/brcm_openomci_onu/pon_port.py b/python/adapters/brcm_openomci_onu/pon_port.py
index 8d5fc3b..5c8c7eb 100644
--- a/python/adapters/brcm_openomci_onu/pon_port.py
+++ b/python/adapters/brcm_openomci_onu/pon_port.py
@@ -180,8 +180,8 @@
 
         # adapter_agent add_port also does an update of port status
         try:
-            yield self._handler.adapter_agent.port_state_update(self._handler.device_id, self._port.type,
-                                                                self._port.port_no,self._port.oper_status)
+            yield self._handler.core_proxy.port_state_update(self._handler.device_id, self._port.type,
+                                                             self._port.port_no,self._port.oper_status)
         except Exception as e:
             self.log.exception('update-port', e=e)