VOL-764: OpenOLT - multiple ONUs per PON
Change-Id: I3f6e3fa3cd0377f38f2475132881ac58b79d991f
diff --git a/voltha/adapters/openolt/openolt_device.py b/voltha/adapters/openolt/openolt_device.py
index 6b5c93e..c8d24f6 100644
--- a/voltha/adapters/openolt/openolt_device.py
+++ b/voltha/adapters/openolt/openolt_device.py
@@ -46,7 +46,8 @@
# FIXME - see also BRDCM_DEFAULT_VLAN in broadcom_onu.py
DEFAULT_MGMT_VLAN = 4091
-Onu = collections.namedtuple("Onu", ["intf_id", "onu_id"])
+OnuKey = collections.namedtuple('OnuKey', ['intf_id', 'onu_id'])
+OnuRec = collections.namedtuple('OnuRec', ['serial_number', 'state'])
"""
Encoding of identifiers
@@ -138,7 +139,7 @@
self.log = structlog.get_logger(id=self.device_id, ip=self.host_and_port)
self.oper_state = 'unknown'
self.nni_oper_state = dict() #intf_id -> oper_state
- self.onus = {} # Onu -> serial_number
+ self.onus = {} # OnuKey -> OnuRec
# Create logical device
ld = LogicalDevice(
@@ -245,29 +246,38 @@
pass
def onu_discovery_indication(self, onu_disc_indication):
- self.log.debug("onu discovery indication", intf_id=onu_disc_indication.intf_id,
- serial_number=onu_disc_indication.serial_number)
+ intf_id = onu_disc_indication.intf_id
+ serial_number=onu_disc_indication.serial_number
- onu_id = self.lookup_onu(serial_number=onu_disc_indication.serial_number)
+ self.log.debug("onu discovery indication", intf_id=intf_id,
+ serial_number=serial_number)
- if onu_id is None:
- onu_id = self.new_onu_id(onu_disc_indication.intf_id)
+ key = self.lookup_key(serial_number=serial_number)
+
+ if key is None:
+ onu_id = self.new_onu_id(intf_id)
try:
- self.add_onu_device(
- onu_disc_indication.intf_id,
- self.intf_id_to_port_no(onu_disc_indication.intf_id, Port.PON_OLT),
- onu_id,
- onu_disc_indication.serial_number)
+ self.add_onu_device(intf_id,
+ self.intf_id_to_port_no(intf_id, Port.PON_OLT),
+ onu_id, serial_number)
except Exception as e:
self.log.exception('onu activation failed', e=e)
else:
- self.activate_onu(
- onu_disc_indication.intf_id, onu_id,
- serial_number=onu_disc_indication.serial_number)
+ self.log.info("activate onu", intf_id=intf_id, onu_id=onu_id,
+ serial_number=serial_number)
+ self.onus[OnuKey(intf_id=intf_id, onu_id=onu_id)] \
+ = OnuRec(serial_number=serial_number, state='discovered')
+ onu = openolt_pb2.Onu(intf_id=intf_id, onu_id=onu_id,
+ serial_number=serial_number)
+ self.stub.ActivateOnu(onu)
else:
- # FIXME - handle discovery of already activated onu
- self.log.info("onu activation in progress",
- intf_id=onu_disc_indication.intf_id, onu_id=onu_id)
+ # FIXME - handle onu discover indication for a discovered/activated onu
+ onu_id = key.onu_id
+ intf_id = key.intf_id
+ if self.onus[key].state == 'discovered' or \
+ self.onus[key].state == 'active':
+ self.log.info("ignore onu discovery indication", intf_id=intf_id,
+ onu_id=onu_id, state=self.onus[key].state)
def mk_uni_port_num(self, intf_id, onu_id):
return intf_id << 11 | onu_id << 4
@@ -282,8 +292,23 @@
self.log.debug("onu indication", intf_id=onu_indication.intf_id,
onu_id=onu_indication.onu_id)
- # FIXME - handle onu_id/serial_number mismatch
- assert onu_indication.onu_id == self.lookup_onu(serial_number=onu_indication.serial_number)
+ key = self.lookup_key(serial_number=onu_indication.serial_number)
+
+ # FIXME - handle serial_number mismatch
+ assert key is not None
+
+ # FIXME - handle intf_id mismatch (ONU move?)
+ assert onu_indication.intf_id == key.intf_id
+
+ # FIXME - handle onu id mismatch
+ assert onu_indication.onu_id == key.onu_id
+
+ if self.onus[key].state is not 'discovered':
+ self.log.debug("ignore onu indication", intf_id=onu_indication.intf_id,
+ onu_id=onu_indication.onu_id, state=self.onus[key].state)
+ return
+
+ self.onus[key] = self.onus[key]._replace(state='active')
onu_device = self.adapter_agent.get_child_device(
self.device_id, onu_id=onu_indication.onu_id)
@@ -399,17 +424,6 @@
self.stub.OnuPacketOut(onu_packet)
- def activate_onu(self, intf_id, onu_id, serial_number):
- self.log.info("activate onu", intf_id=intf_id, onu_id=onu_id,
- serial_number=serial_number)
-
- self.onus[Onu(intf_id=intf_id, onu_id=onu_id)] = serial_number
-
- onu = openolt_pb2.Onu(intf_id=intf_id, onu_id=onu_id,
- serial_number=serial_number)
-
- self.stub.ActivateOnu(onu)
-
def send_proxied_message(self, proxy_address, msg):
omci = openolt_pb2.OmciMsg(intf_id=proxy_address.channel_id, # intf_id
onu_id=proxy_address.onu_id, pkt=str(msg))
@@ -521,8 +535,8 @@
# onu_id is unique per PON.
# FIXME - Remove hardcoded limit on ONUs per PON (64)
for i in range(1, 64):
- onu = Onu(intf_id=intf_id, onu_id=i)
- if onu not in self.onus:
+ key = OnuKey(intf_id=intf_id, onu_id=i)
+ if key not in self.onus:
onu_id = i
break
return onu_id
@@ -538,16 +552,16 @@
ord(vendor_specific[3])>>4 & 0x0f,
ord(vendor_specific[3]) & 0x0f])
- def lookup_onu(self, serial_number):
- onu_id = None
- for onu, s in self.onus.iteritems():
- if s.vendor_id == serial_number.vendor_id:
- str1 = self.stringify_vendor_specific(s.vendor_specific)
+ def lookup_key(self, serial_number):
+ key = None
+ for k, r in self.onus.iteritems():
+ if r.serial_number.vendor_id == serial_number.vendor_id:
+ str1 = self.stringify_vendor_specific(r.serial_number.vendor_specific)
str2 = self.stringify_vendor_specific(serial_number.vendor_specific)
if str1 == str2:
- onu_id = onu.onu_id
+ key = k
break
- return onu_id
+ return key
def update_flow_table(self, flows):
device = self.adapter_agent.get_device(self.device_id)