From d30f4d66de96a67f8cdfe4cc8c74a439323d7eb8 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 5 Jul 2007 14:38:39 +0100 Subject: [PATCH 01/14] WAF: make the --run option work again --- wscript | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wscript b/wscript index b5be10dda..59b11569c 100644 --- a/wscript +++ b/wscript @@ -124,10 +124,7 @@ def build(bld): variant_env = bld.env_of_name(variant_name) bld.m_allenvs['default'] = variant_env # switch to the active variant - if Params.g_options.run: - run_program(Params.g_options.run) - return - elif Params.g_options.shell: + if Params.g_options.shell: run_shell() return @@ -154,6 +151,9 @@ def shutdown(): if Params.g_options.doxygen: doxygen() + if Params.g_options.run: + run_program(Params.g_options.run) + def _find_program(program_name): for obj in Object.g_allobjs: if obj.target == program_name: From 0f246d7f694ba597132f4eba6408fa5f167c8a09 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 5 Jul 2007 14:44:00 +0100 Subject: [PATCH 02/14] WAF: when the program specified by --run is not found, print a list of all available program names in the error message. --- wscript | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/wscript b/wscript index 59b11569c..f2a86df00 100644 --- a/wscript +++ b/wscript @@ -155,10 +155,15 @@ def shutdown(): run_program(Params.g_options.run) def _find_program(program_name): + found_programs = [] for obj in Object.g_allobjs: + if obj.m_type != 'program' or not obj.target: + continue + found_programs.append(obj.target) if obj.target == program_name: return obj - raise ValueError("progam '%s' not found" % (program_name,)) + raise ValueError("progam '%s' not found; available programs are: %r" + % (program_name, found_programs)) def _run_argv(argv): env = Params.g_build.env_of_name('default') @@ -199,8 +204,8 @@ def run_program(program_string): try: program_obj = _find_program(program_name) - except ValueError: - Params.fatal("progam '%s' not found" % (program_name,)) + except ValueError, ex: + Params.fatal(str(ex)) try: program_node, = program_obj.m_linktask.m_outputs From 0b32b0109f8f5e7630fa40dcfe1ab941fd1eb14b Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 5 Jul 2007 14:48:21 +0100 Subject: [PATCH 03/14] WAF: fix simple typo in error message. --- wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wscript b/wscript index f2a86df00..c90171b8c 100644 --- a/wscript +++ b/wscript @@ -162,7 +162,7 @@ def _find_program(program_name): found_programs.append(obj.target) if obj.target == program_name: return obj - raise ValueError("progam '%s' not found; available programs are: %r" + raise ValueError("program '%s' not found; available programs are: %r" % (program_name, found_programs)) def _run_argv(argv): From de608e90c195f36590ab0a109686648ff49e13d5 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sat, 7 Jul 2007 18:10:54 +0100 Subject: [PATCH 04/14] WAF: option --run now filters out programs not in the subtree starting at the launch dir --- wscript | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index c90171b8c..da8b140a5 100644 --- a/wscript +++ b/wscript @@ -8,6 +8,7 @@ import Params import Object import pproc as subprocess import optparse +import os.path Params.g_autoconfig = 1 @@ -154,11 +155,18 @@ def shutdown(): if Params.g_options.run: run_program(Params.g_options.run) -def _find_program(program_name): +def _find_program(program_name, env): + launch_dir = os.path.abspath(Params.g_cwd_launch) found_programs = [] for obj in Object.g_allobjs: if obj.m_type != 'program' or not obj.target: continue + + ## filter out programs not in the subtree starting at the launch dir + if not (obj.path.abspath().startswith(launch_dir) + or obj.path.abspath(env).startswith(launch_dir)): + continue + found_programs.append(obj.target) if obj.target == program_name: return obj @@ -203,7 +211,7 @@ def run_program(program_string): program_name = argv[0] try: - program_obj = _find_program(program_name) + program_obj = _find_program(program_name, env) except ValueError, ex: Params.fatal(str(ex)) From 65f894b7acabd24bdad49c96e12680cedf47ba2e Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sun, 8 Jul 2007 12:24:22 +0100 Subject: [PATCH 05/14] WAF: --run now runs the specified program from the directory where waf was invoked. --- wscript | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/wscript b/wscript index da8b140a5..c66fd987b 100644 --- a/wscript +++ b/wscript @@ -221,7 +221,13 @@ def run_program(program_string): Params.fatal("%s does not appear to be a program" % (program_name,)) execvec = [program_node.abspath(env)] + argv[1:] - return _run_argv(execvec) + + former_cwd = os.getcwd() + os.chdir(Params.g_cwd_launch) + try: + return _run_argv(execvec) + finally: + os.chdir(former_cwd) def run_shell(): From 441a8868a09382ca72b4356f064b0462062310e5 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 9 Jul 2007 14:31:52 +0100 Subject: [PATCH 06/14] Fix unit test assertion failure error message (was printing the value instead of the expression itself) --- src/core/test.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/test.h b/src/core/test.h index 982cb989c..356c08ee2 100644 --- a/src/core/test.h +++ b/src/core/test.h @@ -130,8 +130,8 @@ private: if (!(assertion)) \ { \ Failure () << __FILE__ << ":" <<__LINE__ \ - << ": assertion `" << (assertion) \ - << "'failed." << std::endl; \ + << ": assertion `" << #assertion \ + << "' failed." << std::endl; \ result = false; \ } From 3ce169b4e2c64da9f6a76d324eb3ad1670ce3918 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 9 Jul 2007 14:36:40 +0100 Subject: [PATCH 07/14] WAF: ignore errors on shutil.rmtree in dist_hook, so that waf dist works even when no docs were previously generated. --- wscript | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index c66fd987b..d6972910c 100644 --- a/wscript +++ b/wscript @@ -21,8 +21,8 @@ srcdir = '.' blddir = 'build' def dist_hook(srcdir, blddir): - shutil.rmtree("doc/html") - shutil.rmtree("doc/latex") + shutil.rmtree("doc/html", True) + shutil.rmtree("doc/latex", True) def set_options(opt): From 67fa3a8c823a94323a781aaca2a8156b544fd366 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 9 Jul 2007 06:43:11 -0700 Subject: [PATCH 08/14] WAF: --update build-waf.txt; add note about waf configure, add waf dist/distclean, remove ./ as part of system path to waf --- doc/build-waf.txt | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/doc/build-waf.txt b/doc/build-waf.txt index 056a45274..5d9d178ea 100644 --- a/doc/build-waf.txt +++ b/doc/build-waf.txt @@ -12,39 +12,53 @@ Gustavo Carneiro (gjcarneiro@gmail.com) is the maintainer. === Building with Waf === To build ns-3 with waf type the commands: - 1. ./waf configure [options] - 2. ./waf + 1. waf configure [options] + 2. waf -[ Note: if ./waf does not exist, see the section "Note for developers" below ] +[ Note: if waf does not exist in your path, see the section +"Note for developers" below ] -To see valid configure options, type ./waf --help. The most important +To see valid configure options, type waf --help. The most important option is -d . Valid debug levels (which are listed in -./waf --help) are: ultradebug, debug, release, and optimized. +waf --help) are: ultradebug, debug, release, and optimized. + +[ Note: Unlike some other build tools, to change the build target, +the option must be supplied during the configure stage rather than +the build stage (i.e., "waf -d optimized" will not work; instead, do +"waf -d optimized configure; waf" ] The resulting binaries are placed in build//srcpath. Other waf usages include: - 1. ./waf check + 1. waf check Runs the unit tests - 2. ./waf --doxygen + 2. waf --doxygen Run doxygen to generate documentation - 3. ./waf --lcov-report + 3. waf --lcov-report Run code coverage analysis (assuming the project was configured with --enable-gcov) - 4. ./waf --run "program [args]" + 4. waf --run "program [args]" Run a ns3 program, given its target name, with the given arguments. This takes care of automatically modifying the the path for finding the ns3 dynamic libraries in the environment before running the program. Note: the "program [args]" string is parsed using POSIX shell rules. - 5. ./waf --shell + 5. waf --shell Starts a nested system shell with modified environment to run ns3 programs. + 6. waf distclean + Cleans out the entire build/ directory + + 7. waf dist + The command 'waf dist' can be used to create a distribution tarball. + It includes all files in the source directory, except some particular + extensions that are blacklisted, such as back files (ending in ~). + === Extending ns-3 === @@ -90,13 +104,9 @@ developers should check it out from a subversion repository: tested to work correctly with ns3, although 'trunk' will likely work as well ] -Then it can be installed system-wide with 'sudo ./waf-light install'. +Then it can be installed system-wide with 'sudo waf-light install'. When preparing a distribution, the resulting 'waf' script, which is self contained (no external files needed), can be easily included in the tarball so that users downloading ns-3 can easily build it without having Waf installed (although Python >= 2.3 is still needed). -The command 'waf dist' can be used to create a distribution tarball. -It includes all files in the source directory, except some particular -extensions that are blacklisted, such as back files (ending in ~). - From 496313f56bfc19a08a3567711e1d1764f4758713 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 10 Jul 2007 13:37:17 +0100 Subject: [PATCH 09/14] WAF: add debugging symbols to optimized builds --- wscript | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wscript b/wscript index d6972910c..95dee9811 100644 --- a/wscript +++ b/wscript @@ -113,6 +113,14 @@ def configure(conf): variant_env.append_value('CXXDEFINES', 'NS3_DEBUG_ENABLE') variant_env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE') + ## In optimized builds we still want debugging symbols, e.g. for + ## profiling, and at least partially usable stack traces. + if 'optimized' in Params.g_options.debug_level.lower(): + for flag in variant_env['CXXFLAGS_DEBUG']: + ## this probably doesn't work for MSVC + if flag.startswith('-g'): + variant_env.append_value('CXXFLAGS', flag) + if sys.platform == 'win32': if os.path.basename(conf.env['CXX']).startswith("g++"): variant_env.append_value("LINKFLAGS", "-Wl,--enable-runtime-pseudo-reloc") From 5629eae3ae87838ca5ab295e8b5669e00ba5ac4d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 10 Jul 2007 13:42:23 +0100 Subject: [PATCH 10/14] WAF: don't change CXXFLAGS if CXXFLAGS is set in the OS environment (so that user CXXFLAGS take precedence). --- wscript | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index 95dee9811..bfa1d96de 100644 --- a/wscript +++ b/wscript @@ -106,7 +106,8 @@ def configure(conf): variant_env.append_value('CXXDEFINES', 'RUN_SELF_TESTS') - if os.path.basename(conf.env['CXX']).startswith("g++"): + if (os.path.basename(conf.env['CXX']).startswith("g++") + and 'CXXFLAGS' not in os.environ): variant_env.append_value('CXXFLAGS', ['-Wall', '-Werror']) if 'debug' in Params.g_options.debug_level.lower(): @@ -115,7 +116,8 @@ def configure(conf): ## In optimized builds we still want debugging symbols, e.g. for ## profiling, and at least partially usable stack traces. - if 'optimized' in Params.g_options.debug_level.lower(): + if ('optimized' in Params.g_options.debug_level.lower() + and 'CXXFLAGS' not in os.environ): for flag in variant_env['CXXFLAGS_DEBUG']: ## this probably doesn't work for MSVC if flag.startswith('-g'): From d757f69479c6104c6506b834d369f708f6d34e3a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 10 Jul 2007 13:45:20 +0100 Subject: [PATCH 11/14] WAF: explain in the docs how to change the compilation flags. --- doc/build-waf.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/build-waf.txt b/doc/build-waf.txt index 5d9d178ea..42bc70eb1 100644 --- a/doc/build-waf.txt +++ b/doc/build-waf.txt @@ -20,7 +20,9 @@ To build ns-3 with waf type the commands: To see valid configure options, type waf --help. The most important option is -d . Valid debug levels (which are listed in -waf --help) are: ultradebug, debug, release, and optimized. +waf --help) are: ultradebug, debug, release, and optimized. It is +also possible to change the flags used for compilation with (e.g.): +CXXFLAGS="-O3" waf configure. [ Note: Unlike some other build tools, to change the build target, the option must be supplied during the configure stage rather than From 42d93b987223f2a3765a923933b78feb5d7b43f9 Mon Sep 17 00:00:00 2001 From: "George F. Riley" Date: Fri, 13 Jul 2007 10:40:10 +0200 Subject: [PATCH 12/14] Simplifications to the point to point devices and channel --- src/devices/p2p/p2p-channel.cc | 74 ++--------- src/devices/p2p/p2p-channel.h | 23 ++-- src/devices/p2p/p2p-net-device.cc | 201 +++++++++--------------------- src/devices/p2p/p2p-net-device.h | 61 +++++---- src/node/mac-address.cc | 21 ++++ src/node/mac-address.h | 15 +++ src/simulator/simulator.h | 74 +++++++++++ 7 files changed, 222 insertions(+), 247 deletions(-) diff --git a/src/devices/p2p/p2p-channel.cc b/src/devices/p2p/p2p-channel.cc index 2833c8bb1..adceda3f4 100644 --- a/src/devices/p2p/p2p-channel.cc +++ b/src/devices/p2p/p2p-channel.cc @@ -76,8 +76,7 @@ PointToPointChannel::Attach(Ptr device) NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted"); NS_ASSERT(device != 0); - m_link[m_nDevices].m_src = device; - ++m_nDevices; + m_link[m_nDevices++].m_src = device; // // If we have both devices connected to the channel, then finish introducing // the two halves and set the links to IDLE. @@ -91,8 +90,9 @@ PointToPointChannel::Attach(Ptr device) } } -bool -PointToPointChannel::TransmitStart(Packet& p, Ptr src) +bool PointToPointChannel::TransmitStart(Packet& p, + Ptr src, + const Time& txTime) { NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src << ")"); @@ -104,65 +104,15 @@ PointToPointChannel::TransmitStart(Packet& p, Ptr src) uint32_t wire = src == m_link[0].m_src ? 0 : 1; - if (m_link[wire].m_state == TRANSMITTING) - { - NS_DEBUG("PointToPointChannel::TransmitStart (): **** ERROR ****"); - NS_DEBUG("PointToPointChannel::TransmitStart (): state TRANSMITTING"); - return false; - } - - NS_DEBUG("PointToPointChannel::TransmitStart (): switch to TRANSMITTING"); - m_link[wire].m_state = TRANSMITTING; + // Here we schedule the packet receive event at the receiver, + // which simplifies this model quite a bit. The channel just + // adds the propagation delay time + Simulator::Schedule (txTime + m_delay, + &PointToPointNetDevice::Receive, + m_link[wire].m_dst, p); return true; } -bool -PointToPointChannel::TransmitEnd(Packet& p, Ptr src) -{ - NS_DEBUG("PointToPointChannel::TransmitEnd (" << &p << ", " << src << ")"); - NS_DEBUG ("PointToPointChannel::TransmitEnd (): UID is " << - p.GetUid () << ")"); - - NS_ASSERT(m_link[0].m_state != INITIALIZING); - NS_ASSERT(m_link[1].m_state != INITIALIZING); - - uint32_t wire = src == m_link[0].m_src ? 0 : 1; - - NS_ASSERT(m_link[wire].m_state == TRANSMITTING); - - m_link[wire].m_state = PROPAGATING; -// -// The sender is going to free the packet as soon as it has been transmitted. -// We need to copy it to get a reference so it won't e deleted. -// - Packet packet = p; - NS_DEBUG ("PointToPointChannel::TransmitEnd (): Schedule event in " << - m_delay.GetSeconds () << "sec"); - Simulator::Schedule (m_delay, - &PointToPointChannel::PropagationCompleteEvent, - this, packet, src); - return true; -} - -void -PointToPointChannel::PropagationCompleteEvent( - Packet p, - Ptr src) -{ - NS_DEBUG("PointToPointChannel::PropagationCompleteEvent (" << &p << ", " << - src << ")"); - NS_DEBUG ("PointToPointChannel::PropagationCompleteEvent (): UID is " << - p.GetUid () << ")"); - - uint32_t wire = src == m_link[0].m_src ? 0 : 1; - NS_ASSERT(m_link[wire].m_state == PROPAGATING); - m_link[wire].m_state = IDLE; - - NS_DEBUG ("PointToPointChannel::PropagationCompleteEvent (): Receive"); - m_link[wire].m_dst->Receive (p); -} - - uint32_t PointToPointChannel::GetNDevices (void) const { @@ -176,13 +126,13 @@ PointToPointChannel::GetDevice (uint32_t i) const return m_link[i].m_src; } - DataRate +const DataRate& PointToPointChannel::GetDataRate (void) { return m_bps; } - Time +const Time& PointToPointChannel::GetDelay (void) { return m_delay; diff --git a/src/devices/p2p/p2p-channel.h b/src/devices/p2p/p2p-channel.h index 97a251177..71bc50ca3 100644 --- a/src/devices/p2p/p2p-channel.h +++ b/src/devices/p2p/p2p-channel.h @@ -51,11 +51,7 @@ class PointToPointNetDevice; */ class PointToPointChannel : public Channel { public: -// -// This is really kidding myself, since just setting N_DEVICES to 3 isn't -// going to come close to magically creating a multi-drop link, but I can't -// bring myself to just type 2 in the code (even though I type 0 and 1 :-). -// +// Each point to point link has exactly two net devices static const int N_DEVICES = 2; /** * \brief Create a PointToPointChannel @@ -68,7 +64,7 @@ public: /** * \brief Create a PointToPointChannel * - * \param bps The bitrate of the channel + * \param bps The maximum bitrate of the channel * \param delay Transmission delay through the channel */ PointToPointChannel (const DataRate& bps, const Time& delay); @@ -77,7 +73,7 @@ public: * \brief Create a PointToPointChannel * * \param name the name of the channel for identification purposes - * \param bps The bitrate of the channel + * \param bps The maximum bitrate of the channel * \param delay Transmission delay through the channel */ PointToPointChannel (const std::string& name, @@ -88,21 +84,22 @@ public: * \param device pointer to the netdevice to attach to the channel */ void Attach (Ptr device); - bool TransmitStart (Packet& p, Ptr src); - bool TransmitEnd (Packet &p, Ptr src); - void PropagationCompleteEvent(Packet p, Ptr src); + bool TransmitStart (Packet& p, Ptr src, + const Time& txTime); + // Below two not needed + //bool TransmitEnd (Packet &p, Ptr src); + //void PropagationCompleteEvent(Packet p, Ptr src); virtual uint32_t GetNDevices (void) const; virtual Ptr GetDevice (uint32_t i) const; - virtual DataRate GetDataRate (void); - virtual Time GetDelay (void); + virtual const DataRate& GetDataRate (void); + virtual const Time& GetDelay (void); private: DataRate m_bps; Time m_delay; - int32_t m_nDevices; enum WireState diff --git a/src/devices/p2p/p2p-net-device.cc b/src/devices/p2p/p2p-net-device.cc index 9542d951b..102cc247f 100644 --- a/src/devices/p2p/p2p-net-device.cc +++ b/src/devices/p2p/p2p-net-device.cc @@ -16,7 +16,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Author: Mathieu Lacage + * Author: Craig Dowell + * Revised: George Riley */ #include @@ -32,11 +33,17 @@ NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice"); namespace ns3 { -PointToPointNetDevice::PointToPointNetDevice (Ptr node) +DataRateDefaultValue PointToPointNetDevice::g_defaultRate( + "PointToPointLinkDataRate", + "The default data rate for point to point links", + DataRate ("10Mb/s")); + + PointToPointNetDevice::PointToPointNetDevice (Ptr node, + const DataRate& rate) : - NetDevice(node, MacAddress ("00:00:00:00:00:00")), + NetDevice(node, MacAddress (6)), m_txMachineState (READY), - m_bps (DataRate (0xffffffff)), + m_bps (rate), m_tInterframeGap (Seconds(0)), m_channel (0), m_queue (0), @@ -73,6 +80,9 @@ PointToPointNetDevice::~PointToPointNetDevice() // We're assuming that the tracing will be set up after the topology creation // phase and this won't actually matter. // +// GFR Comments. Don't see where the "copy the pointer and add reference" +// stated above is done. Can original author please comment and/or fix. +// Shouldn't the queue pointer also bump the refcount? PointToPointNetDevice::PointToPointNetDevice (const PointToPointNetDevice& nd) : NetDevice(nd), @@ -92,6 +102,8 @@ PointToPointNetDevice::PointToPointNetDevice (const PointToPointNetDevice& nd) } + // GFR COmments...shouldn't this decrement the refcount instead + // of just nil-ing out the pointer? Don't understand this. void PointToPointNetDevice::DoDispose() { m_channel = 0; @@ -101,100 +113,54 @@ void PointToPointNetDevice::DoDispose() // // Assignment operator for PointToPointNetDevice. // -// This uses the non-obvious trick of taking the source net device passed by -// value instead of by reference. This causes the copy constructor to be -// invoked (where the real work is done -- see above). All we have to do -// here is to return the newly constructed net device. // - PointToPointNetDevice& -PointToPointNetDevice::operator= (const PointToPointNetDevice nd) +PointToPointNetDevice& +PointToPointNetDevice::operator= (const PointToPointNetDevice& nd) { NS_DEBUG ("PointToPointNetDevice::operator= (" << &nd << ")"); + // FIXME. Not sure what to do here + // GFR Note. I would suggest dis-allowing netdevice assignment, + // as well as pass-by-value (ie. copy constructor). + // This resolves some of the questions above about copy constructors. + // Why should we ever copy or assign a net device? return *this; } - void -PointToPointNetDevice::SetDataRate(DataRate bps) +void PointToPointNetDevice::SetDataRate(const DataRate& bps) { m_bps = bps; } - void -PointToPointNetDevice::SetInterframeGap(Time t) +void PointToPointNetDevice::SetInterframeGap(const Time& t) { m_tInterframeGap = t; } - bool -PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest) +bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest) { NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")"); NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")"); + // GFR Comment. Why is this an assertion? Can't a link legitimately + // "go down" during the simulation? Shouldn't we just wait for it + // to come back up? NS_ASSERT (IsLinkUp ()); -#ifdef NOTYET - struct NetDevicePacketDestAddress tag; - tag.address = address; - p.AddTag (tag); -#endif - // // This class simulates a point to point device. In the case of a serial -// link, this means that we're simulating something like a UART. This is -// not a requirement for a point-to-point link, but it's a typical model for -// the device. +// link, this means that we're simulating something like a UART. // -// Generally, a real device will have a list of pending packets to transmit. -// An on-device CPU frees the main CPU(s) of the details of what is happening -// in the device and feeds the USART. The main CPU basically just sees the -// list of packets -- it puts packets into the list, and the device frees the -// packets when they are transmitted. -// -// In the case of our virtual device here, the queue pointed to by m_queue -// corresponds to this list. The main CPU adds packets to the list by -// calling this method and when the device completes a send, the packets are -// freed in an "interrupt" service routine. -// -// We're going to do the same thing here. So first of all, the incoming packet -// goes onto our queue if possible. If the queue can't handle it, there's -// nothing to be done. -// - if (m_queue->Enqueue(p) == false ) - { - return false; - } -// -// If there's a transmission in progress, the "interrupt" will keep the -// transmission process going. If the device is idle, we need to start a -// transmission. -// -// In the real world, the USART runs until it finishes sending bits, and then -// pulls on the device's transmit complete interrupt wire. At the same time, -// the electrons from the last wiggle of the wire are busy propagating down -// the wire. In the case of a long speed-of-light delay in the wire, we could -// conceivably start transmitting the next packet before the end of the -// previously sent data has even reached the end of the wire. This situation -// is usually avoided (like the plague) and an "interframe gap" is introduced. -// This is usually the round-trip delay on the channel plus some hard-to- -// quantify receiver turn-around time (the time required for the receiver -// to process the last frame and prepare for reception of the next). -// -// So, if the transmit machine is ready, we need to schedule a transmit -// complete event (at which time we tell the channel we're no longer sending -// bits). A separate transmit ready event (at which time the transmitter -// becomes ready to start sending bits again is scheduled there). Finally, -// we tell the channel (via TransmitStart ()) that we've started wiggling the -// wire and bits are coming out. -// -// If the transmit machine is not ready, we just leave and the transmit ready -// event we know is coming will kick-start the transmit process. // +// If there's a transmission in progress, we enque the packet for later +// trnsmission; otherwise we send it now. if (m_txMachineState == READY) { return TransmitStart (p); } - return true; + else + { + return m_queue->Enqueue(p); + } } bool @@ -206,81 +172,41 @@ PointToPointNetDevice::TransmitStart (Packet &p) // // This function is called to start the process of transmitting a packet. // We need to tell the channel that we've started wiggling the wire and -// schedule an event that will be executed when it's time to tell the -// channel that we're done wiggling the wire. +// schedule an event that will be executed when the transmission is complete. // NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit"); m_txMachineState = BUSY; - Time tEvent = Seconds (m_bps.CalculateTxTime(p.GetSize())); + Time txTime = Seconds (m_bps.CalculateTxTime(p.GetSize())); + Time txCompleteTime = txTime + m_tInterframeGap; NS_DEBUG ("PointToPointNetDevice::TransmitStart (): " << "Schedule TransmitCompleteEvent in " << - tEvent.GetSeconds () << "sec"); - - Simulator::Schedule (tEvent, - &PointToPointNetDevice::TransmitCompleteEvent, + txCompleteTime.GetSeconds () << "sec"); + // Schedule the tx complete event + Simulator::Schedule (txCompleteTime, + &PointToPointNetDevice::TransmitComplete, this); - return m_channel->TransmitStart (p, this); + return m_channel->TransmitStart(p, this, txTime); } - void -PointToPointNetDevice::TransmitCompleteEvent (void) +void PointToPointNetDevice::TransmitComplete (void) { NS_DEBUG ("PointToPointNetDevice::TransmitCompleteEvent ()"); // // This function is called to finish the process of transmitting a packet. // We need to tell the channel that we've stopped wiggling the wire and -// schedule an event that will be executed when it's time to re-enable -// the transmitter after the interframe gap. +// get the next packet from the queue. If the queue is empty, we are +// done, otherwise transmit the next packet. // NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting"); - m_txMachineState = GAP; - Packet p; - bool found; - found = m_queue->Dequeue (p); - NS_ASSERT_MSG(found, "Packet must be on queue if transmitted"); - NS_DEBUG ("PointToPointNetDevice::TransmitCompleteEvent (): Pkt UID is " << - p.GetUid () << ")"); - m_channel->TransmitEnd (p, this); - - NS_DEBUG ( - "PointToPointNetDevice::TransmitCompleteEvent (): " << - "Schedule TransmitReadyEvent in " - << m_tInterframeGap.GetSeconds () << "sec"); - - Simulator::Schedule (m_tInterframeGap, - &PointToPointNetDevice::TransmitReadyEvent, - this); -} - - void -PointToPointNetDevice::TransmitReadyEvent (void) -{ - NS_DEBUG ("PointToPointNetDevice::TransmitReadyEvent ()"); -// -// This function is called to enable the transmitter after the interframe -// gap has passed. If there are pending transmissions, we use this opportunity -// to start the next transmit. -// - NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap"); m_txMachineState = READY; - - if (m_queue->IsEmpty()) - { - return; - } - else - { - Packet p; - bool found; - found = m_queue->Peek (p); - NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?"); - TransmitStart (p); - } + Packet p; + if (!m_queue->Dequeue(p)) return; // Nothing to do at this point + TransmitStart(p); } -TraceResolver * -PointToPointNetDevice::DoCreateTraceResolver (TraceContext const &context) +TraceResolver* PointToPointNetDevice::DoCreateTraceResolver ( + TraceContext const &context) { CompositeTraceResolver *resolver = new CompositeTraceResolver (context); resolver->Add ("queue", @@ -292,8 +218,7 @@ PointToPointNetDevice::DoCreateTraceResolver (TraceContext const &context) return resolver; } -bool -PointToPointNetDevice::Attach (Ptr ch) +bool PointToPointNetDevice::Attach (Ptr ch) { NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")"); @@ -301,7 +226,9 @@ PointToPointNetDevice::Attach (Ptr ch) m_channel->Attach(this); m_bps = m_channel->GetDataRate (); - m_tInterframeGap = m_channel->GetDelay (); + // GFR Comment. Below is definitely wrong. Interframe gap + // is unrelated to channel delay. + //m_tInterframeGap = m_channel->GetDelay (); /* * For now, this device is up whenever a channel is attached to it. @@ -315,38 +242,32 @@ PointToPointNetDevice::Attach (Ptr ch) return true; } -void -PointToPointNetDevice::AddQueue (Ptr q) +void PointToPointNetDevice::AddQueue (Ptr q) { NS_DEBUG ("PointToPointNetDevice::AddQueue (" << q << ")"); m_queue = q; } -void -PointToPointNetDevice::Receive (Packet& p) +void PointToPointNetDevice::Receive (Packet& p) { - // ignore return value for now. NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")"); m_rxTrace (p); ForwardUp (p); } -Ptr -PointToPointNetDevice::GetQueue(void) const +Ptr PointToPointNetDevice::GetQueue(void) const { return m_queue; } -Ptr -PointToPointNetDevice::DoGetChannel(void) const +Ptr PointToPointNetDevice::DoGetChannel(void) const { return m_channel; } -bool -PointToPointNetDevice::DoNeedsArp (void) const +bool PointToPointNetDevice::DoNeedsArp (void) const { return false; } diff --git a/src/devices/p2p/p2p-net-device.h b/src/devices/p2p/p2p-net-device.h index e1eb8a666..526d84523 100644 --- a/src/devices/p2p/p2p-net-device.h +++ b/src/devices/p2p/p2p-net-device.h @@ -30,6 +30,7 @@ #include "ns3/callback-trace-source.h" #include "ns3/nstime.h" #include "ns3/data-rate.h" +#include "ns3/default-value.h" #include "ns3/ptr.h" namespace ns3 { @@ -80,7 +81,8 @@ public: * @see PointToPointTopology::AddPointToPointLink () * @param node the Node to which this device is connected. */ - PointToPointNetDevice (Ptr node); + PointToPointNetDevice (Ptr node, + const DataRate& = g_defaultRate.GetValue()); /** * Copy Construct a PointToPointNetDevice * @@ -105,7 +107,7 @@ public: * * @param nd the object to be copied */ - PointToPointNetDevice& operator= (PointToPointNetDevice nd); + PointToPointNetDevice& operator= (const PointToPointNetDevice& nd); /** * Set the Data Rate used for transmission of packets. The data rate is * set in the Attach () method from the corresponding field in the channel @@ -114,7 +116,7 @@ public: * @see Attach () * @param bps the data rate at which this object operates */ - void SetDataRate(DataRate bps); + void SetDataRate(const DataRate& bps); /** * Set the inteframe gap used to separate packets. The interframe gap * defines the minimum space required between packets sent by this device. @@ -125,7 +127,7 @@ public: * @see Attach () * @param t the interframe gap time */ - void SetInterframeGap(Time t); + void SetInterframeGap(const Time& t); /** * Attach the device to a channel. * @@ -190,6 +192,19 @@ protected: * @returns a pointer to the channel */ virtual Ptr DoGetChannel(void) const; + /** + * Set a new default data rate + * @param Data rate to set for new default + */ + static void SetDefaultRate(const DataRate&); + + /** + * Get the current default rate. + * @returns a const reference to current default + */ + + static const DataRate& GetDefaultRate(); + private: /** * Send a Packet Down the Wire. @@ -223,39 +238,17 @@ private: /** * Stop Sending a Packet Down the Wire and Begin the Interframe Gap. * - * The TransmitCompleteEvent method is used internally to finish the process - * of sending a packet out on the channel. During execution of this method - * the TransmitEnd method is called on the channel to let it know that the - * physical device this class represents has virually finished sending - * signals. The channel uses this event to begin its speed of light delay - * timer after which it notifies the Net Device at the other end of the - * link that the bits have arrived. During this method, the net device - * also schedules the TransmitReadyEvent at which time the transmitter - * becomes ready to send the next packet. + * The TransmitComplete method is used internally to finish the process + * of sending a packet out on the channel. * - * @see PointToPointChannel::TransmitEnd () - * @see TransmitReadyEvent () - * @returns true if success, false on failure */ - void TransmitCompleteEvent (void); - /** - * Cause the Transmitter to Become Ready to Send Another Packet. - * - * The TransmitReadyEvent method is used internally to re-enable the - * transmit machine of the net device. It is scheduled after a suitable - * interframe gap after the completion of the previous transmission. - * The queue is checked at this time, and if there is a packet waiting on - * the queue, the transmission process is begun. - * - * @see TransmitStart () - */ - void TransmitReadyEvent (void); + void TransmitComplete(void); /** * Create a Trace Resolver for events in the net device. * * @see class TraceResolver */ - virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); + virtual TraceResolver* DoCreateTraceResolver (TraceContext const &context); virtual bool DoNeedsArp (void) const; /** * Enumeration of the states of the transmit machine of the net device. @@ -263,8 +256,7 @@ private: enum TxMachineState { READY, /**< The transmitter is ready to begin transmission of a packet */ - BUSY, /**< The transmitter is busy transmitting a packet */ - GAP /**< The transmitter is in the interframe gap time */ + BUSY /**< The transmitter is busy transmitting a packet */ }; /** * The state of the Net Device transmit state machine. @@ -305,6 +297,11 @@ private: * @see class TraceResolver */ CallbackTraceSource m_rxTrace; + /** + * Default data rate. Used for all newly created p2p net devices + */ + static DataRateDefaultValue g_defaultRate; + }; }; // namespace ns3 diff --git a/src/node/mac-address.cc b/src/node/mac-address.cc index be455a8a3..9dcf9bdd6 100644 --- a/src/node/mac-address.cc +++ b/src/node/mac-address.cc @@ -33,6 +33,9 @@ namespace ns3 { +// Static variables +uint8_t MacAddress::g_nextAddress[MacAddress::MAX_LEN]; + static char AsciiToLowCase (char c) { @@ -54,6 +57,13 @@ MacAddress::MacAddress () : m_len(0) } } +MacAddress::MacAddress(uint8_t len) : m_len(len) +{ + NS_ASSERT (len <= MacAddress::MAX_LEN); + AdvanceAddress(); + memcpy(m_address, g_nextAddress, len); +} + MacAddress::MacAddress (uint8_t const *address, uint8_t len) { NS_ASSERT (len <= MacAddress::MAX_LEN); @@ -148,6 +158,17 @@ MacAddress::Set (uint8_t const ad[MacAddress::MAX_LEN], uint8_t len) m_len = len; } +// Static methods +void MacAddress::AdvanceAddress() + { + // Advance to next address, little end first + for(size_t i = 0; i < MAX_LEN; ++i) + { + if (++g_nextAddress[i] != 0) break; + } + } + +// Non-member operators bool operator == (MacAddress const&a, MacAddress const&b) { return a.IsEqual (b); diff --git a/src/node/mac-address.h b/src/node/mac-address.h index 75a80b700..76c5a6ae0 100644 --- a/src/node/mac-address.h +++ b/src/node/mac-address.h @@ -46,6 +46,13 @@ public: * This MacAddress has length of zero, and is internally all zeros */ MacAddress (void); + /** + * \brief Construct a MacAddress using the next available + * address. + * \see MacAddres::Next + * \param len length, in bytes, of the desired address + */ + MacAddress(uint8_t len); /** * \brief Construct a MacAddress from a byte-array * @@ -97,6 +104,14 @@ public: */ void Set (uint8_t const ad[MAX_LEN], uint8_t len); + // Static methods/members + /** + * + * Advance the global to the next available mac address. + */ + static void AdvanceAddress(); + static uint8_t g_nextAddress[MAX_LEN]; + private: uint8_t m_address[MAX_LEN]; uint8_t m_len; diff --git a/src/simulator/simulator.h b/src/simulator/simulator.h index 02cf6741c..fed3e8424 100644 --- a/src/simulator/simulator.h +++ b/src/simulator/simulator.h @@ -173,6 +173,10 @@ public: */ template static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1), OBJ obj, T1 a1); + template + static EventId Schedule (Time const &time, void (T::*mem_ptr) (const T1&), OBJ obj, T1 a1); // GFR + template + static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1&), OBJ obj, T1 a1); // GFR /** * @param time the relative expiration time of the event. * @param mem_ptr member method pointer to invoke @@ -234,6 +238,10 @@ public: */ template static EventId Schedule (Time const &time, void (*f) (T1), T1 a1); + template + static EventId Schedule (Time const &time, void (*f) (const T1&), T1 a1); // GFR + template + static EventId Schedule (Time const &time, void (*f) (T1&), T1 a1); // GFR /** * @param time the relative expiration time of the event. * @param f the function to invoke @@ -533,6 +541,10 @@ private: static EventImpl *MakeEvent (void (T::*mem_ptr) (void), OBJ obj); template static EventImpl *MakeEvent (void (T::*mem_ptr) (T1), OBJ obj, T1 a1); + template + static EventImpl *MakeEvent (void (T::*mem_ptr) (const T1&), OBJ obj, T1 a1); // GFR + template + static EventImpl *MakeEvent (void (T::*mem_ptr) (T1&), OBJ obj, T1 a1); // GFR template static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2); template @@ -642,6 +654,56 @@ EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1), OBJ obj, T1 a1) return ev; } +template +EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (const T1&), OBJ obj, T1 a1) +{ + // one argument version, with const reference + class EventMemberImpl1 : public EventImpl { + public: + typedef void (T::*F)(const T1&); + EventMemberImpl1 (OBJ obj, F function, T1 a1) + : m_obj (obj), + m_function (function), + m_a1 (a1) + {} + protected: + virtual ~EventMemberImpl1 () {} + private: + virtual void Notify (void) { + (EventMemberImplTraits::GetReference (m_obj).*m_function) (m_a1); + } + OBJ m_obj; + F m_function; + T1 m_a1; + } *ev = new EventMemberImpl1 (obj, mem_ptr, a1); + return ev; +} + +template +EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1&), OBJ obj, T1 a1) +{ + // one argument version with non-const reference + class EventMemberImpl1 : public EventImpl { + public: + typedef void (T::*F)(T1&); + EventMemberImpl1 (OBJ obj, F function, T1 a1) + : m_obj (obj), + m_function (function), + m_a1 (a1) + {} + protected: + virtual ~EventMemberImpl1 () {} + private: + virtual void Notify (void) { + (EventMemberImplTraits::GetReference (m_obj).*m_function) (m_a1); + } + OBJ m_obj; + F m_function; + T1 m_a1; + } *ev = new EventMemberImpl1 (obj, mem_ptr, a1); + return ev; +} + template EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2) { @@ -920,6 +982,18 @@ EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1), OBJ obj, return Schedule (time, MakeEvent (mem_ptr, obj, a1)); } +template +EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (const T1&), OBJ obj, T1 a1) +{ + return Schedule (time, MakeEvent (mem_ptr, obj, a1)); +} + +template +EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1&), OBJ obj, T1 a1) +{ + return Schedule (time, MakeEvent (mem_ptr, obj, a1)); +} + template EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2) { From b6c01554873e759762ee52716259568b8744011c Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 12 Jul 2007 12:41:37 +0100 Subject: [PATCH 13/14] Make Simulator::IsExpired parameter const, to reflect the fact that the EventId is not changed. EventId::IsExpired and EventId::IsRunning also made const. --- src/simulator/event-id.cc | 4 ++-- src/simulator/event-id.h | 4 ++-- src/simulator/simulator.cc | 2 +- src/simulator/simulator.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/simulator/event-id.cc b/src/simulator/event-id.cc index 7357070b0..356be7f60 100644 --- a/src/simulator/event-id.cc +++ b/src/simulator/event-id.cc @@ -45,12 +45,12 @@ EventId::Cancel (void) } } bool -EventId::IsExpired (void) +EventId::IsExpired (void) const { return Simulator::IsExpired (*this); } bool -EventId::IsRunning (void) +EventId::IsRunning (void) const { return !IsExpired (); } diff --git a/src/simulator/event-id.h b/src/simulator/event-id.h index a7514289d..499065373 100644 --- a/src/simulator/event-id.h +++ b/src/simulator/event-id.h @@ -44,8 +44,8 @@ public: * method. * \returns true if the event has expired, false otherwise. */ - bool IsExpired (void); - bool IsRunning (void); + bool IsExpired (void) const; + bool IsRunning (void) const; public: /* The following methods are semi-private * they are supposed to be invoked only by diff --git a/src/simulator/simulator.cc b/src/simulator/simulator.cc index 226f7357a..9e21fa2ba 100644 --- a/src/simulator/simulator.cc +++ b/src/simulator/simulator.cc @@ -266,7 +266,7 @@ SimulatorPrivate::Cancel (EventId &id) } bool -SimulatorPrivate::IsExpired (EventId ev) +SimulatorPrivate::IsExpired (const EventId ev) { if (ev.GetEventImpl () == 0 || ev.GetTs () < m_currentTs || diff --git a/src/simulator/simulator.h b/src/simulator/simulator.h index fed3e8424..f307be980 100644 --- a/src/simulator/simulator.h +++ b/src/simulator/simulator.h @@ -529,7 +529,7 @@ public: * @param id the event to test for expiration * @returns true if the event has expired, false otherwise. */ - static bool IsExpired (EventId id); + static bool IsExpired (const EventId id); /** * Return the "current simulation time". */ From ae8f10ae470fda24b1f024d6480cf761941a025b Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sun, 15 Jul 2007 13:04:47 +0100 Subject: [PATCH 14/14] WAF: derive the variable NS3_MODULES from the 'all_modules' list in src/wscript, instead of requiring every module to define a configure function to register themselves. This way module registration is done in one place only: src/wscript. Requires module naming conventions, though. --- src/applications/wscript | 5 ----- src/common/wscript | 3 --- src/core/wscript | 2 -- src/devices/p2p/wscript | 4 ---- src/internet-node/wscript | 4 ---- src/node/wscript | 4 ---- src/simulator/wscript | 2 -- src/wscript | 4 +++- 8 files changed, 3 insertions(+), 25 deletions(-) diff --git a/src/applications/wscript b/src/applications/wscript index 85fa0513b..0874d58ab 100644 --- a/src/applications/wscript +++ b/src/applications/wscript @@ -1,10 +1,5 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- - -def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-applications') - - def build(bld): obj = bld.create_obj('cpp', 'shlib') obj.name = 'ns3-applications' diff --git a/src/common/wscript b/src/common/wscript index c6f3be7f0..6efd5bfc9 100644 --- a/src/common/wscript +++ b/src/common/wscript @@ -1,8 +1,5 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-common') - def build(bld): common = bld.create_obj('cpp', 'shlib') common.name = 'ns3-common' diff --git a/src/core/wscript b/src/core/wscript index ce9795c8e..222539171 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -3,8 +3,6 @@ import sys def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-core') - e = conf.create_header_configurator() e.mandatory = False e.name = 'stdlib.h' diff --git a/src/devices/p2p/wscript b/src/devices/p2p/wscript index c4c0f7952..73b27d061 100644 --- a/src/devices/p2p/wscript +++ b/src/devices/p2p/wscript @@ -1,10 +1,6 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-p2p') - - def build(bld): p2p = bld.create_obj('cpp', 'shlib') p2p.name = 'ns3-p2p' diff --git a/src/internet-node/wscript b/src/internet-node/wscript index 806861fd3..bf3236159 100644 --- a/src/internet-node/wscript +++ b/src/internet-node/wscript @@ -1,10 +1,6 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-internet-node') - - def build(bld): obj = bld.create_obj('cpp', 'shlib') obj.name = 'ns3-internet-node' diff --git a/src/node/wscript b/src/node/wscript index c608945c7..18419e1df 100644 --- a/src/node/wscript +++ b/src/node/wscript @@ -1,9 +1,5 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-node') - - def build(bld): node = bld.create_obj('cpp', 'shlib') node.name = 'ns3-node' diff --git a/src/simulator/wscript b/src/simulator/wscript index fec0412c0..a940cd25a 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -15,8 +15,6 @@ def set_options(opt): def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-simulator') - if Params.g_options.high_precision_as_double: conf.add_define('USE_HIGH_PRECISION_DOUBLE', 1) conf.env['USE_HIGH_PRECISION_DOUBLE'] = 1 diff --git a/src/wscript b/src/wscript index 2e2349f10..bc0fb4ff8 100644 --- a/src/wscript +++ b/src/wscript @@ -29,9 +29,11 @@ def configure(conf): blddir = os.path.abspath(os.path.join(conf.m_blddir, conf.env.variant())) for module in all_modules: - conf.sub_config(module) conf.env.append_value('NS3_MODULE_PATH', os.path.join(blddir, 'src', module)) + ## Used to link the 'run-tests' program with all of ns-3 code + conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_modules] + def build(bld): Object.register('ns3header', Ns3Header)