diff --git a/.gitignore b/.gitignore index 6289e42c..3c6a8ea2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ +.debbuild .deps +.rpmbuild .version .version.date Makefile @@ -11,5 +13,6 @@ config.h.in config.log config.status configure +core-*.tar.gz debian stamp-h1 diff --git a/configure.ac b/configure.ac index 93c3b917..a81fa8e7 100644 --- a/configure.ac +++ b/configure.ac @@ -198,15 +198,6 @@ if test "x$enable_daemon" = "xyes" ; then AC_CHECK_FUNCS([atexit dup2 gettimeofday memset socket strerror uname]) fi -# simple architecture detection -if test `uname -m` = "x86_64"; then - ARCH=amd64 -else - ARCH=i386 -fi -AC_MSG_RESULT([using architecture $ARCH]) -AC_SUBST(ARCH) - # Host-specific detection want_linux_netns=no want_bsd=no diff --git a/daemon/core/emane/emane.py b/daemon/core/emane/emane.py index 69ed3be1..45086a15 100644 --- a/daemon/core/emane/emane.py +++ b/daemon/core/emane/emane.py @@ -45,8 +45,8 @@ class Emane(ConfigurableManager): (SUCCESS, NOT_NEEDED, NOT_READY) = (0, 1, 2) EVENTCFGVAR = 'LIBEMANEEVENTSERVICECONFIG' # possible self.version values - (EMANEUNK, EMANE074, EMANE081, EMANE091, EMANE092, EMANE093) = \ - (0, 7, 8, 91, 92, 93) + (EMANEUNK, EMANE074, EMANE081, EMANE091, EMANE092, EMANE093, EMANE101) = \ + (0, 7, 8, 91, 92, 93, 101) DEFAULT_LOG_LEVEL = 3 def __init__(self, session): @@ -746,7 +746,7 @@ class Emane(ConfigurableManager): ''' for n in sorted(self._objs.keys()): emanenode = self._objs[n] - nems = emanenode.buildnemxmlfiles(self) + emanenode.buildnemxmlfiles(self) def appendtransporttonem(self, doc, nem, nodenum, ifc=None): ''' Given a nem XML node and EMANE WLAN node number, append @@ -1175,6 +1175,8 @@ def emane_version(): v = Emane.EMANE092 elif result.startswith('0.9.3'): v = Emane.EMANE093 + elif result.startswith('1.0.1'): + v = Emane.EMANE101 return v, result.strip() # set version variables for the Emane class diff --git a/daemon/core/emane/rfpipe.py b/daemon/core/emane/rfpipe.py index 36722524..6eb329e9 100644 --- a/daemon/core/emane/rfpipe.py +++ b/daemon/core/emane/rfpipe.py @@ -124,8 +124,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) diff --git a/daemon/core/emane/tdma.py b/daemon/core/emane/tdma.py new file mode 100644 index 00000000..cc705f56 --- /dev/null +++ b/daemon/core/emane/tdma.py @@ -0,0 +1,114 @@ + +# +# CORE +# Copyright (c)2013 Company. +# See the LICENSE file included in this distribution. +# +# author: Name +# +''' +tdma.py: EMANE TDMA model bindings for CORE +''' + +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 + +class EmaneTdmaModel(EmaneModel): + def __init__(self, session, objid = None, verbose = False): + EmaneModel.__init__(self, session, objid, verbose) + + # model name + _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', + 'True,False', 'enable promiscuous mode'), + ("flowcontrolenable", coreapi.CONF_DATA_TYPE_BOOL, '0', + 'On,Off', 'enable traffic flow control'), + ("flowcontroltokens", coreapi.CONF_DATA_TYPE_UINT16, '10', + '', 'number of flow control tokens'), + ("fragmentcheckthreshold", coreapi.CONF_DATA_TYPE_UINT16, '2', + '', 'rate in seconds for check if fragment reassembly efforts should be abandoned'), + ("fragmenttimeoutthreshold", coreapi.CONF_DATA_TYPE_UINT16, '5', + '', 'threshold in seconds to wait for another packet fragment for reassembly'), + ('neighbormetricdeletetime', coreapi.CONF_DATA_TYPE_FLOAT, '60.0', + '', 'neighbor RF reception timeout for removal from neighbor table (sec)'), + ('neighbormetricupdateinterval', coreapi.CONF_DATA_TYPE_FLOAT, '1.0', + '', 'neighbor table update interval (sec)'), + ("pcrcurveuri", coreapi.CONF_DATA_TYPE_STRING, '%s/tdmabasemodelpcr.xml' % xml_path, + '', 'SINR/PCR curve file'), + ("queue.aggregationenable", coreapi.CONF_DATA_TYPE_BOOL, '1', + 'On,Off', 'enable transmit packet aggregation'), + ('queue.aggregationslotthreshold', coreapi.CONF_DATA_TYPE_FLOAT, '90.0', + '', 'percentage of a slot that must be filled in order to conclude aggregation'), + ("queue.depth", coreapi.CONF_DATA_TYPE_UINT16, '256', + '', 'size of the per service class downstream packet queues (packets)'), + ("queue.fragmentationenable", coreapi.CONF_DATA_TYPE_BOOL, '1', + 'On,Off', 'enable packet fragmentation (over multiple slots)'), + ("queue.strictdequeueenable", coreapi.CONF_DATA_TYPE_BOOL, '0', + 'On,Off', 'enable strict dequeueing to specified queues only'), + ] + + # PHY parameters from Universal PHY + _confmatrix_phy = EmaneUniversalModel._confmatrix + + _confmatrix = _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)) + + 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) + 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) + mactag = nemdoc.createElement("mac") + mactag.setAttribute("definition", self.macxmlname(ifc)) + nem.appendChild(mactag) + phytag = nemdoc.createElement("phy") + phytag.setAttribute("definition", self.phyxmlname(ifc)) + nem.appendChild(phytag) + e.xmlwrite(nemdoc, self.nemxmlname(ifc)) + + names = list(self.getnames()) + macnames = names[:len(self._confmatrix_mac)] + phynames = names[len(self._confmatrix_mac):] + # make any changes to the mac/phy names here to e.g. exclude them from + # the XML output + + macdoc = e.xmldoc("mac") + mac = macdoc.getElementsByTagName("mac").pop() + 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) + e.xmlwrite(macdoc, self.macxmlname(ifc)) + + phydoc = EmaneUniversalModel.getphydoc(e, self, values, phynames) + e.xmlwrite(phydoc, self.phyxmlname(ifc)) + diff --git a/daemon/core/netns/vnet.py b/daemon/core/netns/vnet.py index 2c364fbb..8dd1c494 100644 --- a/daemon/core/netns/vnet.py +++ b/daemon/core/netns/vnet.py @@ -11,8 +11,6 @@ vnet.py: PyCoreNet and LxBrNet classes that implement virtual networks using Linux Ethernet bridging and ebtables rules. ''' -import traceback - import os, sys, threading, time, subprocess from core.api import coreapi @@ -347,10 +345,6 @@ class LxBrNet(PyCoreNet): ''' Configure link parameters by applying tc queuing disciplines on the interface. ''' - - #sys.stderr.write("enter linkconfig() ...\n") - #traceback.print_stack() - if devname is None: devname = netif.localname tc = [TC_BIN, "qdisc", "replace", "dev", devname] diff --git a/daemon/core/services/nrl.py b/daemon/core/services/nrl.py index 5afe202c..481185bf 100644 --- a/daemon/core/services/nrl.py +++ b/daemon/core/services/nrl.py @@ -91,7 +91,7 @@ class NrlNhdp(NrlService): servicenames = map(lambda x: x._name, services) if "SMF" in servicenames: - cmd += " -flooding ecds" + cmd += " -flooding ecds-etx sticky" cmd += " -smfClient %s_smf" % node.name netifs = filter(lambda x: not getattr(x, 'control', False), \ diff --git a/daemon/core/session.py b/daemon/core/session.py index 9e226f53..223bd9e9 100644 --- a/daemon/core/session.py +++ b/daemon/core/session.py @@ -14,6 +14,7 @@ that manages a CORE session. import os, sys, tempfile, shutil, shlex, atexit, gc, pwd import threading, time, random import traceback +import subprocess from core.api import coreapi if os.uname()[0] == "Linux": @@ -289,8 +290,16 @@ class Session(object): self.warn("Error writing hook '%s': %s" % (filename, e)) self.info("Running hook %s for state %s" % (filename, state)) try: - check_call(["/bin/sh", filename], cwd=self.sessiondir, - env=self.getenviron()) + stdout = open(os.path.join(self.sessiondir, + filename + '.log'), 'w') + stderr = subprocess.STDOUT + except: + stdout = None + stderr = None + try: + check_call(["/bin/sh", filename], stdin=open(os.devnull, 'r'), + stdout=stdout, stderr=stderr, close_fds=True, + cwd=self.sessiondir, env=self.getenviron()) except Exception, e: self.warn("Error running hook '%s' for state %s: %s" % (filename, state, e)) diff --git a/packaging/deb.mk b/packaging/deb.mk new file mode 100644 index 00000000..14116c12 --- /dev/null +++ b/packaging/deb.mk @@ -0,0 +1,56 @@ +DEBBUILD = .debbuild + +CORE_VERSION = $(shell cat .version 2> /dev/null) + +COREBUILD = $(DEBBUILD)/core-$(CORE_VERSION) + +.PHONY: all +all: clean .version build + +.PHONY: clean +clean: + rm -rf $(DEBBUILD) + +.PHONY: build +build: changelog + cd $(COREBUILD) && dpkg-buildpackage -b -us -uc + @printf "\ndebian packages built in $(DEBBUILD)\n\n" + +.PHONY: changelog +changelog: debian + echo "core ($(CORE_VERSION)-1) unstable; urgency=low" > $(COREBUILD)/debian/changelog.generated + echo " * interim package generated from source" >> $(COREBUILD)/debian/changelog.generated + echo " -- CORE Developers $$(date -R)" >> $(COREBUILD)/debian/changelog.generated + cd $(COREBUILD)/debian && \ + { test ! -L changelog && mv -f changelog changelog.save; } && \ + { test "$$(readlink changelog)" = "changelog.generated" || \ + ln -sf changelog.generated changelog; } + +.PHONY: debian +debian: corebuild + cd $(COREBUILD) && ln -s packaging/deb debian + +.PHONY: corebuild +corebuild: $(DEBBUILD) dist + tar -C $(DEBBUILD) -xzf core-$(CORE_VERSION).tar.gz + +.PHONY: dist +dist: Makefile + $(MAKE) dist + +Makefile: configure + ./configure + +configure: bootstrap.sh + ./bootstrap.sh + +bootstrap.sh: + @printf "\nERROR: make must be called from the top-level directory:\n" + @printf " make -f packaging/$(lastword $(MAKEFILE_LIST))\n\n" + @false + +.version: Makefile + $(MAKE) $@ + +$(DEBBUILD): + mkdir -p $@ diff --git a/packaging/deb/core-daemon.install.in b/packaging/deb/core-daemon.install.in index 886be338..4656c188 100644 --- a/packaging/deb/core-daemon.install.in +++ b/packaging/deb/core-daemon.install.in @@ -1,23 +1,20 @@ #! /usr/bin/dh-exec @SBINDIR@ @CORE_CONF_DIR@ -# configure prints a warning if CORE_DATA_DIR is used here -# ATdatarootdirAT is expanding to ${datarootdir}/man/man1/ -/usr/share/core/examples/corens3 -/usr/share/core/examples/*.py -/usr/share/core/examples/hooks -/usr/share/core/examples/myservices -/usr/share/core/examples/netns -/usr/share/core/examples/services -# ATmandirAT is expanding to ${datarootdir}/man/man1/core-daemon.1 -/usr/share/man/man1/vnoded.1 -/usr/share/man/man1/vcmd.1 -/usr/share/man/man1/netns.1 -/usr/share/man/man1/core-daemon.1 -/usr/share/man/man1/coresendmsg.1 -/usr/share/man/man1/core-cleanup.1 -/usr/share/man/man1/core-xen-cleanup.1 -# ATpythondirAT is expanding to ${prefix}/lib/python2.7/dist-packages -/usr/lib/python2.7/dist-packages +@CORE_DATA_DIR@/examples/corens3 +@CORE_DATA_DIR@/examples/*.py +@CORE_DATA_DIR@/examples/hooks +@CORE_DATA_DIR@/examples/myservices +@CORE_DATA_DIR@/examples/netns +@CORE_DATA_DIR@/examples/services +# ATmandirAT is expanding to ${datarootdir}/man +@datarootdir@/man/man1/vnoded.1 +@datarootdir@/man/man1/vcmd.1 +@datarootdir@/man/man1/netns.1 +@datarootdir@/man/man1/core-daemon.1 +@datarootdir@/man/man1/coresendmsg.1 +@datarootdir@/man/man1/core-cleanup.1 +@datarootdir@/man/man1/core-xen-cleanup.1 +@pyprefix@/lib/python2.7/dist-packages /etc/init.d /etc/logrotate.d diff --git a/packaging/deb/core-gui.install.in b/packaging/deb/core-gui.install.in index a8e85893..89bbc19c 100644 --- a/packaging/deb/core-gui.install.in +++ b/packaging/deb/core-gui.install.in @@ -1,11 +1,9 @@ #! /usr/bin/dh-exec @BINDIR@/core-gui @CORE_LIB_DIR@ -# configure prints a warning if CORE_DATA_DIR is used here -# ATdatarootdirAT is expanding to ${datarootdir}/man/man1/ -/usr/share/core/icons -/usr/share/core/examples/configs -/usr/share/pixmaps -/usr/share/applications -# ATmandirAT is expanding to ${datarootdir}/man/man1/core-gui.1 -/usr/share/man/man1/core-gui.1 +@CORE_DATA_DIR@/icons +@CORE_DATA_DIR@/examples/configs +@datarootdir@/pixmaps +@datarootdir@/applications +# ATmandirAT is expanding to ${datarootdir}/man +@datarootdir@/man/man1/core-gui.1 diff --git a/packaging/rpm.mk b/packaging/rpm.mk new file mode 100644 index 00000000..cb70c141 --- /dev/null +++ b/packaging/rpm.mk @@ -0,0 +1,40 @@ +RPMBUILD = .rpmbuild + +CORE_VERSION = $(shell cat .version 2> /dev/null) + +.PHONY: all +all: clean .version build + +.PHONY: clean +clean: + rm -rf $(RPMBUILD) + +.PHONY: build +build: dist + for d in SOURCES SPECS; do mkdir -p $(RPMBUILD)/$$d; done + cp -afv core-$(CORE_VERSION).tar.gz $(RPMBUILD)/SOURCES + cp -afv packaging/rpm/core.spec $(RPMBUILD)/SPECS + rpmbuild -bb --clean $(RPMBUILD)/SPECS/core.spec \ + --define "_topdir $$PWD/.rpmbuild" + @printf "\nRPM packages saved in $(RPMBUILD)/RPMS\n\n" + +.PHONY: dist +dist: Makefile + $(MAKE) dist + +Makefile: configure + ./configure --prefix=/usr --exec-prefix=/usr + +configure: bootstrap.sh + ./bootstrap.sh + +bootstrap.sh: + @printf "\nERROR: make must be called from the top-level directory:\n" + @printf " make -f packaging/$(lastword $(MAKEFILE_LIST))\n\n" + @false + +.version: Makefile + $(MAKE) $@ + +$(RPMBUILD): + mkdir -p $@ diff --git a/packaging/rpm/core.spec.in b/packaging/rpm/core.spec.in index 1c6d5da6..7a586ba3 100644 --- a/packaging/rpm/core.spec.in +++ b/packaging/rpm/core.spec.in @@ -336,6 +336,7 @@ fi %{python_sitelib}/core/emane/__init__.py* %{python_sitelib}/core/emane/nodes.py* %{python_sitelib}/core/emane/rfpipe.py* +%{python_sitelib}/core/emane/tdma.py* %{python_sitelib}/core/emane/universal.py* %{python_sitelib}/core/__init__.py* %{python_sitelib}/core/location.py* @@ -402,7 +403,7 @@ fi %{_sbindir}/vnoded %changelog -* Thu Jun 5 2015 CORE Developers - 4.8 +* Fri Jun 5 2015 CORE Developers - 4.8 - Support for NRL Network Modeling Framework (NMF) XML representation, bugfixes * Wed Aug 6 2014 Jeff Ahrenholz - 4.7 - EMANE 0.9.1, asymmetric links, bugfixes