pass over emane code to cleanup methods and some documentation

This commit is contained in:
Blake J. Harnden 2018-03-28 13:58:49 -07:00
parent ef48052d41
commit b7327a5798
9 changed files with 356 additions and 267 deletions

View file

@ -1,5 +1,5 @@
""" """
bypass.py: EMANE Bypass model for CORE EMANE Bypass model for CORE
""" """
from core.emane.emanemodel import EmaneModel from core.emane.emanemodel import EmaneModel
@ -9,8 +9,8 @@ from core.enumerations import ConfigDataTypes
class EmaneBypassModel(EmaneModel): class EmaneBypassModel(EmaneModel):
name = "emane_bypass" name = "emane_bypass"
config_matrix = [ config_matrix = [
("none", ConfigDataTypes.BOOL.value, "0", ("none", ConfigDataTypes.BOOL.value, "0", "True,False",
"True,False", "There are no parameters for the bypass model."), "There are no parameters for the bypass model."),
] ]
# value groupings # value groupings
@ -19,36 +19,55 @@ class EmaneBypassModel(EmaneModel):
def __init__(self, session, object_id=None): def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id) EmaneModel.__init__(self, session, object_id)
def buildnemxmlfiles(self, e, ifc): def build_xml_files(self, emane_manager, interface):
""" """
Build the necessary nem, mac, and phy XMLs in the given path. Build the necessary nem, mac, and phy XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide nXXemane_bypassnem.xml, that file also. Otherwise the WLAN-wide nXXemane_bypassnem.xml,
nXXemane_bypassmac.xml, nXXemane_bypassphy.xml are used. nXXemane_bypassmac.xml, nXXemane_bypassphy.xml are used.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param interface: interface for the emane node
:return: nothing
""" """
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc) values = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None: if values is None:
return return
nemdoc = e.xmldoc("nem")
nem = nemdoc.getElementsByTagName("nem").pop()
nem.setAttribute("name", "BYPASS NEM")
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc)
mactag = nemdoc.createElement("mac")
mactag.setAttribute("definition", self.macxmlname(ifc))
nem.appendChild(mactag)
phytag = nemdoc.createElement("phy")
phytag.setAttribute("definition", self.phyxmlname(ifc))
nem.appendChild(phytag)
e.xmlwrite(nemdoc, self.nemxmlname(ifc))
macdoc = e.xmldoc("mac") # retrieve xml names
mac = macdoc.getElementsByTagName("mac").pop() nem_name = self.nem_name(interface)
mac.setAttribute("name", "BYPASS MAC") mac_name = self.mac_name(interface)
mac.setAttribute("library", "bypassmaclayer") phy_name = self.phy_name(interface)
e.xmlwrite(macdoc, self.macxmlname(ifc))
phydoc = e.xmldoc("phy") # create nem document
phy = phydoc.getElementsByTagName("phy").pop() nem_document = emane_manager.xmldoc("nem")
phy.setAttribute("name", "BYPASS PHY") nem_element = nem_document.getElementsByTagName("nem").pop()
phy.setAttribute("library", "bypassphylayer") nem_element.setAttribute("name", "BYPASS NEM")
e.xmlwrite(phydoc, self.phyxmlname(ifc)) emane_manager.appendtransporttonem(nem_document, nem_element, self.object_id, interface)
# create link to mac definition
mac_element = nem_document.createElement("mac")
mac_element.setAttribute("definition", mac_name)
nem_element.appendChild(mac_element)
# create link to phy definition
phy_element = nem_document.createElement("phy")
phy_element.setAttribute("definition", phy_name)
nem_element.appendChild(phy_element)
# write nem document
emane_manager.xmlwrite(nem_document, nem_name)
# create and write mac document
mac_document = emane_manager.xmldoc("mac")
mac_element = mac_document.getElementsByTagName("mac").pop()
mac_element.setAttribute("name", "BYPASS MAC")
mac_element.setAttribute("library", "bypassmaclayer")
emane_manager.xmlwrite(mac_document, mac_name)
# create and write phy document
phy_document = emane_manager.xmldoc("phy")
phy_element = phy_document.getElementsByTagName("phy").pop()
phy_element.setAttribute("name", "BYPASS PHY")
phy_element.setAttribute("library", "bypassphylayer")
emane_manager.xmlwrite(phy_document, phy_name)

View file

@ -9,10 +9,7 @@ from core.enumerations import ConfigDataTypes
try: try:
from emanesh.events.commeffectevent import CommEffectEvent from emanesh.events.commeffectevent import CommEffectEvent
except ImportError: except ImportError:
try: logger.info("emane 1.2.1 not found")
from emane.events.commeffectevent import CommEffectEvent
except ImportError:
logger.info("emane 0.9.1+ not found")
def convert_none(x): def convert_none(x):
@ -28,10 +25,9 @@ def convert_none(x):
class EmaneCommEffectModel(EmaneModel): class EmaneCommEffectModel(EmaneModel):
# model name
name = "emane_commeffect" name = "emane_commeffect"
# CommEffect parameters
_confmatrix_shim_base = [ config_matrix = [
("filterfile", ConfigDataTypes.STRING.value, "", ("filterfile", ConfigDataTypes.STRING.value, "",
"", "filter file"), "", "filter file"),
("groupid", ConfigDataTypes.UINT32.value, "0", ("groupid", ConfigDataTypes.UINT32.value, "0",
@ -40,54 +36,64 @@ class EmaneCommEffectModel(EmaneModel):
"On,Off", "enable promiscuous mode"), "On,Off", "enable promiscuous mode"),
("receivebufferperiod", ConfigDataTypes.FLOAT.value, "1.0", ("receivebufferperiod", ConfigDataTypes.FLOAT.value, "1.0",
"", "receivebufferperiod"), "", "receivebufferperiod"),
]
_confmatrix_shim_091 = [
("defaultconnectivitymode", ConfigDataTypes.BOOL.value, "1", ("defaultconnectivitymode", ConfigDataTypes.BOOL.value, "1",
"On,Off", "defaultconnectivity"), "On,Off", "defaultconnectivity"),
] ]
_confmatrix_shim = _confmatrix_shim_base + _confmatrix_shim_091
config_matrix = _confmatrix_shim config_groups = "CommEffect SHIM Parameters:1-%d" % len(config_matrix)
# value groupings
config_groups = "CommEffect SHIM Parameters:1-%d" % len(_confmatrix_shim)
def __init__(self, session, object_id=None): def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id) EmaneModel.__init__(self, session, object_id)
def buildnemxmlfiles(self, e, ifc): def build_xml_files(self, emane_manager, interface):
""" """
Build the necessary nem and commeffect XMLs in the given path. Build the necessary nem and commeffect XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide that file also. Otherwise the WLAN-wide
nXXemane_commeffectnem.xml, nXXemane_commeffectshim.xml are used. nXXemane_commeffectnem.xml, nXXemane_commeffectshim.xml are used.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param interface: interface for the emane node
:return: nothing
""" """
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc) values = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None: if values is None:
return return
shimdoc = e.xmldoc("shim")
shim = shimdoc.getElementsByTagName("shim").pop() # retrieve xml names
nem_name = self.nem_name(interface)
shim_name = self.shim_name(interface)
shim_document = emane_manager.xmldoc("shim")
shim = shim_document.getElementsByTagName("shim").pop()
shim.setAttribute("name", "commeffect SHIM") shim.setAttribute("name", "commeffect SHIM")
shim.setAttribute("library", "commeffectshim") shim.setAttribute("library", "commeffectshim")
names = self.getnames() names = self.getnames()
shimnames = list(names[:len(self._confmatrix_shim)]) shim_names = list(names[:len(self.config_matrix)])
shimnames.remove("filterfile") shim_names.remove("filterfile")
# append all shim options (except filterfile) to shimdoc # append all shim options (except filterfile) to shimdoc
map(lambda n: shim.appendChild(e.xmlparam(shimdoc, n, self.valueof(n, values))), shimnames) for name in shim_names:
value = self.valueof(name, values)
param = emane_manager.xmlparam(shim_document, name, value)
shim.appendChild(param)
# empty filterfile is not allowed # empty filterfile is not allowed
ff = self.valueof("filterfile", values) ff = self.valueof("filterfile", values)
if ff.strip() != "": if ff.strip() != "":
shim.appendChild(e.xmlparam(shimdoc, "filterfile", ff)) shim.appendChild(emane_manager.xmlparam(shim_document, "filterfile", ff))
e.xmlwrite(shimdoc, self.shimxmlname(ifc)) emane_manager.xmlwrite(shim_document, shim_name)
nemdoc = e.xmldoc("nem") nem_document = emane_manager.xmldoc("nem")
nem = nemdoc.getElementsByTagName("nem").pop() nem_element = nem_document.getElementsByTagName("nem").pop()
nem.setAttribute("name", "commeffect NEM") nem_element.setAttribute("name", "commeffect NEM")
nem.setAttribute("type", "unstructured") nem_element.setAttribute("type", "unstructured")
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc) emane_manager.appendtransporttonem(nem_document, nem_element, self.object_id, interface)
nem.appendChild(e.xmlshimdefinition(nemdoc, self.shimxmlname(ifc)))
e.xmlwrite(nemdoc, self.nemxmlname(ifc)) shim_xml = emane_manager.xmlshimdefinition(nem_document, shim_name)
nem_element.appendChild(shim_xml)
emane_manager.xmlwrite(nem_document, nem_name)
def linkconfig(self, netif, bw=None, delay=None, loss=None, duplicate=None, jitter=None, netif2=None): def linkconfig(self, netif, bw=None, delay=None, loss=None, duplicate=None, jitter=None, netif2=None):
""" """

View file

@ -33,12 +33,7 @@ try:
from emane.events import LocationEvent from emane.events import LocationEvent
from emane.events.eventserviceexception import EventServiceException from emane.events.eventserviceexception import EventServiceException
except ImportError: except ImportError:
try: logger.info("emane 1.2.1 not found")
from emanesh.events import EventService
from emanesh.events import LocationEvent
from emanesh.events.eventserviceexception import EventServiceException
except ImportError:
logger.info("emane 0.9.1+ not found")
EMANE_MODELS = [ EMANE_MODELS = [
EmaneRfPipeModel, EmaneRfPipeModel,
@ -680,7 +675,7 @@ class EmaneManager(ConfigurableManager):
""" """
for key in sorted(self._emane_nodes.keys()): for key in sorted(self._emane_nodes.keys()):
emane_node = self._emane_nodes[key] emane_node = self._emane_nodes[key]
emane_node.buildnemxmlfiles(self) emane_node.build_xml_files(self)
def appendtransporttonem(self, doc, nem, nodenum, ifc=None): def appendtransporttonem(self, doc, nem, nodenum, ifc=None):
""" """
@ -1061,7 +1056,7 @@ class EmaneGlobalModel(EmaneModel):
def __init__(self, session, object_id=None): def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id) EmaneModel.__init__(self, session, object_id)
def buildnemxmlfiles(self, e, ifc): def build_xml_files(self, emane_manager, interface):
""" """
Build the necessary nem, mac, and phy XMLs in the given path. Build the necessary nem, mac, and phy XMLs in the given path.
""" """

View file

@ -11,35 +11,14 @@ from core.xml import xmlutils
class EmaneModel(WirelessModel): class EmaneModel(WirelessModel):
""" """
EMANE models inherit from this parent class, which takes care of EMANE models inherit from this parent class, which takes care of
handling configuration messages based on the _confmatrix list of handling configuration messages based on the list of
configurable parameters. Helper functions also live here. configurable parameters. Helper functions also live here.
""" """
_prefix = {
"y": 1e-24, # yocto
"z": 1e-21, # zepto
"a": 1e-18, # atto
"f": 1e-15, # femto
"p": 1e-12, # pico
"n": 1e-9, # nano
"u": 1e-6, # micro
"m": 1e-3, # mili
"c": 1e-2, # centi
"d": 1e-1, # deci
"k": 1e3, # kilo
"M": 1e6, # mega
"G": 1e9, # giga
"T": 1e12, # tera
"P": 1e15, # peta
"E": 1e18, # exa
"Z": 1e21, # zetta
"Y": 1e24, # yotta
}
@classmethod @classmethod
def configure_emane(cls, session, config_data): def configure_emane(cls, session, config_data):
""" """
Handle configuration messages for setting up a model. Handle configuration messages for configuring an emane model.
Pass the Emane object as the manager object.
:param core.session.Session session: session to configure emane :param core.session.Session session: session to configure emane
:param core.conf.ConfigData config_data: configuration data for carrying out a configuration :param core.conf.ConfigData config_data: configuration data for carrying out a configuration
@ -55,13 +34,17 @@ class EmaneModel(WirelessModel):
""" """
logger.info("emane model(%s) has no post setup tasks", self.name) logger.info("emane model(%s) has no post setup tasks", self.name)
def buildnemxmlfiles(self, e, ifc): def build_xml_files(self, emane_manager, interface):
""" """
Build the necessary nem, mac, and phy XMLs in the given path. Build the necessary nem, mac, and phy XMLs in the given path.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param interface: interface for the emane node
:return: nothing
""" """
raise NotImplementedError raise NotImplementedError
def buildplatformxmlnementry(self, doc, n, ifc): def build_nem_xml(self, doc, emane_node, interface):
""" """
Build the NEM definition that goes into the platform.xml file. Build the NEM definition that goes into the platform.xml file.
@ -71,93 +54,125 @@ class EmaneModel(WirelessModel):
or per-EmaneNode config (e.g. <nem definition="n1emane_rfpipe.xml" id="1">. or per-EmaneNode config (e.g. <nem definition="n1emane_rfpipe.xml" id="1">.
This can be overriden by a model for NEM flexibility; n is the EmaneNode. This can be overriden by a model for NEM flexibility; n is the EmaneNode.
<nem name="NODE-001" definition="rfpipenem.xml">
:param xml.dom.minidom.Document doc: xml document
:param core.emane.nodes.EmaneNode emane_node: emane node to get information from
:param interface: interface for the emane node
:return: created platform xml
""" """
nem = doc.createElement("nem")
nem.setAttribute("name", ifc.localname)
# if this netif contains a non-standard (per-interface) config, # if this netif contains a non-standard (per-interface) config,
# then we need to use a more specific xml file here # then we need to use a more specific xml file here
nem.setAttribute("definition", self.nemxmlname(ifc)) nem_name = self.nem_name(interface)
nem = doc.createElement("nem")
nem.setAttribute("name", interface.localname)
nem.setAttribute("definition", nem_name)
return nem return nem
def buildplatformxmltransportentry(self, doc, n, ifc): def build_transport_xml(self, doc, emane_node, interface):
""" """
Build the transport definition that goes into the platform.xml file. Build the transport definition that goes into the platform.xml file.
This returns an XML element that will added to the nem definition. This returns an XML element that will be added to the nem definition.
This default method supports raw and virtual transport types, but may be This default method supports raw and virtual transport types, but may be
overriden by a model to support the e.g. pluggable virtual transport. overridden by a model to support the e.g. pluggable virtual transport.
n is the EmaneNode.
""" <transport definition="transvirtual.xml" group="1">
ttype = ifc.transport_type <param name="device" value="n1.0.158" />
if not ttype: </transport>
logger.info("warning: %s interface type unsupported!", ifc.name)
ttype = "raw" :param xml.dom.minidom.Document doc: xml document
:param core.emane.nodes.EmaneNode emane_node: emane node to get information from
:param interface: interface for the emane node
:return: created transport xml
"""
transport_type = interface.transport_type
if not transport_type:
logger.info("warning: %s interface type unsupported!", interface.name)
transport_type = "raw"
transport_name = emane_node.transportxmlname(transport_type)
transport = doc.createElement("transport")
transport.setAttribute("definition", transport_name)
trans = doc.createElement("transport")
trans.setAttribute("definition", n.transportxmlname(ttype))
param = doc.createElement("param") param = doc.createElement("param")
param.setAttribute("name", "device") param.setAttribute("name", "device")
param.setAttribute("value", interface.name)
if ttype == "raw": transport.appendChild(param)
# raw RJ45 name e.g. "eth0" return transport
param.setAttribute("value", ifc.name)
else:
# virtual TAP name e.g. "n3.0.17"
param.setAttribute("value", ifc.localname)
param.setAttribute("value", ifc.name)
trans.appendChild(param) def _basename(self, interface=None):
return trans
def basename(self, interface=None):
""" """
Return the string that other names are based on. Create name that is leveraged for configuration file creation.
If a specific config is stored for a node"s interface, a unique
filename is needed; otherwise the name of the EmaneNode is used. :param interface: interface for this model
:return: basename used for file creation
:rtype: str
""" """
emane = self.session.emane
name = "n%s" % self.object_id name = "n%s" % self.object_id
emane_manager = self.session.emane
if interface is not None: if interface:
nodenum = interface.node.objid node_id = interface.node.objid
# Adamson change - use getifcconfig() to get proper result if emane_manager.getifcconfig(node_id, self.name, None, interface) is not None:
# if emane.getconfig(nodenum, self._name, None)[1] is not None:
if emane.getifcconfig(nodenum, self.name, None, interface) is not None:
name = interface.localname.replace(".", "_") name = interface.localname.replace(".", "_")
return "%s%s" % (name, self.name) return "%s%s" % (name, self.name)
def nemxmlname(self, interface=None): def nem_name(self, interface=None):
""" """
Return the string name for the NEM XML file, e.g. "n3rfpipenem.xml" Return the string name for the NEM XML file, e.g. "n3rfpipenem.xml"
:param interface: interface for this model
:return: nem xml filename
:rtype: str
""" """
basename = self._basename(interface)
append = "" append = ""
if interface and interface.transport_type == "raw": if interface and interface.transport_type == "raw":
append = "_raw" append = "_raw"
return "%snem%s.xml" % (self.basename(interface), append) return "%snem%s.xml" % (basename, append)
def shimxmlname(self, ifc=None): def shim_name(self, interface=None):
""" """
Return the string name for the SHIM XML file, e.g. "commeffectshim.xml" Return the string name for the SHIM XML file, e.g. "commeffectshim.xml"
"""
return "%sshim.xml" % self.basename(ifc)
def macxmlname(self, ifc=None): :param interface: interface for this model
:return: shim xml filename
:rtype: str
"""
return "%sshim.xml" % self._basename(interface)
def mac_name(self, interface=None):
""" """
Return the string name for the MAC XML file, e.g. "n3rfpipemac.xml" Return the string name for the MAC XML file, e.g. "n3rfpipemac.xml"
"""
return "%smac.xml" % self.basename(ifc)
def phyxmlname(self, ifc=None): :param interface: interface for this model
:return: mac xml filename
:rtype: str
"""
return "%smac.xml" % self._basename(interface)
def phy_name(self, interface=None):
""" """
Return the string name for the PHY XML file, e.g. "n3rfpipephy.xml" Return the string name for the PHY XML file, e.g. "n3rfpipephy.xml"
:param interface: interface for this model
:return: phy xml filename
:rtype: str
""" """
return "%sphy.xml" % self.basename(ifc) return "%sphy.xml" % self._basename(interface)
def update(self, moved, moved_netifs): def update(self, moved, moved_netifs):
""" """
invoked from MobilityModel when nodes are moved; this causes Invoked from MobilityModel when nodes are moved; this causes
EMANE location events to be generated for the nodes in the moved emane location events to be generated for the nodes in the moved
list, making EmaneModels compatible with Ns2ScriptedMobility list, making EmaneModels compatible with Ns2ScriptedMobility.
:param bool moved: were nodes moved
:param list moved_netifs: interfaces that were moved
:return:
""" """
try: try:
wlan = self.session.get_object(self.object_id) wlan = self.session.get_object(self.object_id)
@ -168,17 +183,28 @@ class EmaneModel(WirelessModel):
def linkconfig(self, netif, bw=None, delay=None, loss=None, duplicate=None, jitter=None, netif2=None): def linkconfig(self, netif, bw=None, delay=None, loss=None, duplicate=None, jitter=None, netif2=None):
""" """
Invoked when a Link Message is received. Default is unimplemented. Invoked when a Link Message is received. Default is unimplemented.
:param core.netns.vif.Veth netif: interface one
:param bw: bandwidth to set to
:param delay: packet delay to set to
:param loss: packet loss to set to
:param duplicate: duplicate percentage to set to
:param jitter: jitter to set to
:param core.netns.vif.Veth netif2: interface two
:return: nothing
""" """
warntxt = "EMANE model %s does not support link " % self.name logger.warn("emane model(%s) does not support link configuration", self.name)
warntxt += "configuration, dropping Link Message"
logger.warn(warntxt)
@staticmethod @staticmethod
def valuestrtoparamlist(dom, name, value): def value_to_params(doc, name, value):
""" """
Helper to convert a parameter to a paramlist. Helper to convert a parameter to a paramlist. Returns an XML paramlist, or None if the value does not expand to
Returns a an XML paramlist, or None if the value does not expand to
multiple values. multiple values.
:param xml.dom.minidom.Document doc: xml document
:param name: name of element for params
:param str value: value string to convert to tuple
:return: xml document with added params or None, when an invalid value has been provided
""" """
try: try:
values = utils.make_tuple_fromstr(value, str) values = utils.make_tuple_fromstr(value, str)
@ -192,4 +218,4 @@ class EmaneModel(WirelessModel):
if len(values) < 2: if len(values) < 2:
return None return None
return xmlutils.add_param_list_to_parent(dom, parent=None, name=name, values=values) return xmlutils.add_param_list_to_parent(doc, parent=None, name=name, values=values)

View file

@ -16,7 +16,7 @@ class EmaneIeee80211abgModel(EmaneModel):
xml_path = "/usr/share/emane/xml/models/mac/ieee80211abg" xml_path = "/usr/share/emane/xml/models/mac/ieee80211abg"
# MAC parameters # MAC parameters
_confmatrix_mac = [ _config_mac = [
("aifs", ConfigDataTypes.STRING.value, "0:2 1:2 2:2 3:1", "", "arbitration inter frame space (0-4:aifs)"), ("aifs", ConfigDataTypes.STRING.value, "0:2 1:2 2:2 3:1", "", "arbitration inter frame space (0-4:aifs)"),
("channelactivityestimationtimer", ConfigDataTypes.FLOAT.value, "0.1", "", ("channelactivityestimationtimer", ConfigDataTypes.FLOAT.value, "0.1", "",
"Defines channel activity estimation timer in seconds"), "Defines channel activity estimation timer in seconds"),
@ -46,58 +46,69 @@ class EmaneIeee80211abgModel(EmaneModel):
] ]
# PHY parameters from Universal PHY # PHY parameters from Universal PHY
_confmatrix_phy = EmaneUniversalModel.config_matrix _config_phy = EmaneUniversalModel.config_matrix
config_matrix = _confmatrix_mac + _confmatrix_phy config_matrix = _config_mac + _config_phy
# value groupings # value groupings
config_groups = "802.11 MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % ( config_groups = "802.11 MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(config_matrix)) len(_config_mac), len(_config_mac) + 1, len(config_matrix))
def __init__(self, session, object_id=None): def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id) EmaneModel.__init__(self, session, object_id)
def buildnemxmlfiles(self, e, ifc): def build_xml_files(self, emane_manager, interface):
""" """
Build the necessary nem, mac, and phy XMLs in the given path. Build the necessary nem, mac, and phy XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide that file also. Otherwise the WLAN-wide
nXXemane_ieee80211abgnem.xml, nXXemane_ieee80211abgemac.xml, nXXemane_ieee80211abgnem.xml, nXXemane_ieee80211abgemac.xml,
nXXemane_ieee80211abgphy.xml are used. nXXemane_ieee80211abgphy.xml are used.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param interface: interface for the emane node
:return: nothing
""" """
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc) values = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None: if values is None:
return return
nemdoc = e.xmldoc("nem")
nem = nemdoc.getElementsByTagName("nem").pop()
nem.setAttribute("name", "ieee80211abg NEM")
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc)
mactag = nemdoc.createElement("mac")
mactag.setAttribute("definition", self.macxmlname(ifc))
nem.appendChild(mactag)
phytag = nemdoc.createElement("phy")
phytag.setAttribute("definition", self.phyxmlname(ifc))
nem.appendChild(phytag)
e.xmlwrite(nemdoc, self.nemxmlname(ifc))
macdoc = e.xmldoc("mac") # retrieve xml names
mac = macdoc.getElementsByTagName("mac").pop() nem_name = self.nem_name(interface)
mac.setAttribute("name", "ieee80211abg MAC") mac_name = self.mac_name(interface)
mac.setAttribute("library", "ieee80211abgmaclayer") phy_name = self.phy_name(interface)
nem_document = emane_manager.xmldoc("nem")
nem_element = nem_document.getElementsByTagName("nem").pop()
nem_element.setAttribute("name", "ieee80211abg NEM")
emane_manager.appendtransporttonem(nem_document, nem_element, self.object_id, interface)
mac_element = nem_document.createElement("mac")
mac_element.setAttribute("definition", mac_name)
nem_element.appendChild(mac_element)
phy_element = nem_document.createElement("phy")
phy_element.setAttribute("definition", phy_name)
nem_element.appendChild(phy_element)
emane_manager.xmlwrite(nem_document, nem_name)
names = self.getnames() names = self.getnames()
macnames = names[:len(self._confmatrix_mac)] mac_names = names[:len(self._config_mac)]
phynames = names[len(self._confmatrix_mac):] phy_names = names[len(self._config_mac):]
# append all MAC options to macdoc mac_document = emane_manager.xmldoc("mac")
for macname in macnames: mac_element = mac_document.getElementsByTagName("mac").pop()
mac9xnvpairlist = self.get9xmacparamequivalent(macname, values) mac_element.setAttribute("name", "ieee80211abg MAC")
mac_element.setAttribute("library", "ieee80211abgmaclayer")
for name in mac_names:
mac9xnvpairlist = self.get9xmacparamequivalent(name, values)
for nvpair in mac9xnvpairlist: for nvpair in mac9xnvpairlist:
mac.appendChild(e.xmlparam(macdoc, nvpair[0], nvpair[1])) param = emane_manager.xmlparam(mac_document, nvpair[0], nvpair[1])
mac_element.appendChild(param)
emane_manager.xmlwrite(mac_document, mac_name)
e.xmlwrite(macdoc, self.macxmlname(ifc)) phy_document = EmaneUniversalModel.get_phy_doc(emane_manager, self, values, phy_names)
emane_manager.xmlwrite(phy_document, phy_name)
phydoc = EmaneUniversalModel.getphydoc(e, self, values, phynames)
e.xmlwrite(phydoc, self.phyxmlname(ifc))
# #
# TEMP HACK: Account for parameter convention change in EMANE 9.x # TEMP HACK: Account for parameter convention change in EMANE 9.x

View file

@ -15,10 +15,7 @@ from core.enumerations import RegisterTlvs
try: try:
from emane.events import LocationEvent from emane.events import LocationEvent
except ImportError: except ImportError:
try: logger.info("emane 1.2.1 not found")
from emanesh.events import LocationEvent
except ImportError:
logger.info("emane 0.9.1+ not found")
class EmaneNet(PyCoreNet): class EmaneNet(PyCoreNet):
@ -122,26 +119,25 @@ class EmaneNode(EmaneNet):
return ret return ret
for netif in self.netifs(): for netif in self.netifs():
# <nem name="NODE-001" definition="rfpipenem.xml"> nementry = self.model.build_nem_xml(doc, self, netif)
nementry = self.model.buildplatformxmlnementry(doc, self, netif) trans = self.model.build_transport_xml(doc, self, netif)
# <transport definition="transvirtual.xml" group="1">
# <param name="device" value="n1.0.158" />
# </transport>
trans = self.model.buildplatformxmltransportentry(doc, self, netif)
nementry.appendChild(trans) nementry.appendChild(trans)
ret[netif] = nementry ret[netif] = nementry
return ret return ret
def buildnemxmlfiles(self, emane): def build_xml_files(self, emane_manager):
""" """
Let the configured model build the necessary nem, mac, and phy XMLs. Let the configured model build the necessary nem, mac, and phy XMLs.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:return: nothing
""" """
if self.model is None: if self.model is None:
return return
# build XML for overall network (EmaneNode) configs # build XML for overall network (EmaneNode) configs
self.model.buildnemxmlfiles(emane, ifc=None) self.model.build_xml_files(emane_manager, interface=None)
# build XML for specific interface (NEM) configs # build XML for specific interface (NEM) configs
need_virtual = False need_virtual = False
@ -150,7 +146,7 @@ class EmaneNode(EmaneNet):
rtype = "raw" rtype = "raw"
for netif in self.netifs(): for netif in self.netifs():
self.model.buildnemxmlfiles(emane, netif) self.model.build_xml_files(emane_manager, netif)
if "virtual" in netif.transport_type: if "virtual" in netif.transport_type:
need_virtual = True need_virtual = True
vtype = netif.transport_type vtype = netif.transport_type
@ -160,10 +156,10 @@ class EmaneNode(EmaneNet):
# build transport XML files depending on type of interfaces involved # build transport XML files depending on type of interfaces involved
if need_virtual: if need_virtual:
self.buildtransportxml(emane, vtype) self.buildtransportxml(emane_manager, vtype)
if need_raw: if need_raw:
self.buildtransportxml(emane, rtype) self.buildtransportxml(emane_manager, rtype)
def buildtransportxml(self, emane, transport_type): def buildtransportxml(self, emane, transport_type):
""" """

View file

@ -15,7 +15,7 @@ class EmaneRfPipeModel(EmaneModel):
# configuration parameters are # configuration parameters are
# ( "name", "type", "default", "possible-value-list", "caption") # ( "name", "type", "default", "possible-value-list", "caption")
# MAC parameters # MAC parameters
_confmatrix_mac = [ _config_mac = [
("datarate", ConfigDataTypes.UINT64.value, "1M", "", "data rate (bps)"), ("datarate", ConfigDataTypes.UINT64.value, "1M", "", "data rate (bps)"),
("delay", ConfigDataTypes.FLOAT.value, "0.0", "", "transmission delay (sec)"), ("delay", ConfigDataTypes.FLOAT.value, "0.0", "", "transmission delay (sec)"),
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "True,False", "enable promiscuous mode"), ("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "True,False", "enable promiscuous mode"),
@ -31,52 +31,65 @@ class EmaneRfPipeModel(EmaneModel):
] ]
# PHY parameters from Universal PHY # PHY parameters from Universal PHY
_confmatrix_phy = EmaneUniversalModel.config_matrix _config_phy = EmaneUniversalModel.config_matrix
config_matrix = _confmatrix_mac + _confmatrix_phy config_matrix = _config_mac + _config_phy
# value groupings # value groupings
config_groups = "RF-PIPE MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % ( config_groups = "RF-PIPE MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(config_matrix)) len(_config_mac), len(_config_mac) + 1, len(config_matrix))
def __init__(self, session, object_id=None): def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id) EmaneModel.__init__(self, session, object_id)
def buildnemxmlfiles(self, e, ifc): def build_xml_files(self, emane_manager, interface):
""" """
Build the necessary nem, mac, and phy XMLs in the given path. Build the necessary nem, mac, and phy XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide nXXemane_rfpipenem.xml, that file also. Otherwise the WLAN-wide nXXemane_rfpipenem.xml,
nXXemane_rfpipemac.xml, nXXemane_rfpipephy.xml are used. nXXemane_rfpipemac.xml, nXXemane_rfpipephy.xml are used.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param interface: interface for the emane node
:return: nothing
""" """
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc) values = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None: if values is None:
return return
nemdoc = e.xmldoc("nem") # retrieve xml names
nem = nemdoc.getElementsByTagName("nem").pop() nem_name = self.nem_name(interface)
nem.setAttribute("name", "RF-PIPE NEM") mac_name = self.mac_name(interface)
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc) phy_name = self.phy_name(interface)
mactag = nemdoc.createElement("mac")
mactag.setAttribute("definition", self.macxmlname(ifc)) nem_document = emane_manager.xmldoc("nem")
nem.appendChild(mactag) nem_element = nem_document.getElementsByTagName("nem").pop()
phytag = nemdoc.createElement("phy") nem_element.setAttribute("name", "RF-PIPE NEM")
phytag.setAttribute("definition", self.phyxmlname(ifc)) emane_manager.appendtransporttonem(nem_document, nem_element, self.object_id, interface)
nem.appendChild(phytag)
e.xmlwrite(nemdoc, self.nemxmlname(ifc)) mac_element = nem_document.createElement("mac")
mac_element.setAttribute("definition", mac_name)
nem_element.appendChild(mac_element)
phy_element = nem_document.createElement("phy")
phy_element.setAttribute("definition", phy_name)
nem_element.appendChild(phy_element)
emane_manager.xmlwrite(nem_document, nem_name)
names = list(self.getnames()) names = list(self.getnames())
macnames = names[:len(self._confmatrix_mac)] mac_name = names[:len(self._config_mac)]
phynames = names[len(self._confmatrix_mac):] phy_names = names[len(self._config_mac):]
macdoc = e.xmldoc("mac") mac_document = emane_manager.xmldoc("mac")
mac = macdoc.getElementsByTagName("mac").pop() mac_element = mac_document.getElementsByTagName("mac").pop()
mac.setAttribute("name", "RF-PIPE MAC") mac_element.setAttribute("name", "RF-PIPE MAC")
mac.setAttribute("library", "rfpipemaclayer") mac_element.setAttribute("library", "rfpipemaclayer")
for name in mac_name:
value = self.valueof(name, values)
param = emane_manager.xmlparam(mac_document, name, value)
mac_element.appendChild(param)
emane_manager.xmlwrite(mac_document, mac_name)
# append MAC options to macdoc phy_document = EmaneUniversalModel.get_phy_doc(emane_manager, self, values, phy_names)
map(lambda n: mac.appendChild(e.xmlparam(macdoc, n, self.valueof(n, values))), macnames) emane_manager.xmlwrite(phy_document, phy_name)
e.xmlwrite(macdoc, self.macxmlname(ifc))
phydoc = EmaneUniversalModel.getphydoc(e, self, values, phynames)
e.xmlwrite(phydoc, self.phyxmlname(ifc))

View file

@ -20,7 +20,7 @@ class EmaneTdmaModel(EmaneModel):
default_schedule = os.path.join(constants.CORE_DATA_DIR, "examples", "tdma", "schedule.xml") default_schedule = os.path.join(constants.CORE_DATA_DIR, "examples", "tdma", "schedule.xml")
# MAC parameters # MAC parameters
_confmatrix_mac = [ _config_mac = [
(schedule_name, ConfigDataTypes.STRING.value, default_schedule, "", "TDMA schedule file"), (schedule_name, ConfigDataTypes.STRING.value, default_schedule, "", "TDMA schedule file"),
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "True,False", "enable promiscuous mode"), ("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "True,False", "enable promiscuous mode"),
("flowcontrolenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "enable traffic flow control"), ("flowcontrolenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "enable traffic flow control"),
@ -46,13 +46,13 @@ class EmaneTdmaModel(EmaneModel):
] ]
# PHY parameters from Universal PHY # PHY parameters from Universal PHY
_confmatrix_phy = EmaneUniversalModel.config_matrix _config_phy = EmaneUniversalModel.config_matrix
config_matrix = _confmatrix_mac + _confmatrix_phy config_matrix = _config_mac + _config_phy
# value groupings # value groupings
config_groups = "TDMA MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % ( config_groups = "TDMA MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(config_matrix)) len(_config_mac), len(_config_mac) + 1, len(config_matrix))
def __init__(self, session, object_id=None): def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id) EmaneModel.__init__(self, session, object_id)
@ -76,47 +76,57 @@ class EmaneTdmaModel(EmaneModel):
logger.info("setting up tdma schedule: schedule(%s) device(%s)", schedule, event_device) logger.info("setting up tdma schedule: schedule(%s) device(%s)", schedule, event_device)
utils.check_cmd(["emaneevent-tdmaschedule", "-i", event_device, schedule]) utils.check_cmd(["emaneevent-tdmaschedule", "-i", event_device, schedule])
def buildnemxmlfiles(self, e, ifc): def build_xml_files(self, emane_manager, interface):
""" """
Build the necessary nem, mac, and phy XMLs in the given path. Build the necessary nem, mac, and phy XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide nXXemane_tdmanem.xml, that file also. Otherwise the WLAN-wide nXXemane_tdmanem.xml,
nXXemane_tdmamac.xml, nXXemane_tdmaphy.xml are used. nXXemane_tdmamac.xml, nXXemane_tdmaphy.xml are used.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param interface: interface for the emane node
:return: nothing
""" """
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc) values = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None: if values is None:
return return
nemdoc = e.xmldoc("nem") # retrieve xml names
nem = nemdoc.getElementsByTagName("nem").pop() nem_name = self.nem_name(interface)
nem.setAttribute("name", "TDMA NEM") mac_name = self.mac_name(interface)
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc) phy_name = self.phy_name(interface)
mactag = nemdoc.createElement("mac")
mactag.setAttribute("definition", self.macxmlname(ifc)) nem_document = emane_manager.xmldoc("nem")
nem.appendChild(mactag) nem_element = nem_document.getElementsByTagName("nem").pop()
phytag = nemdoc.createElement("phy") nem_element.setAttribute("name", "TDMA NEM")
phytag.setAttribute("definition", self.phyxmlname(ifc)) emane_manager.appendtransporttonem(nem_document, nem_element, self.object_id, interface)
nem.appendChild(phytag)
e.xmlwrite(nemdoc, self.nemxmlname(ifc)) mac_element = nem_document.createElement("mac")
mac_element.setAttribute("definition", mac_name)
nem_element.appendChild(mac_element)
phy_element = nem_document.createElement("phy")
phy_element.setAttribute("definition", phy_name)
nem_element.appendChild(phy_element)
emane_manager.xmlwrite(nem_document, nem_name)
names = list(self.getnames()) names = list(self.getnames())
macnames = names[:len(self._confmatrix_mac)] mac_names = names[:len(self._config_mac)]
phynames = names[len(self._confmatrix_mac):] phy_names = names[len(self._config_mac):]
# make any changes to the mac/phy names here to e.g. exclude them from the XML output # make any changes to the mac/phy names here to e.g. exclude them from the XML output
macnames.remove(EmaneTdmaModel.schedule_name) mac_names.remove(EmaneTdmaModel.schedule_name)
macdoc = e.xmldoc("mac") mac_document = emane_manager.xmldoc("mac")
mac = macdoc.getElementsByTagName("mac").pop() mac_element = mac_document.getElementsByTagName("mac").pop()
mac.setAttribute("name", "TDMA MAC") mac_element.setAttribute("name", "TDMA MAC")
mac.setAttribute("library", "tdmaeventschedulerradiomodel") mac_element.setAttribute("library", "tdmaeventschedulerradiomodel")
# append MAC options to macdoc for name in mac_names:
for name in macnames:
value = self.valueof(name, values) value = self.valueof(name, values)
param = e.xmlparam(macdoc, name, value) param = emane_manager.xmlparam(mac_document, name, value)
mac.appendChild(param) mac_element.appendChild(param)
emane_manager.xmlwrite(mac_document, mac_name)
e.xmlwrite(macdoc, self.macxmlname(ifc)) phydoc = EmaneUniversalModel.get_phy_doc(emane_manager, self, values, phy_names)
emane_manager.xmlwrite(phydoc, phy_name)
phydoc = EmaneUniversalModel.getphydoc(e, self, values, phynames)
e.xmlwrite(phydoc, self.phyxmlname(ifc))

View file

@ -13,9 +13,6 @@ class EmaneUniversalModel(EmaneModel):
not instantiated. not instantiated.
""" """
def __init__(self, session, object_id=None):
raise NotImplemented("Cannot use this class directly")
name = "emane_universal" name = "emane_universal"
_xmlname = "universalphy" _xmlname = "universalphy"
_xmllibrary = "universalphylayer" _xmllibrary = "universalphylayer"
@ -53,22 +50,38 @@ class EmaneUniversalModel(EmaneModel):
("txpower", ConfigDataTypes.FLOAT.value, "0.0", "", "transmit power (dBm)"), ("txpower", ConfigDataTypes.FLOAT.value, "0.0", "", "transmit power (dBm)"),
] ]
def __init__(self, session, object_id=None):
raise NotImplemented("Cannot use this class directly")
@classmethod @classmethod
def getphydoc(cls, e, mac, values, phynames): def get_phy_doc(cls, emane_manager, emane_model, values, phy_names):
phydoc = e.xmldoc("phy") """
phy = phydoc.getElementsByTagName("phy").pop() Create a phy doc for a model based on the universal model.
phy.setAttribute("name", cls._xmlname)
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param core.emane.emanemodel.EmaneModel emane_model: model to create phy doc for
:param tuple values: emane model configuration values
:param phy_names: names for phy configuration values
:return:
"""
phy_document = emane_manager.xmldoc("phy")
phy_element = phy_document.getElementsByTagName("phy").pop()
phy_element.setAttribute("name", cls._xmlname)
name = "frequencyofinterest" name = "frequencyofinterest"
value = mac.valueof(name, values) value = emane_model.valueof(name, values)
frequencies = cls.valuestrtoparamlist(phydoc, name, value) frequencies = cls.value_to_params(phy_document, name, value)
if frequencies: if frequencies:
phynames = list(phynames) phy_names = list(phy_names)
phynames.remove("frequencyofinterest") phy_names.remove("frequencyofinterest")
# append all PHY options to phydoc # append all PHY options to phydoc
map(lambda n: phy.appendChild(e.xmlparam(phydoc, n, mac.valueof(n, values))), phynames) for name in phy_names:
if frequencies: value = emane_model.valueof(name, values)
phy.appendChild(frequencies) param = emane_manager.xmlparam(phy_document, name, value)
phy_element.appendChild(param)
return phydoc if frequencies:
phy_element.appendChild(frequencies)
return phy_document