def get(self, *args, **kwargs): """List all PNFDevs or a single PNFDev. Args: [0]: the address of the pnfdev Example URLs: GET /api/v1/<wtps|cpps|vbses> GET /api/v1/<wtps|cpps|vbses>/11:22:33:44:55:66 """ try: if len(args) > 1: raise ValueError("Invalid url") if len(args) == 0: self.write_as_json(self.server.pnfdevs.values()) else: pnfdev = self.server.pnfdevs[EtherAddress(args[0])] self.write_as_json(pnfdev) except ValueError as ex: self.send_error(400, message=ex) except KeyError as ex: self.send_error(404, message=ex)
def get(self, *args, **kwargs): """ Get all LVAPs in a Pool or just the specified one. Args: pool_id: the network name lvap_id: the lvap address Example URLs: GET /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26/lvaps GET /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26/ lvaps/11:22:33:44:55:66 """ try: if len(args) not in (1, 2): raise ValueError("Invalid URL") tenant_id = uuid.UUID(args[0]) tenant = RUNTIME.tenants[tenant_id] if len(args) == 1: self.write_as_json(tenant.lvaps.values()) else: lvap = EtherAddress(args[1]) self.write_as_json(tenant.lvaps[lvap]) except KeyError as ex: self.send_error(404, message=ex) except ValueError as ex: self.send_error(400, message=ex) self.set_status(200, None)
def fill_bytes_sample(self, values): out = {} for value in values: lvap = EtherAddress(value[0]) if lvap not in out: out[lvap] = [] out[lvap].append([value[1], value[2]]) for lvap in out.keys(): data = out[lvap] samples = sorted(data, key=lambda entry: entry[0]) new_out = [0] * len(self.bins) for entry in samples: if len(entry) == 0: continue size = entry[0] count = entry[1] for i in range(0, len(self.bins)): if size <= self.bins[i]: new_out[i] = new_out[i] + size * count break out[lvap] = new_out return out
def __parse_vbses_descriptor(self, descriptor): for addr in descriptor['lte']['vbses']: vbs_addr = EtherAddress(addr) if vbs_addr not in self.tenant.vbses: raise KeyError("Unable to find VBS %s" % addr) self.lte['vbses'][vbs_addr] = \ {'static-properties': {}, 'runtime-properties': {}, 'cells': {}} if 'static-properties' in descriptor['lte']['vbses'][addr]: if 'sched_id' in \ descriptor['lte']['vbses'][addr]['static-properties']: sched_id = descriptor['lte']['vbses'][addr] \ ['static-properties']['sched_id'] if isinstance(sched_id, int): self.lte['vbses'][vbs_addr]['static-properties'] \ ['sched_id'] = sched_id else: self.lte['vbses'][vbs_addr]['static-properties'] \ ['sched_id'] = int(sched_id) if 'rbgs' in \ descriptor['lte']['vbses'][addr]['static-properties']: rbgs = descriptor['lte']['vbses'][addr] \ ['static-properties']['rbgs'] if isinstance(rbgs, int): self.lte['vbses'][vbs_addr]['static-properties'] \ ['rbgs'] = rbgs else: self.lte['vbses'][vbs_addr]['static-properties'] \ ['rbgs'] = int(rbgs) if 'runtime-properties' in descriptor['lte']['vbses'][addr]: if 'rntis' in \ descriptor['lte']['vbses'][addr]['runtime-properties']: rntis = descriptor['lte']['vbses'][addr] \ ['runtime-properties']['rntis'] if isinstance(rntis, list): self.lte['vbses'][vbs_addr]['runtime-properties'] \ ['rntis'] = [int(x) for x in rntis] else: self.lte['vbses'][vbs_addr]['runtime-properties'] \ ['rntis'] = [int(rntis)] if 'cells' in descriptor['lte']['vbses'][addr]: self.lte['vbses'][vbs_addr]['cells'] = \ descriptor['lte']['vbses'][addr]['cells']
def _handle_status_vap(self, wtp, status): """Handle an incoming STATUS_VAP message. Args: status, a STATUS_VAP message Returns: None """ bssid = EtherAddress(status.bssid) ssid = SSID(status.ssid) tenant = RUNTIME.load_tenant(ssid) if not tenant: self.log.info("VAP %s from unknown tenant %s", bssid, ssid) return # Check if block is valid valid = wtp.get_block(status.hwaddr, status.channel, status.band) if not valid: self.log.warning("No valid intersection found. Removing VAP.") wtp.connection.send_del_vap(bssid) return # If the VAP does not exists, then create a new one if bssid not in tenant.vaps: vap = VAP(bssid, valid, tenant) tenant.vaps[bssid] = vap vap = tenant.vaps[bssid] self.log.info("VAP status %s", vap)
def wtp_addr(self, value): """Set WTP addr""" try: self.__wtp_addr = EtherAddress(value) except: raise ValueError("Invalid value for WTP address!") self.__wtp_addr = None
def _handle_status_transmission_policy(self, wtp, status): """Handle an incoming TRANSMISSION_POLICY message. Args: status, a TRANSMISSION_POLICY message Returns: None """ # Check if block is valid valid = wtp.get_block(status.hwaddr, status.channel, status.band) if not valid: self.log.warning("No valid intersection found. Removing block.") return sta = EtherAddress(status.sta) tx_policy = valid[0].tx_policies[sta] tx_policy.set_mcs([float(x) / 2 for x in status.mcs]) tx_policy.set_ht_mcs([int(x) for x in status.ht_mcs]) tx_policy.set_rts_cts(status.rts_cts) tx_policy.set_mcast(status.tx_mcast) tx_policy.set_ur_count(status.ur_mcast_count) tx_policy.set_no_ack(status.flags.no_ack) self.log.info("Tranmission policy status %s", tx_policy)
def get(self, *args, **kwargs): """ Get all LVAPs or just the specified one. Args: lvap_id: the lvap address Example URLs: GET /api/v1/lvaps GET /api/v1/lvaps/11:22:33:44:55:66 """ try: if len(args) > 1: raise ValueError("Invalid URL") if len(args) == 0: self.write( json.dumps(RUNTIME.lvaps.values(), cls=EmpowerEncoder)) else: lvap = EtherAddress(args[0]) self.write(json.dumps(RUNTIME.lvaps[lvap], cls=EmpowerEncoder)) except KeyError as ex: self.send_error(404, message=ex) except ValueError as ex: self.send_error(400, message=ex) self.set_status(200, None)
def __init__(self): Module.__init__(self) self._addrs = EtherAddress('FF:FF:FF:FF:FF:FF') self._limit = -1 self._period = 2000 self._block = None self.frames = []
def _trigger_message(self, msg_type): if msg_type not in self.server.pt_types: LOG.error("Unknown message type %u", msg_type) return if self.server.pt_types[msg_type]: LOG.info("Got message type %u (%s)", msg_type, self.server.pt_types[msg_type].name) msg = self.server.pt_types[msg_type].parse(self.__buffer) addr = EtherAddress(msg.wtp) try: wtp = RUNTIME.wtps[addr] except KeyError: LOG.error("Unknown WTP (%s), closing connection", addr) self.stream.close() return handler_name = "_handle_%s" % self.server.pt_types[msg_type].name if hasattr(self, handler_name): handler = getattr(self, handler_name) handler(wtp, msg) if msg_type in self.server.pt_types_handlers: for handler in self.server.pt_types_handlers[msg_type]: handler(msg)
def on_cpp_down(self, bye): """ Handle an BYE message. Args: bye, a BYE message Returns: None """ for event in list(self.modules.values()): if event.tenant_id not in RUNTIME.tenants: return addr = EtherAddress(bye['addr']) cpps = RUNTIME.tenants[event.tenant_id].cpps if addr not in cpps: return cpp = cpps[addr] LOG.info("Event: CPP Down %s", cpp.addr) handle_callback(cpp, event)
def bssid(self, bssid): """ Set the bssid. """ if bssid == EtherAddress("00:00:00:00:00:00"): self._bssid = None else: self._bssid = bssid
def post(self, *args, **kwargs): """ Add a pnfdev to a tenant. Args: tenant_id: network name of a tenant addr: the address of a pnfdev Example URLs: POST /api/v1/pools/52313ecb-9d00-4b7d-b873-b55d3d9ada26/ pnfdev/11:22:33:44:55:66 """ try: if len(args) != 2: raise ValueError("Invalid url") tenant_id = UUID(args[0]) addr = EtherAddress(args[1]) tenant = RUNTIME.tenants[tenant_id] pnfdev = self.server.pnfdevs[addr] tenant.add_pnfdev(pnfdev) except ValueError as ex: self.send_error(400, message=ex) except KeyError as ex: self.send_error(404, message=ex) self.set_status(204, None)
def get(self, *args, **kwargs): """ Get all VAPs in a Pool or just the specified one. Args: pool_id: the network name vap_id: the vap address Example URLs: GET /api/v1/pools/EmPOWER/vaps GET /api/v1/pools/EmPOWER/vaps/11:22:33:44:55:66 """ try: if len(args) > 2 or len(args) < 1: raise ValueError("Invalid URL") tenant_id = uuid.UUID(args[0]) tenant = RUNTIME.tenants[tenant_id] vaps = tenant.vaps if len(args) == 1: self.write_as_json(vaps.values()) else: vap = EtherAddress(args[1]) self.write_as_json(vaps[vap]) except KeyError as ex: self.send_error(404, message=ex) except ValueError as ex: self.send_error(400, message=ex) self.set_status(200, None)
def handle_response(self, response): """Handle an incoming STATS_RESPONSE message. Args: stats, a STATS_RESPONSE message Returns: None """ # update this object self.cqm_links = {} for entry in response.stats: addr = EtherAddress(entry[0]) if addr not in RUNTIME.lvaps: continue lvap = RUNTIME.lvaps[addr] if not lvap.tenant or lvap.tenant.tenant_id != self.tenant_id: continue value = { 'addr': addr, 'p_pdr': entry[1] / 180.0, 'last_rssi_avg': entry[2] / 180.0 } self.cqm_links[addr] = value # call callback self.handle_callback(self)
def handle_message(self, msg): """Handle incoming message.""" addr = EtherAddress(msg['addr']) if addr not in self.server.pnfdevs: LOG.info("Unknown origin %s, closing connection", addr) self.close() return LOG.info("Received %s seq %u from %s" % (msg['type'], msg['seq'], self.request.remote_ip)) handler_name = "_handle_%s" % msg['type'] if hasattr(self, handler_name): handler = getattr(self, handler_name) try: handler(msg) except Exception as ex: LOG.exception(ex) return if msg['type'] in self.server.pt_types_handlers: for handler in self.server.pt_types_handlers[msg['type']]: handler(msg)
def get(self, *args, **kwargs): """ List all PNFDevs or a single PNFDev if the pnfdev_addr is specified. Returns 404 if pnfdev not exists. Args: pnfdev_addr: the address of the pnfdev Example URLs: GET /api/v1/pnfdev GET /api/v1/pnfdev/11:22:33:44:55:66 """ try: if len(args) > 1: raise ValueError("Invalid url") if len(args) == 0: self.write_as_json(self.server.pnfdevs.values()) else: pnfdev = self.server.pnfdevs[EtherAddress(args[0])] self.write_as_json(pnfdev) except ValueError as ex: self.send_error(400, message=ex) except KeyError as ex: self.send_error(404, message=ex)
def _handle_caps_response(self, caps): """Handle an incoming cap response message. Args: caps, a CAP_RESPONSE message Returns: None """ dpid = DPID(caps['dpid']) if dpid not in RUNTIME.datapaths: RUNTIME.datapaths[dpid] = Datapath(dpid) self.cpp.datapath = RUNTIME.datapaths[dpid] for port_id, port in caps['ports'].items(): if int(port_id) not in self.cpp.datapath.network_ports: network_port = NetworkPort(dp=self.cpp.datapath, port_id=int(port['port_id']), hwaddr=EtherAddress(port['hwaddr']), iface=port['iface']) self.cpp.datapath.network_ports[int(port_id)] = network_port # set state to online self.cpp.set_online() # fetch active lvnfs self.send_lvnf_status_request()
def delete(self, *args, **kwargs): """ Remove a pnfdev from a Tenant. Args: tenant_id: network name of a tenant addr: the address of a pnfdev Example URLs: DELETE /api/v1/pools/52313ecb-9d00-4b7d-b873-b55d3d9ada26/ pnfdev/11:22:33:44:55:66 """ try: if len(args) != 2: raise ValueError("Invalid url") tenant_id = UUID(args[0]) addr = EtherAddress(args[1]) tenant = RUNTIME.tenants[tenant_id] tenant_pnfdevs = getattr(tenant, self.server.PNFDEV.ALIAS) pnfdev = tenant_pnfdevs[addr] tenant.remove_pnfdev(pnfdev) except ValueError as ex: self.send_error(400, message=ex) except KeyError as ex: self.send_error(404, message=ex) self.set_status(204, None)
def _handle_status_port(cls, status): """Handle an incoming PORT message. Args: status, a STATUS_PORT message Returns: None """ wtp_addr = EtherAddress(status.wtp) try: wtp = RUNTIME.wtps[wtp_addr] except KeyError: LOG.info("Status from unknown WTP %s", wtp_addr) return if not wtp.connection: LOG.info("Status from disconnected WTP %s", wtp_addr) return sta_addr = EtherAddress(status.sta) hwaddr = EtherAddress(status.hwaddr) block = ResourceBlock(wtp, hwaddr, status.channel, status.band) # incoming block pool = ResourcePool() pool.add(block) match = wtp.supports & pool if not match: LOG.error("Incoming block %s is invalid", block) return block = match.pop() LOG.info("Port status from %s, station %s", wtp_addr, sta_addr) tx_policy = block.tx_policies[sta_addr] tx_policy._mcs = set([float(x) / 2 for x in status.mcs]) tx_policy._rts_cts = int(status.rts_cts) tx_policy._mcast = int(status.tx_mcast) tx_policy._ur_count = int(status.ur_mcast_count) tx_policy._no_ack = bool(status.flags.no_ack) LOG.info("Port status %s", tx_policy)
def generate_bssid(base_mac, sta_mac): """ Generate a new BSSID address. """ base = str(base_mac).split(":")[0:3] unicast_addr_mask = int(base[0], 16) & 0xFE base[0] = str(format(unicast_addr_mask, 'X')) sta = str(sta_mac).split(":")[3:6] return EtherAddress(":".join(base + sta))
def __init__(self, tenant, **kwargs): self.__addrs = EtherAddress(DEFAULT_ADDRS) self.conflicts = {'networks': [], 'stations': []} EmpowerApp.__init__(self, tenant, **kwargs) wtpup(tenant_id=self.tenant.tenant_id, callback=self.wtp_up_callback)
def put(self, *args, **kwargs): """ Set the cell for a given UE. Args: ud_id: the ue id Request: version: the protocol version (1.0) Example URLs: PUT /api/v1/ues/97958af4-6f86-4cd2-9e66-2e61ec60dd0f """ try: if len(args) != 1: raise ValueError("Invalid URL") request = tornado.escape.json_decode(self.request.body) if "version" not in request: raise ValueError("missing version element") ue_id = uuid.UUID(args[0]) ue = RUNTIME.ues[ue_id] if "vbs" in request: vbs_addr = EtherAddress(request['vbs']) vbs = RUNTIME.vbses[vbs_addr] ue.vbs = vbs elif "cell" in request: vbs_addr = EtherAddress(request['cell']['vbs']) vbs = RUNTIME.vbses[vbs_addr] pci = int(request['cell']['pci']) cell = vbs.get_cell_by_pci(pci) ue.cell = cell except KeyError as ex: self.send_error(404, message=ex) except ValueError as ex: self.send_error(400, message=ex) self.set_status(204, None)
def low_rssi(self, trigger): """ Perform handover if an LVAP's rssi is going below the threshold. """ lvap_addr = EtherAddress(trigger.events[-1]['lvap']) lvap = self.lvap(lvap_addr) self.handover(lvap)
def put(self, *args, **kwargs): """ Set the cell for a given UE. Args: tenant_id: the tenant id imsi: the ue IMSI Request: version: the protocol version (1.0) Example URLs: PUT /api/v1/tenants/52313ecb-9d00-4b7d-b873-b55d3d9ada26/ues/111 """ try: if len(args) != 2: raise ValueError("Invalid URL") request = tornado.escape.json_decode(self.request.body) if "version" not in request: raise ValueError("missing version element") if "vbs" not in request: raise ValueError("missing vbs element") if "pci" not in request: raise ValueError("missing pci element") tenant_id = uuid.UUID(args[0]) imsi = int(args[1]) tenant = RUNTIME.tenants[tenant_id] ue = tenant.ues[imsi] vbs_addr = EtherAddress(request['vbs']) pci = int(request['pci']) vbs = tenant.vbses[vbs_addr] target = None for cell in vbs.cells: if cell.pci == pci: target = cell if not target: raise KeyError("Cell %s/%u not found", vbs_addr, pci) ue.cell = target except KeyError as ex: self.send_error(404, message=ex) except ValueError as ex: self.send_error(400, message=ex) self.set_status(204, None)
def mac_address(self, value): """Set mac_address.""" if value is not None: if isinstance(value, str): self.__mac_address = EtherAddress(str(value)) else: raise ValueError("Invalid value for mac_address!") else: self.__mac_address = None
def send_add_lvap(self, lvap, block, set_mask): """Send a ADD_LVAP message. Args: lvap: an LVAP object Returns: None Raises: TypeError: if lvap is not an LVAP object. """ flags = Container(authenticated=lvap.authentication_state, associated=lvap.association_state, set_mask=set_mask) encap = EtherAddress("00:00:00:00:00:00") if lvap.encap: encap = lvap.encap add_lvap = Container(version=PT_VERSION, type=PT_ADD_LVAP, length=51, seq=self.wtp.seq, module_id=lvap.module_id, flags=flags, assoc_id=lvap.assoc_id, hwaddr=block.hwaddr.to_raw(), channel=block.channel, band=block.band, supported_band=lvap.supported_band, sta=lvap.addr.to_raw(), encap=encap.to_raw(), net_bssid=lvap.net_bssid.to_raw(), lvap_bssid=lvap.lvap_bssid.to_raw(), ssids=[]) if lvap.ssid: b_ssid = lvap.ssid.to_raw() tmp = Container(length=len(b_ssid), ssid=b_ssid) add_lvap.ssids.append(tmp) add_lvap.length = add_lvap.length + len(b_ssid) + 1 else: add_lvap.ssids.append(Container(length=0, ssid=b'')) add_lvap.length = add_lvap.length + 1 for ssid in lvap.ssids: b_ssid = ssid.to_raw() tmp = Container(length=len(b_ssid), ssid=b_ssid) add_lvap.ssids.append(tmp) add_lvap.length = add_lvap.length + len(b_ssid) + 1 LOG.info("Add lvap %s", lvap) print(add_lvap) msg = ADD_LVAP.build(add_lvap) self.stream.write(msg)
def convert_hex_enb_id_to_ether_address(self, enb_id): str_hex_value = format(enb_id, 'x') padding = '0' * (12 - len(str_hex_value)) mac_string = padding + str_hex_value mac_string_array = [ mac_string[i:i + 2] for i in range(0, len(mac_string), 2) ] return EtherAddress(":".join(mac_string_array))
def _trigger_message(self, msg_type): if msg_type not in self.server.pt_types: self.log.error("Unknown message type %u", msg_type) return if self.server.pt_types[msg_type]: msg_name = self.server.pt_types[msg_type].name msg = self.server.pt_types[msg_type].parse(self.__buffer) addr = EtherAddress(msg.wtp) try: wtp = RUNTIME.wtps[addr] except KeyError: self.log.error("Unknown WTP (%s), closing connection", addr) self.stream.close() return valid = [PT_HELLO] if not wtp.connection and msg_type not in valid: self.log.info("Got %s message from disconnected %s seq %u", msg_name, EtherAddress(addr), msg.seq) return self.log.info("Got %s message from %s seq %u", msg_name, EtherAddress(addr), msg.seq) valid = [PT_HELLO, PT_CAPS_RESPONSE] if not wtp.is_online() and msg_type not in valid: self.log.info("WTP %s not ready", wtp.addr) return handler_name = "_handle_%s" % self.server.pt_types[msg_type].name if hasattr(self, handler_name): handler = getattr(self, handler_name) handler(wtp, msg) if msg_type in self.server.pt_types_handlers: for handler in self.server.pt_types_handlers[msg_type]: handler(wtp, msg)
def hex_to_ether(in_hex): """Convert Int to EtherAddress.""" str_hex_value = format(in_hex, 'x') padding = '0' * (12 - len(str_hex_value)) mac_string = padding + str_hex_value mac_string_array = \ [mac_string[i:i+2] for i in range(0, len(mac_string), 2)] return EtherAddress(":".join(mac_string_array))