VOL-757: OpenOLT - MAC based dpid

Change-Id: Icb6376c652c929d268f6cf518ab2d935f33459d0
diff --git a/voltha/adapters/openolt/openolt.py b/voltha/adapters/openolt/openolt.py
index ad12474..0360d5e 100644
--- a/voltha/adapters/openolt/openolt.py
+++ b/voltha/adapters/openolt/openolt.py
@@ -59,6 +59,7 @@
         self.devices = dict()  # device_id -> OpenoltDevice()
         self.interface = registry('main').get_args().interface
         self.logical_device_id_to_root_device_id = dict()
+        self.num_devices = 0
 
     def start(self):
         log.info('started', interface=self.interface)
@@ -86,7 +87,8 @@
         log.info('adopt-device', device=device)
         kwargs = {
             'adapter_agent': self.adapter_agent,
-            'device': device
+            'device': device,
+            'device_num': self.num_devices + 1
         }
         try:
             self.devices[device.id] = OpenoltDevice(**kwargs)
@@ -94,6 +96,8 @@
             log.error('Failed to adopt OpenOLT device', error=e)
             del self.devices[device.id]
             raise
+        else:
+            self.num_devices += 1
 
     def reconcile_device(self, device):
         log.info('reconcile-device', device=device)
diff --git a/voltha/adapters/openolt/openolt_device.py b/voltha/adapters/openolt/openolt_device.py
index 69d9941..25c4c16 100644
--- a/voltha/adapters/openolt/openolt_device.py
+++ b/voltha/adapters/openolt/openolt_device.py
@@ -114,14 +114,15 @@
     onu id = 7 bits = 128 ONUs per PON port
 
 
-Logical (OF) NNI port number
+PON OLT (OF) port number
 
-    OpenFlow port number corresponding to OLT NNI
+    OpenFlow port number corresponding to PON OLT ports
 
-     15                              0
-    +--+------------------------------+
-    |1 |           nni  id            |
-    +--+------------------------------+
+     31    28                                 0
+    +--------+------------------------~~~------+
+    |  0x2   |          pon intf id            |
+    +--------+------------------------~~~------+
+
 """
 
 """
@@ -133,41 +134,23 @@
         super(OpenoltDevice, self).__init__()
 
         self.adapter_agent = kwargs['adapter_agent']
+        self.device_num = kwargs['device_num']
         device = kwargs['device']
         self.device_id = device.id
         self.host_and_port = device.host_and_port
         self.log = structlog.get_logger(id=self.device_id, ip=self.host_and_port)
-        self.oper_state = 'unknown'
         self.nni_oper_state = dict() #intf_id -> oper_state
         self.onus = {} # OnuKey -> OnuRec
 
-        # Create logical device
-        ld = LogicalDevice(
-            desc=ofp_desc(
-                hw_desc='FIXME',
-                sw_desc='FIXME', serial_num='FIXME',
-                dp_desc='n/a'),
-            switch_features=ofp_switch_features(
-                n_buffers=256, n_tables=2,
-                capabilities=(
-                    OFPC_FLOW_STATS | OFPC_TABLE_STATS |
-                    OFPC_GROUP_STATS | OFPC_PORT_STATS)),
-            root_device_id=self.device_id)
-        # FIXME
-        ld_initialized = self.adapter_agent.create_logical_device(ld, dpid='de:ad:be:ef:fe:ed') # FIXME
-        self.logical_device_id = ld_initialized.id
-
         # Update device
         device.root = True
         device.vendor = 'Edgecore'
         device.model = 'ASFvOLT16'
         device.serial_number = self.host_and_port # FIXME
-        device.parent_id = self.logical_device_id
         device.connect_status = ConnectStatus.REACHABLE
         device.oper_status = OperStatus.ACTIVATING
         self.adapter_agent.update_device(device)
 
-
         # Initialize gRPC
         self.channel = grpc.insecure_channel(self.host_and_port)
         self.channel_ready_future = grpc.channel_ready_future(self.channel)
@@ -185,15 +168,18 @@
             # get the next indication from olt
             ind = next(self.indications)
             self.log.debug("rx indication", indication=ind)
-            # schedule indication handlers to be run in the main event loop
+
+            # indication handlers run in the main event loop
             if ind.HasField('olt_ind'):
                 reactor.callFromThread(self.olt_indication, ind.olt_ind)
             elif ind.HasField('intf_ind'):
                 reactor.callFromThread(self.intf_indication, ind.intf_ind)
             elif ind.HasField('intf_oper_ind'):
-                reactor.callFromThread(self.intf_oper_indication, ind.intf_oper_ind)
+                reactor.callFromThread(self.intf_oper_indication,
+                        ind.intf_oper_ind)
             elif ind.HasField('onu_disc_ind'):
-                reactor.callFromThread(self.onu_discovery_indication, ind.onu_disc_ind)
+                reactor.callFromThread(self.onu_discovery_indication,
+                        ind.onu_disc_ind)
             elif ind.HasField('onu_ind'):
                 reactor.callFromThread(self.onu_indication, ind.onu_ind)
             elif ind.HasField('omci_ind'):
@@ -203,7 +189,36 @@
 
     def olt_indication(self, olt_indication):
 	self.log.debug("olt indication", olt_ind=olt_indication)
-        self.set_oper_state(olt_indication.oper_state)
+
+        # FIXME
+        if olt_indication.oper_state == "down":
+	    self.log.error("ignore olt oper state down", olt_ind=olt_indication)
+            return
+
+        if not hasattr(olt_indication, 'mac') or \
+                not olt_indication.mac:
+            mac = '00:00:00:00:00:' + '{:02x}'.format(self.device_num)
+        else:
+            mac = olt_indication.mac
+
+        # Create logical OF device
+        desc = ofp_desc(hw_desc='FIXME', sw_desc='FIXME', serial_num='FIXME',
+                dp_desc='xgs-pon-olt')
+        capabilities = (OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_GROUP_STATS | \
+                OFPC_PORT_STATS)
+        switch_features = ofp_switch_features(n_buffers=256, n_tables=2,
+                capabilities=capabilities)
+        ld = LogicalDevice(desc=desc, switch_features=switch_features,
+                root_device_id=self.device_id)
+        ld_initialized = self.adapter_agent.create_logical_device(ld, dpid=mac)
+        self.logical_device_id = ld_initialized.id
+
+        # Update phys OF device
+        device = self.adapter_agent.get_device(self.device_id)
+        device.parent_id = self.logical_device_id
+        device.oper_status = OperStatus.ACTIVE
+        self.adapter_agent.update_device(device)
+
 
     def intf_indication(self, intf_indication):
 	self.log.debug("intf indication", intf_id=intf_indication.intf_id,
@@ -218,8 +233,10 @@
         self.add_port(intf_indication.intf_id, Port.PON_OLT, oper_status)
 
     def intf_oper_indication(self, intf_oper_indication):
-	self.log.debug("Received interface oper state change indication", intf_id=intf_oper_indication.intf_id,
-            type=intf_oper_indication.type, oper_state=intf_oper_indication.oper_state)
+	self.log.debug("Received interface oper state change indication",
+                intf_id=intf_oper_indication.intf_id,
+                type=intf_oper_indication.type,
+                oper_state=intf_oper_indication.oper_state)
 
         if intf_oper_indication.oper_state == "up":
             oper_state = OperStatus.ACTIVE
@@ -304,14 +321,16 @@
         assert onu_indication.onu_id == key.onu_id
 
         if self.onus[key].state is not 'discovered':
-            self.log.debug("ignore onu indication", intf_id=onu_indication.intf_id,
-                    onu_id=onu_indication.onu_id, state=self.onus[key].state)
+            self.log.debug("ignore onu indication",
+                    intf_id=onu_indication.intf_id,
+                    onu_id=onu_indication.onu_id,
+                    state=self.onus[key].state)
             return
 
         self.onus[key] = self.onus[key]._replace(state='active')
 
-        onu_device = self.adapter_agent.get_child_device(
-            self.device_id, onu_id=onu_indication.onu_id)
+        onu_device = self.adapter_agent.get_child_device(self.device_id,
+                onu_id=onu_indication.onu_id)
         assert onu_device is not None
 
         msg = {'proxy_address':onu_device.proxy_address,
@@ -452,9 +471,6 @@
             # FIXME - Remove hardcoded '129'
             return intf_id + 129
         elif intf_type is Port.PON_OLT:
-            # Interface Ids (reported by device) are zero-based indexed
-            # OpenFlow port numbering is one-based.
-            #return intf_id + 65 # FIXME
             return 0x2<<28 | intf_id
         else:
 	    raise Exception('Invalid port type')
@@ -469,17 +485,6 @@
             prefix = "uni"
         return prefix + "-" + str(port_no)
 
-    def update_device_status(self, connect_status=None, oper_status=None,
-            reason=None):
-        device = self.adapter_agent.get_device(self.device_id)
-        if connect_status is not None:
-            device.connect_status = connect_status
-        if oper_status is not None:
-            device.oper_status = oper_status
-        if reason is not None:
-            device.reason = reason
-        self.adapter_agent.update_device(device)
-
     def add_logical_port(self, port_no, intf_id):
         self.log.info('adding-logical-port', port_no=port_no)
 
@@ -516,26 +521,9 @@
 
         return port_no, label
 
-    def set_oper_state(self, new_state):
-        if self.oper_state != new_state:
-	    if new_state == 'up':
-	        self.update_device_status(connect_status=ConnectStatus.REACHABLE,
-		        oper_status=OperStatus.ACTIVE,
-		        reason='OLT indication - operation state up')
-	    elif new_state == 'down':
-	        self.update_device_status(connect_status=ConnectStatus.REACHABLE,
-		        oper_status=OperStatus.FAILED,
-		        reason='OLT indication - operation state down')
-            else:
-	        raise ValueError('Invalid oper_state in olt_indication')
-
-            self.oper_state = new_state
-
     def new_onu_id(self, intf_id):
         onu_id = None
-        # onu_id is unique per PON.
-        # FIXME - Remove hardcoded limit on ONUs per PON (64)
-        for i in range(1, 64):
+        for i in range(1, 512):
             key = OnuKey(intf_id=intf_id, onu_id=i)
             if key not in self.onus:
                 onu_id = i
diff --git a/voltha/adapters/openolt/protos/openolt.proto b/voltha/adapters/openolt/protos/openolt.proto
index c9f6d98..7041800 100644
--- a/voltha/adapters/openolt/protos/openolt.proto
+++ b/voltha/adapters/openolt/protos/openolt.proto
@@ -63,6 +63,10 @@
 
 message OltIndication {
     string oper_state = 1;	// up, down
+    string mac = 2;
+    string serial_number = 3;
+    string manufacturer = 4;
+    string name = 5;
 }
 
 message IntfIndication {