Initial commit moving openolt adapter from voltha-go to the new repo.
This version works with ponsim rather than openolt, this is temporary.
It is currently being fixed to work with openolt.

Change-Id: I34a800c98f050140b367e2d474b7aa8b79f34b9a
Signed-off-by: William Kurkian <wkurkian@cisco.com>
diff --git a/python/adapters/openolt/openolt_platform.py b/python/adapters/openolt/openolt_platform.py
new file mode 100644
index 0000000..a44eafc
--- /dev/null
+++ b/python/adapters/openolt/openolt_platform.py
@@ -0,0 +1,164 @@
+#
+# 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.protos.device_pb2 import Port
+import voltha.protos.device_pb2 as dev_pb2
+
+"""
+Encoding of identifiers
+=======================
+
+Flow id
+
+    Identifies a flow within a single OLT
+    Flow Id is unique per OLT
+    Multiple GEM ports can map to same flow id
+
+     13    11              4      0
+    +--------+--------------+------+
+    | pon id |    onu id    | Flow |
+    |        |              | idx  |
+    +--------+--------------+------+
+
+    14 bits = 16384 flows (per OLT).
+
+    pon id = 4 bits = 16 PON ports
+    onu id = 7 bits = 128 ONUss per PON port
+    Flow index = 3 bits = 4 bi-directional flows per ONU
+                        = 8 uni-directional flows per ONU
+
+
+Logical (OF) UNI port number
+
+    OpenFlow port number corresponding to PON UNI
+
+     15       11              4      0
+    +--+--------+--------------+------+
+    |0 | pon id |    onu id    |   0  |
+    +--+--------+--------------+------+
+
+    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
+
+    OpenFlow port number corresponding to PON OLT ports
+
+     31    28                                 0
+    +--------+------------------------~~~------+
+    |  0x2   |          pon intf id            |
+    +--------+------------------------~~~------+
+
+"""
+
+class OpenOltPlatform(object):
+    MAX_PONS_PER_OLT = 16
+    MAX_ONUS_PER_PON = 32
+    MAX_UNIS_PER_ONU = 16
+
+    def __init__(self, log, resource_mgr):
+        self.log = log
+        self.resource_mgr = resource_mgr
+
+    def mk_uni_port_num(self, intf_id, onu_id, uni_id):
+        assert intf_id < OpenOltPlatform.MAX_PONS_PER_OLT
+        assert onu_id < OpenOltPlatform.MAX_ONUS_PER_PON
+        assert uni_id < OpenOltPlatform.MAX_UNIS_PER_ONU
+        self.resource_mgr.assert_uni_id_limit(intf_id, onu_id, uni_id)
+        return intf_id << 11 | onu_id << 4 | uni_id
+
+    #def mk_flow_id(self, intf_id, onu_id, idx):
+    #    return intf_id << 9 | onu_id << 4 | idx
+
+    def uni_id_from_port_num(self, port_num):
+        return port_num & 0xF
+
+    def onu_id_from_port_num(self, port_num):
+        return (port_num >> 4) & 0x7F
+
+
+    def intf_id_from_uni_port_num(self, port_num):
+        return (port_num >> 11) & 0xF
+
+
+    def intf_id_from_pon_port_no(self, port_no):
+        return port_no & 0xF
+
+
+    def intf_id_to_port_no(self, intf_id, intf_type):
+        if intf_type is Port.ETHERNET_NNI:
+            return (0x1 << 16) | intf_id
+        elif intf_type is Port.PON_OLT:
+            return 0x2 << 28 | intf_id
+        else:
+            raise Exception('Invalid port type')
+
+
+    def intf_id_from_nni_port_num(self, port_num):
+        return port_num & 0xFFFF
+
+
+    def intf_id_to_port_type_name(self, intf_id):
+        if (2 << 28 ^ intf_id) < 16:
+            return Port.PON_OLT
+        elif intf_id & (0x1 << 16) == (0x1 << 16):
+            return Port.ETHERNET_NNI
+        else:
+            return Port.ETHERNET_UNI
+
+    def port_type_name_by_port_index(self, port_index):
+        try:
+            return dev_pb2._PORT_PORTTYPE.values_by_number[port_index].name
+        except Exception as err:
+            raise Exception(err)
+
+    def extract_access_from_flow(self, in_port, out_port):
+        if self.is_upstream(out_port):
+            return (in_port,
+                    self.intf_id_from_uni_port_num(in_port),
+                    self.onu_id_from_port_num(in_port),
+                    self.uni_id_from_port_num(in_port))
+        else:
+            return (out_port,
+                    self.intf_id_from_uni_port_num(out_port),
+                    self.onu_id_from_port_num(out_port),
+                    self.uni_id_from_port_num(out_port))
+
+    def is_upstream(self, out_port):
+
+        if out_port in [0xfffd, 0xfffffffd]:
+            # To Controller
+            return True
+        if (out_port & (0x1 << 16)) == (0x1 << 16):
+            # NNI interface
+            return True
+
+        return False
+    #
+    #def max_onus_per_pon(self):
+    #    return OpenOltPlatform.MAX_ONUS_PER_PON