VOL-217 - Introduce OltAdapter and OnuAdapter classes

Change-Id: I914f1cb73aba41b1c1aaa27d5deba7a6f991951f
diff --git a/voltha/adapters/asfvolt16_olt/asfvolt16_olt.py b/voltha/adapters/asfvolt16_olt/asfvolt16_olt.py
index 18d0f04..983152a 100644
--- a/voltha/adapters/asfvolt16_olt/asfvolt16_olt.py
+++ b/voltha/adapters/asfvolt16_olt/asfvolt16_olt.py
@@ -18,9 +18,9 @@
 Asfvolt16 OLT adapter
 """
 
-from voltha.adapters.iadapter import IAdapter
+from voltha.adapters.iadapter import OltAdapter
 
-class Asfvolt16Adapter(IAdapter):
+class Asfvolt16Adapter(OltAdapter):
     def __init__(self, adapter_agent, config):
         super(Asfvolt16Adapter, self).__init__(adapter_agent=adapter_agent,
                                                config=config,
@@ -32,4 +32,50 @@
         self.adapter_agent.register_for_inter_adapter_messages()
 
 class Asfvolt16Handler(object):
-    pass
+    def __init__(self, adapter, device_id):
+        raise NotImplementedError()
+
+    def __del__(self):
+        raise NotImplementedError()
+
+    def get_channel(self):
+        raise NotImplementedError()
+
+    def _get_nni_port(self):
+        raise NotImplementedError()
+
+    def activate(self, device):
+        raise NotImplementedError()
+
+    def reconcile(self, device):
+        raise NotImplementedError()
+
+    def rcv_io(self, port, frame):
+        raise NotImplementedError()
+
+    def update_flow_table(self, flows):
+        raise NotImplementedError()
+
+    def update_pm_config(self, device, pm_config):
+        raise NotImplementedError()
+
+    def send_proxied_message(self, proxy_address, msg):
+        raise NotImplementedError()
+
+    def packet_out(self, egress_port, msg):
+        raise NotImplementedError()
+
+    def reboot(self):
+        raise NotImplementedError()
+
+    def disable(self):
+        raise NotImplementedError()
+
+    def reenable(self):
+        raise NotImplementedError()
+
+    def delete(self):
+        raise NotImplementedError()
+
+    def start_kpi_collection(self, device_id):
+        raise NotImplementedError()
diff --git a/voltha/adapters/iadapter.py b/voltha/adapters/iadapter.py
index 3588f72..b0b1aaa 100644
--- a/voltha/adapters/iadapter.py
+++ b/voltha/adapters/iadapter.py
@@ -22,6 +22,7 @@
 from zope.interface import implementer
 from twisted.internet import reactor
 
+from voltha.protos.common_pb2 import AdminState
 from voltha.protos.device_pb2 import DeviceType, DeviceTypes
 from voltha.adapters.interface import IAdapterInterface
 from voltha.protos.adapter_pb2 import Adapter
@@ -72,9 +73,6 @@
     def change_master_state(self, master):
         raise NotImplementedError()
 
-    def update_pm_config(self, device, pm_config):
-        raise NotImplementedError()
-
     def adopt_device(self, device):
         self.devices_handlers[device.id] = self.device_handler_class(self, device.id)
         reactor.callLater(0, self.devices_handlers[device.id].activate, device)
@@ -120,10 +118,14 @@
     def update_flows_incrementally(self, device, flow_changes, group_changes):
         raise NotImplementedError()
 
+    def update_pm_config(self, device, pm_config):
+        log.info("adapter-update-pm-config", device=device,
+                 pm_config=pm_config)
+        handler = self.devices_handlers[device.id]
+        handler.update_pm_config(device, pm_config)
+
     def send_proxied_message(self, proxy_address, msg):
-        log.info('send-proxied-message', proxy_address=proxy_address, msg=msg)
-        handler = self.devices_handlers[proxy_address.device_id]
-        handler.send_proxied_message(proxy_address, msg)
+        raise NotImplementedError()
 
     def receive_proxied_message(self, proxy_address, msg):
         raise NotImplementedError()
@@ -139,3 +141,81 @@
 
     def unsuppress_alarm(self, filter):
         raise NotImplementedError()
+
+"""
+OLT Adapter base class
+"""
+class OltAdapter(IAdapter):
+    def __init__(self, adapter_agent, config, device_handler_class, name, vendor, version):
+        super(OltAdapter, self).__init__(adapter_agent,
+                                         config,
+                                         device_handler_class,
+                                         name,
+                                         vendor,
+                                         version)
+        self.logical_device_id_to_root_device_id = dict()
+
+    def reconcile_device(self, device):
+        try:
+            self.devices_handlers[device.id] = self.device_handler_class(self, device.id)
+            # Work only required for devices that are in ENABLED state
+            if device.admin_state == AdminState.ENABLED:
+                reactor.callLater(0,
+                                  self.devices_handlers[device.id].reconcile,
+                                  device)
+            else:
+                # Invoke the children reconciliation which would setup the
+                # basic children data structures
+                self.adapter_agent.reconcile_child_devices(device.id)
+            return device
+        except Exception, e:
+            log.exception('Exception', e=e)
+
+    def send_proxied_message(self, proxy_address, msg):
+        log.info('send-proxied-message', proxy_address=proxy_address, msg=msg)
+        handler = self.devices_handlers[proxy_address.device_id]
+        handler.send_proxied_message(proxy_address, msg)
+
+    def receive_packet_out(self, logical_device_id, egress_port_no, msg):
+        def ldi_to_di(ldi):
+            di = self.logical_device_id_to_root_device_id.get(ldi)
+            if di is None:
+                logical_device = self.adapter_agent.get_logical_device(ldi)
+                di = logical_device.root_device_id
+                self.logical_device_id_to_root_device_id[ldi] = di
+            return di
+
+        device_id = ldi_to_di(logical_device_id)
+        handler = self.devices_handlers[device_id]
+        handler.packet_out(egress_port_no, msg)
+
+"""
+ONU Adapter base class
+"""
+class OnuAdapter(IAdapter):
+    def __init__(self, adapter_agent, config, device_handler_class, name, vendor, version):
+        super(OnuAdapter, self).__init__(adapter_agent,
+                                         config,
+                                         device_handler_class,
+                                         name,
+                                         vendor,
+                                         version)
+    def reconcile_device(self, device):
+        self.devices_handlers[device.id] = self.device_handler_class(self, device.id)
+        # Reconcile only if state was ENABLED
+        if device.admin_state == AdminState.ENABLED:
+            reactor.callLater(0,
+                              self.devices_handlers[device.id].reconcile,
+                              device)
+        return device
+
+    def receive_proxied_message(self, proxy_address, msg):
+        log.info('receive-proxied-message', proxy_address=proxy_address,
+                 device_id=proxy_address.device_id, msg=msg)
+        # Device_id from the proxy_address is the olt device id. We need to
+        # get the onu device id using the port number in the proxy_address
+        device = self.adapter_agent. \
+            get_child_device_with_proxy_address(proxy_address)
+        if device:
+            handler = self.devices_handlers[device.id]
+            handler.receive_message(msg)
diff --git a/voltha/adapters/loader.py b/voltha/adapters/loader.py
index cbc07e7..7c8340b 100644
--- a/voltha/adapters/loader.py
+++ b/voltha/adapters/loader.py
@@ -30,9 +30,8 @@
 
 from voltha.adapters.interface import IAdapterInterface
 from voltha.core.adapter_agent import AdapterAgent
-from voltha.protos import third_party
 from voltha.registry import IComponent
-from voltha.adapters.iadapter import IAdapter
+from voltha.adapters.iadapter import IAdapter, OltAdapter, OnuAdapter
 
 log = structlog.get_logger()
 
@@ -87,6 +86,8 @@
                         cls = getattr(module, attr_name)
                         if isinstance(cls, type) and \
                                 cls is not IAdapter and \
+                                cls is not OltAdapter and \
+                                cls is not OnuAdapter and \
                                 IAdapterInterface.implementedBy(cls):
                             verifyClass(IAdapterInterface, cls)
                             yield adapter_name, cls
diff --git a/voltha/adapters/ponsim_olt/ponsim_olt.py b/voltha/adapters/ponsim_olt/ponsim_olt.py
index 994ab14..7fffac8 100644
--- a/voltha/adapters/ponsim_olt/ponsim_olt.py
+++ b/voltha/adapters/ponsim_olt/ponsim_olt.py
@@ -25,13 +25,12 @@
 import structlog
 from scapy.layers.l2 import Ether, Dot1Q
 from scapy.layers.inet import Raw
-from twisted.internet import reactor
 from twisted.internet.defer import inlineCallbacks
 
 from common.frameio.frameio import BpfProgramFilter, hexify
 from common.utils.asleep import asleep
 from twisted.internet.task import LoopingCall
-from voltha.adapters.iadapter import IAdapter
+from voltha.adapters.iadapter import OltAdapter
 from voltha.core.logical_device_agent import mac_str_to_tuple
 from voltha.protos import third_party
 from voltha.protos import ponsim_pb2
@@ -175,7 +174,7 @@
         except Exception as e:
             log.exception('failed-to-send-alarm', e=e)
 
-class PonSimOltAdapter(IAdapter):
+class PonSimOltAdapter(OltAdapter):
     def __init__(self, adapter_agent, config):
         super(PonSimOltAdapter, self).__init__(adapter_agent=adapter_agent,
                                                config=config,
@@ -183,8 +182,6 @@
                                                name='ponsim_olt',
                                                vendor='Voltha project',
                                                version='0.4')
-        self.logical_device_id_to_root_device_id = dict()
-
 
     def update_pm_config(self, device, pm_config):
         log.info("adapter-update-pm-config", device=device,
@@ -192,36 +189,6 @@
         handler = self.devices_handlers[device.id]
         handler.update_pm_config(device, pm_config)
 
-    def reconcile_device(self, device):
-        try:
-            self.devices_handlers[device.id] = PonSimOltHandler(self,
-                                                                device.id)
-            # Work only required for devices that are in ENABLED state
-            if device.admin_state == AdminState.ENABLED:
-                reactor.callLater(0,
-                                  self.devices_handlers[device.id].reconcile,
-                                  device)
-            else:
-                # Invoke the children reconciliation which would setup the
-                # basic children data structures
-                self.adapter_agent.reconcile_child_devices(device.id)
-            return device
-        except Exception, e:
-            log.exception('Exception', e=e)
-
-    def receive_packet_out(self, logical_device_id, egress_port_no, msg):
-        def ldi_to_di(ldi):
-            di = self.logical_device_id_to_root_device_id.get(ldi)
-            if di is None:
-                logical_device = self.adapter_agent.get_logical_device(ldi)
-                di = logical_device.root_device_id
-                self.logical_device_id_to_root_device_id[ldi] = di
-            return di
-
-        device_id = ldi_to_di(logical_device_id)
-        handler = self.devices_handlers[device_id]
-        handler.packet_out(egress_port_no, msg)
-
 class PonSimOltHandler(object):
     def __init__(self, adapter, device_id):
         self.adapter = adapter
diff --git a/voltha/adapters/ponsim_onu/ponsim_onu.py b/voltha/adapters/ponsim_onu/ponsim_onu.py
index d9faff8..79aea55 100644
--- a/voltha/adapters/ponsim_onu/ponsim_onu.py
+++ b/voltha/adapters/ponsim_onu/ponsim_onu.py
@@ -19,11 +19,10 @@
 """
 
 import structlog
-from twisted.internet import reactor
 from twisted.internet.defer import DeferredQueue, inlineCallbacks
 from common.utils.asleep import asleep
 
-from voltha.adapters.iadapter import IAdapter
+from voltha.adapters.iadapter import OnuAdapter
 from voltha.core.logical_device_agent import mac_str_to_tuple
 from voltha.protos import third_party
 from voltha.protos.common_pb2 import OperStatus, ConnectStatus, AdminState
@@ -38,7 +37,7 @@
 log = structlog.get_logger()
 
 
-class PonSimOnuAdapter(IAdapter):
+class PonSimOnuAdapter(OnuAdapter):
     def __init__(self, adapter_agent, config):
         super(PonSimOnuAdapter, self).__init__(adapter_agent=adapter_agent,
                                                config=config,
@@ -47,27 +46,6 @@
                                                vendor='Voltha project',
                                                version='0.4')
 
-    def get_device_details(self, device):
-        raise NotImplementedError()
-
-    def send_proxied_message(self, proxy_address, msg):
-        log.info('send-proxied-message', proxy_address=proxy_address, msg=msg)
-
-    def receive_proxied_message(self, proxy_address, msg):
-        log.info('receive-proxied-message', proxy_address=proxy_address,
-                 device_id=proxy_address.device_id, msg=msg)
-        # Device_id from the proxy_address is the olt device id. We need to
-        # get the onu device id using the port number in the proxy_address
-        device = self.adapter_agent. \
-            get_child_device_with_proxy_address(proxy_address)
-        if device:
-            handler = self.devices_handlers[device.id]
-            handler.receive_message(msg)
-
-    def receive_packet_out(self, logical_device_id, egress_port_no, msg):
-        log.info('packet-out', logical_device_id=logical_device_id,
-                 egress_port_no=egress_port_no, msg_len=len(msg))
-
 class PonSimOnuHandler(object):
     def __init__(self, adapter, device_id):
         self.adapter = adapter