--- a/SConstruct Sun May 13 12:46:18 2007 +0100
+++ b/SConstruct Sun May 13 12:52:38 2007 +0100
@@ -25,12 +25,12 @@
'test.cc',
'random-variable.cc',
'rng-stream.cc',
- 'ns-unknown.cc',
+ 'interface.cc',
'uid-manager.cc',
'default-value.cc',
'command-line.cc',
'type-name.cc',
- 'ns-unknown-manager.cc',
+ 'component-manager.cc',
])
env = Environment()
if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin':
@@ -58,11 +58,11 @@
'test.h',
'random-variable.h',
'rng-stream.h',
- 'ns-unknown.h',
+ 'interface.h',
'default-value.h',
'command-line.h',
'type-name.h',
- 'ns-unknown-manager.h',
+ 'component-manager.h',
])
def config_core (env, config):
@@ -209,6 +209,7 @@
'socket.cc',
'i-udp.cc',
'i-ipv4.cc',
+ 'application.cc',
])
node.add_inst_headers ([
'node.h',
@@ -224,25 +225,22 @@
'socket.h',
'i-udp.h',
'i-ipv4.h',
+ 'application.h',
])
applications = build.Ns3Module ('applications', 'src/applications')
ns3.add (applications)
applications.add_deps (['node'])
applications.add_sources ([
- 'application-list.cc',
- 'application.cc',
'onoff-application.cc',
])
applications.add_inst_headers ([
- 'application-list.h',
- 'application.h',
'onoff-application.h',
])
inode = build.Ns3Module ('internet-node', 'src/internet-node')
ns3.add (inode)
-inode.add_deps (['node', 'applications'])
+inode.add_deps (['node'])
inode.add_sources ([
'internet-node.cc',
'l3-demux.cc',
@@ -418,7 +416,7 @@
example_simple_p2p = build.Ns3Module('simple-p2p', 'examples')
example_simple_p2p.set_executable()
ns3.add(example_simple_p2p)
-example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node'])
+example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications'])
example_simple_p2p.add_source('simple-p2p.cc')
ns3.generate_dependencies()
--- a/examples/simple-p2p.cc Sun May 13 12:46:18 2007 +0100
+++ b/examples/simple-p2p.cc Sun May 13 12:52:38 2007 +0100
@@ -45,6 +45,7 @@
#include "ns3/debug.h"
#include "ns3/command-line.h"
#include "ns3/default-value.h"
+#include "ns3/ptr.h"
#include "ns3/simulator.h"
#include "ns3/nstime.h"
@@ -65,7 +66,6 @@
#include "ns3/trace-root.h"
#include "ns3/p2p-topology.h"
#include "ns3/onoff-application.h"
-#include "ns3/application-list.h"
#include "ns3/random-variable.h"
using namespace ns3;
@@ -100,21 +100,21 @@
// Here, we will explicitly create four nodes. In more sophisticated
// topologies, we could configure a node factory.
- Node* n0 = new InternetNode ();
- Node* n1 = new InternetNode ();
- Node* n2 = new InternetNode ();
- Node* n3 = new InternetNode ();
+ Ptr<Node> n0 = MakeNewObject<InternetNode> ();
+ Ptr<Node> n1 = MakeNewObject<InternetNode> ();
+ Ptr<Node> n2 = MakeNewObject<InternetNode> ();
+ Ptr<Node> n3 = MakeNewObject<InternetNode> ();
// We create the channels first without any IP addressing information
- PointToPointChannel *channel0 =
+ Ptr<PointToPointChannel> channel0 =
PointToPointTopology::AddPointToPointLink (
n0, n2, DataRate(5000000), MilliSeconds(2));
- PointToPointChannel *channel1 =
+ Ptr<PointToPointChannel> channel1 =
PointToPointTopology::AddPointToPointLink (
n1, n2, DataRate(5000000), MilliSeconds(2));
- PointToPointChannel *channel2 =
+ Ptr<PointToPointChannel> channel2 =
PointToPointTopology::AddPointToPointLink (
n2, n3, DataRate(1500000), MilliSeconds(10));
@@ -122,21 +122,27 @@
PointToPointTopology::AddIpv4Addresses (
channel0, n0, Ipv4Address("10.1.1.1"),
n2, Ipv4Address("10.1.1.2"));
- channel0->Unref ();
PointToPointTopology::AddIpv4Addresses (
channel1, n1, Ipv4Address("10.1.2.1"),
n2, Ipv4Address("10.1.2.2"));
- channel1->Unref ();
PointToPointTopology::AddIpv4Addresses (
channel2, n2, Ipv4Address("10.1.3.1"),
n3, Ipv4Address("10.1.3.2"));
- channel2->Unref ();
+
+ // Finally, we add static routes. These three steps (Channel and
+ // NetDevice creation, IP Address assignment, and routing) are
+ // separated because there may be a need to postpone IP Address
+ // assignment (emulation) or modify to use dynamic routing
+ PointToPointTopology::AddIpv4Routes(n0, n2, channel0);
+ PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
+ PointToPointTopology::AddIpv4Routes(n2, n3, channel2);
+
// Create the OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s
- OnOffApplication* ooff0 = new OnOffApplication(
+ Ptr<OnOffApplication> ooff = MakeNewObject<OnOffApplication> (
n0,
Ipv4Address("10.1.3.2"),
80,
@@ -144,19 +150,12 @@
ConstantVariable(0),
DataRate(448000),
210);
- // Add to Node's ApplicationList (takes ownership of pointer)
- ApplicationList *apl0 = n0->QueryInterface<ApplicationList>
- (ApplicationList::iid);
- apl0->Add(ooff0);
- apl0->Unref ();
-
// Start the application
- ooff0->Start(Seconds(1.0));
- ooff0->Stop (Seconds(10.0));
- ooff0->Unref ();
+ ooff->Start(Seconds(1.0));
+ ooff->Stop (Seconds(10.0));
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
- OnOffApplication* ooff1 = new OnOffApplication(
+ ooff = MakeNewObject<OnOffApplication> (
n3,
Ipv4Address("10.1.2.1"),
80,
@@ -164,30 +163,18 @@
ConstantVariable(0),
DataRate(448000),
210);
- // Add to Node's ApplicationList (takes ownership of pointer)
- ApplicationList *apl3 = n3->QueryInterface<ApplicationList> (ApplicationList::iid);
- apl3->Add(ooff1);
- apl3->Unref ();
// Start the application
- ooff1->Start(Seconds(1.1));
- ooff1->Stop (Seconds(10.0));
- ooff1->Unref ();
+ ooff->Start(Seconds(1.1));
+ ooff->Stop (Seconds(10.0));
// Here, finish off packet routing configuration
// This will likely set by some global StaticRouting object in the future
- IIpv4 *ipv4;
+ Ptr<IIpv4> ipv4;
ipv4 = n0->QueryInterface<IIpv4> (IIpv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
- ipv4->Unref ();
ipv4 = n3->QueryInterface<IIpv4> (IIpv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
- ipv4->Unref ();
-
- n0->Unref ();
- n1->Unref ();
- n2->Unref ();
- n3->Unref ();
-
+
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-p2p.tr file
AsciiTrace asciitrace ("simple-p2p.tr");
@@ -196,7 +183,8 @@
// Also configure some tcpdump traces; each interface will be traced
// The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
- // and can be read by the "tcpdump -r" command
+ // and can be read by the "tcpdump -r" command (use "-tt" option to
+ // display timestamps correctly)
PcapTrace pcaptrace ("simple-p2p.pcap");
pcaptrace.TraceAllIp ();
--- a/samples/main-ptr.cc Sun May 13 12:46:18 2007 +0100
+++ b/samples/main-ptr.cc Sun May 13 12:52:38 2007 +0100
@@ -1,10 +1,11 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
#include "ns3/ptr.h"
+#include "ns3/object.h"
#include <iostream>
using namespace ns3;
-class A
+class A : public Object
{
public:
A ();
@@ -48,7 +49,7 @@
{
// Create a new object of type A, store it in global
// variable g_a
- Ptr<A> a = new A ();
+ Ptr<A> a = MakeNewObject<A> ();
a->Method ();
Ptr<A> prev = StoreA (a);
NS_ASSERT (prev == 0);
@@ -57,18 +58,17 @@
{
// Create a new object of type A, store it in global
// variable g_a, get a hold on the previous A object.
- Ptr<A> a = new A ();
+ Ptr<A> a = MakeNewObject<A> ();
Ptr<A> prev = StoreA (a);
// call method on object
prev->Method ();
// Clear the currently-stored object
ClearA ();
- // remove the raw pointer from its smart pointer.
- // we can do this because the refcount is exactly one
- // here
- A *raw = prev.Remove ();
+ // get the raw pointer and release it.
+ A *raw = GetPointer (prev);
+ prev = 0;
raw->Method ();
- delete raw;
+ raw->Unref ();
}
--- a/samples/main-simple.cc Sun May 13 12:46:18 2007 +0100
+++ b/samples/main-simple.cc Sun May 13 12:52:38 2007 +0100
@@ -9,7 +9,7 @@
using namespace ns3;
static void
-GenerateTraffic (Socket *socket, uint32_t size)
+GenerateTraffic (Ptr<Socket> socket, uint32_t size)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl;
socket->Send (0, size);
@@ -24,32 +24,30 @@
}
static void
-SocketPrinter (Socket *socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort)
+SocketPrinter (Ptr<Socket> socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl;
}
static void
-PrintTraffic (Socket *socket)
+PrintTraffic (Ptr<Socket> socket)
{
socket->RecvDummy (MakeCallback (&SocketPrinter));
}
-int main (int argc, char *argv[])
+void
+RunSimulation (void)
{
- InternetNode *a = new InternetNode ();
+ Ptr<InternetNode> a = MakeNewObject<InternetNode> ();
- IUdp *udp;
- udp = a->QueryInterface<IUdp> (IUdp::iid);
+ Ptr<IUdp> udp = a->QueryInterface<IUdp> (IUdp::iid);
- Socket *sink = udp->CreateSocket ();
+ Ptr<Socket> sink = udp->CreateSocket ();
sink->Bind (80);
- Socket *source = udp->CreateSocket ();
+ Ptr<Socket> source = udp->CreateSocket ();
source->Connect (Ipv4Address::GetLoopback (), 80);
- udp->Unref ();
-
GenerateTraffic (source, 500);
PrintTraffic (sink);
@@ -57,10 +55,11 @@
Simulator::Run ();
Simulator::Destroy ();
+}
- sink->Unref ();
- source->Unref ();
- a->Unref ();
+int main (int argc, char *argv[])
+{
+ RunSimulation ();
return 0;
}
--- a/src/applications/application-list.cc Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-// -*- Mode:NS3 -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-// Implement the application list capability for NS3 nodes
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "application.h"
-#include "application-list.h"
-
-namespace ns3{
-
-const Iid ApplicationList::iid ("ApplicationList");
-
-ApplicationList::ApplicationList(Node* n)
- : NsUnknown (ApplicationList::iid)
-{}
-
-void
-ApplicationList::DoDispose (void)
-{
- for (std::vector<Application*>::const_iterator i = m_apps.begin();
- i != m_apps.end(); ++i)
- {
- Application *app = *i;
- app->Dispose ();
- app->Unref ();
- }
- m_apps.clear ();
- NsUnknown::DoDispose ();
-}
-
-ApplicationList::~ApplicationList()
-{}
-
-ApplicationList* ApplicationList::Copy(Node * n) const
-{ // Copy this app list
- ApplicationList* r = new ApplicationList(n);
- return r;
-}
-
-void
-ApplicationList::Add(Application* a)
-{
- a->Ref ();
- m_apps.push_back(a);
-}
-
-void ApplicationList::SetNode(Node * n)
-{
- // Set the node pointer in each application
- for (std::vector<Application *>::const_iterator i = m_apps.begin();
- i != m_apps.end(); ++i)
- { // Set correct node pointer in each app
- (*i)->SetNode(n);
- }
-}
-
-
-uint32_t ApplicationList::Count() const
-{
- return m_apps.size();
-}
-
-Application* ApplicationList::Get(uint32_t i) const
-{ // Get the i'th application. Note, this is linear time in N
- if (m_apps.empty()) return 0; // List is empty
- return m_apps[i];
-}
-
-}//namespace ns3
--- a/src/applications/application-list.h Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-// -*- Mode:NS3 -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-// Manages the list of applications associated with a node.
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef __APPLICATION_LIST_H__
-#define __APPLICATION_LIST_H__
-
-#include "application.h"
-#include "ns3/ns-unknown.h"
-#include <vector>
-
-namespace ns3 {
-
-class ApplicationList : public NsUnknown
-{
-public:
- static const Iid iid;
- ApplicationList(Node*);
- // Copy constructor not needed, default one is correct
- virtual ~ApplicationList();
- // Inherited from Capabilty
- virtual ApplicationList* Copy(Node*) const;
- virtual void SetNode(Node *); // Sets the node for all apps
- virtual void Add(Application*); // Add an already new'ed app
- // Manage the list
- template <typename T> T* AddCopy(const T& t) // Add a new application
- {
- T* a = t.Copy();
- m_apps.push_back(a);
- return a;
- }
- void Remove(Application*); // Application has finished
- uint32_t Count() const; // Number of applications
- Application* Get(uint32_t i) const; // Get app by index
-
-protected:
- virtual void DoDispose (void);
-private:
- std::vector<Application*> m_apps;
-};
-
-}//namespace ns3
-#endif
-
--- a/src/applications/application.cc Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +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>
- */
-
-// Implementation for ns3 Application base class.
-// George F. Riley, Georgia Tech, Fall 2006
-
-#include "application.h"
-#include "ns3/node.h"
-#include "ns3/nstime.h"
-#include "ns3/random-variable.h"
-#include "ns3/simulator.h"
-
-using namespace std;
-
-namespace ns3 {
-
-// Application Methods
-
-// \brief Application Constructor
-Application::Application(Node * n)
- : m_node (n),
- m_startVar(0), m_stopVar(0),
- m_start(false), m_stop(false)
-{
- m_node->Ref ();
-}
-
-Application::Application(const Application& o)
- : m_node(0), m_startVar(0), m_stopVar(0),
- m_start(false), m_stop(false)
-{ // Copy constructor
- m_node = o.m_node;
- m_node->Ref ();
- // 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()
-{}
-
-void
-Application::DoDispose (void)
-{
- if (m_node != 0)
- {
- m_node->Unref ();
- m_node = 0;
- }
- if (m_start)
- {
- Simulator::Cancel(m_startEvent);
- m_start = false;
- }
- if (m_stop)
- {
- Simulator::Cancel(m_stopEvent);
- m_stop = false;
- }
- delete m_startVar;
- m_startVar = 0;
- delete m_stopVar;
- m_stopVar = 0;
-}
-
-Application& Application::operator=(const Application& rhs)
-{
- if (this == &rhs) return *this; // Self assignment
- m_node->Unref ();
- m_node = 0;
- m_node = rhs.m_node;
- m_node->Ref ();
-
- delete m_startVar;
- m_startVar = 0;
- if (rhs.m_startVar) m_startVar = rhs.m_startVar->Copy();
-
- delete m_stopVar;
- m_stopVar = 0;
- 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(Node * n)
-{
- if (m_node != 0)
- {
- m_node->Unref ();
- }
- m_node = n;
- m_node->Ref ();
-}
-
-Node* Application::PeekNode() const
-{
- return m_node;
-}
-
-// 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
-
-
--- a/src/applications/application.h Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +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>
- */
-
-#ifndef __APPLICATION_H__
-#define __APPLICATION_H__
-
-#include "ns3/event-id.h"
-#include "ns3/nstime.h"
-#include "ns3/object.h"
-
-namespace ns3 {
-
-class Node;
-class RandomVariable;
-
-/**
- * \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.
- */
-class Application : public Object
-{
-public:
- Application(Node *);
- 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(Node *);
-
- /**
- * \brief Returns the pointer to the attached node.
- */
- Node* PeekNode() const;
-
- // Members
- Node * 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();
-
- virtual void DoDispose (void);
-private:
- // Helpers
- void ScheduleStart();
- void ScheduleStop();
-};
-
-} //namespace ns3
-#endif
--- a/src/applications/onoff-application.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/applications/onoff-application.cc Sun May 13 12:52:38 2007 +0100
@@ -42,7 +42,7 @@
// Constructors
- OnOffApplication::OnOffApplication(Node * n,
+ OnOffApplication::OnOffApplication(Ptr<Node> n,
const Ipv4Address rip, // Remote IP addr
uint16_t rport, // Remote port
const RandomVariable& ontime,
@@ -67,7 +67,7 @@
{
}
-OnOffApplication::OnOffApplication(Node * n, const OnOffApplication& c)
+OnOffApplication::OnOffApplication(Ptr<Node> n, const OnOffApplication& c)
: Application(n),
m_socket(0),
m_peerIP(c.m_peerIP),
@@ -92,11 +92,7 @@
void
OnOffApplication::DoDispose (void)
{
- if (m_socket != 0)
- {
- m_socket->Unref ();
- m_socket = 0;
- }
+ m_socket = 0;
delete m_onTime;
delete m_offTime;
@@ -170,9 +166,8 @@
this));
#endif
- IUdp *udp = PeekNode ()->QueryInterface<IUdp> (IUdp::iid);
+ Ptr<IUdp> udp = GetNode ()->QueryInterface<IUdp> (IUdp::iid);
m_socket = udp->CreateSocket ();
- udp->Unref ();
m_socket->Connect (m_peerIP, m_peerPort);
}
StopApplication(); // Insure no pending event
@@ -199,11 +194,6 @@
}
}
-OnOffApplication* OnOffApplication::Copy() const
-{
- return new OnOffApplication(*this);
-}
-
// Event handlers
void OnOffApplication::StartSending()
{
@@ -263,13 +253,13 @@
ScheduleNextTx();
}
-void OnOffApplication::ConnectionSucceeded(Socket*)
+void OnOffApplication::ConnectionSucceeded(Ptr<Socket>)
{
m_connected = true;
ScheduleStartEvent();
}
-void OnOffApplication::ConnectionFailed(Socket*)
+void OnOffApplication::ConnectionFailed(Ptr<Socket>)
{
cout << "OnOffApplication, Connection Failed" << endl;
}
--- a/src/applications/onoff-application.h Sun May 13 12:46:18 2007 +0100
+++ b/src/applications/onoff-application.h Sun May 13 12:52:38 2007 +0100
@@ -27,8 +27,9 @@
#ifndef __onoff_application_h__
#define __onoff_application_h__
-#include "application.h"
+#include "ns3/application.h"
#include "ns3/event-id.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -40,7 +41,7 @@
class OnOffApplication : public Application {
public:
- OnOffApplication(Node * n,
+ OnOffApplication(Ptr<Node> n,
const Ipv4Address, // Peer IP address
uint16_t, // Peer port
const RandomVariable&, // Random variable for On time
@@ -48,11 +49,10 @@
DataRate = g_defaultRate, // Data rate when on
uint32_t = g_defaultSize); // Size of packets
- OnOffApplication(Node * n, const OnOffApplication&); // Copy constructor
+ OnOffApplication(Ptr<Node> n, const OnOffApplication&); // Copy constructor
virtual ~OnOffApplication(); // Destructor
virtual void StartApplication(); // Called at time specified by Start
virtual void StopApplication(); // Called at time specified by Stop
- virtual OnOffApplication* Copy() const;// Make a copy of the application
// Event handlers
void StartSending();
@@ -70,7 +70,7 @@
static void DefaultSize(uint32_t s) { g_defaultSize = s;}
public:
- Socket * m_socket; // Associated socket
+ Ptr<Socket> m_socket; // Associated socket
Ipv4Address m_peerIP; // Peer IP address
uint16_t m_peerPort; // Peer port
bool m_connected; // True if connected
@@ -96,9 +96,9 @@
void ScheduleNextTx();
void ScheduleStartEvent();
void ScheduleStopEvent();
- void ConnectionSucceeded(Socket*);
- void ConnectionFailed(Socket*);
- void Ignore(Socket*);
+ void ConnectionSucceeded(Ptr<Socket>);
+ void ConnectionFailed(Ptr<Socket>);
+ void Ignore(Ptr<Socket>);
protected:
};
--- a/src/applications/wscript Sun May 13 12:46:18 2007 +0100
+++ b/src/applications/wscript Sun May 13 12:52:38 2007 +0100
@@ -7,14 +7,10 @@
obj.target = obj.name
obj.uselib_local = ['ns3-node']
obj.source = [
- 'application-list.cc',
- 'application.cc',
'onoff-application.cc',
]
headers = bld.create_obj('ns3header')
headers.source = [
- 'application-list.h',
- 'application.h',
'onoff-application.h',
]
--- a/src/common/array-trace-resolver.h Sun May 13 12:46:18 2007 +0100
+++ b/src/common/array-trace-resolver.h Sun May 13 12:52:38 2007 +0100
@@ -87,7 +87,6 @@
Callback<uint32_t> m_getSize;
Callback<T *, uint32_t> m_get;
};
-
}//namespace ns3
namespace ns3 {
@@ -108,8 +107,8 @@
template <typename T>
ArrayTraceResolver<T>::ArrayTraceResolver (TraceContext const &context,
- Callback<uint32_t> getSize,
- Callback<T *, uint32_t> get)
+ Callback<uint32_t> getSize,
+ Callback<T *, uint32_t> get)
: TraceResolver (context),
m_getSize (getSize),
m_get (get)
@@ -120,15 +119,15 @@
{
TraceResolverList list;
if (id == "*")
+ {
+ for (uint32_t i = 0; i < m_getSize (); i++)
{
- for (uint32_t i = 0; i < m_getSize (); i++)
- {
TraceContext context = GetContext ();
- typename ArrayTraceResolver<T>::Index index = typename ArrayTraceResolver<T>::Index (i);
+ typename ArrayTraceResolver<T>::Index index = typename ArrayTraceResolver<T>::Index (i);
context.Add (index);
list.push_back (m_get (i)->CreateTraceResolver (context));
- }
}
+ }
return list;
}
--- a/src/core/command-line.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/core/command-line.cc Sun May 13 12:52:38 2007 +0100
@@ -1,4 +1,23 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech University, INRIA
+ *
+ * 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
+ *
+ * Authors: Raj Bhattacharjea <raj.b@gatech.edu>,
+ * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
#include "command-line.h"
#include <unistd.h>
--- a/src/core/command-line.h Sun May 13 12:46:18 2007 +0100
+++ b/src/core/command-line.h Sun May 13 12:52:38 2007 +0100
@@ -1,4 +1,23 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech University, INRIA
+ *
+ * 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
+ *
+ * Authors: Raj Bhattacharjea <raj.b@gatech.edu>,
+ * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
#ifndef COMMAND_LINE_H
#define COMMAND_LINE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/component-manager.cc Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,243 @@
+/* -*- 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 "component-manager.h"
+#include "uid-manager.h"
+#include "singleton.h"
+
+namespace ns3 {
+
+// we redefine a UidManager type for the class id singleton below.
+// otherwise, we would have to share the same id singleton instance
+// with the Iids.
+class CidManager : public UidManager
+{};
+
+ClassId::ClassId (std::string name)
+ : m_classId (Singleton<CidManager>::Get ()->Allocate (name))
+{}
+
+ClassId::ClassId (uint32_t classId)
+ : m_classId (classId)
+{}
+
+std::string
+ClassId::GetName (void)
+{
+ return Singleton<CidManager>::Get ()->LookupByUid (m_classId);
+}
+
+bool operator == (const ClassId &a, const ClassId &b)
+{
+ return a.m_classId == b.m_classId;
+}
+
+Ptr<Interface>
+ComponentManager::Create (ClassId classId)
+{
+ Callback<Ptr<Interface> > callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
+ return callback ();
+}
+
+CallbackBase *
+ComponentManager::Lookup (ClassId classId)
+{
+ List *list = Singleton<List>::Get ();
+ for (List::const_iterator i = list->begin (); i != list->end (); i++)
+ {
+ if (i->first == classId)
+ {
+ return i->second;
+ }
+ }
+ return 0;
+}
+
+ClassId
+ComponentManager::LookupByName (std::string name)
+{
+ return ClassId (Singleton<CidManager>::Get ()->LookupByName (name));
+}
+
+ClassId
+ComponentManager::Register (std::string name, CallbackBase *callback)
+{
+ ClassId classId = ClassId (name);
+ List *list = Singleton<List>::Get ();
+ list->push_back (std::make_pair (classId, callback));
+ return classId;
+}
+
+
+} // namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+#include "interface.h"
+
+namespace {
+
+
+class B : public ns3::Interface
+{
+public:
+ static const ns3::InterfaceId iid;
+ B ();
+};
+
+const ns3::InterfaceId B::iid ("IB");
+
+B::B ()
+ : Interface (B::iid)
+{}
+
+
+class A : public ns3::Interface
+{
+public:
+ static const ns3::ClassId cidZero;
+ static const ns3::ClassId cidOneBool;
+ static const ns3::ClassId cidOneUi32;
+ static const ns3::InterfaceId iid;
+
+ A ();
+ A (bool);
+ A (uint32_t);
+
+ bool m_zeroInvoked;
+ bool m_oneBoolInvoked;
+ bool m_oneUi32Invoked;
+
+ bool m_bool;
+ int m_ui32;
+};
+
+const ns3::ClassId A::cidZero = ns3::ComponentManager::RegisterConstructor <A> ("A");
+const ns3::ClassId A::cidOneBool = ns3::ComponentManager::RegisterConstructor <A,bool> ("ABool");
+const ns3::ClassId A::cidOneUi32 = ns3::ComponentManager::RegisterConstructor <A,uint32_t> ("AUi32");
+const ns3::InterfaceId A::iid ("IA");
+
+A::A ()
+ : Interface (A::iid),
+ m_zeroInvoked (true),
+ m_oneBoolInvoked (false),
+ m_oneUi32Invoked (false)
+{
+ ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+ AddInterface (b);
+}
+
+A::A (bool bo)
+ : Interface (A::iid),
+ m_zeroInvoked (false),
+ m_oneBoolInvoked (true),
+ m_oneUi32Invoked (false),
+ m_bool (bo)
+{
+ ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+ AddInterface (b);
+}
+
+A::A (uint32_t i)
+ : Interface (A::iid),
+ m_zeroInvoked (false),
+ m_oneBoolInvoked (false),
+ m_oneUi32Invoked (true),
+ m_ui32 (i)
+{
+ ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+ AddInterface (b);
+}
+
+}
+
+namespace ns3 {
+
+class ComponentManagerTest : public Test
+{
+public:
+ ComponentManagerTest ();
+ virtual bool RunTests (void);
+};
+
+ComponentManagerTest::ComponentManagerTest ()
+ : Test ("ComponentManager")
+{}
+bool
+ComponentManagerTest::RunTests (void)
+{
+ bool ok = true;
+
+ Ptr<A> a = 0;
+ a = ComponentManager::Create<A> (A::cidZero, A::iid);
+ if (a == 0 ||
+ !a->m_zeroInvoked)
+ {
+ ok = false;
+ }
+
+ a = ComponentManager::Create<A,bool> (A::cidOneBool, A::iid, true);
+ if (a == 0 ||
+ !a->m_oneBoolInvoked ||
+ !a->m_bool)
+ {
+ ok = false;
+ }
+
+ a = ComponentManager::Create<A,bool> (A::cidOneBool, A::iid, false);
+ if (a == 0 ||
+ !a->m_oneBoolInvoked ||
+ a->m_bool)
+ {
+ ok = false;
+ }
+
+ a = ComponentManager::Create<A,uint32_t> (A::cidOneUi32, A::iid, 10);
+ if (a == 0 ||
+ !a->m_oneUi32Invoked ||
+ a->m_ui32 != 10)
+ {
+ ok = false;
+ }
+
+ a = ComponentManager::Create<A> (A::cidOneUi32, A::iid, (uint32_t)10);
+ if (a == 0 ||
+ !a->m_oneUi32Invoked ||
+ a->m_ui32 != 10)
+ {
+ ok = false;
+ }
+
+ Ptr<B> b = ComponentManager::Create<B,uint32_t> (A::cidOneUi32, B::iid, 10);
+ if (b == 0)
+ {
+ ok = false;
+ }
+
+ return ok;
+}
+
+
+static ComponentManagerTest g_unknownManagerTest;
+
+} // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/component-manager.h Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,274 @@
+/* -*- 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 NS_UNKNOWN_MANAGER_H
+#define NS_UNKNOWN_MANAGER_H
+
+#include <string>
+#include <vector>
+#include <stdint.h>
+#include "callback.h"
+#include "interface.h"
+#include "fatal-error.h"
+#include "ptr.h"
+
+namespace ns3 {
+
+/**
+ * \brief Unique Identifier for class constructors.
+ *
+ * Instances of this type must be allocated through
+ * the ns3::Ns3UnknownManager::RegisterConstructor methods
+ */
+class ClassId
+{
+public:
+ /**
+ * \returns the symbolic name associated to this class id
+ *
+ * This name is the name which was associated to this class id
+ * by the ns3::Ns3UnknownManager::RegisterConstructor methods.
+ * This name is also the name which is expected to be input
+ * to ns3::UnknownManager::LookupByName.
+ */
+ std::string GetName (void);
+private:
+ ClassId (std::string name);
+ ClassId (uint32_t classId);
+ friend class ComponentManager;
+ friend bool operator == (const ClassId &a, const ClassId &b);
+ uint32_t m_classId;
+};
+
+/**
+ * \brief Create any Interface
+ *
+ * This class keeps track of a set of ClassId, each
+ * of which uniquely identifies the constructor of an
+ * object which derives from the Interface base class.
+ * This class can also create an instance of any of
+ * the objects tracked through any of their tracked
+ * constructor/ClassId.
+ */
+class ComponentManager
+{
+public:
+ /**
+ * \param name the symbolic name to lookup
+ * \returns the ClassId associated to the input name.
+ */
+ static ClassId LookupByName (std::string name);
+
+ /**
+ * \param classId class id of the constructor to invoke.
+ * \return a pointer to the instance created.
+ *
+ * Create an instance of the object identified by its
+ * ClassId. This method invokes the default constructor.
+ */
+ static Ptr<Interface> Create (ClassId classId);
+
+ /**
+ * \param classId class id of the constructor to invoke.
+ * \param a1 argument to pass to the constructor.
+ * \return a pointer to the instance created.
+ *
+ * Create an instance of the object identified by its
+ * ClassId.
+ */
+ template <typename T1>
+ static Ptr<Interface> Create (ClassId classId, T1 a1);
+
+ /**
+ * \param classId class id of the constructor to invoke.
+ * \param a1 first argument to pass to the constructor.
+ * \param a2 second argument to pass to the constructor.
+ * \return a pointer to the instance created.
+ *
+ * Create an instance of the object identified by its
+ * ClassId.
+ */
+ template <typename T1, typename T2>
+ static Ptr<Interface> Create (ClassId classId, T1 a1, T2 a2);
+
+ /**
+ * \param classId class id of the constructor to invoke.
+ * \param iid interface id to query for
+ * \return a pointer to the instance created.
+ *
+ * Create an instance of the object identified by its
+ * ClassId, call QueryInterface on it, and return the
+ * result.
+ */
+ template <typename T>
+ static Ptr<T> Create (ClassId classId, InterfaceId iid);
+
+ template <typename T, typename T1>
+ static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1);
+
+ template <typename T, typename T1, typename T2>
+ static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2);
+
+ /**
+ * \param name the symbolic name to associate to this
+ * constructor
+ * \returns a ClassId which uniquely identifies this constructor.
+ */
+ template <typename T>
+ static ClassId RegisterConstructor (std::string name)
+ {
+ static Callback<Ptr<Interface> > callback =
+ MakeCallback (&ComponentManager::MakeObjectZero<T>);
+ return ComponentManager::Register (name, &callback);
+ }
+
+ /**
+ * \param name the symbolic name to associate to this
+ * constructor
+ * \returns a ClassId which uniquely identifies this constructor.
+ */
+ template <typename T, typename T1>
+ static ClassId RegisterConstructor (std::string name)
+ {
+ static Callback<Ptr<Interface> ,T1> callback = MakeCallback (&ComponentManager::MakeObjectOne<T,T1>);
+ return ComponentManager::Register (name, &callback);
+ }
+
+ /**
+ * \param name the symbolic name to associate to this
+ * constructor
+ * \returns a ClassId which uniquely identifies this constructor.
+ */
+ template <typename T, typename T1, typename T2>
+ static ClassId RegisterConstructor (std::string name)
+ {
+ static Callback<Ptr<Interface>,T1,T2> callback = MakeCallback (&ComponentManager::MakeObjectTwo<T,T1,T2>);
+ return ComponentManager::Register (name, &callback);
+ }
+private:
+ static ClassId Register (std::string name, CallbackBase *callback);
+
+ template <typename T1, typename T2,
+ typename T3, typename T4,
+ typename T5>
+ static Callback<Ptr<Interface>,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
+
+ template <typename T>
+ static Ptr<Interface> MakeObjectZero (void);
+
+ template <typename T, typename T1>
+ static Ptr<Interface> MakeObjectOne (T1 a1);
+
+ template <typename T, typename T1, typename T2>
+ static Ptr<Interface> MakeObjectTwo (T1 a1, T2 a2);
+
+ typedef std::vector<std::pair<ClassId, CallbackBase *> > List;
+ static List *GetList (void);
+ static CallbackBase *Lookup (ClassId classId);
+};
+
+} // namespace ns3
+
+
+namespace ns3 {
+
+template <typename T1, typename T2,
+ typename T3, typename T4,
+ typename T5>
+Callback<Ptr<Interface>,T1,T2,T3,T4,T5>
+ComponentManager::DoGetCallback (ClassId classId)
+{
+ CallbackBase *callback = Lookup (classId);
+ if (callback == 0)
+ {
+ NS_FATAL_ERROR ("Invalid Class Id.");
+ }
+ Callback<Ptr<Interface>, T1,T2,T3,T4,T5> reference;
+ reference.Assign (*callback);
+ return reference;
+}
+
+
+template <typename T1>
+Ptr<Interface>
+ComponentManager::Create (ClassId classId, T1 a1)
+{
+ Callback<Ptr<Interface>, T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
+ return callback (a1);
+}
+
+template <typename T1, typename T2>
+Ptr<Interface>
+ComponentManager::Create (ClassId classId, T1 a1, T2 a2)
+{
+ Callback<Ptr<Interface> , T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
+ return callback (a1, a2);
+}
+
+template <typename T>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid)
+{
+ Ptr<Interface> obj = Create (classId);
+ Ptr<T> i = obj->QueryInterface<T> (iid);
+ return i;
+}
+
+template <typename T, typename T1>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1)
+{
+ Ptr<Interface> obj = Create (classId, a1);
+ Ptr<T> i = obj->QueryInterface<T> (iid);
+ return i;
+}
+
+template <typename T, typename T1, typename T2>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2)
+{
+ Ptr<Interface> obj = Create (classId, a1, a2);
+ Ptr<T> i = obj->QueryInterface<T> (iid);
+ return i;
+}
+
+
+template <typename T>
+Ptr<Interface>
+ComponentManager::MakeObjectZero (void)
+{
+ return MakeNewObject<T> ();
+}
+template <typename T, typename T1>
+Ptr<Interface>
+ComponentManager::MakeObjectOne (T1 a1)
+{
+ return MakeNewObject<T> (a1);
+}
+template <typename T, typename T1, typename T2>
+Ptr<Interface>
+ComponentManager::MakeObjectTwo (T1 a1, T2 a2)
+{
+ return MakeNewObject<T> (a1, a2);
+}
+
+} // namespace ns3
+
+#endif /* NS_UNKNOWN_MANAGER_H */
--- a/src/core/debug.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/core/debug.cc Sun May 13 12:52:38 2007 +0100
@@ -48,7 +48,7 @@
DebugComponentEnableEnvVar (void)
{
#ifdef HAVE_GETENV
- char *envVar = getenv("NS3_DEBUG");
+ char *envVar = getenv("NS_DEBUG");
if (envVar == 0)
{
return;
--- a/src/core/default-value.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/core/default-value.cc Sun May 13 12:52:38 2007 +0100
@@ -1,4 +1,22 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * 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 "default-value.h"
#include "fatal-error.h"
--- a/src/core/default-value.h Sun May 13 12:46:18 2007 +0100
+++ b/src/core/default-value.h Sun May 13 12:52:38 2007 +0100
@@ -1,4 +1,22 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * 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 DEFAULT_VALUE_H
#define DEFAULT_VALUE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/interface.cc Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,386 @@
+/* -*- 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 "interface.h"
+#include "singleton.h"
+#include "uid-manager.h"
+#include <string>
+#include <list>
+#include <stdint.h>
+#include "assert.h"
+#include "debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("Interface");
+
+namespace ns3 {
+
+class IidManager : public UidManager
+{};
+
+InterfaceId::InterfaceId (std::string name)
+ : m_iid (Singleton<IidManager>::Get ()->Allocate (name))
+{}
+
+bool operator == (const InterfaceId &a, const InterfaceId &b)
+{
+ return a.m_iid == b.m_iid;
+}
+
+
+class InterfaceImpl
+{
+public:
+ InterfaceImpl (InterfaceId iid, Interface *interface);
+ ~InterfaceImpl ();
+ void Ref (void);
+ void RefAll (InterfaceImpl *other);
+ void Unref (void);
+ void UnrefAll (void);
+ Interface *PeekQueryInterface (InterfaceId iid) const;
+ void DoDisposeAll (void);
+ void AddInterface (Interface * interface);
+ void AddSelfInterface (InterfaceId iid, Interface *interface);
+private:
+ typedef std::list<std::pair<InterfaceId,Interface *> > List;
+ uint32_t m_ref;
+ List m_list;
+ bool m_disposed;
+};
+
+InterfaceImpl::InterfaceImpl (InterfaceId iid, Interface * interface)
+ : m_ref (1),
+ m_disposed (false)
+{
+ NS_DEBUG ("new " << this << " ref=" << m_ref);
+ m_list.push_back (std::make_pair (iid, interface));
+}
+InterfaceImpl::~InterfaceImpl ()
+{
+ for (List::const_iterator i = m_list.begin ();
+ i != m_list.end (); i++)
+ {
+ i->second->UnrefInternal ();
+ }
+ m_list.clear ();
+}
+void
+InterfaceImpl::Ref (void)
+{
+ m_ref++;
+ NS_DEBUG ("inc " << this << " ref=" << m_ref);
+}
+void
+InterfaceImpl::RefAll (InterfaceImpl *other)
+{
+ m_ref += other->m_ref;
+ NS_DEBUG ("inc all " << this << " o=" << other->m_ref << " ref=" << m_ref);
+}
+void
+InterfaceImpl::Unref (void)
+{
+ NS_ASSERT (m_ref > 0);
+ m_ref--;
+ NS_DEBUG ("dec " << this << " ref=" << m_ref);
+ if (m_ref == 0)
+ {
+ delete this;
+ }
+}
+void
+InterfaceImpl::UnrefAll (void)
+{
+ NS_ASSERT (m_ref > 0);
+ m_ref = 0;
+ delete this;
+ NS_DEBUG ("dec all " << this);
+}
+void
+InterfaceImpl::DoDisposeAll (void)
+{
+ NS_ASSERT (!m_disposed);
+ for (List::const_iterator i = m_list.begin ();
+ i != m_list.end (); i++)
+ {
+ Interface *interface = i->second;
+ interface->DoDispose ();
+ }
+ m_disposed = true;
+}
+Interface *
+InterfaceImpl::PeekQueryInterface (InterfaceId iid) const
+{
+ for (List::const_iterator i = m_list.begin ();
+ i != m_list.end (); i++)
+ {
+ if (i->first == iid)
+ {
+ return i->second;
+ }
+ }
+ return 0;
+}
+void
+InterfaceImpl::AddInterface (Interface *interface)
+{
+ for (List::const_iterator i = interface->m_impl->m_list.begin ();
+ i != interface->m_impl->m_list.end (); i++)
+ {
+ // XXX here, we should check that we have only one
+ // instance of each interface
+ i->second->RefInternal ();
+ m_list.push_back (std::make_pair (i->first, i->second));
+ }
+}
+void
+InterfaceImpl::AddSelfInterface (InterfaceId iid, Interface *interface)
+{
+ interface->RefInternal ();
+ m_list.push_back (std::make_pair (iid, interface));
+}
+
+
+Interface::Interface (InterfaceId iid)
+ : m_impl (new InterfaceImpl (iid, this)),
+ m_ref (1)
+{}
+Interface::~Interface ()
+{
+ m_impl = 0;
+ m_ref = -1;
+}
+void
+Interface::Ref (void) const
+{
+ m_impl->Ref ();
+}
+void
+Interface::Unref (void) const
+{
+ m_impl->Unref ();
+}
+
+void
+Interface::Dispose (void)
+{
+ m_impl->DoDisposeAll ();
+}
+
+void
+Interface::DoDispose (void)
+{
+ // we do not do anything by default.
+}
+
+void
+Interface::RefInternal (void)
+{
+ m_ref++;
+}
+
+void
+Interface::UnrefInternal (void)
+{
+ NS_ASSERT (m_ref != 0);
+ m_ref--;
+ if (m_ref == 0)
+ {
+ delete this;
+ }
+}
+
+Ptr<Interface>
+Interface::DoQueryInterface (InterfaceId iid) const
+{
+ return m_impl->PeekQueryInterface (iid);
+}
+
+void
+Interface::AddInterface (Ptr<Interface> interface)
+{
+ Interface *p = PeekPointer (interface);
+ m_impl->AddInterface (p);
+ m_impl->RefAll (p->m_impl);
+ p->m_impl->UnrefAll ();
+ p->m_impl = m_impl;
+}
+
+void
+Interface::AddSelfInterface (InterfaceId iid, Ptr<Interface> interface)
+{
+ m_impl->AddSelfInterface (iid, PeekPointer (interface));
+}
+
+
+}//namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+
+namespace {
+
+class A : public ns3::Interface
+{
+public:
+ static const ns3::InterfaceId iid;
+ A ()
+ : Interface (A::iid)
+ {}
+};
+class B : public ns3::Interface
+{
+public:
+ static const ns3::InterfaceId iid;
+ B ()
+ : Interface (B::iid)
+ {}
+};
+class BaseA : public ns3::Interface
+{
+public:
+ static const ns3::InterfaceId iid;
+ BaseA ()
+ : Interface (BaseA::iid)
+ {}
+};
+class BaseB : public ns3::Interface
+{
+public:
+ static const ns3::InterfaceId iid;
+ BaseB ()
+ : Interface (BaseB::iid)
+ {}
+};
+class Base : public ns3::Interface
+{
+public:
+ static const ns3::InterfaceId iid;
+ Base ()
+ : Interface (Base::iid)
+ {}
+};
+class Derived : public Base
+{
+public:
+ static const ns3::InterfaceId iid;
+ Derived ()
+ {
+ AddSelfInterface (Derived::iid, this);
+ }
+};
+
+const ns3::InterfaceId A::iid ("A");
+const ns3::InterfaceId B::iid ("B");
+const ns3::InterfaceId BaseA::iid ("BaseA");
+const ns3::InterfaceId BaseB::iid ("BaseB");
+const ns3::InterfaceId Base::iid ("Base");
+const ns3::InterfaceId Derived::iid ("Derived");
+
+}//namespace
+
+
+namespace ns3 {
+
+class InterfaceTest : public Test
+{
+public:
+ InterfaceTest ();
+ virtual bool RunTests (void);
+};
+
+InterfaceTest::InterfaceTest ()
+ : Test ("Interface")
+{}
+bool
+InterfaceTest::RunTests (void)
+{
+ bool ok = true;
+
+ //DerivedAB *derivedAB;
+
+
+ Ptr<A> a = MakeNewObject<A> ();
+
+ a = MakeNewObject<A> ();
+ Ptr<A> a1 = a->QueryInterface<A> (A::iid);
+ if (a1 == 0 || a1 != a)
+ {
+ ok = false;
+ }
+ a1 = a->QueryInterface<A> (A::iid);
+ if (a1 == 0 || a1 != a)
+ {
+ ok = false;
+ }
+
+ Ptr<B> b = MakeNewObject<B> ();
+ Ptr<B> b1 = b->QueryInterface<B> (B::iid);
+ if (b1 == 0 || b1 != b)
+ {
+ ok = false;
+ }
+
+ a = MakeNewObject<A> ();
+ a->AddInterface (b);
+ b1 = b->QueryInterface<B> (B::iid);
+ if (b1 == 0 || b1 != b)
+ {
+ ok = false;
+ }
+ a1 = b->QueryInterface<A> (A::iid);
+ if (a1 == 0 || a1 != a)
+ {
+ ok = false;
+ }
+ a1 = a->QueryInterface<A> (A::iid);
+ if (a1 == 0 || a1 != a)
+ {
+ ok = false;
+ }
+ b1 = a->QueryInterface<B> (B::iid);
+ if (b1 == 0 || b1 != b)
+ {
+ ok = false;
+ }
+
+ Ptr<Derived> derived = MakeNewObject<Derived> ();
+ Ptr<Base> base = derived->QueryInterface<Base> (Base::iid);
+ if (base == 0)
+ {
+ ok = false;
+ }
+ Ptr<Derived> derived1 = base->QueryInterface<Derived> (Derived::iid);
+ if (derived1 == 0 || derived1 != derived)
+ {
+ ok = false;
+ }
+
+ // the following cannot work and it is on purpose
+ // delete derived;
+
+ return ok;
+}
+
+
+static InterfaceTest g_interface_test;
+
+}// namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/interface.h Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,128 @@
+/* -*- 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 INTERFACE_H
+#define INTERFACE_H
+
+#include <string>
+#include "ptr.h"
+
+namespace ns3 {
+
+class InterfaceImpl;
+
+class InterfaceId
+{
+public:
+ InterfaceId (std::string name);
+private:
+ friend bool operator == (const InterfaceId &a, const InterfaceId &b);
+ uint32_t m_iid;
+};
+
+/**
+ * \brief COM-like IUnknown
+ *
+ * This class should be used as a base class for every object which
+ * wishes to provide a COM-like QueryInterface API. Multiple
+ * inheritance where this base class is at the top of the dreaded
+ * "diamond" shape is not allowed.
+ */
+class Interface
+{
+public:
+ virtual ~Interface ();
+ void Ref (void) const;
+ void Unref (void) const;
+
+ /**
+ * \param iid the Interface id of the requested interface
+ */
+ template <typename T>
+ Ptr<T> QueryInterface (InterfaceId iid) const;
+
+ /**
+ * \param interface another interface
+ *
+ * Aggregate together the two interfaces. After this call,
+ * the two interface objects are tied together: each of them
+ * will be able to perform QI on each other and their lifetimes
+ * will be found by the same reference count.
+ */
+ void AddInterface (Ptr<Interface> interface);
+
+ void Dispose (void);
+protected:
+ /**
+ * \param iid the Interface Id of the interface defined by a direct subclass
+ * of this base class
+ *
+ * If you are a direct subclass of this class, you _must_ register
+ * the name of your interface with this constructor.
+ */
+ Interface (InterfaceId iid);
+ /**
+ * \param iid the Interface id of the interface
+ * \param interface a pointer to the interface object
+ *
+ * If you are not a direct subclass of the ns3::Interface base class,
+ * and if you want to register yourself as another accessible interface
+ * (typically, your subclass has added API), you need to call
+ * this method to associate an interface id to your interface.
+ */
+ void AddSelfInterface (InterfaceId iid, Ptr<Interface> interface);
+protected:
+ /**
+ * Subclasses who want to handle the "dispose" event should
+ * override this method. They are also responsible for
+ * "chaining up" to their parent class' DoDispose method
+ * once they have done their own "dispose".
+ */
+ virtual void DoDispose (void);
+private:
+ friend class InterfaceImpl;
+ Interface ();
+ Ptr<Interface> DoQueryInterface (InterfaceId iid) const;
+ void RefInternal (void);
+ void UnrefInternal (void);
+ InterfaceImpl *m_impl;
+ uint32_t m_ref;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+Ptr<T>
+Interface::QueryInterface (InterfaceId iid) const
+{
+ Ptr<Interface> found = DoQueryInterface (iid);
+ if (found != 0)
+ {
+ return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
+ }
+ return 0;
+}
+
+
+}//namespace ns3
+
+#endif /* INTERFACE_H */
--- a/src/core/ns-unknown-manager.cc Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +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 "ns-unknown-manager.h"
-#include "uid-manager.h"
-#include "singleton.h"
-
-namespace ns3 {
-
-// we redefine a UidManager type for the class id singleton below.
-// otherwise, we would have to share the same id singleton instance
-// with the Iids.
-class CidManager : public UidManager
-{};
-
-ClassId::ClassId (std::string name)
- : m_classId (Singleton<CidManager>::Get ()->Allocate (name))
-{}
-
-ClassId::ClassId (uint32_t classId)
- : m_classId (classId)
-{}
-
-std::string
-ClassId::GetName (void)
-{
- return Singleton<CidManager>::Get ()->LookupByUid (m_classId);
-}
-
-bool operator == (const ClassId &a, const ClassId &b)
-{
- return a.m_classId == b.m_classId;
-}
-
-NsUnknown *
-NsUnknownManager::Create (ClassId classId)
-{
- Callback<NsUnknown *> callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
- return callback ();
-}
-
-CallbackBase *
-NsUnknownManager::Lookup (ClassId classId)
-{
- List *list = Singleton<List>::Get ();
- for (List::const_iterator i = list->begin (); i != list->end (); i++)
- {
- if (i->first == classId)
- {
- return i->second;
- }
- }
- return 0;
-}
-
-ClassId
-NsUnknownManager::LookupByName (std::string name)
-{
- return ClassId (Singleton<CidManager>::Get ()->LookupByName (name));
-}
-
-ClassId
-NsUnknownManager::Register (std::string name, CallbackBase *callback)
-{
- ClassId classId = ClassId (name);
- List *list = Singleton<List>::Get ();
- list->push_back (std::make_pair (classId, callback));
- return classId;
-}
-
-
-} // namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "test.h"
-#include "ns-unknown.h"
-
-namespace {
-
-
-class B : public ns3::NsUnknown
-{
-public:
- static const ns3::Iid iid;
- B ();
-};
-
-const ns3::Iid B::iid ("IB");
-
-B::B ()
- : NsUnknown (B::iid)
-{}
-
-
-class A : public ns3::NsUnknown
-{
-public:
- static const ns3::ClassId cidZero;
- static const ns3::ClassId cidOneBool;
- static const ns3::ClassId cidOneUi32;
- static const ns3::Iid iid;
-
- A ();
- A (bool);
- A (uint32_t);
-
- bool m_zeroInvoked;
- bool m_oneBoolInvoked;
- bool m_oneUi32Invoked;
-
- bool m_bool;
- int m_ui32;
-};
-
-const ns3::ClassId A::cidZero = ns3::NsUnknownManager::RegisterConstructor <A> ("A");
-const ns3::ClassId A::cidOneBool = ns3::NsUnknownManager::RegisterConstructor <A,bool> ("ABool");
-const ns3::ClassId A::cidOneUi32 = ns3::NsUnknownManager::RegisterConstructor <A,uint32_t> ("AUi32");
-const ns3::Iid A::iid ("IA");
-
-A::A ()
- : NsUnknown (A::iid),
- m_zeroInvoked (true),
- m_oneBoolInvoked (false),
- m_oneUi32Invoked (false)
-{
- B *b = new B ();
- AddInterface (b);
- b->Unref ();
-}
-
-A::A (bool bo)
- : NsUnknown (A::iid),
- m_zeroInvoked (false),
- m_oneBoolInvoked (true),
- m_oneUi32Invoked (false),
- m_bool (bo)
-{
- B *b = new B ();
- AddInterface (b);
- b->Unref ();
-}
-
-A::A (uint32_t i)
- : NsUnknown (A::iid),
- m_zeroInvoked (false),
- m_oneBoolInvoked (false),
- m_oneUi32Invoked (true),
- m_ui32 (i)
-{
- B *b = new B ();
- AddInterface (b);
- b->Unref ();
-}
-
-}
-
-namespace ns3 {
-
-class NsUnknownManagerTest : public Test
-{
-public:
- NsUnknownManagerTest ();
- virtual bool RunTests (void);
-};
-
-NsUnknownManagerTest::NsUnknownManagerTest ()
- : Test ("NsUnknownManager")
-{}
-bool
-NsUnknownManagerTest::RunTests (void)
-{
- bool ok = true;
-
- A *a = 0;
- a = NsUnknownManager::Create<A> (A::cidZero, A::iid);
- if (a == 0 ||
- !a->m_zeroInvoked)
- {
- ok = false;
- }
- a->Unref ();
-
- a = NsUnknownManager::Create<A,bool> (A::cidOneBool, A::iid, true);
- if (a == 0 ||
- !a->m_oneBoolInvoked ||
- !a->m_bool)
- {
- ok = false;
- }
- a->Unref ();
-
- a = NsUnknownManager::Create<A,bool> (A::cidOneBool, A::iid, false);
- if (a == 0 ||
- !a->m_oneBoolInvoked ||
- a->m_bool)
- {
- ok = false;
- }
- a->Unref ();
-
- a = NsUnknownManager::Create<A,uint32_t> (A::cidOneUi32, A::iid, 10);
- if (a == 0 ||
- !a->m_oneUi32Invoked ||
- a->m_ui32 != 10)
- {
- ok = false;
- }
- a->Unref ();
-
- a = NsUnknownManager::Create<A> (A::cidOneUi32, A::iid, (uint32_t)10);
- if (a == 0 ||
- !a->m_oneUi32Invoked ||
- a->m_ui32 != 10)
- {
- ok = false;
- }
- a->Unref ();
-
- B *b = NsUnknownManager::Create<B,uint32_t> (A::cidOneUi32, B::iid, 10);
- if (b == 0)
- {
- ok = false;
- }
- b->Unref ();
-
- return ok;
-}
-
-
-static NsUnknownManagerTest g_unknownManagerTest;
-
-} // namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/core/ns-unknown-manager.h Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +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 NS_UNKNOWN_MANAGER_H
-#define NS_UNKNOWN_MANAGER_H
-
-#include <string>
-#include <vector>
-#include <stdint.h>
-#include "callback.h"
-#include "ns-unknown.h"
-#include "fatal-error.h"
-
-namespace ns3 {
-
-/**
- * \brief Unique Identifier for class constructors.
- *
- * Instances of this type must be allocated through
- * the ns3::Ns3UnknownManager::RegisterConstructor methods
- */
-class ClassId
-{
-public:
- /**
- * \returns the symbolic name associated to this class id
- *
- * This name is the name which was associated to this class id
- * by the ns3::Ns3UnknownManager::RegisterConstructor methods.
- * This name is also the name which is expected to be input
- * to ns3::UnknownManager::LookupByName.
- */
- std::string GetName (void);
-private:
- ClassId (std::string name);
- ClassId (uint32_t classId);
- friend class NsUnknownManager;
- friend bool operator == (const ClassId &a, const ClassId &b);
- uint32_t m_classId;
-};
-
-/**
- * \brief Create any NsUnknown
- *
- * This class keeps track of a set of ClassId, each
- * of which uniquely identifies the constructor of an
- * object which derives from the NsUnknown base class.
- * This class can also create an instance of any of
- * the objects tracked through any of their tracked
- * constructor/ClassId.
- */
-class NsUnknownManager
-{
-public:
- /**
- * \param name the symbolic name to lookup
- * \returns the ClassId associated to the input name.
- */
- static ClassId LookupByName (std::string name);
-
- /**
- * \param classId class id of the constructor to invoke.
- * \return a pointer to the instance created.
- *
- * Create an instance of the object identified by its
- * ClassId. This method invokes the default constructor.
- */
- static NsUnknown *Create (ClassId classId);
-
- /**
- * \param classId class id of the constructor to invoke.
- * \param a1 argument to pass to the constructor.
- * \return a pointer to the instance created.
- * \overload NsUnknown *Create (ClassId)
- *
- * Create an instance of the object identified by its
- * ClassId.
- */
- template <typename T1>
- static NsUnknown *Create (ClassId classId, T1 a1);
-
- /**
- * \param classId class id of the constructor to invoke.
- * \param a1 first argument to pass to the constructor.
- * \param a2 second argument to pass to the constructor.
- * \return a pointer to the instance created.
- * \overload NsUnknown *Create (ClassId)
- *
- * Create an instance of the object identified by its
- * ClassId.
- */
- template <typename T1, typename T2>
- static NsUnknown *Create (ClassId classId, T1 a1, T2 a2);
-
- /**
- * \param classId class id of the constructor to invoke.
- * \param iid interface id to query for
- * \return a pointer to the instance created.
- * \overload NsUnknown *Create (ClassId)
- *
- * Create an instance of the object identified by its
- * ClassId, call QueryInterface on it, and return the
- * result.
- */
- template <typename T>
- static T *Create (ClassId classId, Iid iid);
-
- template <typename T, typename T1>
- static T *Create (ClassId classId, Iid iid, T1 a1);
-
- template <typename T, typename T1, typename T2>
- static T *Create (ClassId classId, Iid iid, T1 a1, T2 a2);
-
- /**
- * \param name the symbolic name to associate to this
- * constructor
- * \returns a ClassId which uniquely identifies this constructor.
- */
- template <typename T>
- static ClassId RegisterConstructor (std::string name)
- {
- static Callback<NsUnknown *> callback =
- MakeCallback (&NsUnknownManager::MakeObjectZero<T>);
- return NsUnknownManager::Register (name, &callback);
- }
-
- /**
- * \param name the symbolic name to associate to this
- * constructor
- * \returns a ClassId which uniquely identifies this constructor.
- * \overload ClassId RegisterConstructor (std::string)
- */
- template <typename T, typename T1>
- static ClassId RegisterConstructor (std::string name)
- {
- static Callback<NsUnknown *,T1> callback = MakeCallback (&NsUnknownManager::MakeObjectOne<T,T1>);
- return NsUnknownManager::Register (name, &callback);
- }
-
- /**
- * \param name the symbolic name to associate to this
- * constructor
- * \returns a ClassId which uniquely identifies this constructor.
- * \overload ClassId RegisterConstructor (std::string)
- */
- template <typename T, typename T1, typename T2>
- static ClassId RegisterConstructor (std::string name)
- {
- static Callback<NsUnknown *,T1,T2> callback = MakeCallback (&NsUnknownManager::MakeObjectTwo<T,T1,T2>);
- return NsUnknownManager::Register (name, &callback);
- }
-private:
- static ClassId Register (std::string name, CallbackBase *callback);
-
- template <typename T1, typename T2,
- typename T3, typename T4,
- typename T5>
- static Callback<NsUnknown *,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
-
- template <typename T>
- static NsUnknown *MakeObjectZero (void);
-
- template <typename T, typename T1>
- static NsUnknown *MakeObjectOne (T1 a1);
-
- template <typename T, typename T1, typename T2>
- static NsUnknown *MakeObjectTwo (T1 a1, T2 a2);
-
- typedef std::vector<std::pair<ClassId, CallbackBase *> > List;
- static List *GetList (void);
- static CallbackBase *Lookup (ClassId classId);
-};
-
-} // namespace ns3
-
-
-namespace ns3 {
-
-template <typename T1, typename T2,
- typename T3, typename T4,
- typename T5>
-Callback<NsUnknown *,T1,T2,T3,T4,T5>
-NsUnknownManager::DoGetCallback (ClassId classId)
-{
- CallbackBase *callback = Lookup (classId);
- if (callback == 0)
- {
- NS_FATAL_ERROR ("Invalid Class Id.");
- }
- Callback<NsUnknown *, T1,T2,T3,T4,T5> reference;
- reference.Assign (*callback);
- return reference;
-}
-
-
-template <typename T1>
-NsUnknown *
-NsUnknownManager::Create (ClassId classId, T1 a1)
-{
- Callback<NsUnknown *, T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
- return callback (a1);
-}
-
-template <typename T1, typename T2>
-NsUnknown *
-NsUnknownManager::Create (ClassId classId, T1 a1, T2 a2)
-{
- Callback<NsUnknown *, T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
- return callback (a1, a2);
-}
-
-template <typename T>
-T *
-NsUnknownManager::Create (ClassId classId, Iid iid)
-{
- NsUnknown *obj = Create (classId);
- T *i = obj->QueryInterface<T> (iid);
- obj->Unref ();
- return i;
-}
-
-template <typename T, typename T1>
-T *
-NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1)
-{
- NsUnknown *obj = Create (classId, a1);
- T *i = obj->QueryInterface<T> (iid);
- obj->Unref ();
- return i;
-}
-
-template <typename T, typename T1, typename T2>
-T *
-NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1, T2 a2)
-{
- NsUnknown *obj = Create (classId, a1, a2);
- T *i = obj->QueryInterface<T> (iid);
- obj->Unref ();
- return i;
-}
-
-
-template <typename T>
-NsUnknown *
-NsUnknownManager::MakeObjectZero (void)
-{
- return new T ();
-}
-template <typename T, typename T1>
-NsUnknown *
-NsUnknownManager::MakeObjectOne (T1 a1)
-{
- return new T (a1);
-}
-template <typename T, typename T1, typename T2>
-NsUnknown *
-NsUnknownManager::MakeObjectTwo (T1 a1, T2 a2)
-{
- return new T (a1, a2);
-}
-
-} // namespace ns3
-
-#endif /* NS_UNKNOWN_MANAGER_H */
--- a/src/core/ns-unknown.cc Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,387 +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 "ns-unknown.h"
-#include "singleton.h"
-#include "uid-manager.h"
-#include <string>
-#include <list>
-#include <stdint.h>
-#include "assert.h"
-
-namespace ns3 {
-
-class IidManager : public UidManager
-{};
-
-Iid::Iid (std::string name)
- : m_iid (Singleton<IidManager>::Get ()->Allocate (name))
-{}
-
-bool operator == (const Iid &a, const Iid &b)
-{
- return a.m_iid == b.m_iid;
-}
-
-
-class NsUnknownImpl
-{
-public:
- NsUnknownImpl (Iid iid, NsUnknown *interface);
- ~NsUnknownImpl ();
- void Ref (void);
- void RefAll (NsUnknownImpl *other);
- void Unref (void);
- void UnrefAll (void);
- NsUnknown *DoQueryInterface (Iid iid) const;
- void DoDisposeAll (void);
- void AddInterface (NsUnknown *interface);
- void AddSelfInterface (Iid iid, NsUnknown *interface);
-private:
- typedef std::list<std::pair<Iid,NsUnknown *> > List;
- uint32_t m_ref;
- List m_list;
- bool m_disposed;
-};
-
-NsUnknownImpl::NsUnknownImpl (Iid iid, NsUnknown *interface)
- : m_ref (1),
- m_disposed (false)
-{
- m_list.push_back (std::make_pair (iid, interface));
-}
-NsUnknownImpl::~NsUnknownImpl ()
-{
- for (List::const_iterator i = m_list.begin ();
- i != m_list.end (); i++)
- {
- i->second->UnrefInternal ();
- }
- m_list.clear ();
-}
-void
-NsUnknownImpl::Ref (void)
-{
- m_ref++;
-}
-void
-NsUnknownImpl::RefAll (NsUnknownImpl *other)
-{
- m_ref += other->m_ref;
-}
-void
-NsUnknownImpl::Unref (void)
-{
- m_ref--;
- if (m_ref == 0)
- {
- delete this;
- }
-}
-void
-NsUnknownImpl::UnrefAll (void)
-{
- m_ref = 0;
- delete this;
-}
-void
-NsUnknownImpl::DoDisposeAll (void)
-{
- NS_ASSERT (!m_disposed);
- for (List::const_iterator i = m_list.begin ();
- i != m_list.end (); i++)
- {
- NsUnknown *interface = i->second;
- interface->DoDispose ();
- }
- m_disposed = true;
-}
-NsUnknown *
-NsUnknownImpl::DoQueryInterface (Iid iid) const
-{
- for (List::const_iterator i = m_list.begin ();
- i != m_list.end (); i++)
- {
- if (i->first == iid)
- {
- i->second->Ref ();
- return i->second;
- }
- }
- return 0;
-}
-void
-NsUnknownImpl::AddInterface (NsUnknown *interface)
-{
- for (List::const_iterator i = interface->m_impl->m_list.begin ();
- i != interface->m_impl->m_list.end (); i++)
- {
- // XXX here, we should check that we have only one
- // instance of each interface
- i->second->RefInternal ();
- m_list.push_back (std::make_pair (i->first, i->second));
- }
-}
-void
-NsUnknownImpl::AddSelfInterface (Iid iid, NsUnknown *interface)
-{
- interface->RefInternal ();
- m_list.push_back (std::make_pair (iid, interface));
-}
-
-
-NsUnknown::NsUnknown (Iid iid)
- : m_impl (new NsUnknownImpl (iid, this)),
- m_ref (1)
-{}
-NsUnknown::~NsUnknown ()
-{
- m_impl = 0;
-}
-void
-NsUnknown::Ref (void)
-{
- m_impl->Ref ();
-}
-void
-NsUnknown::Unref (void)
-{
- m_impl->Unref ();
-}
-
-void
-NsUnknown::Dispose (void)
-{
- m_impl->DoDisposeAll ();
-}
-
-void
-NsUnknown::DoDispose (void)
-{
- // we do not do anything by default.
-}
-
-void
-NsUnknown::RefInternal (void)
-{
- m_ref++;
-}
-
-void
-NsUnknown::UnrefInternal (void)
-{
- NS_ASSERT (m_ref != 0);
- m_ref--;
- if (m_ref == 0)
- {
- delete this;
- }
-}
-
-NsUnknown *
-NsUnknown::DoQueryInterface (Iid iid) const
-{
- return m_impl->DoQueryInterface (iid);
-}
-
-void
-NsUnknown::AddInterface (NsUnknown *interface)
-{
- m_impl->AddInterface (interface);
- m_impl->RefAll (interface->m_impl);
- interface->m_impl->UnrefAll ();
- interface->m_impl = m_impl;
-}
-
-void
-NsUnknown::AddSelfInterface (Iid iid, NsUnknown *interface)
-{
- m_impl->AddSelfInterface (iid, interface);
-}
-
-
-}//namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "test.h"
-
-namespace {
-
-class A : public ns3::NsUnknown
-{
-public:
- static const ns3::Iid iid;
- A ()
- : NsUnknown (A::iid)
- {}
-};
-class B : public ns3::NsUnknown
-{
-public:
- static const ns3::Iid iid;
- B ()
- : NsUnknown (B::iid)
- {}
-};
-class BaseA : public ns3::NsUnknown
-{
-public:
- static const ns3::Iid iid;
- BaseA ()
- : NsUnknown (BaseA::iid)
- {}
-};
-class BaseB : public ns3::NsUnknown
-{
-public:
- static const ns3::Iid iid;
- BaseB ()
- : NsUnknown (BaseB::iid)
- {}
-};
-class Base : public ns3::NsUnknown
-{
-public:
- static const ns3::Iid iid;
- Base ()
- : NsUnknown (Base::iid)
- {}
-};
-class Derived : public Base
-{
-public:
- static const ns3::Iid iid;
- Derived ()
- {
- AddSelfInterface (Derived::iid, this);
- }
-};
-
-const ns3::Iid A::iid ("A");
-const ns3::Iid B::iid ("B");
-const ns3::Iid BaseA::iid ("BaseA");
-const ns3::Iid BaseB::iid ("BaseB");
-const ns3::Iid Base::iid ("Base");
-const ns3::Iid Derived::iid ("Derived");
-
-}//namespace
-
-
-namespace ns3 {
-
-class InterfaceTest : public Test
-{
-public:
- InterfaceTest ();
- virtual bool RunTests (void);
-};
-
-InterfaceTest::InterfaceTest ()
- : Test ("NsUnknown")
-{}
-bool
-InterfaceTest::RunTests (void)
-{
- bool ok = true;
-
- //DerivedAB *derivedAB;
-
-
- A *a = new A ();
- a->Unref ();
-
- a = new A ();
- A *a1 = a->QueryInterface<A> (A::iid);
- if (a1 == 0 || a1 != a)
- {
- ok = false;
- }
- a1->Unref ();
- a1 = a->QueryInterface<A> (A::iid);
- if (a1 == 0 || a1 != a)
- {
- ok = false;
- }
- a1->Unref ();
- a->Unref ();
-
- B *b = new B ();
- B *b1 = b->QueryInterface<B> (B::iid);
- if (b1 == 0 || b1 != b)
- {
- ok = false;
- }
- b1->Unref ();
-
- a = new A ();
- a->AddInterface (b);
- b1 = b->QueryInterface<B> (B::iid);
- if (b1 == 0 || b1 != b)
- {
- ok = false;
- }
- b1->Unref ();
- a1 = b->QueryInterface<A> (A::iid);
- if (a1 == 0 || a1 != a)
- {
- ok = false;
- }
- a1->Unref ();
- a1 = a->QueryInterface<A> (A::iid);
- if (a1 == 0 || a1 != a)
- {
- ok = false;
- }
- a1->Unref ();
- b1 = a->QueryInterface<B> (B::iid);
- if (b1 == 0 || b1 != b)
- {
- ok = false;
- }
- b1->Unref ();
-
- a->Unref ();
- b->Unref ();
-
- Derived *derived = new Derived ();
- Base *base = derived->QueryInterface<Base> (Base::iid);
- if (base == 0)
- {
- ok = false;
- }
- Derived *derived1 = base->QueryInterface<Derived> (Derived::iid);
- if (derived1 == 0 || derived1 != derived)
- {
- ok = false;
- }
- derived1->Unref ();
- base->Unref ();
- derived->Unref ();
-
- return ok;
-}
-
-
-static InterfaceTest g_interface_test;
-
-}// namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/core/ns-unknown.h Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +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 INTERFACE_H
-#define INTERFACE_H
-
-#include <string>
-
-
-namespace ns3 {
-
-class NsUnknownImpl;
-
-class Iid
-{
-public:
- Iid (std::string name);
-private:
- friend bool operator == (const Iid &a, const Iid &b);
- uint32_t m_iid;
-};
-
-/**
- * \brief COM-like IUnknown
- *
- * This class should be used as a base class for every object which
- * wishes to provide a COM-like QueryInterface API. Multiple
- * inheritance where this base class is at the top of the dreaded
- * "diamond" shape is not allowed.
- */
-class NsUnknown
-{
-public:
- virtual ~NsUnknown ();
- void Ref (void);
- void Unref (void);
-
- /**
- * \param iid the NsUnknown id of the requested interface
- */
- template <typename T>
- T *QueryInterface (Iid iid) const;
-
- /**
- * \param interface another interface
- *
- * Aggregate together the two interfaces. After this call,
- * the two interface objects are tied together: each of them
- * will be able to perform QI on each other and their lifetimes
- * will be found by the same reference count.
- */
- void AddInterface (NsUnknown *interface);
-
- void Dispose (void);
-protected:
- /**
- * \param iid the Interface Id of the interface defined by a direct subclass
- * of this base class
- *
- * If you are a direct subclass of this class, you _must_ register
- * the name of your interface with this constructor.
- */
- NsUnknown (Iid iid);
- /**
- * \param iid the Interface id of the interface
- * \param a pointer to the interface object
- *
- * If you are not a direct subclass of the ns3::NsUnknown base class,
- * and if you want to register yourself as another accessible interface
- * (typically, your subclass has added API), you need to call
- * this method to associate an interface id to your interface.
- */
- void AddSelfInterface (Iid iid, NsUnknown *interface);
-protected:
- /**
- * Subclasses who want to handle the "dispose" event should
- * override this method. They are also responsible for
- * "chaining up" to their parent class' DoDispose method
- * once they have done their own "dispose".
- */
- virtual void DoDispose (void);
-private:
- friend class NsUnknownImpl;
- NsUnknown ();
- NsUnknown *DoQueryInterface (Iid iid) const;
- void RefInternal (void);
- void UnrefInternal (void);
- NsUnknownImpl *m_impl;
- uint32_t m_ref;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-T *
-NsUnknown::QueryInterface (Iid iid) const
-{
- NsUnknown *found = DoQueryInterface (iid);
- if (found != 0)
- {
- return dynamic_cast<T *> (found);
- }
- return 0;
-}
-
-
-}//namespace ns3
-
-#endif /* INTERFACE_H */
--- a/src/core/object.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/core/object.cc Sun May 13 12:52:38 2007 +0100
@@ -29,7 +29,9 @@
Object::Object ()
: m_count (1),
m_disposed (false)
-{}
+{
+ NS_DEBUG ("Object::Object: m_count=0");
+}
Object::~Object ()
{}
@@ -37,17 +39,16 @@
void
Object::Ref (void) const
{
- NS_DEBUG("Object::Ref (): this == 0x" << this);
m_count++;
- NS_DEBUG("Object::Ref (): m_count bumped to " << m_count);
+ NS_DEBUG("Object::Ref (): this == 0x" << this << " m_count=" << m_count);
}
void
Object::Unref (void) const
{
- NS_DEBUG("Object::Unref (): this == 0x" << this);
+ NS_ASSERT (m_count > 0);
m_count--;
- NS_DEBUG("Object::Ref (): m_count dropped to " << m_count);
+ NS_DEBUG("Object::Unref (): this == 0x" << this << " m_count=" << m_count);
if (m_count == 0)
{
--- a/src/core/ptr.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/core/ptr.cc Sun May 13 12:52:38 2007 +0100
@@ -24,10 +24,11 @@
#include "test.h"
#include "callback.h"
+#include "object.h"
namespace ns3 {
-class NoCount
+class NoCount : public Object
{
public:
NoCount (Callback<void> cb);
@@ -92,7 +93,7 @@
Callback<void> cb = MakeCallback (&PtrTest::DestroyNotify, this);
m_nDestroyed = false;
{
- Ptr<NoCount> p = new NoCount (cb);
+ Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
}
if (m_nDestroyed != 1)
{
@@ -102,7 +103,7 @@
m_nDestroyed = 0;
{
Ptr<NoCount> p;
- p = new NoCount (cb);
+ p = MakeNewObject<NoCount> (cb);
p = p;
}
if (m_nDestroyed != 1)
@@ -113,7 +114,7 @@
m_nDestroyed = 0;
{
Ptr<NoCount> p1;
- p1 = new NoCount (cb);
+ p1 = MakeNewObject<NoCount> (cb);
Ptr<NoCount> p2 = p1;
}
if (m_nDestroyed != 1)
@@ -124,7 +125,7 @@
m_nDestroyed = 0;
{
Ptr<NoCount> p1;
- p1 = new NoCount (cb);
+ p1 = MakeNewObject<NoCount> (cb);
Ptr<NoCount> p2;
p2 = p1;
}
@@ -136,8 +137,8 @@
m_nDestroyed = 0;
{
Ptr<NoCount> p1;
- p1 = new NoCount (cb);
- Ptr<NoCount> p2 = new NoCount (cb);
+ p1 = MakeNewObject<NoCount> (cb);
+ Ptr<NoCount> p2 = MakeNewObject<NoCount> (cb);
p2 = p1;
}
if (m_nDestroyed != 2)
@@ -148,9 +149,9 @@
m_nDestroyed = 0;
{
Ptr<NoCount> p1;
- p1 = new NoCount (cb);
+ p1 = MakeNewObject<NoCount> (cb);
Ptr<NoCount> p2;
- p2 = new NoCount (cb);
+ p2 = MakeNewObject<NoCount> (cb);
p2 = p1;
}
if (m_nDestroyed != 2)
@@ -161,8 +162,8 @@
m_nDestroyed = 0;
{
Ptr<NoCount> p1;
- p1 = new NoCount (cb);
- p1 = new NoCount (cb);
+ p1 = MakeNewObject<NoCount> (cb);
+ p1 = MakeNewObject<NoCount> (cb);
}
if (m_nDestroyed != 2)
{
@@ -174,8 +175,8 @@
Ptr<NoCount> p1;
{
Ptr<NoCount> p2;
- p1 = new NoCount (cb);
- p2 = new NoCount (cb);
+ p1 = MakeNewObject<NoCount> (cb);
+ p2 = MakeNewObject<NoCount> (cb);
p2 = p1;
}
if (m_nDestroyed != 1)
@@ -193,8 +194,8 @@
Ptr<NoCount> p1;
{
Ptr<NoCount> p2;
- p1 = new NoCount (cb);
- p2 = new NoCount (cb);
+ p1 = MakeNewObject<NoCount> (cb);
+ p2 = MakeNewObject<NoCount> (cb);
p2 = CallTest (p1);
}
if (m_nDestroyed != 1)
@@ -236,11 +237,12 @@
{
NoCount *raw;
{
- Ptr<NoCount> p = new NoCount (cb);
+ Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
{
Ptr<NoCount const> p1 = p;
}
- raw = p.Remove ();
+ raw = GetPointer (p);
+ p = 0;
}
if (m_nDestroyed != 0)
{
@@ -252,16 +254,32 @@
m_nDestroyed = 0;
{
- Ptr<NoCount> p = new NoCount (cb);
- NoCount const&v1 = *p;
- NoCount v2 = *p;
- v1.Nothing ();
- v2.Nothing ();
+ Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
+ const NoCount *v1 = PeekPointer (p);
+ NoCount *v2 = PeekPointer (p);
+ v1->Nothing ();
+ v2->Nothing ();
}
- if (m_nDestroyed != 2)
+ if (m_nDestroyed != 1)
{
ok = false;
}
+
+ {
+ Ptr<Object> p0 = MakeNewObject<NoCount> (cb);
+ Ptr<NoCount> p1 = MakeNewObject<NoCount> (cb);
+ if (p0 == p1)
+ {
+ ok = false;
+ }
+ if (p0 != p1)
+ {
+ }
+ else
+ {
+ ok = false;
+ }
+ }
return ok;
--- a/src/core/ptr.h Sun May 13 12:46:18 2007 +0100
+++ b/src/core/ptr.h Sun May 13 12:52:38 2007 +0100
@@ -28,32 +28,43 @@
namespace ns3 {
/**
- * \brief smart pointer class similar to boost::shared_ptr
+ * \brief smart pointer class similar to boost::intrusive_ptr
*
- * This smart-pointer class is supposed to be used to manage
- * heap-allocated objects: when it decides it does not need
- * the object it references, it invokes operator delete on it.
+ * This smart-pointer class assumes that the underlying
+ * type provides a pair of Ref and Unref methods which are
+ * expected to increment and decrement the internal refcount
+ * of the object instance.
+ *
* This implementation allows you to manipulate the smart pointer
* as if it was a normal pointer: you can compare it with zero,
- * compare it against other pointers, etc. However, the only
- * operation we are careful to avoid is the conversion back to
- * raw pointers: if you need to convert back, you need to invoke
- * the Ptr<T>::Remove method which returns a raw pointer and
- * makes the smart pointer forget about the raw pointer.
+ * compare it against other pointers, assign zero to it, etc.
+ *
+ * It is possible to extract the raw pointer from this
+ * smart pointer with the GetPointer and PeekPointer methods.
+ *
+ * If you want to store a newed object into a smart pointer,
+ * we recommend you to use the MakeNewObject template functions
+ * to create the object and store it in a smart pointer to avoid
+ * memory leaks. These functions are really small conveniance
+ * functions and their goal is just is save you a small
+ * bit of typing.
*/
template <typename T>
class Ptr
{
private:
T *m_ptr;
- uint32_t *m_count;
class Tester {
private:
void operator delete (void *);
};
- static uint32_t *AllocCount (void);
- static void DeallocCount (uint32_t *count);
friend class Ptr<const T>;
+ template <typename U>
+ friend U *GetPointer (const Ptr<U> &p);
+ template <typename U>
+ friend U *PeekPointer (const Ptr<U> &p);
+
+ void Acquire (void) const;
public:
/**
* Create an empty smart pointer
@@ -75,100 +86,271 @@
Ptr (Ptr<U> const &o);
~Ptr () ;
Ptr<T> &operator = (Ptr const& o);
- T const& operator * () const;
+
T *operator -> () const;
T *operator -> ();
// allow if (!sp)
bool operator! ();
// allow if (sp)
+ // disable delete sp
operator Tester * () const;
- // allow if (sp == 0)
- template <typename T1, typename T2>
- inline friend bool operator == (Ptr<T1> const &lhs, T2 const *rhs);
- // allow if (0 == sp)
- template <typename T1, typename T2>
- inline friend bool operator == (T1 const *lhs, Ptr<T2> &rhs);
- // allow if (sp != 0)
- template <typename T1, typename T2>
- inline friend bool operator != (Ptr<T1> const &lhs, T2 const *rhs);
- // allow if (0 != sp)
- template <typename T1, typename T2>
- inline friend bool operator != (T1 const *lhs, Ptr<T2> &rhs);
-
- template <typename T1, typename T2>
- inline friend Ptr<T1> const_pointer_cast (Ptr<T2> const&p);
-
-
- /**
- * \returns raw pointer
- *
- * It is a programming error to invoke this method when
- * the reference count of the smart pointer is not one.
- * If you try to do it anyway, an assert will be triggered.
- * If asserts are disabled, bad things will happen.
- * Once you have successfully called Ptr<T>::Remove on
- * a smart pointer, the smart pointer will forget
- * about the raw pointer and will stop managing it. As such,
- * you, as the caller, become responsible for invoking
- * operator delete on the returned raw pointer.
- */
- T *Remove (void);
};
template <typename T>
-uint32_t *
-Ptr<T>::AllocCount (void)
+Ptr<T> MakeNewObject (void);
+
+template <typename T, typename T1>
+Ptr<T> MakeNewObject (T1 a1);
+
+template <typename T, typename T1, typename T2>
+Ptr<T> MakeNewObject (T1 a1, T2 a2);
+
+template <typename T, typename T1, typename T2, typename T3>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3);
+
+template <typename T, typename T1, typename T2, typename T3, typename T4>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4);
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
+
+/**
+ * \return the pointer managed by this smart pointer.
+ *
+ * The underlying refcount is not incremented prior
+ * to returning to the caller so the caller is not
+ * responsible for calling Unref himself.
+ */
+template <typename T>
+T * PeekPointer (const Ptr<T> &p);
+
+/**
+ * \return the pointer managed by this smart pointer.
+ *
+ * The underlying refcount is incremented prior
+ * to returning to the caller so the caller is
+ * responsible for calling Unref himself.
+ */
+template <typename T>
+T * GetPointer (const Ptr<T> &p);
+
+
+// allow if (sp == 0)
+template <typename T1, typename T2>
+bool operator == (Ptr<T1> const &lhs, T2 const *rhs);
+
+// allow if (0 == sp)
+template <typename T1, typename T2>
+bool operator == (T1 const *lhs, Ptr<T2> &rhs);
+
+// allow if (sp != 0)
+template <typename T1, typename T2>
+bool operator != (Ptr<T1> const &lhs, T2 const *rhs);
+
+// allow if (0 != sp)
+template <typename T1, typename T2>
+bool operator != (T1 const *lhs, Ptr<T2> &rhs);
+
+// allow if (sp0 == sp1)
+template <typename T1, typename T2>
+bool operator == (Ptr<T1> const &lhs, Ptr<T2> const &rhs);
+
+// allow if (sp0 != sp1)
+template <typename T1, typename T2>
+bool operator != (Ptr<T1> const &lhs, Ptr<T2> const &rhs);
+
+template <typename T1, typename T2>
+Ptr<T1> const_pointer_cast (Ptr<T2> const&p);
+
+} // namespace ns3
+
+
+namespace ns3 {
+
+ /*************************************************
+ * friend non-member function implementations
+ ************************************************/
+
+template <typename T>
+Ptr<T> MakeNewObject (void)
+{
+ T *obj = new T ();
+ Ptr<T> p = obj;
+ obj->Unref ();
+ return p;
+}
+
+template <typename T, typename T1>
+Ptr<T> MakeNewObject (T1 a1)
+{
+ T *obj = new T (a1);
+ Ptr<T> p = obj;
+ obj->Unref ();
+ return p;
+}
+
+template <typename T, typename T1, typename T2>
+Ptr<T> MakeNewObject (T1 a1, T2 a2)
+{
+ T *obj = new T (a1, a2);
+ Ptr<T> p = obj;
+ obj->Unref ();
+ return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3)
{
- return new uint32_t [1] ();
+ T *obj = new T (a1, a2, a3);
+ Ptr<T> p = obj;
+ obj->Unref ();
+ return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4)
+{
+ T *obj = new T (a1, a2, a3, a4);
+ Ptr<T> p = obj;
+ obj->Unref ();
+ return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+{
+ T *obj = new T (a1, a2, a3, a4, a5);
+ Ptr<T> p = obj;
+ obj->Unref ();
+ return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
+{
+ T *obj = new T (a1, a2, a3, a4, a5, a6);
+ Ptr<T> p = obj;
+ obj->Unref ();
+ return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
+{
+ T *obj = new T (a1, a2, a3, a4, a5, a6, a7);
+ Ptr<T> p = obj;
+ obj->Unref ();
+ return p;
+}
+
+template <typename T>
+T * PeekPointer (const Ptr<T> &p)
+{
+ return p.m_ptr;
+}
+
+template <typename T>
+T * GetPointer (const Ptr<T> &p)
+{
+ p.Acquire ();
+ return p.m_ptr;
}
+
+template <typename T1, typename T2>
+bool
+operator == (Ptr<T1> const &lhs, T2 const *rhs)
+{
+ return PeekPointer (lhs) == rhs;
+}
+
+template <typename T1, typename T2>
+bool
+operator == (T1 const *lhs, Ptr<T2> &rhs)
+{
+ return lhs == PeekPointer (rhs);
+}
+
+template <typename T1, typename T2>
+bool
+operator != (Ptr<T1> const &lhs, T2 const *rhs)
+{
+ return PeekPointer (lhs) != rhs;
+}
+
+template <typename T1, typename T2>
+bool
+operator != (T1 const *lhs, Ptr<T2> &rhs)
+{
+ return lhs != PeekPointer (rhs);
+}
+
+template <typename T1, typename T2>
+bool
+operator == (Ptr<T1> const &lhs, Ptr<T2> const &rhs)
+{
+ return PeekPointer (lhs) == PeekPointer (rhs);
+}
+
+template <typename T1, typename T2>
+bool
+operator != (Ptr<T1> const &lhs, Ptr<T2> const &rhs)
+{
+ return PeekPointer (lhs) != PeekPointer (rhs);
+}
+
+
+template <typename T1, typename T2>
+Ptr<T1>
+const_pointer_cast (Ptr<T2> const&p)
+{
+ return Ptr<T1> (const_cast<T1 *> (PeekPointer (p)));
+}
+
+
+/****************************************************
+ * Member method implementations.
+ ***************************************************/
+
template <typename T>
void
-Ptr<T>::DeallocCount (uint32_t *count)
+Ptr<T>::Acquire (void) const
{
- delete [] count;
+ if (m_ptr != 0)
+ {
+ m_ptr->Ref ();
+ }
}
template <typename T>
Ptr<T>::Ptr ()
- : m_ptr (0),
- m_count (0)
+ : m_ptr (0)
{}
template <typename T>
Ptr<T>::Ptr (T *ptr)
- : m_ptr (ptr),
- m_count (0)
+ : m_ptr (ptr)
{
- if (m_ptr != 0)
- {
- m_count = Ptr::AllocCount ();
- *m_count = 1;
- }
+ Acquire ();
}
template <typename T>
Ptr<T>::Ptr (Ptr const&o)
- : m_ptr (o.m_ptr),
- m_count (0)
+ : m_ptr (PeekPointer (o))
{
- if (m_ptr != 0)
- {
- m_count = o.m_count;
- (*m_count)++;
- }
+ Acquire ();
}
template <typename T>
template <typename U>
Ptr<T>::Ptr (Ptr<U> const &o)
- : m_ptr (o.m_ptr),
- m_count (0)
+ : m_ptr (PeekPointer (o))
{
- if (m_ptr != 0)
- {
- NS_ASSERT (o.m_ptr != 0);
- m_count = o.m_count;
- (*m_count)++;
- }
+ Acquire ();
}
template <typename T>
@@ -176,12 +358,7 @@
{
if (m_ptr != 0)
{
- (*m_count)--;
- if ((*m_count) == 0)
- {
- delete m_ptr;
- Ptr::DeallocCount (m_count);
- }
+ m_ptr->Unref();
}
}
@@ -190,33 +367,19 @@
Ptr<T>::operator = (Ptr const& o)
{
if (&o == this)
- return *this;
+ {
+ return *this;
+ }
if (m_ptr != 0)
{
- (*m_count)--;
- if ((*m_count) == 0)
- {
- delete m_ptr;
- Ptr::DeallocCount (m_count);
- }
+ m_ptr->Unref();
}
m_ptr = o.m_ptr;
- if (m_ptr != 0)
- {
- m_count = o.m_count;
- (*m_count)++;
- }
+ Acquire ();
return *this;
}
template <typename T>
-T const&
-Ptr<T>::operator * () const
-{
- return *m_ptr;
-}
-
-template <typename T>
T *
Ptr<T>::operator -> ()
{
@@ -248,57 +411,6 @@
return &test;
}
-template <typename T>
-T *
-Ptr<T>::Remove (void)
-{
- if (m_ptr == 0)
- {
- return (T *) 0;
- }
- else
- {
- NS_ASSERT ((*m_count) == 1);
- Ptr::DeallocCount (m_count);
- T *retval = m_ptr;
- m_ptr = 0;
- return retval;
- }
-}
-
-// non-member friend functions.
-template <typename T1, typename T2>
-bool
-operator == (Ptr<T1> const &lhs, T2 const *rhs)
-{
- return lhs.m_ptr == rhs;
-}
-template <typename T1, typename T2>
-bool
-operator == (T1 const *lhs, Ptr<T2> &rhs)
-{
- return lhs == rhs.m_ptr;
-}
-template <typename T1, typename T2>
-bool
-operator != (Ptr<T1> const &lhs, T2 const *rhs)
-{
- return lhs.m_ptr != rhs;
-}
-template <typename T1, typename T2>
-bool
-operator != (T1 const *lhs, Ptr<T2> &rhs)
-{
- return lhs != rhs.m_ptr;
-}
-
-template <typename T1, typename T2>
-Ptr<T1>
-const_pointer_cast (Ptr<T2> const&p)
-{
- return Ptr<T1> (const_cast<T1 *> (p.m_ptr));
-}
-
}; // namespace ns3
--- a/src/core/random-variable.h Sun May 13 12:46:18 2007 +0100
+++ b/src/core/random-variable.h Sun May 13 12:52:38 2007 +0100
@@ -200,6 +200,7 @@
* UniformVariable x(0,10);
* x.GetValue(); //will always return numbers [0,10]
* UniformVariable::GetSingleValue(100,1000); //returns a value [100,1000]
+ * \endcode
*/
class UniformVariable : public RandomVariable {
public:
--- a/src/core/uid-manager.h Sun May 13 12:46:18 2007 +0100
+++ b/src/core/uid-manager.h Sun May 13 12:52:38 2007 +0100
@@ -27,6 +27,9 @@
namespace ns3 {
+/**
+ * zero is never a valid uid value.
+ */
class UidManager
{
public:
--- a/src/core/wscript Sun May 13 12:46:18 2007 +0100
+++ b/src/core/wscript Sun May 13 12:52:38 2007 +0100
@@ -33,12 +33,12 @@
'test.cc',
'random-variable.cc',
'rng-stream.cc',
- 'ns-unknown.cc',
+ 'interface.cc',
'uid-manager.cc',
'default-value.cc',
'command-line.cc',
'type-name.cc',
- 'ns-unknown-manager.cc',
+ 'component-manager.cc',
]
if sys.platform == 'win32':
@@ -63,10 +63,10 @@
'test.h',
'random-variable.h',
'rng-stream.h',
- 'ns-unknown.h',
+ 'interface.h',
'default-value.h',
'command-line.h',
'type-name.h',
- 'ns-unknown-manager.h',
+ 'component-manager.h',
]
--- a/src/devices/p2p-gfr/p2p-channel.cc Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Implementation of simple point-to-point channel
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "ns3/simulator.h"
-#include "ns3/packet.h"
-#include "ns3/node.h"
-#include "p2p-channel.h"
-#include "p2p-net-device.h"
-
-namespace ns3 {
-
-P2PChannel::P2PChannel(const Time& delay, double maxRate)
- : m_nd1(0), m_nd2(0),
- m_delay (delay),
- m_maxRate (maxRate)
-{
-}
-
-P2PChannel::~P2PChannel ()
-{}
-
-// Channels create compatible net devices
-P2PNetDevice* P2PChannel::CreateNetDevice(Node *node, MacAddress address)
-{
- // Create a new point-to-point network device
- P2PNetDevice* nd = new P2PNetDevice(node, address);
- nd->Connect (this);
- // Add to list of peers
- if (!m_nd1) m_nd1 = nd;
- else m_nd2 = nd;
- return nd;
-}
-
-void P2PChannel::RemoveNetDevice(NetDevice* nd)
-{
- if (nd == m_nd1) m_nd1 = 0;
- if (nd == m_nd2) m_nd2 = 0;
- // Now if all removed, remove the channel as well
- if (!m_nd1 && !m_nd2)
- {
- delete this;
- }
-}
-
-void P2PChannel::Send(P2PNetDevice *device, Packet& p, double rate)
-{ // Schedule a receive event at receiver
- // First calculate time in future
- double maxRate;
- if (rate < m_maxRate)
- {
- maxRate = rate;
- }
- else
- {
- maxRate = m_maxRate;
- }
- Time txTime = Seconds (p.GetSize() * 8 / maxRate);
- Time rxTime = m_delay + txTime;
- P2PNetDevice *to, *from;
- if (device == m_nd1)
- {
- from = m_nd1;
- to = m_nd2;
- }
- else
- {
- from = m_nd2;
- to = m_nd1;
- }
- // Schedule the receive event at receiver
- Simulator::Schedule(rxTime, &P2PNetDevice::Receive, to, p);
- // Schedule the link free event
- Simulator::Schedule(txTime, &P2PNetDevice::TxComplete, from);
-
-}
-
-}//namespace ns3
--- a/src/devices/p2p-gfr/p2p-channel.h Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Definition of a simple point-to-point channel
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef P2P_CHANNEL_H
-#define P2P_CHANNEL_H
-
-#include "ns3/nstime.h"
-#include "ns3/mac-address.h"
-
-namespace ns3 {
-
-class P2PNetDevice;
-class NetDevice;
-class Node;
-class Packet;
-
-class P2PChannel {
-public:
- P2PChannel(const Time& delay, double maxRate /* bits/s */);
- ~P2PChannel();
-
- P2PNetDevice* CreateNetDevice(Node *node, MacAddress address);
- void RemoveNetDevice (NetDevice *device);
- void Send (P2PNetDevice *device, Packet&p, double rate /* bits/s */);
-private:
- // The two endpoints of this channel
- P2PNetDevice* m_nd1;
- P2PNetDevice* m_nd2;
- Time m_delay;
- double m_maxRate;
-};
-
-}//namespace ns3
-
-#endif
--- a/src/devices/p2p-gfr/p2p-net-device.cc Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Implementation of a point-to-point network device
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "ns3/empty-trace-resolver.h"
-#include "p2p-net-device.h"
-#include "p2p-channel.h"
-
-namespace ns3 {
-
-P2PNetDevice::P2PNetDevice (Node *node, MacAddress const &addr)
- : NetDevice (node, addr),
- m_rate (1000000)
-{
- SetMtu (2300);
- EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
-}
-
-P2PNetDevice::~P2PNetDevice()
-{ // Inform channel that we are destroyed
- m_channel->RemoveNetDevice(this);
-}
-
-void
-P2PNetDevice::SetRate (double rate)
-{
- m_rate = rate;
-}
-
-void
-P2PNetDevice::Connect (P2PChannel *channel)
-{
- m_channel = channel;
- NotifyLinkUp ();
-}
-
-bool
-P2PNetDevice::SendTo (Packet& p, const MacAddress&)
-{
- m_channel->Send (this, p, m_rate);
- return true;
-}
-
-TraceResolver *
-P2PNetDevice::DoCreateTraceResolver (TraceContext const &context)
-{
- return new EmptyTraceResolver (context);
-}
-
-void
-P2PNetDevice::Receive(Packet p)
-{
- ForwardUp (p);
-}
-
-void
-P2PNetDevice::TxComplete (void)
-{}
-
-}//namespace ns3
--- a/src/devices/p2p-gfr/p2p-net-device.h Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Definition for a Point-to-Point network device
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef P2P_NET_DEVICE_H
-#define P2P_NET_DEVICE_H
-
-#include "ns3/net-device.h"
-
-namespace ns3 {
-
-class P2PChannel;
-
-class P2PNetDevice : public NetDevice {
-public:
- P2PNetDevice(Node *node, MacAddress const &addr);
- virtual ~P2PNetDevice();
-
- void SetRate (double rate);
- void Connect (P2PChannel *channel);
- void Receive(Packet p);
- void TxComplete (void);
- private:
- virtual bool SendTo (Packet& p, const MacAddress& dest);
- virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
-
- double m_rate;
- P2PChannel *m_channel;
-};
-
-}//namespace ns3
-
-#endif /* P2P_NET_DEVICE_H */
-
--- a/src/devices/p2p-gfr/wscript Sun May 13 12:46:18 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-
-def build(bld):
- p2p = bld.create_obj('cpp', 'objects')
- p2p.name = 'ns3-p2p-gfr'
- p2p.source = [
- 'p2p-net-device.cc',
- 'p2p-channel.cc',
- 'p2p-topology.cc',
- 'p2p-phy.cc',
- 'layer-connector.cc',
- ]
- headers = bld.create_obj('ns3header')
- headers.name = 'ns3-p2p-gfr-headers'
- headers.source = [
- 'p2p-net-device.h',
- 'p2p-channel.h',
- 'p2p-topology.h',
- 'p2p-phy.h',
- 'layer-connector.h',
- ]
-
--- a/src/devices/p2p/p2p-channel.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-channel.cc Sun May 13 12:52:38 2007 +0100
@@ -70,11 +70,11 @@
}
void
-PointToPointChannel::Attach(PointToPointNetDevice *device)
+PointToPointChannel::Attach(Ptr<PointToPointNetDevice> device)
{
NS_DEBUG("PointToPointChannel::Attach (" << device << ")");
NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
- NS_ASSERT(device);
+ NS_ASSERT(device != 0);
m_link[m_nDevices].m_src = device;
++m_nDevices;
@@ -92,7 +92,7 @@
}
bool
-PointToPointChannel::TransmitStart(Packet& p, PointToPointNetDevice* src)
+PointToPointChannel::TransmitStart(Packet& p, Ptr<PointToPointNetDevice> src)
{
NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src <<
")");
@@ -117,7 +117,7 @@
}
bool
-PointToPointChannel::TransmitEnd(Packet& p, PointToPointNetDevice* src)
+PointToPointChannel::TransmitEnd(Packet& p, Ptr<PointToPointNetDevice> src)
{
NS_DEBUG("PointToPointChannel::TransmitEnd (" << &p << ", " << src << ")");
NS_DEBUG ("PointToPointChannel::TransmitEnd (): UID is " <<
@@ -147,7 +147,7 @@
void
PointToPointChannel::PropagationCompleteEvent(
Packet p,
- PointToPointNetDevice *src)
+ Ptr<PointToPointNetDevice> src)
{
NS_DEBUG("PointToPointChannel::PropagationCompleteEvent (" << &p << ", " <<
src << ")");
@@ -169,7 +169,7 @@
return m_nDevices;
}
-NetDevice *
+Ptr<NetDevice>
PointToPointChannel::GetDevice (uint32_t i) const
{
NS_ASSERT(i < 2);
--- a/src/devices/p2p/p2p-channel.h Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-channel.h Sun May 13 12:52:38 2007 +0100
@@ -21,6 +21,7 @@
#include <list>
#include "ns3/channel.h"
+#include "ns3/ptr.h"
#include "ns3/packet.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
@@ -62,13 +63,13 @@
PointToPointChannel (const std::string& name,
const DataRate& bps, const Time& delay);
- void Attach (PointToPointNetDevice* device);
- bool TransmitStart (Packet& p, PointToPointNetDevice *src);
- bool TransmitEnd (Packet &p, PointToPointNetDevice *src);
- void PropagationCompleteEvent(Packet p, PointToPointNetDevice *src);
+ 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 NetDevice *GetDevice (uint32_t i) const;
+ virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
virtual DataRate GetDataRate (void);
virtual Time GetDelay (void);
@@ -92,8 +93,8 @@
public:
Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
WireState m_state;
- PointToPointNetDevice *m_src;
- PointToPointNetDevice *m_dst;
+ Ptr<PointToPointNetDevice> m_src;
+ Ptr<PointToPointNetDevice> m_dst;
};
Link m_link[N_DEVICES];
--- a/src/devices/p2p/p2p-net-device.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-net-device.cc Sun May 13 12:52:38 2007 +0100
@@ -32,7 +32,7 @@
namespace ns3 {
-PointToPointNetDevice::PointToPointNetDevice (Node* node)
+PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node)
:
NetDevice(node, MacAddress ("00:00:00:00:00:00")),
m_txMachineState (READY),
@@ -55,8 +55,6 @@
PointToPointNetDevice::~PointToPointNetDevice()
{
NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()");
-
- delete m_queue;
m_queue = 0;
}
@@ -81,18 +79,12 @@
m_txMachineState(READY),
m_bps (nd.m_bps),
m_tInterframeGap (nd.m_tInterframeGap),
- m_channel(0),
+ m_channel(nd.m_channel),
m_queue(0),
m_rxTrace ()
{
NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << &nd << ")");
- if (nd.m_channel)
- {
- m_channel = nd.m_channel;
- m_channel->Ref ();
- }
-
if (nd.m_queue)
{
m_queue = nd.m_queue;
@@ -102,12 +94,8 @@
void PointToPointNetDevice::DoDispose()
{
- if (m_channel != 0)
- {
- m_channel->Unref ();
- m_channel = 0;
- }
- NetDevice::DoDispose ();
+ m_channel = 0;
+ NetDevice::DoDispose ();
}
//
@@ -296,7 +284,7 @@
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
resolver->Add ("queue",
- MakeCallback (&Queue::CreateTraceResolver, m_queue),
+ MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)),
PointToPointNetDevice::QUEUE);
resolver->Add ("rx",
m_rxTrace,
@@ -305,18 +293,11 @@
}
bool
-PointToPointNetDevice::Attach (PointToPointChannel* ch)
+PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
{
NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")");
- if (m_channel)
- {
- m_channel->Unref ();
- m_channel = 0;
- }
-
m_channel = ch;
- m_channel->Ref ();
m_channel->Attach(this);
m_bps = m_channel->GetDataRate ();
@@ -335,7 +316,7 @@
}
void
-PointToPointNetDevice::AddQueue (Queue* q)
+PointToPointNetDevice::AddQueue (Ptr<Queue> q)
{
NS_DEBUG ("PointToPointNetDevice::AddQueue (" << q << ")");
@@ -352,16 +333,15 @@
ForwardUp (p);
}
-Queue*
+Ptr<Queue>
PointToPointNetDevice::GetQueue(void) const
{
return m_queue;
}
-Channel*
+Ptr<Channel>
PointToPointNetDevice::DoGetChannel(void) const
{
- m_channel->Ref();
return m_channel;
}
--- a/src/devices/p2p/p2p-net-device.h Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-net-device.h Sun May 13 12:52:38 2007 +0100
@@ -30,6 +30,7 @@
#include "ns3/callback-trace-source.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -79,7 +80,7 @@
* @see PointToPointTopology::AddPointToPointLink ()
* @param node the Node to which this device is connected.
*/
- PointToPointNetDevice (Node* node);
+ PointToPointNetDevice (Ptr<Node> node);
/**
* Copy Construct a PointToPointNetDevice
*
@@ -139,7 +140,7 @@
* @see SetInterframeGap ()
* @param ch a pointer to the channel to which this object is being attached.
*/
- bool Attach(PointToPointChannel* ch);
+ bool Attach(Ptr<PointToPointChannel> ch);
/**
* Attach a queue to the PointToPointNetDevice.
*
@@ -154,7 +155,7 @@
* @param queue a pointer to the queue for which object is assuming
* ownership.
*/
- void AddQueue(Queue* queue);
+ void AddQueue(Ptr<Queue> queue);
/**
* Receive a packet from a connected PointToPointChannel.
*
@@ -178,7 +179,7 @@
* @see PointToPointTopology
* @returns a pointer to the queue.
*/
- Queue* GetQueue(void) const;
+ Ptr<Queue> GetQueue(void) const;
/**
* Get a copy of the attached Channel
*
@@ -188,7 +189,7 @@
* @see PointToPointChannel
* @returns a pointer to the channel
*/
- virtual Channel *DoGetChannel(void) const;
+ virtual Ptr<Channel> DoGetChannel(void) const;
private:
/**
* Send a Packet Down the Wire.
@@ -287,7 +288,7 @@
* attached.
* @see class PointToPointChannel
*/
- PointToPointChannel* m_channel;
+ Ptr<PointToPointChannel> m_channel;
/**
* The Queue which this PointToPointNetDevice uses as a packet source.
* Management of this Queue has been delegated to the PointToPointNetDevice
@@ -295,7 +296,7 @@
* @see class Queue
* @see class DropTailQueue
*/
- Queue* m_queue;
+ Ptr<Queue> m_queue;
/**
* The trace source for the packet reception events that the device can
* fire.
--- a/src/devices/p2p/p2p-topology.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-topology.cc Sun May 13 12:52:38 2007 +0100
@@ -24,13 +24,13 @@
#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/drop-tail.h"
#include "ns3/i-ipv4.h"
+#include "ns3/queue.h"
#include "p2p-channel.h"
#include "p2p-net-device.h"
@@ -38,35 +38,35 @@
namespace ns3 {
-PointToPointChannel *
+Ptr<PointToPointChannel>
PointToPointTopology::AddPointToPointLink(
- Node* n1,
- Node* n2,
+ Ptr<Node> n1,
+ Ptr<Node> n2,
const DataRate& bps,
const Time& delay)
{
- PointToPointChannel* channel = new PointToPointChannel(bps, delay);
+ Ptr<PointToPointChannel> channel = MakeNewObject<PointToPointChannel> (bps, delay);
- PointToPointNetDevice* net1 = new PointToPointNetDevice(n1);
- net1->AddQueue(Queue::Default().Copy());
- n1->AddDevice (net1);
+ Ptr<PointToPointNetDevice> net1 = MakeNewObject<PointToPointNetDevice> (n1);
+
+ Ptr<Queue> q = Queue::CreateDefault ();
+ net1->AddQueue(q);
net1->Attach (channel);
- net1->Unref ();
- PointToPointNetDevice* net2 = new PointToPointNetDevice(n2);
- net2->AddQueue(Queue::Default().Copy());
- n2->AddDevice (net2);
+ Ptr<PointToPointNetDevice> net2 = MakeNewObject<PointToPointNetDevice> (n2);
+
+ q = Queue::CreateDefault ();
+ net2->AddQueue(q);
net2->Attach (channel);
- net2->Unref ();
return channel;
}
-bool
+void
PointToPointTopology::AddIpv4Addresses(
- const PointToPointChannel *chan,
- Node* n1, const Ipv4Address& addr1,
- Node* n2, const Ipv4Address& addr2)
+ 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
@@ -76,148 +76,97 @@
// The PointToPoint channel is used to find the relevant NetDevices
NS_ASSERT (chan->GetNDevices () == 2);
- NetDevice* nd1 = chan->GetDevice (0);
- NetDevice* nd2 = chan->GetDevice (1);
+ 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->PeekNode ()->GetId () == n2->GetId () ) &&
- (nd2->PeekNode ()->GetId () == n1->GetId () ) )
+ if ( (nd1->GetNode ()->GetId () == n2->GetId () ) &&
+ (nd2->GetNode ()->GetId () == n1->GetId () ) )
{
std::swap(nd1, nd2);
}
- NS_ASSERT (nd1->PeekNode ()->GetId () == n1->GetId ());
- NS_ASSERT (nd2->PeekNode ()->GetId () == n2->GetId ());
+ NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
+ NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
- IIpv4 *ip1 = n1->QueryInterface<IIpv4> (IIpv4::iid);
+ Ptr<IIpv4> ip1 = n1->QueryInterface<IIpv4> (IIpv4::iid);
uint32_t index1 = ip1->AddInterface (nd1);
ip1->SetAddress (index1, addr1);
ip1->SetNetworkMask (index1, netmask);
ip1->SetUp (index1);
- IIpv4 *ip2 = n2->QueryInterface<IIpv4> (IIpv4::iid);
+ Ptr<IIpv4> ip2 = n2->QueryInterface<IIpv4> (IIpv4::iid);
uint32_t index2 = ip2->AddInterface (nd2);
ip2->SetAddress (index2, addr2);
ip2->SetNetworkMask (index2, netmask);
ip2->SetUp (index2);
- ip1->AddHostRouteTo (addr2, index1);
- ip2->AddHostRouteTo (addr1, index2);
-
- ip1->Unref ();
- ip2->Unref ();
-
- return true;
-}
-
-#ifdef NOTYET
-
-// Get the net device connecting node n1 to n2. For topologies where
-// there are possibly multiple devices connecting n1 and n2 (for example
-// wireless with two devices on different channels) this will return
-// the first one found.
-PointToPointNetDevice* PointToPointTopology::GetNetDevice(Node* n1, Node* n2)
-{
- // First get the NetDeviceList capability from node 1
- NetDeviceList* ndl1 = n1->GetNetDeviceList();
- if (!ndl1) return 0; // No devices, return nil
- // Get the list of devices
- const NetDeviceList::NetDevices_t& dlist = ndl1->GetAll();
- for (NetDeviceList::NetDevices_t::const_iterator i = dlist.Begin();
- i != dlist.End(); ++i)
- { // Check each device
- NetDevice* nd = *i; // next device
- Channel* c = nd->GetChannel();
- if (!c) continue; // No channel
- if (c->NodeIsPeer(n2)) return nd; // found it
- }
- return 0; // None found
-}
-
-// Get the channel connecting node n1 to node n2
-PointToPointChannel* PointToPointTopology::GetChannel(
- Node* n1,
- Node* n2
-)
-{
- NetDevice* nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, so no channel
- return nd->GetChannel();
-}
-
-Queue* PointToPointTopology::GetQueue(Node* n1, Node* n2)
-{
- NetDevice* nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, so in queue
- return nd->GetQueue();
-}
-
-Queue* PointToPointTopology::SetQueue(Node* n1, Node* n2, const Queue& q)
-{
- NetDevice* nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, can't set queue
- // Add the specified queue to the netdevice
- return nd->SetQueue(q);
}
-#endif
+void
+PointToPointTopology::AddIpv4Routes (
+ Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
+{
+ // The PointToPoint channel is used to find the relevant NetDevices
+ NS_ASSERT (chan->GetNDevices () == 2);
+ Ptr<NetDevice> nd1 = chan->GetDevice (0);
+ Ptr<NetDevice> nd2 = chan->GetDevice (1);
+
+ // Assert that n1 is the Node owning one of the two NetDevices
+ // and make sure that nd1 corresponds to it
+ if (nd1->GetNode ()->GetId () == n1->GetId ())
+ {
+ ; // Do nothing
+ }
+ else if (nd2->GetNode ()->GetId () == n1->GetId ())
+ {
+ std::swap(nd1, nd2);
+ }
+ else
+ {
+ NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+ }
+
+ // Assert that n2 is the Node owning one of the two NetDevices
+ // and make sure that nd2 corresponds to it
+ if (nd2->GetNode ()->GetId () != n2->GetId ())
+ {
+ NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+ }
-#ifdef GFR
-P2PChannel* Topology::AddDuplexLink(Node* n1, const IPAddr& ip1,
- Node* n2, const IPAddr& ip2,
- const Rate& rate, const Time& delay)
-{
- // First get the NetDeviceList capability from each node
- NetDeviceList* ndl1 = n1->GetNetDeviceList();
- NetDeviceList* ndl2 = n2->GetNetDeviceList();
- if (!ndl1 || !ndl2) return nil; // Both ends must have NetDeviceList
- // Get the net devices
- P2PNetDevice* nd1 = ndl1->Add(P2PNetDevice(n1, rate, nil));
- P2PNetDevice* nd2 = ndl2->Add(P2PNetDevice(n1, rate, nd1->GetChannel()));
- // Not implemented yet. Add appropriate layer 2 protocol for
- // the net devices.
- // Get the L3 proto for node 1 and configure it with this device
- L3Demux* l3demux1 = n1->GetL3Demux();
- L3Protocol* l3proto1 = nil;
- // If the node 1 l3 demux exists, find the coresponding l3 protocol
- if (l3demux1) l3proto1 = l3demux1->Lookup(ip1.L3Proto());
- // If the l3 protocol exists, configure this net device. Use a mask
- // of all ones, since there is only one device on the remote end
- // of this link
- if (l3proto1) l3proto1->AddNetDevice(nd1, ip1, ip1.GetMask(ip1.Size()*8));
- // Same for node 2
- L3Demux* l3demux2 = n2->GetL3Demux();
- L3Protocol* l3proto2 = nil;
- // If the node 2 l3 demux exists, find the coresponding l3 protocol
- if (l3demux2) l3proto2 = l3demux2->Lookup(ip2.L3Proto());
- if (l3proto2) l3proto2->AddNetDevice(nd2, ip2, ip2.GetMask(ip2.Size()*8));
- return dynamic_cast<P2PChannel*>(nd1->GetChannel()); // Always succeeds
+ // Assert that both are Ipv4 nodes
+ Ptr<IIpv4> ip1 = nd1->GetNode ()->QueryInterface<IIpv4> (IIpv4::iid);
+ Ptr<IIpv4> ip2 = nd2->GetNode ()->QueryInterface<IIpv4> (IIpv4::iid);
+ NS_ASSERT(ip1 != 0 && ip2 != 0);
+
+ // Get interface indexes for both nodes corresponding to the right channel
+ uint32_t index1 = 0;
+ bool found = false;
+ for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
+ {
+ if (ip1 ->GetNetDevice (i) == nd1)
+ {
+ index1 = i;
+ found = true;
+ }
+ }
+ NS_ASSERT(found);
+
+ uint32_t index2 = 0;
+ found = false;
+ for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
+ {
+ if (ip2 ->GetNetDevice (i) == nd2)
+ {
+ index2 = i;
+ found = true;
+ }
+ }
+ NS_ASSERT(found);
+
+ ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
+ ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2);
}
-// Get the channel connecting node n1 to node n2
-Channel* Topology::GetChannel(Node* n1, Node* n2)
-{
- NetDevice* nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, so no channel
- return nd->GetChannel();
-}
-
-Queue* Topology::GetQueue(Node* n1, Node* n2)
-{
- NetDevice* nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, so in queue
- return nd->GetQueue();
-}
-
-Queue* Topology::SetQueue(Node* n1, Node* n2, const Queue& q)
-{
- NetDevice* nd = GetNetDevice(n1, n2);
- if (!nd) return 0; // No net device, can't set queue
- // Add the specified queue to the netdevice
- return nd->SetQueue(q);
-}
-
-#endif
-
} // namespace ns3
--- a/src/devices/p2p/p2p-topology.h Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-topology.h Sun May 13 12:52:38 2007 +0100
@@ -19,10 +19,11 @@
//
// 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
@@ -33,47 +34,51 @@
class IPAddr;
class DataRate;
class Queue;
-//class Time;
/**
- * \brief A helper class to create Topologies based on the ns3::PointToPointNetDevice and
- * ns3::PointToPointChannel objects.
- *
- * XXX ??
- * I think that some of the methods below are not implemented.
- * If so, remove them.
+ * \brief A helper class to create Topologies based on the
+ * ns3::PointToPointNetDevice and ns3::PointToPointChannel objects.
*/
class PointToPointTopology {
public:
/**
+ * \param n1 Node
+ * \param n2 Node
+ * \param rate Maximum transmission link rate
+ * \param delay one-way propagation delay
+ * \return Pointer to the underlying PointToPointChannel
+ *
* Add a full-duplex point-to-point link between two nodes
- * with the specified IP addresses, with specified maximum transmission rate
- * and propagation delay.
+ * and attach PointToPointNetDevices to the resulting
+ * PointToPointChannel.
*/
- static PointToPointChannel* AddPointToPointLink(
- Node*, Node*, const DataRate&, const Time&);
+ static Ptr<PointToPointChannel> AddPointToPointLink(
+ Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
- static bool AddIpv4Addresses(
- const PointToPointChannel*,
- Node*, const Ipv4Address&,
- Node*, const Ipv4Address&);
+ /**
+ * \param chan PointToPointChannel to use
+ * \param n1 Node
+ * \param addr1 Ipv4 Address for n1
+ * \param n2 Node
+ * \param addr2 Ipv4 Address for n2
+ *
+ * Add Ipv4Addresses to the Ipv4 interfaces associated with the
+ * two PointToPointNetDevices on the provided PointToPointChannel
+ */
+ static void AddIpv4Addresses(
+ Ptr<const PointToPointChannel> chan,
+ Ptr<Node> n1, const Ipv4Address& addr1,
+ Ptr<Node> n2, const Ipv4Address& addr2);
/**
- * Get the connecting node n1 to node n2
- */
- static PointToPointChannel* GetChannel(Node*, Node*);
- /**
- * Get the NetDevice connecting node n1 to n2
+ * \param channel PointToPointChannel to use
+ * \param n1 Node
+ * \param n2 Node
+ *
+ * For the given PointToPointChannel, for each Node, add an
+ * IPv4 host route to the IPv4 address of the peer node.
*/
- static PointToPointNetDevice* GetNetDevice(Node*, Node*);
- /**
- * Get the queue associated with a link between two nodes
- */
- static Queue* GetQueue(Node*, Node*);
- /**
- * Set the queue associated with a link between two nodes
- */
- static Queue* SetQueue(Node*, Node*, const Queue&);
+ static void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
};
} // namespace ns3
--- a/src/internet-node/arp-cache.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp-cache.cc Sun May 13 12:52:38 2007 +0100
@@ -28,24 +28,21 @@
namespace ns3 {
-ArpCache::ArpCache (NetDevice *device, Ipv4Interface *interface)
+ArpCache::ArpCache (Ptr<NetDevice> device, Ipv4Interface *interface)
: m_device (device),
m_interface (interface),
m_aliveTimeout (Seconds (120)),
m_deadTimeout (Seconds (100)),
m_waitReplyTimeout (Seconds (1))
-{
- m_device->Ref ();
-}
+{}
ArpCache::~ArpCache ()
{
- m_device->Unref ();
Flush ();
}
-NetDevice *
-ArpCache::PeekDevice (void) const
+Ptr<NetDevice>
+ArpCache::GetDevice (void) const
{
return m_device;
}
--- a/src/internet-node/arp-cache.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp-cache.h Sun May 13 12:52:38 2007 +0100
@@ -27,6 +27,7 @@
#include "ns3/net-device.h"
#include "ns3/ipv4-address.h"
#include "ns3/mac-address.h"
+#include "ns3/ptr.h"
#include "sgi-hashmap.h"
namespace ns3 {
@@ -38,10 +39,10 @@
public:
class Entry;
- ArpCache (NetDevice *device, Ipv4Interface *interface);
+ ArpCache (Ptr<NetDevice> device, Ipv4Interface *interface);
~ArpCache ();
- NetDevice *PeekDevice (void) const;
+ Ptr<NetDevice> GetDevice (void) const;
Ipv4Interface *GetInterface (void) const;
void SetAliveTimeout (Time aliveTimeout);
@@ -91,7 +92,7 @@
typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash> Cache;
typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash>::iterator CacheI;
- NetDevice *m_device;
+ Ptr<NetDevice> m_device;
Ipv4Interface *m_interface;
Time m_aliveTimeout;
Time m_deadTimeout;
--- a/src/internet-node/arp-ipv4-interface.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp-ipv4-interface.cc Sun May 13 12:52:38 2007 +0100
@@ -31,25 +31,21 @@
namespace ns3 {
-ArpIpv4Interface::ArpIpv4Interface (Node *node, NetDevice *device)
+ArpIpv4Interface::ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device)
: Ipv4Interface (device),
m_node (node)
-{
- m_node->Ref ();
-}
+{}
ArpIpv4Interface::~ArpIpv4Interface ()
-{
- m_node->Unref ();
-}
+{}
TraceResolver *
ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context)
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- if (PeekDevice () != 0)
+ if (GetDevice () != 0)
{
resolver->Add ("netdevice",
- MakeCallback (&NetDevice::CreateTraceResolver, PeekDevice ()),
+ MakeCallback (&NetDevice::CreateTraceResolver, PeekPointer (GetDevice ())),
ArpIpv4Interface::NETDEVICE);
}
@@ -59,21 +55,20 @@
void
ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
{
- NS_ASSERT (PeekDevice () != 0);
- if (PeekDevice ()->NeedsArp ())
+ NS_ASSERT (GetDevice () != 0);
+ if (GetDevice ()->NeedsArp ())
{
- IArpPrivate * arp = m_node->QueryInterface<IArpPrivate> (IArpPrivate::iid);
+ Ptr<IArpPrivate> arp = m_node->QueryInterface<IArpPrivate> (IArpPrivate::iid);
MacAddress hardwareDestination;
- bool found = arp->Lookup (p, dest, PeekDevice (), &hardwareDestination);
+ bool found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination);
if (found)
{
- PeekDevice ()->Send (p, hardwareDestination, Ipv4::PROT_NUMBER);
+ GetDevice ()->Send (p, hardwareDestination, Ipv4::PROT_NUMBER);
}
- arp->Unref ();
}
else
{
- PeekDevice ()->Send (p, PeekDevice ()->GetBroadcast (), Ipv4::PROT_NUMBER);
+ GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), Ipv4::PROT_NUMBER);
}
}
--- a/src/internet-node/arp-ipv4-interface.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp-ipv4-interface.h Sun May 13 12:52:38 2007 +0100
@@ -23,6 +23,7 @@
#define ARP_IPV4_INTERFACE_H
#include "ipv4-interface.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -42,13 +43,13 @@
NETDEVICE,
ARP,
};
- ArpIpv4Interface (Node *node, NetDevice *device);
+ ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device);
virtual ~ArpIpv4Interface ();
private:
virtual void SendTo (Packet p, Ipv4Address dest);
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
- Node *m_node;
+ Ptr<Node> m_node;
};
}//namespace ns3
--- a/src/internet-node/arp.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp.cc Sun May 13 12:52:38 2007 +0100
@@ -36,17 +36,13 @@
const uint16_t Arp::PROT_NUMBER = 0x0806;
-Arp::Arp (Node *node)
+Arp::Arp (Ptr<Node> node)
: L3Protocol (PROT_NUMBER, 0/* XXX: correct version number ? */ ),
m_node (node)
-{
- m_node->Ref ();
-}
+{}
Arp::~Arp ()
-{
- Dispose ();
-}
+{}
void
Arp::DoDispose (void)
@@ -56,11 +52,7 @@
delete *i;
}
m_cacheList.clear ();
- if (m_node != 0)
- {
- m_node->Unref ();
- m_node = 0;
- }
+ m_node = 0;
L3Protocol::DoDispose ();
}
@@ -71,18 +63,17 @@
}
ArpCache *
-Arp::FindCache (NetDevice *device)
+Arp::FindCache (Ptr<NetDevice> device)
{
for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
{
- if ((*i)->PeekDevice () == device)
+ if ((*i)->GetDevice () == device)
{
return *i;
}
}
- IIpv4Private *ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
+ Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device);
- ipv4->Unref ();
ArpCache * cache = new ArpCache (device, interface);
NS_ASSERT (device->IsBroadcast ());
device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
@@ -91,7 +82,7 @@
}
void
-Arp::Receive(Packet& packet, NetDevice *device)
+Arp::Receive(Packet& packet, Ptr<NetDevice> device)
{
ArpCache *cache = FindCache (device);
ArpHeader arp;
@@ -140,7 +131,7 @@
}
bool
Arp::Lookup (Packet &packet, Ipv4Address destination,
- NetDevice *device,
+ Ptr<NetDevice> device,
MacAddress *hardwareDestination)
{
ArpCache *cache = FindCache (device);
@@ -212,25 +203,25 @@
Arp::SendArpRequest (ArpCache const *cache, Ipv4Address to)
{
ArpHeader arp;
- arp.SetRequest (cache->PeekDevice ()->GetAddress (),
+ arp.SetRequest (cache->GetDevice ()->GetAddress (),
cache->GetInterface ()->GetAddress (),
- cache->PeekDevice ()->GetBroadcast (),
+ cache->GetDevice ()->GetBroadcast (),
to);
Packet packet;
packet.AddHeader (arp);
- cache->PeekDevice ()->Send (packet, cache->PeekDevice ()->GetBroadcast (), PROT_NUMBER);
+ cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
}
void
Arp::SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac)
{
ArpHeader arp;
- arp.SetReply (cache->PeekDevice ()->GetAddress (),
+ arp.SetReply (cache->GetDevice ()->GetAddress (),
cache->GetInterface ()->GetAddress (),
toMac, toIp);
Packet packet;
packet.AddHeader (arp);
- cache->PeekDevice ()->Send (packet, toMac, PROT_NUMBER);
+ cache->GetDevice ()->Send (packet, toMac, PROT_NUMBER);
}
}//namespace ns3
--- a/src/internet-node/arp.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp.h Sun May 13 12:52:38 2007 +0100
@@ -24,6 +24,7 @@
#include <list>
#include "ns3/ipv4-address.h"
#include "ns3/mac-address.h"
+#include "ns3/ptr.h"
#include "l3-protocol.h"
namespace ns3 {
@@ -40,24 +41,24 @@
public:
static const uint16_t PROT_NUMBER;
- Arp (Node *node);
+ Arp (Ptr<Node> node);
~Arp ();
virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
- virtual void Receive(Packet& p, NetDevice *device);
+ virtual void Receive(Packet& p, Ptr<NetDevice> device);
bool Lookup (Packet &p, Ipv4Address destination,
- NetDevice *device,
+ Ptr<NetDevice> device,
MacAddress *hardwareDestination);
protected:
virtual void DoDispose (void);
private:
typedef std::list<ArpCache *> CacheList;
- ArpCache *FindCache (NetDevice *device);
+ ArpCache *FindCache (Ptr<NetDevice> device);
void SendArpRequest (ArpCache const *cache, Ipv4Address to);
void SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac);
CacheList m_cacheList;
- Node *m_node;
+ Ptr<Node> m_node;
};
}//namespace ns3
--- a/src/internet-node/ascii-trace.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ascii-trace.cc Sun May 13 12:52:38 2007 +0100
@@ -110,7 +110,7 @@
m_os << Simulator::Now ().GetSeconds () << " ";
NodeList::NodeIndex nodeIndex;
context.Get (nodeIndex);
- m_os << "node=" << NodeList::PeekNode (nodeIndex)->GetId () << " ";
+ m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
Ipv4::InterfaceIndex interfaceIndex;
context.Get (interfaceIndex);
m_os << "interface=" << interfaceIndex << " ";
@@ -124,7 +124,7 @@
m_os << "r " << Simulator::Now ().GetSeconds () << " ";
NodeList::NodeIndex nodeIndex;
context.Get (nodeIndex);
- m_os << "node=" << NodeList::PeekNode (nodeIndex)->GetId () << " ";
+ m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
Ipv4::InterfaceIndex interfaceIndex;
context.Get (interfaceIndex);
m_os << "interface=" << interfaceIndex << " ";
--- a/src/internet-node/i-arp-private.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-arp-private.cc Sun May 13 12:52:38 2007 +0100
@@ -21,17 +21,16 @@
#include "i-arp-private.h"
#include "arp.h"
#include "ns3/assert.h"
+#include "ns3/net-device.h"
namespace ns3 {
-const Iid IArpPrivate::iid ("IArpPrivate");
+const InterfaceId IArpPrivate::iid ("IArpPrivate");
-IArpPrivate::IArpPrivate (Arp *arp)
- : NsUnknown (IArpPrivate::iid),
+IArpPrivate::IArpPrivate (Ptr<Arp> arp)
+ : Interface (IArpPrivate::iid),
m_arp (arp)
-{
- m_arp->Ref ();
-}
+{}
IArpPrivate::~IArpPrivate ()
{
NS_ASSERT (m_arp == 0);
@@ -39,7 +38,7 @@
bool
IArpPrivate::Lookup (Packet &p, Ipv4Address destination,
- NetDevice *device,
+ Ptr<NetDevice> device,
MacAddress *hardwareDestination)
{
return m_arp->Lookup (p, destination, device, hardwareDestination);
@@ -48,9 +47,8 @@
void
IArpPrivate::DoDispose (void)
{
- m_arp->Unref ();
m_arp = 0;
- NsUnknown::DoDispose ();
+ Interface::DoDispose ();
}
--- a/src/internet-node/i-arp-private.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-arp-private.h Sun May 13 12:52:38 2007 +0100
@@ -21,7 +21,7 @@
#ifndef I_ARP_PRIVATE_H
#define I_ARP_PRIVATE_H
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
#include "ns3/ipv4-address.h"
namespace ns3 {
@@ -31,19 +31,19 @@
class Packet;
class Arp;
-class IArpPrivate : public NsUnknown
+class IArpPrivate : public Interface
{
public:
- static const Iid iid;
- IArpPrivate (Arp *arp);
+ static const InterfaceId iid;
+ IArpPrivate (Ptr<Arp> arp);
virtual ~IArpPrivate ();
bool Lookup (Packet &p, Ipv4Address destination,
- NetDevice *device,
+ Ptr<NetDevice> device,
MacAddress *hardwareDestination);
protected:
virtual void DoDispose (void);
private:
- Arp *m_arp;
+ Ptr<Arp> m_arp;
};
} // namespace ns3
--- a/src/internet-node/i-ipv4-impl.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-ipv4-impl.cc Sun May 13 12:52:38 2007 +0100
@@ -20,15 +20,15 @@
*/
#include "i-ipv4-impl.h"
#include "ipv4.h"
+#include "ipv4-interface.h"
#include "ns3/assert.h"
+#include "ns3/net-device.h"
namespace ns3 {
-IIpv4Impl::IIpv4Impl (Ipv4 *ipv4)
+IIpv4Impl::IIpv4Impl (Ptr<Ipv4> ipv4)
: m_ipv4 (ipv4)
-{
- m_ipv4->Ref ();
-}
+{}
IIpv4Impl::~IIpv4Impl ()
{
NS_ASSERT (m_ipv4 == 0);
@@ -36,7 +36,6 @@
void
IIpv4Impl::DoDispose (void)
{
- m_ipv4->Unref ();
m_ipv4 = 0;
}
@@ -90,7 +89,7 @@
return m_ipv4->RemoveRoute (i);
}
uint32_t
-IIpv4Impl::AddInterface (NetDevice *device)
+IIpv4Impl::AddInterface (Ptr<NetDevice> device)
{
return m_ipv4->AddInterface (device);
}
@@ -99,6 +98,11 @@
{
return m_ipv4->GetNInterfaces ();
}
+Ptr<NetDevice>
+IIpv4Impl::GetNetDevice (uint32_t i)
+{
+ return m_ipv4->GetInterface (i)-> GetDevice ();
+}
void
IIpv4Impl::SetAddress (uint32_t i, Ipv4Address address)
--- a/src/internet-node/i-ipv4-impl.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-ipv4-impl.h Sun May 13 12:52:38 2007 +0100
@@ -22,6 +22,7 @@
#define I_IPV4_IMPL_H
#include "ns3/i-ipv4.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -30,7 +31,7 @@
class IIpv4Impl : public IIpv4
{
public:
- IIpv4Impl (Ipv4 *ipv4);
+ IIpv4Impl (Ptr<Ipv4> ipv4);
virtual ~IIpv4Impl ();
@@ -51,8 +52,9 @@
virtual uint32_t GetNRoutes (void);
virtual Ipv4Route *GetRoute (uint32_t i);
virtual void RemoveRoute (uint32_t i);
- virtual uint32_t AddInterface (NetDevice *device);
+ virtual uint32_t AddInterface (Ptr<NetDevice> device);
virtual uint32_t GetNInterfaces (void);
+ virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
virtual void SetAddress (uint32_t i, Ipv4Address address);
virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
@@ -65,7 +67,7 @@
protected:
virtual void DoDispose (void);
private:
- Ipv4 *m_ipv4;
+ Ptr<Ipv4> m_ipv4;
};
} // namespace ns3
--- a/src/internet-node/i-ipv4-private.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-ipv4-private.cc Sun May 13 12:52:38 2007 +0100
@@ -21,17 +21,16 @@
#include "i-ipv4-private.h"
#include "ipv4.h"
#include "ns3/assert.h"
+#include "ns3/net-device.h"
namespace ns3 {
-const Iid IIpv4Private::iid ("IIpv4Private");
+const InterfaceId IIpv4Private::iid ("IIpv4Private");
-IIpv4Private::IIpv4Private (Ipv4 *ipv4)
- : NsUnknown (IIpv4Private::iid),
+IIpv4Private::IIpv4Private (Ptr<Ipv4> ipv4)
+ : Interface (IIpv4Private::iid),
m_ipv4 (ipv4)
-{
- m_ipv4->Ref ();
-}
+{}
IIpv4Private::~IIpv4Private ()
{
NS_ASSERT (m_ipv4 == 0);
@@ -48,21 +47,20 @@
m_ipv4->Send (packet, source, destination, protocol);
}
Ipv4Interface *
-IIpv4Private::FindInterfaceForDevice (NetDevice const*device)
+IIpv4Private::FindInterfaceForDevice (Ptr<const NetDevice>device)
{
return m_ipv4->FindInterfaceForDevice (device);
}
void
-IIpv4Private::Receive(Packet& p, NetDevice *device)
+IIpv4Private::Receive(Packet& p, Ptr<NetDevice> device)
{
m_ipv4->Receive (p, device);
}
void
IIpv4Private::DoDispose (void)
{
- m_ipv4->Unref ();
m_ipv4 = 0;
- NsUnknown::DoDispose ();
+ Interface::DoDispose ();
}
} // namespace ns3
--- a/src/internet-node/i-ipv4-private.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-ipv4-private.h Sun May 13 12:52:38 2007 +0100
@@ -21,8 +21,9 @@
#ifndef I_IPV4_PRIVATE_H
#define I_IPV4_PRIVATE_H
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
#include <stdint.h>
namespace ns3 {
@@ -34,22 +35,22 @@
class Ipv4Interface;
class NetDevice;
-class IIpv4Private : public NsUnknown
+class IIpv4Private : public Interface
{
public:
- static const Iid iid;
- IIpv4Private (Ipv4 *ipv4);
+ static const InterfaceId iid;
+ IIpv4Private (Ptr<Ipv4> ipv4);
virtual ~IIpv4Private ();
TraceResolver *CreateTraceResolver (TraceContext const &context);
void Send (Packet const &packet, Ipv4Address source,
Ipv4Address destination, uint8_t protocol);
- Ipv4Interface *FindInterfaceForDevice (NetDevice const*device);
- void Receive(Packet& p, NetDevice *device);
+ Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice>device);
+ void Receive(Packet& p, Ptr<NetDevice> device);
protected:
virtual void DoDispose (void);
private:
- Ipv4 *m_ipv4;
+ Ptr<Ipv4> m_ipv4;
};
} // namespace ns3
--- a/src/internet-node/i-udp-impl.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-udp-impl.cc Sun May 13 12:52:38 2007 +0100
@@ -20,21 +20,20 @@
*/
#include "i-udp-impl.h"
#include "udp.h"
+#include "ns3/socket.h"
#include "ns3/assert.h"
namespace ns3 {
-IUdpImpl::IUdpImpl (Udp *udp)
+IUdpImpl::IUdpImpl (Ptr<Udp> udp)
: m_udp (udp)
-{
- m_udp->Ref ();
-}
+{}
IUdpImpl::~IUdpImpl ()
{
NS_ASSERT (m_udp == 0);
}
-Socket *
+Ptr<Socket>
IUdpImpl::CreateSocket (void)
{
return m_udp->CreateSocket ();
@@ -43,11 +42,7 @@
void
IUdpImpl::DoDispose (void)
{
- if (m_udp != 0)
- {
- m_udp->Unref ();
- m_udp = 0;
- }
+ m_udp = 0;
IUdp::DoDispose ();
}
--- a/src/internet-node/i-udp-impl.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-udp-impl.h Sun May 13 12:52:38 2007 +0100
@@ -22,6 +22,7 @@
#define I_UDP_IMPL_H
#include "ns3/i-udp.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -30,15 +31,15 @@
class IUdpImpl : public IUdp
{
public:
- IUdpImpl (Udp *udp);
+ IUdpImpl (Ptr<Udp> udp);
virtual ~IUdpImpl ();
- virtual Socket *CreateSocket (void);
+ virtual Ptr<Socket> CreateSocket (void);
protected:
virtual void DoDispose (void);
private:
- Udp *m_udp;
+ Ptr<Udp> m_udp;
};
} // namespace ns3
--- a/src/internet-node/internet-node.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/internet-node.cc Sun May 13 12:52:38 2007 +0100
@@ -22,7 +22,6 @@
// George F. Riley, Georgia Tech, Fall 2006
#include "ns3/composite-trace-resolver.h"
-#include "ns3/application-list.h"
#include "ns3/net-device.h"
#include "l3-demux.h"
@@ -41,42 +40,28 @@
InternetNode::InternetNode()
{
- Ipv4 *ipv4 = new Ipv4 (this);
- Arp *arp = new Arp (this);
- Udp *udp = new Udp (this);
+ Ptr<Ipv4> ipv4 = MakeNewObject<Ipv4> (this);
+ Ptr<Arp> arp = MakeNewObject<Arp> (this);
+ Ptr<Udp> udp = MakeNewObject<Udp> (this);
- ApplicationList *applicationList = new ApplicationList(this);
- L3Demux *l3Demux = new L3Demux(this);
- Ipv4L4Demux *ipv4L4Demux = new Ipv4L4Demux(this);
+ Ptr<L3Demux> l3Demux = MakeNewObject<L3Demux> (this);
+ Ptr<Ipv4L4Demux> ipv4L4Demux = MakeNewObject<Ipv4L4Demux> (this);
l3Demux->Insert (ipv4);
l3Demux->Insert (arp);
ipv4L4Demux->Insert (udp);
- IUdpImpl *udpImpl = new IUdpImpl (udp);
- IArpPrivate *arpPrivate = new IArpPrivate (arp);
- IIpv4Impl *ipv4Impl = new IIpv4Impl (ipv4);
- IIpv4Private *ipv4Private = new IIpv4Private (ipv4);
+ Ptr<IUdpImpl> udpImpl = MakeNewObject<IUdpImpl> (udp);
+ Ptr<IArpPrivate> arpPrivate = MakeNewObject<IArpPrivate> (arp);
+ Ptr<IIpv4Impl> ipv4Impl = MakeNewObject<IIpv4Impl> (ipv4);
+ Ptr<IIpv4Private> ipv4Private = MakeNewObject<IIpv4Private> (ipv4);
- NsUnknown::AddInterface (ipv4Private);
- NsUnknown::AddInterface (ipv4Impl);
- NsUnknown::AddInterface (arpPrivate);
- NsUnknown::AddInterface (udpImpl);
- NsUnknown::AddInterface (applicationList);
- NsUnknown::AddInterface (l3Demux);
- NsUnknown::AddInterface (ipv4L4Demux);
-
-
- applicationList->Unref ();
- l3Demux->Unref ();
- ipv4L4Demux->Unref ();
- arp->Unref ();
- ipv4->Unref ();
- udp->Unref ();
- udpImpl->Unref ();
- arpPrivate->Unref ();
- ipv4Impl->Unref ();
- ipv4Private->Unref ();
+ Interface::AddInterface (ipv4Private);
+ Interface::AddInterface (ipv4Impl);
+ Interface::AddInterface (arpPrivate);
+ Interface::AddInterface (udpImpl);
+ Interface::AddInterface (l3Demux);
+ Interface::AddInterface (ipv4L4Demux);
}
InternetNode::~InternetNode ()
@@ -89,14 +74,13 @@
}
TraceResolver *
-InternetNode::CreateTraceResolver (TraceContext const &context)
+InternetNode::DoCreateTraceResolver (TraceContext const &context)
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- IIpv4Private *ipv4 = QueryInterface<IIpv4Private> (IIpv4Private::iid);
+ Ptr<IIpv4Private> ipv4 = QueryInterface<IIpv4Private> (IIpv4Private::iid);
resolver->Add ("ipv4",
- MakeCallback (&IIpv4Private::CreateTraceResolver, ipv4),
+ MakeCallback (&IIpv4Private::CreateTraceResolver, PeekPointer (ipv4)),
InternetNode::IPV4);
- ipv4->Unref ();
return resolver;
}
@@ -108,17 +92,16 @@
}
void
-InternetNode::DoAddDevice (NetDevice *device) const
+InternetNode::DoAddDevice (Ptr<NetDevice> device) const
{
device->SetReceiveCallback (MakeCallback (&InternetNode::ReceiveFromDevice, this));
}
bool
-InternetNode::ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const
+InternetNode::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const
{
- L3Demux *demux = QueryInterface<L3Demux> (L3Demux::iid);
- L3Protocol *target = demux->PeekProtocol (protocolNumber);
- demux->Unref ();
+ Ptr<L3Demux> demux = QueryInterface<L3Demux> (L3Demux::iid);
+ Ptr<L3Protocol> target = demux->GetProtocol (protocolNumber);
if (target != 0)
{
Packet packet = p;
--- a/src/internet-node/internet-node.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/internet-node.h Sun May 13 12:52:38 2007 +0100
@@ -41,14 +41,14 @@
};
InternetNode();
virtual ~InternetNode ();
- virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
void SetName(std::string name);
protected:
virtual void DoDispose(void);
private:
- virtual void DoAddDevice (NetDevice *device) const;
- bool ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const;
+ virtual void DoAddDevice (Ptr<NetDevice> device) const;
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
+ bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
std::string m_name;
};
--- a/src/internet-node/ipv4-interface.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-interface.cc Sun May 13 12:52:38 2007 +0100
@@ -31,26 +31,16 @@
* becoming useable, the user must invoke SetUp on them
* once the final Ipv4 address and mask has been set.
*/
-Ipv4Interface::Ipv4Interface (NetDevice *nd)
+Ipv4Interface::Ipv4Interface (Ptr<NetDevice> nd)
: m_netdevice (nd),
m_ifup(false)
-{
- if (m_netdevice != 0)
- {
- m_netdevice->Ref ();
- }
-}
+{}
Ipv4Interface::~Ipv4Interface ()
-{
- if (m_netdevice != 0)
- {
- m_netdevice->Unref ();
- }
-}
+{}
-NetDevice*
-Ipv4Interface::PeekDevice (void) const
+Ptr<NetDevice>
+Ipv4Interface::GetDevice (void) const
{
return m_netdevice;
}
--- a/src/internet-node/ipv4-interface.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-interface.h Sun May 13 12:52:38 2007 +0100
@@ -25,6 +25,7 @@
#include <list>
#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -69,7 +70,7 @@
* This value can be zero in which case the MTU
* of this interface will be 2^(16-1).
*/
- Ipv4Interface (NetDevice *nd);
+ Ipv4Interface (Ptr<NetDevice> nd);
virtual ~Ipv4Interface();
/**
@@ -87,7 +88,7 @@
* \returns the underlying NetDevice. This method can return
* zero if this interface has no associated NetDevice.
*/
- NetDevice *PeekDevice (void) const;
+ Ptr<NetDevice> GetDevice (void) const;
/**
* \param a set the ipv4 address of this interface.
@@ -153,7 +154,7 @@
private:
virtual void SendTo (Packet p, Ipv4Address dest) = 0;
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
- NetDevice* m_netdevice;
+ Ptr<NetDevice> m_netdevice;
bool m_ifup;
Ipv4Address m_address;
Ipv4Mask m_netmask;
--- a/src/internet-node/ipv4-l4-demux.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-l4-demux.cc Sun May 13 12:52:38 2007 +0100
@@ -30,14 +30,12 @@
namespace ns3 {
-const Iid Ipv4L4Demux::iid ("Ipv4L4Demux");
+const InterfaceId Ipv4L4Demux::iid ("Ipv4L4Demux");
-Ipv4L4Demux::Ipv4L4Demux (Node *node)
- : NsUnknown (Ipv4L4Demux::iid),
+Ipv4L4Demux::Ipv4L4Demux (Ptr<Node> node)
+ : Interface (Ipv4L4Demux::iid),
m_node (node)
-{
- m_node->Ref ();
-}
+{}
Ipv4L4Demux::~Ipv4L4Demux()
{}
@@ -45,18 +43,14 @@
void
Ipv4L4Demux::DoDispose (void)
{
- for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+ for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
{
(*i)->Dispose ();
- (*i)->Unref ();
+ *i = 0;
}
m_protocols.clear ();
- if (m_node != 0)
- {
- m_node->Unref ();
- m_node = 0;
- }
- NsUnknown::DoDispose ();
+ m_node = 0;
+ Interface::DoDispose ();
}
TraceResolver *
@@ -65,25 +59,24 @@
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
{
- Ipv4L4Protocol *protocol = *i;
+ Ptr<Ipv4L4Protocol> protocol = *i;
std::string protValue;
std::ostringstream oss (protValue);
oss << (*i)->GetProtocolNumber ();
Ipv4L4ProtocolTraceType protocolNumber = (*i)->GetProtocolNumber ();
resolver->Add (protValue,
- MakeCallback (&Ipv4L4Protocol::CreateTraceResolver, protocol),
+ MakeCallback (&Ipv4L4Protocol::CreateTraceResolver, PeekPointer (protocol)),
protocolNumber);
}
return resolver;
}
void
-Ipv4L4Demux::Insert(Ipv4L4Protocol *protocol)
+Ipv4L4Demux::Insert(Ptr<Ipv4L4Protocol> protocol)
{
- protocol->Ref ();
m_protocols.push_back (protocol);
}
-Ipv4L4Protocol*
-Ipv4L4Demux::PeekProtocol(int protocolNumber)
+Ptr<Ipv4L4Protocol>
+Ipv4L4Demux::GetProtocol(int protocolNumber)
{
for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
{
@@ -95,7 +88,7 @@
return 0;
}
void
-Ipv4L4Demux::Erase(Ipv4L4Protocol*protocol)
+Ipv4L4Demux::Remove (Ptr<Ipv4L4Protocol> protocol)
{
m_protocols.remove (protocol);
}
--- a/src/internet-node/ipv4-l4-demux.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-l4-demux.h Sun May 13 12:52:38 2007 +0100
@@ -26,7 +26,8 @@
#define IPV4_L4_DEMUX_H
#include <list>
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -38,12 +39,12 @@
/**
* \brief L4 Ipv4 Demux
*/
-class Ipv4L4Demux : public NsUnknown
+class Ipv4L4Demux : public Interface
{
public:
- static const Iid iid;
+ static const InterfaceId iid;
typedef int Ipv4L4ProtocolTraceType;
- Ipv4L4Demux (Node *node);
+ Ipv4L4Demux (Ptr<Node> node);
virtual ~Ipv4L4Demux();
/**
@@ -64,7 +65,7 @@
* a working L4 Protocol and returned from this method.
* The caller does not get ownership of the returned pointer.
*/
- void Insert(Ipv4L4Protocol *protocol);
+ void Insert(Ptr<Ipv4L4Protocol> protocol);
/**
* \param protocolNumber number of protocol to lookup
* in this L4 Demux
@@ -74,19 +75,19 @@
* to forward packets up the stack to the right protocol.
* It is also called from InternetNode::GetUdp for example.
*/
- Ipv4L4Protocol* PeekProtocol(int protocolNumber);
+ Ptr<Ipv4L4Protocol> GetProtocol(int protocolNumber);
/**
* \param protocol protocol to remove from this demux.
*
* The input value to this method should be the value
* returned from the Ipv4L4Protocol::Insert method.
*/
- void Erase(Ipv4L4Protocol*protocol);
+ void Remove (Ptr<Ipv4L4Protocol> protocol);
private:
virtual void DoDispose (void);
- typedef std::list<Ipv4L4Protocol*> L4List_t;
+ typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
L4List_t m_protocols;
- Node *m_node;
+ Ptr<Node> m_node;
};
} //namespace ns3
--- a/src/internet-node/ipv4-l4-protocol.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-l4-protocol.h Sun May 13 12:52:38 2007 +0100
@@ -29,7 +29,6 @@
namespace ns3 {
-class Node;
class Packet;
class Ipv4Address;
class TraceResolver;
--- a/src/internet-node/ipv4-loopback-interface.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-loopback-interface.cc Sun May 13 12:52:38 2007 +0100
@@ -27,16 +27,12 @@
namespace ns3 {
-Ipv4LoopbackInterface::Ipv4LoopbackInterface (Node *node)
+Ipv4LoopbackInterface::Ipv4LoopbackInterface (Ptr<Node> node)
: Ipv4Interface (0),
m_node (node)
-{
- m_node->Ref ();
-}
+{}
Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()
-{
- m_node->Unref ();
-}
+{}
TraceResolver *
Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context)
@@ -47,9 +43,8 @@
void
Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
{
- IIpv4Private *ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
- ipv4->Receive (packet, PeekDevice ());
- ipv4->Unref ();
+ Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
+ ipv4->Receive (packet, GetDevice ());
}
}//namespace ns3
--- a/src/internet-node/ipv4-loopback-interface.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-loopback-interface.h Sun May 13 12:52:38 2007 +0100
@@ -23,6 +23,7 @@
#define IPV4_LOOPBACK_INTERFACE_H
#include "ipv4-interface.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -31,14 +32,14 @@
class Ipv4LoopbackInterface : public Ipv4Interface
{
public:
- Ipv4LoopbackInterface (Node *node);
+ Ipv4LoopbackInterface (Ptr<Node> node);
virtual ~Ipv4LoopbackInterface ();
private:
virtual void SendTo (Packet p, Ipv4Address dest);
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
- Node *m_node;
+ Ptr<Node> m_node;
};
}//namespace ns3
--- a/src/internet-node/ipv4.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4.cc Sun May 13 12:52:38 2007 +0100
@@ -27,6 +27,7 @@
#include "ns3/ipv4-address.h"
#include "ns3/ipv4-route.h"
#include "ns3/node.h"
+#include "ns3/net-device.h"
#include "ipv4.h"
#include "ipv4-l4-protocol.h"
@@ -42,7 +43,7 @@
const uint16_t Ipv4::PROT_NUMBER = 0x0800;
-Ipv4::Ipv4(Node *node)
+Ipv4::Ipv4(Ptr<Node> node)
: L3Protocol (PROT_NUMBER, 4),
m_nInterfaces (0),
m_defaultTtl (64),
@@ -51,12 +52,9 @@
m_node (node)
{
SetupLoopback ();
- m_node->Ref ();
}
Ipv4::~Ipv4 ()
-{
- DoDispose ();
-}
+{}
void
Ipv4::DoDispose (void)
@@ -83,11 +81,7 @@
delete m_defaultRoute;
m_defaultRoute = 0;
}
- if (m_node != 0)
- {
- m_node->Unref ();
- m_node = 0;
- }
+ m_node = 0;
L3Protocol::DoDispose ();
}
@@ -317,7 +311,7 @@
uint32_t
-Ipv4::AddInterface (NetDevice *device)
+Ipv4::AddInterface (Ptr<NetDevice> device)
{
Ipv4Interface *interface = new ArpIpv4Interface (m_node, device);
return AddIpv4Interface (interface);
@@ -351,11 +345,11 @@
}
Ipv4Interface *
-Ipv4::FindInterfaceForDevice (NetDevice const*device)
+Ipv4::FindInterfaceForDevice (Ptr<const NetDevice> device)
{
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
{
- if ((*i)->PeekDevice () == device)
+ if ((*i)->GetDevice () == device)
{
return *i;
}
@@ -364,12 +358,12 @@
}
void
-Ipv4::Receive(Packet& packet, NetDevice *device)
+Ipv4::Receive(Packet& packet, Ptr<NetDevice> device)
{
uint32_t index = 0;
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
{
- if ((*i)->PeekDevice () == device)
+ if ((*i)->GetDevice () == device)
{
m_rxTrace (packet, index);
break;
@@ -449,7 +443,7 @@
bool
-Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device)
+Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device)
{
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
i != m_interfaces.end (); i++)
@@ -465,7 +459,7 @@
i != m_interfaces.end (); i++)
{
Ipv4Interface *interface = *i;
- if (interface->PeekDevice () == device)
+ if (interface->GetDevice () == device)
{
if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ()))
{
@@ -511,9 +505,8 @@
void
Ipv4::ForwardUp (Packet p, Ipv4Header const&ip)
{
- Ipv4L4Demux *demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
- Ipv4L4Protocol *protocol = demux->PeekProtocol (ip.GetProtocol ());
- demux->Unref ();
+ Ptr<Ipv4L4Demux> demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
+ Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
protocol->Receive (p, ip.GetSource (), ip.GetDestination ());
}
--- a/src/internet-node/ipv4.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4.h Sun May 13 12:52:38 2007 +0100
@@ -27,6 +27,7 @@
#include "ns3/callback-trace-source.h"
#include "ns3/array-trace-resolver.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
#include "l3-protocol.h"
namespace ns3 {
@@ -58,7 +59,7 @@
};
typedef ArrayTraceResolver<Ipv4Interface>::Index InterfaceIndex;
- Ipv4(Node *node);
+ Ipv4(Ptr<Node> node);
virtual ~Ipv4 ();
/**
@@ -164,7 +165,7 @@
* to disable it, you can invoke Ipv4Interface::SetDown which will
* make sure that it is never used during packet forwarding.
*/
- uint32_t AddInterface (NetDevice *device);
+ uint32_t AddInterface (Ptr<NetDevice> device);
/**
* \param i index of interface to return
* \returns the requested interface
@@ -181,7 +182,7 @@
* Try to find an Ipv4Interface whose NetDevice is equal to
* the input NetDevice.
*/
- Ipv4Interface *FindInterfaceForDevice (NetDevice const*device);
+ Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice> device);
/**
@@ -191,7 +192,7 @@
* - implement a per-NetDevice ARP cache
* - send back arp replies on the right device
*/
- virtual void Receive(Packet& p, NetDevice *device);
+ virtual void Receive(Packet& p, Ptr<NetDevice> device);
/**
* \param packet packet to send
@@ -219,7 +220,7 @@
virtual void DoDispose (void);
private:
void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
- bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device);
+ bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
void ForwardUp (Packet p, Ipv4Header const&ip);
uint32_t AddIpv4Interface (Ipv4Interface *interface);
void SetupLoopback (void);
@@ -240,7 +241,7 @@
HostRoutes m_hostRoutes;
NetworkRoutes m_networkRoutes;
Ipv4Route *m_defaultRoute;
- Node *m_node;
+ Ptr<Node> m_node;
CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
CallbackTraceSource<Packet const &> m_dropTrace;
--- a/src/internet-node/l3-demux.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/l3-demux.cc Sun May 13 12:52:38 2007 +0100
@@ -29,14 +29,12 @@
namespace ns3 {
-const Iid L3Demux::iid ("L3Demux");
+const InterfaceId L3Demux::iid ("L3Demux");
-L3Demux::L3Demux (Node *node)
- : NsUnknown (L3Demux::iid),
+L3Demux::L3Demux (Ptr<Node> node)
+ : Interface (L3Demux::iid),
m_node (node)
-{
- m_node->Ref ();
-}
+{}
L3Demux::~L3Demux()
{}
@@ -47,15 +45,11 @@
for (L3Map_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
{
i->second->Dispose ();
- i->second->Unref ();
+ i->second = 0;
}
m_protocols.clear ();
- if (m_node != 0)
- {
- m_node->Unref ();
- m_node = 0;
- }
- NsUnknown::DoDispose ();
+ m_node = 0;
+ Interface::DoDispose ();
}
TraceResolver *
@@ -69,23 +63,25 @@
oss << i->second->GetProtocolNumber ();
ProtocolTraceType context = i->second->GetProtocolNumber ();
resolver->Add (protValue,
- MakeCallback (&L3Protocol::CreateTraceResolver, i->second),
+ MakeCallback (&L3Protocol::CreateTraceResolver, PeekPointer (i->second)),
context);
}
return resolver;
}
-void L3Demux::Insert(L3Protocol *p)
+void L3Demux::Insert(Ptr<L3Protocol> p)
{
- p->Ref ();
m_protocols.insert(L3Map_t::value_type(p->GetProtocolNumber (), p));
}
-L3Protocol*
-L3Demux::PeekProtocol (int p)
+Ptr<L3Protocol>
+L3Demux::GetProtocol (int p)
{ // Look up a protocol by protocol number
L3Map_t::iterator i = m_protocols.find(p);
- if (i == m_protocols.end()) return 0; // Not found
+ if (i == m_protocols.end())
+ {
+ return 0;
+ }
return i->second; // Return the protocol
}
--- a/src/internet-node/l3-demux.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/l3-demux.h Sun May 13 12:52:38 2007 +0100
@@ -28,7 +28,8 @@
#define L3_DEMUX_H
#include <map>
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -40,12 +41,12 @@
/**
* \brief L3 Demux
*/
-class L3Demux : public NsUnknown
+class L3Demux : public Interface
{
public:
- static const Iid iid;
+ static const InterfaceId iid;
typedef int ProtocolTraceType;
- L3Demux(Node *node);
+ L3Demux(Ptr<Node> node);
virtual ~L3Demux();
/**
@@ -67,7 +68,7 @@
* a working L3 Protocol and returned from this method.
* The caller does not get ownership of the returned pointer.
*/
- void Insert(ns3::L3Protocol * protocol);
+ void Insert(Ptr<L3Protocol> protocol);
/**
* \param protocolNumber number of protocol to lookup
* in this L4 Demux
@@ -77,20 +78,13 @@
* to forward packets up the stack to the right protocol.
* It is also called from InternetNode::GetIpv4 for example.
*/
- ns3::L3Protocol* PeekProtocol (int protocolNumber);
- /**
- * \param protocol protocol to remove from this demux.
- *
- * The input value to this method should be the value
- * returned from the L3Protocol::Insert method.
- */
- void Erase(ns3::L3Protocol*protocol);
+ Ptr<L3Protocol> GetProtocol (int protocolNumber);
protected:
virtual void DoDispose (void);
private:
- typedef std::map<int, ns3::L3Protocol*> L3Map_t;
+ typedef std::map<int, Ptr<ns3::L3Protocol> > L3Map_t;
- Node *m_node;
+ Ptr<Node> m_node;
L3Map_t m_protocols;
};
--- a/src/internet-node/l3-protocol.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/l3-protocol.h Sun May 13 12:52:38 2007 +0100
@@ -26,12 +26,12 @@
#define L3_PROTOCOL_H
#include "ns3/object.h"
+#include "ns3/ptr.h"
namespace ns3 {
class Packet;
class NetDevice;
-class Node;
class TraceResolver;
class TraceContext;
@@ -54,7 +54,7 @@
* - implement a per-NetDevice ARP cache
* - send back arp replies on the right device
*/
- virtual void Receive(Packet& p, NetDevice *device) = 0;
+ virtual void Receive(Packet& p, Ptr<NetDevice> device) = 0;
protected:
virtual void DoDispose (void);
--- a/src/internet-node/pcap-trace.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/pcap-trace.cc Sun May 13 12:52:38 2007 +0100
@@ -84,7 +84,7 @@
{
NodeList::NodeIndex nodeIndex;
context.Get (nodeIndex);
- uint32_t nodeId = NodeList::PeekNode (nodeIndex)->GetId ();
+ uint32_t nodeId = NodeList::GetNode (nodeIndex)->GetId ();
PcapWriter *writer = GetStream (nodeId, interfaceIndex);
writer->WritePacket (p);
}
--- a/src/internet-node/udp-socket.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/udp-socket.cc Sun May 13 12:52:38 2007 +0100
@@ -26,7 +26,7 @@
namespace ns3 {
-UdpSocket::UdpSocket (Node *node, Udp *udp)
+UdpSocket::UdpSocket (Ptr<Node> node, Ptr<Udp> udp)
: m_endPoint (0),
m_node (node),
m_udp (udp),
@@ -34,17 +34,10 @@
m_shutdownSend (false),
m_shutdownRecv (false),
m_connected (false)
-{
- m_udp->Ref ();
- m_node->Ref ();
-}
+{}
UdpSocket::~UdpSocket ()
{
- if (m_node != 0)
- {
- m_node->Unref ();
- m_node = 0;
- }
+ m_node = 0;
if (m_endPoint != 0)
{
NS_ASSERT (m_udp != 0);
@@ -60,15 +53,11 @@
m_udp->DeAllocate (m_endPoint);
NS_ASSERT (m_endPoint == 0);
}
- if (m_udp != 0)
- {
- m_udp->Unref ();
- m_udp = 0;
- }
+ m_udp = 0;
}
-Node *
-UdpSocket::PeekNode (void) const
+Ptr<Node>
+UdpSocket::GetNode (void) const
{
return m_node;
}
@@ -76,17 +65,9 @@
void
UdpSocket::Destroy (void)
{
- if (m_node != 0)
- {
- m_node->Unref ();
- m_node = 0;
- }
+ m_node = 0;
m_endPoint = 0;
- if (m_udp != 0)
- {
- m_udp->Unref ();
- m_udp = 0;
- }
+ m_udp = 0;
}
int
UdpSocket::FinishBind (void)
@@ -144,7 +125,7 @@
}
void
-UdpSocket::DoClose(ns3::Callback<void, Socket*> closeCompleted)
+UdpSocket::DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted)
{
// XXX: we should set the close state and check it in all API methods.
if (!closeCompleted.IsNull ())
@@ -155,9 +136,9 @@
void
UdpSocket::DoConnect(const Ipv4Address & address,
uint16_t portNumber,
- ns3::Callback<void, Socket*> connectionSucceeded,
- ns3::Callback<void, Socket*> connectionFailed,
- ns3::Callback<void, Socket*> halfClose)
+ ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
+ ns3::Callback<void, Ptr<Socket> > connectionFailed,
+ ns3::Callback<void, Ptr<Socket> > halfClose)
{
m_defaultAddress = address;
m_defaultPort = portNumber;
@@ -168,9 +149,9 @@
m_connected = true;
}
int
-UdpSocket::DoAccept(ns3::Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
- ns3::Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
- ns3::Callback<void, Socket*> closeRequested)
+UdpSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
+ ns3::Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
+ ns3::Callback<void, Ptr<Socket> > closeRequested)
{
// calling accept on a udp socket is a programming error.
m_errno = EOPNOTSUPP;
@@ -179,7 +160,7 @@
int
UdpSocket::DoSend (const uint8_t* buffer,
uint32_t size,
- ns3::Callback<void, Socket*, uint32_t> dataSent)
+ ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
if (!m_connected)
{
@@ -199,7 +180,7 @@
}
int
UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
- ns3::Callback<void, Socket*, uint32_t> dataSent)
+ ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
if (m_endPoint == 0)
{
@@ -228,7 +209,7 @@
uint16_t port,
const uint8_t *buffer,
uint32_t size,
- ns3::Callback<void, Socket*, uint32_t> dataSent)
+ ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
if (m_connected)
{
@@ -247,12 +228,12 @@
return DoSendPacketTo (p, address, port, dataSent);
}
void
-UdpSocket::DoRecv(ns3::Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
+UdpSocket::DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
{
m_rxCallback = callback;
}
void
-UdpSocket::DoRecvDummy(ns3::Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> callback)
+UdpSocket::DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> callback)
{
m_dummyRxCallback = callback;
}
--- a/src/internet-node/udp-socket.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/udp-socket.h Sun May 13 12:52:38 2007 +0100
@@ -24,6 +24,7 @@
#include <stdint.h>
#include "ns3/callback.h"
#include "ns3/socket.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -38,11 +39,11 @@
/**
* Create an unbound udp socket.
*/
- UdpSocket (Node *node, Udp *udp);
+ UdpSocket (Ptr<Node> node, Ptr<Udp> udp);
virtual ~UdpSocket ();
virtual enum SocketErrno GetErrno (void) const;
- virtual Node *PeekNode (void) const;
+ virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
virtual int Bind (Ipv4Address address);
virtual int Bind (uint16_t port);
@@ -51,25 +52,25 @@
virtual int ShutdownRecv (void);
private:
- virtual void DoClose(ns3::Callback<void, Socket*> closeCompleted);
+ virtual void DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted);
virtual void DoConnect(const Ipv4Address & address,
uint16_t portNumber,
- ns3::Callback<void, Socket*> connectionSucceeded,
- ns3::Callback<void, Socket*> connectionFailed,
- ns3::Callback<void, Socket*> halfClose);
- virtual int DoAccept(ns3::Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
- ns3::Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
- ns3::Callback<void, Socket*> closeRequested);
+ ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
+ ns3::Callback<void, Ptr<Socket> > connectionFailed,
+ ns3::Callback<void, Ptr<Socket> > halfClose);
+ virtual int DoAccept(ns3::Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
+ ns3::Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
+ ns3::Callback<void, Ptr<Socket> > closeRequested);
virtual int DoSend (const uint8_t* buffer,
uint32_t size,
- ns3::Callback<void, Socket*, uint32_t> dataSent);
+ ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
virtual int DoSendTo(const Ipv4Address &address,
uint16_t port,
const uint8_t *buffer,
uint32_t size,
- ns3::Callback<void, Socket*, uint32_t> dataSent);
- virtual void DoRecv(ns3::Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t>);
- virtual void DoRecvDummy(ns3::Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t>);
+ ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
+ virtual void DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t>);
+ virtual void DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t>);
private:
friend class Udp;
@@ -78,15 +79,15 @@
void ForwardUp (const Packet &p, Ipv4Address saddr, uint16_t sport);
void Destroy (void);
int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
- ns3::Callback<void, Socket*, uint32_t> dataSent);
+ ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
Ipv4EndPoint *m_endPoint;
- Node *m_node;
- Udp *m_udp;
+ Ptr<Node> m_node;
+ Ptr<Udp> m_udp;
Ipv4Address m_defaultAddress;
uint16_t m_defaultPort;
- Callback<void,Socket*,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback;
- Callback<void,Socket*,uint8_t const*,uint32_t,const Ipv4Address &,uint16_t> m_rxCallback;
+ Callback<void,Ptr<Socket>,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback;
+ Callback<void,Ptr<Socket>,uint8_t const*,uint32_t,const Ipv4Address &,uint16_t> m_rxCallback;
enum SocketErrno m_errno;
bool m_shutdownSend;
bool m_shutdownRecv;
--- a/src/internet-node/udp.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/udp.cc Sun May 13 12:52:38 2007 +0100
@@ -38,13 +38,11 @@
/* see http://www.iana.org/assignments/protocol-numbers */
const uint8_t Udp::PROT_NUMBER = 17;
-Udp::Udp (Node *node)
+Udp::Udp (Ptr<Node> node)
: Ipv4L4Protocol (PROT_NUMBER, 2),
m_node (node),
m_endPoints (new Ipv4EndPointDemux ())
-{
- m_node->Ref ();
-}
+{}
Udp::~Udp ()
{}
@@ -63,18 +61,15 @@
delete m_endPoints;
m_endPoints = 0;
}
- if (m_node != 0)
- {
- m_node->Unref ();
- m_node = 0;
- }
+ m_node = 0;
Ipv4L4Protocol::DoDispose ();
}
-Socket *
+Ptr<Socket>
Udp::CreateSocket (void)
{
- return new UdpSocket (m_node, this);
+ Ptr<Socket> socket = MakeNewObject<UdpSocket> (m_node, this);
+ return socket;
}
Ipv4EndPoint *
@@ -142,11 +137,10 @@
packet.AddHeader (udpHeader);
- IIpv4Private *ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
+ Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
if (ipv4 != 0)
{
ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
- ipv4->Unref ();
}
}
--- a/src/internet-node/udp.h Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/udp.h Sun May 13 12:52:38 2007 +0100
@@ -26,6 +26,7 @@
#include "ns3/packet.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
#include "ipv4-end-point-demux.h"
#include "ipv4-l4-protocol.h"
@@ -40,12 +41,12 @@
public:
static const uint8_t PROT_NUMBER;
- Udp (Node *node);
+ Udp (Ptr<Node> node);
virtual ~Udp ();
virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
- Socket *CreateSocket (void);
+ Ptr<Socket> CreateSocket (void);
Ipv4EndPoint *Allocate (void);
Ipv4EndPoint *Allocate (Ipv4Address address);
@@ -67,7 +68,7 @@
protected:
virtual void DoDispose (void);
private:
- Node *m_node;
+ Ptr<Node> m_node;
Ipv4EndPointDemux *m_endPoints;
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/application.cc Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,113 @@
+/* -*- 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 "ns3/node.h"
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+#include "ns3/simulator.h"
+
+using namespace std;
+
+namespace ns3 {
+
+// Application Methods
+
+// \brief Application Constructor
+Application::Application(Ptr<Node> n)
+ : m_node (n)
+{
+ m_node->AddApplication (this);
+}
+
+// \brief Application Destructor
+Application::~Application()
+{}
+
+void
+Application::DoDispose (void)
+{
+ m_node = 0;
+ Simulator::Cancel(m_startEvent);
+ Simulator::Cancel(m_stopEvent);
+}
+
+void Application::Start(const Time& startTime)
+{
+ ScheduleStart (startTime);
+}
+
+void Application::Start(const RandomVariable& startVar)
+{
+ RandomVariable *v = startVar.Copy ();
+ ScheduleStart (Seconds (v->GetValue ()));
+ delete v;
+}
+
+
+void Application::Stop(const Time& stopTime)
+{
+ ScheduleStop (stopTime);
+}
+
+void Application::Stop(const RandomVariable& stopVar)
+{
+ RandomVariable *v = stopVar.Copy ();
+ ScheduleStop (Seconds (v->GetValue ()));
+ delete v;
+}
+
+Ptr<Node> Application::GetNode() const
+{
+ return m_node;
+}
+
+// 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 (const Time &startTime)
+{
+ m_startEvent = Simulator::Schedule(startTime -
+ Simulator::Now(),
+ &Application::StartApplication, this);
+}
+
+void Application::ScheduleStop (const Time &stopTime)
+{
+ m_stopEvent = Simulator::Schedule(stopTime -
+ Simulator::Now(),
+ &Application::StopApplication, this);
+}
+
+} //namespace ns3
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/application.h Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,135 @@
+/* -*- 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__
+
+#include "ns3/event-id.h"
+#include "ns3/nstime.h"
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+#include "ns3/node.h"
+
+namespace ns3 {
+
+class Node;
+class RandomVariable;
+
+/**
+ * \brief The base class for all ns3 applicationes
+ *
+ * Class Application is the base class for all ns3 applications.
+ * Applications are associated with individual nodes.
+ *
+ * Conceptually, an application has zero or more Socket
+ * objects associated with it, that are created using the Socket
+ * creation API of the Kernel capability. The Socket object
+ * API is modeled after the
+ * well-known BSD sockets interface, although it is somewhat
+ * simplified for use with ns3. Further, any socket call that
+ * would normally "block" in normal sockets will return immediately
+ * in ns3. A set of "upcalls" are defined that will be called when
+ * the previous blocking call would normally exit. THis is documented
+ * in more detail Socket class in socket.h.
+ */
+class Application : public Object
+{
+public:
+ Application(Ptr<Node>);
+ virtual ~Application();
+
+ /**
+ * \brief Specify application start time
+ * \param startTime Start time for this application, absolute time,
+ * relative to the start of the simulation.
+ *
+ * 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.
+ */
+ void Start(const Time& startTime);
+
+ /**
+ * \brief Specify application start time.
+ * \param startVariable the random variable to use to pick
+ * the real start time as an absolute time, in units of
+ * seconds, relative to the start of the simulation.
+ */
+ void Start(const RandomVariable& startVariable);
+
+ /**
+ * \brief Specify application stop time
+ * \param stopTime Stop time for this application, relative to the
+ * start of the simulation.
+ *
+ * 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, to be notified when that
+ * time has come.
+ */
+ void Stop(const Time& stopTime);
+
+ /**
+ * \brief Specify application stop time
+ * \param stopVariable the random variable to use to pick
+ * the real stop time, in units of seconds,
+ * relative to the start of the simulation.
+ */
+ void Stop(const RandomVariable& stopVariable);
+
+ /**
+ * \returns the Node to which this Application object is attached.
+ */
+ Ptr<Node> GetNode() const;
+
+private:
+ /**
+ * \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 (void);
+
+ /**
+ * \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 (void);
+protected:
+ virtual void DoDispose (void);
+private:
+ void ScheduleStart (const Time &time);
+ void ScheduleStop (const Time &time);
+
+ EventId m_startEvent;
+ EventId m_stopEvent;
+ Ptr<Node> m_node;
+};
+
+} //namespace ns3
+#endif
--- a/src/node/channel.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/channel.cc Sun May 13 12:52:38 2007 +0100
@@ -27,14 +27,18 @@
namespace ns3 {
+const InterfaceId Channel::iid ("Channel");
+
Channel::Channel ()
- : m_name("Channel")
+ : Interface (Channel::iid),
+ m_name("Channel")
{
NS_DEBUG("Channel::Channel ()");
}
Channel::Channel (std::string name)
- : m_name(name)
+ : Interface (Channel::iid),
+ m_name(name)
{
NS_DEBUG("Channel::Channel (" << name << ")");
}
--- a/src/node/channel.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/channel.h Sun May 13 12:52:38 2007 +0100
@@ -24,7 +24,8 @@
#include <string>
#include <stdint.h>
-#include "ns3/object.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -36,9 +37,10 @@
* A channel is a logical path over which information flows. The path can
* be as simple as a short piece of wire, or as complicated as space-time.
*/
-class Channel : public Object
+class Channel : public Interface
{
public:
+ static const InterfaceId iid;
Channel ();
Channel (std::string name);
@@ -57,7 +59,7 @@
*
* This method must be implemented by subclasses.
*/
- virtual NetDevice *GetDevice (uint32_t i) const = 0;
+ virtual Ptr<NetDevice> GetDevice (uint32_t i) const = 0;
protected:
virtual ~Channel ();
--- a/src/node/drop-tail.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/drop-tail.cc Sun May 13 12:52:38 2007 +0100
@@ -27,12 +27,13 @@
static class QueueStackInitializationClass {
public:
QueueStackInitializationClass () {
- Queue::Default (DropTailQueue ());
- static DropTailQueue queue;
- Queue::AddDefault (queue, "DropTailQueue");
+ Queue::AddDefault ("DropTailQueue");
}
} queue_stack_initialization_class;
+const ClassId DropTailQueue::cid =
+ ComponentManager::RegisterConstructor<DropTailQueue> ("DropTailQueue");
+
DropTailQueue::DropTailQueue () :
Queue (),
@@ -47,11 +48,6 @@
NS_DEBUG("DropTailQueue::~DropTailQueue ()");
}
-DropTailQueue* DropTailQueue::Copy() const
-{
- return new DropTailQueue(*this);
-}
-
void
DropTailQueue::SetMaxPackets (uint32_t npackets)
{
--- a/src/node/drop-tail.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/drop-tail.h Sun May 13 12:52:38 2007 +0100
@@ -23,6 +23,7 @@
#include <queue>
#include "ns3/packet.h"
#include "ns3/queue.h"
+#include "ns3/component-manager.h"
namespace ns3 {
@@ -32,10 +33,10 @@
class DropTailQueue : public Queue {
public:
+ static const ClassId cid;
DropTailQueue ();
virtual ~DropTailQueue();
- virtual DropTailQueue* Copy() const;
void SetMaxPackets (uint32_t npackets);
uint32_t GetMaxPackets (void);
--- a/src/node/i-ipv4.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/i-ipv4.cc Sun May 13 12:52:38 2007 +0100
@@ -22,10 +22,10 @@
namespace ns3 {
-const Iid IIpv4::iid ("IIpv4");
+const InterfaceId IIpv4::iid ("IIpv4");
IIpv4::IIpv4 ()
- : NsUnknown (IIpv4::iid)
+ : Interface (IIpv4::iid)
{}
IIpv4::~IIpv4 ()
--- a/src/node/i-ipv4.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/i-ipv4.h Sun May 13 12:52:38 2007 +0100
@@ -23,7 +23,7 @@
#include <stdint.h>
#include "ns3/ipv4-address.h"
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
namespace ns3 {
@@ -31,10 +31,10 @@
class Packet;
class Ipv4Route;
-class IIpv4 : public NsUnknown
+class IIpv4 : public Interface
{
public:
- static const Iid iid;
+ static const InterfaceId iid;
IIpv4 ();
virtual ~IIpv4 ();
@@ -116,12 +116,18 @@
* to disable it, you can invoke Ipv4Interface::SetDown which will
* make sure that it is never used during packet forwarding.
*/
- virtual uint32_t AddInterface (NetDevice *device) = 0;
+ virtual uint32_t AddInterface (Ptr<NetDevice> device) = 0;
/**
* \returns the number of interfaces added by the user.
*/
virtual uint32_t GetNInterfaces (void) = 0;
+ /**
+ * \param index of interface
+ * \returns address of the NetDevice associated with the ipv4 interface
+ */
+ virtual Ptr<NetDevice> GetNetDevice (uint32_t i) = 0;
+
virtual void SetAddress (uint32_t i, Ipv4Address address) = 0;
virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0;
virtual Ipv4Mask GetNetworkMask (uint32_t t) const = 0;
--- a/src/node/i-udp.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/i-udp.cc Sun May 13 12:52:38 2007 +0100
@@ -22,10 +22,10 @@
namespace ns3 {
-const Iid IUdp::iid ("IUdp");
+const InterfaceId IUdp::iid ("IUdp");
IUdp::IUdp ()
- : NsUnknown (IUdp::iid)
+ : Interface (IUdp::iid)
{}
} // namespace ns3
--- a/src/node/i-udp.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/i-udp.h Sun May 13 12:52:38 2007 +0100
@@ -21,20 +21,21 @@
#ifndef I_UDP_H
#define I_UDP_H
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
namespace ns3 {
class Socket;
-class IUdp : public NsUnknown
+class IUdp : public Interface
{
public:
- static const Iid iid;
+ static const InterfaceId iid;
IUdp ();
- virtual Socket *CreateSocket (void) = 0;
+ virtual Ptr<Socket> CreateSocket (void) = 0;
};
} // namespace ns3
--- a/src/node/mac-address.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/mac-address.h Sun May 13 12:52:38 2007 +0100
@@ -19,10 +19,6 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
-/*
- * This implementation borrowed from yans
- */
-
#ifndef MAC_ADDRESS_H
#define MAC_ADDRESS_H
--- a/src/node/net-device.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/net-device.cc Sun May 13 12:52:38 2007 +0100
@@ -21,15 +21,19 @@
#include <iostream>
#include "ns3/assert.h"
+#include "ns3/interface.h"
+#include "channel.h"
#include "net-device.h"
#include "llc-snap-header.h"
#include "node.h"
-#include "ns3/channel.h"
namespace ns3 {
-NetDevice::NetDevice(Node *node, const MacAddress& addr) :
+const InterfaceId NetDevice::iid ("NetDevice");
+
+NetDevice::NetDevice(Ptr<Node> node, const MacAddress& addr) :
+ Interface (NetDevice::iid),
m_node (node),
m_name(""),
m_ifIndex (0),
@@ -40,14 +44,11 @@
m_isMulticast (false),
m_isPointToPoint (false)
{
- m_node->Ref ();
+ m_node->AddDevice (this);
}
NetDevice::~NetDevice ()
-{
- m_node->Unref ();
- m_node = 0;
-}
+{}
MacAddress
NetDevice::GetAddress (void) const
@@ -188,7 +189,7 @@
return DoCreateTraceResolver (context);
}
-Channel *
+Ptr<Channel>
NetDevice::GetChannel (void) const
{
return DoGetChannel ();
@@ -228,8 +229,8 @@
}
}
-Node *
-NetDevice::PeekNode (void) const
+Ptr<Node>
+NetDevice::GetNode (void) const
{
return m_node;
}
@@ -241,13 +242,15 @@
}
void
-NetDevice::SetReceiveCallback (Callback<bool,NetDevice *,const Packet &,uint16_t> cb)
+NetDevice::SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb)
{
m_receiveCallback = cb;
}
void
NetDevice::DoDispose()
-{}
+{
+ m_node = 0;
+}
}; // namespace ns3
--- a/src/node/net-device.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/net-device.h Sun May 13 12:52:38 2007 +0100
@@ -25,7 +25,8 @@
#include <stdint.h>
#include "ns3/callback.h"
#include "ns3/packet.h"
-#include "ns3/object.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
#include "mac-address.h"
namespace ns3 {
@@ -54,14 +55,10 @@
* this base class and implement your own version of the
* NetDevice::SendTo method.
*/
-class NetDevice : public Object
+class NetDevice : public Interface
{
public:
- /**
- * \param node base class node pointer of device's node
- * \param addr MAC address of this device.
- */
- NetDevice(Node* node, const MacAddress& addr);
+ static const InterfaceId iid;
virtual ~NetDevice();
/**
@@ -78,7 +75,7 @@
* returned can be zero if the NetDevice is not yet connected
* to any channel.
*/
- Channel *GetChannel (void) const;
+ Ptr<Channel> GetChannel (void) const;
/**
* \return the current MacAddress of this interface.
@@ -109,7 +106,7 @@
/**
* \param index ifIndex of the device
*/
- void SetIfIndex(const uint32_t);
+ void SetIfIndex(const uint32_t index);
/**
* \return index ifIndex of the device
*/
@@ -169,14 +166,29 @@
* base class to print the nodeid for example, it can invoke
* this method.
*/
- Node* PeekNode (void) const;
+ Ptr<Node> GetNode (void) const;
+ /**
+ * \returns true if ARP is needed, false otherwise.
+ *
+ * Called by higher-layers to check if this NetDevice requires
+ * ARP to be used.
+ */
bool NeedsArp (void) const;
- void SetReceiveCallback (Callback<bool,NetDevice *,const Packet &,uint16_t> cb);
+ /**
+ * \param cb callback to invoke whenever a packet has been received and must
+ * be forwarded to the higher layers.
+ */
+ void SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb);
protected:
/**
+ * \param node base class node pointer of device's node
+ * \param addr MAC address of this device.
+ */
+ NetDevice(Ptr<Node> node, const MacAddress& addr);
+ /**
* Enable broadcast support. This method should be
* called by subclasses from their constructor
*/
@@ -224,6 +236,12 @@
*/
bool ForwardUp (Packet& p);
+ /**
+ * The dispose method for this NetDevice class.
+ * Subclasses are expected to override this method _and_
+ * to chain up to it by calling NetDevice::DoDispose
+ * at the end of their own DoDispose method.
+ */
virtual void DoDispose (void);
private:
@@ -238,10 +256,30 @@
* subclasses to forward packets. Subclasses MUST override this method.
*/
virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
+ /**
+ * \returns true if this NetDevice needs the higher-layers
+ * to perform ARP over it, false otherwise.
+ *
+ * Subclasses must implement this method.
+ */
virtual bool DoNeedsArp (void) const = 0;
+ /**
+ * \param context the trace context to associated to the
+ * trace resolver.
+ * \returns a trace resolver associated to the input context.
+ * the caller takes ownership of the pointer returned.
+ *
+ * Subclasses must implement this method.
+ */
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
- virtual Channel *DoGetChannel (void) const = 0;
- Node* m_node;
+ /**
+ * \returns the channel associated to this NetDevice.
+ *
+ * Subclasses must implement this method.
+ */
+ virtual Ptr<Channel> DoGetChannel (void) const = 0;
+
+ Ptr<Node> m_node;
std::string m_name;
uint16_t m_ifIndex;
MacAddress m_address;
@@ -252,7 +290,7 @@
bool m_isMulticast;
bool m_isPointToPoint;
Callback<void> m_linkChangeCallback;
- Callback<bool,NetDevice *,const Packet &,uint16_t> m_receiveCallback;
+ Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
};
}; // namespace ns3
--- a/src/node/node-list.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/node-list.cc Sun May 13 12:52:38 2007 +0100
@@ -49,37 +49,37 @@
NodeListPriv ();
~NodeListPriv ();
- uint32_t Add (Node *node);
+ uint32_t Add (Ptr<Node> node);
NodeList::Iterator Begin (void);
NodeList::Iterator End (void);
TraceResolver *CreateTraceResolver (TraceContext const &context);
Node *PeekNode (uint32_t n);
+ Ptr<Node> GetNode (uint32_t n);
uint32_t GetNNodes (void);
private:
- std::vector<Node *> m_nodes;
+ std::vector<Ptr<Node> > m_nodes;
};
NodeListPriv::NodeListPriv ()
{}
NodeListPriv::~NodeListPriv ()
{
- for (std::vector<Node *>::iterator i = m_nodes.begin ();
+ for (std::vector<Ptr<Node> >::iterator i = m_nodes.begin ();
i != m_nodes.end (); i++)
{
- Node *node = *i;
+ Ptr<Node> node = *i;
node->Dispose ();
- node->Unref ();
+ *i = 0;
}
m_nodes.erase (m_nodes.begin (), m_nodes.end ());
}
uint32_t
-NodeListPriv::Add (Node *node)
+NodeListPriv::Add (Ptr<Node> node)
{
uint32_t index = m_nodes.size ();
- node->Ref ();
m_nodes.push_back (node);
return index;
@@ -102,9 +102,16 @@
Node *
NodeListPriv::PeekNode (uint32_t n)
{
+ return PeekPointer (m_nodes[n]);
+}
+
+Ptr<Node>
+NodeListPriv::GetNode (uint32_t n)
+{
return m_nodes[n];
}
+
TraceResolver *
NodeListPriv::CreateTraceResolver (TraceContext const &context)
{
@@ -126,7 +133,7 @@
namespace ns3 {
uint32_t
-NodeList::Add (Node *node)
+NodeList::Add (Ptr<Node> node)
{
return SimulationSingleton<NodeListPriv>::Get ()->Add (node);
}
@@ -145,10 +152,10 @@
{
return SimulationSingleton<NodeListPriv>::Get ()->CreateTraceResolver (context);
}
-Node *
-NodeList::PeekNode (uint32_t n)
+Ptr<Node>
+NodeList::GetNode (uint32_t n)
{
- return SimulationSingleton<NodeListPriv>::Get ()->PeekNode (n);
+ return SimulationSingleton<NodeListPriv>::Get ()->GetNode (n);
}
--- a/src/node/node-list.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/node-list.h Sun May 13 12:52:38 2007 +0100
@@ -24,6 +24,7 @@
#include <vector>
#include "ns3/array-trace-resolver.h"
+#include "ns3/ptr.h"
namespace ns3 {
@@ -31,18 +32,48 @@
class TraceResolver;
class TraceContext;
+/**
+ * \brief the list of simulation nodes.
+ *
+ * Every Node created is automatically added to this list.
+ */
class NodeList
{
public:
typedef ArrayTraceResolver<Node>::Index NodeIndex;
- typedef std::vector<Node *>::iterator Iterator;
+ typedef std::vector< Ptr<Node> >::iterator Iterator;
- static uint32_t Add (Node *node);
+ /**
+ * \param node node to add
+ * \returns index of node in list.
+ *
+ * This method is called automatically from Node::Node so
+ * the user has little reason to call it himself.
+ */
+ static uint32_t Add (Ptr<Node> node);
+ /**
+ * \returns a C++ iterator located at the beginning of this
+ * list.
+ */
static Iterator Begin (void);
+ /**
+ * \returns a C++ iterator located at the end of this
+ * list.
+ */
static Iterator End (void);
+ /**
+ * \param context trace context to use for trace resolver
+ * to create.
+ * \returns the requested trace resolver. The caller
+ * takes ownership of the returned pointer.
+ */
static TraceResolver *CreateTraceResolver (TraceContext const &context);
- static Node *PeekNode (uint32_t n);
+ /**
+ * \param n index of requested node.
+ * \returns the Node associated to index n.
+ */
+ static Ptr<Node> GetNode (uint32_t n);
};
}//namespace ns3
--- a/src/node/node.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/node.cc Sun May 13 12:52:38 2007 +0100
@@ -25,14 +25,15 @@
#include "node.h"
#include "node-list.h"
#include "net-device.h"
+#include "application.h"
#include "ns3/simulator.h"
namespace ns3{
-const Iid Node::iid ("Node");
+const InterfaceId Node::iid ("Node");
Node::Node()
- : NsUnknown (Node::iid),
+ : Interface (Node::iid),
m_id(0),
m_sid(0)
{
@@ -40,7 +41,7 @@
}
Node::Node(uint32_t sid)
- : NsUnknown (Node::iid),
+ : Interface (Node::iid),
m_id(0),
m_sid(sid)
{
@@ -50,6 +51,12 @@
Node::~Node ()
{}
+TraceResolver *
+Node::CreateTraceResolver (TraceContext const &context)
+{
+ return DoCreateTraceResolver (context);
+}
+
uint32_t
Node::GetId (void) const
{
@@ -62,23 +69,16 @@
return m_sid;
}
-void
-Node::SetSystemId(uint32_t s )
+uint32_t
+Node::AddDevice (Ptr<NetDevice> device)
{
- m_sid = s;
-}
-
-uint32_t
-Node::AddDevice (NetDevice *device)
-{
- device->Ref ();
uint32_t index = m_devices.size ();
m_devices.push_back (device);
DoAddDevice (device);
device->SetIfIndex(index);
return index;
}
-NetDevice *
+Ptr<NetDevice>
Node::GetDevice (uint32_t index) const
{
return m_devices[index];
@@ -89,17 +89,44 @@
return m_devices.size ();
}
+uint32_t
+Node::AddApplication (Ptr<Application> application)
+{
+ uint32_t index = m_applications.size ();
+ m_applications.push_back (application);
+ return index;
+}
+Ptr<Application>
+Node::GetApplication (uint32_t index) const
+{
+ return m_applications[index];
+}
+uint32_t
+Node::GetNApplications (void) const
+{
+ return m_applications.size ();
+}
+
+
void Node::DoDispose()
{
- for (std::vector<NetDevice *>::iterator i = m_devices.begin ();
+ for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
i != m_devices.end (); i++)
{
- NetDevice *device = *i;
+ Ptr<NetDevice> device = *i;
device->Dispose ();
- device->Unref ();
+ *i = 0;
}
m_devices.clear ();
- NsUnknown::DoDispose ();
+ for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
+ i != m_applications.end (); i++)
+ {
+ Ptr<Application> application = *i;
+ application->Dispose ();
+ *i = 0;
+ }
+ m_applications.clear ();
+ Interface::DoDispose ();
}
}//namespace ns3
--- a/src/node/node.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/node.h Sun May 13 12:52:38 2007 +0100
@@ -27,41 +27,145 @@
#include <vector>
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
namespace ns3 {
class TraceContext;
class TraceResolver;
class NetDevice;
+class Application;
-class Node : public NsUnknown
+/**
+ * \brief A network Node.
+ *
+ * This class holds together:
+ * - a list of NetDevice objects which represent the network interfaces
+ * of this node which are connected to other Node instances through
+ * Channel instances.
+ * - a list of Application objects which represent the userspace
+ * traffic generation applications which interact with the Node
+ * through the Socket API.
+ * - a node Id: a unique per-node identifier.
+ * - a system Id: a unique Id used for parallel simulations.
+ * - a trace resolver which can be used to connect user trace sinks
+ * to the node's trace sources.
+ *
+ * Every Node created is added to the NodeList automatically.
+ */
+class Node : public Interface
{
public:
- static const Iid iid;
+ static const InterfaceId iid;
- Node();
- Node(uint32_t); // Specify which system for a distributed simulation
virtual ~Node();
- virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
+ /**
+ * \param context the trace context for the TraceResolver to create
+ * \returns a newly-created TraceResolver. The caller takes
+ * ownership of the returned pointer.
+ *
+ * Request the Node to create a trace resolver. This method
+ * could be used directly by a user who needs access to very low-level
+ * trace configuration.
+ */
+ TraceResolver *CreateTraceResolver (TraceContext const &context);
+ /**
+ * \returns the unique id of this node.
+ *
+ * This unique id happens to be also the index of the Node into
+ * the NodeList.
+ */
uint32_t GetId (void) const;
+
+ /**
+ * \returns the system id for parallel simulations associated
+ * to this node.
+ */
uint32_t GetSystemId (void) const;
- void SetSystemId(uint32_t s);
- uint32_t AddDevice (NetDevice *device);
- NetDevice *GetDevice (uint32_t index) const;
+ /**
+ * \param device NetDevice to associate to this node.
+ * \returns the index of the NetDevice into the Node's list of
+ * NetDevice.
+ *
+ * Associate this device to this node.
+ * This method is called automatically from NetDevice::NetDevice
+ * so the user has little reason to call this method himself.
+ */
+ uint32_t AddDevice (Ptr<NetDevice> device);
+ /**
+ * \param index the index of the requested NetDevice
+ * \returns the requested NetDevice associated to this Node.
+ */
+ Ptr<NetDevice> GetDevice (uint32_t index) const;
+ /**
+ * \returns the number of NetDevice instances associated
+ * to this Node.
+ */
uint32_t GetNDevices (void) const;
+ /**
+ * \param application Application to associate to this node.
+ * \returns the index of the Application within the Node's list
+ * of Application.
+ *
+ * Associated this Application to this Node. This method is called
+ * automatically from Application::Application so the user
+ * has little reasons to call this method directly.
+ */
+ uint32_t AddApplication (Ptr<Application> application);
+ /**
+ * \param index
+ * \returns the application associated to this requested index
+ * within this Node.
+ */
+ Ptr<Application> GetApplication (uint32_t index) const;
+ /**
+ * \returns the number of applications associated to this Node.
+ */
+ uint32_t GetNApplications (void) const;
+
protected:
+ /**
+ * Must be invoked by subclasses only.
+ */
+ Node();
+ /**
+ * \param systemId a unique integer used for parallel simulations.
+ *
+ * Must be invoked by subclasses only.
+ */
+ Node(uint32_t systemId);
+ /**
+ * The dispose method. Subclasses must override this method
+ * and must chain up to it by calling Node::DoDispose at the
+ * end of their own DoDispose method.
+ */
virtual void DoDispose (void);
private:
- virtual void DoAddDevice (NetDevice *device) const = 0;
+ /**
+ * \param context the trace context
+ * \returns a trace resolver to the user. The user must delete it.
+ *
+ * Subclasses must implement this method.
+ */
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
+ /**
+ * \param device the device added to this Node.
+ *
+ * This method is invoked whenever a user calls Node::AddDevice.
+ * Subclasses are expected to call NetDevice::SetReceiveCallback
+ * at this point to setup the node's receive function for
+ * the NetDevice packets.
+ */
+ virtual void DoAddDevice (Ptr<NetDevice> device) const = 0;
uint32_t m_id; // Node id for this node
uint32_t m_sid; // System id for this node
- std::vector<NetDevice *> m_devices;
+ std::vector<Ptr<NetDevice> > m_devices;
+ std::vector<Ptr<Application> > m_applications;
};
} //namespace ns3
--- a/src/node/queue.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/queue.cc Sun May 13 12:52:38 2007 +0100
@@ -19,16 +19,18 @@
#include "ns3/debug.h"
#include "ns3/composite-trace-resolver.h"
+#include "ns3/default-value.h"
+#include "ns3/component-manager.h"
#include "queue.h"
-#include "ns3/default-value.h"
NS_DEBUG_COMPONENT_DEFINE ("Queue");
namespace ns3 {
-Queue* Queue::defaultQueue = 0;
+const InterfaceId Queue::iid ("Queue");
Queue::Queue() :
+ Interface (Queue::iid),
m_nBytes(0),
m_nTotalReceivedBytes(0),
m_nPackets(0),
@@ -194,50 +196,23 @@
m_traceDrop (p);
}
-// Static methods for managing default queue
-
-// Set new default
-void Queue::Default(const Queue& q)
-{
- delete defaultQueue; // delete previous (if any)
- defaultQueue = q.Copy(); // set new default
-}
-
-// Get current default
-Queue& Queue::Default()
-{
- // ! Need to schedule an "at end" event to delete the default
- return *defaultQueue;
-}
-
-
-Queue *
+Ptr<Queue>
Queue::CreateDefault (void)
{
std::string defaultValue = GetDefault ()->GetValue ();
- for (List::iterator i = GetList ()->begin ();
- i != GetList ()->end (); i++)
- {
- if (i->second == defaultValue)
- {
- return i->first->Copy ();
- }
- }
- NS_ASSERT (false);
- // quiet compiler
- return 0;
+ ClassId classId = ComponentManager::LookupByName (defaultValue);
+ Ptr<Queue> queue = ComponentManager::Create<Queue> (classId, Queue::iid);
+ return queue;
}
void
-Queue::Add (Queue &queue, const std::string &name)
+Queue::Add (const std::string &name)
{
GetDefault ()->AddPossibleValue (name);
- GetList ()->push_back (std::make_pair (&queue, name));
}
void
-Queue::AddDefault (Queue &queue, const std::string &name)
+Queue::AddDefault (const std::string &name)
{
GetDefault ()->AddDefaultValue (name);
- GetList ()->push_back (std::make_pair (&queue, name));
}
StringEnumDefaultValue *
Queue::GetDefault (void)
@@ -245,12 +220,6 @@
static StringEnumDefaultValue value ("Queue", "Packet Queue");
return &value;
}
-Queue::List *
-Queue::GetList (void)
-{
- static List list;
- return &list;
-}
}; // namespace ns3
--- a/src/node/queue.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/queue.h Sun May 13 12:52:38 2007 +0100
@@ -28,6 +28,7 @@
#include <string>
#include <list>
#include "ns3/packet.h"
+#include "ns3/interface.h"
#include "ns3/callback-trace-source.h"
#include "ns3/trace-resolver.h"
@@ -35,9 +36,11 @@
class StringEnumDefaultValue;
-class Queue
+class Queue : public Interface
{
public:
+ static const InterfaceId iid;
+
enum TraceType {
ENQUEUE,
DEQUEUE,
@@ -46,8 +49,6 @@
Queue ();
virtual ~Queue ();
- virtual Queue* Copy() const = 0;
-
TraceResolver *CreateTraceResolver (TraceContext const &context);
bool IsEmpty (void);
@@ -112,22 +113,13 @@
uint32_t m_nTotalDroppedPackets;
public:
- static Queue *CreateDefault (void);
- static void Add (Queue &queue, const std::string &name);
- static void AddDefault (Queue &queue, const std::string &name);
+ static Ptr<Queue> CreateDefault (void);
+ static void Add (const std::string &name);
+ static void AddDefault (const std::string &name);
private:
typedef std::list<std::pair<Queue *,std::string> > List;
static StringEnumDefaultValue *GetDefault (void);
static List *GetList (void);
-
-public:
- // Static methods to manage queue default
- // Set desired queue default
- static void Default(const Queue& q);
- // Return reference to the current default queue type
- static Queue& Default();
- // Static variable pointing to current default queue
- static Queue* defaultQueue;
};
}; // namespace ns3
--- a/src/node/socket.cc Sun May 13 12:46:18 2007 +0100
+++ b/src/node/socket.cc Sun May 13 12:52:38 2007 +0100
@@ -6,7 +6,7 @@
{}
void
-Socket::Close(Callback<void, Socket*> closeCompleted)
+Socket::Close(Callback<void, Ptr<Socket> > closeCompleted)
{
DoClose (closeCompleted);
}
@@ -14,23 +14,23 @@
void
Socket::Connect(const Ipv4Address & address,
uint16_t portNumber,
- Callback<void, Socket*> connectionSucceeded,
- Callback<void, Socket*> connectionFailed,
- Callback<void, Socket*> halfClose)
+ Callback<void, Ptr<Socket> > connectionSucceeded,
+ Callback<void, Ptr<Socket> > connectionFailed,
+ Callback<void, Ptr<Socket> > halfClose)
{
DoConnect (address, portNumber, connectionSucceeded, connectionFailed, halfClose);
}
int
-Socket::Accept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
- Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
- Callback<void, Socket*> closeRequested)
+Socket::Accept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
+ Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
+ Callback<void, Ptr<Socket> > closeRequested)
{
return DoAccept (connectionRequest, newConnectionCreated, closeRequested);
}
int
Socket::Send (const uint8_t* buffer,
uint32_t size,
- Callback<void, Socket*, uint32_t> dataSent)
+ Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
return DoSend (buffer, size, dataSent);
}
@@ -39,42 +39,42 @@
uint16_t port,
const uint8_t *buffer,
uint32_t size,
- Callback<void, Socket*, uint32_t> dataSent)
+ Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
return DoSendTo (address, port, buffer, size, dataSent);
}
void
-Socket::Recv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
+Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
{
DoRecv (callback);
}
void
-Socket::RecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> callback)
+Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> callback)
{
DoRecvDummy (callback);
}
bool
-Socket::RefuseAllConnections (Socket* socket, const Ipv4Address& address, uint16_t port)
+Socket::RefuseAllConnections (Ptr<Socket> socket, const Ipv4Address& address, uint16_t port)
{
return false;
}
void
-Socket::DummyCallbackVoidSocket (Socket *socket)
+Socket::DummyCallbackVoidSocket (Ptr<Socket> socket)
{}
void
-Socket::DummyCallbackVoidSocketUi32 (Socket *socket, uint32_t)
+Socket::DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t)
{}
void
-Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Socket *socket, uint32_t, const Ipv4Address &, uint16_t)
+Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr<Socket> socket, uint32_t, const Ipv4Address &, uint16_t)
{}
void
-Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Socket *socket, const uint8_t *, uint32_t,
+Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr<Socket> socket, const uint8_t *, uint32_t,
const Ipv4Address &, uint16_t)
{}
void
-Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Socket *socket, const Ipv4Address &, uint16_t)
+Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Ptr<Socket> socket, const Ipv4Address &, uint16_t)
{}
--- a/src/node/socket.h Sun May 13 12:46:18 2007 +0100
+++ b/src/node/socket.h Sun May 13 12:52:38 2007 +0100
@@ -22,6 +22,7 @@
#define __SOCKET_H__
#include "ns3/callback.h"
+#include "ns3/ptr.h"
#include "ipv4-address.h"
#include "ns3/object.h"
#include <stdint.h>
@@ -65,7 +66,7 @@
/**
* \returns the node this socket is associated with.
*/
- virtual Node *PeekNode (void) const = 0;
+ virtual Ptr<Node> GetNode (void) const = 0;
/**
* Allocate a free port number and
@@ -113,7 +114,7 @@
* After the Close call, the socket is no longer valid, and cannot
* safely be used for subsequent operations.
*/
- void Close(Callback<void, Socket*> closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
+ void Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
/**
* \returns zero on success, -1 on failure.
@@ -146,9 +147,9 @@
*/
void Connect(const Ipv4Address & address,
uint16_t portNumber,
- Callback<void, Socket*> connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
- Callback<void, Socket*> connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
- Callback<void, Socket*> halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
+ Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
+ Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
+ Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
/**
* \brief Accept connection requests from remote hosts
@@ -169,11 +170,11 @@
* \param closeRequested Callback for connection close request from peer.
* XXX: when is this callback invoked ?
*/
- int Accept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest =
+ int Accept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest =
MakeCallback(&Socket::RefuseAllConnections),
- Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated =
+ Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated =
MakeCallback (&Socket::DummyCallbackVoidSocketIpv4AddressUi16),
- Callback<void, Socket*> closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
+ Callback<void, Ptr<Socket> > closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
/**
* \brief Send data (or dummy data) to the remote host
@@ -185,7 +186,7 @@
*/
int Send (const uint8_t* buffer,
uint32_t size,
- Callback<void, Socket*, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
+ Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
/**
* \brief Send data to a specified peer.
@@ -201,59 +202,59 @@
uint16_t port,
const uint8_t *buffer,
uint32_t size,
- Callback<void, Socket*, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
+ Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
/**
* \brief Receive data
- * \param Received data callback. Invoked whenever new data is received.
+ * \param receivedData Invoked whenever new data is received.
*
* If you wish to transport only dummy packets, this method is not a very
* efficient way to receive these dummy packets: it will trigger a memory
* allocation to hold the dummy memory into a buffer which can be passed
* to the user. Instead, consider using the RecvDummy method.
*/
- void Recv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> =
+ void Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receivedData =
MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16));
/**
* \brief Receive data
- * \param Received data callback. Invoked whenever new data is received.
+ * \param receivedData Invoked whenever new data is received.
*
* This method is included because it is vastly more efficient than the
* Recv method when you use dummy payload.
*/
- void RecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> =
+ void RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> receivedData =
MakeCallback (&Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16));
private:
- virtual void DoClose(Callback<void, Socket*> closeCompleted) = 0;
+ virtual void DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
virtual void DoConnect(const Ipv4Address & address,
uint16_t portNumber,
- Callback<void, Socket*> connectionSucceeded,
- Callback<void, Socket*> connectionFailed,
- Callback<void, Socket*> halfClose) = 0;
- virtual int DoAccept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
- Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
- Callback<void, Socket*> closeRequested) = 0;
+ Callback<void, Ptr<Socket> > connectionSucceeded,
+ Callback<void, Ptr<Socket> > connectionFailed,
+ Callback<void, Ptr<Socket> > halfClose) = 0;
+ virtual int DoAccept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
+ Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
+ Callback<void, Ptr<Socket> > closeRequested) = 0;
virtual int DoSend (const uint8_t* buffer,
uint32_t size,
- Callback<void, Socket*, uint32_t> dataSent) = 0;
+ Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
virtual int DoSendTo(const Ipv4Address &address,
uint16_t port,
const uint8_t *buffer,
uint32_t size,
- Callback<void, Socket*, uint32_t> dataSent) = 0;
- virtual void DoRecv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0;
- virtual void DoRecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t>) = 0;
+ Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
+ virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0;
+ virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t>) = 0;
- static bool RefuseAllConnections (Socket* socket, const Ipv4Address& address, uint16_t port);
- static void DummyCallbackVoidSocket (Socket *socket);
- static void DummyCallbackVoidSocketUi32 (Socket *socket, uint32_t);
- static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Socket *socket, uint32_t, const Ipv4Address &, uint16_t);
- static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Socket *socket, const uint8_t *, uint32_t,
+ static bool RefuseAllConnections (Ptr<Socket> socket, const Ipv4Address& address, uint16_t port);
+ static void DummyCallbackVoidSocket (Ptr<Socket> socket);
+ static void DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t);
+ static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr<Socket> socket, uint32_t, const Ipv4Address &, uint16_t);
+ static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr<Socket> socket, const uint8_t *, uint32_t,
const Ipv4Address &, uint16_t);
- static void DummyCallbackVoidSocketIpv4AddressUi16 (Socket *socket, const Ipv4Address &, uint16_t);
+ static void DummyCallbackVoidSocketIpv4AddressUi16 (Ptr<Socket> socket, const Ipv4Address &, uint16_t);
};
} //namespace ns3
--- a/src/node/wscript Sun May 13 12:46:18 2007 +0100
+++ b/src/node/wscript Sun May 13 12:52:38 2007 +0100
@@ -20,6 +20,7 @@
'socket.cc',
'i-udp.cc',
'i-ipv4.cc',
+ 'application.cc',
]
headers = bld.create_obj('ns3header')
@@ -37,4 +38,5 @@
'socket.h',
'i-udp.h',
'i-ipv4.h',
+ 'application.h',
]