updates to support external transport configuration and an emane transport service to generate and run emanetransport for a configured external transport model
This commit is contained in:
parent
bf222cd5b4
commit
bfbee35a53
10 changed files with 108 additions and 16 deletions
|
@ -105,7 +105,7 @@ class Configuration(object):
|
|||
Represents a configuration options.
|
||||
"""
|
||||
|
||||
def __init__(self, _id, _type, label, default="", options=None):
|
||||
def __init__(self, _id, _type, label=None, default="", options=None):
|
||||
"""
|
||||
Creates a Configuration object.
|
||||
|
||||
|
|
|
@ -41,8 +41,9 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
shim_defaults = {}
|
||||
config_shim = emanemanifest.parse(shim_xml, shim_defaults)
|
||||
|
||||
# comm effect does not need the default phy configuration
|
||||
# comm effect does not need the default phy and external configurations
|
||||
phy_config = ()
|
||||
external_config = ()
|
||||
|
||||
@classmethod
|
||||
def configurations(cls):
|
||||
|
|
|
@ -128,7 +128,9 @@ class EmaneManager(ModelManager):
|
|||
if not config and self.has_configs(interface.node.objid):
|
||||
config = self.get_configs(node_id=interface.node.objid, config_type=model_name)
|
||||
|
||||
if not config and interface.transport_type == "raw":
|
||||
# get non interface config, when none found
|
||||
# if not config and interface.transport_type == "raw":
|
||||
if not config and self.has_configs(node_id):
|
||||
# with EMANE 0.9.2+, we need an extra NEM XML from
|
||||
# model.buildnemxmlfiles(), so defaults are returned here
|
||||
config = self.get_configs(node_id=node_id, config_type=model_name)
|
||||
|
@ -561,11 +563,12 @@ class EmaneManager(ModelManager):
|
|||
Build a platform.xml file now that all nodes are configured.
|
||||
"""
|
||||
nemid = int(self.get_config("nem_id_start"))
|
||||
platform_xmls = {}
|
||||
|
||||
# assume self._objslock is already held here
|
||||
for key in sorted(self._emane_nodes.keys()):
|
||||
emane_node = self._emane_nodes[key]
|
||||
nemid = emanexml.build_node_platform_xml(self, ctrlnet, emane_node, nemid)
|
||||
nemid = emanexml.build_node_platform_xml(self, ctrlnet, emane_node, nemid, platform_xmls)
|
||||
|
||||
def buildnemxml(self):
|
||||
"""
|
||||
|
|
|
@ -5,7 +5,9 @@ import os
|
|||
|
||||
from core import logger
|
||||
from core.conf import ConfigGroup
|
||||
from core.conf import Configuration
|
||||
from core.emane import emanemanifest
|
||||
from core.enumerations import ConfigDataTypes
|
||||
from core.mobility import WirelessModel
|
||||
from core.xml import emanexml
|
||||
|
||||
|
@ -32,19 +34,28 @@ class EmaneModel(WirelessModel):
|
|||
}
|
||||
phy_config = emanemanifest.parse(phy_xml, phy_defaults)
|
||||
|
||||
# support for external configurations
|
||||
external_config = [
|
||||
Configuration("external", ConfigDataTypes.BOOL, default="0"),
|
||||
Configuration("platformendpoint", ConfigDataTypes.STRING, default="127.0.0.1:40001"),
|
||||
Configuration("transportendpoint", ConfigDataTypes.STRING, default="127.0.0.1:50002")
|
||||
]
|
||||
|
||||
config_ignore = set()
|
||||
|
||||
@classmethod
|
||||
def configurations(cls):
|
||||
return cls.mac_config + cls.phy_config
|
||||
return cls.mac_config + cls.phy_config + cls.external_config
|
||||
|
||||
@classmethod
|
||||
def config_groups(cls):
|
||||
mac_len = len(cls.mac_config)
|
||||
phy_len = len(cls.phy_config) + mac_len
|
||||
config_len = len(cls.configurations())
|
||||
return [
|
||||
ConfigGroup("MAC Parameters", 1, mac_len),
|
||||
ConfigGroup("PHY Parameters", mac_len + 1, config_len)
|
||||
ConfigGroup("PHY Parameters", mac_len + 1, phy_len),
|
||||
ConfigGroup("External Parameters", phy_len + 1, config_len)
|
||||
]
|
||||
|
||||
def build_xml_files(self, config, interface=None):
|
||||
|
@ -60,6 +71,7 @@ class EmaneModel(WirelessModel):
|
|||
mac_name = emanexml.mac_file_name(self, interface)
|
||||
phy_name = emanexml.phy_file_name(self, interface)
|
||||
|
||||
# check if this is external
|
||||
transport_type = "virtual"
|
||||
if interface and interface.transport_type == "raw":
|
||||
transport_type = "raw"
|
||||
|
@ -67,7 +79,7 @@ class EmaneModel(WirelessModel):
|
|||
|
||||
# create nem xml file
|
||||
nem_file = os.path.join(self.session.session_dir, nem_name)
|
||||
emanexml.create_nem_xml(self, nem_file, transport_name, mac_name, phy_name)
|
||||
emanexml.create_nem_xml(self, config, nem_file, transport_name, mac_name, phy_name)
|
||||
|
||||
# create mac xml file
|
||||
mac_file = os.path.join(self.session.session_dir, mac_name)
|
||||
|
|
|
@ -131,7 +131,7 @@ class EmaneNode(EmaneNet):
|
|||
for netif in self.netifs():
|
||||
if do_netns and "virtual" in netif.transport_type.lower():
|
||||
netif.install()
|
||||
netif.setaddrs()
|
||||
# netif.setaddrs()
|
||||
if not self.session.emane.genlocationevents():
|
||||
netif.poshook = None
|
||||
continue
|
||||
|
|
|
@ -169,6 +169,7 @@ class TunTap(PyCoreNetIf):
|
|||
:return: wait for device local response
|
||||
:rtype: int
|
||||
"""
|
||||
logger.debug("waiting for device local: %s", self.localname)
|
||||
|
||||
def localdevexists():
|
||||
args = [constants.IP_BIN, "link", "show", self.localname]
|
||||
|
@ -182,6 +183,7 @@ class TunTap(PyCoreNetIf):
|
|||
|
||||
:return: nothing
|
||||
"""
|
||||
logger.debug("waiting for device node: %s", self.name)
|
||||
|
||||
def nodedevexists():
|
||||
args = [constants.IP_BIN, "link", "show", self.name]
|
||||
|
|
40
daemon/core/services/emaneservices.py
Normal file
40
daemon/core/services/emaneservices.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
from core.enumerations import NodeTypes
|
||||
from core.misc import nodeutils
|
||||
from core.service import CoreService
|
||||
from core.xml import emanexml
|
||||
|
||||
|
||||
class EmaneTransportService(CoreService):
|
||||
name = "transportd"
|
||||
executables = ("emanetransportd", "emanegentransportxml")
|
||||
group = "EMANE"
|
||||
dependencies = ()
|
||||
dirs = ()
|
||||
configs = ("emanetransport.sh",)
|
||||
startup = ("sh %s" % configs[0],)
|
||||
validate = ("pidof %s" % executables[0],)
|
||||
validation_timer = 0.5
|
||||
shutdown = ("killall %s" % executables[0],)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
if filename == cls.configs[0]:
|
||||
transport_commands = []
|
||||
for interface in node.netifs(sort=True):
|
||||
network_node = node.session.get_object(interface.net.objid)
|
||||
if nodeutils.is_node(network_node, NodeTypes.EMANE):
|
||||
if not node.session.emane.has_configs(network_node.objid):
|
||||
continue
|
||||
all_configs = node.session.emane.get_all_configs(network_node.objid)
|
||||
config = all_configs.get(network_node.model.name)
|
||||
if emanexml.is_external(config):
|
||||
nem_id = network_node.getnemid(interface)
|
||||
command = "emanetransportd -r -l 0 -d ../transportdaemon%s.xml" % nem_id
|
||||
transport_commands.append(command)
|
||||
transport_commands = "\n".join(transport_commands)
|
||||
return """
|
||||
emanegentransportxml -o ../ ../platform%s.xml
|
||||
%s
|
||||
""" % (node.objid, transport_commands)
|
||||
else:
|
||||
raise ValueError
|
|
@ -84,6 +84,11 @@ def create_emane_model_config(node_id, model, config):
|
|||
value = config[phy_config.id]
|
||||
add_configuration(phy_element, phy_config.id, value)
|
||||
|
||||
external_element = etree.SubElement(emane_element, "external")
|
||||
for external_config in model.external_config:
|
||||
value = config[external_config.id]
|
||||
add_configuration(external_element, external_config.id, value)
|
||||
|
||||
return emane_element
|
||||
|
||||
|
||||
|
@ -774,6 +779,12 @@ class CoreXmlReader(object):
|
|||
value = config.get("value")
|
||||
configs[name] = value
|
||||
|
||||
external_configuration = emane_configuration.find("external")
|
||||
for config in external_configuration.iterchildren():
|
||||
name = config.get("name")
|
||||
value = config.get("value")
|
||||
configs[name] = value
|
||||
|
||||
logger.info("reading emane configuration node(%s) model(%s)", node_id, model_name)
|
||||
self.session.emane.set_model_config(node_id, model_name, configs)
|
||||
|
||||
|
|
|
@ -10,6 +10,17 @@ from core.xml import corexml
|
|||
_hwaddr_prefix = "02:02"
|
||||
|
||||
|
||||
def is_external(config):
|
||||
"""
|
||||
Checks if the configuration is for an external transport.
|
||||
|
||||
:param dict config: configuration to check
|
||||
:return: True if external, False otherwise
|
||||
:rtype: bool
|
||||
"""
|
||||
return config.get("external") == "1"
|
||||
|
||||
|
||||
def _value_to_params(value):
|
||||
"""
|
||||
Helper to convert a parameter to a parameter tuple.
|
||||
|
@ -85,7 +96,7 @@ def add_configurations(xml_element, configurations, config, config_ignore):
|
|||
add_param(xml_element, name, value)
|
||||
|
||||
|
||||
def build_node_platform_xml(emane_manager, control_net, node, nem_id):
|
||||
def build_node_platform_xml(emane_manager, control_net, node, nem_id, platform_xmls):
|
||||
"""
|
||||
Create platform xml for a specific node.
|
||||
|
||||
|
@ -93,15 +104,15 @@ def build_node_platform_xml(emane_manager, control_net, node, nem_id):
|
|||
:param core.netns.nodes.CtrlNet control_net: control net node for this emane network
|
||||
:param core.emane.nodes.EmaneNode node: node to write platform xml for
|
||||
:param int nem_id: nem id to use for interfaces for this node
|
||||
:param dict platform_xmls: stores platform xml elements to append nem entries to
|
||||
:return: the next nem id that can be used for creating platform xml files
|
||||
:rtype: int
|
||||
"""
|
||||
logger.debug("building emane platform xml for node(%s): %s", node, node.name)
|
||||
nem_entries = {}
|
||||
platform_xmls = {}
|
||||
|
||||
if node.model is None:
|
||||
logger.info("warning: EmaneNode %s has no associated model", node.name)
|
||||
logger.warn("warning: EmaneNode %s has no associated model", node.name)
|
||||
return nem_entries
|
||||
|
||||
for netif in node.netifs():
|
||||
|
@ -109,6 +120,16 @@ def build_node_platform_xml(emane_manager, control_net, node, nem_id):
|
|||
nem_definition = nem_file_name(node.model, netif)
|
||||
nem_element = etree.Element("nem", id=str(nem_id), name=netif.localname, definition=nem_definition)
|
||||
|
||||
# check if this is an external transport, get default config if an interface specific one does not exist
|
||||
config = emane_manager.getifcconfig(node.model.object_id, netif, node.model.name)
|
||||
|
||||
if is_external(config):
|
||||
nem_element.set("transport", "external")
|
||||
platform_endpoint = "platformendpoint"
|
||||
add_param(nem_element, platform_endpoint, config[platform_endpoint])
|
||||
transport_endpoint = "transportendpoint"
|
||||
add_param(nem_element, transport_endpoint, config[transport_endpoint])
|
||||
|
||||
# build transport xml
|
||||
transport_type = netif.transport_type
|
||||
if not transport_type:
|
||||
|
@ -220,7 +241,6 @@ def build_xml_files(emane_manager, node):
|
|||
need_raw = True
|
||||
rtype = netif.transport_type
|
||||
|
||||
# build transport XML files depending on type of interfaces involved
|
||||
if need_virtual:
|
||||
build_transport_xml(emane_manager, node, vtype)
|
||||
|
||||
|
@ -270,7 +290,7 @@ def create_phy_xml(emane_model, config, file_path):
|
|||
Create the phy xml document.
|
||||
|
||||
:param core.emane.emanemodel.EmaneModel emane_model: emane model to create phy xml for
|
||||
:param dict config: all current configuration values, mac + phy
|
||||
:param dict config: all current configuration values
|
||||
:param str file_path: path to write file to
|
||||
:return: nothing
|
||||
"""
|
||||
|
@ -287,7 +307,7 @@ def create_mac_xml(emane_model, config, file_path):
|
|||
Create the mac xml document.
|
||||
|
||||
:param core.emane.emanemodel.EmaneModel emane_model: emane model to create phy xml for
|
||||
:param dict config: all current configuration values, mac + phy
|
||||
:param dict config: all current configuration values
|
||||
:param str file_path: path to write file to
|
||||
:return: nothing
|
||||
"""
|
||||
|
@ -299,11 +319,12 @@ def create_mac_xml(emane_model, config, file_path):
|
|||
create_file(mac_element, "mac", file_path)
|
||||
|
||||
|
||||
def create_nem_xml(emane_model, nem_file, transport_definition, mac_definition, phy_definition):
|
||||
def create_nem_xml(emane_model, config, nem_file, transport_definition, mac_definition, phy_definition):
|
||||
"""
|
||||
Create the nem xml document.
|
||||
|
||||
:param core.emane.emanemodel.EmaneModel emane_model: emane model to create phy xml for
|
||||
:param dict config: all current configuration values
|
||||
:param str nem_file: nem file path to write
|
||||
:param str transport_definition: transport file definition path
|
||||
:param str mac_definition: mac file definition path
|
||||
|
@ -311,6 +332,8 @@ def create_nem_xml(emane_model, nem_file, transport_definition, mac_definition,
|
|||
:return: nothing
|
||||
"""
|
||||
nem_element = etree.Element("nem", name="%s NEM" % emane_model.name)
|
||||
if is_external(config):
|
||||
nem_element.set("type", "unstructured")
|
||||
etree.SubElement(nem_element, "transport", definition=transport_definition)
|
||||
etree.SubElement(nem_element, "mac", definition=mac_definition)
|
||||
etree.SubElement(nem_element, "phy", definition=phy_definition)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
}
|
||||
},
|
||||
"root": {
|
||||
"level": "INFO",
|
||||
"level": "DEBUG",
|
||||
"handlers": ["console"]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue