--- a/.hgignore Sun May 13 10:57:43 2007 +0200
+++ b/.hgignore Sun May 13 11:24:28 2007 +0200
@@ -2,6 +2,8 @@
.*\.o$
.*~$
build-dir
+build
.*\.sconsign
doc/html.*
doc/latex.*
+.lock-wscript
--- a/doc/main.txt Sun May 13 10:57:43 2007 +0200
+++ b/doc/main.txt Sun May 13 11:24:28 2007 +0200
@@ -19,6 +19,7 @@
* - a class to register regression tests with the test manager: ns3::Test and ns3::TestManager
* - debugging facilities: \ref debugging, \ref assert, \ref error
* - \ref randomvariable
+ * - \ref config
* - a class to handle automatic deletion of multiple sets of objects of different types:
* ns3::ObjectContainer
*
--- a/examples/simple-p2p.cc Sun May 13 10:57:43 2007 +0200
+++ b/examples/simple-p2p.cc Sun May 13 11:24:28 2007 +0200
@@ -66,7 +66,6 @@
#include "ns3/trace-root.h"
#include "ns3/p2p-topology.h"
#include "ns3/onoff-application.h"
-#include "ns3/application-list.h"
#include "ns3/random-variable.h"
using namespace ns3;
@@ -132,6 +131,15 @@
channel2, n2, Ipv4Address("10.1.3.1"),
n3, Ipv4Address("10.1.3.2"));
+ // Finally, we add static routes. These three steps (Channel and
+ // NetDevice creation, IP Address assignment, and routing) are
+ // separated because there may be a need to postpone IP Address
+ // assignment (emulation) or modify to use dynamic routing
+ PointToPointTopology::AddIpv4Routes(n0, n2, channel0);
+ PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
+ PointToPointTopology::AddIpv4Routes(n2, n3, channel2);
+
+
// Create the OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s
Ptr<OnOffApplication> ooff = MakeNewObject<OnOffApplication> (
@@ -175,7 +183,8 @@
// Also configure some tcpdump traces; each interface will be traced
// The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
- // and can be read by the "tcpdump -r" command
+ // and can be read by the "tcpdump -r" command (use "-tt" option to
+ // display timestamps correctly)
PcapTrace pcaptrace ("simple-p2p.pcap");
pcaptrace.TraceAllIp ();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ns3/_placeholder_ Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,1 @@
+This is a placeholder file used only to keep the ns3 directory present (needed for the WAF build system).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,30 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+import Params
+
+def build(bld):
+ def create_ns_prog(name, source, deps=['core', 'common', 'simulator']):
+ obj = bld.create_obj('cpp', 'program')
+ obj.target = name
+ obj.uselib_local = ' '.join(["ns3-%s" % dep for dep in deps])
+ obj.source = source
+ for module in deps:
+ obj.env.append_value('RPATH', r'-Wl,--rpath=\$ORIGIN/../src/%s' % (module,))
+ return obj
+
+ obj = create_ns_prog('main-callback', 'main-callback.cc')
+ obj = create_ns_prog('main-simulator', 'main-simulator.cc')
+ obj = create_ns_prog('main-packet', 'main-packet.cc')
+ #obj = create_ns_prog('main-trace', 'main-trace.cc')
+ obj = create_ns_prog('main-test', 'main-test.cc')
+ obj = create_ns_prog('main-ptr', 'main-ptr.cc')
+
+ #obj = create_ns_prog('main-p2p-net-device-if', 'main-p2p-net-device-if.cc',
+ # deps=['core', 'common', 'simulator', 'node', 'p2p'])
+
+ obj = create_ns_prog('main-simple', 'main-simple.cc',
+ deps=['core', 'common', 'simulator',
+ 'node', 'internet-node', 'applications'])
+
+ #obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc',
+ # deps=['core', 'common', 'simulator', 'node', 'p2p'])
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,20 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+ obj = bld.create_obj('cpp', 'shlib')
+ obj.name = 'ns3-applications'
+ obj.target = obj.name
+ obj.deps = ['ns3-node']
+ obj.source = [
+ 'application-list.cc',
+ 'application.cc',
+ 'onoff-application.cc',
+ ]
+
+ headers = bld.create_obj('ns3header')
+ headers.source = [
+ 'application-list.h',
+ 'application.h',
+ 'onoff-application.h',
+ ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,49 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+ common = bld.create_obj('cpp', 'shlib')
+ common.name = 'ns3-common'
+ common.target = common.name
+ common.deps = ['ns3-core', 'ns3-simulator']
+ common.source = [
+ 'buffer.cc',
+ 'header.cc',
+ 'chunk.cc',
+ 'trailer.cc',
+ 'packet.cc',
+ 'tags.cc',
+ 'pcap-writer.cc',
+ 'variable-tracer-test.cc',
+ 'trace-context.cc',
+ 'trace-resolver.cc',
+ 'callback-trace-source.cc',
+ 'empty-trace-resolver.cc',
+ 'composite-trace-resolver.cc',
+ 'trace-root.cc',
+ 'data-rate.cc',
+ ]
+ headers = bld.create_obj('ns3header')
+ headers.source = [
+ 'buffer.h',
+ 'header.h',
+ 'chunk.h',
+ 'trailer.h',
+ 'tags.h',
+ 'packet.h',
+ 'uv-trace-source.h',
+ 'sv-trace-source.h',
+ 'fv-trace-source.h',
+ 'pcap-writer.h',
+ 'callback-trace-source.h',
+ 'trace-context.h',
+ 'trace-resolver.h',
+ 'empty-trace-resolver.h',
+ 'composite-trace-resolver.h',
+ 'array-trace-resolver.h',
+ 'trace-root.h',
+ 'terminal-trace-resolver.h',
+ 'smartvector.h',
+ 'smartset.h',
+ 'data-rate.h',
+ ]
--- a/src/core/command-line.h Sun May 13 10:57:43 2007 +0200
+++ b/src/core/command-line.h Sun May 13 11:24:28 2007 +0200
@@ -8,16 +8,48 @@
namespace ns3 {
+/**
+ * \brief Command line argument processing class
+ * \ingroup config
+ *
+ * Often times in simulations, the user will want the ability to change and
+ * tweak simulation parameters without having to recompile the entire
+ * simulation. This can be done by passing arguments in from the command
+ * line invocation of a simulation.
+ * This class is a collection of static functions to aid in this facility.
+ * By using it, users get the automatic things like support for --help command
+ * line arguments. See samples/main-default-value.cc for more info.
+ */
class CommandLine
{
public:
+ /**
+ * \brief Add a command line argument to the system
+ * \param name Name of the string to expect on the command line
+ * \param help A help string for this param, displayed --help is used.
+ * \param value The desination to store the value read from the command line
+ */
template <typename T>
static void AddArgValue (const std::string &name,
const std::string &help,
T &value);
+ /**
+ * \brief Add a command line triggered function call to the system
+ * \param name Name of the string to expect on the command line
+ * \param help A help string for this param, displayed --help is used.
+ * \param value An ns3::Callback that gets called if name is present as a
+ * commandline argument.
+ */
static void AddArgCommand (const std::string &name,
const std::string &help,
Callback<void> cb);
+ /**
+ * \brief Parse the command line for arguments thus far added
+ * \param argc Number of strings on the command line; pass this directly from
+ * the first argument of your main(int,char**) function
+ * \param argv Array of strings passed in as arguments; pass this directly from
+ * the second argument of your main(int,char**) function
+ */
static void Parse (int argc, char *argv[]);
private:
template <typename T>
--- a/src/core/default-value.h Sun May 13 10:57:43 2007 +0200
+++ b/src/core/default-value.h Sun May 13 11:24:28 2007 +0200
@@ -6,6 +6,11 @@
#include <list>
#include "callback.h"
+/**
+ * \defgroup config Simulation configuration
+ *
+ */
+
namespace ns3 {
class DefaultValueBase
@@ -45,6 +50,7 @@
};
/**
+ * \ingroup config
* \param name name of variable to bind
* \param value value to bind to the specified variable
*
@@ -58,6 +64,7 @@
/**
* \brief A Boolean variable for ns3::Bind
+ * \ingroup config
*
* Every instance of this type is automatically
* registered in the variable pool which is used
@@ -95,6 +102,7 @@
/**
* \brief An Integer variable for ns3::Bind
+ * \ingroup config
*
* Every instance of this type is automatically
* registered in the variable pool which is used
@@ -147,6 +155,14 @@
T m_value;
};
+/**
+ * \brief Named enumeration defaults
+ * \ingroup config
+ *
+ * Every instance of this type is automatically
+ * registered in the variable pool which is used
+ * by ns3::Bind.
+ */
class StringEnumDefaultValue : public DefaultValueBase
{
public:
@@ -168,6 +184,7 @@
/**
* \brief An enum variable for ns3::Bind
+ * \ingroup config
*
* Every instance of this type is automatically
* registered in the variable pool which is used
@@ -232,6 +249,11 @@
T m_value;
};
+/**
+ * \brief Class used to call a certain function during the configuration of the
+ * simulation
+ * \ingroup config
+ */
class CommandDefaultValue : public DefaultValueBase
{
public:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,74 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+import sys
+
+
+def configure(conf):
+ e = conf.create_header_configurator()
+ e.mandatory = False
+ e.name = 'stdlib.h'
+ e.define = 'HAVE_STDLIB_H'
+ e.run()
+
+ e = conf.create_header_configurator()
+ e.mandatory = False
+ e.name = 'stdlib.h'
+ e.define = 'HAVE_GETENV'
+ e.run()
+
+ conf.write_config_header('ns3/core-config.h')
+
+
+
+def build(bld):
+ core = bld.create_obj('cpp', 'shlib')
+ core.name = 'ns3-core'
+ core.target = core.name
+ core.deps = 'ns3-core-headers'
+ core.source = [
+ 'reference-list-test.cc',
+ 'callback-test.cc',
+ 'debug.cc',
+ 'assert.cc',
+ 'ptr.cc',
+ 'object.cc',
+ 'test.cc',
+ 'random-variable.cc',
+ 'rng-stream.cc',
+ 'ns-unknown.cc',
+ 'uid-manager.cc',
+ 'default-value.cc',
+ 'command-line.cc',
+ 'type-name.cc',
+ 'ns-unknown-manager.cc',
+ ]
+
+ if sys.platform == 'win32':
+ core.source.extend([
+ 'win32-system-wall-clock-ms.cc',
+ ])
+ else:
+ core.source.extend([
+ 'unix-system-wall-clock-ms.cc',
+ ])
+
+ headers = bld.create_obj('ns3header')
+ headers.name = 'ns3-core-headers'
+ headers.source = [
+ 'system-wall-clock-ms.h',
+ 'reference-list.h',
+ 'callback.h',
+ 'ptr.h',
+ 'object.h',
+ 'debug.h',
+ 'assert.h',
+ 'fatal-error.h',
+ 'test.h',
+ 'random-variable.h',
+ 'rng-stream.h',
+ 'ns-unknown.h',
+ 'default-value.h',
+ 'command-line.h',
+ 'type-name.h',
+ 'ns-unknown-manager.h',
+ ]
+
--- a/src/devices/p2p-gfr/p2p-channel.cc Sun May 13 10:57:43 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Implementation of simple point-to-point channel
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "ns3/simulator.h"
-#include "ns3/packet.h"
-#include "ns3/node.h"
-#include "p2p-channel.h"
-#include "p2p-net-device.h"
-
-namespace ns3 {
-
-P2PChannel::P2PChannel(const Time& delay, double maxRate)
- : m_nd1(0), m_nd2(0),
- m_delay (delay),
- m_maxRate (maxRate)
-{
-}
-
-P2PChannel::~P2PChannel ()
-{}
-
-// Channels create compatible net devices
-P2PNetDevice* P2PChannel::CreateNetDevice(Node *node, MacAddress address)
-{
- // Create a new point-to-point network device
- P2PNetDevice* nd = new P2PNetDevice(node, address);
- nd->Connect (this);
- // Add to list of peers
- if (!m_nd1) m_nd1 = nd;
- else m_nd2 = nd;
- return nd;
-}
-
-void P2PChannel::RemoveNetDevice(NetDevice* nd)
-{
- if (nd == m_nd1) m_nd1 = 0;
- if (nd == m_nd2) m_nd2 = 0;
- // Now if all removed, remove the channel as well
- if (!m_nd1 && !m_nd2)
- {
- delete this;
- }
-}
-
-void P2PChannel::Send(P2PNetDevice *device, Packet& p, double rate)
-{ // Schedule a receive event at receiver
- // First calculate time in future
- double maxRate;
- if (rate < m_maxRate)
- {
- maxRate = rate;
- }
- else
- {
- maxRate = m_maxRate;
- }
- Time txTime = Seconds (p.GetSize() * 8 / maxRate);
- Time rxTime = m_delay + txTime;
- P2PNetDevice *to, *from;
- if (device == m_nd1)
- {
- from = m_nd1;
- to = m_nd2;
- }
- else
- {
- from = m_nd2;
- to = m_nd1;
- }
- // Schedule the receive event at receiver
- Simulator::Schedule(rxTime, &P2PNetDevice::Receive, to, p);
- // Schedule the link free event
- Simulator::Schedule(txTime, &P2PNetDevice::TxComplete, from);
-
-}
-
-}//namespace ns3
--- a/src/devices/p2p-gfr/p2p-channel.h Sun May 13 10:57:43 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Definition of a simple point-to-point channel
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef P2P_CHANNEL_H
-#define P2P_CHANNEL_H
-
-#include "ns3/nstime.h"
-#include "ns3/mac-address.h"
-
-namespace ns3 {
-
-class P2PNetDevice;
-class NetDevice;
-class Node;
-class Packet;
-
-class P2PChannel {
-public:
- P2PChannel(const Time& delay, double maxRate /* bits/s */);
- ~P2PChannel();
-
- P2PNetDevice* CreateNetDevice(Node *node, MacAddress address);
- void RemoveNetDevice (NetDevice *device);
- void Send (P2PNetDevice *device, Packet&p, double rate /* bits/s */);
-private:
- // The two endpoints of this channel
- P2PNetDevice* m_nd1;
- P2PNetDevice* m_nd2;
- Time m_delay;
- double m_maxRate;
-};
-
-}//namespace ns3
-
-#endif
--- a/src/devices/p2p-gfr/p2p-net-device.cc Sun May 13 10:57:43 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Implementation of a point-to-point network device
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "ns3/empty-trace-resolver.h"
-#include "p2p-net-device.h"
-#include "p2p-channel.h"
-
-namespace ns3 {
-
-P2PNetDevice::P2PNetDevice (Node *node, MacAddress const &addr)
- : NetDevice (node, addr),
- m_rate (1000000)
-{
- SetMtu (2300);
- EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
-}
-
-P2PNetDevice::~P2PNetDevice()
-{ // Inform channel that we are destroyed
- m_channel->RemoveNetDevice(this);
-}
-
-void
-P2PNetDevice::SetRate (double rate)
-{
- m_rate = rate;
-}
-
-void
-P2PNetDevice::Connect (P2PChannel *channel)
-{
- m_channel = channel;
- NotifyLinkUp ();
-}
-
-bool
-P2PNetDevice::SendTo (Packet& p, const MacAddress&)
-{
- m_channel->Send (this, p, m_rate);
- return true;
-}
-
-TraceResolver *
-P2PNetDevice::DoCreateTraceResolver (TraceContext const &context)
-{
- return new EmptyTraceResolver (context);
-}
-
-void
-P2PNetDevice::Receive(Packet p)
-{
- ForwardUp (p);
-}
-
-void
-P2PNetDevice::TxComplete (void)
-{}
-
-}//namespace ns3
--- a/src/devices/p2p-gfr/p2p-net-device.h Sun May 13 10:57:43 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Definition for a Point-to-Point network device
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef P2P_NET_DEVICE_H
-#define P2P_NET_DEVICE_H
-
-#include "ns3/net-device.h"
-
-namespace ns3 {
-
-class P2PChannel;
-
-class P2PNetDevice : public NetDevice {
-public:
- P2PNetDevice(Node *node, MacAddress const &addr);
- virtual ~P2PNetDevice();
-
- void SetRate (double rate);
- void Connect (P2PChannel *channel);
- void Receive(Packet p);
- void TxComplete (void);
- private:
- virtual bool SendTo (Packet& p, const MacAddress& dest);
- virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
-
- double m_rate;
- P2PChannel *m_channel;
-};
-
-}//namespace ns3
-
-#endif /* P2P_NET_DEVICE_H */
-
--- a/src/devices/p2p/p2p-topology.cc Sun May 13 10:57:43 2007 +0200
+++ b/src/devices/p2p/p2p-topology.cc Sun May 13 11:24:28 2007 +0200
@@ -24,6 +24,8 @@
#include <algorithm>
#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/fatal-error.h"
#include "ns3/nstime.h"
#include "ns3/internet-node.h"
#include "ns3/ipv4-address.h"
@@ -60,7 +62,7 @@
return channel;
}
-bool
+void
PointToPointTopology::AddIpv4Addresses(
Ptr<const PointToPointChannel> chan,
Ptr<Node> n1, const Ipv4Address& addr1,
@@ -99,111 +101,72 @@
ip2->SetNetworkMask (index2, netmask);
ip2->SetUp (index2);
- ip1->AddHostRouteTo (addr2, index1);
- ip2->AddHostRouteTo (addr1, index2);
-
- return true;
-}
-
-#ifdef NOTYET
-
-// Get the net device connecting node n1 to n2. For topologies where
-// there are possibly multiple devices connecting n1 and n2 (for example
-// wireless with two devices on different channels) this will return
-// the first one found.
-Ptr<PointToPointNetDevice> PointToPointTopology::GetNetDevice(Ptr<Node> n1, Ptr<Node> n2)
-{
- for (NetDeviceList::NetDevices_t::const_iterator i = dlist.Begin();
- i != dlist.End(); ++i)
- { // Check each device
- Ptr<NetDevice> nd = *i; // next device
- Ptr<Channel> c = nd->GetChannel();
- if (!c) continue; // No channel
- if (c->NodeIsPeer(n2)) return nd; // found it
- }
- return 0; // None found
-}
-
-// Get the channel connecting node n1 to node n2
-Ptr<PointToPointChannel> PointToPointTopology::GetChannel(
- Ptr<Node> n1,
- Ptr<Node> n2
-)
-{
- Ptr<NetDevice> nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, so no channel
- return nd->GetChannel();
-}
-
-Ptr<Queue> PointToPointTopology::GetQueue(Ptr<Node> n1, Ptr<Node> n2)
-{
- Ptr<NetDevice> nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, so in queue
- return nd->GetQueue();
-}
-
-void PointToPointTopology::SetQueue(Ptr<Node> n1, Ptr<Node> n2, Ptr<Queue> q)
-{
- Ptr<NetDevice> nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, can't set queue
- // Add the specified queue to the netdevice
- return nd->SetQueue(q);
}
-#endif
+void
+PointToPointTopology::AddIpv4Routes (
+ Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
+{
+ // The PointToPoint channel is used to find the relevant NetDevices
+ NS_ASSERT (chan->GetNDevices () == 2);
+ Ptr<NetDevice> nd1 = chan->GetDevice (0);
+ Ptr<NetDevice> nd2 = chan->GetDevice (1);
+
+ // Assert that n1 is the Node owning one of the two NetDevices
+ // and make sure that nd1 corresponds to it
+ if (nd1->GetNode ()->GetId () == n1->GetId ())
+ {
+ ; // Do nothing
+ }
+ else if (nd2->GetNode ()->GetId () == n1->GetId ())
+ {
+ std::swap(nd1, nd2);
+ }
+ else
+ {
+ NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+ }
+
+ // Assert that n2 is the Node owning one of the two NetDevices
+ // and make sure that nd2 corresponds to it
+ if (nd2->GetNode ()->GetId () != n2->GetId ())
+ {
+ NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+ }
-#ifdef GFR
-P2PChannel Topology::AddDuplexLink(Ptr<Node> n1, const IPAddr& ip1,
- Ptr<Node> n2, const IPAddr& ip2,
- const Rate& rate, const Time& delay)
-{
- // Get the net devices
- P2PNetDevice* nd1 = ndl1->Add(P2PNetDevice(n1, rate, nil));
- P2PNetDevice* nd2 = ndl2->Add(P2PNetDevice(n1, rate, nd1->GetChannel()));
- // Not implemented yet. Add appropriate layer 2 protocol for
- // the net devices.
- // Get the L3 proto for node 1 and configure it with this device
- Ptr<L3Demux> l3demux1 = n1->GetL3Demux();
- Ptr<L3Protocol> l3proto1 = nil;
- // If the node 1 l3 demux exists, find the coresponding l3 protocol
- if (l3demux1) l3proto1 = l3demux1->Lookup(ip1.L3Proto());
- // If the l3 protocol exists, configure this net device. Use a mask
- // of all ones, since there is only one device on the remote end
- // of this link
- if (l3proto1) l3proto1->AddNetDevice(nd1, ip1, ip1.GetMask(ip1.Size()*8));
- // Same for node 2
- Ptr<L3Demux> l3demux2 = n2->GetL3Demux();
- Ptr<L3Protocol> l3proto2 = nil;
- // If the node 2 l3 demux exists, find the coresponding l3 protocol
- if (l3demux2) l3proto2 = l3demux2->Lookup(ip2.L3Proto());
- if (l3proto2) l3proto2->AddNetDevice(nd2, ip2, ip2.GetMask(ip2.Size()*8));
- return dynamic_cast<P2PChannel*>(nd1->GetChannel()); // Always succeeds
+ // Assert that both are Ipv4 nodes
+ Ptr<IIpv4> ip1 = nd1->GetNode ()->QueryInterface<IIpv4> (IIpv4::iid);
+ Ptr<IIpv4> ip2 = nd2->GetNode ()->QueryInterface<IIpv4> (IIpv4::iid);
+ NS_ASSERT(ip1 != 0 && ip2 != 0);
+
+ // Get interface indexes for both nodes corresponding to the right channel
+ uint32_t index1 = 0;
+ bool found = false;
+ for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
+ {
+ if (ip1 ->GetNetDevice (i) == nd1)
+ {
+ index1 = i;
+ found = true;
+ }
+ }
+ NS_ASSERT(found);
+
+ uint32_t index2 = 0;
+ found = false;
+ for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
+ {
+ if (ip2 ->GetNetDevice (i) == nd2)
+ {
+ index2 = i;
+ found = true;
+ }
+ }
+ NS_ASSERT(found);
+
+ ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
+ ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2);
}
-// Get the channel connecting node n1 to node n2
-Ptr<Channel> Topology::GetChannel(Ptr<Node> n1, Ptr<Node> n2)
-{
- Ptr<NetDevice> nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, so no channel
- return nd->GetChannel();
-}
-
-Ptr<Queue> Topology::GetQueue(Ptr<Node> n1, Ptr<Node> n2)
-{
- Ptr<NetDevice> nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, so in queue
- return nd->GetQueue();
-}
-
-void Topology::SetQueue(Ptr<Node> n1, Ptr<Node> n2, Ptr<Queue> q)
-{
- Ptr<NetDevice> nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, can't set queue
- // Add the specified queue to the netdevice
- return nd->SetQueue(q);
-}
-
-#endif
-
} // namespace ns3
--- a/src/devices/p2p/p2p-topology.h Sun May 13 10:57:43 2007 +0200
+++ b/src/devices/p2p/p2p-topology.h Sun May 13 11:24:28 2007 +0200
@@ -34,47 +34,51 @@
class IPAddr;
class DataRate;
class Queue;
-//class Time;
/**
- * \brief A helper class to create Topologies based on the ns3::PointToPointNetDevice and
- * ns3::PointToPointChannel objects.
- *
- * XXX ??
- * I think that some of the methods below are not implemented.
- * If so, remove them.
+ * \brief A helper class to create Topologies based on the
+ * ns3::PointToPointNetDevice and ns3::PointToPointChannel objects.
*/
class PointToPointTopology {
public:
/**
+ * \param n1 Node
+ * \param n2 Node
+ * \param rate Maximum transmission link rate
+ * \param delay one-way propagation delay
+ * \return Pointer to the underlying PointToPointChannel
+ *
* Add a full-duplex point-to-point link between two nodes
- * with the specified IP addresses, with specified maximum transmission rate
- * and propagation delay.
+ * and attach PointToPointNetDevices to the resulting
+ * PointToPointChannel.
*/
static Ptr<PointToPointChannel> AddPointToPointLink(
- Ptr<Node>, Ptr<Node>, const DataRate&, const Time&);
+ Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
- static bool AddIpv4Addresses(
- Ptr<const PointToPointChannel>,
- Ptr<Node>, const Ipv4Address&,
- Ptr<Node>, const Ipv4Address&);
+ /**
+ * \param chan PointToPointChannel to use
+ * \param n1 Node
+ * \param addr1 Ipv4 Address for n1
+ * \param n2 Node
+ * \param addr2 Ipv4 Address for n2
+ *
+ * Add Ipv4Addresses to the Ipv4 interfaces associated with the
+ * two PointToPointNetDevices on the provided PointToPointChannel
+ */
+ static void AddIpv4Addresses(
+ Ptr<const PointToPointChannel> chan,
+ Ptr<Node> n1, const Ipv4Address& addr1,
+ Ptr<Node> n2, const Ipv4Address& addr2);
/**
- * Get the connecting node n1 to node n2
- */
- static Ptr<PointToPointChannel> GetChannel(Ptr<Node>, Ptr<Node>);
- /**
- * Get the NetDevice connecting node n1 to n2
+ * \param channel PointToPointChannel to use
+ * \param n1 Node
+ * \param n2 Node
+ *
+ * For the given PointToPointChannel, for each Node, add an
+ * IPv4 host route to the IPv4 address of the peer node.
*/
- static Ptr<PointToPointNetDevice> GetNetDevice(Ptr<Node>, Ptr<Node>);
- /**
- * Get the queue associated with a link between two nodes
- */
- static Queue* GetQueue(Ptr<Node>, Ptr<Node>);
- /**
- * Set the queue associated with a link between two nodes
- */
- static Queue* SetQueue(Ptr<Node>, Ptr<Node>, const Queue&);
+ static void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/p2p/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,18 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+ p2p = bld.create_obj('cpp', 'shlib')
+ p2p.name = 'ns3-p2p'
+ p2p.target = p2p.name
+ p2p.deps = ['ns3-node']
+ p2p.source = [
+ 'p2p-net-device.cc',
+ 'p2p-channel.cc',
+ ]
+ headers = bld.create_obj('ns3header')
+ headers.source = [
+ 'p2p-net-device.h',
+ 'p2p-channel.h',
+ ]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,6 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ bld.add_subdirs('p2p')
+ #bld.add_subdirs('p2p-gfr')
+
--- a/src/internet-node/i-ipv4-impl.cc Sun May 13 10:57:43 2007 +0200
+++ b/src/internet-node/i-ipv4-impl.cc Sun May 13 11:24:28 2007 +0200
@@ -20,6 +20,7 @@
*/
#include "i-ipv4-impl.h"
#include "ipv4.h"
+#include "ipv4-interface.h"
#include "ns3/assert.h"
#include "ns3/net-device.h"
@@ -97,6 +98,11 @@
{
return m_ipv4->GetNInterfaces ();
}
+Ptr<NetDevice>
+IIpv4Impl::GetNetDevice (uint32_t i)
+{
+ return m_ipv4->GetInterface (i)-> GetDevice ();
+}
void
IIpv4Impl::SetAddress (uint32_t i, Ipv4Address address)
--- a/src/internet-node/i-ipv4-impl.h Sun May 13 10:57:43 2007 +0200
+++ b/src/internet-node/i-ipv4-impl.h Sun May 13 11:24:28 2007 +0200
@@ -54,6 +54,7 @@
virtual void RemoveRoute (uint32_t i);
virtual uint32_t AddInterface (Ptr<NetDevice> device);
virtual uint32_t GetNInterfaces (void);
+ virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
virtual void SetAddress (uint32_t i, Ipv4Address address);
virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,43 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+ obj = bld.create_obj('cpp', 'shlib')
+ obj.name = 'ns3-internet-node'
+ obj.target = obj.name
+ obj.deps = ['ns3-node', 'ns3-applications']
+ obj.source = [
+ 'internet-node.cc',
+ 'l3-demux.cc',
+ 'l3-protocol.cc',
+ 'ipv4-l4-demux.cc',
+ 'ipv4-l4-protocol.cc',
+ 'ipv4-header.cc',
+ 'udp-header.cc',
+ 'ipv4-checksum.cc',
+ 'ipv4-interface.cc',
+ 'ipv4.cc',
+ 'ipv4-end-point.cc',
+ 'udp.cc',
+ 'arp-header.cc',
+ 'arp-cache.cc',
+ 'arp-ipv4-interface.cc',
+ 'arp.cc',
+ 'ipv4-loopback-interface.cc',
+ 'header-utils.cc',
+ 'udp-socket.cc',
+ 'ipv4-end-point-demux.cc',
+ 'i-udp-impl.cc',
+ 'i-arp-private.cc',
+ 'i-ipv4-impl.cc',
+ 'i-ipv4-private.cc',
+ 'ascii-trace.cc',
+ 'pcap-trace.cc',
+ ]
+
+ headers = bld.create_obj('ns3header')
+ headers.source = [
+ 'internet-node.h',
+ 'ascii-trace.h',
+ 'pcap-trace.h',
+ ]
--- a/src/node/application.h Sun May 13 10:57:43 2007 +0200
+++ b/src/node/application.h Sun May 13 11:24:28 2007 +0200
@@ -21,32 +21,6 @@
#ifndef __APPLICATION_H__
#define __APPLICATION_H__
-//
-// \brief The base class for all ns3 applicationes
-//
-// Class Application is the base class for all ns3 applications.
-// Applications are associated with individual nodes, and are created
-// using the AddApplication method in the ApplicationManager capability.
-//
-// Conceptually, an application has zero or more Socket
-// objects associated with it, that are created using the Socket
-// creation API of the Kernel capability. The Socket object
-// API is modeled after the
-// well-known BSD sockets interface, although it is somewhat
-// simplified for use with ns3. Further, any socket call that
-// would normally "block" in normal sockets will return immediately
-// in ns3. A set of "upcalls" are defined that will be called when
-// the previous blocking call would normally exit. THis is documented
-// in more detail Socket class in socket.h.
-//
-// There is a second application class in ns3, called "ThreadedApplication"
-// that implements a true sockets interface, which should be used
-// when porting existing sockets code to ns3. The true
-// sockets approach is significantly
-// less memory--efficient using private stacks for each defined application,
-// so that approach should be used with care. The design and implementation
-// of the ThreadedApplication are still being discussed.
-
#include "ns3/event-id.h"
#include "ns3/nstime.h"
#include "ns3/object.h"
@@ -59,7 +33,21 @@
class RandomVariable;
/**
- * \brief a model for userspace applications.
+ * \brief The base class for all ns3 applicationes
+ *
+ * Class Application is the base class for all ns3 applications.
+ * Applications are associated with individual nodes.
+ *
+ * Conceptually, an application has zero or more Socket
+ * objects associated with it, that are created using the Socket
+ * creation API of the Kernel capability. The Socket object
+ * API is modeled after the
+ * well-known BSD sockets interface, although it is somewhat
+ * simplified for use with ns3. Further, any socket call that
+ * would normally "block" in normal sockets will return immediately
+ * in ns3. A set of "upcalls" are defined that will be called when
+ * the previous blocking call would normally exit. THis is documented
+ * in more detail Socket class in socket.h.
*/
class Application : public Object
{
--- a/src/node/i-ipv4.h Sun May 13 10:57:43 2007 +0200
+++ b/src/node/i-ipv4.h Sun May 13 11:24:28 2007 +0200
@@ -122,6 +122,12 @@
*/
virtual uint32_t GetNInterfaces (void) = 0;
+ /**
+ * \param index of interface
+ * \returns address of the NetDevice associated with the ipv4 interface
+ */
+ virtual Ptr<NetDevice> GetNetDevice (uint32_t i) = 0;
+
virtual void SetAddress (uint32_t i, Ipv4Address address) = 0;
virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0;
virtual Ipv4Mask GetNetworkMask (uint32_t t) const = 0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,40 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+ node = bld.create_obj('cpp', 'shlib')
+ node.name = 'ns3-node'
+ node.target = node.name
+ node.deps = ['ns3-core', 'ns3-common', 'ns3-simulator']
+ node.source = [
+ 'node.cc',
+ 'ipv4-address.cc',
+ 'net-device.cc',
+ 'mac-address.cc',
+ 'llc-snap-header.cc',
+ 'ipv4-route.cc',
+ 'queue.cc',
+ 'drop-tail.cc',
+ 'channel.cc',
+ 'node-list.cc',
+ 'socket.cc',
+ 'i-udp.cc',
+ 'i-ipv4.cc',
+ ]
+
+ headers = bld.create_obj('ns3header')
+ headers.source = [
+ 'node.h',
+ 'ipv4-address.h',
+ 'net-device.h',
+ 'mac-address.h',
+ 'ipv4-route.h',
+ 'queue.h',
+ 'drop-tail.h',
+ 'llc-snap-header.h',
+ 'channel.h',
+ 'node-list.h',
+ 'socket.h',
+ 'i-udp.h',
+ 'i-ipv4.h',
+ ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,95 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+import sys
+
+import Params
+
+
+def set_options(opt):
+ opt.add_option('--high-precision-as-double',
+ help=('Whether to use a double floating point'
+ ' type for high precision time values'),
+ action="store_true", default=False,
+ dest='high_precision_as_double')
+
+
+def configure(conf):
+ if Params.g_options.high_precision_as_double:
+ conf.add_define('USE_HIGH_PRECISION_DOUBLE', 1)
+ conf.env['USE_HIGH_PRECISION_DOUBLE'] = 1
+ highprec = 'long double'
+ else:
+ conf.env['USE_HIGH_PRECISION_DOUBLE'] = 0
+ highprec = '128-bit integer'
+ conf.check_message_custom('high precision time', 'implementation', highprec)
+
+ e = conf.create_header_configurator()
+ e.mandatory = False
+ e.name = 'stdint.h'
+ e.define = 'HAVE_STDINT_H'
+ e.run()
+
+ e = conf.create_header_configurator()
+ e.mandatory = False
+ e.name = 'inttypes.h'
+ e.define = 'HAVE_INTTYPES_H'
+ e.run()
+
+ e = conf.create_header_configurator()
+ e.mandatory = False
+ e.name = 'sys/inttypes.h'
+ e.define = 'HAVE_SYS_INT_TYPES_H'
+ e.run()
+
+ conf.write_config_header('ns3/simulator-config.h')
+
+
+
+def build(bld):
+ sim = bld.create_obj('cpp', 'shlib')
+ sim.name = 'ns3-simulator'
+ sim.target = sim.name
+ sim.deps = 'ns3-simulator-headers ns3-core-headers'
+
+ sim.source = [
+ 'high-precision.cc',
+ 'time.cc',
+ 'event-id.cc',
+ 'scheduler.cc',
+ 'scheduler-factory.cc',
+ 'scheduler-list.cc',
+ 'scheduler-heap.cc',
+ 'scheduler-map.cc',
+ 'event-impl.cc',
+ 'simulator.cc',
+ ]
+ headers = bld.create_obj('ns3header')
+ headers.name = 'ns3-simulator-headers'
+ headers.source = [
+ 'high-precision.h',
+ 'nstime.h',
+ 'event-id.h',
+ 'event-impl.h',
+ 'simulator.h',
+ 'scheduler.h',
+ 'scheduler-factory.h',
+ 'simulation-singleton.h',
+ ]
+
+ env = bld.env_of_name('default')
+ if env['USE_HIGH_PRECISION_DOUBLE']:
+ sim.source.extend([
+ 'high-precision-double.cc',
+ ])
+ headers.source.extend([
+ 'high-precision-double.h',
+ ])
+ else:
+ sim.source.extend([
+ 'high-precision-128.cc',
+ 'cairo-wideint.c',
+ ])
+ headers.source.extend([
+ 'high-precision-128.h',
+ 'cairo-wideint-private.h',
+ ])
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,13 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def set_options(opt):
+ opt.sub_options('simulator')
+
+def configure(conf):
+ conf.sub_config('core')
+ conf.sub_config('simulator')
+
+def build(bld):
+ bld.add_subdirs('core common simulator')
+ bld.add_subdirs('node internet-node devices applications')
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,25 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+import sys
+import Params
+
+def build(bld):
+
+ def create_ns_prog(name, source):
+ obj = bld.create_obj('cpp', 'program')
+ obj.target = name
+ obj.deps = "ns3-core ns3-common ns3-simulator"
+ obj.uselib_local = "ns3-core ns3-common ns3-simulator"
+ obj.source = source
+ for module in ['core', 'common', 'simulator']:
+ obj.env.append_value('RPATH', r'-Wl,--rpath=\$ORIGIN/../src/%s' % (module,))
+ return obj
+
+ unit_tests = create_ns_prog('run-tests', 'run-tests.cc')
+ unit_tests.install_var = 0 #do not install
+ unit_tests.unit_test = 1
+
+ #if sys.platform != 'win32':
+ obj = create_ns_prog('bench-simulator', 'bench-simulator.cc')
+ obj = create_ns_prog('replay-simulation', 'replay-simulation.cc')
+ ## bench-packets requires missing header files
+ #obj = create_ns_prog('bench-packets', 'bench-packets.cc')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wscript Sun May 13 11:24:28 2007 +0200
@@ -0,0 +1,183 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+import os
+
+import Params
+import Object
+import Action
+import Common
+import shutil
+import subprocess
+
+Params.g_autoconfig = 1
+
+# the following two variables are used by the target "waf dist"
+VERSION = '3.0.1'
+APPNAME = 'ns-3-waf'
+
+# these variables are mandatory ('/' are converted automatically)
+srcdir = '.'
+blddir = 'build'
+
+class Ns3Header(Object.genobj):
+ """A public NS-3 header file"""
+ def __init__(self, env=None):
+ Object.genobj.__init__(self, 'other')
+ self.inst_var = 'INCLUDEDIR'
+ self.inst_dir = 'ns3'
+ self.env = env
+ if not self.env:
+ self.env = Params.g_build.m_allenvs['default']
+
+ def apply(self):
+ ns3_dir_node = Params.g_build.m_srcnode.find_dir("ns3")
+ inputs = []
+ outputs = []
+ for filename in self.to_list(self.source):
+ src_node = self.path.find_source(filename)
+ if src_node is None:
+ Params.fatal("source ns3 header file %s not found" % (filename,))
+ dst_node = ns3_dir_node.find_build(os.path.basename(filename))
+ assert dst_node is not None
+ inputs.append(src_node)
+ outputs.append(dst_node)
+ task = self.create_task('ns3_headers', self.env, 1)
+ task.set_inputs(inputs)
+ task.set_outputs(outputs)
+
+ def install(self):
+ for i in self.m_tasks:
+ current = Params.g_build.m_curdirnode
+ lst = map(lambda a: a.relpath_gen(current), i.m_outputs)
+ Common.install_files(self.inst_var, self.inst_dir, lst)
+
+def _ns3_headers_inst(task):
+ assert len(task.m_inputs) == len(task.m_outputs)
+ inputs = [node.srcpath(task.m_env) for node in task.m_inputs]
+ outputs = [node.bldpath(task.m_env) for node in task.m_outputs]
+ for src, dst in zip(inputs, outputs):
+ try:
+ os.chmod(dst, 0600)
+ except OSError:
+ pass
+ shutil.copy2(src, dst)
+ ## make the headers in builddir read-only, to prevent
+ ## accidental modification
+ os.chmod(dst, 0400)
+ return 0
+
+def init():
+ Object.register('ns3header', Ns3Header)
+ Action.Action('ns3_headers', func=_ns3_headers_inst, color='BLUE')
+
+def set_options(opt):
+ # options provided by the modules
+ if not opt.tool_options('msvc'):
+ opt.tool_options('g++')
+
+ opt.add_option('--enable-gcov',
+ help=('Enable code coverage analysis'),
+ action="store_true", default=False,
+ dest='enable_gcov')
+
+ opt.add_option('--lcov-report',
+ help=('Generate a code coverage report '
+ '(use this option at build time, not in configure)'),
+ action="store_true", default=False,
+ dest='lcov_report')
+
+ opt.add_option('--doxygen',
+ help=('Run doxygen to generate html documentation from source comments'),
+ action="store_true", default=False,
+ dest='doxygen')
+
+ # options provided in a script in a subdirectory named "src"
+ opt.sub_options('src')
+
+
+def configure(conf):
+ if not conf.check_tool('msvc'):
+ if not conf.check_tool('g++'):
+ Params.fatal("No suitable compiler found")
+
+
+ # create the second environment, set the variant and set its name
+ variant_env = conf.env.copy()
+ variant_name = Params.g_options.debug_level.lower()
+
+ if Params.g_options.enable_gcov:
+ variant_name += '-gcov'
+ variant_env.append_value('CCFLAGS', '-fprofile-arcs')
+ variant_env.append_value('CCFLAGS', '-ftest-coverage')
+ variant_env.append_value('CXXFLAGS', '-fprofile-arcs')
+ variant_env.append_value('CXXFLAGS', '-ftest-coverage')
+ variant_env.append_value('LINKFLAGS', '-fprofile-arcs')
+
+ conf.env['NS3_ACTIVE_VARIANT'] = variant_name
+ variant_env['NS3_ACTIVE_VARIANT'] = variant_name
+ variant_env.set_variant(variant_name)
+ conf.set_env_name(variant_name, variant_env)
+ conf.setenv(variant_name)
+
+ variant_env.append_value('CXXDEFINES', 'RUN_SELF_TESTS')
+ if 'debug' in Params.g_options.debug_level.lower():
+ variant_env.append_value('CXXDEFINES', 'NS3_DEBUG_ENABLE')
+ variant_env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE')
+
+ conf.sub_config('src')
+
+
+def build(bld):
+ variant_name = bld.env_of_name('default')['NS3_ACTIVE_VARIANT']
+ variant_env = bld.env_of_name(variant_name)
+ bld.m_allenvs['default'] = variant_env # switch to the active variant
+ # process subfolders from here
+ bld.add_subdirs('src')
+ bld.add_subdirs('samples utils')
+
+
+def shutdown():
+ import UnitTest
+ ut = UnitTest.unit_test()
+ ut.change_to_testfile_dir = True
+ ut.want_to_see_test_output = True
+ ut.want_to_see_test_error = True
+ ut.run()
+ #ut.print_results()
+
+ if Params.g_options.lcov_report:
+ env = Params.g_build.env_of_name('default')
+ variant_name = env['NS3_ACTIVE_VARIANT']
+
+ if 'gcov' not in variant_name:
+ Params.fatal("project not configured for code coverage;"
+ " reconfigure with --enable-gcov")
+
+ os.chdir(blddir)
+ try:
+ lcov_report_dir = os.path.join(variant_name, 'lcov-report')
+ create_dir_command = "rm -rf " + lcov_report_dir
+ create_dir_command += " && mkdir " + lcov_report_dir + ";"
+
+ if subprocess.Popen(create_dir_command, shell=True).wait():
+ raise SystemExit(1)
+
+ info_file = os.path.join(lcov_report_dir, variant_name + '.info')
+ lcov_command = "../utils/lcov/lcov -c -d . -o " + info_file
+ lcov_command += " --source-dirs=" + os.getcwd()
+ lcov_command += ":" + os.path.join(
+ os.getcwd(), variant_name, 'include')
+ if subprocess.Popen(lcov_command, shell=True).wait():
+ raise SystemExit(1)
+
+ genhtml_command = "../utils/lcov/genhtml -o " + lcov_report_dir
+ genhtml_command += " " + info_file
+ if subprocess.Popen(genhtml_command, shell=True).wait():
+ raise SystemExit(1)
+ finally:
+ os.chdir("..")
+
+ if Params.g_options.doxygen:
+ doxygen_config = os.path.join('doc', 'doxygen.conf')
+ if subprocess.Popen(['doxygen', doxygen_config]).wait():
+ raise SystemExit(1)
+