added support for emane manifest parsing into core compatible information, refactoring of emane code to align with its usage

This commit is contained in:
Blake J. Harnden 2018-03-30 12:08:33 -07:00
parent 8963ef51e3
commit fd32e1cf78
7 changed files with 271 additions and 259 deletions

View file

@ -8,20 +8,23 @@ from core.enumerations import ConfigDataTypes
class EmaneBypassModel(emanemodel.EmaneModel): class EmaneBypassModel(emanemodel.EmaneModel):
name = "emane_bypass" name = "emane_bypass"
library = "bypassmaclayer"
# values to ignore, when writing xml files
config_ignore = {"none"} config_ignore = {"none"}
_config_mac = [
# mac definitions
mac_library = "bypassmaclayer"
config_mac = [
("none", ConfigDataTypes.BOOL.value, "0", "True,False", ("none", ConfigDataTypes.BOOL.value, "0", "True,False",
"There are no parameters for the bypass model."), "There are no parameters for the bypass model."),
] ]
_config_phy = []
config_matrix = _config_mac + _config_phy
config_groups = "Bypass Parameters:1-1"
def create_phy_doc(self, emane_manager, values): # phy definitions
phy_document = emane_manager.xmldoc("phy") phy_library = "bypassphylayer"
phy_element = phy_document.getElementsByTagName("phy").pop() config_phy = []
phy_element.setAttribute("name", "%s PHY" % self.name)
phy_element.setAttribute("library", "bypassphylayer") # defines overall config
return phy_document config_matrix = config_mac + config_phy
# gui display tabs
config_groups = "Bypass Parameters:1-1"

View file

@ -3,8 +3,8 @@ commeffect.py: EMANE CommEffect model for CORE
""" """
from core import logger from core import logger
from core.emane import emanemanifest
from core.emane import emanemodel from core.emane import emanemodel
from core.enumerations import ConfigDataTypes
try: try:
from emane.events.commeffectevent import CommEffectEvent from emane.events.commeffectevent import CommEffectEvent
@ -27,13 +27,11 @@ def convert_none(x):
class EmaneCommEffectModel(emanemodel.EmaneModel): class EmaneCommEffectModel(emanemodel.EmaneModel):
name = "emane_commeffect" name = "emane_commeffect"
config_matrix = [ shim_library = "commeffectshim"
("filterfile", ConfigDataTypes.STRING.value, "", "", "filter file"), shim_xml = "/usr/share/emane/manifest/commeffectshim.xml"
("groupid", ConfigDataTypes.UINT32.value, "0", "", "NEM Group ID"), shim_defaults = {}
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "On,Off", "enable promiscuous mode"), config_shim = emanemanifest.parse(shim_xml, shim_defaults)
("receivebufferperiod", ConfigDataTypes.FLOAT.value, "1.0", "", "receivebufferperiod"), config_matrix = config_shim
("defaultconnectivitymode", ConfigDataTypes.BOOL.value, "1", "On,Off", "defaultconnectivity"),
]
config_groups = "CommEffect SHIM Parameters:1-%d" % len(config_matrix) config_groups = "CommEffect SHIM Parameters:1-%d" % len(config_matrix)
@ -56,30 +54,9 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
nem_name = self.nem_name(interface) nem_name = self.nem_name(interface)
shim_name = self.shim_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("library", "commeffectshim")
names = self.getnames()
shim_names = list(names[:len(self.config_matrix)])
shim_names.remove("filterfile")
# append all shim options (except filterfile) to shimdoc
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
ff = self.valueof("filterfile", values)
if ff.strip() != "":
shim.appendChild(emane_manager.xmlparam(shim_document, "filterfile", ff))
emane_manager.xmlwrite(shim_document, shim_name)
nem_document = emane_manager.xmldoc("nem") nem_document = emane_manager.xmldoc("nem")
nem_element = nem_document.getElementsByTagName("nem").pop() nem_element = nem_document.getElementsByTagName("nem").pop()
nem_element.setAttribute("name", "commeffect NEM") nem_element.setAttribute("name", "%s NEM" % self.name)
nem_element.setAttribute("type", "unstructured") nem_element.setAttribute("type", "unstructured")
emane_manager.appendtransporttonem(nem_document, nem_element, self.object_id, interface) emane_manager.appendtransporttonem(nem_document, nem_element, self.object_id, interface)
@ -87,6 +64,27 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
nem_element.appendChild(shim_xml) nem_element.appendChild(shim_xml)
emane_manager.xmlwrite(nem_document, nem_name) 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)
param = emane_manager.xmlparam(shim_document, name, value)
shim_element.appendChild(param)
# empty filterfile is not allowed
ff = self.valueof("filterfile", values)
if ff.strip() != "":
shim_element.appendChild(emane_manager.xmlparam(shim_document, "filterfile", ff))
emane_manager.xmlwrite(shim_document, shim_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):
""" """
Generate CommEffect events when a Link Message is received having Generate CommEffect events when a Link Message is received having

View file

@ -0,0 +1,112 @@
from core import logger
from core.enumerations import ConfigDataTypes
try:
from emane.shell import manifest
except ImportError:
logger.info("emane 1.2.1 not found")
def _type_value(config_type):
"""
Convert emane configuration type to core configuration value.
:param str config_type: emane configuration type
:return:
"""
config_type = config_type.upper()
if config_type == "DOUBLE":
config_type = "FLOAT"
return ConfigDataTypes[config_type].value
def _get_possible(config_type, config_regex):
"""
Retrieve possible config value options based on emane regexes.
:param str config_type: emane configuration type
:param str config_regex: emane configuration regex
:return: a string listing comma delimited values, if needed, empty string otherwise
:rtype: str
"""
if config_type == "bool":
return "On,Off"
if config_type == "string" and config_regex:
possible = config_regex[2:-2]
possible = possible.replace("|", ",")
return possible
return ""
def _get_default(config_type_name, config_value):
"""
Convert default configuration values to one used by core.
:param str config_type_name: emane configuration type name
:param list config_value: emane configuration value list
:return: default core config value
:rtype: str
"""
config_default = ""
if config_type_name == "bool":
if config_value and config_value[0] == "true":
config_default = "1"
else:
config_default = "0"
elif config_value:
config_default = config_value[0]
if config_default is None:
config_default = ""
return config_default
def parse(manifest_path, defaults):
"""
Parses a valid emane manifest file and converts the provided configuration values into ones used by core.
:param str manifest_path: absolute manifest file path
:param dict defaults: used to override default values for configurations
:return: list of core configuration values
:rtype: list
"""
# load configuration file
manifest_file = manifest.Manifest(manifest_path)
manifest_configurations = manifest_file.getAllConfiguration()
configurations = []
for config_name in sorted(manifest_configurations):
config_info = manifest_file.getConfigurationInfo(config_name)
# map type to internal config data type value for core
config_type = config_info.get("numeric")
if not config_type:
config_type = config_info.get("nonnumeric")
config_type_name = config_type["type"]
config_type_value = _type_value(config_type_name)
# get default values, using provided defaults
if config_name in defaults:
config_default = defaults[config_name]
else:
config_value = config_info["values"]
config_default = _get_default(config_type_name, config_value)
# map to possible values used as options within the gui
config_regex = config_info.get("regex")
possible = _get_possible(config_type_name, config_regex)
# define description and account for gui quirks
config_descriptions = config_name
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)
return configurations

View file

@ -3,7 +3,7 @@ Defines Emane Models used within CORE.
""" """
from core import logger from core import logger
from core.enumerations import ConfigDataTypes from core.emane import emanemanifest
from core.misc import utils from core.misc import utils
from core.mobility import WirelessModel from core.mobility import WirelessModel
from core.xml import xmlutils from core.xml import xmlutils
@ -40,98 +40,31 @@ def value_to_params(doc, name, value):
return xmlutils.add_param_list_to_parent(doc, parent=None, name=name, values=values) return xmlutils.add_param_list_to_parent(doc, parent=None, name=name, values=values)
class EmaneUniversalModel(object):
"""
This Univeral PHY model is meant to be imported by other models,
not instantiated.
"""
name = "emane_universal"
# 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"),
("fading.nakagami.distance0", ConfigDataTypes.FLOAT.value, "100.0", "",
"Nakagami D0: distance lower bound in meters"),
("fading.nakagami.distance1", ConfigDataTypes.FLOAT.value, "250.0", "",
"Nakagami D1: distance upper bound in meters"),
("fading.nakagami.m0", ConfigDataTypes.FLOAT.value, "0.75", "", "Nakagami M0: shape factor for distance < D0"),
("fading.nakagami.m1", ConfigDataTypes.FLOAT.value, "1.0", "",
"Nakagami M1: shape factor for distance >= D0 < D1"),
("fading.nakagami.m2", ConfigDataTypes.FLOAT.value, "200.0", "",
"Nakagami M2: shape factor for distance >= D1"),
("fixedantennagain", ConfigDataTypes.FLOAT.value, "0.0", "", "antenna gain (dBi)"),
("fixedantennagainenable", ConfigDataTypes.BOOL.value, "1", "On,Off", "enable fixed antenna gain"),
("frequency", ConfigDataTypes.UINT64.value, "2.347G", "", "frequency (Hz)"),
("frequencyofinterest", ConfigDataTypes.UINT64.value, "2.347G", "", "frequency of interest (Hz)"),
("noisebinsize", ConfigDataTypes.UINT64.value, "20", "", "noise bin size in microseconds"),
("noisemaxclampenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "Noise max clamp enable"),
("noisemaxmessagepropagation", ConfigDataTypes.UINT64.value, "200000", "",
"Noise maximum message propagation in microsecond"),
("noisemaxsegmentduration", ConfigDataTypes.UINT64.value, "1000000", "",
"Noise maximum segment duration in microseconds"),
("noisemaxsegmentoffset", ConfigDataTypes.UINT64.value, "300000", "",
"Noise maximum segment offset in microseconds"),
("noisemode", ConfigDataTypes.STRING.value, "none", "none,all,outofband", "noise processing mode"),
("propagationmodel", ConfigDataTypes.STRING.value, "2ray", "precomputed,2ray,freespace", "path loss mode"),
("subid", ConfigDataTypes.UINT16.value, "1", "", "subid"),
("systemnoisefigure", ConfigDataTypes.FLOAT.value, "4.0", "", "system noise figure (dB)"),
("timesyncthreshold", ConfigDataTypes.UINT64.value, "10000", "", "Time sync threshold"),
("txpower", ConfigDataTypes.FLOAT.value, "0.0", "", "transmit power (dBm)"),
]
def __init__(self, session, object_id=None):
raise NotImplemented("Cannot use this class directly")
@classmethod
def get_phy_doc(cls, emane_manager, emane_model, values, phy_names):
"""
Create a phy doc for a model based on the universal model.
: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"
value = emane_model.valueof(name, values)
frequencies = value_to_params(phy_document, name, value)
if frequencies:
phy_names = list(phy_names)
phy_names.remove("frequencyofinterest")
# append all PHY options to phydoc
for name in phy_names:
value = emane_model.valueof(name, values)
param = emane_manager.xmlparam(phy_document, name, value)
phy_element.appendChild(param)
if frequencies:
phy_element.appendChild(frequencies)
return phy_document
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 list of handling configuration messages based on the list of
configurable parameters. Helper functions also live here. configurable parameters. Helper functions also live here.
""" """
_config_mac = [] # default mac configuration settings
_config_phy = EmaneUniversalModel.config_matrix mac_library = None
library = None mac_xml = None
mac_defaults = {}
config_mac = []
# default phy configuration settings, using the universal model
phy_library = None
phy_xml = "/usr/share/emane/manifest/emanephy.xml"
phy_defaults = {
"subid": "1",
"propagationmodel": "2ray",
"noisemode": "none"
}
config_phy = emanemanifest.parse(phy_xml, phy_defaults)
config_ignore = set() config_ignore = set()
config_matrix = _config_mac + _config_phy config_matrix = config_mac + config_phy
config_groups = create_config_groups(_config_mac, config_matrix) config_groups = create_config_groups(config_mac, config_matrix)
def __init__(self, session, object_id=None): def __init__(self, session, object_id=None):
WirelessModel.__init__(self, session, object_id) WirelessModel.__init__(self, session, object_id)
@ -157,16 +90,22 @@ class EmaneModel(WirelessModel):
# create mac document and write to disk # create mac document and write to disk
mac_name = self.mac_name(interface) mac_name = self.mac_name(interface)
mac_document = self.create_mac_doc(emane_manager, values) mac_document = self.create_mac_doc(emane_manager, values)
if mac_document:
emane_manager.xmlwrite(mac_document, mac_name) emane_manager.xmlwrite(mac_document, mac_name)
# create phy document and write to disk # create phy document and write to disk
phy_name = self.phy_name(interface) phy_name = self.phy_name(interface)
phy_document = self.create_phy_doc(emane_manager, values) phy_document = self.create_phy_doc(emane_manager, values)
if phy_document:
emane_manager.xmlwrite(phy_document, phy_name) emane_manager.xmlwrite(phy_document, phy_name)
def create_nem_doc(self, emane_manager, interface): def create_nem_doc(self, emane_manager, interface):
"""
Create the nem xml document.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param interface: interface for the emane node
:return: nem document
:rtype: xml.dom.minidom.Document
"""
mac_name = self.mac_name(interface) mac_name = self.mac_name(interface)
phy_name = self.phy_name(interface) phy_name = self.phy_name(interface)
@ -186,16 +125,24 @@ class EmaneModel(WirelessModel):
return nem_document return nem_document
def create_mac_doc(self, emane_manager, values): def create_mac_doc(self, emane_manager, values):
"""
Create the mac xml document.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param tuple values: all current configuration values, mac + phy
:return: nem document
:rtype: xml.dom.minidom.Document
"""
names = list(self.getnames()) names = list(self.getnames())
mac_names = names[:len(self._config_mac)] mac_names = names[:len(self.config_mac)]
mac_document = emane_manager.xmldoc("mac") mac_document = emane_manager.xmldoc("mac")
mac_element = mac_document.getElementsByTagName("mac").pop() mac_element = mac_document.getElementsByTagName("mac").pop()
mac_element.setAttribute("name", "%s MAC" % self.name) mac_element.setAttribute("name", "%s MAC" % self.name)
if not self.library: if not self.mac_library:
raise ValueError("must define emane model library") raise ValueError("must define emane model library")
mac_element.setAttribute("library", self.library) mac_element.setAttribute("library", self.mac_library)
for name in mac_names: for name in mac_names:
if name in self.config_ignore: if name in self.config_ignore:
@ -207,9 +154,46 @@ class EmaneModel(WirelessModel):
return mac_document return mac_document
def create_phy_doc(self, emane_manager, values): def create_phy_doc(self, emane_manager, values):
"""
Create the phy xml document.
:param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
:param tuple values: all current configuration values, mac + phy
:return: nem document
:rtype: xml.dom.minidom.Document
"""
names = list(self.getnames()) names = list(self.getnames())
phy_names = names[len(self._config_mac):] phy_names = names[len(self.config_mac):]
return EmaneUniversalModel.get_phy_doc(emane_manager, self, values, phy_names)
phy_document = emane_manager.xmldoc("phy")
phy_element = phy_document.getElementsByTagName("phy").pop()
phy_element.setAttribute("name", "%s PHY" % self.name)
if self.phy_library:
phy_element.setAttribute("library", self.phy_library)
# hack to account for config that can contain more than 1 value
frequencies = None
name = "frequencyofinterest"
try:
value = self.valueof(name, values)
frequencies = value_to_params(phy_document, name, value)
if frequencies:
phy_names = list(phy_names)
phy_names.remove("frequencyofinterest")
except ValueError:
logger.info("%s is not present in the phy names", name)
# append all PHY options to phydoc
for name in phy_names:
value = self.valueof(name, values)
param = emane_manager.xmlparam(phy_document, name, value)
phy_element.appendChild(param)
if frequencies:
phy_element.appendChild(frequencies)
return phy_document
@classmethod @classmethod
def configure_emane(cls, session, config_data): def configure_emane(cls, session, config_data):

View file

@ -2,89 +2,24 @@
ieee80211abg.py: EMANE IEEE 802.11abg model for CORE ieee80211abg.py: EMANE IEEE 802.11abg model for CORE
""" """
from core.emane import emanemanifest
from core.emane import emanemodel from core.emane import emanemodel
from core.enumerations import ConfigDataTypes
class EmaneIeee80211abgModel(emanemodel.EmaneModel): class EmaneIeee80211abgModel(emanemodel.EmaneModel):
# model name # model name
name = "emane_ieee80211abg" name = "emane_ieee80211abg"
library = "ieee80211abgmaclayer"
# mac configuration # mac configuration
_80211rates = "1 1 Mbps,2 2 Mbps,3 5.5 Mbps,4 11 Mbps,5 6 Mbps," + \ mac_library = "ieee80211abgmaclayer"
"6 9 Mbps,7 12 Mbps,8 18 Mbps,9 24 Mbps,10 36 Mbps,11 48 Mbps," + \ mac_xml = "/usr/share/emane/manifest/ieee80211abgmaclayer.xml"
"12 54 Mbps" mac_defaults = {
xml_path = "/usr/share/emane/xml/models/mac/ieee80211abg" "pcrcurveuri": "/usr/share/emane/xml/models/mac/ieee80211abg/ieee80211pcr.xml",
_config_mac = [ }
("aifs", ConfigDataTypes.STRING.value, "0:2 1:2 2:2 3:1", "", "arbitration inter frame space (0-4:aifs)"), config_mac = emanemanifest.parse(mac_xml, mac_defaults)
("channelactivityestimationtimer", ConfigDataTypes.FLOAT.value, "0.1", "",
"Defines channel activity estimation timer in seconds"),
("cwmax", ConfigDataTypes.STRING.value, "0:1024 1:1024 2:64 3:16", "", "max contention window (0-4:maxw)"),
("cwmin", ConfigDataTypes.STRING.value, "0:32 1:32 2:16 3:8", "", "min contention window (0-4:minw)"),
("distance", ConfigDataTypes.UINT32.value, "1000", "", "max distance (m)"),
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "On,Off", "enable promiscuous mode"),
("flowcontrolenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "enable traffic flow control"),
("flowcontroltokens", ConfigDataTypes.UINT16.value, "10", "", "number of flow control tokens"),
("mode", ConfigDataTypes.UINT8.value, "0", "0 802.11b (DSSS only),1 802.11b (DSSS only)," +
"2 802.11a or g (OFDM),3 802.11b/g (DSSS and OFDM)", "mode"),
("multicastrate", ConfigDataTypes.UINT8.value, "1", _80211rates, "multicast rate (Mbps)"),
("msdu", ConfigDataTypes.UINT16.value, "0:65535 1:65535 2:65535 3:65535", "", "MSDU categories (0-4:size)"),
("neighbormetricdeletetime", ConfigDataTypes.FLOAT.value, "60.0", "",
"R2RI neighbor table inactivity time (sec)"),
("neighbortimeout", ConfigDataTypes.FLOAT.value, "30.0", "", "Neighbor timeout in seconds for estimation"),
("pcrcurveuri", ConfigDataTypes.STRING.value, "%s/ieee80211pcr.xml" % xml_path, "", "SINR/PCR curve file"),
("queuesize", ConfigDataTypes.STRING.value, "0:255 1:255 2:255 3:255", "", "queue size (0-4:size)"),
("radiometricenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "report radio metrics via R2RI"),
("radiometricreportinterval", ConfigDataTypes.FLOAT.value, "1.0", "",
"R2RI radio metric report interval (sec)"),
("retrylimit", ConfigDataTypes.STRING.value, "0:3 1:3 2:3 3:3", "", "retry limit (0-4:numretries)"),
("rtsthreshold", ConfigDataTypes.UINT16.value, "0", "", "RTS threshold (bytes)"),
("txop", ConfigDataTypes.STRING.value, "0:0 1:0 2:0 3:0", "", "txop (0-4:usec)"),
("unicastrate", ConfigDataTypes.UINT8.value, "4", _80211rates, "unicast rate (Mbps)"),
("wmmenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "WiFi Multimedia (WMM)"),
]
config_matrix = _config_mac + emanemodel.EmaneModel._config_phy # defines overall config
config_groups = emanemodel.create_config_groups(_config_mac, config_matrix) config_matrix = config_mac + emanemodel.EmaneModel.config_phy
def create_mac_doc(self, emane_manager, values): # gui display tabs
names = self.getnames() config_groups = emanemodel.create_config_groups(config_mac, config_matrix)
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)
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)
return mac_document
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(mac_name, values)
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 mac_name in ["aifs", "txop"]:
val = "%f" % (float(val) * 1e-6)
name9x = "%s%d" % (mac_name, idx)
nvpairlist.append([name9x, val])
else:
nvpairlist.append([mac_name, macparmval])
return nvpairlist

View file

@ -2,31 +2,24 @@
rfpipe.py: EMANE RF-PIPE model for CORE rfpipe.py: EMANE RF-PIPE model for CORE
""" """
from core.emane import emanemanifest
from core.emane import emanemodel from core.emane import emanemodel
from core.enumerations import ConfigDataTypes
class EmaneRfPipeModel(emanemodel.EmaneModel): class EmaneRfPipeModel(emanemodel.EmaneModel):
# model name # model name
name = "emane_rfpipe" name = "emane_rfpipe"
library = "rfpipemaclayer"
# mac configuration # mac configuration
xml_path = "/usr/share/emane/xml/models/mac/rfpipe" mac_library = "rfpipemaclayer"
_config_mac = [ mac_xml = "/usr/share/emane/manifest/rfpipemaclayer.xml"
("datarate", ConfigDataTypes.UINT64.value, "1M", "", "data rate (bps)"), mac_defaults = {
("delay", ConfigDataTypes.FLOAT.value, "0.0", "", "transmission delay (sec)"), "pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml",
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, "0", "True,False", "enable promiscuous mode"), }
("flowcontrolenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "enable traffic flow control"), config_mac = emanemanifest.parse(mac_xml, mac_defaults)
("flowcontroltokens", ConfigDataTypes.UINT16.value, "10", "", "number of flow control tokens"),
("jitter", ConfigDataTypes.FLOAT.value, "0.0", "", "transmission jitter (sec)"),
("neighbormetricdeletetime", ConfigDataTypes.FLOAT.value, "60.0", "",
"R2RI neighbor table inactivity time (sec)"),
("pcrcurveuri", ConfigDataTypes.STRING.value, "%s/rfpipepcr.xml" % xml_path, "", "SINR/PCR curve file"),
("radiometricenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "report radio metrics via R2RI"),
("radiometricreportinterval", ConfigDataTypes.FLOAT.value, "1.0", "",
"R2RI radio metric report interval (sec)"),
]
config_matrix = _config_mac + emanemodel.EmaneModel._config_phy # defines overall config
config_groups = emanemodel.create_config_groups(_config_mac, config_matrix) config_matrix = config_mac + emanemodel.EmaneModel.config_phy
# gui display tabs
config_groups = emanemodel.create_config_groups(config_mac, config_matrix)

View file

@ -6,6 +6,7 @@ import os
from core import constants from core import constants
from core import logger from core import logger
from core.emane import emanemanifest
from core.emane import emanemodel from core.emane import emanemodel
from core.enumerations import ConfigDataTypes from core.enumerations import ConfigDataTypes
from core.misc import utils from core.misc import utils
@ -14,40 +15,26 @@ from core.misc import utils
class EmaneTdmaModel(emanemodel.EmaneModel): class EmaneTdmaModel(emanemodel.EmaneModel):
# model name # model name
name = "emane_tdma" name = "emane_tdma"
library = "tdmaeventschedulerradiomodel"
# mac configuration # mac configuration
xml_path = "/usr/share/emane/xml/models/mac/tdmaeventscheduler" mac_library = "tdmaeventschedulerradiomodel"
mac_xml = "/usr/share/emane/manifest/tdmaeventschedulerradiomodel.xml"
mac_defaults = {
"pcrcurveuri": "/usr/share/emane/xml/models/mac/tdmaeventscheduler/tdmabasemodelpcr.xml",
}
config_mac = emanemanifest.parse(mac_xml, mac_defaults)
# add custom schedule options and ignore it when writing emane xml
schedule_name = "schedule" schedule_name = "schedule"
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")
config_mac.insert(0, (schedule_name, ConfigDataTypes.STRING.value, default_schedule, "", "TDMA schedule file"))
config_ignore = {schedule_name} 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"),
("flowcontrolenable", ConfigDataTypes.BOOL.value, "0", "On,Off", "enable traffic flow control"),
("flowcontroltokens", ConfigDataTypes.UINT16.value, "10", "", "number of flow control tokens"),
("fragmentcheckthreshold", ConfigDataTypes.UINT16.value, "2", "",
"rate in seconds for check if fragment reassembly efforts should be abandoned"),
("fragmenttimeoutthreshold", ConfigDataTypes.UINT16.value, "5", "",
"threshold in seconds to wait for another packet fragment for reassembly"),
("neighbormetricdeletetime", ConfigDataTypes.FLOAT.value, "60.0", "",
"neighbor RF reception timeout for removal from neighbor table (sec)"),
("neighbormetricupdateinterval", ConfigDataTypes.FLOAT.value, "1.0", "",
"neighbor table update interval (sec)"),
("pcrcurveuri", ConfigDataTypes.STRING.value, "%s/tdmabasemodelpcr.xml" % xml_path, "", "SINR/PCR curve file"),
("queue.aggregationenable", ConfigDataTypes.BOOL.value, "1", "On,Off", "enable transmit packet aggregation"),
("queue.aggregationslotthreshold", ConfigDataTypes.FLOAT.value, "90.0", "",
"percentage of a slot that must be filled in order to conclude aggregation"),
("queue.depth", ConfigDataTypes.UINT16.value, "256", "",
"size of the per service class downstream packet queues (packets)"),
("queue.fragmentationenable", ConfigDataTypes.BOOL.value, "1", "On,Off",
"enable packet fragmentation (over multiple slots)"),
("queue.strictdequeueenable", ConfigDataTypes.BOOL.value, "0", "On,Off",
"enable strict dequeueing to specified queues only"),
]
config_matrix = _config_mac + emanemodel.EmaneModel._config_phy # defines overall config
config_groups = emanemodel.create_config_groups(_config_mac, config_matrix) config_matrix = config_mac + emanemodel.EmaneModel.config_phy
# gui display tabs
config_groups = emanemodel.create_config_groups(config_mac, config_matrix)
def post_startup(self, emane_manager): def post_startup(self, emane_manager):
""" """