daemon: updated core.emane to avoid using deprecated type hinting

This commit is contained in:
Blake Harnden 2023-04-13 12:18:24 -07:00
parent 3d722a7721
commit 4c222d1a7a
9 changed files with 73 additions and 78 deletions

View file

@ -6,7 +6,7 @@ import logging
import os import os
import threading import threading
from enum import Enum from enum import Enum
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Type, Union from typing import TYPE_CHECKING, Optional, Union
from core import utils from core import utils
from core.emane.emanemodel import EmaneModel from core.emane.emanemodel import EmaneModel
@ -126,9 +126,9 @@ class EmaneManager:
""" """
super().__init__() super().__init__()
self.session: "Session" = session self.session: "Session" = session
self.nems_to_ifaces: Dict[int, CoreInterface] = {} self.nems_to_ifaces: dict[int, CoreInterface] = {}
self.ifaces_to_nems: Dict[CoreInterface, int] = {} self.ifaces_to_nems: dict[CoreInterface, int] = {}
self._emane_nets: Dict[int, EmaneNet] = {} self._emane_nets: dict[int, EmaneNet] = {}
self._emane_node_lock: threading.Lock = threading.Lock() self._emane_node_lock: threading.Lock = threading.Lock()
# port numbers are allocated from these counters # port numbers are allocated from these counters
self.platformport: int = self.session.options.get_int( self.platformport: int = self.session.options.get_int(
@ -141,14 +141,14 @@ class EmaneManager:
self.eventmonthread: Optional[threading.Thread] = None self.eventmonthread: Optional[threading.Thread] = None
# model for global EMANE configuration options # model for global EMANE configuration options
self.node_configs: Dict[int, Dict[str, Dict[str, str]]] = {} self.node_configs: dict[int, dict[str, dict[str, str]]] = {}
self.node_models: Dict[int, str] = {} self.node_models: dict[int, str] = {}
# link monitor # link monitor
self.link_monitor: EmaneLinkMonitor = EmaneLinkMonitor(self) self.link_monitor: EmaneLinkMonitor = EmaneLinkMonitor(self)
# emane event monitoring # emane event monitoring
self.services: Dict[str, EmaneEventService] = {} self.services: dict[str, EmaneEventService] = {}
self.nem_service: Dict[int, EmaneEventService] = {} self.nem_service: dict[int, EmaneEventService] = {}
def next_nem_id(self, iface: CoreInterface) -> int: def next_nem_id(self, iface: CoreInterface) -> int:
nem_id = self.session.options.get_int("nem_id_start") nem_id = self.session.options.get_int("nem_id_start")
@ -161,7 +161,7 @@ class EmaneManager:
def get_config( def get_config(
self, key: int, model: str, default: bool = True self, key: int, model: str, default: bool = True
) -> Optional[Dict[str, str]]: ) -> Optional[dict[str, str]]:
""" """
Get the current or default configuration for an emane model. Get the current or default configuration for an emane model.
@ -181,7 +181,7 @@ class EmaneManager:
config = model_class.default_values() config = model_class.default_values()
return config return config
def set_config(self, key: int, model: str, config: Dict[str, str] = None) -> None: def set_config(self, key: int, model: str, config: dict[str, str] = None) -> None:
""" """
Sets and update the provided configuration against the default model Sets and update the provided configuration against the default model
or currently set emane model configuration. or currently set emane model configuration.
@ -199,7 +199,7 @@ class EmaneManager:
model_configs = self.node_configs.setdefault(key, {}) model_configs = self.node_configs.setdefault(key, {})
model_configs[model] = model_config model_configs[model] = model_config
def get_model(self, model_name: str) -> Type[EmaneModel]: def get_model(self, model_name: str) -> type[EmaneModel]:
""" """
Convenience method for getting globally loaded emane models. Convenience method for getting globally loaded emane models.
@ -211,7 +211,7 @@ class EmaneManager:
def get_iface_config( def get_iface_config(
self, emane_net: EmaneNet, iface: CoreInterface self, emane_net: EmaneNet, iface: CoreInterface
) -> Dict[str, str]: ) -> dict[str, str]:
""" """
Retrieve configuration for a given interface, first checking for interface Retrieve configuration for a given interface, first checking for interface
specific config, node specific config, network specific config, and finally specific config, node specific config, network specific config, and finally
@ -260,7 +260,7 @@ class EmaneManager:
) )
self._emane_nets[emane_net.id] = emane_net self._emane_nets[emane_net.id] = emane_net
def getnodes(self) -> Set[CoreNode]: def getnodes(self) -> set[CoreNode]:
""" """
Return a set of CoreNodes that are linked to an EMANE network, Return a set of CoreNodes that are linked to an EMANE network,
e.g. containers having one or more radio interfaces. e.g. containers having one or more radio interfaces.
@ -335,7 +335,7 @@ class EmaneManager:
self.start_daemon(iface) self.start_daemon(iface)
self.install_iface(iface, config) self.install_iface(iface, config)
def get_ifaces(self) -> List[Tuple[EmaneNet, TunTap]]: def get_ifaces(self) -> list[tuple[EmaneNet, TunTap]]:
ifaces = [] ifaces = []
for emane_net in self._emane_nets.values(): for emane_net in self._emane_nets.values():
if not emane_net.wireless_model: if not emane_net.wireless_model:
@ -354,7 +354,7 @@ class EmaneManager:
return sorted(ifaces, key=lambda x: (x[1].node.id, x[1].id)) return sorted(ifaces, key=lambda x: (x[1].node.id, x[1].id))
def setup_control_channels( def setup_control_channels(
self, nem_id: int, iface: CoreInterface, config: Dict[str, str] self, nem_id: int, iface: CoreInterface, config: dict[str, str]
) -> None: ) -> None:
node = iface.node node = iface.node
# setup ota device # setup ota device
@ -419,7 +419,7 @@ class EmaneManager:
def get_nem_position( def get_nem_position(
self, iface: CoreInterface self, iface: CoreInterface
) -> Optional[Tuple[int, float, float, int]]: ) -> Optional[tuple[int, float, float, int]]:
""" """
Retrieves nem position for a given interface. Retrieves nem position for a given interface.
@ -453,7 +453,7 @@ class EmaneManager:
event.append(nemid, latitude=lat, longitude=lon, altitude=alt) event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
self.publish_event(nemid, event, send_all=True) self.publish_event(nemid, event, send_all=True)
def set_nem_positions(self, moved_ifaces: List[CoreInterface]) -> None: def set_nem_positions(self, moved_ifaces: list[CoreInterface]) -> None:
""" """
Several NEMs have moved, from e.g. a WaypointMobilityModel Several NEMs have moved, from e.g. a WaypointMobilityModel
calculation. Generate an EMANE Location Event having several calculation. Generate an EMANE Location Event having several
@ -480,7 +480,7 @@ class EmaneManager:
try: try:
with path.open("a") as f: with path.open("a") as f:
f.write(f"{iface.node.name} {iface.name} {nem_id}\n") f.write(f"{iface.node.name} {iface.name} {nem_id}\n")
except IOError: except OSError:
logger.exception("error writing to emane nem file") logger.exception("error writing to emane nem file")
def links_enabled(self) -> bool: def links_enabled(self) -> bool:
@ -624,7 +624,7 @@ class EmaneManager:
args = f"{emanecmd} -f {log_file} {platform_xml}" args = f"{emanecmd} -f {log_file} {platform_xml}"
node.host_cmd(args, cwd=self.session.directory) node.host_cmd(args, cwd=self.session.directory)
def install_iface(self, iface: TunTap, config: Dict[str, str]) -> None: def install_iface(self, iface: TunTap, config: dict[str, str]) -> None:
external = config.get("external", "0") external = config.get("external", "0")
if external == "0": if external == "0":
iface.set_ips() iface.set_ips()

View file

@ -1,6 +1,5 @@
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Dict, List
from core.config import Configuration from core.config import Configuration
from core.emulator.enumerations import ConfigDataTypes from core.emulator.enumerations import ConfigDataTypes
@ -33,7 +32,7 @@ def _type_value(config_type: str) -> ConfigDataTypes:
return ConfigDataTypes[config_type] return ConfigDataTypes[config_type]
def _get_possible(config_type: str, config_regex: str) -> List[str]: def _get_possible(config_type: str, config_regex: str) -> list[str]:
""" """
Retrieve possible config value options based on emane regexes. Retrieve possible config value options based on emane regexes.
@ -51,7 +50,7 @@ def _get_possible(config_type: str, config_regex: str) -> List[str]:
return [] return []
def _get_default(config_type_name: str, config_value: List[str]) -> str: def _get_default(config_type_name: str, config_value: list[str]) -> str:
""" """
Convert default configuration values to one used by core. Convert default configuration values to one used by core.
@ -74,7 +73,7 @@ def _get_default(config_type_name: str, config_value: List[str]) -> str:
return config_default return config_default
def parse(manifest_path: Path, defaults: Dict[str, str]) -> List[Configuration]: def parse(manifest_path: Path, defaults: dict[str, str]) -> list[Configuration]:
""" """
Parses a valid emane manifest file and converts the provided configuration values Parses a valid emane manifest file and converts the provided configuration values
into ones used by core. into ones used by core.

View file

@ -3,7 +3,7 @@ Defines Emane Models used within CORE.
""" """
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Dict, List, Optional, Set from typing import Optional
from core.config import ConfigBool, ConfigGroup, ConfigString, Configuration from core.config import ConfigBool, ConfigGroup, ConfigString, Configuration
from core.emane import emanemanifest from core.emane import emanemanifest
@ -28,38 +28,38 @@ class EmaneModel(WirelessModel):
# default platform configuration settings # default platform configuration settings
platform_controlport: str = "controlportendpoint" platform_controlport: str = "controlportendpoint"
platform_xml: str = "nemmanager.xml" platform_xml: str = "nemmanager.xml"
platform_defaults: Dict[str, str] = { platform_defaults: dict[str, str] = {
"eventservicedevice": DEFAULT_DEV, "eventservicedevice": DEFAULT_DEV,
"eventservicegroup": "224.1.2.8:45703", "eventservicegroup": "224.1.2.8:45703",
"otamanagerdevice": DEFAULT_DEV, "otamanagerdevice": DEFAULT_DEV,
"otamanagergroup": "224.1.2.8:45702", "otamanagergroup": "224.1.2.8:45702",
} }
platform_config: List[Configuration] = [] platform_config: list[Configuration] = []
# default mac configuration settings # default mac configuration settings
mac_library: Optional[str] = None mac_library: Optional[str] = None
mac_xml: Optional[str] = None mac_xml: Optional[str] = None
mac_defaults: Dict[str, str] = {} mac_defaults: dict[str, str] = {}
mac_config: List[Configuration] = [] mac_config: list[Configuration] = []
# default phy configuration settings, using the universal model # default phy configuration settings, using the universal model
phy_library: Optional[str] = None phy_library: Optional[str] = None
phy_xml: str = "emanephy.xml" phy_xml: str = "emanephy.xml"
phy_defaults: Dict[str, str] = { phy_defaults: dict[str, str] = {
"subid": "1", "subid": "1",
"propagationmodel": "2ray", "propagationmodel": "2ray",
"noisemode": "none", "noisemode": "none",
} }
phy_config: List[Configuration] = [] phy_config: list[Configuration] = []
# support for external configurations # support for external configurations
external_config: List[Configuration] = [ external_config: list[Configuration] = [
ConfigBool(id="external", default="0"), ConfigBool(id="external", default="0"),
ConfigString(id="platformendpoint", default="127.0.0.1:40001"), ConfigString(id="platformendpoint", default="127.0.0.1:40001"),
ConfigString(id="transportendpoint", default="127.0.0.1:50002"), ConfigString(id="transportendpoint", default="127.0.0.1:50002"),
] ]
config_ignore: Set[str] = set() config_ignore: set[str] = set()
@classmethod @classmethod
def load(cls, emane_prefix: Path) -> None: def load(cls, emane_prefix: Path) -> None:
@ -94,7 +94,7 @@ class EmaneModel(WirelessModel):
cls.platform_config.pop(controlport_index) cls.platform_config.pop(controlport_index)
@classmethod @classmethod
def configurations(cls) -> List[Configuration]: def configurations(cls) -> list[Configuration]:
""" """
Returns the combination all all configurations (mac, phy, and external). Returns the combination all all configurations (mac, phy, and external).
@ -105,7 +105,7 @@ class EmaneModel(WirelessModel):
) )
@classmethod @classmethod
def config_groups(cls) -> List[ConfigGroup]: def config_groups(cls) -> list[ConfigGroup]:
""" """
Returns the defined configuration groups. Returns the defined configuration groups.
@ -122,7 +122,7 @@ class EmaneModel(WirelessModel):
ConfigGroup("External Parameters", phy_len + 1, config_len), ConfigGroup("External Parameters", phy_len + 1, config_len),
] ]
def build_xml_files(self, config: Dict[str, str], iface: CoreInterface) -> None: def build_xml_files(self, config: dict[str, str], iface: CoreInterface) -> None:
""" """
Builds xml files for this emane model. Creates a nem.xml file that points to Builds xml files for this emane model. Creates a nem.xml file that points to
both mac.xml and phy.xml definitions. both mac.xml and phy.xml definitions.
@ -146,7 +146,7 @@ class EmaneModel(WirelessModel):
""" """
logger.debug("emane model(%s) has no post setup tasks", self.name) logger.debug("emane model(%s) has no post setup tasks", self.name)
def update(self, moved_ifaces: List[CoreInterface]) -> None: def update(self, moved_ifaces: list[CoreInterface]) -> None:
""" """
Invoked from MobilityModel when nodes are moved; this causes Invoked from MobilityModel when nodes are moved; this causes
emane location events to be generated for the nodes in the moved emane location events to be generated for the nodes in the moved

View file

@ -2,7 +2,7 @@ import logging
import sched import sched
import threading import threading
import time import time
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple from typing import TYPE_CHECKING, Optional
from lxml import etree from lxml import etree
@ -34,10 +34,10 @@ NEM_SELF: int = 65535
class LossTable: class LossTable:
def __init__(self, losses: Dict[float, float]) -> None: def __init__(self, losses: dict[float, float]) -> None:
self.losses: Dict[float, float] = losses self.losses: dict[float, float] = losses
self.sinrs: List[float] = sorted(self.losses.keys()) self.sinrs: list[float] = sorted(self.losses.keys())
self.loss_lookup: Dict[int, float] = {} self.loss_lookup: dict[int, float] = {}
for index, value in enumerate(self.sinrs): for index, value in enumerate(self.sinrs):
self.loss_lookup[index] = self.losses[value] self.loss_lookup[index] = self.losses[value]
self.mac_id: Optional[str] = None self.mac_id: Optional[str] = None
@ -84,7 +84,7 @@ class EmaneClient:
self.client: shell.ControlPortClient = shell.ControlPortClient( self.client: shell.ControlPortClient = shell.ControlPortClient(
self.address, port self.address, port
) )
self.nems: Dict[int, LossTable] = {} self.nems: dict[int, LossTable] = {}
self.setup() self.setup()
def setup(self) -> None: def setup(self) -> None:
@ -110,7 +110,7 @@ class EmaneClient:
self.nems[nem_id] = loss_table self.nems[nem_id] = loss_table
def check_links( def check_links(
self, links: Dict[Tuple[int, int], EmaneLink], loss_threshold: int self, links: dict[tuple[int, int], EmaneLink], loss_threshold: int
) -> None: ) -> None:
for from_nem, loss_table in self.nems.items(): for from_nem, loss_table in self.nems.items():
tables = self.client.getStatisticTable(loss_table.mac_id, (SINR_TABLE,)) tables = self.client.getStatisticTable(loss_table.mac_id, (SINR_TABLE,))
@ -138,11 +138,11 @@ class EmaneClient:
link = EmaneLink(from_nem, to_nem, sinr) link = EmaneLink(from_nem, to_nem, sinr)
links[link_key] = link links[link_key] = link
def handle_tdma(self, config: Dict[str, Tuple]): def handle_tdma(self, config: dict[str, tuple]):
pcr = config["pcrcurveuri"][0][0] pcr = config["pcrcurveuri"][0][0]
logger.debug("tdma pcr: %s", pcr) logger.debug("tdma pcr: %s", pcr)
def handle_80211(self, config: Dict[str, Tuple]) -> LossTable: def handle_80211(self, config: dict[str, tuple]) -> LossTable:
unicastrate = config["unicastrate"][0][0] unicastrate = config["unicastrate"][0][0]
pcr = config["pcrcurveuri"][0][0] pcr = config["pcrcurveuri"][0][0]
logger.debug("80211 pcr: %s", pcr) logger.debug("80211 pcr: %s", pcr)
@ -159,7 +159,7 @@ class EmaneClient:
losses[sinr] = por losses[sinr] = por
return LossTable(losses) return LossTable(losses)
def handle_rfpipe(self, config: Dict[str, Tuple]) -> LossTable: def handle_rfpipe(self, config: dict[str, tuple]) -> LossTable:
pcr = config["pcrcurveuri"][0][0] pcr = config["pcrcurveuri"][0][0]
logger.debug("rfpipe pcr: %s", pcr) logger.debug("rfpipe pcr: %s", pcr)
tree = etree.parse(pcr) tree = etree.parse(pcr)
@ -179,9 +179,9 @@ class EmaneClient:
class EmaneLinkMonitor: class EmaneLinkMonitor:
def __init__(self, emane_manager: "EmaneManager") -> None: def __init__(self, emane_manager: "EmaneManager") -> None:
self.emane_manager: "EmaneManager" = emane_manager self.emane_manager: "EmaneManager" = emane_manager
self.clients: List[EmaneClient] = [] self.clients: list[EmaneClient] = []
self.links: Dict[Tuple[int, int], EmaneLink] = {} self.links: dict[tuple[int, int], EmaneLink] = {}
self.complete_links: Set[Tuple[int, int]] = set() self.complete_links: set[tuple[int, int]] = set()
self.loss_threshold: Optional[int] = None self.loss_threshold: Optional[int] = None
self.link_interval: Optional[int] = None self.link_interval: Optional[int] = None
self.link_timeout: Optional[int] = None self.link_timeout: Optional[int] = None
@ -210,7 +210,7 @@ class EmaneLinkMonitor:
if client.nems: if client.nems:
self.clients.append(client) self.clients.append(client)
def get_addresses(self) -> List[Tuple[str, int]]: def get_addresses(self) -> list[tuple[str, int]]:
addresses = [] addresses = []
nodes = self.emane_manager.getnodes() nodes = self.emane_manager.getnodes()
for node in nodes: for node in nodes:
@ -273,25 +273,25 @@ class EmaneLinkMonitor:
if self.running: if self.running:
self.scheduler.enter(self.link_interval, 0, self.check_links) self.scheduler.enter(self.link_interval, 0, self.check_links)
def get_complete_id(self, link_id: Tuple[int, int]) -> Tuple[int, int]: def get_complete_id(self, link_id: tuple[int, int]) -> tuple[int, int]:
value1, value2 = link_id value1, value2 = link_id
if value1 < value2: if value1 < value2:
return value1, value2 return value1, value2
else: else:
return value2, value1 return value2, value1
def is_complete_link(self, link_id: Tuple[int, int]) -> bool: def is_complete_link(self, link_id: tuple[int, int]) -> bool:
reverse_id = link_id[1], link_id[0] reverse_id = link_id[1], link_id[0]
return link_id in self.links and reverse_id in self.links return link_id in self.links and reverse_id in self.links
def get_link_label(self, link_id: Tuple[int, int]) -> str: def get_link_label(self, link_id: tuple[int, int]) -> str:
source_id = tuple(sorted(link_id)) source_id = tuple(sorted(link_id))
source_link = self.links[source_id] source_link = self.links[source_id]
dest_id = link_id[::-1] dest_id = link_id[::-1]
dest_link = self.links[dest_id] dest_link = self.links[dest_id]
return f"{source_link.sinr:.1f} / {dest_link.sinr:.1f}" return f"{source_link.sinr:.1f} / {dest_link.sinr:.1f}"
def send_link(self, message_type: MessageFlags, link_id: Tuple[int, int]) -> None: def send_link(self, message_type: MessageFlags, link_id: tuple[int, int]) -> None:
nem1, nem2 = link_id nem1, nem2 = link_id
link = self.emane_manager.get_nem_link(nem1, nem2, message_type) link = self.emane_manager.get_nem_link(nem1, nem2, message_type)
if link: if link:

View file

@ -1,7 +1,6 @@
import logging import logging
import pkgutil import pkgutil
from pathlib import Path from pathlib import Path
from typing import Dict, List, Type
from core import utils from core import utils
from core.emane import models as emane_models from core.emane import models as emane_models
@ -12,10 +11,10 @@ logger = logging.getLogger(__name__)
class EmaneModelManager: class EmaneModelManager:
models: Dict[str, Type[EmaneModel]] = {} models: dict[str, type[EmaneModel]] = {}
@classmethod @classmethod
def load_locals(cls, emane_prefix: Path) -> List[str]: def load_locals(cls, emane_prefix: Path) -> list[str]:
""" """
Load local core emane models and make them available. Load local core emane models and make them available.
@ -38,7 +37,7 @@ class EmaneModelManager:
return errors return errors
@classmethod @classmethod
def load(cls, path: Path, emane_prefix: Path) -> List[str]: def load(cls, path: Path, emane_prefix: Path) -> list[str]:
""" """
Search and load custom emane models and make them available. Search and load custom emane models and make them available.
@ -63,7 +62,7 @@ class EmaneModelManager:
return errors return errors
@classmethod @classmethod
def get(cls, name: str) -> Type[EmaneModel]: def get(cls, name: str) -> type[EmaneModel]:
model = cls.models.get(name) model = cls.models.get(name)
if model is None: if model is None:
raise CoreError(f"emame model does not exist {name}") raise CoreError(f"emame model does not exist {name}")

View file

@ -2,7 +2,6 @@
EMANE Bypass model for CORE EMANE Bypass model for CORE
""" """
from pathlib import Path from pathlib import Path
from typing import List, Set
from core.config import ConfigBool, Configuration from core.config import ConfigBool, Configuration
from core.emane import emanemodel from core.emane import emanemodel
@ -12,11 +11,11 @@ class EmaneBypassModel(emanemodel.EmaneModel):
name: str = "emane_bypass" name: str = "emane_bypass"
# values to ignore, when writing xml files # values to ignore, when writing xml files
config_ignore: Set[str] = {"none"} config_ignore: set[str] = {"none"}
# mac definitions # mac definitions
mac_library: str = "bypassmaclayer" mac_library: str = "bypassmaclayer"
mac_config: List[Configuration] = [ mac_config: list[Configuration] = [
ConfigBool( ConfigBool(
id="none", id="none",
default="0", default="0",
@ -26,7 +25,7 @@ class EmaneBypassModel(emanemodel.EmaneModel):
# phy definitions # phy definitions
phy_library: str = "bypassphylayer" phy_library: str = "bypassphylayer"
phy_config: List[Configuration] = [] phy_config: list[Configuration] = []
@classmethod @classmethod
def load(cls, emane_prefix: Path) -> None: def load(cls, emane_prefix: Path) -> None:

View file

@ -4,7 +4,6 @@ commeffect.py: EMANE CommEffect model for CORE
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Dict, List
from lxml import etree from lxml import etree
@ -42,12 +41,12 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
name: str = "emane_commeffect" name: str = "emane_commeffect"
shim_library: str = "commeffectshim" shim_library: str = "commeffectshim"
shim_xml: str = "commeffectshim.xml" shim_xml: str = "commeffectshim.xml"
shim_defaults: Dict[str, str] = {} shim_defaults: dict[str, str] = {}
config_shim: List[Configuration] = [] config_shim: list[Configuration] = []
# comm effect does not need the default phy and external configurations # comm effect does not need the default phy and external configurations
phy_config: List[Configuration] = [] phy_config: list[Configuration] = []
external_config: List[Configuration] = [] external_config: list[Configuration] = []
@classmethod @classmethod
def load(cls, emane_prefix: Path) -> None: def load(cls, emane_prefix: Path) -> None:
@ -56,11 +55,11 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
cls.config_shim = emanemanifest.parse(shim_xml_path, cls.shim_defaults) cls.config_shim = emanemanifest.parse(shim_xml_path, cls.shim_defaults)
@classmethod @classmethod
def configurations(cls) -> List[Configuration]: def configurations(cls) -> list[Configuration]:
return cls.platform_config + cls.config_shim return cls.platform_config + cls.config_shim
@classmethod @classmethod
def config_groups(cls) -> List[ConfigGroup]: def config_groups(cls) -> list[ConfigGroup]:
platform_len = len(cls.platform_config) platform_len = len(cls.platform_config)
return [ return [
ConfigGroup("Platform Parameters", 1, platform_len), ConfigGroup("Platform Parameters", 1, platform_len),
@ -71,7 +70,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
), ),
] ]
def build_xml_files(self, config: Dict[str, str], iface: CoreInterface) -> None: def build_xml_files(self, config: dict[str, str], iface: CoreInterface) -> None:
""" """
Build the necessary nem and commeffect XMLs in the given path. Build the necessary nem and commeffect XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build If an individual NEM has a nonstandard config, we need to build

View file

@ -4,7 +4,6 @@ tdma.py: EMANE TDMA model bindings for CORE
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Set
from core import constants, utils from core import constants, utils
from core.config import ConfigString from core.config import ConfigString
@ -28,7 +27,7 @@ class EmaneTdmaModel(emanemodel.EmaneModel):
default_schedule: Path = ( default_schedule: Path = (
constants.CORE_DATA_DIR / "examples" / "tdma" / "schedule.xml" constants.CORE_DATA_DIR / "examples" / "tdma" / "schedule.xml"
) )
config_ignore: Set[str] = {schedule_name} config_ignore: set[str] = {schedule_name}
@classmethod @classmethod
def load(cls, emane_prefix: Path) -> None: def load(cls, emane_prefix: Path) -> None:

View file

@ -6,7 +6,7 @@ share the same MAC+PHY model.
import logging import logging
import time import time
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Type, Union from typing import TYPE_CHECKING, Callable, Optional, Union
from core.emulator.data import InterfaceData, LinkData, LinkOptions from core.emulator.data import InterfaceData, LinkData, LinkOptions
from core.emulator.distributed import DistributedServer from core.emulator.distributed import DistributedServer
@ -196,7 +196,7 @@ class EmaneNet(CoreNetworkBase):
def unlink(self, iface1: CoreInterface, iface2: CoreInterface) -> None: def unlink(self, iface1: CoreInterface, iface2: CoreInterface) -> None:
pass pass
def updatemodel(self, config: Dict[str, str]) -> None: def updatemodel(self, config: dict[str, str]) -> None:
""" """
Update configuration for the current model. Update configuration for the current model.
@ -212,8 +212,8 @@ class EmaneNet(CoreNetworkBase):
def setmodel( def setmodel(
self, self,
model: Union[Type["EmaneModel"], Type["WayPointMobility"]], model: Union[type["EmaneModel"], type["WayPointMobility"]],
config: Dict[str, str], config: dict[str, str],
) -> None: ) -> None:
""" """
set the EmaneModel associated with this node set the EmaneModel associated with this node
@ -225,7 +225,7 @@ class EmaneNet(CoreNetworkBase):
self.mobility = model(session=self.session, _id=self.id) self.mobility = model(session=self.session, _id=self.id)
self.mobility.update_config(config) self.mobility.update_config(config)
def links(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]: def links(self, flags: MessageFlags = MessageFlags.NONE) -> list[LinkData]:
links = [] links = []
emane_manager = self.session.emane emane_manager = self.session.emane
# gather current emane links # gather current emane links