VOL-1204 Clean NNI port number for openolt

Change-Id: I64ba697881c7c4bbf2f0367ad2ce8c0dc9d8b8fe
diff --git a/voltha/adapters/openolt/openolt_device.py b/voltha/adapters/openolt/openolt_device.py
index c7410fc..db68bca 100644
--- a/voltha/adapters/openolt/openolt_device.py
+++ b/voltha/adapters/openolt/openolt_device.py
@@ -834,7 +834,7 @@
 
         ofp = ofp_port(
             port_no=port_no,
-            hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % port_no),
+            hw_addr=mac_str_to_tuple(self._get_mac_form_port_no(port_no)),
             name=label, config=0, state=of_oper_state, curr=cap,
             advertised=cap, peer=cap, curr_speed=curr_speed,
             max_speed=max_speed)
@@ -849,6 +849,13 @@
         self.adapter_agent.add_logical_port(self.logical_device_id,
                                             logical_port)
 
+    def _get_mac_form_port_no(self, port_no):
+        mac = ''
+        for i in range(4):
+            mac = ':%02x' % ((port_no >> (i * 8)) & 0xff) + mac
+        return '00:00' + mac
+
+
     def add_port(self, intf_id, port_type, oper_status):
         port_no = platform.intf_id_to_port_no(intf_id, port_type)
 
diff --git a/voltha/adapters/openolt/openolt_flow_mgr.py b/voltha/adapters/openolt/openolt_flow_mgr.py
index 96afa0f..69e712a 100644
--- a/voltha/adapters/openolt/openolt_flow_mgr.py
+++ b/voltha/adapters/openolt/openolt_flow_mgr.py
@@ -20,6 +20,7 @@
 from voltha.protos.openflow_13_pb2 import OFPXMC_OPENFLOW_BASIC, \
     ofp_flow_stats, ofp_match, OFPMT_OXM, Flows, FlowGroups, \
     OFPXMT_OFB_IN_PORT, OFPXMT_OFB_VLAN_VID
+from voltha.protos.device_pb2 import Port
 import voltha.core.flow_decomposer as fd
 import openolt_platform as platform
 from voltha.adapters.openolt.protos import openolt_pb2
@@ -326,7 +327,8 @@
         downstream_logical_flow = copy.deepcopy(logical_flow)
         for oxm_field in downstream_logical_flow.match.oxm_fields:
             if oxm_field.ofb_field.type == OFPXMT_OFB_IN_PORT:
-                oxm_field.ofb_field.port = 128
+                oxm_field.ofb_field.port = \
+                    platform.intf_id_to_port_no(0, Port.ETHERNET_NNI)
 
         classifier['udp_src'] = 67
         classifier['udp_dst'] = 68
@@ -517,8 +519,10 @@
         for flow in flows:
             in_port = fd.get_in_port(flow)
             out_port = fd.get_out_port(flow)
-            #FIXME
-            if in_port == port and out_port == 128:
+
+            if in_port == port and \
+                platform.intf_id_to_port_type_name(out_port) == Port.ETHERNET_NNI:
+
                 fields = fd.get_ofb_fields(flow)
                 self.log.debug('subscriber flow found', fields=fields)
                 for field in fields:
diff --git a/voltha/adapters/openolt/openolt_platform.py b/voltha/adapters/openolt/openolt_platform.py
index c4b7cac..a7f6904 100644
--- a/voltha/adapters/openolt/openolt_platform.py
+++ b/voltha/adapters/openolt/openolt_platform.py
@@ -81,6 +81,17 @@
     pon id = 4 bits = 16 PON ports
     onu id = 7 bits = 128 ONUs per PON port
 
+Logical (OF) NNI port number
+
+    OpenFlow port number corresponding to PON UNI
+
+     16                             0
+    +--+----------------------------+
+    |1 |                    intf_id |
+    +--+----------------------------+
+
+    No overlap with UNI port number space
+
 
 PON OLT (OF) port number
 
@@ -130,8 +141,7 @@
 
 def intf_id_to_port_no(intf_id, intf_type):
     if intf_type is Port.ETHERNET_NNI:
-        # FIXME - Remove hardcoded '128'
-        return intf_id + 128
+        return (0x1 << 16) | intf_id
     elif intf_type is Port.PON_OLT:
         return 0x2 << 28 | intf_id
     else:
@@ -139,22 +149,16 @@
 
 
 def intf_id_from_nni_port_num(port_num):
-    return port_num - 128
+    return port_num & 0xFFFF
 
-def intf_id_to_intf_type(intf_id):
-
-    if (2 << 28 ^ intf_id) < 16:
-        return Port.PON_OLT
-    elif  128 <= intf_id <= 132:
-        return Port.ETHERNET_NNI
-    else:
-        raise Exception('Invalid intf_id value')
 
 def intf_id_to_port_type_name(intf_id):
-    try:
-        return  port_type_name_by_port_index(intf_id_to_intf_type(intf_id))
-    except Exception as err:
-        raise Exception(err)
+    if (2 << 28 ^ intf_id) < 16:
+        return Port.PON_OLT
+    elif intf_id & (0x1 << 16) == (0x1 << 16):
+        return Port.ETHERNET_NNI
+    else:
+        return None
 
 def port_type_name_by_port_index(port_index):
     try:
@@ -163,21 +167,20 @@
         raise Exception(err)
 
 def extract_access_from_flow(in_port, out_port):
-    if is_upstream(in_port, out_port):
+    if is_upstream(out_port):
         return (intf_id_from_uni_port_num(in_port), onu_id_from_port_num(
             in_port))
     else:
         return (intf_id_from_uni_port_num(out_port), onu_id_from_port_num(
             out_port))
 
-def is_upstream(in_port, out_port):
-    #FIXME
-    if out_port in [128, 129, 130, 131, 0xfffd, 0xfffffffd]:
+def is_upstream(out_port):
+
+    if out_port in [0xfffd, 0xfffffffd]:
+        # To Controller
         return True
-    # if in_port not in [128, 129, 130, 131]:
-    #     return True
+    if (out_port & (0x1 << 16)) == (0x1 << 16):
+        # NNI interface
+        return True
 
     return False
-
-def is_downstream(in_port, out_port):
-    return not is_upstream(in_port, out_port)
\ No newline at end of file
diff --git a/voltha/adapters/openolt/openolt_statistics.py b/voltha/adapters/openolt/openolt_statistics.py
index 774b7eb..d9c77b1 100644
--- a/voltha/adapters/openolt/openolt_statistics.py
+++ b/voltha/adapters/openolt/openolt_statistics.py
@@ -25,6 +25,7 @@
 from voltha.extensions.kpi.olt.olt_pm_metrics import OltPmMetrics
 from voltha.protos.device_pb2 import PmConfig, PmConfigs, PmGroupConfig
 
+
 class OpenOltStatisticsMgr(object):
     def __init__(self, openolt_device, log, **kargs):
 
@@ -89,7 +90,8 @@
         #
         #
         # #FIXME : only the first uplink is a logical port
-        # if port_stats.intf_id == 128:
+        # if platform.intf_id_to_port_type_name(port_stats.intf_id) ==
+        #   Port.ETHERNET_NNI:
         #     # ONOS update
         #     self.update_logical_port_stats(port_stats)
         # # FIXME: Discard other uplinks, they do not exist as an object