OpenOLT - hooks for customizing OpenOLT adapter
Change-Id: I88e0ab6bb5f2c14637f1d1462511f56f3d38c732
diff --git a/voltha/adapters/acme/__init__.py b/voltha/adapters/acme/__init__.py
new file mode 100644
index 0000000..b0fb0b2
--- /dev/null
+++ b/voltha/adapters/acme/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# 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.
diff --git a/voltha/adapters/acme/acme.py b/voltha/adapters/acme/acme.py
new file mode 100644
index 0000000..3682f23
--- /dev/null
+++ b/voltha/adapters/acme/acme.py
@@ -0,0 +1,77 @@
+#
+# 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.
+#
+
+"""
+Acme - A dummy olt adapter that customizes Openolt adapter.
+"""
+import structlog
+from copy import deepcopy
+
+from voltha.protos.device_pb2 import DeviceType
+from voltha.protos.adapter_pb2 import AdapterConfig
+from voltha.protos.adapter_pb2 import Adapter
+from voltha.protos.common_pb2 import LogLevel
+from voltha.adapters.openolt.openolt import OpenoltAdapter, OpenOltDefaults
+from voltha.adapters.openolt.openolt_device import OpenoltDevice
+from voltha.adapters.acme.acme_platform import AcmePlatform
+
+log = structlog.get_logger()
+
+class AcmeAdapter(OpenoltAdapter):
+ name = 'acme'
+
+ supported_device_types = [
+ DeviceType(
+ id=name,
+ adapter=name,
+ accepts_bulk_flow_update=True,
+ accepts_direct_logical_flows_update=True
+ )
+ ]
+
+ def __init__(self, adapter_agent, config):
+ super(AcmeAdapter, self).__init__(adapter_agent, config)
+
+ # overwrite the descriptor
+ self.descriptor = Adapter(
+ id=self.name,
+ vendor='Acme Inc.',
+ version='0.1',
+ config=AdapterConfig(log_level=LogLevel.INFO)
+ )
+
+ def adopt_device(self, device):
+ log.info('adopt-device', device=device)
+
+ support_classes = deepcopy(OpenOltDefaults)
+
+ # Customize platform
+ support_classes['platform'] = AcmePlatform
+
+ kwargs = {
+ 'support_classes': support_classes,
+ 'adapter_agent': self.adapter_agent,
+ 'device': device,
+ 'device_num': self.num_devices + 1
+ }
+ try:
+ self.devices[device.id] = OpenoltDevice(**kwargs)
+ except Exception as e:
+ log.error('Failed to adopt OpenOLT device', error=e)
+ del self.devices[device.id]
+ raise
+ else:
+ self.num_devices += 1
diff --git a/voltha/adapters/acme/acme_platform.py b/voltha/adapters/acme/acme_platform.py
new file mode 100644
index 0000000..e3ebf71
--- /dev/null
+++ b/voltha/adapters/acme/acme_platform.py
@@ -0,0 +1,107 @@
+#
+# 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
+
+
+MAX_ONUS_PER_PON = 2
+
+class AcmePlatform(object):
+
+ def __init__(self, log, device_info):
+ self.log = log
+ self.device_info = device_info
+
+ def mk_alloc_id(self, intf_id, onu_id, idx=0):
+ # FIXME - driver should do prefixing 1 << 10 as it is Maple specific
+ # return 1<<10 | onu_id<<6 | idx
+ return 1023 + intf_id * MAX_ONUS_PER_PON + onu_id # FIXME
+
+
+ def mk_gemport_id(self, intf_id, onu_id, idx=0):
+ return 1024 + (((MAX_ONUS_PER_PON * intf_id + onu_id - 1) * 7) + idx)
+
+ def onu_id_from_gemport_id(self, gemport_id):
+ return (((gemport_id - 1024) // 7) % MAX_ONUS_PER_PON) + 1
+
+ def mk_uni_port_num(self, intf_id, onu_id):
+ return intf_id << 11 | onu_id << 4
+
+ def mk_flow_id(self, intf_id, onu_id, idx):
+ return intf_id << 9 | onu_id << 4 | idx
+
+
+ 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 None
+
+ 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 (self.intf_id_from_uni_port_num(in_port),
+ self.onu_id_from_port_num(in_port))
+ else:
+ return (self.intf_id_from_uni_port_num(out_port),
+ self.onu_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 MAX_ONUS_PER_PON
diff --git a/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py b/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
index 87796ca..4e8b2dd 100644
--- a/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
+++ b/voltha/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
@@ -42,8 +42,6 @@
from voltha.adapters.brcm_openomci_onu.uni_port import *
from voltha.adapters.brcm_openomci_onu.onu_traffic_descriptor import *
-import voltha.adapters.openolt.openolt_platform as platform
-
OP = EntityOperations
RC = ReasonCodes
@@ -806,8 +804,10 @@
self.log.error('openolt_adapter_agent-could-not-be-retrieved')
# TODO: This knowledge is locked away in openolt. and it assumes one onu equals one uni...
- uni_no_start = platform.mk_uni_port_num(self._onu_indication.intf_id,
- self._onu_indication.onu_id)
+ parent_device = self.adapter_agent.get_device(device.parent_id)
+ parent_adapter = parent_adapter_agent.adapter.devices[parent_device.id]
+ uni_no_start = parent_adapter.platform.mk_uni_port_num(
+ self._onu_indication.intf_id, self._onu_indication.onu_id)
# TODO: Some or parts of this likely need to move to UniPort. especially the format stuff
working_port = self._next_port_number
diff --git a/voltha/adapters/openolt/openolt.py b/voltha/adapters/openolt/openolt.py
index 239cc2a..7ccec65 100644
--- a/voltha/adapters/openolt/openolt.py
+++ b/voltha/adapters/openolt/openolt.py
@@ -29,11 +29,26 @@
from voltha.protos.common_pb2 import OperationResp
from voltha.protos.device_pb2 import DeviceType, DeviceTypes
from voltha.registry import registry
+from voltha.adapters.openolt.openolt_flow_mgr import OpenOltFlowMgr
+from voltha.adapters.openolt.openolt_alarms import OpenOltAlarmMgr
+from voltha.adapters.openolt.openolt_statistics import OpenOltStatisticsMgr
+from voltha.adapters.openolt.openolt_bw import OpenOltBW
+from voltha.adapters.openolt.openolt_platform import OpenOltPlatform
_ = third_party
log = structlog.get_logger()
+OpenOltDefaults = {
+ 'support_classes': {
+ 'platform': OpenOltPlatform,
+ 'flow_mgr': OpenOltFlowMgr,
+ 'alarm_mgr': OpenOltAlarmMgr,
+ 'stats_mgr': OpenOltStatisticsMgr,
+ 'bw_mgr': OpenOltBW
+ }
+}
+
@implementer(IAdapterInterface)
class OpenoltAdapter(object):
name = 'openolt'
@@ -88,7 +103,9 @@
def adopt_device(self, device):
log.info('adopt-device', device=device)
+
kwargs = {
+ 'support_classes': OpenOltDefaults['support_classes'],
'adapter_agent': self.adapter_agent,
'device': device,
'device_num': self.num_devices + 1
diff --git a/voltha/adapters/openolt/openolt_alarms.py b/voltha/adapters/openolt/openolt_alarms.py
index efb9c1f..764a013 100644
--- a/voltha/adapters/openolt/openolt_alarms.py
+++ b/voltha/adapters/openolt/openolt_alarms.py
@@ -15,8 +15,6 @@
#
import arrow
-import voltha.adapters.openolt.openolt_platform as platform
-# from voltha.protos.device_pb2 import Port
from voltha.extensions.alarms.adapter_alarms import AdapterAlarms
from voltha.extensions.alarms.simulator.simulate_alarms import AdapterAlarmSimulator
from voltha.extensions.alarms.olt.olt_los_alarm import OltLosAlarm
@@ -37,7 +35,8 @@
class OpenOltAlarmMgr(object):
- def __init__(self, log, adapter_agent, device_id, logical_device_id):
+ def __init__(self, log, adapter_agent, device_id, logical_device_id,
+ platform):
"""
20180711 - Addition of adapter_agent and device_id
to facilitate alarm processing and kafka posting
@@ -49,6 +48,7 @@
self.adapter_agent = adapter_agent
self.device_id = device_id
self.logical_device_id = logical_device_id
+ self.platform = platform
"""
The following is added to reduce the continual posting of OLT LOS alarming
to Kafka. Set enable_alarm_suppress = true to enable otherwise the
@@ -112,13 +112,13 @@
self.log.debug('los indication received', los_ind=los_ind,
int_id=los_ind.intf_id, status=los_ind.status)
try:
- port_type_name = platform.intf_id_to_port_type_name(los_ind.intf_id)
+ port_type_name = self.platform.intf_id_to_port_type_name(los_ind.intf_id)
if los_ind.status == 1 or los_ind.status == "on":
# Zero out the suppression counter on OLT_LOS raise
self.alarm_suppress['olt_los_clear'] = 0
OltLosAlarm(self.alarms, intf_id=los_ind.intf_id, port_type_name=port_type_name).raise_alarm()
else:
- """
+ """
Check if there has been more that one los clear following a previous los
"""
if self.alarm_suppress['olt_los_clear'] == 0 and self.enable_alarm_suppress:
@@ -455,7 +455,7 @@
onu_device = None
onu_device = self.adapter_agent.get_child_device(
self.device_id,
- parent_port_no=platform.intf_id_to_port_no(
+ parent_port_no=self.platform.intf_id_to_port_no(
port_intf_id, device_pb2.Port.PON_OLT),
onu_id=onu_id)
onu_device_id = onu_device.id
diff --git a/voltha/adapters/openolt/openolt_device.py b/voltha/adapters/openolt/openolt_device.py
index 0255901..e5bf92f 100644
--- a/voltha/adapters/openolt/openolt_device.py
+++ b/voltha/adapters/openolt/openolt_device.py
@@ -36,11 +36,6 @@
from voltha.protos.bbf_fiber_tcont_body_pb2 import TcontsConfigData
from voltha.protos.bbf_fiber_gemport_body_pb2 import GemportsConfigData
-from voltha.adapters.openolt.openolt_statistics import OpenOltStatisticsMgr
-import voltha.adapters.openolt.openolt_platform as platform
-from voltha.adapters.openolt.openolt_flow_mgr import OpenOltFlowMgr
-from voltha.adapters.openolt.openolt_alarms import OpenOltAlarmMgr
-from voltha.adapters.openolt.openolt_bw import OpenOltBW
from voltha.extensions.alarms.onu.onu_discovery_alarm import OnuDiscoveryAlarm
@@ -90,6 +85,13 @@
self.adapter_agent = kwargs['adapter_agent']
self.device_num = kwargs['device_num']
device = kwargs['device']
+
+ self.platform_class = kwargs['support_classes']['platform']
+ self.flow_mgr_class = kwargs['support_classes']['flow_mgr']
+ self.alarm_mgr_class = kwargs['support_classes']['alarm_mgr']
+ self.stats_mgr_class = kwargs['support_classes']['stats_mgr']
+ self.bw_mgr_class = kwargs['support_classes']['bw_mgr']
+
is_reconciliation = kwargs.get('reconciliation', False)
self.device_id = device.id
self.host_and_port = device.host_and_port
@@ -151,12 +153,6 @@
self.channel = grpc.insecure_channel(self.host_and_port)
self.channel_ready_future = grpc.channel_ready_future(self.channel)
- 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)
-
self.log.info('openolt-device-created', device_id=self.device_id)
def post_init(self, event):
@@ -188,16 +184,23 @@
device_info = self.stub.GetDeviceInfo(openolt_pb2.Empty())
self.log.info('Device connected', device_info=device_info)
+ self.platform = self.platform_class(self.log, device_info)
+
+ self.flow_mgr = self.flow_mgr_class(self.log, self.stub,
+ self.device_id,
+ self.logical_device_id,
+ self.platform)
+ self.alarm_mgr = self.alarm_mgr_class(self.log, self.adapter_agent,
+ self.device_id,
+ self.logical_device_id,
+ self.platform)
+ self.stats_mgr = self.stats_mgr_class(self, self.log, self.platform)
+ self.bw_mgr = self.bw_mgr_class(self.log, self.proxy)
+
device.vendor = device_info.vendor
device.model = device_info.model
device.hardware_version = device_info.hardware_version
device.firmware_version = device_info.firmware_version
-
- self.flow_mgr = OpenOltFlowMgr(self.log, self.stub, self.device_id,
- self.logical_device_id)
-
- # TODO: check for uptime and reboot if too long (VOL-1192)
-
device.connect_status = ConnectStatus.REACHABLE
self.adapter_agent.update_device(device)
@@ -221,7 +224,7 @@
# Children ports
child_devices = self.adapter_agent.get_child_devices(self.device_id)
for onu_device in child_devices:
- uni_no = platform.mk_uni_port_num(
+ uni_no = self.platform.mk_uni_port_num(
onu_device.proxy_address.channel_id,
onu_device.proxy_address.onu_id)
uni_name = self.port_name(uni_no, Port.ETHERNET_UNI,
@@ -395,7 +398,7 @@
try:
self.add_onu_device(
intf_id,
- platform.intf_id_to_port_no(intf_id, Port.PON_OLT),
+ self.platform.intf_id_to_port_no(intf_id, Port.PON_OLT),
onu_id, serial_number)
self.activate_onu(intf_id, onu_id, serial_number,
serial_number_str)
@@ -455,7 +458,7 @@
else:
onu_device = self.adapter_agent.get_child_device(
self.device_id,
- parent_port_no=platform.intf_id_to_port_no(
+ parent_port_no=self.platform.intf_id_to_port_no(
onu_indication.intf_id, Port.PON_OLT),
onu_id=onu_indication.onu_id)
@@ -464,10 +467,10 @@
onu_id=onu_indication.onu_id)
return
- if platform.intf_id_from_pon_port_no(onu_device.parent_port_no) \
+ if self.platform.intf_id_from_pon_port_no(onu_device.parent_port_no) \
!= onu_indication.intf_id:
self.log.warn('ONU-is-on-a-different-intf-id-now',
- previous_intf_id=platform.intf_id_from_pon_port_no(
+ previous_intf_id=self.platform.intf_id_from_pon_port_no(
onu_device.parent_port_no),
current_intf_id=onu_indication.intf_id)
# FIXME - handle intf_id mismatch (ONU move?)
@@ -479,7 +482,7 @@
expected_onu_id=onu_device.proxy_address.onu_id,
received_onu_id=onu_indication.onu_id)
- uni_no = platform.mk_uni_port_num(onu_indication.intf_id,
+ uni_no = self.platform.mk_uni_port_num(onu_indication.intf_id,
onu_indication.onu_id)
uni_name = self.port_name(uni_no, Port.ETHERNET_UNI,
serial_number=onu_device.serial_number)
@@ -552,12 +555,12 @@
# tcont creation (onu)
tcont = TcontsConfigData()
- tcont.alloc_id = platform.mk_alloc_id(
+ tcont.alloc_id = self.platform.mk_alloc_id(
onu_indication.intf_id, onu_indication.onu_id)
# gem port creation
gem_port = GemportsConfigData()
- gem_port.gemport_id = platform.mk_gemport_id(
+ gem_port.gemport_id = self.platform.mk_gemport_id(
onu_indication.intf_id,
onu_indication.onu_id)
@@ -620,7 +623,7 @@
onu_device = self.adapter_agent.get_child_device(
self.device_id, onu_id=omci_indication.onu_id,
- parent_port_no=platform.intf_id_to_port_no(
+ parent_port_no=self.platform.intf_id_to_port_no(
omci_indication.intf_id, Port.PON_OLT), )
self.adapter_agent.receive_proxied_message(onu_device.proxy_address,
@@ -635,11 +638,11 @@
flow_id=pkt_indication.flow_id)
if pkt_indication.intf_type == "pon":
- onu_id = platform.onu_id_from_gemport_id(pkt_indication.gemport_id)
- logical_port_num = platform.mk_uni_port_num(pkt_indication.intf_id,
+ onu_id = self.platform.onu_id_from_gemport_id(pkt_indication.gemport_id)
+ logical_port_num = self.platform.mk_uni_port_num(pkt_indication.intf_id,
onu_id)
elif pkt_indication.intf_type == "nni":
- logical_port_num = platform.intf_id_to_port_no(
+ logical_port_num = self.platform.intf_id_to_port_no(
pkt_indication.intf_id,
Port.ETHERNET_NNI)
@@ -682,13 +685,13 @@
self.log.debug(
'sending-packet-to-ONU', egress_port=egress_port,
- intf_id=platform.intf_id_from_uni_port_num(egress_port),
- onu_id=platform.onu_id_from_port_num(egress_port),
+ intf_id=self.platform.intf_id_from_uni_port_num(egress_port),
+ onu_id=self.platform.onu_id_from_port_num(egress_port),
packet=str(payload).encode("HEX"))
onu_pkt = openolt_pb2.OnuPacket(
- intf_id=platform.intf_id_from_uni_port_num(egress_port),
- onu_id=platform.onu_id_from_port_num(egress_port),
+ intf_id=self.platform.intf_id_from_uni_port_num(egress_port),
+ onu_id=self.platform.onu_id_from_port_num(egress_port),
pkt=send_pkt)
self.stub.OnuPacketOut(onu_pkt)
@@ -700,7 +703,7 @@
send_pkt = binascii.unhexlify(str(pkt).encode("HEX"))
uplink_pkt = openolt_pb2.UplinkPacket(
- intf_id=platform.intf_id_from_nni_port_num(egress_port),
+ intf_id=self.platform.intf_id_from_nni_port_num(egress_port),
pkt=send_pkt)
self.stub.UplinkPacketOut(uplink_pkt)
@@ -713,7 +716,7 @@
def send_proxied_message(self, proxy_address, msg):
onu_device = self.adapter_agent.get_child_device(
self.device_id, onu_id=proxy_address.onu_id,
- parent_port_no=platform.intf_id_to_port_no(
+ parent_port_no=self.platform.intf_id_to_port_no(
proxy_address.channel_id, Port.PON_OLT)
)
if onu_device.connect_status != ConnectStatus.REACHABLE:
@@ -801,7 +804,7 @@
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)
+ port_no = self.platform.intf_id_to_port_no(intf_id, port_type)
label = self.port_name(port_no, port_type, intf_id)
@@ -843,12 +846,12 @@
pon_onu_ids = [onu_device.proxy_address.onu_id
for onu_device in onu_devices
if onu_device.proxy_address.channel_id == intf_id]
- for i in range(1, platform.MAX_ONUS_PER_PON):
+ for i in range(1, self.platform.max_onus_per_pon()):
if i not in pon_onu_ids:
return i
self.log.error('All available onu_ids taken on this pon',
- intf_id=intf_id, ids_taken=platform.MAX_ONUS_PER_PON)
+ intf_id=intf_id, ids_taken=self.platform.max_onus_per_pon())
return None
def update_flow_table(self, flows):
diff --git a/voltha/adapters/openolt/openolt_flow_mgr.py b/voltha/adapters/openolt/openolt_flow_mgr.py
index 4a57c5c..9e21510 100644
--- a/voltha/adapters/openolt/openolt_flow_mgr.py
+++ b/voltha/adapters/openolt/openolt_flow_mgr.py
@@ -22,7 +22,6 @@
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
from voltha.registry import registry
@@ -72,11 +71,13 @@
class OpenOltFlowMgr(object):
- def __init__(self, log, stub, device_id, logical_device_id):
+ def __init__(self, log, stub, device_id, logical_device_id,
+ platform):
self.log = log
self.stub = stub
self.device_id = device_id
self.logical_device_id = logical_device_id
+ self.platform = platform
self.logical_flows_proxy = registry('core').get_proxy(
'/logical_devices/{}/flows'.format(self.logical_device_id))
self.flows_proxy = registry('core').get_proxy(
@@ -188,7 +189,7 @@
classifier_info[METADATA] = field.vlan_vid & 0xfff
- (intf_id, onu_id) = platform.extract_access_from_flow(
+ (intf_id, onu_id) = self.platform.extract_access_from_flow(
classifier_info[IN_PORT], action_info[OUTPUT])
@@ -317,9 +318,9 @@
def add_hsia_flow(self, intf_id, onu_id, classifier, action,
direction, hsia_id, logical_flow):
- gemport_id = platform.mk_gemport_id(intf_id, onu_id)
- alloc_id = platform.mk_alloc_id(intf_id, onu_id)
- flow_id = platform.mk_flow_id(intf_id, onu_id, hsia_id)
+ gemport_id = self.platform.mk_gemport_id(intf_id, onu_id)
+ alloc_id = self.platform.mk_alloc_id(intf_id, onu_id)
+ flow_id = self.platform.mk_flow_id(intf_id, onu_id, hsia_id)
flow = openolt_pb2.Flow(
onu_id=onu_id, flow_id=flow_id, flow_type=direction,
@@ -341,9 +342,9 @@
classifier[PACKET_TAG_TYPE] = SINGLE_TAG
classifier.pop(VLAN_VID, None)
- gemport_id = platform.mk_gemport_id(intf_id, onu_id)
- alloc_id = platform.mk_alloc_id(intf_id, onu_id)
- flow_id = platform.mk_flow_id(intf_id, onu_id, DHCP_FLOW_INDEX)
+ gemport_id = self.platform.mk_gemport_id(intf_id, onu_id)
+ alloc_id = self.platform.mk_alloc_id(intf_id, onu_id)
+ flow_id = self.platform.mk_flow_id(intf_id, onu_id, DHCP_FLOW_INDEX)
upstream_flow = openolt_pb2.Flow(
onu_id=onu_id, flow_id=flow_id, flow_type=UPSTREAM,
@@ -362,15 +363,15 @@
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 = \
- platform.intf_id_to_port_no(0, Port.ETHERNET_NNI)
+ self.platform.intf_id_to_port_no(0, Port.ETHERNET_NNI)
classifier[UDP_SRC] = 67
classifier[UDP_DST] = 68
classifier[PACKET_TAG_TYPE] = DOUBLE_TAG
action.pop(PUSH_VLAN, None)
- flow_id = platform.mk_flow_id(intf_id, onu_id,
- DHCP_DOWNLINK_FLOW_INDEX)
+ flow_id = self.platform.mk_flow_id(intf_id, onu_id,
+ DHCP_DOWNLINK_FLOW_INDEX)
downstream_flow = openolt_pb2.Flow(
onu_id=onu_id, flow_id=flow_id, flow_type=DOWNSTREAM,
@@ -395,9 +396,9 @@
# Add Upstream EAPOL Flow.
- gemport_id = platform.mk_gemport_id(intf_id, onu_id)
- alloc_id = platform.mk_alloc_id(intf_id, onu_id)
- uplink_flow_id = platform.mk_flow_id(intf_id, onu_id, eapol_id)
+ gemport_id = self.platform.mk_gemport_id(intf_id, onu_id)
+ alloc_id = self.platform.mk_alloc_id(intf_id, onu_id)
+ uplink_flow_id = self.platform.mk_flow_id(intf_id, onu_id, eapol_id)
upstream_flow = openolt_pb2.Flow(
onu_id=onu_id, flow_id=uplink_flow_id, flow_type=UPSTREAM,
@@ -428,8 +429,8 @@
downlink_action[PUSH_VLAN] = True
downlink_action[VLAN_VID] = vlan_id
- downlink_flow_id = platform.mk_flow_id(intf_id, onu_id,
- DOWNSTREAM_FLOW_FOR_PACKET_OUT)
+ downlink_flow_id = self.platform.mk_flow_id(
+ intf_id, onu_id, DOWNSTREAM_FLOW_FOR_PACKET_OUT)
downstream_flow = openolt_pb2.Flow(
onu_id=onu_id, flow_id=downlink_flow_id, flow_type=DOWNSTREAM,
@@ -450,7 +451,7 @@
downstream_logical_flow.instructions.extend(
fd.mk_instructions_from_actions([fd.output(
- platform.mk_uni_port_num(intf_id, onu_id))]))
+ self.platform.mk_uni_port_num(intf_id, onu_id))]))
self.add_flow_to_device(downstream_flow, downstream_logical_flow)
@@ -560,9 +561,9 @@
if field.eth_type == EAP_ETH_TYPE:
eap_flow = True
if field.type == fd.IN_PORT:
- eap_intf_id = platform.intf_id_from_uni_port_num(
+ eap_intf_id = self.platform.intf_id_from_uni_port_num(
field.port)
- eap_onu_id = platform.onu_id_from_port_num(field.port)
+ eap_onu_id = self.platform.onu_id_from_port_num(field.port)
if eap_flow:
self.log.debug('eap flow detected', onu_id=onu_id,
@@ -581,7 +582,7 @@
in_port = fd.get_in_port(flow)
out_port = fd.get_out_port(flow)
if in_port == port and \
- platform.intf_id_to_port_type_name(out_port) \
+ self.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)
diff --git a/voltha/adapters/openolt/openolt_platform.py b/voltha/adapters/openolt/openolt_platform.py
index a9dc3fd..0a8a2fd 100644
--- a/voltha/adapters/openolt/openolt_platform.py
+++ b/voltha/adapters/openolt/openolt_platform.py
@@ -106,80 +106,88 @@
# MAX_ONUS_PER_PON = 112
MAX_ONUS_PER_PON = 32
-def mk_alloc_id(intf_id, onu_id, idx=0):
- # FIXME - driver should do prefixing 1 << 10 as it is Maple specific
- # return 1<<10 | onu_id<<6 | idx
- return 1023 + intf_id * MAX_ONUS_PER_PON + onu_id # FIXME
+class OpenOltPlatform(object):
+
+ def __init__(self, log, device_info):
+ self.log = log
+ self.device_info = device_info
+
+ def mk_alloc_id(self, intf_id, onu_id, idx=0):
+ # FIXME - driver should do prefixing 1 << 10 as it is Maple specific
+ # return 1<<10 | onu_id<<6 | idx
+ return 1023 + intf_id * MAX_ONUS_PER_PON + onu_id # FIXME
-def mk_gemport_id(intf_id, onu_id, idx=0):
- return 1024 + (((MAX_ONUS_PER_PON * intf_id + onu_id - 1) * 7) + idx)
+ def mk_gemport_id(self, intf_id, onu_id, idx=0):
+ return 1024 + (((MAX_ONUS_PER_PON * intf_id + onu_id - 1) * 7) + idx)
-def onu_id_from_gemport_id(gemport_id):
- return (((gemport_id - 1024) // 7) % MAX_ONUS_PER_PON) + 1
+ def onu_id_from_gemport_id(self, gemport_id):
+ return (((gemport_id - 1024) // 7) % MAX_ONUS_PER_PON) + 1
-def mk_uni_port_num(intf_id, onu_id):
- return intf_id << 11 | onu_id << 4
+ def mk_uni_port_num(self, intf_id, onu_id):
+ return intf_id << 11 | onu_id << 4
-def mk_flow_id(intf_id, onu_id, idx):
- return intf_id << 9 | onu_id << 4 | idx
+ def mk_flow_id(self, intf_id, onu_id, idx):
+ return intf_id << 9 | onu_id << 4 | idx
-def onu_id_from_port_num(port_num):
- return (port_num >> 4) & 0x7F
+ def onu_id_from_port_num(self, port_num):
+ return (port_num >> 4) & 0x7F
-def intf_id_from_uni_port_num(port_num):
- return (port_num >> 11) & 0xF
+ def intf_id_from_uni_port_num(self, port_num):
+ return (port_num >> 11) & 0xF
-def intf_id_from_pon_port_no(port_no):
- return port_no & 0xF
+ def intf_id_from_pon_port_no(self, port_no):
+ return port_no & 0xF
-def intf_id_to_port_no(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_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(port_num):
- return port_num & 0xFFFF
+ def intf_id_from_nni_port_num(self, port_num):
+ return port_num & 0xFFFF
-def intf_id_to_port_type_name(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 None
+ 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 None
-def port_type_name_by_port_index(port_index):
- try:
- return dev_pb2._PORT_PORTTYPE.values_by_number[port_index].name
- except Exception as err:
- raise Exception(err)
+ 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(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 extract_access_from_flow(self, in_port, out_port):
+ if self.is_upstream(out_port):
+ return (self.intf_id_from_uni_port_num(in_port),
+ self.onu_id_from_port_num(in_port))
+ else:
+ return (self.intf_id_from_uni_port_num(out_port),
+ self.onu_id_from_port_num(out_port))
-def is_upstream(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
+ if out_port in [0xfffd, 0xfffffffd]:
+ # To Controller
+ return True
+ if (out_port & (0x1 << 16)) == (0x1 << 16):
+ # NNI interface
+ return True
- return False
+ return False
+ def max_onus_per_pon(self):
+ return MAX_ONUS_PER_PON
diff --git a/voltha/adapters/openolt/openolt_statistics.py b/voltha/adapters/openolt/openolt_statistics.py
index 118b025..bfdb61c 100644
--- a/voltha/adapters/openolt/openolt_statistics.py
+++ b/voltha/adapters/openolt/openolt_statistics.py
@@ -15,7 +15,6 @@
#
# from voltha.protos.events_pb2 import KpiEvent, MetricValuePairs
# from voltha.protos.events_pb2 import KpiEventType
-# import voltha.adapters.openolt.openolt_platform as platform
# from voltha.adapters.openolt.nni_port import NniPort
# from voltha.adapters.openolt.pon_port import PonPort
@@ -24,11 +23,10 @@
from twisted.internet import reactor, defer
from voltha.extensions.kpi.olt.olt_pm_metrics import OltPmMetrics
from voltha.protos.device_pb2 import PmConfig, PmConfigs, PmGroupConfig, Port
-import voltha.adapters.openolt.openolt_platform as platform
class OpenOltStatisticsMgr(object):
- def __init__(self, openolt_device, log, **kargs):
+ def __init__(self, openolt_device, log, platform, **kargs):
"""
kargs are used to pass debugging flags at this time.
@@ -38,6 +36,7 @@
"""
self.device = openolt_device
self.log = log
+ self.platform = platform
# Northbound and Southbound ports
# added to initialize the pm_metrics
self.northbound_ports = self.init_ports(type="nni")
@@ -66,7 +65,7 @@
"""
override the default naming structures in the OltPmMetrics class.
This is being done until the protos can be modified in the BAL driver
-
+
"""
self.pm_metrics.nni_pm_names = (self.get_openolt_port_pm_names())['nni_pm_names']
self.pm_metrics.nni_metrics_config = {m: PmConfig(name=m, type=t, enabled=True)
@@ -135,8 +134,8 @@
try:
intf_id = port_stats.intf_id
- if platform.intf_id_to_port_no(0, Port.ETHERNET_NNI) < intf_id < \
- platform.intf_id_to_port_no(4, Port.ETHERNET_NNI) :
+ if self.platform.intf_id_to_port_no(0, Port.ETHERNET_NNI) < intf_id < \
+ self.platform.intf_id_to_port_no(4, Port.ETHERNET_NNI) :
"""
for this release we are only interested in the first NNI for
Northbound.
@@ -166,15 +165,15 @@
"""
Based upon the intf_id map to an nni port or a pon port
the intf_id is the key to the north or south bound collections
-
+
Based upon the intf_id the port object (nni_port or pon_port) will
have its data attr. updated by the current dataset collected.
-
+
For prefixing the rule is currently to use the port number and not the intf_id
-
+
"""
#FIXME : Just use first NNI for now
- if intf_id == platform.intf_id_to_port_no(0,
+ if intf_id == self.platform.intf_id_to_port_no(0,
Port.ETHERNET_NNI):
#NNI port (just the first one)
self.update_port_object_kpi_data(
@@ -218,9 +217,9 @@
"""
The following 4 methods customer naming, the generation of the port objects, building of those
objects and populating new data. The pm metrics operate on the value that are contained in the Port objects.
- This class updates those port objects with the current data from the grpc indication and
+ This class updates those port objects with the current data from the grpc indication and
post the data on a fixed interval.
-
+
"""
def get_openolt_port_pm_names(self):
"""
@@ -386,14 +385,14 @@
:return:
"""
try:
- """
- This builds a port object which is added to the
+ """
+ This builds a port object which is added to the
appropriate northbound or southbound values
"""
if type == "nni":
kwargs = {
'port_no': port_num,
- 'intf_id': platform.intf_id_to_port_no(port_num,
+ 'intf_id': self.platform.intf_id_to_port_no(port_num,
Port.ETHERNET_NNI),
"device_id": self.device.device_id
}
@@ -405,9 +404,9 @@
# intf_id and pon_id are currently equal.
kwargs = {
'port_no': port_num,
- 'intf_id': platform.intf_id_to_port_no(port_num,
+ 'intf_id': self.platform.intf_id_to_port_no(port_num,
Port.PON_OLT),
- 'pon-id': platform.intf_id_to_port_no(port_num,
+ 'pon-id': self.platform.intf_id_to_port_no(port_num,
Port.PON_OLT),
"device_id": self.device.device_id
}
@@ -487,12 +486,12 @@
Statistics taken from nni_port
self.intf_id = 0 #handled by getter
self.port_no = 0 #handled by getter
- self.port_id = 0 #handled by getter
+ self.port_id = 0 #handled by getter
Note: In the current implementation of the kpis coming from the BAL the stats are the
samne model for NNI and PON.
- TODO: Integrate additional kpis for the PON and other southbound port objecgts.
+ TODO: Integrate additional kpis for the PON and other southbound port objecgts.
"""
@@ -604,4 +603,4 @@
return "NniPort-{}: Admin: {}, Oper: {}, parent: {}".format(self._port_no,
self._admin_state,
self._oper_status,
- self._parent)
\ No newline at end of file
+ self._parent)