merged cleanup branch with master

This commit is contained in:
Rod A Santiago 2017-06-19 18:09:28 -07:00
parent 0a91fe7a3e
commit 55a6e2dcef
81 changed files with 11596 additions and 15021 deletions

View file

@ -0,0 +1,54 @@
import subprocess
from core.misc import log
from core.misc import utils
logger = log.get_logger(__name__)
EMANEUNK = 0
EMANE074 = 7
EMANE081 = 8
EMANE091 = 91
EMANE092 = 92
EMANE093 = 93
EMANE101 = 101
VERSION = None
VERSIONSTR = None
def emane_version():
"""
Return the locally installed EMANE version identifier and string.
"""
global VERSION
global VERSIONSTR
cmd = ("emane", "--version")
try:
status, result = utils.cmdresult(cmd)
except (OSError, subprocess.CalledProcessError):
logger.exception("error checking emane version")
status = -1
result = ""
VERSION = EMANEUNK
if status == 0:
if result.startswith("0.7.4"):
VERSION = EMANE074
elif result.startswith("0.8.1"):
VERSION = EMANE081
elif result.startswith("0.9.1"):
VERSION = EMANE091
elif result.startswith("0.9.2"):
VERSION = EMANE092
elif result.startswith("0.9.3"):
VERSION = EMANE093
elif result.startswith("1.0.1"):
VERSION = EMANE101
VERSIONSTR = result.strip()
# set version variables for the Emane class
emane_version()

View file

@ -1,48 +1,38 @@
#
# CORE
# Copyright (c)2011-2012 the Boeing Company.
# See the LICENSE file included in this distribution.
#
# author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
#
'''
"""
bypass.py: EMANE Bypass model for CORE
'''
"""
import sys
import string
from core.api import coreapi
from core.emane.emanemodel import EmaneModel
from core.enumerations import ConfigDataTypes
from core.constants import *
from emane import EmaneModel
class EmaneBypassModel(EmaneModel):
def __init__(self, session, objid = None, verbose = False):
EmaneModel.__init__(self, session, objid, verbose)
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
_name = "emane_bypass"
_confmatrix = [
("none",coreapi.CONF_DATA_TYPE_BOOL, '0',
'True,False','There are no parameters for the bypass model.'),
name = "emane_bypass"
config_matrix = [
("none", ConfigDataTypes.BOOL.value, '0',
'True,False', 'There are no parameters for the bypass model.'),
]
# value groupings
_confgroups = "Bypass Parameters:1-1"
config_groups = "Bypass Parameters:1-1"
def buildnemxmlfiles(self, e, ifc):
''' 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.
'''
values = e.getifcconfig(self.objid, self._name,
self.getdefaultvalues(), ifc)
"""
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.
"""
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc)
if values is None:
return
nemdoc = e.xmldoc("nem")
nem = nemdoc.getElementsByTagName("nem").pop()
nem.setAttribute("name", "BYPASS NEM")
e.appendtransporttonem(nemdoc, nem, self.objid, ifc)
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc)
mactag = nemdoc.createElement("mac")
mactag.setAttribute("definition", self.macxmlname(ifc))
nem.appendChild(mactag)
@ -62,5 +52,3 @@ class EmaneBypassModel(EmaneModel):
phy.setAttribute("name", "BYPASS PHY")
phy.setAttribute("library", "bypassphylayer")
e.xmlwrite(phydoc, self.phyxmlname(ifc))

View file

@ -1,76 +1,70 @@
#
# CORE
# Copyright (c)2010-2014 the Boeing Company.
# See the LICENSE file included in this distribution.
#
# authors: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
# Randy Charland <rcharland@ll.mit.edu>
#
'''
"""
commeffect.py: EMANE CommEffect model for CORE
'''
"""
from core import emane
from core.emane.emanemodel import EmaneModel
from core.enumerations import ConfigDataTypes
from core.misc import log
logger = log.get_logger(__name__)
import sys
import string
try:
from emanesh.events import EventService
except:
pass
from core.api import coreapi
from core.constants import *
from emane import Emane, EmaneModel
except ImportError:
logger.error("error importing emanesh")
try:
import emaneeventservice
import emaneeventcommeffect
except Exception, e:
pass
except ImportError:
logger.error("error importing emaneeventservice and emaneeventcommeffect")
class EmaneCommEffectModel(EmaneModel):
def __init__(self, session, objid = None, verbose = False):
EmaneModel.__init__(self, session, objid, verbose)
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
# model name
_name = "emane_commeffect"
name = "emane_commeffect"
# CommEffect parameters
_confmatrix_shim_base = [
("filterfile", coreapi.CONF_DATA_TYPE_STRING, '',
("filterfile", ConfigDataTypes.STRING.value, '',
'', 'filter file'),
("groupid", coreapi.CONF_DATA_TYPE_UINT32, '0',
("groupid", ConfigDataTypes.UINT32.value, '0',
'', 'NEM Group ID'),
("enablepromiscuousmode", coreapi.CONF_DATA_TYPE_BOOL, '0',
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable promiscuous mode'),
("receivebufferperiod", coreapi.CONF_DATA_TYPE_FLOAT, '1.0',
("receivebufferperiod", ConfigDataTypes.FLOAT.value, '1.0',
'', 'receivebufferperiod'),
]
_confmatrix_shim_081 = [
("defaultconnectivity", coreapi.CONF_DATA_TYPE_BOOL, '0',
("defaultconnectivity", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'defaultconnectivity'),
("enabletighttimingmode", coreapi.CONF_DATA_TYPE_BOOL, '0',
("enabletighttimingmode", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable tight timing mode'),
]
_confmatrix_shim_091 = [
("defaultconnectivitymode", coreapi.CONF_DATA_TYPE_BOOL, '0',
("defaultconnectivitymode", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'defaultconnectivity'),
]
if Emane.version >= Emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
_confmatrix_shim = _confmatrix_shim_base + _confmatrix_shim_091
else:
_confmatrix_shim = _confmatrix_shim_base + _confmatrix_shim_081
_confmatrix = _confmatrix_shim
config_matrix = _confmatrix_shim
# value groupings
_confgroups = "CommEffect SHIM Parameters:1-%d" \
% len(_confmatrix_shim)
config_groups = "CommEffect SHIM Parameters:1-%d" % len(_confmatrix_shim)
def buildnemxmlfiles(self, e, ifc):
''' Build the necessary nem and commeffect 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_commeffectnem.xml, nXXemane_commeffectshim.xml are used.
'''
values = e.getifcconfig(self.objid, self._name,
self.getdefaultvalues(), ifc)
"""
Build the necessary nem and commeffect 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_commeffectnem.xml, nXXemane_commeffectshim.xml are used.
"""
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc)
if values is None:
return
shimdoc = e.xmldoc("shim")
@ -83,8 +77,7 @@ class EmaneCommEffectModel(EmaneModel):
shimnames.remove("filterfile")
# append all shim options (except filterfile) to shimdoc
map( lambda n: shim.appendChild(e.xmlparam(shimdoc, n, \
self.valueof(n, values))), shimnames)
map(lambda n: shim.appendChild(e.xmlparam(shimdoc, n, self.valueof(n, values))), shimnames)
# empty filterfile is not allowed
ff = self.valueof("filterfile", values)
if ff.strip() != '':
@ -95,20 +88,24 @@ class EmaneCommEffectModel(EmaneModel):
nem = nemdoc.getElementsByTagName("nem").pop()
nem.setAttribute("name", "commeffect NEM")
nem.setAttribute("type", "unstructured")
e.appendtransporttonem(nemdoc, nem, self.objid, ifc)
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc)
nem.appendChild(e.xmlshimdefinition(nemdoc, self.shimxmlname(ifc)))
e.xmlwrite(nemdoc, self.nemxmlname(ifc))
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
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
link parameters.
'''
if self.session.emane.version >= self.session.emane.EMANE091:
"""
if emane.VERSION >= emane.EMANE091:
raise NotImplementedError, \
"CommEffect linkconfig() not implemented for EMANE 0.9.1+"
"CommEffect linkconfig() not implemented for EMANE 0.9.1+"
def z(x):
''' Helper to use 0 for None values. '''
"""
Helper to use 0 for None values.
"""
if type(x) is str:
x = float(x)
if x is None:
@ -118,17 +115,16 @@ class EmaneCommEffectModel(EmaneModel):
service = self.session.emane.service
if service is None:
self.session.warn("%s: EMANE event service unavailable" % \
self._name)
logger.warn("%s: EMANE event service unavailable" % self.name)
return
if netif is None or netif2 is None:
self.session.warn("%s: missing NEM information" % self._name)
logger.warn("%s: missing NEM information" % self.name)
return
# TODO: batch these into multiple events per transmission
# TODO: may want to split out seconds portion of delay and jitter
event = emaneeventcommeffect.EventCommEffect(1)
index = 0
e = self.session.obj(self.objid)
e = self.session.get_object(self.object_id)
nemid = e.getnemid(netif)
nemid2 = e.getnemid(netif2)
mbw = bw
@ -139,6 +135,3 @@ class EmaneCommEffectModel(EmaneModel):
emaneeventservice.PLATFORMID_ANY,
nemid2, emaneeventservice.COMPONENTID_ANY,
event.export())

File diff suppressed because it is too large Load diff

View file

@ -1,117 +1,113 @@
#
# CORE
# Copyright (c)2010-2014 the Boeing Company.
# See the LICENSE file included in this distribution.
#
# author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
#
'''
"""
ieee80211abg.py: EMANE IEEE 802.11abg model for CORE
'''
"""
from core import emane
from core.emane.emanemodel import EmaneModel
from core.emane.universal import EmaneUniversalModel
from core.enumerations import ConfigDataTypes
from core.misc import log
logger = log.get_logger(__name__)
import sys
import string
try:
from emanesh.events import EventService
except:
pass
from core.api import coreapi
from core.constants import *
from emane import Emane, EmaneModel
from universal import EmaneUniversalModel
logger.error("error importing emanesh")
class EmaneIeee80211abgModel(EmaneModel):
def __init__(self, session, objid = None, verbose = False):
EmaneModel.__init__(self, session, objid, verbose)
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
# model name
_name = "emane_ieee80211abg"
name = "emane_ieee80211abg"
_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'
if Emane.version >= Emane.EMANE091:
'6 9 Mbps,7 12 Mbps,8 18 Mbps,9 24 Mbps,10 36 Mbps,11 48 Mbps,' + \
'12 54 Mbps'
if emane.VERSION >= emane.EMANE091:
xml_path = '/usr/share/emane/xml/models/mac/ieee80211abg'
else:
xml_path = "/usr/share/emane/models/ieee80211abg/xml"
# MAC parameters
_confmatrix_mac_base = [
("mode", coreapi.CONF_DATA_TYPE_UINT8, '0',
("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'),
("enablepromiscuousmode", coreapi.CONF_DATA_TYPE_BOOL, '0',
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable promiscuous mode'),
("distance", coreapi.CONF_DATA_TYPE_UINT32, '1000',
("distance", ConfigDataTypes.UINT32.value, '1000',
'', 'max distance (m)'),
("unicastrate", coreapi.CONF_DATA_TYPE_UINT8, '4', _80211rates,
("unicastrate", ConfigDataTypes.UINT8.value, '4', _80211rates,
'unicast rate (Mbps)'),
("multicastrate", coreapi.CONF_DATA_TYPE_UINT8, '1', _80211rates,
("multicastrate", ConfigDataTypes.UINT8.value, '1', _80211rates,
'multicast rate (Mbps)'),
("rtsthreshold", coreapi.CONF_DATA_TYPE_UINT16, '0',
("rtsthreshold", ConfigDataTypes.UINT16.value, '0',
'', 'RTS threshold (bytes)'),
("pcrcurveuri", coreapi.CONF_DATA_TYPE_STRING,
("pcrcurveuri", ConfigDataTypes.STRING.value,
'%s/ieee80211pcr.xml' % xml_path,
'', 'SINR/PCR curve file'),
("flowcontrolenable", coreapi.CONF_DATA_TYPE_BOOL, '0',
("flowcontrolenable", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable traffic flow control'),
("flowcontroltokens", coreapi.CONF_DATA_TYPE_UINT16, '10',
("flowcontroltokens", ConfigDataTypes.UINT16.value, '10',
'', 'number of flow control tokens'),
]
# mac parameters introduced in EMANE 0.8.1
# mac parameters introduced in EMANE 0.8.1
# Note: The entry format for category queue parameters (queuesize, aifs, etc) were changed in
# EMANE 9.x, but are being preserved for the time being due to space constraints in the
# CORE GUI. A conversion function (get9xmacparamequivalent) has been defined to support this.
# CORE GUI. A conversion function (get9xmacparamequivalent) has been defined to support this.
_confmatrix_mac_extended = [
("wmmenable", coreapi.CONF_DATA_TYPE_BOOL, '0',
("wmmenable", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'WiFi Multimedia (WMM)'),
("queuesize", coreapi.CONF_DATA_TYPE_STRING, '0:255 1:255 2:255 3:255',
("queuesize", ConfigDataTypes.STRING.value, '0:255 1:255 2:255 3:255',
'', 'queue size (0-4:size)'),
("cwmin", coreapi.CONF_DATA_TYPE_STRING, '0:32 1:32 2:16 3:8',
("cwmin", ConfigDataTypes.STRING.value, '0:32 1:32 2:16 3:8',
'', 'min contention window (0-4:minw)'),
("cwmax", coreapi.CONF_DATA_TYPE_STRING, '0:1024 1:1024 2:64 3:16',
("cwmax", ConfigDataTypes.STRING.value, '0:1024 1:1024 2:64 3:16',
'', 'max contention window (0-4:maxw)'),
("aifs", coreapi.CONF_DATA_TYPE_STRING, '0:2 1:2 2:2 3:1',
("aifs", ConfigDataTypes.STRING.value, '0:2 1:2 2:2 3:1',
'', 'arbitration inter frame space (0-4:aifs)'),
("txop", coreapi.CONF_DATA_TYPE_STRING, '0:0 1:0 2:0 3:0',
("txop", ConfigDataTypes.STRING.value, '0:0 1:0 2:0 3:0',
'', 'txop (0-4:usec)'),
("retrylimit", coreapi.CONF_DATA_TYPE_STRING, '0:3 1:3 2:3 3:3',
("retrylimit", ConfigDataTypes.STRING.value, '0:3 1:3 2:3 3:3',
'', 'retry limit (0-4:numretries)'),
]
_confmatrix_mac_091 = [
('radiometricenable', coreapi.CONF_DATA_TYPE_BOOL, '0',
('radiometricenable', ConfigDataTypes.BOOL.value, '0',
'On,Off', 'report radio metrics via R2RI'),
('radiometricreportinterval', coreapi.CONF_DATA_TYPE_FLOAT, '1.0',
('radiometricreportinterval', ConfigDataTypes.FLOAT.value, '1.0',
'', 'R2RI radio metric report interval (sec)'),
('neighbormetricdeletetime', coreapi.CONF_DATA_TYPE_FLOAT, '60.0',
('neighbormetricdeletetime', ConfigDataTypes.FLOAT.value, '60.0',
'', 'R2RI neighbor table inactivity time (sec)'),
]
_confmatrix_mac = _confmatrix_mac_base + _confmatrix_mac_extended
if Emane.version >= Emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
_confmatrix_mac += _confmatrix_mac_091
# PHY parameters from Universal PHY
_confmatrix_phy = EmaneUniversalModel._confmatrix
_confmatrix_phy = EmaneUniversalModel.config_matrix
_confmatrix = _confmatrix_mac + _confmatrix_phy
config_matrix = _confmatrix_mac + _confmatrix_phy
# value groupings
_confgroups = "802.11 MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" \
% (len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(_confmatrix))
config_groups = "802.11 MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(config_matrix))
def buildnemxmlfiles(self, e, ifc):
''' 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.
'''
values = e.getifcconfig(self.objid, self._name,
self.getdefaultvalues(), ifc)
"""
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.
"""
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc)
if values is None:
return
nemdoc = e.xmldoc("nem")
nem = nemdoc.getElementsByTagName("nem").pop()
nem.setAttribute("name", "ieee80211abg NEM")
e.appendtransporttonem(nemdoc, nem, self.objid, ifc)
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc)
mactag = nemdoc.createElement("mac")
mactag.setAttribute("definition", self.macxmlname(ifc))
nem.appendChild(mactag)
@ -130,15 +126,14 @@ class EmaneIeee80211abgModel(EmaneModel):
phynames = names[len(self._confmatrix_mac):]
# append all MAC options to macdoc
if Emane.version >= Emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
for macname in macnames:
mac9xnvpairlist = self.get9xmacparamequivalent(macname, values)
for nvpair in mac9xnvpairlist:
mac.appendChild(e.xmlparam(macdoc, nvpair[0], nvpair[1]))
else:
map( lambda n: mac.appendChild(e.xmlparam(macdoc, n, \
self.valueof(n, values))), macnames)
map(lambda n: mac.appendChild(e.xmlparam(macdoc, n, self.valueof(n, values))), macnames)
e.xmlwrite(macdoc, self.macxmlname(ifc))
phydoc = EmaneUniversalModel.getphydoc(e, self, values, phynames)
@ -149,25 +144,25 @@ class EmaneIeee80211abgModel(EmaneModel):
# 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):
''' 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
def get9xmacparamequivalent(self, macname, values):
"""
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)
if macname in ["queuesize","aifs","cwmin","cwmax","txop","retrylimit"]:
if macname in ["queuesize", "aifs", "cwmin", "cwmax", "txop", "retrylimit"]:
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"]:
val = "%f" % (float(val)*(1e-6))
if macname in ["aifs", "txop"]:
val = "%f" % (float(val) * 1e-6)
name9x = "%s%d" % (macname, idx)
nvpairlist.append([name9x, val])
else:
nvpairlist.append([macname, macparmval])
return nvpairlist

View file

@ -1,69 +1,72 @@
#
# CORE
# Copyright (c)2010-2014 the Boeing Company.
# See the LICENSE file included in this distribution.
#
# author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
#
'''
"""
nodes.py: definition of an EmaneNode class for implementing configuration
control of an EMANE emulation. An EmaneNode has several attached NEMs that
share the same MAC+PHY model.
'''
"""
import sys
import os.path
from os import path
from core.api import coreapi
from core import emane
from core.coreobj import PyCoreNet
from core.enumerations import LinkTypes
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.misc import log
logger = log.get_logger(__name__)
try:
from emanesh.events import EventService
from emanesh.events import LocationEvent
except Exception, e:
pass
except ImportError:
logger.error("error loading emanesh")
try:
import emaneeventservice
import emaneeventlocation
except Exception, e:
''' Don't require all CORE users to have EMANE libeventservice and its
Python bindings installed.
'''
pass
except ImportError:
"""
Don't require all CORE users to have EMANE libeventservice and its
Python bindings installed.
"""
logger.error("error loading emaneeventservice and emaneeventlocation")
class EmaneNet(PyCoreNet):
''' EMANE network base class.
'''
apitype = coreapi.CORE_NODE_EMANE
linktype = coreapi.CORE_LINK_WIRELESS
type = "wlan" # icon used
"""
EMANE network base class.
"""
apitype = NodeTypes.EMANE.value
linktype = LinkTypes.WIRELESS.value
# icon used
type = "wlan"
class EmaneNode(EmaneNet):
''' EMANE node contains NEM configuration and causes connected nodes
to have TAP interfaces (instead of VEth). These are managed by the
Emane controller object that exists in a session.
'''
def __init__(self, session, objid = None, name = None, verbose = False,
start = True):
PyCoreNet.__init__(self, session, objid, name, verbose, start)
self.verbose = verbose
"""
EMANE node contains NEM configuration and causes connected nodes
to have TAP interfaces (instead of VEth). These are managed by the
Emane controller object that exists in a session.
"""
def __init__(self, session, objid=None, name=None, start=True):
PyCoreNet.__init__(self, session, objid, name, start)
self.conf = ""
self.up = False
self.nemidmap = {}
self.model = None
self.mobility = None
def linkconfig(self, netif, bw = None, delay = None,
loss = None, duplicate = None, jitter = None, netif2 = None):
''' The CommEffect model supports link configuration.
'''
def linkconfig(self, netif, bw=None, delay=None, loss=None, duplicate=None, jitter=None, netif2=None):
"""
The CommEffect model supports link configuration.
"""
if not self.model:
return
return self.model.linkconfig(netif=netif, bw=bw, delay=delay, loss=loss,
duplicate=duplicate, jitter=jitter, netif2=netif2)
duplicate=duplicate, jitter=jitter, netif2=netif2)
def config(self, conf):
#print "emane", self.name, "got config:", conf
self.conf = conf
def shutdown(self):
@ -76,55 +79,57 @@ class EmaneNode(EmaneNet):
pass
def setmodel(self, model, config):
''' set the EmaneModel associated with this node
'''
if (self.verbose):
self.info("adding model %s" % model._name)
if model._type == coreapi.CORE_TLV_REG_WIRELESS:
"""
set the EmaneModel associated with this node
"""
logger.info("adding model: %s", model.name)
if model.config_type == RegisterTlvs.WIRELESS.value:
# EmaneModel really uses values from ConfigurableManager
# when buildnemxml() is called, not during init()
self.model = model(session=self.session, objid=self.objid,
verbose=self.verbose)
elif model._type == coreapi.CORE_TLV_REG_MOBILITY:
self.mobility = model(session=self.session, objid=self.objid,
verbose=self.verbose, values=config)
self.model = model(session=self.session, object_id=self.objid)
elif model.config_type == RegisterTlvs.MOBILITY.value:
self.mobility = model(session=self.session, object_id=self.objid, values=config)
def setnemid(self, netif, nemid):
''' Record an interface to numerical ID mapping. The Emane controller
object manages and assigns these IDs for all NEMs.
'''
"""
Record an interface to numerical ID mapping. The Emane controller
object manages and assigns these IDs for all NEMs.
"""
self.nemidmap[netif] = nemid
def getnemid(self, netif):
''' Given an interface, return its numerical ID.
'''
"""
Given an interface, return its numerical ID.
"""
if netif not in self.nemidmap:
return None
else:
return self.nemidmap[netif]
def getnemnetif(self, nemid):
''' Given a numerical NEM ID, return its interface. This returns the
first interface that matches the given NEM ID.
'''
"""
Given a numerical NEM ID, return its interface. This returns the
first interface that matches the given NEM ID.
"""
for netif in self.nemidmap:
if self.nemidmap[netif] == nemid:
return netif
return None
def netifs(self, sort=True):
''' Retrieve list of linked interfaces sorted by node number.
'''
"""
Retrieve list of linked interfaces sorted by node number.
"""
return sorted(self._netif.values(), key=lambda ifc: ifc.node.objid)
def buildplatformxmlentry(self, doc):
''' Return a dictionary of XML elements describing the NEMs
connected to this EmaneNode for inclusion in the platform.xml file.
'''
"""
Return a dictionary of XML elements describing the NEMs
connected to this EmaneNode for inclusion in the platform.xml file.
"""
ret = {}
if self.model is None:
self.info("warning: EmaneNode %s has no associated model" % \
self.name)
logger.info("warning: EmaneNode %s has no associated model" % self.name)
return ret
for netif in self.netifs():
# <nem name="NODE-001" definition="rfpipenem.xml">
@ -139,9 +144,9 @@ class EmaneNode(EmaneNet):
return ret
def buildnemxmlfiles(self, emane):
''' Let the configured model build the necessary nem, mac, and phy
XMLs.
'''
"""
Let the configured model build the necessary nem, mac, and phy XMLs.
"""
if self.model is None:
return
# build XML for overall network (EmaneNode) configs
@ -166,8 +171,9 @@ class EmaneNode(EmaneNet):
self.buildtransportxml(emane, rtype)
def buildtransportxml(self, emane, type):
''' Write a transport XML file for the Virtual or Raw Transport.
'''
"""
Write a transport XML file for the Virtual or Raw Transport.
"""
transdoc = emane.xmldoc("transport")
trans = transdoc.getElementsByTagName("transport").pop()
trans.setAttribute("name", "%s Transport" % type.capitalize())
@ -176,7 +182,7 @@ class EmaneNode(EmaneNet):
flowcontrol = False
names = self.model.getnames()
values = emane.getconfig(self.objid, self.model._name,
values = emane.getconfig(self.objid, self.model.name,
self.model.getdefaultvalues())[1]
if "flowcontrolenable" in names and values:
i = names.index("flowcontrolenable")
@ -184,35 +190,30 @@ class EmaneNode(EmaneNet):
flowcontrol = True
if "virtual" in type.lower():
if os.path.exists("/dev/net/tun_flowctl"):
trans.appendChild(emane.xmlparam(transdoc, "devicepath",
"/dev/net/tun_flowctl"))
if path.exists("/dev/net/tun_flowctl"):
trans.appendChild(emane.xmlparam(transdoc, "devicepath", "/dev/net/tun_flowctl"))
else:
trans.appendChild(emane.xmlparam(transdoc, "devicepath",
"/dev/net/tun"))
trans.appendChild(emane.xmlparam(transdoc, "devicepath", "/dev/net/tun"))
if flowcontrol:
trans.appendChild(emane.xmlparam(transdoc, "flowcontrolenable",
"on"))
trans.appendChild(emane.xmlparam(transdoc, "flowcontrolenable", "on"))
emane.xmlwrite(transdoc, self.transportxmlname(type.lower()))
def transportxmlname(self, type):
''' Return the string name for the Transport XML file,
e.g. 'n3transvirtual.xml'
'''
"""
Return the string name for the Transport XML file, e.g. 'n3transvirtual.xml'
"""
return "n%strans%s.xml" % (self.objid, type)
def installnetifs(self, do_netns=True):
''' Install TAP devices into their namespaces. This is done after
EMANE daemons have been started, because that is their only chance
to bind to the TAPs.
'''
if self.session.emane.genlocationevents() and \
self.session.emane.service is None:
"""
Install TAP devices into their namespaces. This is done after
EMANE daemons have been started, because that is their only chance
to bind to the TAPs.
"""
if self.session.emane.genlocationevents() and self.session.emane.service is None:
warntxt = "unable to publish EMANE events because the eventservice "
warntxt += "Python bindings failed to load"
self.session.exception(coreapi.CORE_EXCP_LEVEL_ERROR, self.name,
self.objid, warntxt)
logger.error(warntxt)
for netif in self.netifs():
if do_netns and "virtual" in netif.transport_type.lower():
@ -224,98 +225,99 @@ class EmaneNode(EmaneNet):
# at this point we register location handlers for generating
# EMANE location events
netif.poshook = self.setnemposition
(x,y,z) = netif.node.position.get()
(x, y, z) = netif.node.position.get()
self.setnemposition(netif, x, y, z)
def deinstallnetifs(self):
''' Uninstall TAP devices. This invokes their shutdown method for
any required cleanup; the device may be actually removed when
emanetransportd terminates.
'''
"""
Uninstall TAP devices. This invokes their shutdown method for
any required cleanup; the device may be actually removed when
emanetransportd terminates.
"""
for netif in self.netifs():
if "virtual" in netif.transport_type.lower():
netif.shutdown()
netif.poshook = None
def setnemposition(self, netif, x, y, z):
''' Publish a NEM location change event using the EMANE event service.
'''
"""
Publish a NEM location change event using the EMANE event service.
"""
if self.session.emane.service is None:
if self.verbose:
self.info("position service not available")
logger.info("position service not available")
return
nemid = self.getnemid(netif)
nemid = self.getnemid(netif)
ifname = netif.localname
if nemid is None:
self.info("nemid for %s is unknown" % ifname)
logger.info("nemid for %s is unknown" % ifname)
return
(lat, long, alt) = self.session.location.getgeo(x, y, z)
if self.verbose:
self.info("setnemposition %s (%s) x,y,z=(%d,%d,%s)"
"(%.6f,%.6f,%.6f)" % \
(ifname, nemid, x, y, z, lat, long, alt))
if self.session.emane.version >= self.session.emane.EMANE091:
logger.info("setnemposition %s (%s) x,y,z=(%d,%d,%s)"
"(%.6f,%.6f,%.6f)" % \
(ifname, nemid, x, y, z, lat, long, alt))
if emane.VERSION >= emane.EMANE091:
event = LocationEvent()
else:
event = emaneeventlocation.EventLocation(1)
# altitude must be an integer or warning is printed
# unused: yaw, pitch, roll, azimuth, elevation, velocity
alt = int(round(alt))
if self.session.emane.version >= self.session.emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
event.append(nemid, latitude=lat, longitude=long, altitude=alt)
self.session.emane.service.publish(0, event)
else:
event.set(0, nemid, lat, long, alt)
self.session.emane.service.publish(emaneeventlocation.EVENT_ID,
emaneeventservice.PLATFORMID_ANY,
emaneeventservice.NEMID_ANY,
emaneeventservice.COMPONENTID_ANY,
event.export())
self.session.emane.service.publish(
emaneeventlocation.EVENT_ID,
emaneeventservice.PLATFORMID_ANY,
emaneeventservice.NEMID_ANY,
emaneeventservice.COMPONENTID_ANY,
event.export()
)
def setnempositions(self, moved_netifs):
''' Several NEMs have moved, from e.g. a WaypointMobilityModel
calculation. Generate an EMANE Location Event having several
entries for each netif that has moved.
'''
"""
Several NEMs have moved, from e.g. a WaypointMobilityModel
calculation. Generate an EMANE Location Event having several
entries for each netif that has moved.
"""
if len(moved_netifs) == 0:
return
if self.session.emane.service is None:
if self.verbose:
self.info("position service not available")
logger.info("position service not available")
return
if self.session.emane.version >= self.session.emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
event = LocationEvent()
else:
event = emaneeventlocation.EventLocation(len(moved_netifs))
i = 0
for netif in moved_netifs:
nemid = self.getnemid(netif)
nemid = self.getnemid(netif)
ifname = netif.localname
if nemid is None:
self.info("nemid for %s is unknown" % ifname)
logger.info("nemid for %s is unknown" % ifname)
continue
(x, y, z) = netif.node.getposition()
(lat, long, alt) = self.session.location.getgeo(x, y, z)
if self.verbose:
self.info("setnempositions %d %s (%s) x,y,z=(%d,%d,%s)"
"(%.6f,%.6f,%.6f)" % \
(i, ifname, nemid, x, y, z, lat, long, alt))
logger.info("setnempositions %d %s (%s) x,y,z=(%d,%d,%s)"
"(%.6f,%.6f,%.6f)" %
(i, ifname, nemid, x, y, z, lat, long, alt))
# altitude must be an integer or warning is printed
alt = int(round(alt))
if self.session.emane.version >= self.session.emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
event.append(nemid, latitude=lat, longitude=long, altitude=alt)
else:
event.set(i, nemid, lat, long, alt)
i += 1
if self.session.emane.version >= self.session.emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
self.session.emane.service.publish(0, event)
else:
self.session.emane.service.publish(emaneeventlocation.EVENT_ID,
emaneeventservice.PLATFORMID_ANY,
emaneeventservice.NEMID_ANY,
emaneeventservice.COMPONENTID_ANY,
event.export())
self.session.emane.service.publish(
emaneeventlocation.EVENT_ID,
emaneeventservice.PLATFORMID_ANY,
emaneeventservice.NEMID_ANY,
emaneeventservice.COMPONENTID_ANY,
event.export()
)

View file

@ -1,33 +1,28 @@
#
# CORE
# Copyright (c)2010-2014 the Boeing Company.
# See the LICENSE file included in this distribution.
#
# authors: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
# Harry Bullen <hbullen@i-a-i.com>
#
'''
"""
rfpipe.py: EMANE RF-PIPE model for CORE
'''
"""
from core import emane
from core.emane.emanemodel import EmaneModel
from core.emane.universal import EmaneUniversalModel
from core.enumerations import ConfigDataTypes
from core.misc import log
logger = log.get_logger(__name__)
import sys
import string
try:
from emanesh.events import EventService
except:
pass
from core.api import coreapi
from core.constants import *
from emane import Emane, EmaneModel
from universal import EmaneUniversalModel
except ImportError:
logger.error("error importing emanesh")
class EmaneRfPipeModel(EmaneModel):
def __init__(self, session, objid = None, verbose = False):
EmaneModel.__init__(self, session, objid, verbose)
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
# model name
_name = "emane_rfpipe"
if Emane.version >= Emane.EMANE091:
name = "emane_rfpipe"
if emane.VERSION >= emane.EMANE091:
xml_path = '/usr/share/emane/xml/models/mac/rfpipe'
else:
xml_path = "/usr/share/emane/models/rfpipe/xml"
@ -36,68 +31,69 @@ class EmaneRfPipeModel(EmaneModel):
# ( 'name', 'type', 'default', 'possible-value-list', 'caption')
# MAC parameters
_confmatrix_mac_base = [
("enablepromiscuousmode", coreapi.CONF_DATA_TYPE_BOOL, '0',
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, '0',
'True,False', 'enable promiscuous mode'),
("datarate", coreapi.CONF_DATA_TYPE_UINT32, '1M',
("datarate", ConfigDataTypes.UINT32.value, '1M',
'', 'data rate (bps)'),
("flowcontrolenable", coreapi.CONF_DATA_TYPE_BOOL, '0',
("flowcontrolenable", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable traffic flow control'),
("flowcontroltokens", coreapi.CONF_DATA_TYPE_UINT16, '10',
("flowcontroltokens", ConfigDataTypes.UINT16.value, '10',
'', 'number of flow control tokens'),
("pcrcurveuri", coreapi.CONF_DATA_TYPE_STRING,
("pcrcurveuri", ConfigDataTypes.STRING.value,
'%s/rfpipepcr.xml' % xml_path,
'', 'SINR/PCR curve file'),
]
_confmatrix_mac_081 = [
("jitter", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
("jitter", ConfigDataTypes.FLOAT.value, '0.0',
'', 'transmission jitter (usec)'),
("delay", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
("delay", ConfigDataTypes.FLOAT.value, '0.0',
'', 'transmission delay (usec)'),
("transmissioncontrolmap", coreapi.CONF_DATA_TYPE_STRING, '',
("transmissioncontrolmap", ConfigDataTypes.STRING.value, '',
'', 'tx control map (nem:rate:freq:tx_dBm)'),
("enabletighttiming", coreapi.CONF_DATA_TYPE_BOOL, '0',
("enabletighttiming", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable tight timing for pkt delay'),
]
_confmatrix_mac_091 = [
("jitter", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
("jitter", ConfigDataTypes.FLOAT.value, '0.0',
'', 'transmission jitter (sec)'),
("delay", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
("delay", ConfigDataTypes.FLOAT.value, '0.0',
'', 'transmission delay (sec)'),
('radiometricenable', coreapi.CONF_DATA_TYPE_BOOL, '0',
('radiometricenable', ConfigDataTypes.BOOL.value, '0',
'On,Off', 'report radio metrics via R2RI'),
('radiometricreportinterval', coreapi.CONF_DATA_TYPE_FLOAT, '1.0',
('radiometricreportinterval', ConfigDataTypes.FLOAT.value, '1.0',
'', 'R2RI radio metric report interval (sec)'),
('neighbormetricdeletetime', coreapi.CONF_DATA_TYPE_FLOAT, '60.0',
('neighbormetricdeletetime', ConfigDataTypes.FLOAT.value, '60.0',
'', 'R2RI neighbor table inactivity time (sec)'),
]
if Emane.version >= Emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
_confmatrix_mac = _confmatrix_mac_base + _confmatrix_mac_091
else:
_confmatrix_mac = _confmatrix_mac_base + _confmatrix_mac_081
# PHY parameters from Universal PHY
_confmatrix_phy = EmaneUniversalModel._confmatrix
_confmatrix_phy = EmaneUniversalModel.config_matrix
_confmatrix = _confmatrix_mac + _confmatrix_phy
config_matrix = _confmatrix_mac + _confmatrix_phy
# value groupings
_confgroups = "RF-PIPE MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" \
% ( len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(_confmatrix))
config_groups = "RF-PIPE MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(config_matrix))
def buildnemxmlfiles(self, e, ifc):
''' 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.
'''
values = e.getifcconfig(self.objid, self._name,
"""
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.
"""
values = e.getifcconfig(self.object_id, self.name,
self.getdefaultvalues(), ifc)
if values is None:
return
nemdoc = e.xmldoc("nem")
nem = nemdoc.getElementsByTagName("nem").pop()
nem.setAttribute("name", "RF-PIPE NEM")
e.appendtransporttonem(nemdoc, nem, self.objid, ifc)
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc)
mactag = nemdoc.createElement("mac")
mactag.setAttribute("definition", self.macxmlname(ifc))
nem.appendChild(mactag)
@ -115,7 +111,7 @@ class EmaneRfPipeModel(EmaneModel):
mac.setAttribute("name", "RF-PIPE MAC")
mac.setAttribute("library", "rfpipemaclayer")
if e.version < e.EMANE091 and \
self.valueof("transmissioncontrolmap", values) is "":
self.valueof("transmissioncontrolmap", values) is "":
macnames.remove("transmissioncontrolmap")
# EMANE 0.7.4 support
if e.version == e.EMANE074:
@ -124,10 +120,8 @@ class EmaneRfPipeModel(EmaneModel):
values = list(values)
values[i] = self.emane074_fixup(values[i], 1000)
# append MAC options to macdoc
map(lambda n: mac.appendChild(e.xmlparam(macdoc, n, \
self.valueof(n, values))), macnames)
map(lambda n: mac.appendChild(e.xmlparam(macdoc, n, self.valueof(n, values))), macnames)
e.xmlwrite(macdoc, self.macxmlname(ifc))
phydoc = EmaneUniversalModel.getphydoc(e, self, values, phynames)
e.xmlwrite(phydoc, self.phyxmlname(ifc))

View file

@ -1,91 +1,85 @@
#
# CORE
# Copyright (c)2013 Company.
# See the LICENSE file included in this distribution.
#
# author: Name <email@company.com>
#
'''
"""
tdma.py: EMANE TDMA model bindings for CORE
'''
"""
from core import emane
from core.emane.emanemodel import EmaneModel
from core.emane.universal import EmaneUniversalModel
from core.enumerations import ConfigDataTypes
from core.misc import log
logger = log.get_logger(__name__)
import sys
import string
try:
from emanesh.events import EventService
except:
pass
from core.api import coreapi
from core.constants import *
from emane import Emane, EmaneModel
from universal import EmaneUniversalModel
logger.error("error importing emanesh")
class EmaneTdmaModel(EmaneModel):
def __init__(self, session, objid = None, verbose = False):
EmaneModel.__init__(self, session, objid, verbose)
def __init__(self, session, object_id=None):
EmaneModel.__init__(self, session, object_id)
# model name
_name = "emane_tdma"
if Emane.version >= Emane.EMANE101:
name = "emane_tdma"
if emane.VERSION >= emane.EMANE101:
xml_path = '/usr/share/emane/xml/models/mac/tdmaeventscheduler'
else:
raise Exception("EMANE TDMA requires EMANE 1.0.1 or greater")
# MAC parameters
_confmatrix_mac = [
("enablepromiscuousmode", coreapi.CONF_DATA_TYPE_BOOL, '0',
("enablepromiscuousmode", ConfigDataTypes.BOOL.value, '0',
'True,False', 'enable promiscuous mode'),
("flowcontrolenable", coreapi.CONF_DATA_TYPE_BOOL, '0',
("flowcontrolenable", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable traffic flow control'),
("flowcontroltokens", coreapi.CONF_DATA_TYPE_UINT16, '10',
("flowcontroltokens", ConfigDataTypes.UINT16.value, '10',
'', 'number of flow control tokens'),
("fragmentcheckthreshold", coreapi.CONF_DATA_TYPE_UINT16, '2',
("fragmentcheckthreshold", ConfigDataTypes.UINT16.value, '2',
'', 'rate in seconds for check if fragment reassembly efforts should be abandoned'),
("fragmenttimeoutthreshold", coreapi.CONF_DATA_TYPE_UINT16, '5',
("fragmenttimeoutthreshold", ConfigDataTypes.UINT16.value, '5',
'', 'threshold in seconds to wait for another packet fragment for reassembly'),
('neighbormetricdeletetime', coreapi.CONF_DATA_TYPE_FLOAT, '60.0',
('neighbormetricdeletetime', ConfigDataTypes.FLOAT.value, '60.0',
'', 'neighbor RF reception timeout for removal from neighbor table (sec)'),
('neighbormetricupdateinterval', coreapi.CONF_DATA_TYPE_FLOAT, '1.0',
('neighbormetricupdateinterval', ConfigDataTypes.FLOAT.value, '1.0',
'', 'neighbor table update interval (sec)'),
("pcrcurveuri", coreapi.CONF_DATA_TYPE_STRING, '%s/tdmabasemodelpcr.xml' % xml_path,
("pcrcurveuri", ConfigDataTypes.STRING.value, '%s/tdmabasemodelpcr.xml' % xml_path,
'', 'SINR/PCR curve file'),
("queue.aggregationenable", coreapi.CONF_DATA_TYPE_BOOL, '1',
("queue.aggregationenable", ConfigDataTypes.BOOL.value, '1',
'On,Off', 'enable transmit packet aggregation'),
('queue.aggregationslotthreshold', coreapi.CONF_DATA_TYPE_FLOAT, '90.0',
('queue.aggregationslotthreshold', ConfigDataTypes.FLOAT.value, '90.0',
'', 'percentage of a slot that must be filled in order to conclude aggregation'),
("queue.depth", coreapi.CONF_DATA_TYPE_UINT16, '256',
("queue.depth", ConfigDataTypes.UINT16.value, '256',
'', 'size of the per service class downstream packet queues (packets)'),
("queue.fragmentationenable", coreapi.CONF_DATA_TYPE_BOOL, '1',
("queue.fragmentationenable", ConfigDataTypes.BOOL.value, '1',
'On,Off', 'enable packet fragmentation (over multiple slots)'),
("queue.strictdequeueenable", coreapi.CONF_DATA_TYPE_BOOL, '0',
("queue.strictdequeueenable", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable strict dequeueing to specified queues only'),
]
# PHY parameters from Universal PHY
_confmatrix_phy = EmaneUniversalModel._confmatrix
_confmatrix_phy = EmaneUniversalModel.config_matrix
_confmatrix = _confmatrix_mac + _confmatrix_phy
config_matrix = _confmatrix_mac + _confmatrix_phy
# value groupings
_confgroups = "TDMA MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % \
(len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(_confmatrix))
config_groups = "TDMA MAC Parameters:1-%d|Universal PHY Parameters:%d-%d" % (
len(_confmatrix_mac), len(_confmatrix_mac) + 1, len(config_matrix))
def buildnemxmlfiles(self, e, ifc):
''' 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.
'''
values = e.getifcconfig(self.objid, self._name,
self.getdefaultvalues(), ifc)
"""
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.
"""
values = e.getifcconfig(self.object_id, self.name, self.getdefaultvalues(), ifc)
if values is None:
return
nemdoc = e.xmldoc("nem")
nem = nemdoc.getElementsByTagName("nem").pop()
nem.setAttribute("name", "TDMA NEM")
e.appendtransporttonem(nemdoc, nem, self.objid, ifc)
e.appendtransporttonem(nemdoc, nem, self.object_id, ifc)
mactag = nemdoc.createElement("mac")
mactag.setAttribute("definition", self.macxmlname(ifc))
nem.appendChild(mactag)
@ -105,10 +99,8 @@ class EmaneTdmaModel(EmaneModel):
mac.setAttribute("name", "TDMA MAC")
mac.setAttribute("library", "tdmaeventschedulerradiomodel")
# append MAC options to macdoc
map(lambda n: mac.appendChild(e.xmlparam(macdoc, n, \
self.valueof(n, values))), macnames)
map(lambda n: mac.appendChild(e.xmlparam(macdoc, n, self.valueof(n, values))), macnames)
e.xmlwrite(macdoc, self.macxmlname(ifc))
phydoc = EmaneUniversalModel.getphydoc(e, self, values, phynames)
e.xmlwrite(phydoc, self.phyxmlname(ifc))

View file

@ -1,99 +1,97 @@
#
# CORE
# Copyright (c)2010-2014 the Boeing Company.
# See the LICENSE file included in this distribution.
#
# author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
#
'''
"""
universal.py: EMANE Universal PHY model for CORE. Enumerates configuration items
used for the Universal PHY.
'''
"""
from core import emane
from core.emane.emanemodel import EmaneModel
from core.enumerations import ConfigDataTypes
from core.misc import log
logger = log.get_logger(__name__)
import sys
import string
try:
from emanesh.events import EventService
except:
pass
from core.api import coreapi
from core.constants import *
from emane import Emane, EmaneModel
except ImportError:
logger.error("error importing emanesh")
class EmaneUniversalModel(EmaneModel):
''' This Univeral PHY model is meant to be imported by other models,
not instantiated.
'''
def __init__(self, session, objid = None, verbose = False):
raise SyntaxError
"""
This Univeral PHY model is meant to be imported by other models,
not instantiated.
"""
_name = "emane_universal"
def __init__(self, session, object_id=None):
raise NotImplemented("Cannot use this class directly")
name = "emane_universal"
_xmlname = "universalphy"
_xmllibrary = "universalphylayer"
# universal PHY parameters
_confmatrix_base = [
("bandwidth", coreapi.CONF_DATA_TYPE_UINT64, '1M',
'', 'rf bandwidth (hz)'),
("frequency", coreapi.CONF_DATA_TYPE_UINT64, '2.347G',
'','frequency (Hz)'),
("frequencyofinterest", coreapi.CONF_DATA_TYPE_UINT64, '2.347G',
'','frequency of interest (Hz)'),
("subid", coreapi.CONF_DATA_TYPE_UINT16, '1',
'','subid'),
("systemnoisefigure", coreapi.CONF_DATA_TYPE_FLOAT, '4.0',
'','system noise figure (dB)'),
("txpower", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
'','transmit power (dBm)'),
("bandwidth", ConfigDataTypes.UINT64.value, '1M',
'', 'rf bandwidth (hz)'),
("frequency", ConfigDataTypes.UINT64.value, '2.347G',
'', 'frequency (Hz)'),
("frequencyofinterest", ConfigDataTypes.UINT64.value, '2.347G',
'', 'frequency of interest (Hz)'),
("subid", ConfigDataTypes.UINT16.value, '1',
'', 'subid'),
("systemnoisefigure", ConfigDataTypes.FLOAT.value, '4.0',
'', 'system noise figure (dB)'),
("txpower", ConfigDataTypes.FLOAT.value, '0.0',
'', 'transmit power (dBm)'),
]
_confmatrix_081 = [
("antennagain", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
'','antenna gain (dBi)'),
("antennaazimuth", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
'','antenna azimuth (deg)'),
("antennaelevation", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
'','antenna elevation (deg)'),
("antennaprofileid", coreapi.CONF_DATA_TYPE_STRING, '1',
'','antenna profile ID'),
("antennaprofilemanifesturi", coreapi.CONF_DATA_TYPE_STRING, '',
'','antenna profile manifest URI'),
("antennaprofileenable", coreapi.CONF_DATA_TYPE_BOOL, '0',
'On,Off','antenna profile mode'),
("defaultconnectivitymode", coreapi.CONF_DATA_TYPE_BOOL, '1',
'On,Off','default connectivity'),
("frequencyofinterestfilterenable", coreapi.CONF_DATA_TYPE_BOOL, '1',
'On,Off','frequency of interest filter enable'),
("noiseprocessingmode", coreapi.CONF_DATA_TYPE_BOOL, '0',
'On,Off','enable noise processing'),
("pathlossmode", coreapi.CONF_DATA_TYPE_STRING, '2ray',
'pathloss,2ray,freespace','path loss mode'),
("antennagain", ConfigDataTypes.FLOAT.value, '0.0',
'', 'antenna gain (dBi)'),
("antennaazimuth", ConfigDataTypes.FLOAT.value, '0.0',
'', 'antenna azimuth (deg)'),
("antennaelevation", ConfigDataTypes.FLOAT.value, '0.0',
'', 'antenna elevation (deg)'),
("antennaprofileid", ConfigDataTypes.STRING.value, '1',
'', 'antenna profile ID'),
("antennaprofilemanifesturi", ConfigDataTypes.STRING.value, '',
'', 'antenna profile manifest URI'),
("antennaprofileenable", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'antenna profile mode'),
("defaultconnectivitymode", ConfigDataTypes.BOOL.value, '1',
'On,Off', 'default connectivity'),
("frequencyofinterestfilterenable", ConfigDataTypes.BOOL.value, '1',
'On,Off', 'frequency of interest filter enable'),
("noiseprocessingmode", ConfigDataTypes.BOOL.value, '0',
'On,Off', 'enable noise processing'),
("pathlossmode", ConfigDataTypes.STRING.value, '2ray',
'pathloss,2ray,freespace', 'path loss mode'),
]
_confmatrix_091 = [
("fixedantennagain", coreapi.CONF_DATA_TYPE_FLOAT, '0.0',
'','antenna gain (dBi)'),
("fixedantennagainenable", coreapi.CONF_DATA_TYPE_BOOL, '1',
'On,Off','enable fixed antenna gain'),
("noisemode", coreapi.CONF_DATA_TYPE_STRING, 'none',
'none,all,outofband','noise processing mode'),
("noisebinsize", coreapi.CONF_DATA_TYPE_UINT64, '20',
'','noise bin size in microseconds'),
("propagationmodel", coreapi.CONF_DATA_TYPE_STRING, '2ray',
'precomputed,2ray,freespace','path loss mode'),
("fixedantennagain", ConfigDataTypes.FLOAT.value, '0.0',
'', 'antenna gain (dBi)'),
("fixedantennagainenable", ConfigDataTypes.BOOL.value, '1',
'On,Off', 'enable fixed antenna gain'),
("noisemode", ConfigDataTypes.STRING.value, 'none',
'none,all,outofband', 'noise processing mode'),
("noisebinsize", ConfigDataTypes.UINT64.value, '20',
'', 'noise bin size in microseconds'),
("propagationmodel", ConfigDataTypes.STRING.value, '2ray',
'precomputed,2ray,freespace', 'path loss mode'),
]
if Emane.version >= Emane.EMANE091:
_confmatrix = _confmatrix_base + _confmatrix_091
if emane.VERSION >= emane.EMANE091:
config_matrix = _confmatrix_base + _confmatrix_091
else:
_confmatrix = _confmatrix_base + _confmatrix_081
config_matrix = _confmatrix_base + _confmatrix_081
# old parameters
_confmatrix_ver074 = [
("antennaazimuthbeamwidth", coreapi.CONF_DATA_TYPE_FLOAT, '360.0',
'','azimith beam width (deg)'),
("antennaelevationbeamwidth", coreapi.CONF_DATA_TYPE_FLOAT, '180.0',
'','elevation beam width (deg)'),
("antennatype", coreapi.CONF_DATA_TYPE_STRING, 'omnidirectional',
'omnidirectional,unidirectional','antenna type'),
]
("antennaazimuthbeamwidth", ConfigDataTypes.FLOAT.value, '360.0',
'', 'azimith beam width (deg)'),
("antennaelevationbeamwidth", ConfigDataTypes.FLOAT.value, '180.0',
'', 'elevation beam width (deg)'),
("antennatype", ConfigDataTypes.STRING.value, 'omnidirectional',
'omnidirectional,unidirectional', 'antenna type'),
]
# parameters that require unit conversion for 0.7.4
_update_ver074 = ("bandwidth", "frequency", "frequencyofinterest")
@ -102,16 +100,15 @@ class EmaneUniversalModel(EmaneModel):
"antennaprofilemanifesturi",
"frequencyofinterestfilterenable")
@classmethod
def getphydoc(cls, e, mac, values, phynames):
phydoc = e.xmldoc("phy")
phy = phydoc.getElementsByTagName("phy").pop()
phy.setAttribute("name", cls._xmlname)
if e.version < e.EMANE091:
if emane.VERSION < emane.EMANE091:
phy.setAttribute("library", cls._xmllibrary)
# EMANE 0.7.4 suppport - to be removed when 0.7.4 support is deprecated
if e.version == e.EMANE074:
if emane.VERSION == emane.EMANE074:
names = mac.getnames()
values = list(values)
phynames = list(phynames)
@ -128,7 +125,7 @@ class EmaneUniversalModel(EmaneModel):
phy.appendChild(e.xmlparam(phydoc, old[0], old[2]))
frequencies = None
if e.version >= e.EMANE091:
if emane.VERSION >= emane.EMANE091:
name = "frequencyofinterest"
value = mac.valueof(name, values)
frequencies = cls.valuestrtoparamlist(phydoc, name, value)
@ -137,10 +134,7 @@ class EmaneUniversalModel(EmaneModel):
phynames.remove("frequencyofinterest")
# append all PHY options to phydoc
map( lambda n: phy.appendChild(e.xmlparam(phydoc, n, \
mac.valueof(n, values))), phynames)
map(lambda n: phy.appendChild(e.xmlparam(phydoc, n, mac.valueof(n, values))), phynames)
if frequencies:
phy.appendChild(frequencies)
return phydoc