ADTRAN OLT: Support ONU removal on LOS
Change-Id: If4b5d2de7b3b340fc2101b64e9775e942eb8e442
diff --git a/voltha/adapters/adtran_olt/adtran_olt.py b/voltha/adapters/adtran_olt/adtran_olt.py
index 21ce715..b38843b 100644
--- a/voltha/adapters/adtran_olt/adtran_olt.py
+++ b/voltha/adapters/adtran_olt/adtran_olt.py
@@ -52,7 +52,7 @@
self.descriptor = Adapter(
id=self.name,
vendor='ADTRAN, Inc.',
- version='1.35',
+ version='1.36',
config=AdapterConfig(log_level=LogLevel.INFO)
)
log.debug('adtran_olt.__init__', adapter_agent=adapter_agent)
diff --git a/voltha/adapters/adtran_olt/adtran_olt_handler.py b/voltha/adapters/adtran_olt/adtran_olt_handler.py
index f1228a8..8a88ea1 100644
--- a/voltha/adapters/adtran_olt/adtran_olt_handler.py
+++ b/voltha/adapters/adtran_olt/adtran_olt_handler.py
@@ -672,17 +672,6 @@
super(AdtranOltHandler, self).delete()
- def delete_child_device(self, proxy_address):
- super(AdtranOltHandler, self).delete_child_device(proxy_address)
-
- # TODO: Verify that ONU object cleanup of ONU will also clean
- # up logical id and physical port
- # pon_intf_id_onu_id = (proxy_address.channel_id,
- # proxy_address.onu_id)
-
- # Free any PON resources that were reserved for the ONU
- # TODO: Done in onu delete now -> self.resource_mgr.free_pon_resources_for_onu(pon_intf_id_onu_id)
-
def rx_pa_packet(self, packets):
if self._pon_agent is not None:
for packet in packets:
@@ -1296,8 +1285,10 @@
try:
from voltha.protos.voltha_pb2 import Device
# NOTE - channel_id of onu is set to pon_id
+ pon_port = self.pon_id_to_port_number(pon_id)
proxy_address = Device.ProxyAddress(device_id=self.device_id,
- channel_id=pon_id, onu_id=onu_id,
+ channel_id=pon_port,
+ onu_id=onu_id,
onu_session_id=onu_id)
self.log.debug("added-onu", port_no=pon_id,
@@ -1306,7 +1297,7 @@
self.adapter_agent.add_onu_device(
parent_device_id=self.device_id,
- parent_port_no=pon_id,
+ parent_port_no=pon_port,
vendor_id=serial_number[:4],
proxy_address=proxy_address,
root=True,
diff --git a/voltha/adapters/adtran_olt/flow/evc_map.py b/voltha/adapters/adtran_olt/flow/evc_map.py
index ee19df9..5f0b227 100644
--- a/voltha/adapters/adtran_olt/flow/evc_map.py
+++ b/voltha/adapters/adtran_olt/flow/evc_map.py
@@ -821,9 +821,9 @@
for pb_tcont in pb_tconts:
from ..xpon.olt_tcont import OltTCont
tcont = OltTCont.create(pb_tcont,
- self._tech_profile_id,
self.pon_id,
self.onu_id,
+ self._tech_profile_id,
uni_id,
ofp_port_no)
if tcont is not None:
@@ -846,8 +846,6 @@
ofp_port_no)
if gem_port is not None:
onu.add_gem_port(gem_port)
- #
- #
self._gem_ids_and_vid = {onu.onu_id: (onu_gems, flow.vlan_id)}
diff --git a/voltha/adapters/adtran_olt/onu.py b/voltha/adapters/adtran_olt/onu.py
index a1c3314..91f87a6 100644
--- a/voltha/adapters/adtran_olt/onu.py
+++ b/voltha/adapters/adtran_olt/onu.py
@@ -19,6 +19,7 @@
from twisted.internet import reactor, defer
from twisted.internet.defer import inlineCallbacks, returnValue, succeed
from common.tech_profile.tech_profile import DEFAULT_TECH_PROFILE_TABLE_ID
+from voltha.protos.device_pb2 import Device
from adtran_olt_handler import AdtranOltHandler
from net.adtran_rest import RestInvalidResponseCode
@@ -50,9 +51,11 @@
self._serial_number_string = onu_info['serial-number']
self._device_id = onu_info['device-id']
self._password = onu_info['password']
-
self._created = False
- self._proxy_address = None
+ self._proxy_address = Device.ProxyAddress(device_id=self.olt.device_id,
+ channel_id=self.olt.pon_id_to_port_number(self._pon_id),
+ onu_id=self._onu_id,
+ onu_session_id=self._onu_id)
self._sync_tick = _HW_SYNC_SECS
self._expedite_sync = False
self._expedite_count = 0
@@ -66,8 +69,6 @@
# Provisionable items
self._enabled = onu_info['enabled']
self._upstream_fec_enable = onu_info.get('upstream-fec')
- self._upstream_channel_speed = onu_info['upstream-channel-speed']
- # TODO: how do we want to enforce upstream channel speed (if at all)?
# KPI related items
self._rssi = -9999
@@ -134,16 +135,6 @@
self.pon.upstream_fec_enable = self.pon.any_upstream_fec_enabled
@property
- def upstream_channel_speed(self):
- return self._upstream_channel_speed
-
- @upstream_channel_speed.setter
- def upstream_channel_speed(self, value):
- assert isinstance(value, (int, float)), 'upstream speed is a numeric value'
- if self._upstream_channel_speed != value:
- self._upstream_channel_speed = value
-
- @property
def password(self):
"""
Get password. Base 64 format
@@ -206,14 +197,6 @@
@property
def proxy_address(self):
- if self._proxy_address is None:
- from voltha.protos.device_pb2 import Device
-
- device_id = self.olt.device_id
- self._proxy_address = Device.ProxyAddress(device_id=device_id,
- channel_id=self.pon.port_no,
- onu_id=self.onu_id,
- onu_session_id=self.onu_id)
return self._proxy_address
@property
@@ -311,7 +294,7 @@
if len(results) == 1 and results[0].get('serial-number', '') != self._serial_number_base64:
self._created = True
- except Exception as e:
+ except Exception as _e:
self.log.warn('onu-exists-check', pon_id=self.pon_id, onu_id=self.onu_id,
serial_number=self.serial_number)
@@ -354,13 +337,13 @@
self._gem_ports.clear()
self._tconts.clear()
+ olt, self._olt = self._olt, None
uri = AdtranOltHandler.GPON_ONU_CONFIG_URI.format(self._pon_id, self._onu_id)
name = 'onu-delete-{}-{}-{}: {}'.format(self._pon_id, self._onu_id,
self._serial_number_base64, self._enabled)
try:
- yield self.olt.rest_client.request('DELETE', uri, name=name)
- self._olt = None
+ yield olt.rest_client.request('DELETE', uri, name=name)
except RestInvalidResponseCode as e:
if e.code != 404:
@@ -371,7 +354,7 @@
# Release resource manager resources for this ONU
pon_intf_id_onu_id = (self.pon_id, self.onu_id)
- self._olt.resource_mgr.free_pon_resources_for_onu(pon_intf_id_onu_id)
+ olt.resource_mgr.free_pon_resources_for_onu(pon_intf_id_onu_id)
returnValue('deleted')
@@ -679,12 +662,6 @@
if not reflow and gem_port.gem_id in self._gem_ports:
returnValue('nop')
- gem_port.pon_id = self.pon_id
- gem_port.onu_id = self.onu_id if self.onu_id is not None else -1
- gem_port.intf_id = self.intf_id
-
- # TODO: Currently only support a single UNI. Need to support multiple and track their GEM Ports
- # Probably best done by having a UNI-Port class (keep it simple)
self.log.info('add', gem_port=gem_port, reflow=reflow)
self._gem_ports[gem_port.gem_id] = gem_port
diff --git a/voltha/adapters/adtran_olt/pon_port.py b/voltha/adapters/adtran_olt/pon_port.py
index c9e18c8..bf7541b 100644
--- a/voltha/adapters/adtran_olt/pon_port.py
+++ b/voltha/adapters/adtran_olt/pon_port.py
@@ -576,7 +576,7 @@
# be handle by ONU H/w sync logic.
for onu in [self._onu_by_id[onu_id] for onu_id in my_onu_ids - hw_onu_ids
if self._onu_by_id.get(onu_id) is not None]:
- dl.append(onu.create(dict(), dict(), reflow=True))
+ dl.append(onu.create(reflow=True))
return defer.gatherResults(dl, consumeErrors=True)
@@ -729,7 +729,6 @@
elif self.activation_method == "autoactivate":
onu_id = self.get_next_onu_id
enabled = True
- channel_speed = 10000000000
upstream_fec_enabled = True
else:
@@ -742,7 +741,6 @@
'pon': self,
'onu-id': onu_id,
'enabled': enabled,
- 'upstream-channel-speed': channel_speed,
'upstream-fec': upstream_fec_enabled,
'password': Onu.DEFAULT_PASSWORD,
}
@@ -797,13 +795,13 @@
reactor.callLater(0, alarm.raise_alarm)
# Have the core create the ONU device
- self._parent.add_onu_device(self._port_no, onu_id, serial_number)
-
- onu = Onu(onu_info)
- self._onus[serial_number_64] = onu
- self._onu_by_id[onu.onu_id] = onu
+ self._parent.add_onu_device(self.pon_id, onu_id, serial_number)
try:
+ onu = Onu(onu_info)
+ self._onus[serial_number_64] = onu
+ self._onu_by_id[onu.onu_id] = onu
+
# Add Multicast to PON on a per-ONU basis
#
# for id_or_vid, gem_port in gem_ports.iteritems():
@@ -853,10 +851,9 @@
if onu_id in self._onu_by_id:
del self._onu_by_id[onu_id]
- for sn_64 in [onu.serial_number_64 for onu in self.onus if onu.onu_id == onu_id]:
- del self._onus[sn_64]
-
if onu is not None:
+ if onu.serial_number_64 in self._onus:
+ del self._onus[onu.serial_number_64]
try:
proxy_address = onu.proxy_address
onu.delete() # Remove from hardware
@@ -867,7 +864,6 @@
except Exception as e:
self.log.exception('onu-delete', serial_number=onu.serial_number, e=e)
-
else:
try:
yield self._remove_from_hardware(onu_id)
@@ -875,7 +871,7 @@
except Exception as e:
self.log.debug('onu-remove', serial_number=onu.serial_number, e=e)
- # Remove from LOS list if needed
+ # Remove from LOS list if needed TODO: Should a 'clear' alarm be sent as well ?
if onu is not None and onu.id in self._active_los_alarms:
self._active_los_alarms.remove(onu.id)
diff --git a/voltha/adapters/adtran_olt/resources/adtran_resource_manager.py b/voltha/adapters/adtran_olt/resources/adtran_resource_manager.py
index db56616..14efbf7 100644
--- a/voltha/adapters/adtran_olt/resources/adtran_resource_manager.py
+++ b/voltha/adapters/adtran_olt/resources/adtran_resource_manager.py
@@ -23,7 +23,6 @@
from bitstring import BitArray
import json
from common.pon_resource_manager.resource_manager import PONResourceManager
-from adtran_tech_profile import AdtnTechProfile
import adtranolt_platform as platform
diff --git a/voltha/adapters/adtran_olt/xpon/gem_port.py b/voltha/adapters/adtran_olt/xpon/gem_port.py
index d14b4f2..14dccb1 100644
--- a/voltha/adapters/adtran_olt/xpon/gem_port.py
+++ b/voltha/adapters/adtran_olt/xpon/gem_port.py
@@ -17,33 +17,22 @@
"""
Class to wrap TCont capabilities
"""
- def __init__(self, gem_id, alloc_id, tech_profile_id,
+ def __init__(self, gem_id, alloc_id, uni_id, tech_profile_id,
encryption=False,
- omci_transport=False,
multicast=False,
- tcont_ref=None,
traffic_class=None,
handler=None,
is_mock=False):
self.gem_id = gem_id
self._alloc_id = alloc_id
+ self.uni_id = uni_id
self.tech_profile_id = tech_profile_id
- self.tcont_ref = tcont_ref
self.traffic_class = traffic_class
self._encryption = encryption
- self._omci_transport = omci_transport
self.multicast = multicast
self._handler = handler
self._is_mock = is_mock
-
- # TODO: Make this a base class and derive OLT and ONU specific classes from it
- # The primary thing to change is the PON ID is OLT specific and the add/remove
- # from hardware methods
- self._pon_id = None
- self._onu_id = None
- self._intf_id = None
-
self.tech_profile_id = None # TODO: Make property and clean up object once tech profiles fully supported
# Statistics
@@ -53,63 +42,22 @@
self.tx_bytes = 0
def __str__(self):
- return "GemPort: alloc-id: {}, gem-id: {}".format(self.alloc_id,self.gem_id)
-
- @property
- def pon_id(self):
- return self._pon_id
-
- @pon_id.setter
- def pon_id(self, pon_id):
- assert self._pon_id is None or self._pon_id == pon_id, 'PON-ID can only be set once'
- self._pon_id = pon_id
-
- @property
- def onu_id(self):
- return self._onu_id
-
- @onu_id.setter
- def onu_id(self, onu_id):
- assert self._onu_id is None or self._onu_id == onu_id, 'ONU-ID can only be set once'
- self._onu_id = onu_id
-
- @property
- def intf_id(self):
- return self._intf_id
-
- @intf_id.setter
- def intf_id(self, intf_id):
- assert self._intf_id is None or self._intf_id == intf_id, 'Port Number can only be set once'
- self._intf_id = intf_id
+ return "GemPort: alloc-id: {}, gem-id: {}, uni-id: {}".format(self.alloc_id,
+ self.gem_id,
+ self.uni_id)
@property
def alloc_id(self):
- if self._alloc_id is None and self._handler is not None:
- try:
- self._alloc_id = self._handler.tconts.get(self.tcont_ref).get('alloc-id')
-
- except Exception:
- pass
-
return self._alloc_id
@property
- def tcont(self):
- tcont_item = self._handler.tconts.get(self.tcont_ref)
- return tcont_item.get('object') if tcont_item is not None else None
-
- @property
def encryption(self):
return self._encryption
- @property
- def omci_transport(self):
- return self._omci_transport
-
def to_dict(self):
return {
'port-id': self.gem_id,
'alloc-id': self.alloc_id,
'encryption': self._encryption,
- 'omci-transport': self.omci_transport
+ 'omci-transport': False
}
diff --git a/voltha/adapters/adtran_olt/xpon/olt_gem_port.py b/voltha/adapters/adtran_olt/xpon/olt_gem_port.py
index 3d2210d..272fb07 100644
--- a/voltha/adapters/adtran_olt/xpon/olt_gem_port.py
+++ b/voltha/adapters/adtran_olt/xpon/olt_gem_port.py
@@ -27,41 +27,46 @@
"""
Adtran OLT specific implementation
"""
- def __init__(self, gem_id, alloc_id, tech_profile_id, pon_id, onu_id,
+ def __init__(self, gem_id, alloc_id, tech_profile_id, pon_id, onu_id, uni_id,
encryption=False,
- omci_transport=False,
multicast=False,
- tcont_ref=None,
traffic_class=None,
handler=None,
is_mock=False):
- super(OltGemPort, self).__init__(gem_id, alloc_id, tech_profile_id,
+ super(OltGemPort, self).__init__(gem_id, alloc_id, uni_id, tech_profile_id,
encryption=encryption,
- omci_transport=omci_transport,
multicast=multicast,
- tcont_ref=tcont_ref,
traffic_class=traffic_class,
handler=handler,
is_mock=is_mock)
self._timestamp = None
- self.pon_id = pon_id
- self.onu_id = onu_id
+ self._pon_id = pon_id
+ self._onu_id = onu_id # None if this is a multicast GEM Port
def __str__(self):
- return "GemPort: {}/{}, alloc-id: {}, gem-id: {}".format(self.pon_id, self.onu_id,
- self.alloc_id, self.gem_id)
+ return "GemPort: {}/{}/{}, alloc-id: {}, gem-id: {}".format(self.pon_id, self.onu_id,
+ self.uni_id, self.alloc_id,
+ self.gem_id)
@staticmethod
- def create(handler, gem, alloc_id, tech_profile_id, pon_id, onu_id, _uni_id, _ofp_port_no):
+ def create(handler, gem, alloc_id, tech_profile_id, pon_id, onu_id, uni_id, _ofp_port_no):
return OltGemPort(gem.gemport_id,
alloc_id,
tech_profile_id,
- pon_id, onu_id,
+ pon_id, onu_id, uni_id,
encryption=gem.aes_encryption.lower() == 'true',
handler=handler,
multicast=False)
@property
+ def pon_id(self):
+ return self._pon_id
+
+ @property
+ def onu_id(self):
+ return self._onu_id
+
+ @property
def timestamp(self):
return self._timestamp
diff --git a/voltha/adapters/adtran_olt/xpon/olt_tcont.py b/voltha/adapters/adtran_olt/xpon/olt_tcont.py
index d678bc3..10fed00 100644
--- a/voltha/adapters/adtran_olt/xpon/olt_tcont.py
+++ b/voltha/adapters/adtran_olt/xpon/olt_tcont.py
@@ -27,13 +27,14 @@
"""
Adtran OLT specific implementation
"""
- def __init__(self, alloc_id, tech_profile_id, traffic_descriptor, pon_id, onu_id, is_mock=False):
- super(OltTCont, self).__init__(alloc_id, tech_profile_id, traffic_descriptor, is_mock=is_mock)
+ def __init__(self, alloc_id, tech_profile_id, traffic_descriptor, pon_id, onu_id, uni_id, is_mock=False):
+ super(OltTCont, self).__init__(alloc_id, tech_profile_id, traffic_descriptor, uni_id, is_mock=is_mock)
self.pon_id = pon_id
self.onu_id = onu_id
def __str__(self):
- return "TCont: {}/{}, alloc-id: {}".format(self.pon_id, self.onu_id, self.alloc_id)
+ return "TCont: {}/{}/{}, alloc-id: {}".format(self.pon_id, self.onu_id,
+ self.uni_id, self.alloc_id)
@staticmethod
def create(tcont, pon_id, onu_id, tech_profile_id, uni_id, ofp_port_no):
@@ -42,7 +43,7 @@
return None
td = OltTrafficDescriptor.create(tcont, pon_id, onu_id, uni_id, ofp_port_no)
- return OltTCont(tcont.alloc_id, tech_profile_id, td, pon_id, onu_id)
+ return OltTCont(tcont.alloc_id, tech_profile_id, td, pon_id, onu_id, uni_id)
@inlineCallbacks
def add_to_hardware(self, session):
diff --git a/voltha/adapters/adtran_olt/xpon/tcont.py b/voltha/adapters/adtran_olt/xpon/tcont.py
index b5e8eee..79d94fa 100644
--- a/voltha/adapters/adtran_olt/xpon/tcont.py
+++ b/voltha/adapters/adtran_olt/xpon/tcont.py
@@ -17,14 +17,13 @@
"""
Class to wrap TCont capabilities
"""
- def __init__(self, alloc_id, tech_profile_id, traffic_descriptor, is_mock=False):
+ def __init__(self, alloc_id, tech_profile_id, traffic_descriptor, uni_id, is_mock=False):
self.alloc_id = alloc_id
self.traffic_descriptor = traffic_descriptor
self._is_mock = is_mock
self.tech_profile_id = tech_profile_id
-
- # TODO: Make this a base class and derive OLT and ONU specific classes from it
- # The primary thing difference is the add/remove from hardware methods
+ self.uni_id = uni_id
def __str__(self):
- return "TCont: alloc-id: {}".format(self.alloc_id)
+ return "TCont: alloc-id: {}, uni-id: {}".format(self.alloc_id,
+ self.uni_id)