initial commit with things working for the most part

This commit is contained in:
Blake J. Harnden 2018-06-06 14:51:45 -07:00
parent c1b6747a26
commit 2ede43e3ae
21 changed files with 1018 additions and 1397 deletions

View file

@ -1,7 +1,7 @@
"""
EMANE Bypass model for CORE
"""
from core.conf import Configuration
from core.emane import emanemodel
from core.enumerations import ConfigDataTypes
@ -15,13 +15,20 @@ class EmaneBypassModel(emanemodel.EmaneModel):
# mac definitions
mac_library = "bypassmaclayer"
mac_config = [
("none", ConfigDataTypes.BOOL.value, "0", "True,False",
"There are no parameters for the bypass model."),
Configuration(
_id="none",
_type=ConfigDataTypes.BOOL,
default="0",
options=["True", "False"],
label="There are no parameters for the bypass model."
)
]
# phy definitions
phy_library = "bypassphylayer"
phy_config = []
# override gui display tabs
config_groups_override = "Bypass Parameters:1-1"
# override config groups
@classmethod
def config_groups(cls):
return "Bypass Parameters:1-1"

View file

@ -35,8 +35,13 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
shim_defaults = {}
config_shim = emanemanifest.parse(shim_xml, shim_defaults)
config_groups_override = "CommEffect SHIM Parameters:1-%d" % len(config_shim)
config_matrix_override = config_shim
@classmethod
def configurations(cls):
return cls.config_shim
@classmethod
def config_groups(cls):
return "CommEffect SHIM Parameters:1-%d" % len(cls.configurations())
def build_xml_files(self, emane_manager, interface):
"""
@ -49,8 +54,9 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
:param interface: interface for the emane node
:return: nothing
"""
values = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None:
default_values = self.default_values()
config = emane_manager.getifcconfig(self.object_id, self.name, default_values, interface)
if not config:
return
# retrieve xml names
@ -67,23 +73,22 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
nem_element.appendChild(shim_xml)
emane_manager.xmlwrite(nem_document, nem_name)
names = self.getnames()
shim_names = list(names)
shim_names.remove("filterfile")
shim_document = emane_manager.xmldoc("shim")
shim_element = shim_document.getElementsByTagName("shim").pop()
shim_element.setAttribute("name", "%s SHIM" % self.name)
shim_element.setAttribute("library", self.shim_library)
# append all shim options (except filterfile) to shimdoc
for name in shim_names:
value = self.valueof(name, values)
for configuration in self.config_shim:
name = configuration.id
if name == "filterfile":
continue
value = config[name]
param = emane_manager.xmlparam(shim_document, name, value)
shim_element.appendChild(param)
# empty filterfile is not allowed
ff = self.valueof("filterfile", values)
ff = config["filterfile"]
if ff.strip() != "":
shim_element.appendChild(emane_manager.xmlparam(shim_document, "filterfile", ff))
emane_manager.xmlwrite(shim_document, shim_name)

View file

@ -10,7 +10,9 @@ from core import CoreCommandError
from core import constants
from core import logger
from core.api import coreapi
from core.conf import ConfigurableManager
from core.conf import ConfigShim
from core.conf import Configuration
from core.conf import NewConfigurableManager
from core.emane import emanemanifest
from core.emane.bypass import EmaneBypassModel
from core.emane.commeffect import EmaneCommEffectModel
@ -50,7 +52,7 @@ EMANE_MODELS = [
]
class EmaneManager(ConfigurableManager):
class EmaneManager(NewConfigurableManager):
"""
EMANE controller object. Lives in a Session instance and is used for
building EMANE config files from all of the EmaneNode objects in this
@ -70,7 +72,7 @@ class EmaneManager(ConfigurableManager):
:param core.session.Session session: session this manager is tied to
:return: nothing
"""
ConfigurableManager.__init__(self)
super(EmaneManager, self).__init__()
self.session = session
self._emane_nodes = {}
self._emane_node_lock = threading.Lock()
@ -84,16 +86,22 @@ class EmaneManager(ConfigurableManager):
# model for global EMANE configuration options
self.emane_config = EmaneGlobalModel(session, None)
self.set_configs(self.emane_config.default_values())
session.broker.handlers.add(self.handledistributed)
self.service = None
self.event_device = None
self._modelclsmap = {
self.emane_config.name: self.emane_config
}
self._modelclsmap = {}
self.service = None
self.emane_check()
def emane_models(self):
return self._modelclsmap.keys()
def get_model_class(self, model_name):
return self._modelclsmap[model_name]
def emane_check(self):
"""
Check if emane is installed and load models.
@ -138,9 +146,8 @@ class EmaneManager(ConfigurableManager):
return
# Get the control network to be used for events
values = self.getconfig(None, "emane", self.emane_config.getdefaultvalues())[1]
group, port = self.emane_config.valueof("eventservicegroup", values).split(":")
self.event_device = self.emane_config.valueof("eventservicedevice", values)
group, port = self.get_config("eventservicegroup").split(":")
self.event_device = self.get_config("eventservicedevice")
eventnetidx = self.session.get_control_net_index(self.event_device)
if eventnetidx < 0:
logger.error("invalid emane event service device provided: %s", self.event_device)
@ -170,7 +177,6 @@ class EmaneManager(ConfigurableManager):
for emane_model in emane_models:
logger.info("loading emane model: %s", emane_model.__name__)
self._modelclsmap[emane_model.name] = emane_model
self.session.add_config_object(emane_model.name, emane_model.config_type, emane_model.configure_emane)
def add_node(self, emane_node):
"""
@ -196,26 +202,31 @@ class EmaneManager(ConfigurableManager):
nodes.add(netif.node)
return nodes
def getmodels(self, n):
def getmodels(self, node):
"""
Used with XML export; see ConfigurableManager.getmodels()
Used with XML export.
"""
r = ConfigurableManager.getmodels(self, n)
# EMANE global params are stored with first EMANE node (if non-default
# values are configured)
sorted_ids = sorted(self.configs.keys())
if None in self.configs and len(sorted_ids) > 1 and n.objid == sorted_ids[1]:
v = self.configs[None]
for model in v:
cls = self._modelclsmap[model[0]]
vals = model[1]
r.append((cls, vals))
return r
configs = self.get_config_types(node.objid)
models = []
for model_name, config in configs.iteritems():
model_class = self._modelclsmap[model_name]
models.append((model_class, config))
logger.debug("emane models: %s", models)
return models
def getifcconfig(self, nodenum, conftype, defaultvalues, ifc):
def getifcconfig(self, node_id, config_type, default_values, ifc):
"""
Retrieve interface configuration or node configuration if not provided.
:param int node_id: node id
:param str config_type: configuration type
:param dict default_values: default configuration values
:param ifc: node interface
:return:
"""
# use the network-wide config values or interface(NEM)-specific values?
if ifc is None:
return self.getconfig(nodenum, conftype, defaultvalues)[1]
return self.get_configs(node_id, config_type) or default_values
else:
# don"t use default values when interface config is the same as net
# note here that using ifc.node.objid as key allows for only one type
@ -229,16 +240,19 @@ class EmaneManager(ConfigurableManager):
if ifc.netindex is not None:
key += ifc.netindex
values = self.getconfig(key, conftype, None)[1]
if not values:
values = self.getconfig(ifc.node.objid, conftype, None)[1]
# try retrieve interface specific configuration
config = self.get_configs(key, config_type)
if not values and ifc.transport_type == "raw":
# otherwise retrieve the interfaces node configuration
if not config:
config = self.get_configs(ifc.node.objid, config_type)
if not config and ifc.transport_type == "raw":
# with EMANE 0.9.2+, we need an extra NEM XML from
# model.buildnemxmlfiles(), so defaults are returned here
values = self.getconfig(nodenum, conftype, defaultvalues)[1]
config = self.get_configs(node_id, config_type) or default_values
return values
return config
def setup(self):
"""
@ -264,9 +278,7 @@ class EmaneManager(ConfigurableManager):
# - needs to be configured before checkdistributed() for distributed
# - needs to exist when eventservice binds to it (initeventservice)
if self.session.master:
values = self.getconfig(None, self.emane_config.name, self.emane_config.getdefaultvalues())[1]
logger.debug("emane config default values: %s", values)
otadev = self.emane_config.valueof("otamanagerdevice", values)
otadev = self.get_config("otamanagerdevice")
netidx = self.session.get_control_net_index(otadev)
logger.debug("emane ota manager device: index(%s) otadev(%s)", netidx, otadev)
if netidx < 0:
@ -275,7 +287,7 @@ class EmaneManager(ConfigurableManager):
ctrlnet = self.session.add_remove_control_net(net_index=netidx, remove=False, conf_required=False)
self.distributedctrlnet(ctrlnet)
eventdev = self.emane_config.valueof("eventservicedevice", values)
eventdev = self.get_config("eventservicedevice")
logger.debug("emane event service device: eventdev(%s)", eventdev)
if eventdev != otadev:
netidx = self.session.get_control_net_index(eventdev)
@ -288,10 +300,11 @@ class EmaneManager(ConfigurableManager):
self.distributedctrlnet(ctrlnet)
if self.checkdistributed():
# we are slave, but haven"t received a platformid yet
cfgval = self.getconfig(None, self.emane_config.name, self.emane_config.getdefaultvalues())[1]
i = self.emane_config.getnames().index("platform_id_start")
if cfgval[i] == self.emane_config.getdefaultvalues()[i]:
# we are slave, but haven't received a platformid yet
platform_id_start = "platform_id_start"
default_values = self.emane_config.default_values()
value = self.get_config(platform_id_start)
if value == default_values[platform_id_start]:
return EmaneManager.NOT_READY
self.setnodemodels()
@ -359,7 +372,7 @@ class EmaneManager(ConfigurableManager):
with self._emane_node_lock:
self._emane_nodes.clear()
# don"t clear self._ifccounts here; NEM counts are needed for buildxml
# don't clear self._ifccounts here; NEM counts are needed for buildxml
self.platformport = self.session.get_config_item_int("emane_platform_port", 8100)
self.transformport = self.session.get_config_item_int("emane_transform_port", 8200)
@ -416,20 +429,16 @@ class EmaneManager(ConfigurableManager):
if not master:
return True
cfgval = self.getconfig(None, self.emane_config.name, self.emane_config.getdefaultvalues())[1]
values = list(cfgval)
nemcount = 0
with self._emane_node_lock:
for key in self._emane_nodes:
emane_node = self._emane_nodes[key]
nemcount += emane_node.numnetif()
nemid = int(self.emane_config.valueof("nem_id_start", values))
nemid = int(self.get_config("nem_id_start"))
nemid += nemcount
platformid = int(self.emane_config.valueof("platform_id_start", values))
names = list(self.emane_config.getnames())
platformid = int(self.get_config("platform_id_start"))
# build an ordered list of servers so platform ID is deterministic
servers = []
@ -448,9 +457,10 @@ class EmaneManager(ConfigurableManager):
platformid += 1
typeflags = ConfigFlags.UPDATE.value
values[names.index("platform_id_start")] = str(platformid)
values[names.index("nem_id_start")] = str(nemid)
msg = EmaneGlobalModel.config_data(flags=0, node_id=None, type_flags=typeflags, values=values)
self.set_config("platform_id_start", str(platformid))
self.set_config("nem_id_start", str(nemid))
msg = ConfigShim.config_data(0, None, typeflags, self.emane_config, self.get_configs())
# TODO: this needs to be converted into a sendable TLV message
server.sock.send(msg)
# increment nemid for next server by number of interfaces
with self._ifccountslock:
@ -489,8 +499,9 @@ class EmaneManager(ConfigurableManager):
if len(servers) < 2:
return
prefix = session.config.get("controlnet")
prefix = getattr(session.options, "controlnet", prefix)
prefix = session.options.get_config("controlnet")
if not prefix:
prefix = session.config.get("controlnet")
prefixes = prefix.split()
# normal Config messaging will distribute controlnets
if len(prefixes) >= len(servers):
@ -557,24 +568,17 @@ class EmaneManager(ConfigurableManager):
for key in self._emane_nodes:
self.setnodemodel(key)
def setnodemodel(self, key):
logger.debug("setting emane node model: %s", key)
emane_node = self._emane_nodes[key]
if key not in self.configs:
logger.debug("no emane node model configuration, leaving")
def setnodemodel(self, node_id):
logger.debug("setting emane models for node: %s", node_id)
node_config_types = self.get_config_types(node_id)
if not node_config_types:
logger.debug("no emane node model configuration, leaving: %s", node_id)
return False
for t, v in self.configs[key]:
logger.debug("configuration: key(%s) value(%s)", t, v)
if t is None:
continue
if t == self.emane_config.name:
continue
# only use the first valid EmaneModel
# convert model name to class (e.g. emane_rfpipe -> EmaneRfPipe)
cls = self._modelclsmap[t]
emane_node.setmodel(cls, v)
emane_node = self._emane_nodes[node_id]
for model_class, config in self.getmodels(emane_node):
logger.debug("setting emane model(%s) config(%s)", model_class, config)
emane_node.setmodel(model_class, config)
return True
# no model has been configured for this EmaneNode
@ -588,8 +592,8 @@ class EmaneManager(ConfigurableManager):
emane_node = None
netif = None
for key in self._emane_nodes:
emane_node = self._emane_nodes[key]
for node_id in self._emane_nodes:
emane_node = self._emane_nodes[node_id]
netif = emane_node.getnemnetif(nemid)
if netif is not None:
break
@ -607,7 +611,7 @@ class EmaneManager(ConfigurableManager):
count += len(emane_node.netifs())
return count
def newplatformxmldoc(self, values, otadev=None, eventdev=None):
def newplatformxmldoc(self, otadev=None, eventdev=None):
"""
Start a new platform XML file. Use global EMANE config values
as keys. Override OTA manager and event service devices if
@ -615,21 +619,20 @@ class EmaneManager(ConfigurableManager):
"""
doc = self.xmldoc("platform")
plat = doc.getElementsByTagName("platform").pop()
names = list(self.emane_config.getnames())
platform_names = names[:len(self.emane_config.emulator_config)]
platform_names.remove("platform_id_start")
platform_values = list(values)
if otadev:
i = platform_names.index("otamanagerdevice")
platform_values[i] = otadev
self.set_config("otamanagerdevice", otadev)
if eventdev:
i = platform_names.index("eventservicedevice")
platform_values[i] = eventdev
self.set_config("eventservicedevice", eventdev)
# append all platform options (except starting id) to doc
for name in platform_names:
value = self.emane_config.valueof(name, platform_values)
for configuration in self.emane_config.emulator_config:
name = configuration.id
if name == "platform_id_start":
continue
value = self.get_config(name)
param = self.xmlparam(doc, name, value)
plat.appendChild(param)
@ -639,8 +642,7 @@ class EmaneManager(ConfigurableManager):
"""
Build a platform.xml file now that all nodes are configured.
"""
values = self.getconfig(None, "emane", self.emane_config.getdefaultvalues())[1]
nemid = int(self.emane_config.valueof("nem_id_start", values))
nemid = int(self.get_config("nem_id_start"))
platformxmls = {}
# assume self._objslock is already held here
@ -660,7 +662,7 @@ class EmaneManager(ConfigurableManager):
eventdev = None
if key not in platformxmls:
platformxmls[key] = self.newplatformxmldoc(values, otadev, eventdev)
platformxmls[key] = self.newplatformxmldoc(otadev, eventdev)
doc = platformxmls[key]
plat = doc.getElementsByTagName("platform").pop()
@ -713,13 +715,11 @@ class EmaneManager(ConfigurableManager):
Build the libemaneeventservice.xml file if event service options
were changed in the global config.
"""
defaults = self.emane_config.getdefaultvalues()
values = self.getconfig(None, "emane", self.emane_config.getdefaultvalues())[1]
need_xml = False
keys = ("eventservicegroup", "eventservicedevice")
for k in keys:
a = self.emane_config.valueof(k, defaults)
b = self.emane_config.valueof(k, values)
default_values = self.emane_config.default_values()
for name in ["eventservicegroup", "eventservicedevice"]:
a = default_values[name]
b = self.get_config(name)
if a != b:
need_xml = True
@ -729,12 +729,12 @@ class EmaneManager(ConfigurableManager):
return
try:
group, port = self.emane_config.valueof("eventservicegroup", values).split(":")
group, port = self.get_config("eventservicegroup").split(":")
except ValueError:
logger.exception("invalid eventservicegroup in EMANE config")
return
dev = self.emane_config.valueof("eventservicedevice", values)
dev = self.get_config("eventservicedevice")
doc = self.xmldoc("emaneeventmsgsvc")
es = doc.getElementsByTagName("emaneeventmsgsvc").pop()
kvs = (("group", group), ("port", port), ("device", dev), ("mcloop", "1"), ("ttl", "32"))
@ -761,13 +761,12 @@ class EmaneManager(ConfigurableManager):
if realtime:
emanecmd += "-r",
values = self.getconfig(None, "emane", self.emane_config.getdefaultvalues())[1]
otagroup, otaport = self.emane_config.valueof("otamanagergroup", values).split(":")
otadev = self.emane_config.valueof("otamanagerdevice", values)
otagroup, otaport = self.get_config("otamanagergroup").split(":")
otadev = self.get_config("otamanagerdevice")
otanetidx = self.session.get_control_net_index(otadev)
eventgroup, eventport = self.emane_config.valueof("eventservicegroup", values).split(":")
eventdev = self.emane_config.valueof("eventservicedevice", values)
eventgroup, eventport = self.get_config("eventservicegroup").split(":")
eventdev = self.get_config("eventservicedevice")
eventservicenetidx = self.session.get_control_net_index(eventdev)
run_emane_on_host = False
@ -799,8 +798,7 @@ class EmaneManager(ConfigurableManager):
node.check_cmd(args)
# start emane
args = emanecmd + ["-f", os.path.join(path, "emane%d.log" % n),
os.path.join(path, "platform%d.xml" % n)]
args = emanecmd + ["-f", os.path.join(path, "emane%d.log" % n), os.path.join(path, "platform%d.xml" % n)]
output = node.check_cmd(args)
logger.info("node(%s) emane daemon running: %s", node.name, args)
logger.info("node(%s) emane daemon output: %s", node.name, output)
@ -855,23 +853,6 @@ class EmaneManager(ConfigurableManager):
emane_node = self._emane_nodes[key]
emane_node.deinstallnetifs()
def configure(self, session, config_data):
"""
Handle configuration messages for global EMANE config.
:param core.conf.ConfigData config_data: configuration data for carrying out a configuration
"""
r = self.emane_config.configure_emane(session, config_data)
# extra logic to start slave Emane object after nemid has been configured from the master
config_type = config_data.type
if config_type == ConfigFlags.UPDATE.value and self.session.master is False:
# instantiation was previously delayed by self.setup()
# returning Emane.NOT_READY
self.session.instantiate()
return r
def doeventmonitor(self):
"""
Returns boolean whether or not EMANE events will be monitored.
@ -900,11 +881,10 @@ class EmaneManager(ConfigurableManager):
return
if self.service is None:
errmsg = "Warning: EMANE events will not be generated " \
"because the emaneeventservice\n binding was " \
"unable to load " \
"(install the python-emaneeventservice bindings)"
logger.error(errmsg)
logger.error("Warning: EMANE events will not be generated "
"because the emaneeventservice\n binding was "
"unable to load "
"(install the python-emaneeventservice bindings)")
return
self.doeventloop = True
self.eventmonthread = threading.Thread(target=self.eventmonitorloop)
@ -1019,6 +999,7 @@ class EmaneGlobalModel(EmaneModel):
"""
Global EMANE configuration options.
"""
_DEFAULT_DEV = "ctrl0"
name = "emane"
@ -1033,19 +1014,26 @@ class EmaneGlobalModel(EmaneModel):
emulator_config = emanemanifest.parse(emulator_xml, emulator_defaults)
emulator_config.insert(
0,
("platform_id_start", ConfigDataTypes.INT32.value, "1", "", "Starting Platform ID (core)")
Configuration(_id="platform_id_start", _type=ConfigDataTypes.INT32, default="1",
label="Starting Platform ID (core)")
)
nem_config = [
("nem_id_start", ConfigDataTypes.INT32.value, "1", "", "Starting NEM ID (core)"),
Configuration(_id="nem_id_start", _type=ConfigDataTypes.INT32, default="1",
label="Starting NEM ID (core)")
]
config_matrix_override = emulator_config + nem_config
config_groups_override = "Platform Attributes:1-%d|NEM Parameters:%d-%d" % (
len(emulator_config), len(emulator_config) + 1, len(config_matrix_override))
@classmethod
def configurations(cls):
return cls.emulator_config + cls.nem_config
@classmethod
def config_groups(cls):
return "Platform Attributes:1-%d|NEM Parameters:%d-%d" % (
len(cls.emulator_config), len(cls.emulator_config) + 1, len(cls.configurations()))
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
super(EmaneGlobalModel, self).__init__(session, object_id)
def build_xml_files(self, emane_manager, interface):
"""

View file

@ -1,4 +1,5 @@
from core import logger
from core.conf import Configuration
from core.enumerations import ConfigDataTypes
manifest = None
@ -23,7 +24,7 @@ def _type_value(config_type):
config_type = "FLOAT"
elif config_type == "INETADDR":
config_type = "STRING"
return ConfigDataTypes[config_type].value
return ConfigDataTypes[config_type]
def _get_possible(config_type, config_regex):
@ -36,14 +37,13 @@ def _get_possible(config_type, config_regex):
:rtype: str
"""
if config_type == "bool":
return "On,Off"
return ["On", "Off"]
if config_type == "string" and config_regex:
possible = config_regex[2:-2]
possible = possible.replace("|", ",")
return possible
return possible.split("|")
return ""
return []
def _get_default(config_type_name, config_value):
@ -116,7 +116,13 @@ def parse(manifest_path, defaults):
if config_name.endswith("uri"):
config_descriptions = "%s file" % config_descriptions
config_tuple = (config_name, config_type_value, config_default, possible, config_descriptions)
configurations.append(config_tuple)
configuration = Configuration(
_id=config_name,
_type=config_type_value,
default=config_default,
options=possible,
label=config_descriptions
)
configurations.append(configuration)
return configurations

View file

@ -34,51 +34,12 @@ def value_to_params(doc, name, value):
return xmlutils.add_param_list_to_parent(doc, parent=None, name=name, values=values)
class EmaneModelMetaClass(type):
"""
Hack into making class level properties to streamline emane model creation, until the Configurable class is
removed or refactored.
"""
@property
def config_matrix(cls):
"""
Convenience method for creating the config matrix, allow for a custom override.
:param EmaneModel cls: emane class
:return: config matrix value
:rtype: list
"""
if cls.config_matrix_override:
return cls.config_matrix_override
else:
return cls.mac_config + cls.phy_config
@property
def config_groups(cls):
"""
Convenience method for creating the config groups, allow for a custom override.
:param EmaneModel cls: emane class
:return: config groups value
:rtype: str
"""
if cls.config_groups_override:
return cls.config_groups_override
else:
mac_len = len(cls.mac_config)
config_len = len(cls.config_matrix)
return "MAC Parameters:1-%d|PHY Parameters:%d-%d" % (mac_len, mac_len + 1, config_len)
class EmaneModel(WirelessModel):
"""
EMANE models inherit from this parent class, which takes care of
handling configuration messages based on the list of
configurable parameters. Helper functions also live here.
"""
__metaclass__ = EmaneModelMetaClass
# default mac configuration settings
mac_library = None
mac_xml = None
@ -97,10 +58,20 @@ class EmaneModel(WirelessModel):
config_ignore = set()
config_groups_override = None
config_matrix_override = None
configurations_override = None
@classmethod
def configurations(cls):
return cls.mac_config + cls.phy_config
@classmethod
def config_groups(cls):
mac_len = len(cls.mac_config)
config_len = len(cls.configurations())
return "MAC Parameters:1-%d|PHY Parameters:%d-%d" % (mac_len, mac_len + 1, config_len)
def __init__(self, session, object_id=None):
WirelessModel.__init__(self, session, object_id)
super(EmaneModel, self).__init__(session, object_id)
def build_xml_files(self, emane_manager, interface):
"""
@ -111,8 +82,8 @@ class EmaneModel(WirelessModel):
:return: nothing
"""
# retrieve configuration values
values = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None:
config = emane_manager.getifcconfig(self.object_id, self.name, self.default_values(), interface)
if not config:
return
# create document and write to disk
@ -122,12 +93,12 @@ class EmaneModel(WirelessModel):
# create mac document and write to disk
mac_name = self.mac_name(interface)
mac_document = self.create_mac_doc(emane_manager, values)
mac_document = self.create_mac_doc(emane_manager, config)
emane_manager.xmlwrite(mac_document, mac_name)
# create phy document and write to disk
phy_name = self.phy_name(interface)
phy_document = self.create_phy_doc(emane_manager, values)
phy_document = self.create_phy_doc(emane_manager, config)
emane_manager.xmlwrite(phy_document, phy_name)
def create_nem_doc(self, emane_manager, interface):
@ -157,18 +128,15 @@ class EmaneModel(WirelessModel):
return nem_document
def create_mac_doc(self, emane_manager, values):
def create_mac_doc(self, emane_manager, config):
"""
Create the mac xml document.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param tuple values: all current configuration values, mac + phy
:param dict config: all current configuration values, mac + phy
:return: nem document
:rtype: xml.dom.minidom.Document
"""
names = list(self.getnames())
mac_names = names[:len(self.mac_config)]
mac_document = emane_manager.xmldoc("mac")
mac_element = mac_document.getElementsByTagName("mac").pop()
mac_element.setAttribute("name", "%s MAC" % self.name)
@ -177,13 +145,14 @@ class EmaneModel(WirelessModel):
raise ValueError("must define emane model library")
mac_element.setAttribute("library", self.mac_library)
for name in mac_names:
for mac_configuration in self.mac_config:
# ignore custom configurations
name = mac_configuration.id
if name in self.config_ignore:
continue
# check if value is a multi param
value = self.valueof(name, values)
value = config[name]
param = value_to_params(mac_document, name, value)
if not param:
param = emane_manager.xmlparam(mac_document, name, value)
@ -192,18 +161,15 @@ class EmaneModel(WirelessModel):
return mac_document
def create_phy_doc(self, emane_manager, values):
def create_phy_doc(self, emane_manager, config):
"""
Create the phy xml document.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param tuple values: all current configuration values, mac + phy
:param dict config: all current configuration values, mac + phy
:return: nem document
:rtype: xml.dom.minidom.Document
"""
names = list(self.getnames())
phy_names = names[len(self.mac_config):]
phy_document = emane_manager.xmldoc("phy")
phy_element = phy_document.getElementsByTagName("phy").pop()
phy_element.setAttribute("name", "%s PHY" % self.name)
@ -212,13 +178,14 @@ class EmaneModel(WirelessModel):
phy_element.setAttribute("library", self.phy_library)
# append all phy options
for name in phy_names:
for phy_configuration in self.phy_config:
# ignore custom configurations
name = phy_configuration.id
if name in self.config_ignore:
continue
# check if value is a multi param
value = self.valueof(name, values)
value = config[name]
param = value_to_params(phy_document, name, value)
if not param:
param = emane_manager.xmlparam(phy_document, name, value)
@ -227,16 +194,6 @@ class EmaneModel(WirelessModel):
return phy_document
@classmethod
def configure_emane(cls, session, config_data):
"""
Handle configuration messages for configuring an emane model.
:param core.session.Session session: session to configure emane
:param core.conf.ConfigData config_data: configuration data for carrying out a configuration
"""
return cls.configure(session.emane, config_data)
def post_startup(self, emane_manager):
"""
Logic to execute after the emane manager is finished with startup.
@ -317,7 +274,7 @@ class EmaneModel(WirelessModel):
if interface:
node_id = interface.node.objid
if emane_manager.getifcconfig(node_id, self.name, None, interface) is not None:
if emane_manager.getifcconfig(node_id, self.name, {}, interface):
name = interface.localname.replace(".", "_")
return "%s%s" % (name, self.name)

View file

@ -174,14 +174,9 @@ class EmaneNode(EmaneNet):
trans.setAttribute("library", "trans%s" % transport_type.lower())
trans.appendChild(emane.xmlparam(transdoc, "bitrate", "0"))
flowcontrol = False
names = self.model.getnames()
values = emane.getconfig(self.objid, self.model.name, self.model.getdefaultvalues())[1]
if "flowcontrolenable" in names and values:
i = names.index("flowcontrolenable")
if self.model.booltooffon(values[i]) == "on":
flowcontrol = True
config = emane.get_configs(self.objid, self.model.name)
logger.debug("transport xml config: %s", config)
flowcontrol = config.get("flowcontrolenable", "0") == "1"
if "virtual" in transport_type.lower():
if os.path.exists("/dev/net/tun_flowctl"):
@ -193,11 +188,11 @@ class EmaneNode(EmaneNet):
emane.xmlwrite(transdoc, self.transportxmlname(transport_type.lower()))
def transportxmlname(self, type):
def transportxmlname(self, _type):
"""
Return the string name for the Transport XML file, e.g. 'n3transvirtual.xml'
"""
return "n%strans%s.xml" % (self.objid, type)
return "n%strans%s.xml" % (self.objid, _type)
def installnetifs(self, do_netns=True):
"""

View file

@ -6,6 +6,7 @@ import os
from core import constants
from core import logger
from core.conf import Configuration
from core.emane import emanemanifest
from core.emane import emanemodel
from core.enumerations import ConfigDataTypes
@ -29,7 +30,12 @@ class EmaneTdmaModel(emanemodel.EmaneModel):
default_schedule = os.path.join(constants.CORE_DATA_DIR, "examples", "tdma", "schedule.xml")
mac_config.insert(
0,
(schedule_name, ConfigDataTypes.STRING.value, default_schedule, "", "TDMA schedule file (core)")
Configuration(
_id=schedule_name,
_type=ConfigDataTypes.STRING,
default=default_schedule,
label="TDMA schedule file (core)"
)
)
config_ignore = {schedule_name}
@ -41,10 +47,10 @@ class EmaneTdmaModel(emanemodel.EmaneModel):
:return: nothing
"""
# get configured schedule
values = emane_manager.getconfig(self.object_id, self.name, self.getdefaultvalues())[1]
if values is None:
config = emane_manager.get_configs()
if not config:
return
schedule = self.valueof(self.schedule_name, values)
schedule = config[self.schedule_name]
event_device = emane_manager.event_device