effort to consolidate logic for emane models, to avoid redundancy for defining a new model

This commit is contained in:
Blake J. Harnden 2018-03-29 13:32:06 -07:00
parent 81840e501c
commit 9ce8233bc3
7 changed files with 134 additions and 294 deletions

View file

@ -8,66 +8,15 @@ from core.enumerations import ConfigDataTypes
class EmaneBypassModel(EmaneModel):
name = "emane_bypass"
config_matrix = [
library = "bypassmaclayer"
config_ignore = {"none"}
_config_mac = [
("none", ConfigDataTypes.BOOL.value, "0", "True,False",
"There are no parameters for the bypass model."),
]
_config_phy = []
# value groupings
config_groups = "Bypass Parameters:1-1"
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
def build_xml_files(self, emane_manager, interface):
"""
Build the necessary nem, mac, and phy XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide nXXemane_bypassnem.xml,
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 = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None:
return
# retrieve xml names
nem_name = self.nem_name(interface)
mac_name = self.mac_name(interface)
phy_name = self.phy_name(interface)
# create nem document
nem_document = emane_manager.xmldoc("nem")
nem_element = nem_document.getElementsByTagName("nem").pop()
nem_element.setAttribute("name", "BYPASS NEM")
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)
@property
def config_groups(self):
return "Bypass Parameters:1-1"

View file

@ -28,22 +28,16 @@ class EmaneCommEffectModel(EmaneModel):
name = "emane_commeffect"
config_matrix = [
("filterfile", ConfigDataTypes.STRING.value, "",
"", "filter file"),
("groupid", ConfigDataTypes.UINT32.value, "0",
"", "NEM Group ID"),
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0",
"On,Off", "enable promiscuous mode"),
("receivebufferperiod", ConfigDataTypes.FLOAT.value, "1.0",
"", "receivebufferperiod"),
("defaultconnectivitymode", ConfigDataTypes.BOOL.value, "1",
"On,Off", "defaultconnectivity"),
("filterfile", ConfigDataTypes.STRING.value, "", "", "filter file"),
("groupid", ConfigDataTypes.UINT32.value, "0", "", "NEM Group ID"),
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "On,Off", "enable promiscuous mode"),
("receivebufferperiod", ConfigDataTypes.FLOAT.value, "1.0", "", "receivebufferperiod"),
("defaultconnectivitymode", ConfigDataTypes.BOOL.value, "1", "On,Off", "defaultconnectivity"),
]
config_groups = "CommEffect SHIM Parameters:1-%d" % len(config_matrix)
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
@property
def config_groups(self):
return "CommEffect SHIM Parameters:1-%d" % len(self.config_matrix)
def build_xml_files(self, emane_manager, interface):
"""

View file

@ -3,6 +3,7 @@ Defines Emane Models used within CORE.
"""
from core import logger
from core.emane.universal import EmaneUniversalModel
from core.misc import utils
from core.mobility import WirelessModel
from core.xml import xmlutils
@ -14,6 +15,98 @@ class EmaneModel(WirelessModel):
handling configuration messages based on the list of
configurable parameters. Helper functions also live here.
"""
_config_mac = []
_config_phy = EmaneUniversalModel.config_matrix
library = None
config_ignore = set()
def __init__(self, session, object_id=None):
WirelessModel.__init__(self, session, object_id)
@property
def config_matrix(self):
return self._config_mac + self._config_phy
@property
def config_groups(self):
mac_len = len(self._config_mac)
config_len = len(self.config_matrix)
return "MAC Parameters:1-%d|PHY Parameters:%d-%d" % (mac_len, mac_len + 1, config_len)
def build_xml_files(self, emane_manager, interface):
"""
Builds xml files for emane. Includes a nem.xml file that points to both mac.xml and phy.xml definitions.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param interface: interface for the emane node
:return: nothing
"""
# retrieve configuration values
values = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None:
return
# create document and write to disk
nem_name = self.nem_name(interface)
nem_document = self.create_nem_doc(emane_manager, interface)
emane_manager.xmlwrite(nem_document, nem_name)
# create mac document and write to disk
mac_name = self.mac_name(interface)
mac_document = self.create_mac_doc(emane_manager, values)
if mac_document:
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)
if phy_document:
emane_manager.xmlwrite(phy_document, phy_name)
def create_nem_doc(self, emane_manager, interface):
mac_name = self.mac_name(interface)
phy_name = self.phy_name(interface)
nem_document = emane_manager.xmldoc("nem")
nem_element = nem_document.getElementsByTagName("nem").pop()
nem_element.setAttribute("name", "%s NEM" % self.name)
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)
return nem_document
def create_mac_doc(self, emane_manager, values):
names = list(self.getnames())
mac_names = names[:len(self._config_mac)]
mac_document = emane_manager.xmldoc("mac")
mac_element = mac_document.getElementsByTagName("mac").pop()
mac_element.setAttribute("name", "%s MAC" % self.name)
if not self.library:
raise ValueError("must define emane model library")
mac_element.setAttribute("library", self.library)
for name in mac_names:
if name in self.config_ignore:
continue
value = self.valueof(name, values)
param = emane_manager.xmlparam(mac_document, name, value)
mac_element.appendChild(param)
return mac_document
def create_phy_doc(self, emane_manager, values):
names = list(self.getnames())
phy_names = names[len(self._config_mac):]
return EmaneUniversalModel.get_phy_doc(emane_manager, self, values, phy_names)
@classmethod
def configure_emane(cls, session, config_data):
@ -34,16 +127,6 @@ class EmaneModel(WirelessModel):
"""
logger.info("emane model(%s) has no post setup tasks", self.name)
def build_xml_files(self, emane_manager, interface):
"""
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
def build_nem_xml(self, doc, emane_node, interface):
"""
Build the NEM definition that goes into the platform.xml file.

View file

@ -3,19 +3,19 @@ ieee80211abg.py: EMANE IEEE 802.11abg model for CORE
"""
from core.emane.emanemodel import EmaneModel
from core.emane.universal import EmaneUniversalModel
from core.enumerations import ConfigDataTypes
class EmaneIeee80211abgModel(EmaneModel):
# model name
name = "emane_ieee80211abg"
library = "ieee80211abgmaclayer"
# mac configuration
_80211rates = "1 1 Mbps,2 2 Mbps,3 5.5 Mbps,4 11 Mbps,5 6 Mbps," + \
"6 9 Mbps,7 12 Mbps,8 18 Mbps,9 24 Mbps,10 36 Mbps,11 48 Mbps," + \
"12 54 Mbps"
xml_path = "/usr/share/emane/xml/models/mac/ieee80211abg"
# MAC parameters
_config_mac = [
("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", "",
@ -45,97 +45,43 @@ class EmaneIeee80211abgModel(EmaneModel):
("wmmenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "WiFi Multimedia (WMM)"),
]
# PHY parameters from Universal PHY
_config_phy = EmaneUniversalModel.config_matrix
config_matrix = _config_mac + _config_phy
# value groupings
config_groups = "802.11 MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_config_mac), len(_config_mac) + 1, len(config_matrix))
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
def build_xml_files(self, emane_manager, interface):
"""
Build the necessary nem, mac, and phy XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide
nXXemane_ieee80211abgnem.xml, nXXemane_ieee80211abgemac.xml,
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 = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None:
return
# retrieve xml names
nem_name = self.nem_name(interface)
mac_name = self.mac_name(interface)
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)
def create_mac_doc(self, emane_manager, values):
names = self.getnames()
mac_names = names[:len(self._config_mac)]
phy_names = names[len(self._config_mac):]
mac_document = emane_manager.xmldoc("mac")
mac_element = mac_document.getElementsByTagName("mac").pop()
mac_element.setAttribute("name", "ieee80211abg MAC")
mac_element.setAttribute("library", "ieee80211abgmaclayer")
mac_element.setAttribute("name", "%s MAC" % self.name)
mac_element.setAttribute("library", self.library)
for name in mac_names:
mac9xnvpairlist = self.get9xmacparamequivalent(name, values)
for nvpair in mac9xnvpairlist:
param = emane_manager.xmlparam(mac_document, nvpair[0], nvpair[1])
mac_element.appendChild(param)
emane_manager.xmlwrite(mac_document, mac_name)
return mac_document
phy_document = EmaneUniversalModel.get_phy_doc(emane_manager, self, values, phy_names)
emane_manager.xmlwrite(phy_document, phy_name)
#
# TEMP HACK: Account for parameter convention change in EMANE 9.x
# This allows CORE to preserve the entry layout for the mac "category" parameters
# and work with EMANE 9.x onwards.
#
def get9xmacparamequivalent(self, macname, values):
def get9xmacparamequivalent(self, mac_name, values):
"""
This accounts for current config values labeled value0, value1, value2, etc.
Generate a list of 80211abg mac parameters in 0.9.x layout for a given mac parameter
in 8.x layout.For mac category parameters, the list returned will contain the four
equivalent 9.x parameter and value pairs. Otherwise, the list returned will only
contain a single name and value pair.
"""
nvpairlist = []
macparmval = self.valueof(macname, values)
macparmval = self.valueof(mac_name, values)
if macname in ["queuesize", "aifs", "cwmin", "cwmax", "txop", "retrylimit", "msdu"]:
if mac_name in ["queuesize", "aifs", "cwmin", "cwmax", "txop", "retrylimit", "msdu"]:
for catval in macparmval.split():
idx_and_val = catval.split(":")
idx = int(idx_and_val[0])
val = idx_and_val[1]
# aifs and tx are in microseconds. Convert to seconds.
if macname in ["aifs", "txop"]:
if mac_name in ["aifs", "txop"]:
val = "%f" % (float(val) * 1e-6)
name9x = "%s%d" % (macname, idx)
name9x = "%s%d" % (mac_name, idx)
nvpairlist.append([name9x, val])
else:
nvpairlist.append([macname, macparmval])
nvpairlist.append([mac_name, macparmval])
return nvpairlist

View file

@ -3,18 +3,16 @@ rfpipe.py: EMANE RF-PIPE model for CORE
"""
from core.emane.emanemodel import EmaneModel
from core.emane.universal import EmaneUniversalModel
from core.enumerations import ConfigDataTypes
class EmaneRfPipeModel(EmaneModel):
# model name
name = "emane_rfpipe"
xml_path = "/usr/share/emane/xml/models/mac/rfpipe"
library = "rfpipemaclayer"
# configuration parameters are
# ( "name", "type", "default", "possible-value-list", "caption")
# MAC parameters
# mac configuration
xml_path = "/usr/share/emane/xml/models/mac/rfpipe"
_config_mac = [
("datarate", ConfigDataTypes.UINT64.value, "1M", "", "data rate (bps)"),
("delay", ConfigDataTypes.FLOAT.value, "0.0", "", "transmission delay (sec)"),
@ -29,67 +27,3 @@ class EmaneRfPipeModel(EmaneModel):
("radiometricreportinterval", ConfigDataTypes.FLOAT.value, "1.0", "",
"R2RI radio metric report interval (sec)"),
]
# PHY parameters from Universal PHY
_config_phy = EmaneUniversalModel.config_matrix
config_matrix = _config_mac + _config_phy
# value groupings
config_groups = "RF-PIPE MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_config_mac), len(_config_mac) + 1, len(config_matrix))
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
def build_xml_files(self, emane_manager, interface):
"""
Build the necessary nem, mac, and phy XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide nXXemane_rfpipenem.xml,
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 = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None:
return
# retrieve xml names
nem_name = self.nem_name(interface)
mac_name = self.mac_name(interface)
phy_name = self.phy_name(interface)
nem_document = emane_manager.xmldoc("nem")
nem_element = nem_document.getElementsByTagName("nem").pop()
nem_element.setAttribute("name", "RF-PIPE 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 = list(self.getnames())
mac_names = names[:len(self._config_mac)]
phy_names = names[len(self._config_mac):]
mac_document = emane_manager.xmldoc("mac")
mac_element = mac_document.getElementsByTagName("mac").pop()
mac_element.setAttribute("name", "RF-PIPE MAC")
mac_element.setAttribute("library", "rfpipemaclayer")
for name in mac_names:
value = self.valueof(name, values)
param = emane_manager.xmlparam(mac_document, name, value)
mac_element.appendChild(param)
emane_manager.xmlwrite(mac_document, mac_name)
phy_document = EmaneUniversalModel.get_phy_doc(emane_manager, self, values, phy_names)
emane_manager.xmlwrite(phy_document, phy_name)

View file

@ -7,7 +7,6 @@ import os
from core import constants
from core import logger
from core.emane.emanemodel import EmaneModel
from core.emane.universal import EmaneUniversalModel
from core.enumerations import ConfigDataTypes
from core.misc import utils
@ -15,11 +14,13 @@ from core.misc import utils
class EmaneTdmaModel(EmaneModel):
# model name
name = "emane_tdma"
library = "tdmaeventschedulerradiomodel"
# mac configuration
xml_path = "/usr/share/emane/xml/models/mac/tdmaeventscheduler"
schedule_name = "schedule"
default_schedule = os.path.join(constants.CORE_DATA_DIR, "examples", "tdma", "schedule.xml")
# MAC parameters
config_ignore = {schedule_name}
_config_mac = [
(schedule_name, ConfigDataTypes.STRING.value, default_schedule, "", "TDMA schedule file"),
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "True,False", "enable promiscuous mode"),
@ -45,18 +46,6 @@ class EmaneTdmaModel(EmaneModel):
"enable strict dequeueing to specified queues only"),
]
# PHY parameters from Universal PHY
_config_phy = EmaneUniversalModel.config_matrix
config_matrix = _config_mac + _config_phy
# value groupings
config_groups = "TDMA MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_config_mac), len(_config_mac) + 1, len(config_matrix))
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
def post_startup(self, emane_manager):
"""
Logic to execute after the emane manager is finished with startup.
@ -68,65 +57,10 @@ class EmaneTdmaModel(EmaneModel):
values = emane_manager.getconfig(self.object_id, self.name, self.getdefaultvalues())[1]
if values is None:
return
schedule = self.valueof(EmaneTdmaModel.schedule_name, values)
schedule = self.valueof(self.schedule_name, values)
event_device = emane_manager.event_device
# initiate tdma schedule
logger.info("setting up tdma schedule: schedule(%s) device(%s)", schedule, event_device)
utils.check_cmd(["emaneevent-tdmaschedule", "-i", event_device, schedule])
def build_xml_files(self, emane_manager, interface):
"""
Build the necessary nem, mac, and phy XMLs in the given path.
If an individual NEM has a nonstandard config, we need to build
that file also. Otherwise the WLAN-wide nXXemane_tdmanem.xml,
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 = emane_manager.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), interface)
if values is None:
return
# retrieve xml names
nem_name = self.nem_name(interface)
mac_name = self.mac_name(interface)
phy_name = self.phy_name(interface)
nem_document = emane_manager.xmldoc("nem")
nem_element = nem_document.getElementsByTagName("nem").pop()
nem_element.setAttribute("name", "TDMA 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 = list(self.getnames())
mac_names = names[:len(self._config_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
mac_names.remove(EmaneTdmaModel.schedule_name)
mac_document = emane_manager.xmldoc("mac")
mac_element = mac_document.getElementsByTagName("mac").pop()
mac_element.setAttribute("name", "TDMA MAC")
mac_element.setAttribute("library", "tdmaeventschedulerradiomodel")
for name in mac_names:
value = self.valueof(name, values)
param = emane_manager.xmlparam(mac_document, name, value)
mac_element.appendChild(param)
emane_manager.xmlwrite(mac_document, mac_name)
phydoc = EmaneUniversalModel.get_phy_doc(emane_manager, self, values, phy_names)
emane_manager.xmlwrite(phydoc, phy_name)

View file

@ -14,10 +14,10 @@ class EmaneUniversalModel(EmaneModel):
"""
name = "emane_universal"
_xmlname = "universalphy"
_xmllibrary = "universalphylayer"
# universal PHY parameters
_xmlname = "universalphy"
_xmllibrary = "universalphylayer"
config_matrix = [
("bandwidth", ConfigDataTypes.UINT64.value, "1M", "", "rf bandwidth (Hz)"),
("fading.model", ConfigDataTypes.STRING.value, "none", "none,event,nakagami", "Defines fading model"),