Begin checkin of ns-3-gfr; s/UdpSocket/DatagramSocket; bring in Application base class and onoff-application, and base class socket; bring in random number generator files
--- a/SConstruct Sun Mar 18 14:06:51 2007 -0700
+++ b/SConstruct Sun Mar 18 14:30:26 2007 -0700
@@ -22,6 +22,8 @@
'assert.cc',
'ptr.cc',
'test.cc',
+ 'random-variable.cc',
+ 'rng-stream.cc',
])
env = Environment()
if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin':
@@ -44,7 +46,9 @@
'debug.h',
'assert.h',
'fatal-error.h',
- 'test.h'
+ 'test.h',
+ 'random-variable.h',
+ 'rng-stream.h'
])
def config_core (env, config):
@@ -192,9 +196,10 @@
'ipv4.cc',
'ipv4-end-point.cc',
'udp-end-point.cc',
- 'udp-socket.cc',
+ 'datagram-socket.cc',
'udp.cc',
'arp-header.cc',
+ 'application.cc',
'arp-cache.cc',
'arp-ipv4-interface.cc',
'arp.cc',
@@ -213,6 +218,7 @@
'ipv4-checksum.h',
'udp.h',
'ipv4-l4-protocol.h',
+ 'application.h',
'arp-header.h',
'arp-cache-cache.h',
'arp.h',
@@ -227,7 +233,7 @@
node.add_inst_headers ([
'node.h',
'internet-node.h',
- 'udp-socket.h',
+ 'datagram-socket.h',
'ipv4-address.h',
'net-device.h',
'arp-ipv4-interface.h',
--- a/samples/main-serial-net-device-if.cc Sun Mar 18 14:06:51 2007 -0700
+++ b/samples/main-serial-net-device-if.cc Sun Mar 18 14:30:26 2007 -0700
@@ -35,7 +35,7 @@
#include "ns3/arp-ipv4-interface.h"
#include "ns3/ipv4.h"
#include "ns3/trace-context.h"
-#include "ns3/udp-socket.h"
+#include "ns3/datagram-socket.h"
#include "ns3/simulator.h"
#include "ns3/node-list.h"
#include "ns3/trace-root.h"
@@ -94,7 +94,7 @@
};
static void
-GenerateTraffic (UdpSocket *socket, uint32_t size)
+GenerateTraffic (DatagramSocket *socket, uint32_t size)
{
std::cout << "Node: " << socket->GetNode()->GetId ()
<< " at=" << Simulator::Now ().GetSeconds () << "s,"
@@ -107,7 +107,7 @@
}
static void
-UdpSocketPrinter (UdpSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
+DatagramSocketPrinter (DatagramSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
{
std::cout << "Node: " << socket->GetNode()->GetId ()
<< " at=" << Simulator::Now ().GetSeconds () << "s,"
@@ -115,9 +115,9 @@
}
static void
-PrintTraffic (UdpSocket *socket)
+PrintTraffic (DatagramSocket *socket)
{
- socket->SetDummyRxCallback (MakeCallback (&UdpSocketPrinter));
+ socket->SetDummyRxCallback (MakeCallback (&DatagramSocketPrinter));
}
@@ -224,8 +224,8 @@
b.GetIpv4()->SetDefaultRoute (Ipv4Address ("10.1.1.1"), 1);
- UdpSocket *source = new UdpSocket (&a);
- UdpSocket *sink = new UdpSocket(&b);
+ DatagramSocket *source = new DatagramSocket (&a);
+ DatagramSocket *sink = new DatagramSocket(&b);
sink->Bind (80);
source->SetDefaultDestination (Ipv4Address ("10.1.1.2"), 80);
--- a/samples/main-simple-p2p.cc Sun Mar 18 14:06:51 2007 -0700
+++ b/samples/main-simple-p2p.cc Sun Mar 18 14:30:26 2007 -0700
@@ -3,7 +3,7 @@
#include "ns3/internet-node.h"
#include "ns3/simulator.h"
-#include "ns3/udp-socket.h"
+#include "ns3/datagram-socket.h"
#include "ns3/nstime.h"
#include "ns3/p2p-channel.h"
#include "ns3/p2p-net-device.h"
@@ -15,7 +15,7 @@
static void
-GenerateTraffic (UdpSocket *socket, uint32_t size)
+GenerateTraffic (DatagramSocket *socket, uint32_t size)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl;
socket->SendDummy (size);
@@ -26,15 +26,15 @@
}
static void
-UdpSocketPrinter (UdpSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
+DatagramSocketPrinter (DatagramSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl;
}
static void
-PrintTraffic (UdpSocket *socket)
+PrintTraffic (DatagramSocket *socket)
{
- socket->SetDummyRxCallback (MakeCallback (&UdpSocketPrinter));
+ socket->SetDummyRxCallback (MakeCallback (&DatagramSocketPrinter));
}
static void
@@ -94,9 +94,9 @@
AddP2PLink (a, b);
- UdpSocket *sink = new UdpSocket (a);
+ DatagramSocket *sink = new DatagramSocket (a);
sink->Bind (80);
- UdpSocket *source = new UdpSocket (b);
+ DatagramSocket *source = new DatagramSocket (b);
source->SetDefaultDestination (Ipv4Address ("192.168.0.2"), 80);
GenerateTraffic (source, 500);
--- a/samples/main-simple.cc Sun Mar 18 14:06:51 2007 -0700
+++ b/samples/main-simple.cc Sun Mar 18 14:30:26 2007 -0700
@@ -2,7 +2,7 @@
#include "ns3/internet-node.h"
#include "ns3/simulator.h"
-#include "ns3/udp-socket.h"
+#include "ns3/datagram-socket.h"
#include "ns3/nstime.h"
using namespace ns3;
@@ -31,7 +31,7 @@
}
static void
-GenerateTraffic (UdpSocket *socket, uint32_t size)
+GenerateTraffic (DatagramSocket *socket, uint32_t size)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl;
socket->SendDummy (size);
@@ -42,15 +42,15 @@
}
static void
-UdpSocketPrinter (UdpSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
+DatagramSocketPrinter (DatagramSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl;
}
static void
-PrintTraffic (UdpSocket *socket)
+PrintTraffic (DatagramSocket *socket)
{
- socket->SetDummyRxCallback (MakeCallback (&UdpSocketPrinter));
+ socket->SetDummyRxCallback (MakeCallback (&DatagramSocketPrinter));
}
int main (int argc, char *argv[])
@@ -59,10 +59,10 @@
InternetNode *a = new InternetNode ();
- UdpSocket *sink = new UdpSocket (a);
+ DatagramSocket *sink = new DatagramSocket (a);
sink->Bind (80);
- UdpSocket *source = new UdpSocket (a);
+ DatagramSocket *source = new DatagramSocket (a);
source->SetDefaultDestination (Ipv4Address::GetLoopback (), 80);
GenerateTraffic (source, 500);
--- a/samples/ns-2/simple.cc Sun Mar 18 14:06:51 2007 -0700
+++ b/samples/ns-2/simple.cc Sun Mar 18 14:30:26 2007 -0700
@@ -53,7 +53,7 @@
#include "ns3/ipv4-address.h"
#include "ns3/arp-ipv4-interface.h"
#include "ns3/ipv4.h"
-#include "ns3/udp-socket.h"
+#include "ns3/datagram-socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/drop-tail.h"
#include "ns3/trace-writer.h"
@@ -164,7 +164,7 @@
static void
-GenerateTraffic (UdpSocket *socket, uint32_t size)
+GenerateTraffic (DatagramSocket *socket, uint32_t size)
{
std::cout << "Node: " << socket->GetNode()->GetId ()
<< " at=" << Simulator::Now ().GetSeconds () << "s,"
@@ -177,7 +177,7 @@
}
static void
-UdpSocketPrinter (UdpSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
+DatagramSocketPrinter (DatagramSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
{
std::cout << "Node: " << socket->GetNode()->GetId ()
<< " at=" << Simulator::Now ().GetSeconds () << "s,"
@@ -185,9 +185,9 @@
}
static void
-PrintTraffic (UdpSocket *socket)
+PrintTraffic (DatagramSocket *socket)
{
- socket->SetDummyRxCallback (MakeCallback (&UdpSocketPrinter));
+ socket->SetDummyRxCallback (MakeCallback (&DatagramSocketPrinter));
}
#if 0
@@ -311,11 +311,11 @@
n2, Ipv4Address("10.1.3.1"), MacAddress("00:00:00:00:00:05"),
n3, Ipv4Address("10.1.3.2"), MacAddress("00:00:00:00:00:06"));
- UdpSocket *source0 = new UdpSocket (n0);
- UdpSocket *source3 = new UdpSocket (n3);
- UdpSocket *sink3 = new UdpSocket(n3);
+ DatagramSocket *source0 = new DatagramSocket (n0);
+ DatagramSocket *source3 = new DatagramSocket (n3);
+ DatagramSocket *sink3 = new DatagramSocket(n3);
sink3->Bind (80);
- UdpSocket *sink1 = new UdpSocket(n1);
+ DatagramSocket *sink1 = new DatagramSocket(n1);
sink1->Bind (80);
source3->SetDefaultDestination (Ipv4Address ("10.1.2.1"), 80);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/random-variable.cc Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,574 @@
+/* -*- 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: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+#include <iostream>
+
+#include <math.h>
+#include <stdlib.h>
+#include <sys/time.h> // for gettimeofday
+#include <unistd.h>
+#include <iostream>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+#include "random-variable.h"
+#include "rng-stream.h"
+#include "fatal-error.h"
+
+using namespace std;
+
+namespace ns3{
+// Seed methods
+
+Seed::~Seed()
+{
+}
+
+RandomSeed::RandomSeed()
+{
+}
+
+RandomSeed::~RandomSeed()
+{
+}
+
+bool RandomSeed::IsRandom() const
+{
+ return true;
+}
+
+ConstantSeed::~ConstantSeed()
+{
+}
+
+bool ConstantSeed::IsRandom() const
+{
+ return false;
+}
+
+ConstantSeed::ConstantSeed(uint32_t s)
+{
+ seeds[0] = s;
+ seeds[1] = s;
+ seeds[2] = s;
+ seeds[3] = s;
+ seeds[4] = s;
+ seeds[5] = s;
+}
+
+ConstantSeed::ConstantSeed(uint32_t s0, uint32_t s1, uint32_t s2,
+ uint32_t s3, uint32_t s4, uint32_t s5)
+{
+ seeds[0] = s0;
+ seeds[1] = s1;
+ seeds[2] = s2;
+ seeds[3] = s3;
+ seeds[4] = s4;
+ seeds[5] = s5;
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// RandomVariable methods
+
+bool RandomVariable::initialized = false; // True if RngStream seed set
+bool RandomVariable::useDevRandom = false; // True if use /dev/random desired
+bool RandomVariable::globalSeedSet = false; // True if GlobalSeed called
+int RandomVariable::devRandom = -1;
+uint32_t RandomVariable::globalSeed[6];
+unsigned long RandomVariable::heuristic_sequence;
+
+RandomVariable::RandomVariable()
+{
+ m_generator = new RngStream();
+ RandomVariable::Initialize(); // sets the seed for the static object
+ m_generator->InitializeStream();
+}
+
+RandomVariable::~RandomVariable()
+{
+ delete m_generator;
+}
+
+uint32_t RandomVariable::GetIntValue()
+{
+ return (uint32_t)GetValue();
+}
+
+void RandomVariable::UseDevRandom(bool udr)
+{
+ RandomVariable::useDevRandom = udr;
+}
+
+bool RandomVariable::SetSeed(const Seed& s)
+{
+ // Seed this stream with the specified seed
+ if (s.IsRandom())
+ {
+ uint32_t seeds[6];
+ while(true)
+ { // Insure seeds are valid
+ GetRandomSeeds(seeds);
+ if (RngStream::CheckSeed(seeds)) break;
+ }
+ m_generator->SetSeeds(seeds);
+ return true;
+ }
+ // Not random seed, use specified
+ const ConstantSeed& cs = (ConstantSeed&)s;
+ if (!RngStream::CheckSeed(cs.seeds))
+ {
+ cout << "Constant seed failed valid check" << endl;
+ return false; // Seed is not valid
+ }
+ m_generator->SetSeeds(cs.seeds);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// RandomVariable static methods
+void RandomVariable::UseGlobalSeed(const Seed& s)
+{
+ if (RandomVariable::globalSeedSet)
+ {
+ cout << "Random number generator already initialized!" << endl;
+ cout << "Call to RandomVariable::UseGlobalSeed() ignored" << endl;
+ return;
+ }
+ if (s.IsRandom()) return; // Random seed is the default
+ const ConstantSeed& cs = (ConstantSeed&)s;
+ RandomVariable::globalSeed[0] = cs.seeds[0];
+ RandomVariable::globalSeed[1] = cs.seeds[1];
+ RandomVariable::globalSeed[2] = cs.seeds[2];
+ RandomVariable::globalSeed[3] = cs.seeds[3];
+ RandomVariable::globalSeed[4] = cs.seeds[4];
+ RandomVariable::globalSeed[5] = cs.seeds[5];
+ if (!RngStream::CheckSeed(RandomVariable::globalSeed))
+ NS_FATAL_ERROR("Invalid seed");
+
+ RandomVariable::globalSeedSet = true;
+}
+
+void RandomVariable::Initialize()
+{
+ if (RandomVariable::initialized) return; // Already initialized and seeded
+ RandomVariable::initialized = true;
+ if (!RandomVariable::globalSeedSet)
+ { // No global seed, try a random one
+ GetRandomSeeds(globalSeed);
+ }
+ // Seed the RngStream package
+ RngStream::SetPackageSeed(globalSeed);
+}
+
+void RandomVariable::GetRandomSeeds(uint32_t seeds[6])
+{
+ // Check if /dev/random exists
+ if (RandomVariable::useDevRandom && RandomVariable::devRandom < 0)
+ {
+ RandomVariable::devRandom = open("/dev/random", O_RDONLY);
+ }
+ if (RandomVariable::devRandom > 0)
+ { // Use /dev/random
+ while(true)
+ {
+ for (int i = 0; i < 6; ++i)
+ {
+ read(RandomVariable::devRandom, &seeds[i], sizeof(seeds[i]));
+ }
+ if (RngStream::CheckSeed(seeds)) break; // Got a valid one
+ }
+ }
+ else
+ { // Seed from time of day (code borrowed from ns2 random seeding)
+ // Thanks to John Heidemann for this technique
+ while(true)
+ {
+ timeval tv;
+ gettimeofday(&tv, 0);
+ seeds[0] = (tv.tv_sec^tv.tv_usec^(++heuristic_sequence <<8))
+ & 0x7fffffff;
+ gettimeofday(&tv, 0);
+ seeds[1] = (tv.tv_sec^tv.tv_usec^(++heuristic_sequence <<8))
+ & 0x7fffffff;
+ gettimeofday(&tv, 0);
+ seeds[2] = (tv.tv_sec^tv.tv_usec^(++heuristic_sequence <<8))
+ & 0x7fffffff;
+ gettimeofday(&tv, 0);
+ seeds[3] = (tv.tv_sec^tv.tv_usec^(++heuristic_sequence <<8))
+ & 0x7fffffff;
+ gettimeofday(&tv, 0);
+ seeds[4] = (tv.tv_sec^tv.tv_usec^(++heuristic_sequence <<8))
+ & 0x7fffffff;
+ gettimeofday(&tv, 0);
+ seeds[5] = (tv.tv_sec^tv.tv_usec^(++heuristic_sequence <<8))
+ & 0x7fffffff;
+ if (RngStream::CheckSeed(seeds)) break; // Got a valid one
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// UniformVariable methods
+UniformVariable::UniformVariable()
+ : m_min(0), m_max(1.0) { }
+
+UniformVariable::UniformVariable(double s, double l)
+ : m_min(s), m_max(l) { }
+
+UniformVariable::UniformVariable(const UniformVariable& c)
+ : m_min(c.m_min), m_max(c.m_max) { }
+
+double UniformVariable::GetValue()
+{
+ return m_min + m_generator->RandU01() * (m_max - m_min);
+}
+
+RandomVariable* UniformVariable::Copy() const
+{
+ return new UniformVariable(*this);
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// ConstantVariable methods
+ConstantVariable::ConstantVariable()
+ : m_const(0) { }
+
+ConstantVariable::ConstantVariable(double c)
+ : m_const(c) { };
+
+ConstantVariable::ConstantVariable(const ConstantVariable& c)
+ : m_const(c.m_const) { }
+
+void ConstantVariable::NewConstant(double c)
+ { m_const = c;}
+
+double ConstantVariable::GetValue()
+{
+ return m_const;
+}
+
+uint32_t ConstantVariable::GetIntValue()
+{
+ return (uint32_t)m_const;
+}
+
+RandomVariable* ConstantVariable::Copy() const
+{
+ return new ConstantVariable(*this);
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// SequentialVariable methods
+SequentialVariable::SequentialVariable(double f, double l, double i, uint32_t c)
+ : m_min(f), m_max(l), m_increment(ConstantVariable(i).Copy()), m_consecutive(c),
+ m_current(f), m_currentConsecutive(0)
+{
+}
+
+SequentialVariable::SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c)
+ : m_min(f), m_max(l), m_increment(i.Copy()), m_consecutive(c),
+ m_current(f), m_currentConsecutive(0)
+{
+}
+
+SequentialVariable::SequentialVariable(const SequentialVariable& c)
+ : m_min(c.m_min), m_max(c.m_max),
+ m_increment(c.m_increment->Copy()), m_consecutive(c.m_consecutive),
+ m_current(c.m_current), m_currentConsecutive(c.m_currentConsecutive)
+{
+}
+
+double SequentialVariable::GetValue()
+{ // Return a sequential series of values
+ double r = m_current;
+ if (++m_currentConsecutive == m_consecutive)
+ { // Time to advance to next
+ m_currentConsecutive = 0;
+ m_current += m_increment->GetValue();
+ if (m_current >= m_max)
+ m_current = m_min + (m_current - m_max);
+ }
+ return r;
+}
+
+RandomVariable* SequentialVariable::Copy() const
+{
+ return new SequentialVariable(*this);
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// ExponentialVariable methods
+ExponentialVariable::ExponentialVariable()
+ : m_mean(1.0), m_bound(0) { }
+
+ExponentialVariable::ExponentialVariable(double m)
+ : m_mean(m), m_bound(0) { }
+
+ExponentialVariable::ExponentialVariable(double m, double b)
+ : m_mean(m), m_bound(b) { }
+
+ExponentialVariable::ExponentialVariable(const ExponentialVariable& c)
+ : m_mean(c.m_mean), m_bound(c.m_bound) { }
+
+double ExponentialVariable::GetValue()
+{
+ double r = -m_mean*log(m_generator->RandU01());
+ if (m_bound != 0 && r > m_bound) return m_bound;
+ return r;
+}
+
+RandomVariable* ExponentialVariable::Copy() const
+{
+ return new ExponentialVariable(*this);
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// ParetoVariable methods
+ParetoVariable::ParetoVariable()
+ : m_mean(1.0), m_shape(1.5), m_bound(0) { }
+
+ParetoVariable::ParetoVariable(double m)
+ : m_mean(m), m_shape(1.5), m_bound(0) { }
+
+ParetoVariable::ParetoVariable(double m, double s)
+ : m_mean(m), m_shape(s), m_bound(0) { }
+
+ParetoVariable::ParetoVariable(double m, double s, double b)
+ : m_mean(m), m_shape(s), m_bound(b) { }
+
+ParetoVariable::ParetoVariable(const ParetoVariable& c)
+ : m_mean(c.m_mean), m_shape(c.m_shape), m_bound(c.m_bound) { }
+
+double ParetoVariable::GetValue()
+{
+ double scale = m_mean * ( m_shape - 1.0) / m_shape;
+ double r = (scale * ( 1.0 / pow(m_generator->RandU01(), 1.0 / m_shape)));
+ if (m_bound != 0 && r > m_bound) return m_bound;
+ return r;
+}
+
+RandomVariable* ParetoVariable::Copy() const
+{
+ return new ParetoVariable(*this);
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// WeibullVariable methods
+WeibullVariable::WeibullVariable() : m_mean(1.0), m_alpha(1), m_bound(0) { }
+WeibullVariable::WeibullVariable(double m)
+ : m_mean(m), m_alpha(1), m_bound(0) { }
+WeibullVariable::WeibullVariable(double m, double s)
+ : m_mean(m), m_alpha(s), m_bound(0) { }
+WeibullVariable::WeibullVariable(double m, double s, double b)
+ : m_mean(m), m_alpha(s), m_bound(b) { };
+WeibullVariable::WeibullVariable(const WeibullVariable& c)
+ : m_mean(c.m_mean), m_alpha(c.m_alpha), m_bound(c.m_bound) { }
+
+double WeibullVariable::GetValue()
+{
+ double exponent = 1.0 / m_alpha;
+ double r = m_mean * pow( -log(m_generator->RandU01()), exponent);
+ if (m_bound != 0 && r > m_bound) return m_bound;
+ return r;
+}
+
+RandomVariable* WeibullVariable::Copy() const
+{
+ return new WeibullVariable(*this);
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// NormalVariable methods
+NormalVariable::NormalVariable()
+ : m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){}
+
+NormalVariable::NormalVariable(double m, double v, double b)
+ : m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { }
+
+NormalVariable::NormalVariable(const NormalVariable& c)
+ : m_mean(c.m_mean), m_variance(c.m_variance), m_bound(c.m_bound) { }
+
+double NormalVariable::GetValue()
+{
+ if (m_nextValid)
+ { // use previously generated
+ m_nextValid = false;
+ return m_next;
+ }
+ while(1)
+ { // See Simulation Modeling and Analysis p. 466 (Averill Law)
+ // for algorithm
+ double u1 = m_generator->RandU01();
+ double u2 = m_generator->RandU01();;
+ double v1 = 2 * u1 - 1;
+ double v2 = 2 * u2 - 1;
+ double w = v1 * v1 + v2 * v2;
+ if (w <= 1.0)
+ { // Got good pair
+ double y = sqrt((-2 * log(w))/w);
+ m_next = m_mean + v2 * y * sqrt(m_variance);
+ if (fabs(m_next) > m_bound) m_next = m_bound * (m_next)/fabs(m_next);
+ m_nextValid = true;
+ double x1 = m_mean + v1 * y * sqrt(m_variance);
+ if (fabs(x1) > m_bound) x1 = m_bound * (x1)/fabs(x1);
+ return x1;
+ }
+ }
+}
+
+RandomVariable* NormalVariable::Copy() const
+{
+ return new NormalVariable(*this);
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// ValueCDF methods
+ValueCDF::ValueCDF()
+ : value(0.0), cdf(0.0){ }
+ValueCDF::ValueCDF(double v, double c)
+ : value(v), cdf(c) { }
+ValueCDF::ValueCDF(const ValueCDF& c)
+ : value(c.value), cdf(c.cdf) { }
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// EmpiricalVariable methods
+EmpiricalVariable::EmpiricalVariable()
+ : validated(false) { }
+
+EmpiricalVariable::EmpiricalVariable(const EmpiricalVariable& c)
+ : validated(c.validated), emp(c.emp) { }
+
+EmpiricalVariable::~EmpiricalVariable() { }
+
+double EmpiricalVariable::GetValue()
+{ // Return a value from the empirical distribution
+ // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
+ if (emp.size() == 0) return 0.0; // HuH? No empirical data
+ if (!validated) Validate(); // Insure in non-decreasing
+ double r = m_generator->RandU01();
+ if (r <= emp.front().cdf)return emp.front().value; // Less than first
+ if (r >= emp.back().cdf) return emp.back().value; // Greater than last
+ // Binary search
+ std::vector<ValueCDF>::size_type bottom = 0;
+ std::vector<ValueCDF>::size_type top = emp.size() - 1;
+ while(1)
+ {
+ std::vector<ValueCDF>::size_type c = (top + bottom) / 2;
+ if (r >= emp[c].cdf && r < emp[c+1].cdf)
+ { // Found it
+ return Interpolate(emp[c].cdf, emp[c+1].cdf,
+ emp[c].value, emp[c+1].value,
+ r);
+ }
+ // Not here, adjust bounds
+ if (r < emp[c].cdf) top = c - 1;
+ else bottom = c + 1;
+ }
+}
+
+RandomVariable* EmpiricalVariable::Copy() const
+{
+ return new EmpiricalVariable(*this);
+}
+
+void EmpiricalVariable::CDF(double v, double c)
+{ // Add a new empirical datapoint to the empirical cdf
+ // NOTE. These MUST be inserted in non-decreasing order
+ emp.push_back(ValueCDF(v, c));
+}
+
+void EmpiricalVariable::Validate()
+{
+ ValueCDF prior;
+ for (std::vector<ValueCDF>::size_type i = 0; i < emp.size(); ++i)
+ {
+ ValueCDF& current = emp[i];
+ if (current.value < prior.value || current.cdf < prior.cdf)
+ { // Error
+ cout << "Empirical Dist error,"
+ << " current value " << current.value
+ << " prior value " << prior.value
+ << " current cdf " << current.cdf
+ << " prior cdf " << prior.cdf << endl;
+ NS_FATAL_ERROR("Empirical Dist error");
+ }
+ prior = current;
+ }
+ validated = true;
+}
+
+double EmpiricalVariable::Interpolate(double c1, double c2,
+ double v1, double v2, double r)
+{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
+ return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// Integer EmpiricalVariable methods
+IntEmpiricalVariable::IntEmpiricalVariable() { }
+
+uint32_t IntEmpiricalVariable::GetIntValue()
+{
+ return (uint32_t)GetValue();
+}
+
+RandomVariable* IntEmpiricalVariable::Copy() const
+{
+ return new IntEmpiricalVariable(*this);
+}
+
+
+double IntEmpiricalVariable::Interpolate(double c1, double c2,
+ double v1, double v2, double r)
+{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
+ return ceil(v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// DeterministicVariable
+DeterministicVariable::DeterministicVariable(double* d, uint32_t c)
+ : count(c), next(c), data(d)
+{ // Nothing else needed
+}
+
+DeterministicVariable::~DeterministicVariable() { }
+
+double DeterministicVariable::GetValue()
+{
+ if (next == count) next = 0;
+ return data[next++];
+}
+
+RandomVariable* DeterministicVariable::Copy() const
+{
+ return new DeterministicVariable(*this);
+}
+
+}//namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/random-variable.h Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,584 @@
+/* -*- 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: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+#ifndef __random_variable_h__
+#define __random_variable_h__
+
+#include <vector>
+#include <algorithm>
+
+
+#define INFINITE_VALUE 1e307
+namespace ns3{
+
+class RngStream;
+
+/**
+ * \brief Pure virtual base class for RNG seeds
+ */
+class Seed {
+ // Seed is used to seed the random number generator(s)
+ // This is a base class for RandomSeed and ConstantSeed
+public:
+ virtual ~Seed();
+ virtual bool IsRandom() const = 0;
+};
+
+/**
+ * \brief random RNG seeds
+ */
+class RandomSeed : public Seed {
+public:
+ RandomSeed();
+ ~RandomSeed();
+ bool IsRandom() const;
+};
+
+/**
+ * \brief constant RNG seeds
+ */
+class ConstantSeed : public Seed
+{
+public:
+ ConstantSeed(uint32_t); // Use six copies of the specified value
+ ConstantSeed(uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t); // Six seeds
+ bool IsRandom() const;
+ ~ConstantSeed();
+public:
+ uint32_t seeds[6];
+};
+
+/**
+ * \brief The basic RNG for NS-3.
+ *
+ * Note: The underlying random number generation method used
+ * by NS-3 is the RngStream code by Pierre L'Ecuyer at
+ * the University of Montreal.
+ *
+ * NS-3 has a rich set of random number generators.
+ * Class RandomVariable defines the base class functionalty
+ * required for all random number generators. By default, the underlying
+ * generator is seeded with the time of day, and then deterministically
+ * creates a sequence of seeds for each subsequent generator that is created.
+ * The rest of the documentation outlines how to change this behavior.
+ */
+class RandomVariable {
+
+public:
+ /**
+ * \brief Constructor for a random number generator with a random seed.
+ */
+ RandomVariable();
+
+ /**
+ * \brief Destructor for a random number generator with a random seed.
+ */
+ virtual ~RandomVariable();
+
+ /**
+ * \brief Returns a random double from the underlying distribution
+ * \return A floating point random value
+ */
+ virtual double GetValue() = 0;
+
+ /**
+ * \brief Returns a random integer integer from the underlying distribution
+ * \return Integer cast of ::GetValue()
+ */
+ virtual uint32_t GetIntValue();
+
+ /**
+ * \return A copy of this object
+ */
+ virtual RandomVariable* Copy() const = 0;
+
+ /**
+ * \brief Use a private seed and private stream for this generator.
+ *
+ * This function explicitly overrides all other seeding behavior for
+ * this object. For example, even if another seeding method has been
+ * used (either by default or calls to UseDevRandom, UseGlobalSeed, etc.)
+ * a call to SetSeed explicitly re-seeds this generator. Example:
+ * \code
+ * UniformVariable x(0,10);//with no other code, defaults to time of day seed
+ * x.SetSeed(...); //overrides time of day seed
+ * \endcode
+ * \param s Seed to use. Can either be a RandomSeed or ConstantSeed.
+ * \return true if valid seed.
+ */
+ bool SetSeed(const Seed& s);
+
+ /**
+ * \brief Set seeding behavior
+ *
+ * Specify whether the POSIX device /dev/random is to
+ * be used for seeding. When this is used, the underlying
+ * generator is seeded with data from /dev/random instead of
+ * being seeded based upon the time of day. For this to be effective,
+ * it must be called before the creation of the first instance of a
+ * RandomVariable or subclass. Example:
+ * \code
+ * RandomVariable::UseDevRandom();
+ * UniformVariable x(2,3); //these are seeded randomly
+ * ExponentialVariable y(120); //etc
+ * \endcode
+ * \param udr True if /dev/random desired.
+ */
+ static void UseDevRandom(bool udr = true);
+
+ /**
+ * \brief Use the global seed to force precisely reproducible results.
+ * It is often desirable to create a simulation that uses random
+ * numbers, while at the same time is completely reproducible.
+ * Specifying this set of six random seeds initializes the
+ * random number generator with the specified seed.
+ * Once this is set, all generators will produce fixed output
+ * from run to run. This is because each time a new generator is created,
+ * the underlying RngStream deterministically creates a new seed based upon
+ * the old one, hence a "stream" of RNGs. Example:
+ * \code
+ * RandomVariable::UseGlobalSeed(...);
+ * UniformVariable x(2,3); //these will give the same output everytime
+ * ExponentialVariable y(120); //as long as the seed stays the same
+ * \endcode
+ * \param s
+ * \return True if seed is valid.
+ */
+ static void UseGlobalSeed(const Seed& s);
+
+private:
+ static bool initialized; // True if package seed is set
+ static void Initialize(); // Initialize the RNG system
+ static void GetRandomSeeds(uint32_t seeds[6]);
+private:
+ static bool useDevRandom; // True if using /dev/random desired
+ static bool globalSeedSet; // True if global seed has been specified
+ static int devRandom; // File handle for /dev/random
+ static uint32_t globalSeed[6]; // The global seed to use
+protected:
+ static unsigned long heuristic_sequence;
+ RngStream* m_generator; //underlying generator being wrapped
+};
+
+
+/**
+ * \brief The uniform distribution RNG for NS-3.
+ */
+class UniformVariable : public RandomVariable {
+public:
+ /**
+ * Creates a uniform random number generator in the
+ * range [0.0 .. 1.0)
+ */
+ UniformVariable();
+
+ /**
+ * Creates a uniform random number generator with the specified range
+ * \param s Low end of the range
+ * \param l High end of the range
+ */
+ UniformVariable(double s, double l);
+
+ UniformVariable(const UniformVariable& c);
+
+ /**
+ * \return A value between low and high values specified by the constructor
+ */
+ virtual double GetValue();
+ virtual RandomVariable* Copy() const;
+private:
+ double m_min;
+ double m_max;
+};
+
+/**
+ * \brief A random variable that returns a constant
+ * Class ConstantVariable defines a random number generator that
+ * returns the same value every sample.
+ */
+class ConstantVariable : public RandomVariable {
+
+public:
+ /**
+ * \brief Construct a ConstantVariable RNG that returns zero every sample
+ */
+ ConstantVariable();
+
+ /**
+ * Construct a ConstantVariable RNG that returns the specified value
+ * every sample.
+ * \param c Unchanging value for this RNG.
+ */
+ ConstantVariable(double c);
+
+
+ ConstantVariable(const ConstantVariable& c) ;
+
+ /**
+ * \brief Specify a new constant RNG for this generator.
+ * \param c New constant value for this RNG.
+ */
+ void NewConstant(double c);
+
+ /**
+ * \return The constant value specified
+ */
+ virtual double GetValue();
+ virtual uint32_t GetIntValue();
+ virtual RandomVariable* Copy() const;
+private:
+ double m_const;
+};
+
+/**
+ * \brief Return a sequential list of values
+ * Class SequentialVariable defines a random number generator that
+ * returns a sequential sequence. The sequence monotonically
+ * increases for a period, then wraps around to the low value
+ * and begins monotonicaly increasing again.
+ */
+class SequentialVariable : public RandomVariable {
+
+public:
+ /**
+ * \brief Constructor for the SequentialVariable RNG.
+ * The four parameters define the sequence. For example
+ * SequentialVariable(0,5,1,2) creates a RNG that has the sequence
+ * 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0 ...
+ * \param f First value of the sequence.
+ * \param l One more than the last value of the sequence.
+ * \param i Increment between sequence values
+ * \param c Number of times each member of the sequence is repeated
+ */
+ SequentialVariable(double f, double l, double i = 1, uint32_t c = 1);
+
+ /**
+ * \brief Constructor for the SequentialVariable RNG.
+ * Differs from the first only in that the increment parameter is a
+ * random variable
+ * \param f First value of the sequence.
+ * \param l One more than the last value of the sequence.
+ * \param i Reference to a Random variable for the sequence increment
+ * \param c Number of times each member of the sequence is repeated
+ */
+ SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c = 1);
+
+ SequentialVariable(const SequentialVariable& c);
+ /**
+ * \return The next value in the Sequence
+ */
+ virtual double GetValue();
+ virtual RandomVariable* Copy() const;
+private:
+ double m_min;
+ double m_max;
+ RandomVariable* m_increment;
+ uint32_t m_consecutive;
+ double m_current;
+ uint32_t m_currentConsecutive;
+};
+
+/**
+ * \brief Exponentially Distributed random var
+ * ExponentialVariable defines a random variable with an exponential distribution
+ */
+class ExponentialVariable : public RandomVariable {
+public:
+ /**
+ * Constructs an exponential random variable with a mean
+ * value of 1.0.
+ */
+ ExponentialVariable();
+
+ /**
+ * \brief Constructs an exponential random variable with a specified mean
+ * \param m Mean value for the random variable
+ */
+ explicit ExponentialVariable(double m);
+
+ /**
+ * \brief Constructs an exponential random variable with spefified
+ * \brief mean and upper limit.
+ * Since exponential distributions can theoretically return unbounded values,
+ * it is sometimes useful to specify a fixed upper limit. Note however when
+ * the upper limit is specified, the true mean of the distribution is
+ * slightly smaller than the mean value specified.
+ * \param m Mean value of the random variable
+ * \param b Upper bound on returned values
+ */
+ ExponentialVariable(double m, double b);
+
+ ExponentialVariable(const ExponentialVariable& c);
+
+ /**
+ * \return A random value from this exponential distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariable* Copy() const;
+private:
+ double m_mean; // Mean value of RV
+ double m_bound; // Upper bound on value (if non-zero)
+};
+
+/**
+ * \brief ParetoVariable distributed random var
+ */
+class ParetoVariable : public RandomVariable { //
+public:
+ /**
+ * Constructs a pareto random variable with a mean of 1 and a shape
+ * parameter of 1.5
+ */
+ ParetoVariable();
+
+ /**
+ * Constructs a pareto random variable with specified mean and shape
+ * parameter of 1.5
+ * \param m Mean value of the distribution
+ */
+ explicit ParetoVariable(double m);
+
+ /**
+ * Constructs a pareto random variable with the specified mean value and
+ * shape parameter.
+ * \param m Mean value of the distribution
+ * \param s Shape parameter for the distribution
+ */
+ ParetoVariable(double m, double s);
+
+ /**
+ * \brief Constructs a pareto random variable with the specified mean
+ * \brief value, shape (alpha), and upper bound.
+ * Since pareto distributions can theoretically return unbounded values,
+ * it is sometimes useful to specify a fixed upper limit. Note however
+ * when the upper limit is specified, the true mean of the distribution
+ * is slightly smaller than the mean value specified.
+ * \param m Mean value
+ * \param s Shape parameter
+ * \param b Upper limit on returned values
+ */
+ ParetoVariable(double m, double s, double b);
+
+ ParetoVariable(const ParetoVariable& c);
+
+ /**
+ * \return A random value from this Pareto distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariable* Copy() const;
+private:
+ double m_mean; // Mean value of RV
+ double m_shape; // Shape parameter
+ double m_bound; // Upper bound on value (if non-zero)
+};
+
+/**
+ * \brief WeibullVariable distributed random var
+ */
+class WeibullVariable : public RandomVariable {
+public:
+ /**
+ * Constructs a weibull random variable with a mean
+ * value of 1.0 and a shape (alpha) parameter of 1
+ */
+ WeibullVariable();
+
+
+ /**
+ * Constructs a weibull random variable with the specified mean
+ * value and a shape (alpha) parameter of 1.5.
+ * \param m mean value of the distribution
+ */
+ WeibullVariable(double m) ;
+
+ /**
+ * Constructs a weibull random variable with the specified mean
+ * value and a shape (alpha).
+ * \param m Mean value for the distribution.
+ * \param s Shape (alpha) parameter for the distribution.
+ */
+ WeibullVariable(double m, double s);
+
+ /**
+ * \brief Constructs a weibull random variable with the specified mean
+ * \brief value, shape (alpha), and upper bound.
+ * Since WeibullVariable distributions can theoretically return unbounded values,
+ * it is sometimes usefull to specify a fixed upper limit. Note however
+ * that when the upper limit is specified, the true mean of the distribution
+ * is slightly smaller than the mean value specified.
+ * \param m Mean value for the distribution.
+ * \param s Shape (alpha) parameter for the distribution.
+ * \param b Upper limit on returned values
+ */
+ WeibullVariable(double m, double s, double b);
+
+ WeibullVariable(const WeibullVariable& c);
+
+ /**
+ * \return A random value from this Weibull distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariable* Copy() const;
+private:
+ double m_mean; // Mean value of RV
+ double m_alpha; // Shape parameter
+ double m_bound; // Upper bound on value (if non-zero)
+};
+
+/**
+ * Class NormalVariable defines a random variable with a
+ * normal (Gaussian) distribution.
+ */
+class NormalVariable : public RandomVariable { // Normally Distributed random var
+
+public:
+ /**
+ * Constructs an normal random variable with a mean
+ * value of 0 and variance of 1.
+ */
+ NormalVariable();
+
+
+ /**
+ * \brief Construct a normal random variable with specified mean and variance
+ * \param m Mean value
+ * \param v Variance
+ * \param b Bound. The NormalVariable is bounded within +-bound.
+ */
+ NormalVariable(double m, double v, double b = INFINITE_VALUE);
+
+ NormalVariable(const NormalVariable& c);
+
+ /**
+ * \return A value from this normal distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariable* Copy() const;
+private:
+ double m_mean; // Mean value of RV
+ double m_variance; // Mean value of RV
+ double m_bound; // Bound on value (absolute value)
+ bool m_nextValid; // True if next valid
+ double m_next; // The algorithm produces two values at a time
+};
+
+// Value/CDF pair class for Emiprical Distributions
+//Doc:ClassXRef
+class ValueCDF {
+public:
+ ValueCDF();
+ ValueCDF(double v, double c);
+ ValueCDF(const ValueCDF& c);
+ double value;
+ double cdf;
+};
+
+/**
+ * \brief EmpiricalVariable distribution random var
+ * Defines a random variable that has a specified, empirical
+ * distribution. The distribution is specified by a
+ * series of calls the the CDF member function, specifying a
+ * value and the probability that the function value is less than
+ * the specified value. When values are requested,
+ * a uniform random variable is used to select a probabililty,
+ * and the return value is interpreted linerarly between the
+ * two appropriate points in the CDF
+ */
+class EmpiricalVariable : public RandomVariable {
+public:
+ /**
+ * Constructor for the EmpiricalVariable random variables.
+ */
+ explicit EmpiricalVariable();
+
+ virtual ~EmpiricalVariable();
+ EmpiricalVariable(const EmpiricalVariable& c);
+ /**
+ * \return A value from this empirical distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariable* Copy() const;
+ /**
+ * \brief Specifies a point in the empirical distribution
+ * \param v The function value for this point
+ * \param c Probability that the function is less than or equal to v
+ */
+ virtual void CDF(double v, double c); // Value, prob <= Value
+
+private:
+ virtual void Validate(); // Insure non-decreasing emiprical values
+ virtual double Interpolate(double, double, double, double, double);
+ bool validated; // True if non-decreasing validated
+ std::vector<ValueCDF> emp; // Empicical CDF
+};
+
+/**
+ * Defines an empirical distribution where all values are integers.
+ * Indentical to {\tt EmpiricalVariable}, but with slightly different
+ * interpolation between points.
+ */
+class IntEmpiricalVariable : public EmpiricalVariable {
+public:
+
+ IntEmpiricalVariable();
+
+ virtual RandomVariable* Copy() const;
+ /**
+ * \return An integer value from this empirical distribution
+ */
+ virtual uint32_t GetIntValue();
+ virtual double Interpolate(double, double, double, double, double);
+};
+
+/**
+ * Defines a random variable that has a specified, predetermined
+ * sequence. This would be useful when trying to force
+ * the RNG to return a known sequence, perhaps to
+ * compare NS-3 to some other simulator
+ */
+class DeterministicVariable : public RandomVariable {
+
+public:
+ /**
+ * \brief Constructor
+ * Creates a generator that returns successive elements of the d array
+ * on successive calls to ::Value(). Note that the d pointer is copied
+ * for use by the generator (shallow-copy), not its contents, so the
+ * contents of the array d points to have to remain unchanged for the use
+ * of DeterministicVariable to be meaningful.
+ * \param d Pointer to array of random values to return in sequence
+ * \param c Number of values in the array
+ */
+ explicit DeterministicVariable(double* d, uint32_t c);
+
+ virtual ~DeterministicVariable();
+ /**
+ * \return The next value in the deterministic sequence
+ */
+ virtual double GetValue();
+ virtual RandomVariable* Copy() const;
+private:
+ uint32_t count;
+ uint32_t next;
+ double* data;
+};
+
+}//namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/rng-stream.cc Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,468 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (C) 2001 Pierre L'Ecuyer (lecuyer@iro.umontreal.ca)
+//
+// 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
+//
+// Modified for ns-3 by: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+#include <cstdlib>
+#include <iostream>
+#include "rng-stream.h"
+using namespace std;
+
+namespace
+{
+const double m1 = 4294967087.0;
+const double m2 = 4294944443.0;
+const double norm = 1.0 / (m1 + 1.0);
+const double a12 = 1403580.0;
+const double a13n = 810728.0;
+const double a21 = 527612.0;
+const double a23n = 1370589.0;
+const double two17 = 131072.0;
+const double two53 = 9007199254740992.0;
+const double fact = 5.9604644775390625e-8; /* 1 / 2^24 */
+
+// The following are the transition matrices of the two MRG components
+// (in matrix form), raised to the powers -1, 1, 2^76, and 2^127, resp.
+
+const double InvA1[3][3] = { // Inverse of A1p0
+ { 184888585.0, 0.0, 1945170933.0 },
+ { 1.0, 0.0, 0.0 },
+ { 0.0, 1.0, 0.0 }
+ };
+
+const double InvA2[3][3] = { // Inverse of A2p0
+ { 0.0, 360363334.0, 4225571728.0 },
+ { 1.0, 0.0, 0.0 },
+ { 0.0, 1.0, 0.0 }
+ };
+
+const double A1p0[3][3] = {
+ { 0.0, 1.0, 0.0 },
+ { 0.0, 0.0, 1.0 },
+ { -810728.0, 1403580.0, 0.0 }
+ };
+
+const double A2p0[3][3] = {
+ { 0.0, 1.0, 0.0 },
+ { 0.0, 0.0, 1.0 },
+ { -1370589.0, 0.0, 527612.0 }
+ };
+
+const double A1p76[3][3] = {
+ { 82758667.0, 1871391091.0, 4127413238.0 },
+ { 3672831523.0, 69195019.0, 1871391091.0 },
+ { 3672091415.0, 3528743235.0, 69195019.0 }
+ };
+
+const double A2p76[3][3] = {
+ { 1511326704.0, 3759209742.0, 1610795712.0 },
+ { 4292754251.0, 1511326704.0, 3889917532.0 },
+ { 3859662829.0, 4292754251.0, 3708466080.0 }
+ };
+
+const double A1p127[3][3] = {
+ { 2427906178.0, 3580155704.0, 949770784.0 },
+ { 226153695.0, 1230515664.0, 3580155704.0 },
+ { 1988835001.0, 986791581.0, 1230515664.0 }
+ };
+
+const double A2p127[3][3] = {
+ { 1464411153.0, 277697599.0, 1610723613.0 },
+ { 32183930.0, 1464411153.0, 1022607788.0 },
+ { 2824425944.0, 32183930.0, 2093834863.0 }
+ };
+
+
+
+//-------------------------------------------------------------------------
+// Return (a*s + c) MOD m; a, s, c and m must be < 2^35
+//
+double MultModM (double a, double s, double c, double m)
+{
+ double v;
+ int32_t a1;
+
+ v = a * s + c;
+
+ if (v >= two53 || v <= -two53) {
+ a1 = static_cast<int32_t> (a / two17); a -= a1 * two17;
+ v = a1 * s;
+ a1 = static_cast<int32_t> (v / m); v -= a1 * m;
+ v = v * two17 + a * s + c;
+ }
+
+ a1 = static_cast<int32_t> (v / m);
+ /* in case v < 0)*/
+ if ((v -= a1 * m) < 0.0) return v += m; else return v;
+}
+
+
+//-------------------------------------------------------------------------
+// Compute the vector v = A*s MOD m. Assume that -m < s[i] < m.
+// Works also when v = s.
+//
+void MatVecModM (const double A[3][3], const double s[3], double v[3],
+ double m)
+{
+ int i;
+ double x[3]; // Necessary if v = s
+
+ for (i = 0; i < 3; ++i) {
+ x[i] = MultModM (A[i][0], s[0], 0.0, m);
+ x[i] = MultModM (A[i][1], s[1], x[i], m);
+ x[i] = MultModM (A[i][2], s[2], x[i], m);
+ }
+ for (i = 0; i < 3; ++i)
+ v[i] = x[i];
+}
+
+
+//-------------------------------------------------------------------------
+// Compute the matrix C = A*B MOD m. Assume that -m < s[i] < m.
+// Note: works also if A = C or B = C or A = B = C.
+//
+void MatMatModM (const double A[3][3], const double B[3][3],
+ double C[3][3], double m)
+{
+ int i, j;
+ double V[3], W[3][3];
+
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 3; ++j)
+ V[j] = B[j][i];
+ MatVecModM (A, V, V, m);
+ for (j = 0; j < 3; ++j)
+ W[j][i] = V[j];
+ }
+ for (i = 0; i < 3; ++i)
+ for (j = 0; j < 3; ++j)
+ C[i][j] = W[i][j];
+}
+
+
+//-------------------------------------------------------------------------
+// Compute the matrix B = (A^(2^e) Mod m); works also if A = B.
+//
+void MatTwoPowModM (const double A[3][3], double B[3][3], double m, int32_t e)
+{
+ int i, j;
+
+ /* initialize: B = A */
+ if (A != B) {
+ for (i = 0; i < 3; ++i)
+ for (j = 0; j < 3; ++j)
+ B[i][j] = A[i][j];
+ }
+ /* Compute B = A^(2^e) mod m */
+ for (i = 0; i < e; i++)
+ MatMatModM (B, B, B, m);
+}
+
+
+//-------------------------------------------------------------------------
+// Compute the matrix B = (A^n Mod m); works even if A = B.
+//
+void MatPowModM (const double A[3][3], double B[3][3], double m, int32_t n)
+{
+ int i, j;
+ double W[3][3];
+
+ /* initialize: W = A; B = I */
+ for (i = 0; i < 3; ++i)
+ for (j = 0; j < 3; ++j) {
+ W[i][j] = A[i][j];
+ B[i][j] = 0.0;
+ }
+ for (j = 0; j < 3; ++j)
+ B[j][j] = 1.0;
+
+ /* Compute B = A^n mod m using the binary decomposition of n */
+ while (n > 0) {
+ if (n % 2) MatMatModM (W, B, B, m);
+ MatMatModM (W, W, W, m);
+ n /= 2;
+ }
+}
+
+
+
+} // end of anonymous namespace
+
+
+namespace ns3{
+//-------------------------------------------------------------------------
+// Generate the next random number.
+//
+double RngStream::U01 ()
+{
+ int32_t k;
+ double p1, p2, u;
+
+ /* Component 1 */
+ p1 = a12 * Cg[1] - a13n * Cg[0];
+ k = static_cast<int32_t> (p1 / m1);
+ p1 -= k * m1;
+ if (p1 < 0.0) p1 += m1;
+ Cg[0] = Cg[1]; Cg[1] = Cg[2]; Cg[2] = p1;
+
+ /* Component 2 */
+ p2 = a21 * Cg[5] - a23n * Cg[3];
+ k = static_cast<int32_t> (p2 / m2);
+ p2 -= k * m2;
+ if (p2 < 0.0) p2 += m2;
+ Cg[3] = Cg[4]; Cg[4] = Cg[5]; Cg[5] = p2;
+
+ /* Combination */
+ u = ((p1 > p2) ? (p1 - p2) * norm : (p1 - p2 + m1) * norm);
+
+ return (anti == false) ? u : (1 - u);
+}
+
+
+//-------------------------------------------------------------------------
+// Generate the next random number with extended (53 bits) precision.
+//
+double RngStream::U01d ()
+{
+ double u;
+ u = U01();
+ if (anti) {
+ // Don't forget that U01() returns 1 - u in the antithetic case
+ u += (U01() - 1.0) * fact;
+ return (u < 0.0) ? u + 1.0 : u;
+ } else {
+ u += U01() * fact;
+ return (u < 1.0) ? u : (u - 1.0);
+ }
+}
+
+//-------------------------------------------------------------------------
+// Check that the seeds are legitimate values. Returns true if legal seeds,
+// false otherwise.
+//
+bool RngStream::CheckSeed (const uint32_t seed[6])
+{
+ int i;
+
+ for (i = 0; i < 3; ++i) {
+ if (seed[i] >= m1) {
+ cerr << "****************************************\n\n"
+ << "ERROR: Seed[" << i << "] >= 4294967087, Seed is not set."
+ << "\n\n****************************************\n\n";
+ return (false);
+ }
+ }
+ for (i = 3; i < 6; ++i) {
+ if (seed[i] >= m2) {
+ cout << "Seed[" << i << "] = " << seed[i] << endl;
+ cerr << "*****************************************\n\n"
+ << "ERROR: Seed[" << i << "] >= 4294944443, Seed is not set."
+ << "\n\n*****************************************\n\n";
+ return (false);
+ }
+ }
+ if (seed[0] == 0 && seed[1] == 0 && seed[2] == 0) {
+ cerr << "****************************\n\n"
+ << "ERROR: First 3 seeds = 0.\n\n"
+ << "****************************\n\n";
+ return (false);
+ }
+ if (seed[3] == 0 && seed[4] == 0 && seed[5] == 0) {
+ cerr << "****************************\n\n"
+ << "ERROR: Last 3 seeds = 0.\n\n"
+ << "****************************\n\n";
+ return (false);
+ }
+ return true;
+}
+
+
+
+//*************************************************************************
+// Public members of the class start here
+
+
+//-------------------------------------------------------------------------
+// The default seed of the package; will be the seed of the first
+// declared RngStream, unless SetPackageSeed is called.
+//
+double RngStream::nextSeed[6] =
+{
+ 12345.0, 12345.0, 12345.0, 12345.0, 12345.0, 12345.0
+};
+
+//-------------------------------------------------------------------------
+// constructor
+//
+RngStream::RngStream ()
+{
+ anti = false;
+ incPrec = false;
+ // Stream initialization moved to separate method.
+}
+
+void RngStream::InitializeStream()
+{ // Moved from the RngStream constructor above to allow seeding
+ // AFTER the global package seed has been set in the Random
+ // object constructor.
+ /* Information on a stream. The arrays {Cg, Bg, Ig} contain the current
+ state of the stream, the starting state of the current SubStream, and the
+ starting state of the stream. This stream generates antithetic variates
+ if anti = true. It also generates numbers with extended precision (53
+ bits if machine follows IEEE 754 standard) if incPrec = true. nextSeed
+ will be the seed of the next declared RngStream. */
+
+ for (int i = 0; i < 6; ++i) {
+ Bg[i] = Cg[i] = Ig[i] = nextSeed[i];
+ }
+
+ MatVecModM (A1p127, nextSeed, nextSeed, m1);
+ MatVecModM (A2p127, &nextSeed[3], &nextSeed[3], m2);
+}
+
+//-------------------------------------------------------------------------
+// Reset Stream to beginning of Stream.
+//
+void RngStream::ResetStartStream ()
+{
+ for (int i = 0; i < 6; ++i)
+ Cg[i] = Bg[i] = Ig[i];
+}
+
+
+//-------------------------------------------------------------------------
+// Reset Stream to beginning of SubStream.
+//
+void RngStream::ResetStartSubstream ()
+{
+ for (int i = 0; i < 6; ++i)
+ Cg[i] = Bg[i];
+}
+
+
+//-------------------------------------------------------------------------
+// Reset Stream to NextSubStream.
+//
+void RngStream::ResetNextSubstream ()
+{
+ MatVecModM(A1p76, Bg, Bg, m1);
+ MatVecModM(A2p76, &Bg[3], &Bg[3], m2);
+ for (int i = 0; i < 6; ++i)
+ Cg[i] = Bg[i];
+}
+
+
+//-------------------------------------------------------------------------
+bool RngStream::SetPackageSeed (const uint32_t seed[6])
+{
+ if (!CheckSeed (seed)) return false;
+ for (int i = 0; i < 6; ++i)
+ nextSeed[i] = seed[i];
+ return true;
+}
+
+
+//-------------------------------------------------------------------------
+bool RngStream::SetSeeds (const uint32_t seed[6])
+{
+ if (!CheckSeed (seed)) return false;
+ for (int i = 0; i < 6; ++i)
+ Cg[i] = Bg[i] = Ig[i] = seed[i];
+ return true;
+}
+
+
+//-------------------------------------------------------------------------
+// if e > 0, let n = 2^e + c;
+// if e < 0, let n = -2^(-e) + c;
+// if e = 0, let n = c.
+// Jump n steps forward if n > 0, backwards if n < 0.
+//
+void RngStream::AdvanceState (int32_t e, int32_t c)
+{
+ double B1[3][3], C1[3][3], B2[3][3], C2[3][3];
+
+ if (e > 0) {
+ MatTwoPowModM (A1p0, B1, m1, e);
+ MatTwoPowModM (A2p0, B2, m2, e);
+ } else if (e < 0) {
+ MatTwoPowModM (InvA1, B1, m1, -e);
+ MatTwoPowModM (InvA2, B2, m2, -e);
+ }
+
+ if (c >= 0) {
+ MatPowModM (A1p0, C1, m1, c);
+ MatPowModM (A2p0, C2, m2, c);
+ } else {
+ MatPowModM (InvA1, C1, m1, -c);
+ MatPowModM (InvA2, C2, m2, -c);
+ }
+
+ if (e) {
+ MatMatModM (B1, C1, C1, m1);
+ MatMatModM (B2, C2, C2, m2);
+ }
+
+ MatVecModM (C1, Cg, Cg, m1);
+ MatVecModM (C2, &Cg[3], &Cg[3], m2);
+}
+
+
+//-------------------------------------------------------------------------
+void RngStream::GetState (uint32_t seed[6]) const
+{
+ for (int i = 0; i < 6; ++i)
+ seed[i] = static_cast<uint32_t> (Cg[i]);
+}
+
+
+//-------------------------------------------------------------------------
+void RngStream::IncreasedPrecis (bool incp)
+{
+ incPrec = incp;
+}
+
+
+//-------------------------------------------------------------------------
+void RngStream::SetAntithetic (bool a)
+{
+ anti = a;
+}
+
+
+//-------------------------------------------------------------------------
+// Generate the next random number.
+//
+double RngStream::RandU01 ()
+{
+ if (incPrec)
+ return U01d();
+ else
+ return U01();
+}
+
+
+//-------------------------------------------------------------------------
+// Generate the next random integer.
+//
+int32_t RngStream::RandInt (int32_t low, int32_t high)
+{
+ return low + static_cast<int32_t> ((high - low + 1) * RandU01 ());
+};
+
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/rng-stream.h Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,60 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (C) 2001 Pierre L'Ecuyer (lecuyer@iro.umontreal.ca)
+//
+// 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
+//
+// Modified for ns-3 by: Rajib Bhattacharjea<raj.b@gatech.edu>
+
+#ifndef RNGSTREAM_H
+#define RNGSTREAM_H
+#include <string>
+
+namespace ns3{
+
+/**
+ * \brief RngStream by Pierre L'Ecuyer, University of Montreal
+ * Adapted to NS3 by Rajib Bhattacharjea, Georgia Tech.
+ */
+class RngStream {
+public: //public api
+ RngStream ();
+ void InitializeStream(); // Separate initialization
+ void ResetStartStream ();
+ void ResetStartSubstream ();
+ void ResetNextSubstream ();
+ void SetAntithetic (bool a);
+ void IncreasedPrecis (bool incp);
+ bool SetSeeds (const uint32_t seed[6]);
+ void AdvanceState (int32_t e, int32_t c);
+ void GetState (uint32_t seed[6]) const;
+ double RandU01 ();
+ int32_t RandInt (int32_t i, int32_t j);
+public: //public static api
+ static bool SetPackageSeed (const uint32_t seed[6]);
+ static bool CheckSeed(const uint32_t seed[6]);
+private: //members
+ double Cg[6], Bg[6], Ig[6];
+ bool anti, incPrec;
+ double U01 ();
+ double U01d ();
+private: //static data
+ static double nextSeed[6];
+};
+
+};//namespace ns3
+
+#endif
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/application.cc Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,173 @@
+/* -*- 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>
+ */
+
+// Implementation for ns3 Application base class.
+// George F. Riley, Georgia Tech, Fall 2006
+
+#include "application.h"
+#include "node.h"
+#include "node-reference.h"
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+#include "ns3/simulator.h"
+
+using namespace std;
+
+namespace ns3 {
+
+#define nil 0
+
+// Application Methods
+
+// \brief Application Constructor
+ Application::Application() : m_node(nil), m_startVar(nil), m_stopVar(nil),
+ m_start(false), m_stop(false)
+{
+}
+
+Application::Application(const Application& o)
+ : m_node(nil), m_startVar(nil), m_stopVar(nil),
+ m_start(false), m_stop(false)
+{ // Copy constructor
+ if (o.GetNode())m_node = new NodeReference(*o.GetNode());
+ // Copy the start and stop random variables if they exist
+ if (o.m_startVar) m_startVar = o.m_startVar->Copy();
+ if (o.m_stopVar) m_stopVar = o.m_stopVar->Copy();
+ if (o.m_start) ScheduleStart();
+ if (o.m_stop) ScheduleStop();
+}
+
+
+// \brief Application Destructor
+Application::~Application()
+{
+ delete m_node;
+ // Cancel the start/stop events if scheduled
+ if (m_start) Simulator::Cancel(m_startEvent);
+ if (m_stop) Simulator::Cancel(m_stopEvent);
+ // Delete the random variablse
+ delete m_startVar;
+ delete m_stopVar;
+}
+
+Application& Application::operator=(const Application& rhs)
+{
+ if (this == &rhs) return *this; // Self assignment
+ delete m_node;
+ m_node = nil;
+ if (rhs.GetNode())m_node = new NodeReference(*rhs.GetNode());
+
+ delete m_startVar;
+ m_startVar = nil;
+ if (rhs.m_startVar) m_startVar = rhs.m_startVar->Copy();
+
+ delete m_stopVar;
+ m_stopVar = nil;
+ if (rhs.m_stopVar) m_stopVar = rhs.m_stopVar->Copy();
+
+ m_start = false;
+ if (rhs.m_start) ScheduleStart();
+ if (rhs.m_stop) ScheduleStop();
+ return *this;
+}
+
+
+// \brief Specify application start time
+// The virtual method STartApp will be called at the time
+// specified by startTime.
+// \param Time to start application (absolute time, from start of simulation)
+void Application::Start(const Time& startTime)
+{
+ delete m_startVar;
+ m_startVar = new ConstantVariable(startTime.GetSeconds());
+ ScheduleStart();
+}
+
+void Application::Start(const RandomVariable& startVar)
+{ // Start at random time
+ delete m_startVar;
+ m_startVar = startVar.Copy();
+ ScheduleStart();
+}
+
+
+// \brief Specify application stop time
+// The virtual method StopApp will be called at the time
+// specified by stopTime.
+// \param Time to stop application (absolute time, from start of simulation)
+void Application::Stop(const Time& stopTime)
+{
+ delete m_stopVar;
+ m_stopVar = new ConstantVariable(stopTime.GetSeconds());
+ ScheduleStop();
+}
+
+void Application::Stop(const RandomVariable& stopVar)
+{ // Stop at random time
+ delete m_stopVar;
+ m_stopVar = stopVar.Copy();
+ ScheduleStop();
+}
+
+// \brief Assign this application to a given node
+// Called by the application manager capability when adding
+// an application to a node.
+void Application::SetNode(const Node& n)
+{
+ delete m_node;
+ m_node = new NodeReference(n);
+}
+
+Node* Application::GetNode() const
+{
+ return m_node->GetNode();
+}
+
+// Protected methods
+// StartApp and StopApp will likely be overridden by application subclasses
+void Application::StartApplication()
+{ // Provide null functionality in case subclass is not interested
+}
+
+void Application::StopApplication()
+{ // Provide null functionality in case subclass is not interested
+}
+
+
+// Private helpers
+void Application::ScheduleStart()
+{
+ m_startEvent = Simulator::Schedule(Seconds(m_startVar->GetValue()) -
+ Simulator::Now(),
+ &Application::StartApplication, this);
+ m_start = true;
+}
+
+void Application::ScheduleStop()
+{
+ m_stopEvent = Simulator::Schedule(Seconds(m_stopVar->GetValue()) -
+ Simulator::Now(),
+ &Application::StopApplication, this);
+ m_stop = true;
+}
+
+} //namespace ns3
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/application.h Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,136 @@
+/* -*- 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>
+ */
+
+#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"
+
+namespace ns3 {
+
+class Node;
+class NodeReference;
+class RandomVariable;
+
+class Application {
+public:
+ Application();
+ Application(const Application&); // Copy constructor
+ Application& operator=(const Application&); // Assignment operator
+ virtual ~Application();
+
+ virtual Application* Copy() const = 0; // All applications must provide
+
+ // \brief Specify application start time
+ // Applications start at various times in the simulation scenario.
+ // The Start method specifies when the application should be
+ // started. The application subclasses should override the
+ // private "StartApplication" method defined below, which is called at the
+ // time specified, to cause the application to begin.
+ // \param Start time for this application, relative to the
+ // current simulation time.
+ void Start(const Time&);
+
+ // \brief Same as above, but uses a random variable for start time
+ // The random variable returns the desired start time in units of
+ // Seconds.
+
+void Start(const RandomVariable&);
+
+ // \brief Specify application stop time
+ // Once an application has started, it is sometimes useful
+ // to stop the application. The Stop method specifies when an
+ // application is to stop. The application subclasses should override
+ // the private StopApplication method defined below, to cause the application
+ // to stop.
+ // \param Stop time for this application, relative to the
+ // current simulation time.
+ void Stop(const Time&);
+
+ // \brief Same as above, but uses a random variable for stop time
+ // The random variable returns the desired stop time in units of
+ // Seconds.
+ void Stop(const RandomVariable&);
+
+ // \brief Attaches an application to a specific node
+ // Specifies which node object this application is associated with.
+ // \param Node object to associate with this application.
+ void SetNode(const Node&);
+
+ // \brief Returns the pointer to the attached node.
+ Node* GetNode() const;
+
+ // Members
+ NodeReference* m_node; // All applications have an associated node
+ RandomVariable* m_startVar; // Random variable for start time
+ RandomVariable* m_stopVar; // Random variable for stop time
+ EventId m_startEvent;// Event identifier for start event
+ EventId m_stopEvent; // Event identifier for the stop event
+ bool m_start; // True if start event scheduled
+ bool m_stop; // True if stop event scheduled
+
+protected:
+ // \brief Application specific startup code
+ // The StartApplication method is called at the start time specifed by Start
+ // This method should be overridden by all or most application
+ // subclasses.
+ virtual void StartApplication();
+
+ // \brief Application specific shutdown code
+ // The StopApplication method is called at the stop time specifed by Stop
+ // This method should be overridden by all or most application
+ // subclasses.
+ virtual void StopApplication();
+
+private:
+ // Helpers
+ void ScheduleStart();
+ void ScheduleStop();
+};
+
+} //namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/datagram-socket.cc Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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 "datagram-socket.h"
+#include "udp.h"
+#include "udp-end-point.h"
+#include "node.h"
+#include "ipv4-l4-demux.h"
+
+namespace ns3 {
+
+DatagramSocket::DatagramSocket (Node *node)
+ : m_endPoint (0),
+ m_node (node)
+{
+ NS_ASSERT (GetUdp () != 0);
+}
+DatagramSocket::~DatagramSocket ()
+{
+ delete m_endPoint;
+}
+
+int
+DatagramSocket::Bind (void)
+{
+ m_endPoint = GetUdp ()->Allocate ();
+ if (m_endPoint == 0)
+ {
+ return -1;
+ }
+ m_endPoint->SetSocket (this);
+ return 0;
+}
+int
+DatagramSocket::Bind (Ipv4Address address)
+{
+ m_endPoint = GetUdp ()->Allocate (address);
+ if (m_endPoint == 0)
+ {
+ return -1;
+ }
+ m_endPoint->SetSocket (this);
+ return 0;
+}
+int
+DatagramSocket::Bind (uint16_t port)
+{
+ m_endPoint = GetUdp ()->Allocate (port);
+ if (m_endPoint == 0)
+ {
+ return -1;
+ }
+ m_endPoint->SetSocket (this);
+ return 0;
+}
+int
+DatagramSocket::Bind (Ipv4Address address, uint16_t port)
+{
+ m_endPoint = GetUdp ()->Allocate (address, port);
+ if (m_endPoint == 0)
+ {
+ return -1;
+ }
+ m_endPoint->SetSocket (this);
+ return 0;
+}
+
+void
+DatagramSocket::SetDefaultDestination (Ipv4Address daddr, uint16_t dport)
+{
+ m_defaultAddress = daddr;
+ m_defaultPort = dport;
+}
+void
+DatagramSocket::SendDummy (uint32_t size)
+{
+ SendDummyTo (size, m_defaultAddress, m_defaultPort);
+}
+void
+DatagramSocket::SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport)
+{
+ if (m_endPoint == 0)
+ {
+ Bind ();
+ if (m_endPoint == 0)
+ {
+ return;
+ }
+ }
+ Packet p = Packet (size);
+ GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr,
+ m_endPoint->GetLocalPort (), dport);
+}
+
+void
+DatagramSocket::Send (uint8_t const*buffer, uint32_t size)
+{
+ SendTo (buffer, size, m_defaultAddress, m_defaultPort);
+}
+void
+DatagramSocket::SendTo (uint8_t const*buffer, uint32_t size,
+ Ipv4Address daddr, uint16_t dport)
+{
+ if (m_endPoint == 0)
+ {
+ Bind ();
+ if (m_endPoint == 0)
+ {
+ return;
+ }
+ }
+ Packet p = Packet (buffer, size);
+ GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr,
+ m_endPoint->GetLocalPort (), dport);
+}
+void
+DatagramSocket::SetDummyRxCallback (Callback<void,DatagramSocket*,
+ uint32_t,
+ Ipv4Address,uint16_t> cb)
+{
+ m_dummyRxCallback = cb;
+}
+void
+DatagramSocket::SetRxCallback (Callback<void,DatagramSocket*,
+ uint8_t const*,uint32_t,
+ Ipv4Address,uint16_t> cb)
+{
+ m_rxCallback = cb;
+}
+
+void
+DatagramSocket::ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport)
+{
+ if (!m_dummyRxCallback.IsNull ())
+ {
+ m_dummyRxCallback (this, p.GetSize (), saddr, sport);
+ }
+ if (!m_rxCallback.IsNull ())
+ {
+ m_rxCallback (this, p.PeekData (), p.GetSize (), saddr, sport);
+ }
+}
+
+Udp *
+DatagramSocket::GetUdp (void) const
+{
+ return m_node->GetUdp ();
+}
+
+Node *
+DatagramSocket::GetNode (void) const
+{
+ return m_node;
+}
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/datagram-socket.h Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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>
+ */
+#ifndef UDP_SOCKET_H
+#define UDP_SOCKET_H
+
+#include <stdint.h>
+#include "ns3/callback.h"
+#include "ipv4-address.h"
+
+namespace ns3 {
+
+class UdpEndPoint;
+class Node;
+class Packet;
+class Udp;
+
+/**
+ * Before any data is sent, the socket must be bound with
+ * one of the Bind methods.
+ * If none of these Bind methods are called prior to
+ * one of the ::Send methods, the socket is implicitely
+ * bound to a random port and to all interfaces.
+ */
+class DatagramSocket
+{
+public:
+ /**
+ * Create an unbound udp socket.
+ */
+ DatagramSocket (Node *node);
+ ~DatagramSocket ();
+
+ /**
+ * Allocate a free port number and
+ * bind this socket to this port number on all
+ * interfaces of this system.
+ *
+ * return 0 on success, -1 on failure.
+ */
+ int Bind (void);
+ /**
+ * Allocate a free port number and
+ * bind this socket to this port number on the
+ * specified interface.
+ *
+ * return 0 on success, -1 on failure.
+ */
+ int Bind (Ipv4Address address);
+
+ /**
+ * Bind this socket to this port number
+ * on all interfaces of this system.
+ *
+ * return 0 on success, -1 on failure.
+ */
+ int Bind (uint16_t port);
+
+ /**
+ * Bind this socket to this port number
+ * on the interface specified by address.
+ *
+ * return 0 on success, -1 on failure.
+ */
+ int Bind (Ipv4Address address, uint16_t port);
+
+
+ /**
+ * Set the default destination address and port
+ * number for all packets outgoing from this socket.
+ */
+ void SetDefaultDestination (Ipv4Address daddr, uint16_t dport);
+
+ /**
+ * Send dummy data to default destination
+ */
+ void SendDummy (uint32_t size);
+ /**
+ * Send dummy data to specified destination
+ */
+ void SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport);
+
+ void Send (uint8_t const*buffer, uint32_t size);
+ void SendTo (uint8_t const*buffer, uint32_t size,
+ Ipv4Address daddr, uint16_t dport);
+
+ /**
+ * When a packet is received by this socket, it invokes the "dummy callback" which
+ * forwards to the application the number of bytes received and from who they
+ * were received.
+ */
+ void SetDummyRxCallback (Callback<void,DatagramSocket*,uint32_t,Ipv4Address,uint16_t> cb);
+ /**
+ * When a packet is received by this socket, it invokes the "normal callback" which
+ * forwards to the application the buffer of bytes received and from who they
+ * were received. The application is responsible for copying that buffer if it wants
+ * to keep track of it.
+ */
+ void SetRxCallback (Callback<void,DatagramSocket*,uint8_t const*,uint32_t,Ipv4Address,uint16_t> cb);
+ /**
+ * Return pointer to node
+ */
+ Node* GetNode(void) const;
+
+private:
+ friend class Udp;
+ // invoked by Udp class
+ void ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport);
+ Udp *GetUdp (void) const;
+
+ UdpEndPoint *m_endPoint;
+ Node *m_node;
+ Ipv4Address m_defaultAddress;
+ uint16_t m_defaultPort;
+ Callback<void,DatagramSocket*,uint32_t,Ipv4Address,uint16_t> m_dummyRxCallback;
+ Callback<void,DatagramSocket*,uint8_t const*,uint32_t,Ipv4Address,uint16_t> m_rxCallback;
+};
+
+}//namespace ns3
+
+#endif /* UDP_SOCKET_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/node-reference.h Sun Mar 18 14:30:26 2007 -0700
@@ -0,0 +1,45 @@
+/* -*- 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>
+//
+
+// Define a class that wraps a node pointer. This allows numerous ns3
+// objects to have access to a node, but without ambiguity of whether
+// the owner should "delete" it.
+
+// George F. Riley, Georgia Tech, Spring 2007
+
+#ifndef __NODE_REFERENCE_H__
+#define __NODE_REFERENCE_H__
+
+namespace ns3 {
+
+class Node;
+
+class NodeReference {
+public:
+ NodeReference(const Node& n)
+ : m_node(n) {}
+ Node* GetNode() const { return (Node*)&m_node;}
+public:
+ const Node& m_node;
+};
+
+} // namespace ns3
+
+#endif
--- a/src/node/udp-end-point.cc Sun Mar 18 14:06:51 2007 -0700
+++ b/src/node/udp-end-point.cc Sun Mar 18 14:30:26 2007 -0700
@@ -28,11 +28,11 @@
{}
void
-UdpEndPoint::SetSocket (UdpSocket *socket)
+UdpEndPoint::SetSocket (DatagramSocket *socket)
{
m_socket = socket;
}
-UdpSocket *
+DatagramSocket *
UdpEndPoint::GetSocket (void) const
{
return m_socket;
--- a/src/node/udp-end-point.h Sun Mar 18 14:06:51 2007 -0700
+++ b/src/node/udp-end-point.h Sun Mar 18 14:30:26 2007 -0700
@@ -27,17 +27,17 @@
namespace ns3 {
-class UdpSocket;
+class DatagramSocket;
class UdpEndPoint : public Ipv4EndPoint
{
public:
UdpEndPoint (Ipv4Address address, uint16_t port);
- void SetSocket (UdpSocket *socket);
- UdpSocket *GetSocket (void) const;
+ void SetSocket (DatagramSocket *socket);
+ DatagramSocket *GetSocket (void) const;
private:
- UdpSocket *m_socket;
+ DatagramSocket *m_socket;
};
}//namespace ns3
--- a/src/node/udp-socket.cc Sun Mar 18 14:06:51 2007 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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 "udp-socket.h"
-#include "udp.h"
-#include "udp-end-point.h"
-#include "node.h"
-#include "ipv4-l4-demux.h"
-
-namespace ns3 {
-
-UdpSocket::UdpSocket (Node *node)
- : m_endPoint (0),
- m_node (node)
-{
- NS_ASSERT (GetUdp () != 0);
-}
-UdpSocket::~UdpSocket ()
-{
- delete m_endPoint;
-}
-
-int
-UdpSocket::Bind (void)
-{
- m_endPoint = GetUdp ()->Allocate ();
- if (m_endPoint == 0)
- {
- return -1;
- }
- m_endPoint->SetSocket (this);
- return 0;
-}
-int
-UdpSocket::Bind (Ipv4Address address)
-{
- m_endPoint = GetUdp ()->Allocate (address);
- if (m_endPoint == 0)
- {
- return -1;
- }
- m_endPoint->SetSocket (this);
- return 0;
-}
-int
-UdpSocket::Bind (uint16_t port)
-{
- m_endPoint = GetUdp ()->Allocate (port);
- if (m_endPoint == 0)
- {
- return -1;
- }
- m_endPoint->SetSocket (this);
- return 0;
-}
-int
-UdpSocket::Bind (Ipv4Address address, uint16_t port)
-{
- m_endPoint = GetUdp ()->Allocate (address, port);
- if (m_endPoint == 0)
- {
- return -1;
- }
- m_endPoint->SetSocket (this);
- return 0;
-}
-
-void
-UdpSocket::SetDefaultDestination (Ipv4Address daddr, uint16_t dport)
-{
- m_defaultAddress = daddr;
- m_defaultPort = dport;
-}
-void
-UdpSocket::SendDummy (uint32_t size)
-{
- SendDummyTo (size, m_defaultAddress, m_defaultPort);
-}
-void
-UdpSocket::SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport)
-{
- if (m_endPoint == 0)
- {
- Bind ();
- if (m_endPoint == 0)
- {
- return;
- }
- }
- Packet p = Packet (size);
- GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr,
- m_endPoint->GetLocalPort (), dport);
-}
-
-void
-UdpSocket::Send (uint8_t const*buffer, uint32_t size)
-{
- SendTo (buffer, size, m_defaultAddress, m_defaultPort);
-}
-void
-UdpSocket::SendTo (uint8_t const*buffer, uint32_t size,
- Ipv4Address daddr, uint16_t dport)
-{
- if (m_endPoint == 0)
- {
- Bind ();
- if (m_endPoint == 0)
- {
- return;
- }
- }
- Packet p = Packet (buffer, size);
- GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr,
- m_endPoint->GetLocalPort (), dport);
-}
-void
-UdpSocket::SetDummyRxCallback (Callback<void,UdpSocket*,
- uint32_t,
- Ipv4Address,uint16_t> cb)
-{
- m_dummyRxCallback = cb;
-}
-void
-UdpSocket::SetRxCallback (Callback<void,UdpSocket*,
- uint8_t const*,uint32_t,
- Ipv4Address,uint16_t> cb)
-{
- m_rxCallback = cb;
-}
-
-void
-UdpSocket::ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport)
-{
- if (!m_dummyRxCallback.IsNull ())
- {
- m_dummyRxCallback (this, p.GetSize (), saddr, sport);
- }
- if (!m_rxCallback.IsNull ())
- {
- m_rxCallback (this, p.PeekData (), p.GetSize (), saddr, sport);
- }
-}
-
-Udp *
-UdpSocket::GetUdp (void) const
-{
- return m_node->GetUdp ();
-}
-
-Node *
-UdpSocket::GetNode (void) const
-{
- return m_node;
-}
-
-}//namespace ns3
--- a/src/node/udp-socket.h Sun Mar 18 14:06:51 2007 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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>
- */
-#ifndef UDP_SOCKET_H
-#define UDP_SOCKET_H
-
-#include <stdint.h>
-#include "ns3/callback.h"
-#include "ipv4-address.h"
-
-namespace ns3 {
-
-class UdpEndPoint;
-class Node;
-class Packet;
-class Udp;
-
-/**
- * Before any data is sent, the socket must be bound with
- * one of the Bind methods.
- * If none of these Bind methods are called prior to
- * one of the ::Send methods, the socket is implicitely
- * bound to a random port and to all interfaces.
- */
-class UdpSocket
-{
-public:
- /**
- * Create an unbound udp socket.
- */
- UdpSocket (Node *node);
- ~UdpSocket ();
-
- /**
- * Allocate a free port number and
- * bind this socket to this port number on all
- * interfaces of this system.
- *
- * return 0 on success, -1 on failure.
- */
- int Bind (void);
- /**
- * Allocate a free port number and
- * bind this socket to this port number on the
- * specified interface.
- *
- * return 0 on success, -1 on failure.
- */
- int Bind (Ipv4Address address);
-
- /**
- * Bind this socket to this port number
- * on all interfaces of this system.
- *
- * return 0 on success, -1 on failure.
- */
- int Bind (uint16_t port);
-
- /**
- * Bind this socket to this port number
- * on the interface specified by address.
- *
- * return 0 on success, -1 on failure.
- */
- int Bind (Ipv4Address address, uint16_t port);
-
-
- /**
- * Set the default destination address and port
- * number for all packets outgoing from this socket.
- */
- void SetDefaultDestination (Ipv4Address daddr, uint16_t dport);
-
- /**
- * Send dummy data to default destination
- */
- void SendDummy (uint32_t size);
- /**
- * Send dummy data to specified destination
- */
- void SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport);
-
- void Send (uint8_t const*buffer, uint32_t size);
- void SendTo (uint8_t const*buffer, uint32_t size,
- Ipv4Address daddr, uint16_t dport);
-
- /**
- * When a packet is received by this socket, it invokes the "dummy callback" which
- * forwards to the application the number of bytes received and from who they
- * were received.
- */
- void SetDummyRxCallback (Callback<void,UdpSocket*,uint32_t,Ipv4Address,uint16_t> cb);
- /**
- * When a packet is received by this socket, it invokes the "normal callback" which
- * forwards to the application the buffer of bytes received and from who they
- * were received. The application is responsible for copying that buffer if it wants
- * to keep track of it.
- */
- void SetRxCallback (Callback<void,UdpSocket*,uint8_t const*,uint32_t,Ipv4Address,uint16_t> cb);
- /**
- * Return pointer to node
- */
- Node* GetNode(void) const;
-
-private:
- friend class Udp;
- // invoked by Udp class
- void ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport);
- Udp *GetUdp (void) const;
-
- UdpEndPoint *m_endPoint;
- Node *m_node;
- Ipv4Address m_defaultAddress;
- uint16_t m_defaultPort;
- Callback<void,UdpSocket*,uint32_t,Ipv4Address,uint16_t> m_dummyRxCallback;
- Callback<void,UdpSocket*,uint8_t const*,uint32_t,Ipv4Address,uint16_t> m_rxCallback;
-};
-
-}//namespace ns3
-
-#endif /* UDP_SOCKET_H */
--- a/src/node/udp.cc Sun Mar 18 14:06:51 2007 -0700
+++ b/src/node/udp.cc Sun Mar 18 14:30:26 2007 -0700
@@ -27,7 +27,7 @@
#include "udp-header.h"
#include "ipv4-end-point-demux.h"
#include "udp-end-point.h"
-#include "udp-socket.h"
+#include "datagram-socket.h"
#include "node.h"
#include "ipv4.h"
#include "l3-demux.h"
@@ -102,7 +102,7 @@
{
return;
}
- UdpSocket *socket = endPoint->GetSocket ();
+ DatagramSocket *socket = endPoint->GetSocket ();
socket->ForwardUp (packet, source, udpHeader.GetSource ());
NS_ASSERT (socket != 0);
}