def setUp(self): #calling the parent class setUp test_logical_device_agent.setUp(self) #re-initializing ports to VENET topology self.ports = { 'olt': [ Port(port_no=0, type=Port.ETHERNET_NNI, device_id='olt'), Port(port_no=1, type=Port.VENET_OLT, device_id='olt', peers=[ Port.PeerPort(device_id='onu1', port_no=1), Port.PeerPort(device_id='onu2', port_no=1) ] ) ], 'onu1': [ Port(port_no=0, type=Port.ETHERNET_UNI, device_id='onu1'), Port(port_no=1, type=Port.VENET_ONU, device_id='onu1', peers=[ Port.PeerPort(device_id='olt', port_no=1), ] ) ], 'onu2': [ Port(port_no=0, type=Port.ETHERNET_UNI, device_id='onu2'), Port(port_no=1, type=Port.VENET_ONU, device_id='onu2', peers=[ Port.PeerPort(device_id='olt', port_no=1), ] ) ], } #resetting root_proxy for VENET topology self.root_proxy = Mock() def get_devices(path): if path == '': return self.devices.values() if path.endswith('/ports'): return self.ports[path[:-len('/ports')]] elif path.find('/') == -1: return self.devices[path] else: raise Exception( 'Nothing to yield for path /devices/{}'.format(path)) def update_devices(path, data): if path.endswith('/flows'): self.device_flows[path[:-len('/flows')]] = data elif path.endswith('/flow_groups'): self.device_groups[path[:-len('/flow_groups')]] = data else: raise NotImplementedError( 'not handling path /devices/{}'.format(path)) self.root_proxy.get = lambda p: \ get_devices(p[len('/devices/'):]) if p.startswith('/devices') \ else None self.root_proxy.update = lambda p, d: \ update_devices(p[len('/devices/'):], d) \ if p.startswith('/devices') \ else None
def _del_peer_reference(self, device_id, port): me_as_peer = Port.PeerPort(device_id=device_id, port_no=port.port_no) for peer in port.peers: peer_port_path = '/devices/{}/ports/{}'.format( peer.device_id, peer.port_no) peer_port = self.root_proxy.get(peer_port_path) if me_as_peer in peer_port.peers: peer_port.peers.remove(me_as_peer) self.root_proxy.update(peer_port_path, peer_port)
def _add_uni_port(self, entity_id): self.log.debug('function-entry') device = self.adapter_agent.get_device(self.device_id) parent_device = self.adapter_agent.get_device(device.parent_id) parent_adapter_agent = registry('adapter_loader').get_agent( parent_device.adapter) if parent_adapter_agent is None: 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) # TODO: Some or parts of this likely need to move to UniPort. especially the format stuff working_port = self._next_port_number uni_no = uni_no_start + working_port uni_name = "uni-{}".format(uni_no) mac_bridge_port_num = working_port + 1 self.log.debug('live-port-number-ready', uni_no=uni_no, uni_name=uni_name) uni_port = UniPort.create(self, uni_name, uni_no, uni_name, device.vlan, device.vlan) uni_port.entity_id = entity_id uni_port.enabled = True uni_port.mac_bridge_port_num = mac_bridge_port_num uni_port.add_logical_port(uni_port.port_number, subscriber_vlan=device.vlan) self.log.debug("created-uni-port", uni=uni_port) self.adapter_agent.add_port(device.id, uni_port.get_port()) parent_adapter_agent.add_port(device.parent_id, uni_port.get_port()) self._unis[uni_port.port_number] = uni_port # TODO: this should be in the PonPortclass pon_port = self._pon.get_port() self.adapter_agent.delete_port_reference_from_parent( self.device_id, pon_port) pon_port.peers.extend([ Port.PeerPort(device_id=device.parent_id, port_no=uni_port.port_number) ]) self._pon._port = pon_port self.adapter_agent.add_port_reference_to_parent( self.device_id, pon_port) self.adapter_agent.update_device(device)
def _add_peer_reference(self, device_id, port): # for referential integrity, add/augment references port.device_id = device_id me_as_peer = Port.PeerPort(device_id=device_id, port_no=port.port_no) for peer in port.peers: peer_port_path = '/devices/{}/ports/{}'.format( peer.device_id, peer.port_no) peer_port = self.root_proxy.get(peer_port_path) if me_as_peer not in peer_port.peers: new = peer_port.peers.add() new.CopyFrom(me_as_peer) self.root_proxy.update(peer_port_path, peer_port)
def _del_peer_reference(self, device_id, port): me_as_peer = Port.PeerPort(device_id=device_id, port_no=port.port_no) for peer in port.peers: try: peer_port_path = '/devices/{}/ports/{}'.format( peer.device_id, peer.port_no) peer_port = self.root_proxy.get(peer_port_path) if me_as_peer in peer_port.peers: peer_port.peers.remove(me_as_peer) self.root_proxy.update(peer_port_path, peer_port) except Exception: # if the device on the other side was already remove # the key cannot be found under /devices/<device_id> pass
def get_port(self): """ Get the VOLTHA PORT object for this port :return: VOLTHA Port object """ if self._port is None: device = self._handler.adapter_agent.get_device(self._handler.device_id) self._port = Port(port_no=self.port_number, label='PON port', type=Port.PON_ONU, admin_state=self._admin_state, oper_status=self._oper_status, peers=[Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no)]) return self._port
def add_port(self, device_id, port): assert isinstance(port, Port) # for referential integrity, add/augment references port.device_id = device_id me_as_peer = Port.PeerPort(device_id=device_id, port_no=port.port_no) for peer in port.peers: peer_port_path = '/devices/{}/ports/{}'.format( peer.device_id, peer.port_no) peer_port = self.root_proxy.get(peer_port_path) if me_as_peer not in peer_port.peers: new = peer_port.peers.add() new.CopyFrom(me_as_peer) self.root_proxy.update(peer_port_path, peer_port) self._make_up_to_date('/devices/{}/ports'.format(device_id), port.port_no, port)
def setUp(self): self.setup_mock_registry() self.flows = Flows(items=[]) self.groups = FlowGroups(items=[]) self.ld_ports = [ LogicalPort(id='0', device_id='olt', device_port_no=0, root_port=True, ofp_port=ofp.ofp_port(port_no=0)), LogicalPort(id='1', device_id='onu1', device_port_no=0, ofp_port=ofp.ofp_port(port_no=1)), LogicalPort(id='2', device_id='onu2', device_port_no=0, ofp_port=ofp.ofp_port(port_no=2)) ] self.devices = { 'olt': Device(id='olt', root=True, parent_id='id'), 'onu1': Device(id='onu1', parent_id='olt', parent_port_no=1, vlan=101), 'onu2': Device(id='onu2', parent_id='olt', parent_port_no=1, vlan=102), } self.ports = { 'olt': [ Port(port_no=0, type=Port.ETHERNET_NNI, device_id='olt'), Port(port_no=1, type=Port.PON_OLT, device_id='olt', peers=[ Port.PeerPort(device_id='onu1', port_no=1), Port.PeerPort(device_id='onu2', port_no=1) ]) ], 'onu1': [ Port(port_no=0, type=Port.ETHERNET_UNI, device_id='onu1'), Port(port_no=1, type=Port.PON_ONU, device_id='onu1', peers=[ Port.PeerPort(device_id='olt', port_no=1), ]) ], 'onu2': [ Port(port_no=0, type=Port.ETHERNET_UNI, device_id='onu2'), Port(port_no=1, type=Port.PON_ONU, device_id='onu2', peers=[ Port.PeerPort(device_id='olt', port_no=1), ]) ], } self.device_flows = {'olt': Flows(), 'onu1': Flows(), 'onu2': Flows()} self.device_groups = { 'olt': FlowGroups(), 'onu1': FlowGroups(), 'onu2': FlowGroups() } self.ld = LogicalDevice(id='id', root_device_id='olt') self.root_proxy = Mock() def get_devices(path): if path == '': return self.devices.values() if path.endswith('/ports'): return self.ports[path[:-len('/ports')]] elif path.find('/') == -1: return self.devices[path] else: raise Exception( 'Nothing to yield for path /devices/{}'.format(path)) def update_devices(path, data): if path.endswith('/flows'): self.device_flows[path[:-len('/flows')]] = data elif path.endswith('/flow_groups'): self.device_groups[path[:-len('/flow_groups')]] = data else: raise NotImplementedError( 'not handling path /devices/{}'.format(path)) self.root_proxy.get = lambda p: \ get_devices(p[len('/devices/'):]) if p.startswith('/devices') \ else None self.root_proxy.update = lambda p, d: \ update_devices(p[len('/devices/'):], d) \ if p.startswith('/devices') \ else None self.ld_proxy = Mock() self.ld_proxy.get = lambda p: \ self.ld_ports if p == '/ports' else ( self.ld if p == '/' else None ) self.flows_proxy = Mock() self.flows_proxy.get = lambda _: self.flows # always '/' path def update_flows(_, flows): # always '/' path self.flows = flows self.flows_proxy.update = update_flows self.groups_proxy = Mock() self.groups_proxy.get = lambda _: self.groups # always '/' path def update_groups(_, groups): # always '/' path self.groups = groups self.groups_proxy.update = update_groups self.core = Mock() self.core.get_proxy = lambda path: \ self.root_proxy if path == '/' else ( self.ld_proxy if path.endswith('id') else ( self.flows_proxy if path.endswith('flows') else self.groups_proxy ) ) self.lda = LogicalDeviceAgent(self.core, self.ld)
def activate(self, device): self.log.info('activating') # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # register for proxied messages right away self.proxy_address = device.proxy_address self.adapter_agent.register_for_proxied_messages(device.proxy_address) # populate device info device.root = True device.vendor = 'Broadcom' device.model = 'n/a' device.hardware_version = 'to be filled' device.firmware_version = 'to be filled' device.software_version = 'to be filled' device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # register physical ports uni_port = Port(port_no=2, label='UNI facing Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) self.adapter_agent.add_port( device.id, Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ])) # add uni port to logical device parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id port_no = device.proxy_address.channel_id cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id='uni-{}'.format(port_no), ofp_port=ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:%02x:%02x' % ((port_no >> 8) & 0xff, port_no & 0xff)), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=uni_port.port_no)) reactor.callLater(10, self.message_exchange) device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)
def _onu_device_activation(self, device): # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # TODO: For now, pretend that we were able to contact the device and obtain # additional information about it. Should add real message. device.vendor = 'Tibit Communications, Inc.' device.model = '10G GPON ONU' device.hardware_version = 'fa161020' device.firmware_version = '16.12.02' device.software_version = '1.0' device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # then shortly after we create some ports for the device uni_port = Port(port_no=2, label='UNI facing Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) self.adapter_agent.add_port( device.id, Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ])) # TODO adding vports to the logical device shall be done by agent? # then we create the logical device port that corresponds to the UNI # port of the device # obtain logical device id parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id # we are going to use the proxy_address.channel_id as unique number # and name for the virtual ports, as this is guaranteed to be unique # in the context of the OLT port, so it is also unique in the context # of the logical device port_no = device.proxy_address.channel_id cap = OFPPF_10GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id=str(port_no), ofp_port=ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple( device.mac_address), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_10GB_FD, max_speed=OFPPF_10GB_FD), device_id=device.id, device_port_no=uni_port.port_no)) # simulate a proxied message sending and receving a reply reply = yield self._message_exchange(device) # and finally update to "ACTIVE" device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) self.start_kpi_collection(device.id)
def _tmp_populate_stuff(self): """ pretend that we discovered some devices and create: - devices - device ports for each - logical device - logical device ports """ olt = Device(id='simulated_olt_1', type='simulated_olt', root=True, vendor='simulated', model='n/a', hardware_version='n/a', firmware_version='n/a', software_version='1.0', serial_number=uuid4().hex, adapter=self.name, oper_status=OperStatus.DISCOVERED) self.adapter_agent.add_device(olt) self.adapter_agent.add_port( olt.id, Port(port_no=1, label='pon', type=Port.PON_OLT)) self.adapter_agent.add_port( olt.id, Port(port_no=2, label='eth', type=Port.ETHERNET_NNI)) onu1 = Device(id='simulated_onu_1', type='simulated_onu', root=False, parent_id=olt.id, parent_port_no=1, vendor='simulated', model='n/a', hardware_version='n/a', firmware_version='n/a', software_version='1.0', serial_number=uuid4().hex, adapter='simulated_onu', oper_status=OperStatus.DISCOVERED, vlan=101) self.adapter_agent.add_device(onu1) self.adapter_agent.add_port( onu1.id, Port(port_no=2, label='eth', type=Port.ETHERNET_UNI)) self.adapter_agent.add_port( onu1.id, Port(port_no=1, label='pon', type=Port.PON_ONU, peers=[Port.PeerPort(device_id=olt.id, port_no=1)])) onu2 = Device(id='simulated_onu_2', type='simulated_onu', root=False, parent_id=olt.id, parent_port_no=1, vendor='simulated', model='n/a', hardware_version='n/a', firmware_version='n/a', software_version='1.0', serial_number=uuid4().hex, adapter='simulated_onu', oper_status=OperStatus.DISCOVERED, vlan=102) self.adapter_agent.add_device(onu2) self.adapter_agent.add_port( onu2.id, Port(port_no=2, label='eth', type=Port.ETHERNET_UNI)) self.adapter_agent.add_port( onu2.id, Port(port_no=1, label='pon', type=Port.PON_ONU, peers=[Port.PeerPort(device_id=olt.id, port_no=1)])) ld = LogicalDevice( id='simulated1', datapath_id=1, desc=ofp_desc(mfr_desc='cord project', hw_desc='simualted pon', sw_desc='simualted pon', serial_num=uuid4().hex, dp_desc='n/a'), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS)), root_device_id=olt.id) self.adapter_agent.create_logical_device(ld) cap = OFPPF_1GB_FD | OFPPF_FIBER for port_no, name, device_id, device_port_no, root_port in [ (1, 'onu1', onu1.id, 2, False), (2, 'onu2', onu2.id, 2, False), (129, 'olt1', olt.id, 2, True) ]: port = LogicalPort(id=name, ofp_port=ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % port_no), name=name, config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device_id, device_port_no=device_port_no, root_port=root_port) self.adapter_agent.add_logical_port(ld.id, port) olt.parent_id = ld.id self.adapter_agent.update_device(olt)
def _simulate_device_activation(self, device): # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # we pretend that we were able to contact the device and obtain # additional information about it device.vendor = 'simulated onu adapter' device.model = 'n/a' device.hardware_version = 'n/a' device.firmware_version = 'n/a' device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE image1 = Image(name="onu_candidate1", version="1.0", hash="1234567892", install_datetime=datetime.datetime.utcnow().isoformat(), is_active=True, is_committed=True, is_valid=True) image2 = Image(name="onu_candidate2", version="1.0", hash="1234567893", install_datetime=datetime.datetime.utcnow().isoformat(), is_active=False, is_committed=False, is_valid=True) device.images.image.extend([image1, image2]) self.adapter_agent.update_device(device) # then shortly after we create some ports for the device yield asleep(0.05) uni_port = Port(port_no=2, label='UNI facing Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) self.adapter_agent.add_port( device.id, Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ])) # TODO adding vports to the logical device shall be done by agent? # then we create the logical device port that corresponds to the UNI # port of the device yield asleep(0.05) # obtain logical device id parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id # we are going to use the proxy_address.channel_id as unique number # and name for the virtual ports, as this is guaranteed to be unique # in the context of the OLT port, so it is also unique in the context # of the logical device port_no = device.proxy_address.channel_id cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id=str(port_no), ofp_port=ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % port_no), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=uni_port.port_no)) # simulate a proxied message sending and receving a reply reply = yield self._simulate_message_exchange(device) # and finally update to "ACTIVE" device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)
def activate(self, device): self.log.info('activating') # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # register for proxied messages right away self.proxy_address = device.proxy_address self.adapter_agent.register_for_proxied_messages(device.proxy_address) # populate device info device.root = False device.vendor = 'ponsim' device.model = 'n/a' device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # Now set the initial PM configuration for this device self.pm_metrics = AdapterPmMetrics(device) pm_config = self.pm_metrics.make_proto() log.info("initial-pm-config", pm_config=pm_config) self.adapter_agent.update_device_pm_config(pm_config, init=True) # register physical ports self.uni_port = Port(port_no=2, label='UNI facing Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.pon_port = Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ]) self.adapter_agent.add_port(device.id, self.uni_port) self.adapter_agent.add_port(device.id, self.pon_port) # add uni port to logical device parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id port_no = device.proxy_address.channel_id cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id='uni-{}'.format(port_no), ofp_port=ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % port_no), name=device.serial_number, config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=self.uni_port.port_no)) device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) # Start collecting stats from the device after a brief pause self.start_kpi_collection(device.id)
def _onu_device_activation(self, device): # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id == 0 device.model = 'GPON ONU' device.hardware_version = 'tbd' device.firmware_version = 'tbd' device.software_version = 'tbd' device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) uni_port = Port( port_no=1000, # FIXME It becomes the alloc_id label="{} ONU".format('PMCS'), type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) pon_port = Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ]) self.adapter_agent.add_port(device.id, pon_port) # obtain logical device id parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id # we are going to use the proxy_address.channel_id as unique number # and name for the virtual ports, as this is guaranteed to be unique # in the context of the OLT port, so it is also unique in the context # of the logical device port_no = device.proxy_address.channel_id # FIXME this may need to be fixed cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id=str(port_no), ofp_port=ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple( device.serial_number)[2:8], name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=uni_port.port_no)) yield self._initialize_onu(device) # and finally update to "ACTIVE" device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)
def _mib_in_sync(self): self.log.debug('function-entry') omci = self._onu_omci_device in_sync = omci.mib_db_in_sync device = self.adapter_agent.get_device(self.device_id) device.reason = 'discovery-mibsync-complete' self.adapter_agent.update_device(device) if not self._dev_info_loaded: self.log.info('loading-device-data-from-mib', in_sync=in_sync, already_loaded=self._dev_info_loaded) omci_dev = self._onu_omci_device config = omci_dev.configuration # TODO: run this sooner somehow... # In Sync, we can register logical ports now. Ideally this could occur on # the first time we received a successful (no timeout) OMCI Rx response. try: parent_device = self.adapter_agent.get_device(device.parent_id) parent_adapter_agent = registry('adapter_loader').get_agent(parent_device.adapter) if parent_adapter_agent is None: self.log.error('openolt_adapter_agent-could-not-be-retrieved') ani_g = config.ani_g_entities uni_g = config.uni_g_entities pptp = config.pptp_entities for key, value in ani_g.iteritems(): self.log.debug("discovered-ani", key=key, value=value) for key, value in uni_g.iteritems(): self.log.debug("discovered-uni", key=key, value=value) for key, value in pptp.iteritems(): self.log.debug("discovered-pptp-uni", key=key, value=value) entity_id = key # 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) working_port = self._next_port_number uni_no = uni_no_start + working_port uni_name = "uni-{}".format(uni_no) mac_bridge_port_num = working_port + 1 self.log.debug('live-port-number-ready', uni_no=uni_no, uni_name=uni_name) uni_port = UniPort.create(self, uni_name, uni_no, uni_name, device.vlan, device.vlan) uni_port.entity_id = entity_id uni_port.enabled = True uni_port.mac_bridge_port_num = mac_bridge_port_num uni_port.add_logical_port(uni_port.port_number, subscriber_vlan=device.vlan) self.log.debug("created-uni-port", uni=uni_port) self.adapter_agent.add_port(device.id, uni_port.get_port()) parent_adapter_agent.add_port(device.parent_id, uni_port.get_port()) self._unis[uni_port.port_number] = uni_port # TODO: this should be in the PonPortclass pon_port = self._pon.get_port() self.adapter_agent.delete_port_reference_from_parent(self.device_id, pon_port) pon_port.peers.extend([Port.PeerPort(device_id=device.parent_id, port_no=uni_port.port_number)]) self._pon._port = pon_port self.adapter_agent.add_port_reference_to_parent(self.device_id, pon_port) # TODO: only one uni/pptp for now. flow bug in openolt break self._total_tcont_count = ani_g.get('total-tcont-count') self._qos_flexibility = config.qos_configuration_flexibility or 0 self._omcc_version = config.omcc_version or OMCCVersion.Unknown self.log.debug("set-total-tcont-count", tcont_count=self._total_tcont_count) # Save our device information self._dev_info_loaded = True self.adapter_agent.update_device(device) except Exception as e: self.log.exception('device-info-load', e=e) self._deferred = reactor.callLater(_STARTUP_RETRY_WAIT, self._mib_in_sync) else: self.log.info('device-info-already-loaded', in_sync=in_sync, already_loaded=self._dev_info_loaded) def success(_results): self.log.info('mib-download-success', _results=_results) device = self.adapter_agent.get_device(self.device_id) device.reason = 'initial-mib-downloaded' device.oper_status = OperStatus.ACTIVE device.connect_status = ConnectStatus.REACHABLE self.enable_ports(device) self.adapter_agent.update_device(device) self._mib_download_task = None def failure(_reason): self.log.info('mib-download-failure', _reason=_reason) # TODO: test this. also verify i can add this task this way self._mib_download_task = BrcmMibDownloadTask(self.omci_agent, self) self._deferred = self._onu_omci_device.task_runner.queue_task(self._mib_download_task) self.log.info('downloading-initial-mib-configuration') self._mib_download_task = BrcmMibDownloadTask(self.omci_agent, self) self._deferred = self._onu_omci_device.task_runner.queue_task(self._mib_download_task) self._deferred.addCallbacks(success, failure)
def activate(self, device): self.log.info('activating') # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id # register for proxied messages right away self.proxy_address = device.proxy_address self.adapter_agent.register_for_proxied_messages(device.proxy_address) # populate device info device.root = True device.vendor = 'Adtran Inc.' device.model = '10G GPON ONU' # TODO: get actual number device.hardware_version = 'NOT AVAILABLE' device.firmware_version = 'NOT AVAILABLE' # TODO: Support more versions as needed images = Image(version='NOT AVAILABLE') device.images.image.extend([images]) device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # register physical ports nni_port = Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no)]) self.adapter_agent.add_port(device.id, nni_port) uni_port = Port(port_no=2, label='Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) # add uni port to logical device parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id port_no = device.proxy_address.channel_id log.info('ONU OPENFLOW PORT WILL BE {}'.format(port_no)) cap = OFPPF_10GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port(logical_device_id, LogicalPort( id='uni-{}'.format(port_no), ofp_port=ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple('08:00:%02x:%02x:%02x:%02x' % ((device.parent_port_no >> 8 & 0xff), device.parent_port_no & 0xff, (port_no >> 8) & 0xff, port_no & 0xff)), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_10GB_FD, max_speed=OFPPF_10GB_FD ), device_id=device.id, device_port_no=uni_port.port_no )) # Begin ONU Activation sequence reactor.callLater(0, self.message_exchange) device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)