initial commit with things working for the most part
This commit is contained in:
parent
c1b6747a26
commit
2ede43e3ae
21 changed files with 1018 additions and 1397 deletions
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue