merge
This commit is contained in:
@@ -1,19 +1,17 @@
|
||||
## -*- 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 = ["ns3-%s" % dep for dep in deps]
|
||||
obj.source = source
|
||||
return obj
|
||||
|
||||
obj = create_ns_prog('simple-global-routing', 'simple-global-routing.cc',
|
||||
deps=['point-to-point', 'internet-node', 'global-routing'])
|
||||
obj = create_ns_prog('simple-point-to-point', 'simple-point-to-point.cc',
|
||||
deps=['point-to-point', 'internet-node'])
|
||||
obj = create_ns_prog('csma-cd-one-subnet', 'csma-cd-one-subnet.cc',
|
||||
deps=['csma-cd', 'internet-node'])
|
||||
obj = create_ns_prog('csma-cd-packet-socket', 'csma-cd-packet-socket.cc', deps=['csma-cd', 'internet-node'])
|
||||
obj = bld.create_ns3_program('simple-global-routing',
|
||||
['point-to-point', 'internet-node', 'global-routing'])
|
||||
obj.source = 'simple-global-routing.cc'
|
||||
|
||||
obj = bld.create_ns3_program('simple-point-to-point', ['point-to-point', 'internet-node'])
|
||||
obj.source = 'simple-point-to-point.cc'
|
||||
|
||||
obj = bld.create_ns3_program('csma-cd-one-subnet', ['csma-cd', 'internet-node'])
|
||||
obj.source = 'csma-cd-one-subnet.cc'
|
||||
|
||||
obj = bld.create_ns3_program('csma-cd-packet-socket', ['csma-cd', 'internet-node'])
|
||||
obj.source = 'csma-cd-packet-socket.cc'
|
||||
|
||||
|
||||
@@ -1,28 +1,37 @@
|
||||
## -*- 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 = ["ns3-%s" % dep for dep in deps]
|
||||
obj.source = source
|
||||
return obj
|
||||
|
||||
obj = create_ns_prog('main-debug', ['main-debug.cc', 'main-debug-other.cc'])
|
||||
obj = create_ns_prog('main-callback', 'main-callback.cc')
|
||||
obj = create_ns_prog('main-ptr', 'main-ptr.cc')
|
||||
#obj = create_ns_prog('main-trace', 'main-trace.cc')
|
||||
obj = create_ns_prog('main-simulator', 'main-simulator.cc')
|
||||
obj = create_ns_prog('main-header', 'main-header.cc')
|
||||
obj = create_ns_prog('main-test', 'main-test.cc')
|
||||
obj = create_ns_prog('main-simple', 'main-simple.cc',
|
||||
deps=['node', 'internet-node', 'applications'])
|
||||
#obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'point-to-point'])
|
||||
obj = create_ns_prog('main-default-value', 'main-default-value.cc',
|
||||
deps=['core', 'simulator', 'node', 'point-to-point'])
|
||||
obj = create_ns_prog('main-grid-topology', 'main-grid-topology.cc',
|
||||
deps=['core', 'simulator', 'mobility', 'internet-node'])
|
||||
obj = create_ns_prog('main-random-topology', 'main-random-topology.cc',
|
||||
deps=['core', 'simulator', 'mobility'])
|
||||
obj = bld.create_ns3_program('main-debug')
|
||||
obj.source = ['main-debug.cc', 'main-debug-other.cc']
|
||||
|
||||
obj = bld.create_ns3_program('main-callback')
|
||||
obj.source = 'main-callback.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-ptr')
|
||||
obj.source = 'main-ptr.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-simulator')
|
||||
obj.source = 'main-simulator.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-header', ['common', 'simulator'])
|
||||
obj.source = 'main-header.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-test')
|
||||
obj.source = 'main-test.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-simple',
|
||||
['node', 'internet-node', 'applications'])
|
||||
obj.source = 'main-simple.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-default-value',
|
||||
['core', 'simulator', 'node', 'point-to-point'])
|
||||
obj.source = 'main-default-value.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-grid-topology',
|
||||
['core', 'simulator', 'mobility', 'internet-node'])
|
||||
obj.source = 'main-grid-topology.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-random-topology',
|
||||
['core', 'simulator', 'mobility'])
|
||||
obj.source = 'main-random-topology.cc'
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
## -*- 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.uselib_local = ['ns3-node']
|
||||
obj = bld.create_ns3_module('applications', ['node'])
|
||||
obj.source = [
|
||||
'onoff-application.cc',
|
||||
]
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
std::vector<uint8_t> TraceContext::m_sizes;
|
||||
|
||||
TraceContext::TraceContext ()
|
||||
: m_data (0)
|
||||
@@ -68,10 +67,17 @@ TraceContext::~TraceContext ()
|
||||
}
|
||||
}
|
||||
|
||||
TraceContext::Sizes *
|
||||
TraceContext::GetSizes (void)
|
||||
{
|
||||
static Sizes sizes;
|
||||
return &sizes;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
TraceContext::GetSize (uint8_t uid)
|
||||
{
|
||||
return m_sizes[uid];
|
||||
return (*GetSizes ())[uid];
|
||||
}
|
||||
|
||||
void
|
||||
@@ -218,7 +224,7 @@ TraceContext::DoGetNextUid (void)
|
||||
static uint8_t uid = 0;
|
||||
if (uid == 0)
|
||||
{
|
||||
m_sizes.push_back (0);
|
||||
GetSizes ()->push_back (0);
|
||||
}
|
||||
uid++;
|
||||
return uid;
|
||||
|
||||
@@ -95,7 +95,8 @@ private:
|
||||
bool DoAdd (uint8_t uid, uint8_t const *buffer);
|
||||
bool DoGet (uint8_t uid, uint8_t *buffer) const;
|
||||
|
||||
static std::vector<uint8_t> m_sizes;
|
||||
typedef std::vector<uint8_t> Sizes;
|
||||
static Sizes *GetSizes (void);
|
||||
struct Data {
|
||||
uint16_t count;
|
||||
uint16_t size;
|
||||
@@ -158,7 +159,7 @@ uint8_t
|
||||
TraceContext::GetNextUid (void)
|
||||
{
|
||||
uint8_t uid = DoGetNextUid ();
|
||||
m_sizes.push_back (sizeof (T));
|
||||
GetSizes ()->push_back (sizeof (T));
|
||||
return uid;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
## -*- 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.uselib_local = ['ns3-core', 'ns3-simulator']
|
||||
common = bld.create_ns3_module('common', ['core', 'simulator'])
|
||||
common.source = [
|
||||
'buffer.cc',
|
||||
'chunk.cc',
|
||||
|
||||
@@ -26,9 +26,7 @@ def configure(conf):
|
||||
|
||||
|
||||
def build(bld):
|
||||
core = bld.create_obj('cpp', 'shlib')
|
||||
core.name = 'ns3-core'
|
||||
core.target = core.name
|
||||
core = bld.create_ns3_module('core')
|
||||
core.source = [
|
||||
'callback-test.cc',
|
||||
'debug.cc',
|
||||
|
||||
@@ -267,7 +267,6 @@ CsmaCdChannel::PropagationCompleteEvent()
|
||||
m_currentPkt.GetUid () << ")");
|
||||
|
||||
NS_ASSERT(m_state == PROPAGATING);
|
||||
m_state = IDLE;
|
||||
|
||||
NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): Receive");
|
||||
|
||||
@@ -279,6 +278,7 @@ CsmaCdChannel::PropagationCompleteEvent()
|
||||
it->devicePtr->Receive (m_currentPkt);
|
||||
}
|
||||
}
|
||||
m_state = IDLE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
|
||||
def build(bld):
|
||||
obj = bld.create_obj('cpp', 'shlib')
|
||||
obj.name = 'ns3-csma-cd'
|
||||
obj.target = obj.name
|
||||
obj.uselib_local = ['ns3-node']
|
||||
obj = bld.create_ns3_module('csma-cd', ['node'])
|
||||
obj.source = [
|
||||
'backoff.cc',
|
||||
'csma-cd-net-device.cc',
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "p2p-channel.h"
|
||||
#include "p2p-net-device.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/debug.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("PointToPointChannel");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
//
|
||||
// By default, you get a channel with the name "PointToPoint Channel" that
|
||||
// has an "infitely" fast transmission speed and zero delay.
|
||||
//
|
||||
PointToPointChannel::PointToPointChannel()
|
||||
:
|
||||
Channel ("PointToPoint Channel"),
|
||||
m_bps (DataRate(0xffffffff)),
|
||||
m_delay (Seconds(0)),
|
||||
m_nDevices(0)
|
||||
{
|
||||
NS_DEBUG("PointToPointChannel::PointToPointChannel ()");
|
||||
}
|
||||
|
||||
PointToPointChannel::PointToPointChannel(
|
||||
const DataRate& bps,
|
||||
const Time& delay)
|
||||
:
|
||||
Channel ("PointToPoint Channel"),
|
||||
m_bps (bps),
|
||||
m_delay (delay),
|
||||
m_nDevices(0)
|
||||
{
|
||||
NS_DEBUG("PointToPointChannel::PointToPointChannel (" << Channel::GetName()
|
||||
<< ", " << bps.GetBitRate() << ", " << delay << ")");
|
||||
}
|
||||
|
||||
PointToPointChannel::PointToPointChannel(
|
||||
const std::string& name,
|
||||
const DataRate& bps,
|
||||
const Time& delay)
|
||||
:
|
||||
Channel (name),
|
||||
m_bps (bps),
|
||||
m_delay (delay),
|
||||
m_nDevices(0)
|
||||
{
|
||||
NS_DEBUG("PointToPointChannel::PointToPointChannel (" << name << ", " <<
|
||||
bps.GetBitRate() << ", " << delay << ")");
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointChannel::Attach(Ptr<PointToPointNetDevice> device)
|
||||
{
|
||||
NS_DEBUG("PointToPointChannel::Attach (" << device << ")");
|
||||
NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
|
||||
NS_ASSERT(device != 0);
|
||||
|
||||
m_link[m_nDevices].m_src = device;
|
||||
++m_nDevices;
|
||||
//
|
||||
// If we have both devices connected to the channel, then finish introducing
|
||||
// the two halves and set the links to IDLE.
|
||||
//
|
||||
if (m_nDevices == N_DEVICES)
|
||||
{
|
||||
m_link[0].m_dst = m_link[1].m_src;
|
||||
m_link[1].m_dst = m_link[0].m_src;
|
||||
m_link[0].m_state = IDLE;
|
||||
m_link[1].m_state = IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PointToPointChannel::TransmitStart(Packet& p, Ptr<PointToPointNetDevice> src)
|
||||
{
|
||||
NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src <<
|
||||
")");
|
||||
NS_DEBUG ("PointToPointChannel::TransmitStart (): 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;
|
||||
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PointToPointChannel::TransmitEnd(Packet& p, Ptr<PointToPointNetDevice> 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<PointToPointNetDevice> 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
|
||||
{
|
||||
return m_nDevices;
|
||||
}
|
||||
|
||||
Ptr<NetDevice>
|
||||
PointToPointChannel::GetDevice (uint32_t i) const
|
||||
{
|
||||
NS_ASSERT(i < 2);
|
||||
return m_link[i].m_src;
|
||||
}
|
||||
|
||||
DataRate
|
||||
PointToPointChannel::GetDataRate (void)
|
||||
{
|
||||
return m_bps;
|
||||
}
|
||||
|
||||
Time
|
||||
PointToPointChannel::GetDelay (void)
|
||||
{
|
||||
return m_delay;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
@@ -1,128 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef POINT_TO_POINT_CHANNEL_H
|
||||
#define POINT_TO_POINT_CHANNEL_H
|
||||
|
||||
#include <list>
|
||||
#include "ns3/channel.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/data-rate.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class PointToPointNetDevice;
|
||||
|
||||
/**
|
||||
* \brief Simple Point To Point Channel.
|
||||
*
|
||||
* This class represents a very simple point to point channel. Think full
|
||||
* duplex RS-232 or RS-422 with null modem and no handshaking. There is no
|
||||
* multi-drop capability on this channel -- there can be a maximum of two
|
||||
* point-to-point net devices connected. Once we start talking about multi-
|
||||
* drop, or CSMA, or some other sharing mechanism, things begin getting
|
||||
* complicated quickly. Rather than invent some ad-hoc mechanism, we just
|
||||
* Keep It Simple everywhere.
|
||||
*
|
||||
* When the channel is instaniated, the constructor takes parameters for
|
||||
* a single speed, in bits per second, and a speed-of-light delay time as a
|
||||
* Time object. Both directions use the same speed and delay time.
|
||||
*
|
||||
* There are two "wires" in the channel. The first device connected gets the
|
||||
* [0] wire to transmit on. The second device gets the [1] wire. There is a
|
||||
* state (IDLE, TRANSMITTING) associated with each wire.
|
||||
*/
|
||||
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 :-).
|
||||
//
|
||||
static const int N_DEVICES = 2;
|
||||
/**
|
||||
* \brief Create a PointToPointChannel
|
||||
*
|
||||
* By default, you get a channel with the name "PointToPoint Channel" that
|
||||
* has an "infitely" fast transmission speed and zero delay.
|
||||
*/
|
||||
PointToPointChannel ();
|
||||
|
||||
/**
|
||||
* \brief Create a PointToPointChannel
|
||||
*
|
||||
* \param bps The bitrate of the channel
|
||||
* \param delay Transmission delay through the channel
|
||||
*/
|
||||
PointToPointChannel (const DataRate& bps, const Time& delay);
|
||||
|
||||
/**
|
||||
* \brief Create a PointToPointChannel
|
||||
*
|
||||
* \param name the name of the channel for identification purposes
|
||||
* \param bps The bitrate of the channel
|
||||
* \param delay Transmission delay through the channel
|
||||
*/
|
||||
PointToPointChannel (const std::string& name,
|
||||
const DataRate& bps, const Time& delay);
|
||||
|
||||
/**
|
||||
* \brief Attach a given netdevice to this channel
|
||||
* \param device pointer to the netdevice to attach to the channel
|
||||
*/
|
||||
void Attach (Ptr<PointToPointNetDevice> device);
|
||||
bool TransmitStart (Packet& p, Ptr<PointToPointNetDevice> src);
|
||||
bool TransmitEnd (Packet &p, Ptr<PointToPointNetDevice> src);
|
||||
void PropagationCompleteEvent(Packet p, Ptr<PointToPointNetDevice> src);
|
||||
|
||||
|
||||
virtual uint32_t GetNDevices (void) const;
|
||||
virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
|
||||
|
||||
virtual DataRate GetDataRate (void);
|
||||
virtual Time GetDelay (void);
|
||||
|
||||
private:
|
||||
DataRate m_bps;
|
||||
Time m_delay;
|
||||
|
||||
int32_t m_nDevices;
|
||||
|
||||
enum WireState
|
||||
{
|
||||
INITIALIZING,
|
||||
IDLE,
|
||||
TRANSMITTING,
|
||||
PROPAGATING
|
||||
};
|
||||
|
||||
class Link
|
||||
{
|
||||
public:
|
||||
Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
|
||||
WireState m_state;
|
||||
Ptr<PointToPointNetDevice> m_src;
|
||||
Ptr<PointToPointNetDevice> m_dst;
|
||||
};
|
||||
|
||||
Link m_link[N_DEVICES];
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* POINT_TO_POINT_CHANNEL_H */
|
||||
@@ -1,354 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005,2006 INRIA
|
||||
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/queue.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/composite-trace-resolver.h"
|
||||
#include "p2p-net-device.h"
|
||||
#include "p2p-channel.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node)
|
||||
:
|
||||
NetDevice(node, MacAddress ("00:00:00:00:00:00")),
|
||||
m_txMachineState (READY),
|
||||
m_bps (DataRate (0xffffffff)),
|
||||
m_tInterframeGap (Seconds(0)),
|
||||
m_channel (0),
|
||||
m_queue (0),
|
||||
m_rxTrace ()
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")");
|
||||
|
||||
// BUGBUG FIXME
|
||||
//
|
||||
// You _must_ support broadcast to get any sort of packet from the ARP layer.
|
||||
EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
|
||||
EnableMulticast();
|
||||
EnablePointToPoint();
|
||||
}
|
||||
|
||||
PointToPointNetDevice::~PointToPointNetDevice()
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()");
|
||||
m_queue = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy constructor for PointToPointNetDevice.
|
||||
//
|
||||
// We use the underlying NetDevice copy constructor to get the base class
|
||||
// copied. These just remain as is (e.g. you get the same name, the same
|
||||
// MAC address). If you need to fix them up, YOU, the copier need to do
|
||||
// that.
|
||||
//
|
||||
// The things we need to be careful of are the channel, the queue and the
|
||||
// trace callback. If the channel pointer is non-zero, we copy the pointer
|
||||
// and add a reference. If the queue is non-zero, we copy it using the queue
|
||||
// assignment operator. We don't mess with the trace -- we just reset it.
|
||||
// We're assuming that the tracing will be set up after the topology creation
|
||||
// phase and this won't actually matter.
|
||||
//
|
||||
PointToPointNetDevice::PointToPointNetDevice (const PointToPointNetDevice& nd)
|
||||
:
|
||||
NetDevice(nd),
|
||||
m_txMachineState(READY),
|
||||
m_bps (nd.m_bps),
|
||||
m_tInterframeGap (nd.m_tInterframeGap),
|
||||
m_channel(nd.m_channel),
|
||||
m_queue(0),
|
||||
m_rxTrace ()
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << &nd << ")");
|
||||
|
||||
if (nd.m_queue)
|
||||
{
|
||||
m_queue = nd.m_queue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PointToPointNetDevice::DoDispose()
|
||||
{
|
||||
m_channel = 0;
|
||||
NetDevice::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)
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::operator= (" << &nd << ")");
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointNetDevice::SetDataRate(DataRate bps)
|
||||
{
|
||||
m_bps = bps;
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointNetDevice::SetInterframeGap(Time t)
|
||||
{
|
||||
m_tInterframeGap = t;
|
||||
}
|
||||
|
||||
bool
|
||||
PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
|
||||
NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
|
||||
|
||||
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.
|
||||
//
|
||||
// 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 (m_txMachineState == READY)
|
||||
{
|
||||
return TransmitStart (p);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PointToPointNetDevice::TransmitStart (Packet &p)
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::TransmitStart (" << &p << ")");
|
||||
NS_DEBUG (
|
||||
"PointToPointNetDevice::TransmitStart (): UID is " << p.GetUid () << ")");
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
|
||||
m_txMachineState = BUSY;
|
||||
Time tEvent = Seconds (m_bps.CalculateTxTime(p.GetSize()));
|
||||
|
||||
NS_DEBUG ("PointToPointNetDevice::TransmitStart (): " <<
|
||||
"Schedule TransmitCompleteEvent in " <<
|
||||
tEvent.GetSeconds () << "sec");
|
||||
|
||||
Simulator::Schedule (tEvent,
|
||||
&PointToPointNetDevice::TransmitCompleteEvent,
|
||||
this);
|
||||
return m_channel->TransmitStart (p, this);
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointNetDevice::TransmitCompleteEvent (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.
|
||||
//
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
PointToPointNetDevice::DoCreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
|
||||
resolver->Add ("queue",
|
||||
MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)),
|
||||
PointToPointNetDevice::QUEUE);
|
||||
resolver->Add ("rx",
|
||||
m_rxTrace,
|
||||
PointToPointNetDevice::RX);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
bool
|
||||
PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")");
|
||||
|
||||
m_channel = ch;
|
||||
|
||||
m_channel->Attach(this);
|
||||
m_bps = m_channel->GetDataRate ();
|
||||
m_tInterframeGap = m_channel->GetDelay ();
|
||||
|
||||
/*
|
||||
* For now, this device is up whenever a channel is attached to it.
|
||||
* In fact, it should become up only when the second device
|
||||
* is attached to the channel. So, there should be a way for
|
||||
* a PointToPointChannel to notify both of its attached devices
|
||||
* that the channel is 'complete', hence that the devices are
|
||||
* up, hence that they can call NotifyLinkUp.
|
||||
*/
|
||||
NotifyLinkUp ();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointNetDevice::AddQueue (Ptr<Queue> q)
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::AddQueue (" << q << ")");
|
||||
|
||||
m_queue = q;
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointNetDevice::Receive (Packet& p)
|
||||
{
|
||||
// ignore return value for now.
|
||||
NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")");
|
||||
|
||||
m_rxTrace (p);
|
||||
ForwardUp (p);
|
||||
}
|
||||
|
||||
Ptr<Queue>
|
||||
PointToPointNetDevice::GetQueue(void) const
|
||||
{
|
||||
return m_queue;
|
||||
}
|
||||
|
||||
Ptr<Channel>
|
||||
PointToPointNetDevice::DoGetChannel(void) const
|
||||
{
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
bool
|
||||
PointToPointNetDevice::DoNeedsArp (void) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
@@ -1,313 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
*
|
||||
* 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: Craig Dowell <craigdo@ee.washington.edu>
|
||||
*/
|
||||
|
||||
#ifndef POINT_TO_POINT_NET_DEVICE_H
|
||||
#define POINT_TO_POINT_NET_DEVICE_H
|
||||
|
||||
#include <string.h>
|
||||
#include "ns3/mac-address.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/callback-trace-source.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/data-rate.h"
|
||||
#include "ns3/ptr.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Queue;
|
||||
class PointToPointChannel;
|
||||
|
||||
/**
|
||||
* \class PointToPointNetDevice
|
||||
* \brief A Device for a Point to Point Network Link.
|
||||
*
|
||||
* Ns-3 takes a four-layer view of a protocol stack. This is the same model
|
||||
* that TCP uses. In this view, layers 5-7 of the OSI reference model are
|
||||
* grouped together into an application layer; layer four (transport / TCP) is
|
||||
* broken out; layer three (network / IP) is broken out; and layers 1-2 are
|
||||
* grouped together. We call this grouping of layers one and two a NetDevice
|
||||
* and represent it as a class in the system.
|
||||
*
|
||||
* The NetDevice class is specialized according to the needs of the specific
|
||||
* kind of network link. In this case, the link is a PointToPoint link. The
|
||||
* PointToPoint link is a family of classes that includes this class, the
|
||||
* PointToPointNetDevice, a PointToPointChannel class that represents the
|
||||
* actual medium across which bits are sent, a PointToPointIpv4Interface class
|
||||
* that provides the hook to tie a general purpose node to this specific
|
||||
* link, and finally, a PointToPointTopology object that is responsible for
|
||||
* putting all of the pieces together.
|
||||
*
|
||||
* This is the PointToPointNetDevice class that represents, essentially, the
|
||||
* PC card that is used to connect to the PointToPoint network.
|
||||
*/
|
||||
class PointToPointNetDevice : public NetDevice {
|
||||
public:
|
||||
/**
|
||||
* Enumeration of the types of traces supported in the class.
|
||||
*
|
||||
*/
|
||||
enum TraceType {
|
||||
QUEUE, /**< Trace queue events on the attached queue */
|
||||
RX, /**< Trace packet reception events (from the channel) */
|
||||
};
|
||||
/**
|
||||
* Construct a PointToPointNetDevice
|
||||
*
|
||||
* This is the constructor for the PointToPointNetDevice. It takes as a
|
||||
* parameter the Node to which this device is connected. Ownership of the
|
||||
* Node pointer is not implied and the node must not be deleded.
|
||||
*
|
||||
* @see PointToPointTopology::AddPointToPointLink ()
|
||||
* @param node the Node to which this device is connected.
|
||||
*/
|
||||
PointToPointNetDevice (Ptr<Node> node);
|
||||
/**
|
||||
* Copy Construct a PointToPointNetDevice
|
||||
*
|
||||
* This is the copy constructor for the PointToPointNetDevice. This is
|
||||
* primarily used in topology creation.
|
||||
*
|
||||
* @see PointToPointTopology::AddPointToPointLink ()
|
||||
* @param nd the object to be copied
|
||||
*/
|
||||
PointToPointNetDevice (const PointToPointNetDevice& nd);
|
||||
/**
|
||||
* Destroy a PointToPointNetDevice
|
||||
*
|
||||
* This is the destructor for the PointToPointNetDevice.
|
||||
*/
|
||||
virtual ~PointToPointNetDevice();
|
||||
/**
|
||||
* Assignment Operator for a PointToPointNetDevice
|
||||
*
|
||||
* This is the assignment operator for the PointToPointNetDevice. This is
|
||||
* to allow
|
||||
*
|
||||
* @param nd the object to be copied
|
||||
*/
|
||||
PointToPointNetDevice& operator= (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
|
||||
* to which the device is attached. It can be overridden using this method.
|
||||
*
|
||||
* @see Attach ()
|
||||
* @param bps the data rate at which this object operates
|
||||
*/
|
||||
void SetDataRate(DataRate bps);
|
||||
/**
|
||||
* Set the inteframe gap used to separate packets. The interframe gap
|
||||
* defines the minimum space required between packets sent by this device.
|
||||
* It is usually set in the Attach () method based on the speed of light
|
||||
* delay of the channel to which the device is attached. It can be
|
||||
* overridden using this method if desired.
|
||||
*
|
||||
* @see Attach ()
|
||||
* @param t the interframe gap time
|
||||
*/
|
||||
void SetInterframeGap(Time t);
|
||||
/**
|
||||
* Attach the device to a channel.
|
||||
*
|
||||
* The PointToPointTopology object creates a PointToPointChannel and two
|
||||
* PointtoPointNetDevices. In order to introduce these components to each
|
||||
* other, the topology object calls Attach () on each PointToPointNetDevice.
|
||||
* Inside this method, the Net Device calls out to the PointToPointChannel
|
||||
* to introduce itself.
|
||||
*
|
||||
* @see PointToPointTopology::AddPointToPointLink ()
|
||||
* @see SetDataRate ()
|
||||
* @see SetInterframeGap ()
|
||||
* @param ch a pointer to the channel to which this object is being attached.
|
||||
*/
|
||||
bool Attach(Ptr<PointToPointChannel> ch);
|
||||
/**
|
||||
* Attach a queue to the PointToPointNetDevice.
|
||||
*
|
||||
* The PointToPointNetDevice "owns" a queue. This queue is created by the
|
||||
* PointToPointTopology object and implements a queueing method such as
|
||||
* DropTail or RED. The PointToPointNetDevice assumes ownership of this
|
||||
* queue and must delete it when the device is destroyed.
|
||||
*
|
||||
* @see PointToPointTopology::AddPointToPointLink ()
|
||||
* @see Queue
|
||||
* @see DropTailQueue
|
||||
* @param queue a pointer to the queue for which object is assuming
|
||||
* ownership.
|
||||
*/
|
||||
void AddQueue(Ptr<Queue> queue);
|
||||
/**
|
||||
* Receive a packet from a connected PointToPointChannel.
|
||||
*
|
||||
* The PointToPointNetDevice receives packets from its connected channel
|
||||
* and forwards them up the protocol stack. This is the public method
|
||||
* used by the channel to indicate that the last bit of a packet has
|
||||
* arrived at the device.
|
||||
*
|
||||
* @see PointToPointChannel
|
||||
* @param p a reference to the received packet
|
||||
*/
|
||||
void Receive (Packet& p);
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
/**
|
||||
* Get a copy of the attached Queue.
|
||||
*
|
||||
* This method is provided for any derived class that may need to get
|
||||
* direct access to the underlying queue.
|
||||
*
|
||||
* @see PointToPointTopology
|
||||
* @returns a pointer to the queue.
|
||||
*/
|
||||
Ptr<Queue> GetQueue(void) const;
|
||||
/**
|
||||
* Get a copy of the attached Channel
|
||||
*
|
||||
* This method is provided for any derived class that may need to get
|
||||
* direct access to the connected channel
|
||||
*
|
||||
* @see PointToPointChannel
|
||||
* @returns a pointer to the channel
|
||||
*/
|
||||
virtual Ptr<Channel> DoGetChannel(void) const;
|
||||
private:
|
||||
/**
|
||||
* Send a Packet Down the Wire.
|
||||
*
|
||||
* The SendTo method is defined as the standard way that the level three
|
||||
* protocol uses to tell a NetDevice to send a packet. SendTo is declared
|
||||
* as abstract in the NetDevice class and we declare it here.
|
||||
*
|
||||
* @see NetDevice
|
||||
* @param p a reference to the packet to send
|
||||
* @param dest a reference to the MacAddress of the destination device
|
||||
* @returns true if success, false on failure
|
||||
*/
|
||||
virtual bool SendTo (Packet& p, const MacAddress& dest);
|
||||
/**
|
||||
* Start Sending a Packet Down the Wire.
|
||||
*
|
||||
* The TransmitStart method is the method that is used internally in the
|
||||
* PointToPointNetDevice to begin the process of sending a packet out on
|
||||
* the channel. The corresponding method is called on the channel to let
|
||||
* it know that the physical device this class represents has virually
|
||||
* started sending signals. An event is scheduled for the time at which
|
||||
* the bits have been completely transmitted.
|
||||
*
|
||||
* @see PointToPointChannel::TransmitStart ()
|
||||
* @see TransmitCompleteEvent ()
|
||||
* @param p a reference to the packet to send
|
||||
* @returns true if success, false on failure
|
||||
*/
|
||||
bool TransmitStart (Packet &p);
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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);
|
||||
/**
|
||||
* Create a Trace Resolver for events in the net device.
|
||||
*
|
||||
* @see class TraceResolver
|
||||
*/
|
||||
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
|
||||
virtual bool DoNeedsArp (void) const;
|
||||
/**
|
||||
* Enumeration of the states of the transmit machine of the net device.
|
||||
*/
|
||||
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 */
|
||||
};
|
||||
/**
|
||||
* The state of the Net Device transmit state machine.
|
||||
* @see TxMachineState
|
||||
*/
|
||||
TxMachineState m_txMachineState;
|
||||
/**
|
||||
* The data rate that the Net Device uses to simulate packet transmission
|
||||
* timing.
|
||||
* @see class DataRate
|
||||
*/
|
||||
DataRate m_bps;
|
||||
/**
|
||||
* The interframe gap that the Net Device uses to throttle packet
|
||||
* transmission
|
||||
* @see class Time
|
||||
*/
|
||||
Time m_tInterframeGap;
|
||||
/**
|
||||
* The PointToPointChannel to which this PointToPointNetDevice has been
|
||||
* attached.
|
||||
* @see class PointToPointChannel
|
||||
*/
|
||||
Ptr<PointToPointChannel> m_channel;
|
||||
/**
|
||||
* The Queue which this PointToPointNetDevice uses as a packet source.
|
||||
* Management of this Queue has been delegated to the PointToPointNetDevice
|
||||
* and it has the responsibility for deletion.
|
||||
* @see class Queue
|
||||
* @see class DropTailQueue
|
||||
*/
|
||||
Ptr<Queue> m_queue;
|
||||
/**
|
||||
* The trace source for the packet reception events that the device can
|
||||
* fire.
|
||||
*
|
||||
* @see class CallBackTraceSource
|
||||
* @see class TraceResolver
|
||||
*/
|
||||
CallbackTraceSource<Packet &> m_rxTrace;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif // POINT_TO_POINT_NET_DEVICE_H
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2006 Georgia Tech Research Corporation
|
||||
//
|
||||
// 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>
|
||||
//
|
||||
|
||||
//
|
||||
// Topology helper for ns3.
|
||||
// George F. Riley, Georgia Tech, Spring 2007
|
||||
|
||||
#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"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/queue.h"
|
||||
|
||||
#include "p2p-channel.h"
|
||||
#include "p2p-net-device.h"
|
||||
#include "p2p-topology.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Ptr<PointToPointChannel>
|
||||
PointToPointTopology::AddPointToPointLink(
|
||||
Ptr<Node> n1,
|
||||
Ptr<Node> n2,
|
||||
const DataRate& bps,
|
||||
const Time& delay)
|
||||
{
|
||||
Ptr<PointToPointChannel> channel = Create<PointToPointChannel> (bps, delay);
|
||||
|
||||
Ptr<PointToPointNetDevice> net1 = Create<PointToPointNetDevice> (n1);
|
||||
|
||||
Ptr<Queue> q = Queue::CreateDefault ();
|
||||
net1->AddQueue(q);
|
||||
net1->Attach (channel);
|
||||
|
||||
Ptr<PointToPointNetDevice> net2 = Create<PointToPointNetDevice> (n2);
|
||||
|
||||
q = Queue::CreateDefault ();
|
||||
net2->AddQueue(q);
|
||||
net2->Attach (channel);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointTopology::AddIpv4Addresses(
|
||||
Ptr<const PointToPointChannel> chan,
|
||||
Ptr<Node> n1, const Ipv4Address& addr1,
|
||||
Ptr<Node> n2, const Ipv4Address& addr2)
|
||||
{
|
||||
|
||||
// Duplex link is assumed to be subnetted as a /30
|
||||
// May run this unnumbered in the future?
|
||||
Ipv4Mask netmask("255.255.255.252");
|
||||
NS_ASSERT (netmask.IsMatch(addr1,addr2));
|
||||
|
||||
// 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);
|
||||
// Make sure that nd1 belongs to n1 and nd2 to n2
|
||||
if ( (nd1->GetNode ()->GetId () == n2->GetId () ) &&
|
||||
(nd2->GetNode ()->GetId () == n1->GetId () ) )
|
||||
{
|
||||
std::swap(nd1, nd2);
|
||||
}
|
||||
NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
|
||||
NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
|
||||
|
||||
Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
uint32_t index1 = ip1->AddInterface (nd1);
|
||||
|
||||
ip1->SetAddress (index1, addr1);
|
||||
ip1->SetNetworkMask (index1, netmask);
|
||||
ip1->SetUp (index1);
|
||||
|
||||
Ptr<Ipv4> ip2 = n2->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
uint32_t index2 = ip2->AddInterface (nd2);
|
||||
|
||||
ip2->SetAddress (index2, addr2);
|
||||
ip2->SetNetworkMask (index2, netmask);
|
||||
ip2->SetUp (index2);
|
||||
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
// Assert that both are Ipv4 nodes
|
||||
Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::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);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2006 Georgia Tech Research Corporation
|
||||
//
|
||||
// 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>
|
||||
//
|
||||
// Topology helper for ns3.
|
||||
// George F. Riley, Georgia Tech, Spring 2007
|
||||
#ifndef __POINT_TO_POINT_TOPOLOGY_H__
|
||||
#define __POINT_TO_POINT_TOPOLOGY_H__
|
||||
|
||||
#include "ns3/ptr.h"
|
||||
|
||||
// The topology class consists of only static methods thar are used to
|
||||
// create the topology and data flows for an ns3 simulation
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class PointToPointChannel;
|
||||
class Node;
|
||||
class IPAddr;
|
||||
class DataRate;
|
||||
class Queue;
|
||||
|
||||
/**
|
||||
* \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 dataRate 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
|
||||
* and attach PointToPointNetDevices to the resulting
|
||||
* PointToPointChannel.
|
||||
*/
|
||||
static Ptr<PointToPointChannel> AddPointToPointLink(
|
||||
Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
|
||||
|
||||
/**
|
||||
* \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);
|
||||
|
||||
/**
|
||||
* \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 void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
## -*- 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'
|
||||
p2p.target = p2p.name
|
||||
p2p.uselib_local = ['ns3-node']
|
||||
p2p.source = [
|
||||
'p2p-net-device.cc',
|
||||
'p2p-channel.cc',
|
||||
'p2p-topology.cc',
|
||||
]
|
||||
headers = bld.create_obj('ns3header')
|
||||
headers.source = [
|
||||
'p2p-net-device.h',
|
||||
'p2p-channel.h',
|
||||
'p2p-topology.h',
|
||||
]
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_obj('cpp', 'shlib')
|
||||
module.name = 'ns3-point-to-point'
|
||||
module.target = module.name
|
||||
module.uselib_local = ['ns3-node']
|
||||
module = bld.create_ns3_module('point-to-point', ['node'])
|
||||
module.source = [
|
||||
'point-to-point-net-device.cc',
|
||||
'point-to-point-channel.cc',
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
|
||||
def build(bld):
|
||||
obj = bld.create_obj('cpp', 'shlib')
|
||||
obj.name = 'ns3-internet-node'
|
||||
obj.target = obj.name
|
||||
obj.uselib_local = ['ns3-node', 'ns3-applications']
|
||||
obj = bld.create_ns3_module('internet-node', ['node', 'applications'])
|
||||
obj.source = [
|
||||
'internet-node.cc',
|
||||
'ipv4-l4-demux.cc',
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
mobility = bld.create_obj('cpp', 'shlib')
|
||||
mobility.name = 'ns3-mobility'
|
||||
mobility.target = mobility.name
|
||||
mobility.uselib_local = ['ns3-core', 'ns3-simulator']
|
||||
mobility = bld.create_ns3_module('mobility', ['core', 'simulator'])
|
||||
mobility.source = [
|
||||
'grid-topology.cc',
|
||||
'hierarchical-mobility-model.cc',
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
## -*- 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.uselib_local = ['ns3-core', 'ns3-common', 'ns3-simulator']
|
||||
node = bld.create_ns3_module('node', ['core', 'common', 'simulator'])
|
||||
node.source = [
|
||||
'address.cc',
|
||||
'eui48-address.cc',
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_obj('cpp', 'shlib')
|
||||
module.name = 'ns3-global-routing'
|
||||
module.target = module.name
|
||||
module.uselib_local = ['ns3-node']
|
||||
module = bld.create_ns3_module('global-routing', ['node'])
|
||||
module.source = [
|
||||
'global-router-interface.cc',
|
||||
'global-route-manager.cc',
|
||||
|
||||
@@ -47,11 +47,7 @@ def configure(conf):
|
||||
|
||||
|
||||
def build(bld):
|
||||
sim = bld.create_obj('cpp', 'shlib')
|
||||
sim.name = 'ns3-simulator'
|
||||
sim.target = sim.name
|
||||
sim.uselib_local = ['ns3-core']
|
||||
|
||||
sim = bld.create_ns3_module('simulator', ['core'])
|
||||
sim.source = [
|
||||
'high-precision.cc',
|
||||
'time.cc',
|
||||
|
||||
19
src/wscript
19
src/wscript
@@ -2,6 +2,7 @@
|
||||
|
||||
import os, os.path
|
||||
import shutil
|
||||
import types
|
||||
|
||||
import Action
|
||||
import Common
|
||||
@@ -38,22 +39,38 @@ def configure(conf):
|
||||
conf.sub_config('simulator')
|
||||
|
||||
blddir = os.path.abspath(os.path.join(conf.m_blddir, conf.env.variant()))
|
||||
conf.env['NS3_MODULE_PATH'] = [os.path.join(blddir, 'src')]
|
||||
for module in all_modules:
|
||||
module_path = os.path.join(blddir, 'src', module)
|
||||
conf.env.append_value('NS3_MODULE_PATH', module_path)
|
||||
if Params.g_options.enable_rpath:
|
||||
conf.env.append_value('RPATH', '-Wl,-rpath=%s' % (module_path,))
|
||||
|
||||
## 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 create_ns3_module(bld, name, dependencies=()):
|
||||
module = bld.create_obj('cpp', 'objects')
|
||||
module.name = 'ns3-' + name
|
||||
module.target = module.name
|
||||
module.add_objects = ['ns3-' + dep for dep in dependencies]
|
||||
module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
|
||||
return module
|
||||
|
||||
|
||||
def build(bld):
|
||||
Object.register('ns3header', Ns3Header)
|
||||
Action.Action('ns3header', func=_ns3_headers_inst, color='BLUE')
|
||||
bld.create_ns3_module = types.MethodType(create_ns3_module, bld)
|
||||
|
||||
bld.add_subdirs(list(all_modules))
|
||||
|
||||
## Create a single ns3 library containing all modules
|
||||
lib = bld.create_obj('cpp', 'shlib')
|
||||
lib.name = 'ns3'
|
||||
lib.target = 'ns3'
|
||||
lib.add_objects = list(bld.env_of_name('default')['NS3_MODULES'])
|
||||
|
||||
|
||||
class Ns3Header(Object.genobj):
|
||||
"""A set of NS-3 header files"""
|
||||
def __init__(self, env=None):
|
||||
|
||||
@@ -4,20 +4,15 @@
|
||||
def build(bld):
|
||||
env = bld.env_of_name('default')
|
||||
|
||||
def create_ns_prog(name, source):
|
||||
obj = bld.create_obj('cpp', 'program')
|
||||
obj.target = name
|
||||
obj.source = source
|
||||
return obj
|
||||
|
||||
unit_tests = create_ns_prog('run-tests', 'run-tests.cc')
|
||||
unit_tests = bld.create_ns3_program('run-tests')
|
||||
unit_tests.install_var = 0 # do not install
|
||||
unit_tests.unit_test = 1 # runs on 'waf check'
|
||||
unit_tests.source = 'run-tests.cc'
|
||||
## link unit test program with all ns3 modules
|
||||
unit_tests.uselib_local = env['NS3_MODULES']
|
||||
unit_tests.uselib_local = 'ns3'
|
||||
|
||||
obj = create_ns_prog('bench-simulator', 'bench-simulator.cc')
|
||||
obj.uselib_local = "ns3-core ns3-common ns3-simulator"
|
||||
obj = bld.create_ns3_program('bench-simulator', ['simulator'])
|
||||
obj.source = 'bench-simulator.cc'
|
||||
|
||||
obj = create_ns_prog('replay-simulation', 'replay-simulation.cc')
|
||||
obj.uselib_local = "ns3-core ns3-common ns3-simulator"
|
||||
obj = bld.create_ns3_program('replay-simulation', ['simulator'])
|
||||
obj.source = 'replay-simulation.cc'
|
||||
|
||||
338
waf
vendored
Executable file
338
waf
vendored
Executable file
File diff suppressed because one or more lines are too long
15
wscript
15
wscript
@@ -2,12 +2,13 @@
|
||||
import sys
|
||||
import shlex
|
||||
import shutil
|
||||
import types
|
||||
import optparse
|
||||
import os.path
|
||||
|
||||
import Params
|
||||
import Object
|
||||
import pproc as subprocess
|
||||
import optparse
|
||||
import os.path
|
||||
|
||||
Params.g_autoconfig = 1
|
||||
|
||||
@@ -135,7 +136,17 @@ def configure(conf):
|
||||
conf.sub_config('src')
|
||||
|
||||
|
||||
def create_ns3_program(bld, name, dependencies=('simulator',)):
|
||||
program = bld.create_obj('cpp', 'program')
|
||||
program.name = name
|
||||
program.target = program.name
|
||||
program.uselib_local = 'ns3'
|
||||
return program
|
||||
|
||||
|
||||
def build(bld):
|
||||
bld.create_ns3_program = types.MethodType(create_ns3_program, 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
|
||||
|
||||
Reference in New Issue
Block a user