merge with trunk

This commit is contained in:
Mathieu Lacage
2007-05-13 11:24:28 +02:00
28 changed files with 788 additions and 445 deletions

View File

@@ -2,6 +2,8 @@
.*\.o$
.*~$
build-dir
build
.*\.sconsign
doc/html.*
doc/latex.*
.lock-wscript

View File

@@ -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
*

View File

@@ -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 @@ int main (int argc, char *argv[])
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 @@ int main (int argc, char *argv[])
// 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 ();

1
ns3/_placeholder_ Normal file
View File

@@ -0,0 +1 @@
This is a placeholder file used only to keep the ns3 directory present (needed for the WAF build system).

30
samples/wscript Normal file
View File

@@ -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'])

20
src/applications/wscript Normal file
View File

@@ -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',
]

49
src/common/wscript Normal file
View File

@@ -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',
]

View File

@@ -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>

View File

@@ -6,6 +6,11 @@
#include <list>
#include "callback.h"
/**
* \defgroup config Simulation configuration
*
*/
namespace ns3 {
class DefaultValueBase
@@ -45,6 +50,7 @@ class DefaultValueList
};
/**
* \ingroup config
* \param name name of variable to bind
* \param value value to bind to the specified variable
*
@@ -58,6 +64,7 @@ void Bind (std::string name, std::string value);
/**
* \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 @@ private:
/**
* \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 @@ private:
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 @@ private:
/**
* \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 @@ public:
T m_value;
};
/**
* \brief Class used to call a certain function during the configuration of the
* simulation
* \ingroup config
*/
class CommandDefaultValue : public DefaultValueBase
{
public:

74
src/core/wscript Normal file
View File

@@ -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',
]

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 @@ PointToPointTopology::AddPointToPointLink(
return channel;
}
bool
void
PointToPointTopology::AddIpv4Addresses(
Ptr<const PointToPointChannel> chan,
Ptr<Node> n1, const Ipv4Address& addr1,
@@ -99,111 +101,72 @@ PointToPointTopology::AddIpv4Addresses(
ip2->SetNetworkMask (index2, netmask);
ip2->SetUp (index2);
ip1->AddHostRouteTo (addr2, index1);
ip2->AddHostRouteTo (addr1, index2);
return true;
}
#ifdef NOTYET
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);
// 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
// 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");
}
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();
// 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");
}
// 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);
}
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
#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
}
// 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

View File

@@ -34,47 +34,51 @@ class Node;
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
* \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<PointToPointChannel> GetChannel(Ptr<Node>, Ptr<Node>);
/**
* Get the NetDevice connecting node n1 to n2
*/
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

18
src/devices/p2p/wscript Normal file
View File

@@ -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',
]

6
src/devices/wscript Normal file
View File

@@ -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')

View File

@@ -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 @@ IIpv4Impl::GetNInterfaces (void)
{
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)

View File

@@ -54,6 +54,7 @@ public:
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);

43
src/internet-node/wscript Normal file
View File

@@ -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',
]

View File

@@ -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 Node;
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
{

View File

@@ -122,6 +122,12 @@ public:
*/
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;

40
src/node/wscript Normal file
View File

@@ -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',
]

95
src/simulator/wscript Normal file
View File

@@ -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',
])

13
src/wscript Normal file
View File

@@ -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')

25
utils/wscript Normal file
View File

@@ -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')

183
wscript Normal file
View File

@@ -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)