daemon: updated config.py to use dataclasses for config classes, updated naming and referencing. updated configurable options to self validate default values align with the config type. updated the example emane model to better align with the current state of things
This commit is contained in:
parent
bb3590fbde
commit
6086d1229b
14 changed files with 171 additions and 133 deletions
|
@ -4,10 +4,12 @@ Common support for configurable CORE objects.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union
|
from dataclasses import dataclass, field
|
||||||
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, Type, Union
|
||||||
|
|
||||||
from core.emane.nodes import EmaneNet
|
from core.emane.nodes import EmaneNet
|
||||||
from core.emulator.enumerations import ConfigDataTypes
|
from core.emulator.enumerations import ConfigDataTypes
|
||||||
|
from core.errors import CoreConfigError
|
||||||
from core.nodes.network import WlanNode
|
from core.nodes.network import WlanNode
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -15,62 +17,56 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
WirelessModelType = Type[WirelessModel]
|
WirelessModelType = Type[WirelessModel]
|
||||||
|
|
||||||
|
_BOOL_OPTIONS: Set[str] = {"0", "1"}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class ConfigGroup:
|
class ConfigGroup:
|
||||||
"""
|
"""
|
||||||
Defines configuration group tabs used for display by ConfigurationOptions.
|
Defines configuration group tabs used for display by ConfigurationOptions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, start: int, stop: int) -> None:
|
name: str
|
||||||
"""
|
start: int
|
||||||
Creates a ConfigGroup object.
|
stop: int
|
||||||
|
|
||||||
:param name: configuration group display name
|
|
||||||
:param start: configurations start index for this group
|
|
||||||
:param stop: configurations stop index for this group
|
|
||||||
"""
|
|
||||||
self.name: str = name
|
|
||||||
self.start: int = start
|
|
||||||
self.stop: int = stop
|
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class Configuration:
|
class Configuration:
|
||||||
"""
|
"""
|
||||||
Represents a configuration options.
|
Represents a configuration options.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
id: str
|
||||||
self,
|
type: ConfigDataTypes
|
||||||
_id: str,
|
label: str = None
|
||||||
_type: ConfigDataTypes,
|
default: str = ""
|
||||||
label: str = None,
|
options: List[str] = field(default_factory=list)
|
||||||
default: str = "",
|
|
||||||
options: List[str] = None,
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
Creates a Configuration object.
|
|
||||||
|
|
||||||
:param _id: unique name for configuration
|
def __post_init__(self) -> None:
|
||||||
:param _type: configuration data type
|
self.label = self.label if self.label else self.id
|
||||||
:param label: configuration label for display
|
if self.type == ConfigDataTypes.BOOL:
|
||||||
:param default: default value for configuration
|
if self.default and self.default not in _BOOL_OPTIONS:
|
||||||
:param options: list options if this is a configuration with a combobox
|
raise CoreConfigError(
|
||||||
"""
|
f"{self.id} bool value must be one of: {_BOOL_OPTIONS}: "
|
||||||
self.id: str = _id
|
f"{self.default}"
|
||||||
self.type: ConfigDataTypes = _type
|
)
|
||||||
self.default: str = default
|
elif self.type == ConfigDataTypes.FLOAT:
|
||||||
if not options:
|
if self.default:
|
||||||
options = []
|
try:
|
||||||
self.options: List[str] = options
|
float(self.default)
|
||||||
if not label:
|
except ValueError:
|
||||||
label = _id
|
raise CoreConfigError(
|
||||||
self.label: str = label
|
f"{self.id} is not a valid float: {self.default}"
|
||||||
|
)
|
||||||
def __str__(self):
|
elif self.type != ConfigDataTypes.STRING:
|
||||||
return (
|
if self.default:
|
||||||
f"{self.__class__.__name__}(id={self.id}, type={self.type}, "
|
try:
|
||||||
f"default={self.default}, options={self.options})"
|
int(self.default)
|
||||||
)
|
except ValueError:
|
||||||
|
raise CoreConfigError(
|
||||||
|
f"{self.id} is not a valid int: {self.default}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ConfigurableOptions:
|
class ConfigurableOptions:
|
||||||
|
|
|
@ -20,20 +20,20 @@ class VpnClient(ConfigService):
|
||||||
validation_mode: ConfigServiceMode = ConfigServiceMode.BLOCKING
|
validation_mode: ConfigServiceMode = ConfigServiceMode.BLOCKING
|
||||||
default_configs: List[Configuration] = [
|
default_configs: List[Configuration] = [
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="keydir",
|
id="keydir",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Key Dir",
|
label="Key Dir",
|
||||||
default="/etc/core/keys",
|
default="/etc/core/keys",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="keyname",
|
id="keyname",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Key Name",
|
label="Key Name",
|
||||||
default="client1",
|
default="client1",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="server",
|
id="server",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Server",
|
label="Server",
|
||||||
default="10.0.2.10",
|
default="10.0.2.10",
|
||||||
),
|
),
|
||||||
|
@ -54,20 +54,20 @@ class VpnServer(ConfigService):
|
||||||
validation_mode: ConfigServiceMode = ConfigServiceMode.BLOCKING
|
validation_mode: ConfigServiceMode = ConfigServiceMode.BLOCKING
|
||||||
default_configs: List[Configuration] = [
|
default_configs: List[Configuration] = [
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="keydir",
|
id="keydir",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Key Dir",
|
label="Key Dir",
|
||||||
default="/etc/core/keys",
|
default="/etc/core/keys",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="keyname",
|
id="keyname",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Key Name",
|
label="Key Name",
|
||||||
default="server",
|
default="server",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="subnet",
|
id="subnet",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Subnet",
|
label="Subnet",
|
||||||
default="10.0.200.0",
|
default="10.0.200.0",
|
||||||
),
|
),
|
||||||
|
|
|
@ -17,11 +17,11 @@ class SimpleService(ConfigService):
|
||||||
shutdown: List[str] = []
|
shutdown: List[str] = []
|
||||||
validation_mode: ConfigServiceMode = ConfigServiceMode.BLOCKING
|
validation_mode: ConfigServiceMode = ConfigServiceMode.BLOCKING
|
||||||
default_configs: List[Configuration] = [
|
default_configs: List[Configuration] = [
|
||||||
Configuration(_id="value1", _type=ConfigDataTypes.STRING, label="Text"),
|
Configuration(id="value1", type=ConfigDataTypes.STRING, label="Text"),
|
||||||
Configuration(_id="value2", _type=ConfigDataTypes.BOOL, label="Boolean"),
|
Configuration(id="value2", type=ConfigDataTypes.BOOL, label="Boolean"),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="value3",
|
id="value3",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Multiple Choice",
|
label="Multiple Choice",
|
||||||
options=["value1", "value2", "value3"],
|
options=["value1", "value2", "value3"],
|
||||||
),
|
),
|
||||||
|
|
|
@ -18,8 +18,8 @@ class EmaneBypassModel(emanemodel.EmaneModel):
|
||||||
mac_library: str = "bypassmaclayer"
|
mac_library: str = "bypassmaclayer"
|
||||||
mac_config: List[Configuration] = [
|
mac_config: List[Configuration] = [
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="none",
|
id="none",
|
||||||
_type=ConfigDataTypes.BOOL,
|
type=ConfigDataTypes.BOOL,
|
||||||
default="0",
|
default="0",
|
||||||
label="There are no parameters for the bypass model.",
|
label="There are no parameters for the bypass model.",
|
||||||
)
|
)
|
||||||
|
|
|
@ -825,38 +825,38 @@ class EmaneGlobalModel:
|
||||||
self.session: "Session" = session
|
self.session: "Session" = session
|
||||||
self.core_config: List[Configuration] = [
|
self.core_config: List[Configuration] = [
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="platform_id_start",
|
id="platform_id_start",
|
||||||
_type=ConfigDataTypes.INT32,
|
type=ConfigDataTypes.INT32,
|
||||||
default="1",
|
default="1",
|
||||||
label="Starting Platform ID",
|
label="Starting Platform ID",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="nem_id_start",
|
id="nem_id_start",
|
||||||
_type=ConfigDataTypes.INT32,
|
type=ConfigDataTypes.INT32,
|
||||||
default="1",
|
default="1",
|
||||||
label="Starting NEM ID",
|
label="Starting NEM ID",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="link_enabled",
|
id="link_enabled",
|
||||||
_type=ConfigDataTypes.BOOL,
|
type=ConfigDataTypes.BOOL,
|
||||||
default="1",
|
default="1",
|
||||||
label="Enable Links?",
|
label="Enable Links?",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="loss_threshold",
|
id="loss_threshold",
|
||||||
_type=ConfigDataTypes.INT32,
|
type=ConfigDataTypes.INT32,
|
||||||
default="30",
|
default="30",
|
||||||
label="Link Loss Threshold (%)",
|
label="Link Loss Threshold (%)",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="link_interval",
|
id="link_interval",
|
||||||
_type=ConfigDataTypes.INT32,
|
type=ConfigDataTypes.INT32,
|
||||||
default="1",
|
default="1",
|
||||||
label="Link Check Interval (sec)",
|
label="Link Check Interval (sec)",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="link_timeout",
|
id="link_timeout",
|
||||||
_type=ConfigDataTypes.INT32,
|
type=ConfigDataTypes.INT32,
|
||||||
default="4",
|
default="4",
|
||||||
label="Link Timeout (sec)",
|
label="Link Timeout (sec)",
|
||||||
),
|
),
|
||||||
|
|
|
@ -118,8 +118,8 @@ def parse(manifest_path: Path, defaults: Dict[str, str]) -> List[Configuration]:
|
||||||
config_descriptions = f"{config_descriptions} file"
|
config_descriptions = f"{config_descriptions} file"
|
||||||
|
|
||||||
configuration = Configuration(
|
configuration = Configuration(
|
||||||
_id=config_name,
|
id=config_name,
|
||||||
_type=config_type_value,
|
type=config_type_value,
|
||||||
default=config_default,
|
default=config_default,
|
||||||
options=possible,
|
options=possible,
|
||||||
label=config_descriptions,
|
label=config_descriptions,
|
||||||
|
|
|
@ -35,8 +35,8 @@ class EmaneTdmaModel(emanemodel.EmaneModel):
|
||||||
)
|
)
|
||||||
super().load(emane_prefix)
|
super().load(emane_prefix)
|
||||||
config_item = Configuration(
|
config_item = Configuration(
|
||||||
_id=cls.schedule_name,
|
id=cls.schedule_name,
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
default=str(cls.default_schedule),
|
default=str(cls.default_schedule),
|
||||||
label="TDMA schedule file (core)",
|
label="TDMA schedule file (core)",
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,51 +13,51 @@ class SessionConfig(ConfigurableManager, ConfigurableOptions):
|
||||||
name: str = "session"
|
name: str = "session"
|
||||||
options: List[Configuration] = [
|
options: List[Configuration] = [
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="controlnet", _type=ConfigDataTypes.STRING, label="Control Network"
|
id="controlnet", type=ConfigDataTypes.STRING, label="Control Network"
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="controlnet0", _type=ConfigDataTypes.STRING, label="Control Network 0"
|
id="controlnet0", type=ConfigDataTypes.STRING, label="Control Network 0"
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="controlnet1", _type=ConfigDataTypes.STRING, label="Control Network 1"
|
id="controlnet1", type=ConfigDataTypes.STRING, label="Control Network 1"
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="controlnet2", _type=ConfigDataTypes.STRING, label="Control Network 2"
|
id="controlnet2", type=ConfigDataTypes.STRING, label="Control Network 2"
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="controlnet3", _type=ConfigDataTypes.STRING, label="Control Network 3"
|
id="controlnet3", type=ConfigDataTypes.STRING, label="Control Network 3"
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="controlnet_updown_script",
|
id="controlnet_updown_script",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Control Network Script",
|
label="Control Network Script",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="enablerj45",
|
id="enablerj45",
|
||||||
_type=ConfigDataTypes.BOOL,
|
type=ConfigDataTypes.BOOL,
|
||||||
default="1",
|
default="1",
|
||||||
label="Enable RJ45s",
|
label="Enable RJ45s",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="preservedir",
|
id="preservedir",
|
||||||
_type=ConfigDataTypes.BOOL,
|
type=ConfigDataTypes.BOOL,
|
||||||
default="0",
|
default="0",
|
||||||
label="Preserve session dir",
|
label="Preserve session dir",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="enablesdt",
|
id="enablesdt",
|
||||||
_type=ConfigDataTypes.BOOL,
|
type=ConfigDataTypes.BOOL,
|
||||||
default="0",
|
default="0",
|
||||||
label="Enable SDT3D output",
|
label="Enable SDT3D output",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="sdturl",
|
id="sdturl",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
default=Sdt.DEFAULT_SDT_URL,
|
default=Sdt.DEFAULT_SDT_URL,
|
||||||
label="SDT3D URL",
|
label="SDT3D URL",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="ovs", _type=ConfigDataTypes.BOOL, default="0", label="Enable OVS"
|
id="ovs", type=ConfigDataTypes.BOOL, default="0", label="Enable OVS"
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
config_type: RegisterTlvs = RegisterTlvs.UTILITY
|
config_type: RegisterTlvs = RegisterTlvs.UTILITY
|
||||||
|
|
|
@ -46,3 +46,11 @@ class CoreServiceBootError(Exception):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CoreConfigError(Exception):
|
||||||
|
"""
|
||||||
|
Used when there is an error defining a configurable option.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
|
@ -236,35 +236,35 @@ class BasicRangeModel(WirelessModel):
|
||||||
name: str = "basic_range"
|
name: str = "basic_range"
|
||||||
options: List[Configuration] = [
|
options: List[Configuration] = [
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="range",
|
id="range",
|
||||||
_type=ConfigDataTypes.UINT32,
|
type=ConfigDataTypes.UINT32,
|
||||||
default="275",
|
default="275",
|
||||||
label="wireless range (pixels)",
|
label="wireless range (pixels)",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="bandwidth",
|
id="bandwidth",
|
||||||
_type=ConfigDataTypes.UINT64,
|
type=ConfigDataTypes.UINT64,
|
||||||
default="54000000",
|
default="54000000",
|
||||||
label="bandwidth (bps)",
|
label="bandwidth (bps)",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="jitter",
|
id="jitter",
|
||||||
_type=ConfigDataTypes.UINT64,
|
type=ConfigDataTypes.UINT64,
|
||||||
default="0",
|
default="0",
|
||||||
label="transmission jitter (usec)",
|
label="transmission jitter (usec)",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="delay",
|
id="delay",
|
||||||
_type=ConfigDataTypes.UINT64,
|
type=ConfigDataTypes.UINT64,
|
||||||
default="5000",
|
default="5000",
|
||||||
label="transmission delay (usec)",
|
label="transmission delay (usec)",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="error", _type=ConfigDataTypes.STRING, default="0", label="loss (%)"
|
id="error", type=ConfigDataTypes.STRING, default="0", label="loss (%)"
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="promiscuous",
|
id="promiscuous",
|
||||||
_type=ConfigDataTypes.BOOL,
|
type=ConfigDataTypes.BOOL,
|
||||||
default="0",
|
default="0",
|
||||||
label="promiscuous mode",
|
label="promiscuous mode",
|
||||||
),
|
),
|
||||||
|
@ -868,40 +868,38 @@ class Ns2ScriptedMobility(WayPointMobility):
|
||||||
name: str = "ns2script"
|
name: str = "ns2script"
|
||||||
options: List[Configuration] = [
|
options: List[Configuration] = [
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="file", _type=ConfigDataTypes.STRING, label="mobility script file"
|
id="file", type=ConfigDataTypes.STRING, label="mobility script file"
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="refresh_ms",
|
id="refresh_ms",
|
||||||
_type=ConfigDataTypes.UINT32,
|
type=ConfigDataTypes.UINT32,
|
||||||
default="50",
|
default="50",
|
||||||
label="refresh time (ms)",
|
label="refresh time (ms)",
|
||||||
),
|
),
|
||||||
|
Configuration(id="loop", type=ConfigDataTypes.BOOL, default="1", label="loop"),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="loop", _type=ConfigDataTypes.BOOL, default="1", label="loop"
|
id="autostart",
|
||||||
),
|
type=ConfigDataTypes.STRING,
|
||||||
Configuration(
|
|
||||||
_id="autostart",
|
|
||||||
_type=ConfigDataTypes.STRING,
|
|
||||||
label="auto-start seconds (0.0 for runtime)",
|
label="auto-start seconds (0.0 for runtime)",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="map",
|
id="map",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="node mapping (optional, e.g. 0:1,1:2,2:3)",
|
label="node mapping (optional, e.g. 0:1,1:2,2:3)",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="script_start",
|
id="script_start",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="script file to run upon start",
|
label="script file to run upon start",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="script_pause",
|
id="script_pause",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="script file to run upon pause",
|
label="script file to run upon pause",
|
||||||
),
|
),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="script_stop",
|
id="script_stop",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="script file to run upon stop",
|
label="script file to run upon stop",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Example custom emane model.
|
Example custom emane model.
|
||||||
"""
|
"""
|
||||||
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Set
|
from typing import Dict, List, Optional, Set
|
||||||
|
|
||||||
from core.config import Configuration
|
from core.config import Configuration
|
||||||
|
@ -39,17 +40,34 @@ class ExampleModel(emanemodel.EmaneModel):
|
||||||
|
|
||||||
name: str = "emane_example"
|
name: str = "emane_example"
|
||||||
mac_library: str = "rfpipemaclayer"
|
mac_library: str = "rfpipemaclayer"
|
||||||
mac_xml: str = "/usr/share/emane/manifest/rfpipemaclayer.xml"
|
mac_xml: str = "rfpipemaclayer.xml"
|
||||||
mac_defaults: Dict[str, str] = {
|
mac_defaults: Dict[str, str] = {
|
||||||
"pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml"
|
"pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml"
|
||||||
}
|
}
|
||||||
mac_config: List[Configuration] = emanemanifest.parse(mac_xml, mac_defaults)
|
mac_config: List[Configuration] = []
|
||||||
phy_library: Optional[str] = None
|
phy_library: Optional[str] = None
|
||||||
phy_xml: str = "/usr/share/emane/manifest/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] = emanemanifest.parse(phy_xml, phy_defaults)
|
phy_config: List[Configuration] = []
|
||||||
config_ignore: Set[str] = set()
|
config_ignore: Set[str] = set()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls, emane_prefix: Path) -> None:
|
||||||
|
"""
|
||||||
|
Called after being loaded within the EmaneManager. Provides configured
|
||||||
|
emane_prefix for parsing xml files.
|
||||||
|
|
||||||
|
:param emane_prefix: configured emane prefix path
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
manifest_path = "share/emane/manifest"
|
||||||
|
# load mac configuration
|
||||||
|
mac_xml_path = emane_prefix / manifest_path / cls.mac_xml
|
||||||
|
cls.mac_config = emanemanifest.parse(mac_xml_path, cls.mac_defaults)
|
||||||
|
# load phy configuration
|
||||||
|
phy_xml_path = emane_prefix / manifest_path / cls.phy_xml
|
||||||
|
cls.phy_config = emanemanifest.parse(phy_xml_path, cls.phy_defaults)
|
||||||
|
|
|
@ -17,8 +17,8 @@ class TestConfigurableOptions(ConfigurableOptions):
|
||||||
name1 = "value1"
|
name1 = "value1"
|
||||||
name2 = "value2"
|
name2 = "value2"
|
||||||
options = [
|
options = [
|
||||||
Configuration(_id=name1, _type=ConfigDataTypes.STRING, label=name1),
|
Configuration(id=name1, type=ConfigDataTypes.STRING, label=name1),
|
||||||
Configuration(_id=name2, _type=ConfigDataTypes.STRING, label=name2),
|
Configuration(id=name2, type=ConfigDataTypes.STRING, label=name2),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@ class MyService(ConfigService):
|
||||||
shutdown = [f"pkill {files[0]}"]
|
shutdown = [f"pkill {files[0]}"]
|
||||||
validation_mode = ConfigServiceMode.BLOCKING
|
validation_mode = ConfigServiceMode.BLOCKING
|
||||||
default_configs = [
|
default_configs = [
|
||||||
Configuration(_id="value1", _type=ConfigDataTypes.STRING, label="Text"),
|
Configuration(id="value1", type=ConfigDataTypes.STRING, label="Text"),
|
||||||
Configuration(_id="value2", _type=ConfigDataTypes.BOOL, label="Boolean"),
|
Configuration(id="value2", type=ConfigDataTypes.BOOL, label="Boolean"),
|
||||||
Configuration(
|
Configuration(
|
||||||
_id="value3",
|
id="value3",
|
||||||
_type=ConfigDataTypes.STRING,
|
type=ConfigDataTypes.STRING,
|
||||||
label="Multiple Choice",
|
label="Multiple Choice",
|
||||||
options=["value1", "value2", "value3"],
|
options=["value1", "value2", "value3"],
|
||||||
),
|
),
|
||||||
|
|
|
@ -120,7 +120,8 @@ Here is an example model with documentation describing functionality:
|
||||||
"""
|
"""
|
||||||
Example custom emane model.
|
Example custom emane model.
|
||||||
"""
|
"""
|
||||||
from typing import Dict, List, Optional, Set
|
from pathlib import Path
|
||||||
|
from typing import Dict, Optional, Set, List
|
||||||
|
|
||||||
from core.config import Configuration
|
from core.config import Configuration
|
||||||
from core.emane import emanemanifest, emanemodel
|
from core.emane import emanemanifest, emanemodel
|
||||||
|
@ -162,14 +163,31 @@ class ExampleModel(emanemodel.EmaneModel):
|
||||||
mac_defaults: Dict[str, str] = {
|
mac_defaults: Dict[str, str] = {
|
||||||
"pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml"
|
"pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml"
|
||||||
}
|
}
|
||||||
mac_config: List[Configuration] = emanemanifest.parse(mac_xml, mac_defaults)
|
mac_config: List[Configuration] = []
|
||||||
phy_library: Optional[str] = None
|
phy_library: Optional[str] = None
|
||||||
phy_xml: str = "/usr/share/emane/manifest/emanephy.xml"
|
phy_xml: str = "/usr/share/emane/manifest/emanephy.xml"
|
||||||
phy_defaults: Dict[str, str] = {
|
phy_defaults: Dict[str, str] = {
|
||||||
"subid": "1", "propagationmodel": "2ray", "noisemode": "none"
|
"subid": "1", "propagationmodel": "2ray", "noisemode": "none"
|
||||||
}
|
}
|
||||||
phy_config: List[Configuration] = emanemanifest.parse(phy_xml, phy_defaults)
|
phy_config: List[Configuration] = []
|
||||||
config_ignore: Set[str] = set()
|
config_ignore: Set[str] = set()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls, emane_prefix: Path) -> None:
|
||||||
|
"""
|
||||||
|
Called after being loaded within the EmaneManager. Provides configured
|
||||||
|
emane_prefix for parsing xml files.
|
||||||
|
|
||||||
|
:param emane_prefix: configured emane prefix path
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
manifest_path = "share/emane/manifest"
|
||||||
|
# load mac configuration
|
||||||
|
mac_xml_path = emane_prefix / manifest_path / cls.mac_xml
|
||||||
|
cls.mac_config = emanemanifest.parse(mac_xml_path, cls.mac_defaults)
|
||||||
|
# load phy configuration
|
||||||
|
phy_xml_path = emane_prefix / manifest_path / cls.phy_xml
|
||||||
|
cls.phy_config = emanemanifest.parse(phy_xml_path, cls.phy_defaults)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Single PC with EMANE
|
## Single PC with EMANE
|
||||||
|
|
Loading…
Reference in a new issue