VOL-956 OpenOLT - ONU rate limiting

Change-Id: Icf5e4f97bbd8bc14b9cffdee5a3b33ceec54583f
diff --git a/voltha/adapters/openolt/openolt_bw.py b/voltha/adapters/openolt/openolt_bw.py
new file mode 100644
index 0000000..77e52d1
--- /dev/null
+++ b/voltha/adapters/openolt/openolt_bw.py
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+DEFAULT_ONU_BW_PROFILE = "default"
+DEFAULT_ONU_PIR = 1000000  # 1Gbps
+
+
+class OpenOltBW(object):
+
+    def __init__(self, log, proxy):
+        self.log = log
+        self.proxy = proxy
+
+    def pir(self, serial_number):
+        bw = 0
+        try:
+            bw = self.proxy.get(
+                '/traffic_descriptor_profiles/{}'.format(serial_number))
+        except KeyError:
+            self.log.info('bandwidth not configured',
+                          serial_number=serial_number)
+            try:
+                bw = self.proxy.get('/traffic_descriptor_profiles/{}' \
+                                    .format(DEFAULT_ONU_BW_PROFILE))
+            except KeyError:
+                return DEFAULT_ONU_PIR
+
+        return bw.maximum_bandwidth
diff --git a/voltha/adapters/openolt/openolt_device.py b/voltha/adapters/openolt/openolt_device.py
index 2eeb7a1..6f6e689 100644
--- a/voltha/adapters/openolt/openolt_device.py
+++ b/voltha/adapters/openolt/openolt_device.py
@@ -21,7 +21,7 @@
 import structlog
 from twisted.internet import reactor
 from scapy.layers.l2 import Ether, Dot1Q
-from transitions import Machine, State
+from transitions import Machine
 
 from voltha.protos.device_pb2 import Port, Device
 from voltha.protos.common_pb2 import OperStatus, AdminState, ConnectStatus
@@ -44,6 +44,7 @@
 from voltha.adapters.openolt.openolt_flow_mgr import OpenOltFlowMgr, \
         DEFAULT_MGMT_VLAN
 from voltha.adapters.openolt.openolt_alarms import OpenOltAlarmMgr
+from voltha.adapters.openolt.openolt_bw import OpenOltBW
 
 
 class OpenoltDevice(object):
@@ -172,9 +173,11 @@
 
         self.stub = openolt_pb2_grpc.OpenoltStub(self.channel)
         self.flow_mgr = OpenOltFlowMgr(self.log, self.stub, self.device_id)
-        self.alarm_mgr = OpenOltAlarmMgr(self.log, self.adapter_agent, self.device_id,
+        self.alarm_mgr = OpenOltAlarmMgr(self.log, self.adapter_agent,
+                                         self.device_id,
                                          self.logical_device_id)
         self.stats_mgr = OpenOltStatisticsMgr(self, self.log)
+        self.bw_mgr = OpenOltBW(self.log, self.proxy)
 
     def do_state_up(self, event):
         device = self.adapter_agent.get_device(self.device_id)
@@ -338,6 +341,10 @@
         self.log.debug("onu discovery indication", intf_id=intf_id,
                        serial_number=serial_number_str)
 
+        pir = self.bw_mgr.pir(serial_number_str)
+        self.log.debug("peak information rate", serial_number=serial_number,
+                       pir=pir)
+
         onu_device = self.adapter_agent.get_child_device(
             self.device_id,
             serial_number=serial_number_str)
@@ -352,7 +359,7 @@
                 self.log.info("activate-onu", intf_id=intf_id, onu_id=onu_id,
                               serial_number=serial_number_str)
                 onu = openolt_pb2.Onu(intf_id=intf_id, onu_id=onu_id,
-                                      serial_number=serial_number)
+                                      serial_number=serial_number, pir=pir)
                 self.stub.ActivateOnu(onu)
             except Exception as e:
                 self.log.exception('onu-activation-failed', e=e)
@@ -383,7 +390,7 @@
                 self.adapter_agent.update_device(onu_device)
 
                 onu = openolt_pb2.Onu(intf_id=intf_id, onu_id=onu_id,
-                                      serial_number=serial_number)
+                                      serial_number=serial_number, pir=pir)
                 self.stub.ActivateOnu(onu)
             else:
                 self.log.warn('unexpected state', onu_id=onu_id,
@@ -649,7 +656,6 @@
                   logical_port_no=logical_port_num)
         self.adapter_agent.send_packet_in(packet=str(pkt), **kw)
 
-
     def packet_out(self, egress_port, msg):
         pkt = Ether(msg)
         self.log.info('packet out', egress_port=egress_port,
@@ -846,15 +852,13 @@
                 except grpc.RpcError as grpc_e:
                     if grpc_e.code() == grpc.StatusCode.ALREADY_EXISTS:
                         self.log.warn('flow already exists', e=grpc_e,
-                                       flow=flow)
+                                      flow=flow)
                     else:
                         self.log.error('failed to add flow', flow=flow,
                                        e=grpc_e)
                 except Exception as e:
                     self.log.error('failed to add flow', flow=flow, e=e)
 
-
-    # There has to be a better way to do this
     def ip_hex(self, ip):
         octets = ip.split(".")
         hex_ip = []
@@ -918,8 +922,10 @@
                        onu_device=child_device,
                        onu_serial_number=child_device.serial_number)
         vendor_id = child_device.vendor_id.encode('hex')
-        vendor_specific = child_device.serial_number.replace(child_device.vendor_id,'').encode('hex')
-        serial_number = openolt_pb2.SerialNumber(vendor_id=vendor_id, vendor_specific=vendor_specific)
+        vendor_specific = child_device.serial_number.replace(
+            child_device.vendor_id, '').encode('hex')
+        serial_number = openolt_pb2.SerialNumber(
+            vendor_id=vendor_id, vendor_specific=vendor_specific)
         onu = openolt_pb2.Onu(intf_id=child_device.proxy_address.channel_id,
                               onu_id=child_device.proxy_address.onu_id,
                               serial_number=serial_number)
@@ -931,9 +937,11 @@
                        onu_device=child_device,
                        onu_serial_number=child_device.serial_number)
         vendor_id = child_device.vendor_id.encode('hex')
-        vendor_specific = child_device.serial_number.replace(child_device.vendor_id,'').encode('hex')
-        serial_number = openolt_pb2.SerialNumber(vendor_id=vendor_id, vendor_specific=vendor_specific)
+        vendor_specific = child_device.serial_number.replace(
+            child_device.vendor_id, '').encode('hex')
+        serial_number = openolt_pb2.SerialNumber(
+            vendor_id=vendor_id, vendor_specific=vendor_specific)
         onu = openolt_pb2.Onu(intf_id=child_device.proxy_address.channel_id,
                               onu_id=child_device.proxy_address.onu_id,
                               serial_number=serial_number)
-        self.stub.DeleteOnu(onu)
\ No newline at end of file
+        self.stub.DeleteOnu(onu)
diff --git a/voltha/adapters/openolt/protos/openolt.proto b/voltha/adapters/openolt/protos/openolt.proto
index 1140748..87515f9 100644
--- a/voltha/adapters/openolt/protos/openolt.proto
+++ b/voltha/adapters/openolt/protos/openolt.proto
@@ -175,6 +175,7 @@
     fixed32 intf_id = 1;
     fixed32 onu_id = 2;
     SerialNumber serial_number = 3;
+    fixed32 pir = 4;   // peak information rate assigned to onu
 }
 
 message OmciMsg {