diff --git a/SConstruct b/SConstruct index 7faa5a2af..e191b5b4e 100644 --- a/SConstruct +++ b/SConstruct @@ -25,12 +25,12 @@ core.add_sources([ '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 @@ core.add_inst_headers([ '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 @@ node.add_sources ([ 'socket.cc', 'i-udp.cc', 'i-ipv4.cc', + 'application.cc', ]) node.add_inst_headers ([ 'node.h', @@ -224,25 +225,22 @@ node.add_inst_headers ([ '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 @@ sample_default_value.add_source('main-default-value.cc') 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() diff --git a/examples/simple-p2p.cc b/examples/simple-p2p.cc index fb4f91311..28028aeca 100644 --- a/examples/simple-p2p.cc +++ b/examples/simple-p2p.cc @@ -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 @@ int main (int argc, char *argv[]) // 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 n0 = MakeNewObject (); + Ptr n1 = MakeNewObject (); + Ptr n2 = MakeNewObject (); + Ptr n3 = MakeNewObject (); // We create the channels first without any IP addressing information - PointToPointChannel *channel0 = + Ptr channel0 = PointToPointTopology::AddPointToPointLink ( n0, n2, DataRate(5000000), MilliSeconds(2)); - PointToPointChannel *channel1 = + Ptr channel1 = PointToPointTopology::AddPointToPointLink ( n1, n2, DataRate(5000000), MilliSeconds(2)); - PointToPointChannel *channel2 = + Ptr channel2 = PointToPointTopology::AddPointToPointLink ( n2, n3, DataRate(1500000), MilliSeconds(10)); @@ -122,21 +122,27 @@ int main (int argc, char *argv[]) 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 ooff = MakeNewObject ( n0, Ipv4Address("10.1.3.2"), 80, @@ -144,19 +150,12 @@ int main (int argc, char *argv[]) ConstantVariable(0), DataRate(448000), 210); - // Add to Node's ApplicationList (takes ownership of pointer) - ApplicationList *apl0 = n0->QueryInterface - (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 ( n3, Ipv4Address("10.1.2.1"), 80, @@ -164,30 +163,18 @@ int main (int argc, char *argv[]) ConstantVariable(0), DataRate(448000), 210); - // Add to Node's ApplicationList (takes ownership of pointer) - ApplicationList *apl3 = n3->QueryInterface (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 ipv4; ipv4 = n0->QueryInterface (IIpv4::iid); ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); - ipv4->Unref (); ipv4 = n3->QueryInterface (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 @@ int main (int argc, char *argv[]) // Also configure some tcpdump traces; each interface will be traced // The output files will be named simple-p2p.pcap-- - // 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 (); diff --git a/samples/main-ptr.cc b/samples/main-ptr.cc index aa350f040..67f20df04 100644 --- a/samples/main-ptr.cc +++ b/samples/main-ptr.cc @@ -1,10 +1,11 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ #include "ns3/ptr.h" +#include "ns3/object.h" #include using namespace ns3; -class A +class A : public Object { public: A (); @@ -48,7 +49,7 @@ int main (int argc, char *argv[]) { // Create a new object of type A, store it in global // variable g_a - Ptr a = new A (); + Ptr a = MakeNewObject (); a->Method (); Ptr prev = StoreA (a); NS_ASSERT (prev == 0); @@ -57,18 +58,17 @@ int main (int argc, char *argv[]) { // Create a new object of type A, store it in global // variable g_a, get a hold on the previous A object. - Ptr a = new A (); + Ptr a = MakeNewObject (); Ptr 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 (); } diff --git a/samples/main-simple.cc b/samples/main-simple.cc index 675a3d16e..186035b97 100644 --- a/samples/main-simple.cc +++ b/samples/main-simple.cc @@ -9,7 +9,7 @@ using namespace ns3; static void -GenerateTraffic (Socket *socket, uint32_t size) +GenerateTraffic (Ptr socket, uint32_t size) { std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl; socket->Send (0, size); @@ -24,32 +24,30 @@ GenerateTraffic (Socket *socket, uint32_t size) } static void -SocketPrinter (Socket *socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort) +SocketPrinter (Ptr 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->RecvDummy (MakeCallback (&SocketPrinter)); } -int main (int argc, char *argv[]) +void +RunSimulation (void) { - InternetNode *a = new InternetNode (); + Ptr a = MakeNewObject (); - IUdp *udp; - udp = a->QueryInterface (IUdp::iid); + Ptr udp = a->QueryInterface (IUdp::iid); - Socket *sink = udp->CreateSocket (); + Ptr sink = udp->CreateSocket (); sink->Bind (80); - Socket *source = udp->CreateSocket (); + Ptr source = udp->CreateSocket (); source->Connect (Ipv4Address::GetLoopback (), 80); - udp->Unref (); - GenerateTraffic (source, 500); PrintTraffic (sink); @@ -57,10 +55,11 @@ int main (int argc, char *argv[]) Simulator::Run (); Simulator::Destroy (); +} - sink->Unref (); - source->Unref (); - a->Unref (); +int main (int argc, char *argv[]) +{ + RunSimulation (); return 0; } diff --git a/src/applications/application-list.cc b/src/applications/application-list.cc deleted file mode 100644 index 068b29581..000000000 --- a/src/applications/application-list.cc +++ /dev/null @@ -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 -// -// 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::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::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 diff --git a/src/applications/application-list.h b/src/applications/application-list.h deleted file mode 100644 index 4e37f5aa0..000000000 --- a/src/applications/application-list.h +++ /dev/null @@ -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 -// -// 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 - -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 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 m_apps; -}; - -}//namespace ns3 -#endif - diff --git a/src/applications/application.cc b/src/applications/application.cc deleted file mode 100644 index c44075b27..000000000 --- a/src/applications/application.cc +++ /dev/null @@ -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 - */ - -// 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 - - diff --git a/src/applications/application.h b/src/applications/application.h deleted file mode 100644 index 235e8b4bc..000000000 --- a/src/applications/application.h +++ /dev/null @@ -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 - */ - -#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 diff --git a/src/applications/onoff-application.cc b/src/applications/onoff-application.cc index 7682faa4b..cd7cd492f 100644 --- a/src/applications/onoff-application.cc +++ b/src/applications/onoff-application.cc @@ -42,7 +42,7 @@ uint32_t OnOffApplication::g_defaultSize = 512; // Constructors - OnOffApplication::OnOffApplication(Node * n, + OnOffApplication::OnOffApplication(Ptr n, const Ipv4Address rip, // Remote IP addr uint16_t rport, // Remote port const RandomVariable& ontime, @@ -67,7 +67,7 @@ uint32_t OnOffApplication::g_defaultSize = 512; { } -OnOffApplication::OnOffApplication(Node * n, const OnOffApplication& c) +OnOffApplication::OnOffApplication(Ptr n, const OnOffApplication& c) : Application(n), m_socket(0), m_peerIP(c.m_peerIP), @@ -92,11 +92,7 @@ OnOffApplication::~OnOffApplication() 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 @@ void OnOffApplication::StartApplication() // Called at time specified by Star this)); #endif - IUdp *udp = PeekNode ()->QueryInterface (IUdp::iid); + Ptr udp = GetNode ()->QueryInterface (IUdp::iid); m_socket = udp->CreateSocket (); - udp->Unref (); m_socket->Connect (m_peerIP, m_peerPort); } StopApplication(); // Insure no pending event @@ -199,11 +194,6 @@ void OnOffApplication::StopApplication() // Called at time specified by Stop } } -OnOffApplication* OnOffApplication::Copy() const -{ - return new OnOffApplication(*this); -} - // Event handlers void OnOffApplication::StartSending() { @@ -263,13 +253,13 @@ void OnOffApplication::SendPacket() ScheduleNextTx(); } -void OnOffApplication::ConnectionSucceeded(Socket*) +void OnOffApplication::ConnectionSucceeded(Ptr) { m_connected = true; ScheduleStartEvent(); } -void OnOffApplication::ConnectionFailed(Socket*) +void OnOffApplication::ConnectionFailed(Ptr) { cout << "OnOffApplication, Connection Failed" << endl; } diff --git a/src/applications/onoff-application.h b/src/applications/onoff-application.h index b259f7682..661fa225e 100644 --- a/src/applications/onoff-application.h +++ b/src/applications/onoff-application.h @@ -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 DataRate; class OnOffApplication : public Application { public: - OnOffApplication(Node * n, + OnOffApplication(Ptr n, const Ipv4Address, // Peer IP address uint16_t, // Peer port const RandomVariable&, // Random variable for On time @@ -48,11 +49,10 @@ public: DataRate = g_defaultRate, // Data rate when on uint32_t = g_defaultSize); // Size of packets - OnOffApplication(Node * n, const OnOffApplication&); // Copy constructor + OnOffApplication(Ptr 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 @@ public: // Static methods static void DefaultSize(uint32_t s) { g_defaultSize = s;} public: - Socket * m_socket; // Associated socket + Ptr 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 @@ private: void ScheduleNextTx(); void ScheduleStartEvent(); void ScheduleStopEvent(); - void ConnectionSucceeded(Socket*); - void ConnectionFailed(Socket*); - void Ignore(Socket*); + void ConnectionSucceeded(Ptr); + void ConnectionFailed(Ptr); + void Ignore(Ptr); protected: }; diff --git a/src/applications/wscript b/src/applications/wscript index db4d3f75a..e6f9582bd 100644 --- a/src/applications/wscript +++ b/src/applications/wscript @@ -7,14 +7,10 @@ def build(bld): 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', ] diff --git a/src/common/array-trace-resolver.h b/src/common/array-trace-resolver.h index af4e231bd..572df6e57 100644 --- a/src/common/array-trace-resolver.h +++ b/src/common/array-trace-resolver.h @@ -87,7 +87,6 @@ private: Callback m_getSize; Callback m_get; }; - }//namespace ns3 namespace ns3 { @@ -108,8 +107,8 @@ ArrayTraceResolver::Index::operator uint32_t () template ArrayTraceResolver::ArrayTraceResolver (TraceContext const &context, - Callback getSize, - Callback get) + Callback getSize, + Callback get) : TraceResolver (context), m_getSize (getSize), m_get (get) @@ -120,15 +119,15 @@ ArrayTraceResolver::DoLookup (std::string id) const { 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::Index index = typename ArrayTraceResolver::Index (i); + typename ArrayTraceResolver::Index index = typename ArrayTraceResolver::Index (i); context.Add (index); list.push_back (m_get (i)->CreateTraceResolver (context)); - } } + } return list; } diff --git a/src/core/command-line.cc b/src/core/command-line.cc index 88a14263b..481c925b4 100644 --- a/src/core/command-line.cc +++ b/src/core/command-line.cc @@ -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 , + * Mathieu Lacage + */ #include "command-line.h" #include diff --git a/src/core/command-line.h b/src/core/command-line.h index 046058dd4..a7ec9f5be 100644 --- a/src/core/command-line.h +++ b/src/core/command-line.h @@ -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 , + * Mathieu Lacage + */ #ifndef COMMAND_LINE_H #define COMMAND_LINE_H diff --git a/src/core/ns-unknown-manager.cc b/src/core/component-manager.cc similarity index 68% rename from src/core/ns-unknown-manager.cc rename to src/core/component-manager.cc index f20438d4c..497a39264 100644 --- a/src/core/ns-unknown-manager.cc +++ b/src/core/component-manager.cc @@ -18,7 +18,7 @@ * * Author: Mathieu Lacage */ -#include "ns-unknown-manager.h" +#include "component-manager.h" #include "uid-manager.h" #include "singleton.h" @@ -49,15 +49,15 @@ bool operator == (const ClassId &a, const ClassId &b) return a.m_classId == b.m_classId; } -NsUnknown * -NsUnknownManager::Create (ClassId classId) +Ptr +ComponentManager::Create (ClassId classId) { - Callback callback = DoGetCallback (classId); + Callback > callback = DoGetCallback (classId); return callback (); } CallbackBase * -NsUnknownManager::Lookup (ClassId classId) +ComponentManager::Lookup (ClassId classId) { List *list = Singleton::Get (); for (List::const_iterator i = list->begin (); i != list->end (); i++) @@ -71,13 +71,13 @@ NsUnknownManager::Lookup (ClassId classId) } ClassId -NsUnknownManager::LookupByName (std::string name) +ComponentManager::LookupByName (std::string name) { return ClassId (Singleton::Get ()->LookupByName (name)); } ClassId -NsUnknownManager::Register (std::string name, CallbackBase *callback) +ComponentManager::Register (std::string name, CallbackBase *callback) { ClassId classId = ClassId (name); List *list = Singleton::Get (); @@ -91,32 +91,32 @@ NsUnknownManager::Register (std::string name, CallbackBase *callback) #ifdef RUN_SELF_TESTS #include "test.h" -#include "ns-unknown.h" +#include "interface.h" namespace { -class B : public ns3::NsUnknown +class B : public ns3::Interface { public: - static const ns3::Iid iid; + static const ns3::InterfaceId iid; B (); }; -const ns3::Iid B::iid ("IB"); +const ns3::InterfaceId B::iid ("IB"); B::B () - : NsUnknown (B::iid) + : Interface (B::iid) {} -class A : public ns3::NsUnknown +class A : public ns3::Interface { public: static const ns3::ClassId cidZero; static const ns3::ClassId cidOneBool; static const ns3::ClassId cidOneUi32; - static const ns3::Iid iid; + static const ns3::InterfaceId iid; A (); A (bool); @@ -130,122 +130,113 @@ public: int m_ui32; }; -const ns3::ClassId A::cidZero = ns3::NsUnknownManager::RegisterConstructor ("A"); -const ns3::ClassId A::cidOneBool = ns3::NsUnknownManager::RegisterConstructor ("ABool"); -const ns3::ClassId A::cidOneUi32 = ns3::NsUnknownManager::RegisterConstructor ("AUi32"); -const ns3::Iid A::iid ("IA"); +const ns3::ClassId A::cidZero = ns3::ComponentManager::RegisterConstructor ("A"); +const ns3::ClassId A::cidOneBool = ns3::ComponentManager::RegisterConstructor ("ABool"); +const ns3::ClassId A::cidOneUi32 = ns3::ComponentManager::RegisterConstructor ("AUi32"); +const ns3::InterfaceId A::iid ("IA"); A::A () - : NsUnknown (A::iid), + : Interface (A::iid), m_zeroInvoked (true), m_oneBoolInvoked (false), m_oneUi32Invoked (false) { - B *b = new B (); + ns3::Ptr b = ns3::MakeNewObject (); AddInterface (b); - b->Unref (); } A::A (bool bo) - : NsUnknown (A::iid), + : Interface (A::iid), m_zeroInvoked (false), m_oneBoolInvoked (true), m_oneUi32Invoked (false), m_bool (bo) { - B *b = new B (); + ns3::Ptr b = ns3::MakeNewObject (); AddInterface (b); - b->Unref (); } A::A (uint32_t i) - : NsUnknown (A::iid), + : Interface (A::iid), m_zeroInvoked (false), m_oneBoolInvoked (false), m_oneUi32Invoked (true), m_ui32 (i) { - B *b = new B (); + ns3::Ptr b = ns3::MakeNewObject (); AddInterface (b); - b->Unref (); } } namespace ns3 { -class NsUnknownManagerTest : public Test +class ComponentManagerTest : public Test { public: - NsUnknownManagerTest (); + ComponentManagerTest (); virtual bool RunTests (void); }; -NsUnknownManagerTest::NsUnknownManagerTest () - : Test ("NsUnknownManager") +ComponentManagerTest::ComponentManagerTest () + : Test ("ComponentManager") {} bool -NsUnknownManagerTest::RunTests (void) +ComponentManagerTest::RunTests (void) { bool ok = true; - A *a = 0; - a = NsUnknownManager::Create (A::cidZero, A::iid); + Ptr a = 0; + a = ComponentManager::Create (A::cidZero, A::iid); if (a == 0 || !a->m_zeroInvoked) { ok = false; } - a->Unref (); - a = NsUnknownManager::Create (A::cidOneBool, A::iid, true); + a = ComponentManager::Create (A::cidOneBool, A::iid, true); if (a == 0 || !a->m_oneBoolInvoked || !a->m_bool) { ok = false; } - a->Unref (); - a = NsUnknownManager::Create (A::cidOneBool, A::iid, false); + a = ComponentManager::Create (A::cidOneBool, A::iid, false); if (a == 0 || !a->m_oneBoolInvoked || a->m_bool) { ok = false; } - a->Unref (); - a = NsUnknownManager::Create (A::cidOneUi32, A::iid, 10); + a = ComponentManager::Create (A::cidOneUi32, A::iid, 10); if (a == 0 || !a->m_oneUi32Invoked || a->m_ui32 != 10) { ok = false; } - a->Unref (); - a = NsUnknownManager::Create (A::cidOneUi32, A::iid, (uint32_t)10); + a = ComponentManager::Create (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 (A::cidOneUi32, B::iid, 10); + Ptr b = ComponentManager::Create (A::cidOneUi32, B::iid, 10); if (b == 0) { ok = false; } - b->Unref (); return ok; } -static NsUnknownManagerTest g_unknownManagerTest; +static ComponentManagerTest g_unknownManagerTest; } // namespace ns3 diff --git a/src/core/ns-unknown-manager.h b/src/core/component-manager.h similarity index 67% rename from src/core/ns-unknown-manager.h rename to src/core/component-manager.h index 34440e3ed..f69648d16 100644 --- a/src/core/ns-unknown-manager.h +++ b/src/core/component-manager.h @@ -25,8 +25,9 @@ #include #include #include "callback.h" -#include "ns-unknown.h" +#include "interface.h" #include "fatal-error.h" +#include "ptr.h" namespace ns3 { @@ -51,22 +52,22 @@ public: private: ClassId (std::string name); ClassId (uint32_t classId); - friend class NsUnknownManager; + friend class ComponentManager; friend bool operator == (const ClassId &a, const ClassId &b); uint32_t m_classId; }; /** - * \brief Create any NsUnknown + * \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 NsUnknown base class. + * 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 NsUnknownManager +class ComponentManager { public: /** @@ -82,51 +83,48 @@ public: * Create an instance of the object identified by its * ClassId. This method invokes the default constructor. */ - static NsUnknown *Create (ClassId classId); + static Ptr 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 - static NsUnknown *Create (ClassId classId, T1 a1); + static Ptr 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 - static NsUnknown *Create (ClassId classId, T1 a1, T2 a2); + static Ptr 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 - static T *Create (ClassId classId, Iid iid); + static Ptr Create (ClassId classId, InterfaceId iid); template - static T *Create (ClassId classId, Iid iid, T1 a1); + static Ptr Create (ClassId classId, InterfaceId iid, T1 a1); template - static T *Create (ClassId classId, Iid iid, T1 a1, T2 a2); + static Ptr Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2); /** * \param name the symbolic name to associate to this @@ -136,35 +134,33 @@ public: template static ClassId RegisterConstructor (std::string name) { - static Callback callback = - MakeCallback (&NsUnknownManager::MakeObjectZero); - return NsUnknownManager::Register (name, &callback); + static Callback > callback = + MakeCallback (&ComponentManager::MakeObjectZero); + return ComponentManager::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 static ClassId RegisterConstructor (std::string name) { - static Callback callback = MakeCallback (&NsUnknownManager::MakeObjectOne); - return NsUnknownManager::Register (name, &callback); + static Callback ,T1> callback = MakeCallback (&ComponentManager::MakeObjectOne); + return ComponentManager::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 static ClassId RegisterConstructor (std::string name) { - static Callback callback = MakeCallback (&NsUnknownManager::MakeObjectTwo); - return NsUnknownManager::Register (name, &callback); + static Callback,T1,T2> callback = MakeCallback (&ComponentManager::MakeObjectTwo); + return ComponentManager::Register (name, &callback); } private: static ClassId Register (std::string name, CallbackBase *callback); @@ -172,16 +168,16 @@ private: template - static Callback DoGetCallback (ClassId classId); + static Callback,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId); template - static NsUnknown *MakeObjectZero (void); + static Ptr MakeObjectZero (void); template - static NsUnknown *MakeObjectOne (T1 a1); + static Ptr MakeObjectOne (T1 a1); template - static NsUnknown *MakeObjectTwo (T1 a1, T2 a2); + static Ptr MakeObjectTwo (T1 a1, T2 a2); typedef std::vector > List; static List *GetList (void); @@ -196,84 +192,81 @@ namespace ns3 { template -Callback -NsUnknownManager::DoGetCallback (ClassId classId) +Callback,T1,T2,T3,T4,T5> +ComponentManager::DoGetCallback (ClassId classId) { CallbackBase *callback = Lookup (classId); if (callback == 0) { NS_FATAL_ERROR ("Invalid Class Id."); } - Callback reference; + Callback, T1,T2,T3,T4,T5> reference; reference.Assign (*callback); return reference; } template -NsUnknown * -NsUnknownManager::Create (ClassId classId, T1 a1) +Ptr +ComponentManager::Create (ClassId classId, T1 a1) { - Callback callback = DoGetCallback (classId); + Callback, T1> callback = DoGetCallback (classId); return callback (a1); } template -NsUnknown * -NsUnknownManager::Create (ClassId classId, T1 a1, T2 a2) +Ptr +ComponentManager::Create (ClassId classId, T1 a1, T2 a2) { - Callback callback = DoGetCallback (classId); + Callback , T1,T2> callback = DoGetCallback (classId); return callback (a1, a2); } template -T * -NsUnknownManager::Create (ClassId classId, Iid iid) +Ptr +ComponentManager::Create (ClassId classId, InterfaceId iid) { - NsUnknown *obj = Create (classId); - T *i = obj->QueryInterface (iid); - obj->Unref (); + Ptr obj = Create (classId); + Ptr i = obj->QueryInterface (iid); return i; } template -T * -NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1) +Ptr +ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1) { - NsUnknown *obj = Create (classId, a1); - T *i = obj->QueryInterface (iid); - obj->Unref (); + Ptr obj = Create (classId, a1); + Ptr i = obj->QueryInterface (iid); return i; } template -T * -NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1, T2 a2) +Ptr +ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2) { - NsUnknown *obj = Create (classId, a1, a2); - T *i = obj->QueryInterface (iid); - obj->Unref (); + Ptr obj = Create (classId, a1, a2); + Ptr i = obj->QueryInterface (iid); return i; } template -NsUnknown * -NsUnknownManager::MakeObjectZero (void) +Ptr +ComponentManager::MakeObjectZero (void) { - return new T (); + return MakeNewObject (); } template -NsUnknown * -NsUnknownManager::MakeObjectOne (T1 a1) +Ptr +ComponentManager::MakeObjectOne (T1 a1) { - return new T (a1); + return MakeNewObject (a1); } template -NsUnknown * -NsUnknownManager::MakeObjectTwo (T1 a1, T2 a2) +Ptr +ComponentManager::MakeObjectTwo (T1 a1, T2 a2) { - return new T (a1, a2); + return MakeNewObject (a1, a2); } } // namespace ns3 diff --git a/src/core/debug.cc b/src/core/debug.cc index 5d57b64cd..abd91b504 100644 --- a/src/core/debug.cc +++ b/src/core/debug.cc @@ -48,7 +48,7 @@ void DebugComponentEnableEnvVar (void) { #ifdef HAVE_GETENV - char *envVar = getenv("NS3_DEBUG"); + char *envVar = getenv("NS_DEBUG"); if (envVar == 0) { return; diff --git a/src/core/default-value.cc b/src/core/default-value.cc index 163497baf..fa0a2406d 100644 --- a/src/core/default-value.cc +++ b/src/core/default-value.cc @@ -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 + */ #include "default-value.h" #include "fatal-error.h" diff --git a/src/core/default-value.h b/src/core/default-value.h index f64e691fb..eea46dc39 100644 --- a/src/core/default-value.h +++ b/src/core/default-value.h @@ -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 + */ #ifndef DEFAULT_VALUE_H #define DEFAULT_VALUE_H diff --git a/src/core/ns-unknown.cc b/src/core/interface.cc similarity index 55% rename from src/core/ns-unknown.cc rename to src/core/interface.cc index d31b61fba..030c5a031 100644 --- a/src/core/ns-unknown.cc +++ b/src/core/interface.cc @@ -18,56 +18,60 @@ * * Author: Mathieu Lacage */ -#include "ns-unknown.h" +#include "interface.h" #include "singleton.h" #include "uid-manager.h" #include #include #include #include "assert.h" +#include "debug.h" + +NS_DEBUG_COMPONENT_DEFINE ("Interface"); namespace ns3 { class IidManager : public UidManager {}; -Iid::Iid (std::string name) +InterfaceId::InterfaceId (std::string name) : m_iid (Singleton::Get ()->Allocate (name)) {} -bool operator == (const Iid &a, const Iid &b) +bool operator == (const InterfaceId &a, const InterfaceId &b) { return a.m_iid == b.m_iid; } -class NsUnknownImpl +class InterfaceImpl { public: - NsUnknownImpl (Iid iid, NsUnknown *interface); - ~NsUnknownImpl (); + InterfaceImpl (InterfaceId iid, Interface *interface); + ~InterfaceImpl (); void Ref (void); - void RefAll (NsUnknownImpl *other); + void RefAll (InterfaceImpl *other); void Unref (void); void UnrefAll (void); - NsUnknown *DoQueryInterface (Iid iid) const; + Interface *PeekQueryInterface (InterfaceId iid) const; void DoDisposeAll (void); - void AddInterface (NsUnknown *interface); - void AddSelfInterface (Iid iid, NsUnknown *interface); + void AddInterface (Interface * interface); + void AddSelfInterface (InterfaceId iid, Interface *interface); private: - typedef std::list > List; + typedef std::list > List; uint32_t m_ref; List m_list; bool m_disposed; }; -NsUnknownImpl::NsUnknownImpl (Iid iid, NsUnknown *interface) +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)); } -NsUnknownImpl::~NsUnknownImpl () +InterfaceImpl::~InterfaceImpl () { for (List::const_iterator i = m_list.begin (); i != m_list.end (); i++) @@ -77,58 +81,63 @@ NsUnknownImpl::~NsUnknownImpl () m_list.clear (); } void -NsUnknownImpl::Ref (void) +InterfaceImpl::Ref (void) { m_ref++; + NS_DEBUG ("inc " << this << " ref=" << m_ref); } void -NsUnknownImpl::RefAll (NsUnknownImpl *other) +InterfaceImpl::RefAll (InterfaceImpl *other) { m_ref += other->m_ref; + NS_DEBUG ("inc all " << this << " o=" << other->m_ref << " ref=" << m_ref); } void -NsUnknownImpl::Unref (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 -NsUnknownImpl::UnrefAll (void) +InterfaceImpl::UnrefAll (void) { + NS_ASSERT (m_ref > 0); m_ref = 0; delete this; + NS_DEBUG ("dec all " << this); } void -NsUnknownImpl::DoDisposeAll (void) +InterfaceImpl::DoDisposeAll (void) { NS_ASSERT (!m_disposed); for (List::const_iterator i = m_list.begin (); i != m_list.end (); i++) { - NsUnknown *interface = i->second; + Interface *interface = i->second; interface->DoDispose (); } m_disposed = true; } -NsUnknown * -NsUnknownImpl::DoQueryInterface (Iid iid) const +Interface * +InterfaceImpl::PeekQueryInterface (InterfaceId 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) +InterfaceImpl::AddInterface (Interface *interface) { for (List::const_iterator i = interface->m_impl->m_list.begin (); i != interface->m_impl->m_list.end (); i++) @@ -140,52 +149,53 @@ NsUnknownImpl::AddInterface (NsUnknown *interface) } } void -NsUnknownImpl::AddSelfInterface (Iid iid, NsUnknown *interface) +InterfaceImpl::AddSelfInterface (InterfaceId iid, Interface *interface) { interface->RefInternal (); m_list.push_back (std::make_pair (iid, interface)); } -NsUnknown::NsUnknown (Iid iid) - : m_impl (new NsUnknownImpl (iid, this)), +Interface::Interface (InterfaceId iid) + : m_impl (new InterfaceImpl (iid, this)), m_ref (1) {} -NsUnknown::~NsUnknown () +Interface::~Interface () { m_impl = 0; + m_ref = -1; } void -NsUnknown::Ref (void) +Interface::Ref (void) const { m_impl->Ref (); } void -NsUnknown::Unref (void) +Interface::Unref (void) const { m_impl->Unref (); } void -NsUnknown::Dispose (void) +Interface::Dispose (void) { m_impl->DoDisposeAll (); } void -NsUnknown::DoDispose (void) +Interface::DoDispose (void) { // we do not do anything by default. } void -NsUnknown::RefInternal (void) +Interface::RefInternal (void) { m_ref++; } void -NsUnknown::UnrefInternal (void) +Interface::UnrefInternal (void) { NS_ASSERT (m_ref != 0); m_ref--; @@ -195,25 +205,26 @@ NsUnknown::UnrefInternal (void) } } -NsUnknown * -NsUnknown::DoQueryInterface (Iid iid) const +Ptr +Interface::DoQueryInterface (InterfaceId iid) const { - return m_impl->DoQueryInterface (iid); + return m_impl->PeekQueryInterface (iid); } void -NsUnknown::AddInterface (NsUnknown *interface) +Interface::AddInterface (Ptr interface) { - m_impl->AddInterface (interface); - m_impl->RefAll (interface->m_impl); - interface->m_impl->UnrefAll (); - interface->m_impl = m_impl; + Interface *p = PeekPointer (interface); + m_impl->AddInterface (p); + m_impl->RefAll (p->m_impl); + p->m_impl->UnrefAll (); + p->m_impl = m_impl; } void -NsUnknown::AddSelfInterface (Iid iid, NsUnknown *interface) +Interface::AddSelfInterface (InterfaceId iid, Ptr interface) { - m_impl->AddSelfInterface (iid, interface); + m_impl->AddSelfInterface (iid, PeekPointer (interface)); } @@ -225,62 +236,62 @@ NsUnknown::AddSelfInterface (Iid iid, NsUnknown *interface) namespace { -class A : public ns3::NsUnknown +class A : public ns3::Interface { public: - static const ns3::Iid iid; + static const ns3::InterfaceId iid; A () - : NsUnknown (A::iid) + : Interface (A::iid) {} }; -class B : public ns3::NsUnknown +class B : public ns3::Interface { public: - static const ns3::Iid iid; + static const ns3::InterfaceId iid; B () - : NsUnknown (B::iid) + : Interface (B::iid) {} }; -class BaseA : public ns3::NsUnknown +class BaseA : public ns3::Interface { public: - static const ns3::Iid iid; + static const ns3::InterfaceId iid; BaseA () - : NsUnknown (BaseA::iid) + : Interface (BaseA::iid) {} }; -class BaseB : public ns3::NsUnknown +class BaseB : public ns3::Interface { public: - static const ns3::Iid iid; + static const ns3::InterfaceId iid; BaseB () - : NsUnknown (BaseB::iid) + : Interface (BaseB::iid) {} }; -class Base : public ns3::NsUnknown +class Base : public ns3::Interface { public: - static const ns3::Iid iid; + static const ns3::InterfaceId iid; Base () - : NsUnknown (Base::iid) + : Interface (Base::iid) {} }; class Derived : public Base { public: - static const ns3::Iid iid; + static const ns3::InterfaceId 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"); +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 @@ -295,7 +306,7 @@ public: }; InterfaceTest::InterfaceTest () - : Test ("NsUnknown") + : Test ("Interface") {} bool InterfaceTest::RunTests (void) @@ -305,76 +316,64 @@ InterfaceTest::RunTests (void) //DerivedAB *derivedAB; - A *a = new A (); - a->Unref (); + Ptr a = MakeNewObject (); - a = new A (); - A *a1 = a->QueryInterface (A::iid); + a = MakeNewObject (); + Ptr a1 = a->QueryInterface (A::iid); if (a1 == 0 || a1 != a) { ok = false; } - a1->Unref (); a1 = a->QueryInterface (A::iid); if (a1 == 0 || a1 != a) { ok = false; } - a1->Unref (); - a->Unref (); - B *b = new B (); - B *b1 = b->QueryInterface (B::iid); + Ptr b = MakeNewObject (); + Ptr b1 = b->QueryInterface (B::iid); if (b1 == 0 || b1 != b) { ok = false; } - b1->Unref (); - a = new A (); + a = MakeNewObject (); a->AddInterface (b); b1 = b->QueryInterface (B::iid); if (b1 == 0 || b1 != b) { ok = false; } - b1->Unref (); a1 = b->QueryInterface (A::iid); if (a1 == 0 || a1 != a) { ok = false; } - a1->Unref (); a1 = a->QueryInterface (A::iid); if (a1 == 0 || a1 != a) { ok = false; } - a1->Unref (); b1 = a->QueryInterface (B::iid); if (b1 == 0 || b1 != b) { ok = false; } - b1->Unref (); - - a->Unref (); - b->Unref (); - Derived *derived = new Derived (); - Base *base = derived->QueryInterface (Base::iid); + Ptr derived = MakeNewObject (); + Ptr base = derived->QueryInterface (Base::iid); if (base == 0) { ok = false; } - Derived *derived1 = base->QueryInterface (Derived::iid); + Ptr derived1 = base->QueryInterface (Derived::iid); if (derived1 == 0 || derived1 != derived) { ok = false; } - derived1->Unref (); - base->Unref (); - derived->Unref (); + + // the following cannot work and it is on purpose + // delete derived; return ok; } diff --git a/src/core/ns-unknown.h b/src/core/interface.h similarity index 73% rename from src/core/ns-unknown.h rename to src/core/interface.h index c5c6af1e4..307152a9d 100644 --- a/src/core/ns-unknown.h +++ b/src/core/interface.h @@ -22,18 +22,18 @@ #define INTERFACE_H #include - +#include "ptr.h" namespace ns3 { -class NsUnknownImpl; +class InterfaceImpl; -class Iid +class InterfaceId { public: - Iid (std::string name); + InterfaceId (std::string name); private: - friend bool operator == (const Iid &a, const Iid &b); + friend bool operator == (const InterfaceId &a, const InterfaceId &b); uint32_t m_iid; }; @@ -45,18 +45,18 @@ private: * inheritance where this base class is at the top of the dreaded * "diamond" shape is not allowed. */ -class NsUnknown +class Interface { public: - virtual ~NsUnknown (); - void Ref (void); - void Unref (void); + virtual ~Interface (); + void Ref (void) const; + void Unref (void) const; /** - * \param iid the NsUnknown id of the requested interface + * \param iid the Interface id of the requested interface */ template - T *QueryInterface (Iid iid) const; + Ptr QueryInterface (InterfaceId iid) const; /** * \param interface another interface @@ -66,7 +66,7 @@ public: * 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 AddInterface (Ptr interface); void Dispose (void); protected: @@ -77,17 +77,17 @@ protected: * If you are a direct subclass of this class, you _must_ register * the name of your interface with this constructor. */ - NsUnknown (Iid iid); + Interface (InterfaceId iid); /** * \param iid the Interface id of the interface - * \param a pointer to the interface object + * \param interface a pointer to the interface object * - * If you are not a direct subclass of the ns3::NsUnknown base class, + * 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 (Iid iid, NsUnknown *interface); + void AddSelfInterface (InterfaceId iid, Ptr interface); protected: /** * Subclasses who want to handle the "dispose" event should @@ -97,12 +97,12 @@ protected: */ virtual void DoDispose (void); private: - friend class NsUnknownImpl; - NsUnknown (); - NsUnknown *DoQueryInterface (Iid iid) const; + friend class InterfaceImpl; + Interface (); + Ptr DoQueryInterface (InterfaceId iid) const; void RefInternal (void); void UnrefInternal (void); - NsUnknownImpl *m_impl; + InterfaceImpl *m_impl; uint32_t m_ref; }; @@ -111,13 +111,13 @@ private: namespace ns3 { template -T * -NsUnknown::QueryInterface (Iid iid) const +Ptr +Interface::QueryInterface (InterfaceId iid) const { - NsUnknown *found = DoQueryInterface (iid); + Ptr found = DoQueryInterface (iid); if (found != 0) { - return dynamic_cast (found); + return Ptr (dynamic_cast (PeekPointer (found))); } return 0; } diff --git a/src/core/object.cc b/src/core/object.cc index 9c7e8d83e..6dc61b4b7 100644 --- a/src/core/object.cc +++ b/src/core/object.cc @@ -29,7 +29,9 @@ namespace ns3 { Object::Object () : m_count (1), m_disposed (false) -{} +{ + NS_DEBUG ("Object::Object: m_count=0"); +} Object::~Object () {} @@ -37,17 +39,16 @@ Object::~Object () 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) { diff --git a/src/core/ptr.cc b/src/core/ptr.cc index a9ba89970..77b19fcd9 100644 --- a/src/core/ptr.cc +++ b/src/core/ptr.cc @@ -24,10 +24,11 @@ #include "test.h" #include "callback.h" +#include "object.h" namespace ns3 { -class NoCount +class NoCount : public Object { public: NoCount (Callback cb); @@ -92,7 +93,7 @@ PtrTest::RunTests (void) Callback cb = MakeCallback (&PtrTest::DestroyNotify, this); m_nDestroyed = false; { - Ptr p = new NoCount (cb); + Ptr p = MakeNewObject (cb); } if (m_nDestroyed != 1) { @@ -102,7 +103,7 @@ PtrTest::RunTests (void) m_nDestroyed = 0; { Ptr p; - p = new NoCount (cb); + p = MakeNewObject (cb); p = p; } if (m_nDestroyed != 1) @@ -113,7 +114,7 @@ PtrTest::RunTests (void) m_nDestroyed = 0; { Ptr p1; - p1 = new NoCount (cb); + p1 = MakeNewObject (cb); Ptr p2 = p1; } if (m_nDestroyed != 1) @@ -124,7 +125,7 @@ PtrTest::RunTests (void) m_nDestroyed = 0; { Ptr p1; - p1 = new NoCount (cb); + p1 = MakeNewObject (cb); Ptr p2; p2 = p1; } @@ -136,8 +137,8 @@ PtrTest::RunTests (void) m_nDestroyed = 0; { Ptr p1; - p1 = new NoCount (cb); - Ptr p2 = new NoCount (cb); + p1 = MakeNewObject (cb); + Ptr p2 = MakeNewObject (cb); p2 = p1; } if (m_nDestroyed != 2) @@ -148,9 +149,9 @@ PtrTest::RunTests (void) m_nDestroyed = 0; { Ptr p1; - p1 = new NoCount (cb); + p1 = MakeNewObject (cb); Ptr p2; - p2 = new NoCount (cb); + p2 = MakeNewObject (cb); p2 = p1; } if (m_nDestroyed != 2) @@ -161,8 +162,8 @@ PtrTest::RunTests (void) m_nDestroyed = 0; { Ptr p1; - p1 = new NoCount (cb); - p1 = new NoCount (cb); + p1 = MakeNewObject (cb); + p1 = MakeNewObject (cb); } if (m_nDestroyed != 2) { @@ -174,8 +175,8 @@ PtrTest::RunTests (void) Ptr p1; { Ptr p2; - p1 = new NoCount (cb); - p2 = new NoCount (cb); + p1 = MakeNewObject (cb); + p2 = MakeNewObject (cb); p2 = p1; } if (m_nDestroyed != 1) @@ -193,8 +194,8 @@ PtrTest::RunTests (void) Ptr p1; { Ptr p2; - p1 = new NoCount (cb); - p2 = new NoCount (cb); + p1 = MakeNewObject (cb); + p2 = MakeNewObject (cb); p2 = CallTest (p1); } if (m_nDestroyed != 1) @@ -236,11 +237,12 @@ PtrTest::RunTests (void) { NoCount *raw; { - Ptr p = new NoCount (cb); + Ptr p = MakeNewObject (cb); { Ptr p1 = p; } - raw = p.Remove (); + raw = GetPointer (p); + p = 0; } if (m_nDestroyed != 0) { @@ -252,16 +254,32 @@ PtrTest::RunTests (void) m_nDestroyed = 0; { - Ptr p = new NoCount (cb); - NoCount const&v1 = *p; - NoCount v2 = *p; - v1.Nothing (); - v2.Nothing (); + Ptr p = MakeNewObject (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 p0 = MakeNewObject (cb); + Ptr p1 = MakeNewObject (cb); + if (p0 == p1) + { + ok = false; + } + if (p0 != p1) + { + } + else + { + ok = false; + } + } return ok; diff --git a/src/core/ptr.h b/src/core/ptr.h index 889e0386e..80f191378 100644 --- a/src/core/ptr.h +++ b/src/core/ptr.h @@ -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 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 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 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::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 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; + template + friend U *GetPointer (const Ptr &p); + template + friend U *PeekPointer (const Ptr &p); + + void Acquire (void) const; public: /** * Create an empty smart pointer @@ -75,100 +86,271 @@ public: Ptr (Ptr const &o); ~Ptr () ; Ptr &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 - inline friend bool operator == (Ptr const &lhs, T2 const *rhs); - // allow if (0 == sp) - template - inline friend bool operator == (T1 const *lhs, Ptr &rhs); - // allow if (sp != 0) - template - inline friend bool operator != (Ptr const &lhs, T2 const *rhs); - // allow if (0 != sp) - template - inline friend bool operator != (T1 const *lhs, Ptr &rhs); - - template - inline friend Ptr const_pointer_cast (Ptr 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::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 -uint32_t * -Ptr::AllocCount (void) +Ptr MakeNewObject (void); + +template +Ptr MakeNewObject (T1 a1); + +template +Ptr MakeNewObject (T1 a1, T2 a2); + +template +Ptr MakeNewObject (T1 a1, T2 a2, T3 a3); + +template +Ptr MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4); + +template +Ptr MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); + +template +Ptr MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6); + +template +Ptr 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 +T * PeekPointer (const Ptr &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 +T * GetPointer (const Ptr &p); + + +// allow if (sp == 0) +template +bool operator == (Ptr const &lhs, T2 const *rhs); + +// allow if (0 == sp) +template +bool operator == (T1 const *lhs, Ptr &rhs); + +// allow if (sp != 0) +template +bool operator != (Ptr const &lhs, T2 const *rhs); + +// allow if (0 != sp) +template +bool operator != (T1 const *lhs, Ptr &rhs); + +// allow if (sp0 == sp1) +template +bool operator == (Ptr const &lhs, Ptr const &rhs); + +// allow if (sp0 != sp1) +template +bool operator != (Ptr const &lhs, Ptr const &rhs); + +template +Ptr const_pointer_cast (Ptr const&p); + +} // namespace ns3 + + +namespace ns3 { + + /************************************************* + * friend non-member function implementations + ************************************************/ + +template +Ptr MakeNewObject (void) { - return new uint32_t [1] (); + T *obj = new T (); + Ptr p = obj; + obj->Unref (); + return p; } + +template +Ptr MakeNewObject (T1 a1) +{ + T *obj = new T (a1); + Ptr p = obj; + obj->Unref (); + return p; +} + +template +Ptr MakeNewObject (T1 a1, T2 a2) +{ + T *obj = new T (a1, a2); + Ptr p = obj; + obj->Unref (); + return p; +} + +template +Ptr MakeNewObject (T1 a1, T2 a2, T3 a3) +{ + T *obj = new T (a1, a2, a3); + Ptr p = obj; + obj->Unref (); + return p; +} + +template +Ptr MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4) +{ + T *obj = new T (a1, a2, a3, a4); + Ptr p = obj; + obj->Unref (); + return p; +} + +template +Ptr MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) +{ + T *obj = new T (a1, a2, a3, a4, a5); + Ptr p = obj; + obj->Unref (); + return p; +} + +template +Ptr MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) +{ + T *obj = new T (a1, a2, a3, a4, a5, a6); + Ptr p = obj; + obj->Unref (); + return p; +} + +template +Ptr 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 p = obj; + obj->Unref (); + return p; +} + +template +T * PeekPointer (const Ptr &p) +{ + return p.m_ptr; +} + +template +T * GetPointer (const Ptr &p) +{ + p.Acquire (); + return p.m_ptr; +} + +template +bool +operator == (Ptr const &lhs, T2 const *rhs) +{ + return PeekPointer (lhs) == rhs; +} + +template +bool +operator == (T1 const *lhs, Ptr &rhs) +{ + return lhs == PeekPointer (rhs); +} + +template +bool +operator != (Ptr const &lhs, T2 const *rhs) +{ + return PeekPointer (lhs) != rhs; +} + +template +bool +operator != (T1 const *lhs, Ptr &rhs) +{ + return lhs != PeekPointer (rhs); +} + +template +bool +operator == (Ptr const &lhs, Ptr const &rhs) +{ + return PeekPointer (lhs) == PeekPointer (rhs); +} + +template +bool +operator != (Ptr const &lhs, Ptr const &rhs) +{ + return PeekPointer (lhs) != PeekPointer (rhs); +} + + +template +Ptr +const_pointer_cast (Ptr const&p) +{ + return Ptr (const_cast (PeekPointer (p))); +} + + +/**************************************************** + * Member method implementations. + ***************************************************/ + template void -Ptr::DeallocCount (uint32_t *count) +Ptr::Acquire (void) const { - delete [] count; + if (m_ptr != 0) + { + m_ptr->Ref (); + } } template Ptr::Ptr () - : m_ptr (0), - m_count (0) + : m_ptr (0) {} template Ptr::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 Ptr::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 template Ptr::Ptr (Ptr 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 @@ -176,12 +358,7 @@ Ptr::~Ptr () { if (m_ptr != 0) { - (*m_count)--; - if ((*m_count) == 0) - { - delete m_ptr; - Ptr::DeallocCount (m_count); - } + m_ptr->Unref(); } } @@ -190,32 +367,18 @@ Ptr & Ptr::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 -T const& -Ptr::operator * () const -{ - return *m_ptr; -} - template T * Ptr::operator -> () @@ -248,57 +411,6 @@ Ptr::operator Tester * () const return &test; } -template -T * -Ptr::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 -bool -operator == (Ptr const &lhs, T2 const *rhs) -{ - return lhs.m_ptr == rhs; -} -template -bool -operator == (T1 const *lhs, Ptr &rhs) -{ - return lhs == rhs.m_ptr; -} -template -bool -operator != (Ptr const &lhs, T2 const *rhs) -{ - return lhs.m_ptr != rhs; -} -template -bool -operator != (T1 const *lhs, Ptr &rhs) -{ - return lhs != rhs.m_ptr; -} - -template -Ptr -const_pointer_cast (Ptr const&p) -{ - return Ptr (const_cast (p.m_ptr)); -} - }; // namespace ns3 diff --git a/src/core/random-variable.h b/src/core/random-variable.h index b5076ca5f..9901b665a 100644 --- a/src/core/random-variable.h +++ b/src/core/random-variable.h @@ -200,6 +200,7 @@ protected: * 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: diff --git a/src/core/uid-manager.h b/src/core/uid-manager.h index 5cc6c1adc..e4648e31a 100644 --- a/src/core/uid-manager.h +++ b/src/core/uid-manager.h @@ -27,6 +27,9 @@ namespace ns3 { +/** + * zero is never a valid uid value. + */ class UidManager { public: diff --git a/src/core/wscript b/src/core/wscript index f28348f17..3131d55c8 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -33,12 +33,12 @@ def build(bld): '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 @@ def build(bld): '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', ] diff --git a/src/devices/p2p-gfr/p2p-channel.cc b/src/devices/p2p-gfr/p2p-channel.cc deleted file mode 100644 index 09e338cdc..000000000 --- a/src/devices/p2p-gfr/p2p-channel.cc +++ /dev/null @@ -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 -// - -// 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 diff --git a/src/devices/p2p-gfr/p2p-channel.h b/src/devices/p2p-gfr/p2p-channel.h deleted file mode 100644 index 891d3826f..000000000 --- a/src/devices/p2p-gfr/p2p-channel.h +++ /dev/null @@ -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 -// - -// 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 diff --git a/src/devices/p2p-gfr/p2p-net-device.cc b/src/devices/p2p-gfr/p2p-net-device.cc deleted file mode 100644 index fe81c2f64..000000000 --- a/src/devices/p2p-gfr/p2p-net-device.cc +++ /dev/null @@ -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 -// - -// 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 diff --git a/src/devices/p2p-gfr/p2p-net-device.h b/src/devices/p2p-gfr/p2p-net-device.h deleted file mode 100644 index 4809ea738..000000000 --- a/src/devices/p2p-gfr/p2p-net-device.h +++ /dev/null @@ -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 -// - -// 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 */ - diff --git a/src/devices/p2p-gfr/wscript b/src/devices/p2p-gfr/wscript deleted file mode 100644 index 8b92512bf..000000000 --- a/src/devices/p2p-gfr/wscript +++ /dev/null @@ -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', - ] - diff --git a/src/devices/p2p/p2p-channel.cc b/src/devices/p2p/p2p-channel.cc index c0a8342b7..2833c8bb1 100644 --- a/src/devices/p2p/p2p-channel.cc +++ b/src/devices/p2p/p2p-channel.cc @@ -70,11 +70,11 @@ PointToPointChannel::PointToPointChannel( } void -PointToPointChannel::Attach(PointToPointNetDevice *device) +PointToPointChannel::Attach(Ptr 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 @@ PointToPointChannel::Attach(PointToPointNetDevice *device) } bool -PointToPointChannel::TransmitStart(Packet& p, PointToPointNetDevice* src) +PointToPointChannel::TransmitStart(Packet& p, Ptr src) { NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src << ")"); @@ -117,7 +117,7 @@ PointToPointChannel::TransmitStart(Packet& p, PointToPointNetDevice* src) } bool -PointToPointChannel::TransmitEnd(Packet& p, PointToPointNetDevice* src) +PointToPointChannel::TransmitEnd(Packet& p, Ptr src) { NS_DEBUG("PointToPointChannel::TransmitEnd (" << &p << ", " << src << ")"); NS_DEBUG ("PointToPointChannel::TransmitEnd (): UID is " << @@ -147,7 +147,7 @@ PointToPointChannel::TransmitEnd(Packet& p, PointToPointNetDevice* src) void PointToPointChannel::PropagationCompleteEvent( Packet p, - PointToPointNetDevice *src) + Ptr src) { NS_DEBUG("PointToPointChannel::PropagationCompleteEvent (" << &p << ", " << src << ")"); @@ -169,7 +169,7 @@ PointToPointChannel::GetNDevices (void) const return m_nDevices; } -NetDevice * +Ptr PointToPointChannel::GetDevice (uint32_t i) const { NS_ASSERT(i < 2); diff --git a/src/devices/p2p/p2p-channel.h b/src/devices/p2p/p2p-channel.h index 13256a2d7..dacdc9c0b 100644 --- a/src/devices/p2p/p2p-channel.h +++ b/src/devices/p2p/p2p-channel.h @@ -21,6 +21,7 @@ #include #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 @@ public: 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 device); + bool TransmitStart (Packet& p, Ptr src); + bool TransmitEnd (Packet &p, Ptr src); + void PropagationCompleteEvent(Packet p, Ptr src); virtual uint32_t GetNDevices (void) const; - virtual NetDevice *GetDevice (uint32_t i) const; + virtual Ptr GetDevice (uint32_t i) const; virtual DataRate GetDataRate (void); virtual Time GetDelay (void); @@ -92,8 +93,8 @@ private: public: Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {} WireState m_state; - PointToPointNetDevice *m_src; - PointToPointNetDevice *m_dst; + Ptr m_src; + Ptr m_dst; }; Link m_link[N_DEVICES]; diff --git a/src/devices/p2p/p2p-net-device.cc b/src/devices/p2p/p2p-net-device.cc index ae322c4fa..9542d951b 100644 --- a/src/devices/p2p/p2p-net-device.cc +++ b/src/devices/p2p/p2p-net-device.cc @@ -32,7 +32,7 @@ NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice"); namespace ns3 { -PointToPointNetDevice::PointToPointNetDevice (Node* node) +PointToPointNetDevice::PointToPointNetDevice (Ptr node) : NetDevice(node, MacAddress ("00:00:00:00:00:00")), m_txMachineState (READY), @@ -55,8 +55,6 @@ PointToPointNetDevice::PointToPointNetDevice (Node* node) PointToPointNetDevice::~PointToPointNetDevice() { NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()"); - - delete m_queue; m_queue = 0; } @@ -81,18 +79,12 @@ PointToPointNetDevice::PointToPointNetDevice (const PointToPointNetDevice& nd) 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 @@ PointToPointNetDevice::PointToPointNetDevice (const PointToPointNetDevice& nd) void PointToPointNetDevice::DoDispose() { - if (m_channel != 0) - { - m_channel->Unref (); - m_channel = 0; - } - NetDevice::DoDispose (); + m_channel = 0; + NetDevice::DoDispose (); } // @@ -296,7 +284,7 @@ PointToPointNetDevice::DoCreateTraceResolver (TraceContext const &context) { 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 @@ PointToPointNetDevice::DoCreateTraceResolver (TraceContext const &context) } bool -PointToPointNetDevice::Attach (PointToPointChannel* ch) +PointToPointNetDevice::Attach (Ptr 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 @@ PointToPointNetDevice::Attach (PointToPointChannel* ch) } void -PointToPointNetDevice::AddQueue (Queue* q) +PointToPointNetDevice::AddQueue (Ptr q) { NS_DEBUG ("PointToPointNetDevice::AddQueue (" << q << ")"); @@ -352,16 +333,15 @@ PointToPointNetDevice::Receive (Packet& p) ForwardUp (p); } -Queue* +Ptr PointToPointNetDevice::GetQueue(void) const { return m_queue; } -Channel* +Ptr PointToPointNetDevice::DoGetChannel(void) const { - m_channel->Ref(); return m_channel; } diff --git a/src/devices/p2p/p2p-net-device.h b/src/devices/p2p/p2p-net-device.h index 2826f6f1b..e1eb8a666 100644 --- a/src/devices/p2p/p2p-net-device.h +++ b/src/devices/p2p/p2p-net-device.h @@ -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 @@ public: * @see PointToPointTopology::AddPointToPointLink () * @param node the Node to which this device is connected. */ - PointToPointNetDevice (Node* node); + PointToPointNetDevice (Ptr node); /** * Copy Construct a PointToPointNetDevice * @@ -139,7 +140,7 @@ public: * @see SetInterframeGap () * @param ch a pointer to the channel to which this object is being attached. */ - bool Attach(PointToPointChannel* ch); + bool Attach(Ptr ch); /** * Attach a queue to the PointToPointNetDevice. * @@ -154,7 +155,7 @@ public: * @param queue a pointer to the queue for which object is assuming * ownership. */ - void AddQueue(Queue* queue); + void AddQueue(Ptr queue); /** * Receive a packet from a connected PointToPointChannel. * @@ -178,7 +179,7 @@ protected: * @see PointToPointTopology * @returns a pointer to the queue. */ - Queue* GetQueue(void) const; + Ptr GetQueue(void) const; /** * Get a copy of the attached Channel * @@ -188,7 +189,7 @@ protected: * @see PointToPointChannel * @returns a pointer to the channel */ - virtual Channel *DoGetChannel(void) const; + virtual Ptr DoGetChannel(void) const; private: /** * Send a Packet Down the Wire. @@ -287,7 +288,7 @@ private: * attached. * @see class PointToPointChannel */ - PointToPointChannel* m_channel; + Ptr 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 @@ private: * @see class Queue * @see class DropTailQueue */ - Queue* m_queue; + Ptr m_queue; /** * The trace source for the packet reception events that the device can * fire. diff --git a/src/devices/p2p/p2p-topology.cc b/src/devices/p2p/p2p-topology.cc index 6ff05eab9..7f9db4660 100644 --- a/src/devices/p2p/p2p-topology.cc +++ b/src/devices/p2p/p2p-topology.cc @@ -24,13 +24,13 @@ #include #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 PointToPointTopology::AddPointToPointLink( - Node* n1, - Node* n2, + Ptr n1, + Ptr n2, const DataRate& bps, const Time& delay) { - PointToPointChannel* channel = new PointToPointChannel(bps, delay); + Ptr channel = MakeNewObject (bps, delay); - PointToPointNetDevice* net1 = new PointToPointNetDevice(n1); - net1->AddQueue(Queue::Default().Copy()); - n1->AddDevice (net1); + Ptr net1 = MakeNewObject (n1); + + Ptr 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 net2 = MakeNewObject (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 chan, + Ptr n1, const Ipv4Address& addr1, + Ptr n2, const Ipv4Address& addr2) { // Duplex link is assumed to be subnetted as a /30 @@ -76,148 +76,97 @@ PointToPointTopology::AddIpv4Addresses( // 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 nd1 = chan->GetDevice (0); + Ptr 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::iid); + Ptr ip1 = n1->QueryInterface (IIpv4::iid); uint32_t index1 = ip1->AddInterface (nd1); ip1->SetAddress (index1, addr1); ip1->SetNetworkMask (index1, netmask); ip1->SetUp (index1); - IIpv4 *ip2 = n2->QueryInterface (IIpv4::iid); + Ptr ip2 = n2->QueryInterface (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 +void +PointToPointTopology::AddIpv4Routes ( + Ptr n1, Ptr n2, Ptr chan) +{ + // The PointToPoint channel is used to find the relevant NetDevices + NS_ASSERT (chan->GetNDevices () == 2); + Ptr nd1 = chan->GetDevice (0); + Ptr nd2 = chan->GetDevice (1); -// Get the net device connecting node n1 to n2. For topologies where -// there are possibly multiple devices connecting n1 and n2 (for example -// wireless with two devices on different channels) this will return -// the first one found. -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 + // Assert that n1 is the Node owning one of the two NetDevices + // and make sure that nd1 corresponds to it + if (nd1->GetNode ()->GetId () == n1->GetId ()) + { + ; // Do nothing + } + else if (nd2->GetNode ()->GetId () == n1->GetId ()) + { + std::swap(nd1, nd2); + } + else + { + NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel"); } - return 0; // None found -} - -// Get the channel connecting node n1 to node n2 -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(); + // Assert that n2 is the Node owning one of the two NetDevices + // and make sure that nd2 corresponds to it + if (nd2->GetNode ()->GetId () != n2->GetId ()) + { + NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel"); + } + + // Assert that both are Ipv4 nodes + Ptr ip1 = nd1->GetNode ()->QueryInterface (IIpv4::iid); + Ptr ip2 = nd2->GetNode ()->QueryInterface (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); } -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 - -#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(nd1->GetChannel()); // Always succeeds -} - -// 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 diff --git a/src/devices/p2p/p2p-topology.h b/src/devices/p2p/p2p-topology.h index dc8cbb88d..1cb643d94 100644 --- a/src/devices/p2p/p2p-topology.h +++ b/src/devices/p2p/p2p-topology.h @@ -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 Node; class IPAddr; class DataRate; class Queue; -//class Time; /** - * \brief A helper class to create Topologies based on the ns3::PointToPointNetDevice and - * ns3::PointToPointChannel objects. - * - * XXX ?? - * I think that some of the methods below are not implemented. - * If so, remove them. + * \brief A helper class to create Topologies based on the + * ns3::PointToPointNetDevice and ns3::PointToPointChannel objects. */ class PointToPointTopology { public: /** + * \param n1 Node + * \param n2 Node + * \param rate Maximum transmission link rate + * \param delay one-way propagation delay + * \return Pointer to the underlying PointToPointChannel + * * Add a full-duplex point-to-point link between two nodes - * with the specified IP addresses, with specified maximum transmission rate - * and propagation delay. + * and attach PointToPointNetDevices to the resulting + * PointToPointChannel. */ - static PointToPointChannel* AddPointToPointLink( - Node*, Node*, const DataRate&, const Time&); + static Ptr AddPointToPointLink( + Ptr n1, Ptr 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 chan, + Ptr n1, const Ipv4Address& addr1, + Ptr n2, const Ipv4Address& addr2); /** - * Get the connecting node n1 to node n2 + * \param channel PointToPointChannel to use + * \param n1 Node + * \param n2 Node + * + * For the given PointToPointChannel, for each Node, add an + * IPv4 host route to the IPv4 address of the peer node. */ - static PointToPointChannel* GetChannel(Node*, Node*); - /** - * Get the NetDevice connecting node n1 to n2 - */ - 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 n1, Ptr n2, Ptr channel); }; } // namespace ns3 diff --git a/src/internet-node/arp-cache.cc b/src/internet-node/arp-cache.cc index 6a6f71bc9..e9f48561d 100644 --- a/src/internet-node/arp-cache.cc +++ b/src/internet-node/arp-cache.cc @@ -28,24 +28,21 @@ namespace ns3 { -ArpCache::ArpCache (NetDevice *device, Ipv4Interface *interface) +ArpCache::ArpCache (Ptr 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 +ArpCache::GetDevice (void) const { return m_device; } diff --git a/src/internet-node/arp-cache.h b/src/internet-node/arp-cache.h index 5923d2ca9..6a1d182be 100644 --- a/src/internet-node/arp-cache.h +++ b/src/internet-node/arp-cache.h @@ -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 @@ class ArpCache { public: class Entry; - ArpCache (NetDevice *device, Ipv4Interface *interface); + ArpCache (Ptr device, Ipv4Interface *interface); ~ArpCache (); - NetDevice *PeekDevice (void) const; + Ptr GetDevice (void) const; Ipv4Interface *GetInterface (void) const; void SetAliveTimeout (Time aliveTimeout); @@ -91,7 +92,7 @@ private: typedef sgi::hash_map Cache; typedef sgi::hash_map::iterator CacheI; - NetDevice *m_device; + Ptr m_device; Ipv4Interface *m_interface; Time m_aliveTimeout; Time m_deadTimeout; diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index ee168bfd8..a4742d04c 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -31,25 +31,21 @@ namespace ns3 { -ArpIpv4Interface::ArpIpv4Interface (Node *node, NetDevice *device) +ArpIpv4Interface::ArpIpv4Interface (Ptr node, Ptr 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 @@ ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context) 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::iid); + Ptr arp = m_node->QueryInterface (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); } } diff --git a/src/internet-node/arp-ipv4-interface.h b/src/internet-node/arp-ipv4-interface.h index 7b92b2234..b1c0698f1 100644 --- a/src/internet-node/arp-ipv4-interface.h +++ b/src/internet-node/arp-ipv4-interface.h @@ -23,6 +23,7 @@ #define ARP_IPV4_INTERFACE_H #include "ipv4-interface.h" +#include "ns3/ptr.h" namespace ns3 { @@ -42,13 +43,13 @@ class ArpIpv4Interface : public Ipv4Interface NETDEVICE, ARP, }; - ArpIpv4Interface (Node *node, NetDevice *device); + ArpIpv4Interface (Ptr node, Ptr device); virtual ~ArpIpv4Interface (); private: virtual void SendTo (Packet p, Ipv4Address dest); virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); - Node *m_node; + Ptr m_node; }; }//namespace ns3 diff --git a/src/internet-node/arp.cc b/src/internet-node/arp.cc index 8c702adf4..3a085793e 100644 --- a/src/internet-node/arp.cc +++ b/src/internet-node/arp.cc @@ -36,17 +36,13 @@ namespace ns3 { const uint16_t Arp::PROT_NUMBER = 0x0806; -Arp::Arp (Node *node) +Arp::Arp (Ptr 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 @@ Arp::DoDispose (void) delete *i; } m_cacheList.clear (); - if (m_node != 0) - { - m_node->Unref (); - m_node = 0; - } + m_node = 0; L3Protocol::DoDispose (); } @@ -71,18 +63,17 @@ Arp::CreateTraceResolver (TraceContext const &context) } ArpCache * -Arp::FindCache (NetDevice *device) +Arp::FindCache (Ptr 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::iid); + Ptr ipv4 = m_node->QueryInterface (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 @@ Arp::FindCache (NetDevice *device) } void -Arp::Receive(Packet& packet, NetDevice *device) +Arp::Receive(Packet& packet, Ptr device) { ArpCache *cache = FindCache (device); ArpHeader arp; @@ -140,7 +131,7 @@ Arp::Receive(Packet& packet, NetDevice *device) } bool Arp::Lookup (Packet &packet, Ipv4Address destination, - NetDevice *device, + Ptr device, MacAddress *hardwareDestination) { ArpCache *cache = FindCache (device); @@ -212,25 +203,25 @@ void 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 diff --git a/src/internet-node/arp.h b/src/internet-node/arp.h index ef909b2c8..0273d5e3b 100644 --- a/src/internet-node/arp.h +++ b/src/internet-node/arp.h @@ -24,6 +24,7 @@ #include #include "ns3/ipv4-address.h" #include "ns3/mac-address.h" +#include "ns3/ptr.h" #include "l3-protocol.h" namespace ns3 { @@ -40,24 +41,24 @@ class Arp : public L3Protocol public: static const uint16_t PROT_NUMBER; - Arp (Node *node); + Arp (Ptr node); ~Arp (); virtual TraceResolver *CreateTraceResolver (TraceContext const &context); - virtual void Receive(Packet& p, NetDevice *device); + virtual void Receive(Packet& p, Ptr device); bool Lookup (Packet &p, Ipv4Address destination, - NetDevice *device, + Ptr device, MacAddress *hardwareDestination); protected: virtual void DoDispose (void); private: typedef std::list CacheList; - ArpCache *FindCache (NetDevice *device); + ArpCache *FindCache (Ptr device); void SendArpRequest (ArpCache const *cache, Ipv4Address to); void SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac); CacheList m_cacheList; - Node *m_node; + Ptr m_node; }; }//namespace ns3 diff --git a/src/internet-node/ascii-trace.cc b/src/internet-node/ascii-trace.cc index 761dcdfb0..9b1a69d01 100644 --- a/src/internet-node/ascii-trace.cc +++ b/src/internet-node/ascii-trace.cc @@ -110,7 +110,7 @@ AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet) 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 @@ AsciiTrace::LogDevRx (TraceContext const &context, Packet &p) 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 << " "; diff --git a/src/internet-node/i-arp-private.cc b/src/internet-node/i-arp-private.cc index 89b628c27..0071b86bd 100644 --- a/src/internet-node/i-arp-private.cc +++ b/src/internet-node/i-arp-private.cc @@ -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) + : Interface (IArpPrivate::iid), m_arp (arp) -{ - m_arp->Ref (); -} +{} IArpPrivate::~IArpPrivate () { NS_ASSERT (m_arp == 0); @@ -39,7 +38,7 @@ IArpPrivate::~IArpPrivate () bool IArpPrivate::Lookup (Packet &p, Ipv4Address destination, - NetDevice *device, + Ptr device, MacAddress *hardwareDestination) { return m_arp->Lookup (p, destination, device, hardwareDestination); @@ -48,9 +47,8 @@ IArpPrivate::Lookup (Packet &p, Ipv4Address destination, void IArpPrivate::DoDispose (void) { - m_arp->Unref (); m_arp = 0; - NsUnknown::DoDispose (); + Interface::DoDispose (); } diff --git a/src/internet-node/i-arp-private.h b/src/internet-node/i-arp-private.h index 39aeb04eb..1d78b07fb 100644 --- a/src/internet-node/i-arp-private.h +++ b/src/internet-node/i-arp-private.h @@ -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 MacAddress; 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); virtual ~IArpPrivate (); bool Lookup (Packet &p, Ipv4Address destination, - NetDevice *device, + Ptr device, MacAddress *hardwareDestination); protected: virtual void DoDispose (void); private: - Arp *m_arp; + Ptr m_arp; }; } // namespace ns3 diff --git a/src/internet-node/i-ipv4-impl.cc b/src/internet-node/i-ipv4-impl.cc index 82b5d0155..19ec5f617 100644 --- a/src/internet-node/i-ipv4-impl.cc +++ b/src/internet-node/i-ipv4-impl.cc @@ -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) : m_ipv4 (ipv4) -{ - m_ipv4->Ref (); -} +{} IIpv4Impl::~IIpv4Impl () { NS_ASSERT (m_ipv4 == 0); @@ -36,7 +36,6 @@ IIpv4Impl::~IIpv4Impl () void IIpv4Impl::DoDispose (void) { - m_ipv4->Unref (); m_ipv4 = 0; } @@ -90,7 +89,7 @@ IIpv4Impl::RemoveRoute (uint32_t i) return m_ipv4->RemoveRoute (i); } uint32_t -IIpv4Impl::AddInterface (NetDevice *device) +IIpv4Impl::AddInterface (Ptr device) { return m_ipv4->AddInterface (device); } @@ -99,6 +98,11 @@ IIpv4Impl::GetNInterfaces (void) { return m_ipv4->GetNInterfaces (); } +Ptr +IIpv4Impl::GetNetDevice (uint32_t i) +{ + return m_ipv4->GetInterface (i)-> GetDevice (); +} void IIpv4Impl::SetAddress (uint32_t i, Ipv4Address address) diff --git a/src/internet-node/i-ipv4-impl.h b/src/internet-node/i-ipv4-impl.h index b3240a089..a2cac5edc 100644 --- a/src/internet-node/i-ipv4-impl.h +++ b/src/internet-node/i-ipv4-impl.h @@ -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 Ipv4; class IIpv4Impl : public IIpv4 { public: - IIpv4Impl (Ipv4 *ipv4); + IIpv4Impl (Ptr ipv4); virtual ~IIpv4Impl (); @@ -51,8 +52,9 @@ public: 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 device); virtual uint32_t GetNInterfaces (void); + virtual Ptr GetNetDevice(uint32_t i); virtual void SetAddress (uint32_t i, Ipv4Address address); virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask); @@ -65,7 +67,7 @@ public: protected: virtual void DoDispose (void); private: - Ipv4 *m_ipv4; + Ptr m_ipv4; }; } // namespace ns3 diff --git a/src/internet-node/i-ipv4-private.cc b/src/internet-node/i-ipv4-private.cc index 2921d5262..8928a363b 100644 --- a/src/internet-node/i-ipv4-private.cc +++ b/src/internet-node/i-ipv4-private.cc @@ -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) + : Interface (IIpv4Private::iid), m_ipv4 (ipv4) -{ - m_ipv4->Ref (); -} +{} IIpv4Private::~IIpv4Private () { NS_ASSERT (m_ipv4 == 0); @@ -48,21 +47,20 @@ IIpv4Private::Send (Packet const &packet, Ipv4Address source, m_ipv4->Send (packet, source, destination, protocol); } Ipv4Interface * -IIpv4Private::FindInterfaceForDevice (NetDevice const*device) +IIpv4Private::FindInterfaceForDevice (Ptrdevice) { return m_ipv4->FindInterfaceForDevice (device); } void -IIpv4Private::Receive(Packet& p, NetDevice *device) +IIpv4Private::Receive(Packet& p, Ptr device) { m_ipv4->Receive (p, device); } void IIpv4Private::DoDispose (void) { - m_ipv4->Unref (); m_ipv4 = 0; - NsUnknown::DoDispose (); + Interface::DoDispose (); } } // namespace ns3 diff --git a/src/internet-node/i-ipv4-private.h b/src/internet-node/i-ipv4-private.h index a300f725f..70695f150 100644 --- a/src/internet-node/i-ipv4-private.h +++ b/src/internet-node/i-ipv4-private.h @@ -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 namespace ns3 { @@ -34,22 +35,22 @@ class TraceResolver; 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); 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 (Ptrdevice); + void Receive(Packet& p, Ptr device); protected: virtual void DoDispose (void); private: - Ipv4 *m_ipv4; + Ptr m_ipv4; }; } // namespace ns3 diff --git a/src/internet-node/i-udp-impl.cc b/src/internet-node/i-udp-impl.cc index 00b522f83..b0b094f44 100644 --- a/src/internet-node/i-udp-impl.cc +++ b/src/internet-node/i-udp-impl.cc @@ -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) : m_udp (udp) -{ - m_udp->Ref (); -} +{} IUdpImpl::~IUdpImpl () { NS_ASSERT (m_udp == 0); } -Socket * +Ptr IUdpImpl::CreateSocket (void) { return m_udp->CreateSocket (); @@ -43,11 +42,7 @@ IUdpImpl::CreateSocket (void) void IUdpImpl::DoDispose (void) { - if (m_udp != 0) - { - m_udp->Unref (); - m_udp = 0; - } + m_udp = 0; IUdp::DoDispose (); } diff --git a/src/internet-node/i-udp-impl.h b/src/internet-node/i-udp-impl.h index 5acbac900..7bd9c4bae 100644 --- a/src/internet-node/i-udp-impl.h +++ b/src/internet-node/i-udp-impl.h @@ -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 Udp; class IUdpImpl : public IUdp { public: - IUdpImpl (Udp *udp); + IUdpImpl (Ptr udp); virtual ~IUdpImpl (); - virtual Socket *CreateSocket (void); + virtual Ptr CreateSocket (void); protected: virtual void DoDispose (void); private: - Udp *m_udp; + Ptr m_udp; }; } // namespace ns3 diff --git a/src/internet-node/internet-node.cc b/src/internet-node/internet-node.cc index 2f18becea..bcda19190 100644 --- a/src/internet-node/internet-node.cc +++ b/src/internet-node/internet-node.cc @@ -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 @@ namespace ns3 { InternetNode::InternetNode() { - Ipv4 *ipv4 = new Ipv4 (this); - Arp *arp = new Arp (this); - Udp *udp = new Udp (this); + Ptr ipv4 = MakeNewObject (this); + Ptr arp = MakeNewObject (this); + Ptr udp = MakeNewObject (this); - ApplicationList *applicationList = new ApplicationList(this); - L3Demux *l3Demux = new L3Demux(this); - Ipv4L4Demux *ipv4L4Demux = new Ipv4L4Demux(this); + Ptr l3Demux = MakeNewObject (this); + Ptr ipv4L4Demux = MakeNewObject (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 udpImpl = MakeNewObject (udp); + Ptr arpPrivate = MakeNewObject (arp); + Ptr ipv4Impl = MakeNewObject (ipv4); + Ptr ipv4Private = MakeNewObject (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 @@ InternetNode::SetName (std::string name) } TraceResolver * -InternetNode::CreateTraceResolver (TraceContext const &context) +InternetNode::DoCreateTraceResolver (TraceContext const &context) { CompositeTraceResolver *resolver = new CompositeTraceResolver (context); - IIpv4Private *ipv4 = QueryInterface (IIpv4Private::iid); + Ptr ipv4 = QueryInterface (IIpv4Private::iid); resolver->Add ("ipv4", - MakeCallback (&IIpv4Private::CreateTraceResolver, ipv4), + MakeCallback (&IIpv4Private::CreateTraceResolver, PeekPointer (ipv4)), InternetNode::IPV4); - ipv4->Unref (); return resolver; } @@ -108,17 +92,16 @@ InternetNode::DoDispose() } void -InternetNode::DoAddDevice (NetDevice *device) const +InternetNode::DoAddDevice (Ptr device) const { device->SetReceiveCallback (MakeCallback (&InternetNode::ReceiveFromDevice, this)); } bool -InternetNode::ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const +InternetNode::ReceiveFromDevice (Ptr device, const Packet &p, uint16_t protocolNumber) const { - L3Demux *demux = QueryInterface (L3Demux::iid); - L3Protocol *target = demux->PeekProtocol (protocolNumber); - demux->Unref (); + Ptr demux = QueryInterface (L3Demux::iid); + Ptr target = demux->GetProtocol (protocolNumber); if (target != 0) { Packet packet = p; diff --git a/src/internet-node/internet-node.h b/src/internet-node/internet-node.h index 835acb870..63d04ed6d 100644 --- a/src/internet-node/internet-node.h +++ b/src/internet-node/internet-node.h @@ -41,14 +41,14 @@ public: }; 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 device) const; + virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); + bool ReceiveFromDevice (Ptr device, const Packet &p, uint16_t protocolNumber) const; std::string m_name; }; diff --git a/src/internet-node/ipv4-interface.cc b/src/internet-node/ipv4-interface.cc index e8bc9b116..cfc398582 100644 --- a/src/internet-node/ipv4-interface.cc +++ b/src/internet-node/ipv4-interface.cc @@ -31,26 +31,16 @@ namespace ns3 { * 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 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 +Ipv4Interface::GetDevice (void) const { return m_netdevice; } diff --git a/src/internet-node/ipv4-interface.h b/src/internet-node/ipv4-interface.h index ef2b56408..1098c567c 100644 --- a/src/internet-node/ipv4-interface.h +++ b/src/internet-node/ipv4-interface.h @@ -25,6 +25,7 @@ #include #include "ns3/ipv4-address.h" +#include "ns3/ptr.h" namespace ns3 { @@ -69,7 +70,7 @@ public: * This value can be zero in which case the MTU * of this interface will be 2^(16-1). */ - Ipv4Interface (NetDevice *nd); + Ipv4Interface (Ptr nd); virtual ~Ipv4Interface(); /** @@ -87,7 +88,7 @@ public: * \returns the underlying NetDevice. This method can return * zero if this interface has no associated NetDevice. */ - NetDevice *PeekDevice (void) const; + Ptr GetDevice (void) const; /** * \param a set the ipv4 address of this interface. @@ -153,7 +154,7 @@ public: private: virtual void SendTo (Packet p, Ipv4Address dest) = 0; virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0; - NetDevice* m_netdevice; + Ptr m_netdevice; bool m_ifup; Ipv4Address m_address; Ipv4Mask m_netmask; diff --git a/src/internet-node/ipv4-l4-demux.cc b/src/internet-node/ipv4-l4-demux.cc index 3547e239f..a60ed9629 100644 --- a/src/internet-node/ipv4-l4-demux.cc +++ b/src/internet-node/ipv4-l4-demux.cc @@ -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) + : Interface (Ipv4L4Demux::iid), m_node (node) -{ - m_node->Ref (); -} +{} Ipv4L4Demux::~Ipv4L4Demux() {} @@ -45,18 +43,14 @@ Ipv4L4Demux::~Ipv4L4Demux() 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 @@ Ipv4L4Demux::CreateTraceResolver (TraceContext const &context) CompositeTraceResolver *resolver = new CompositeTraceResolver (context); for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i) { - Ipv4L4Protocol *protocol = *i; + Ptr 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 protocol) { - protocol->Ref (); m_protocols.push_back (protocol); } -Ipv4L4Protocol* -Ipv4L4Demux::PeekProtocol(int protocolNumber) +Ptr +Ipv4L4Demux::GetProtocol(int protocolNumber) { for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i) { @@ -95,7 +88,7 @@ Ipv4L4Demux::PeekProtocol(int protocolNumber) return 0; } void -Ipv4L4Demux::Erase(Ipv4L4Protocol*protocol) +Ipv4L4Demux::Remove (Ptr protocol) { m_protocols.remove (protocol); } diff --git a/src/internet-node/ipv4-l4-demux.h b/src/internet-node/ipv4-l4-demux.h index 3e70ad9d7..f6b199be9 100644 --- a/src/internet-node/ipv4-l4-demux.h +++ b/src/internet-node/ipv4-l4-demux.h @@ -26,7 +26,8 @@ #define IPV4_L4_DEMUX_H #include -#include "ns3/ns-unknown.h" +#include "ns3/interface.h" +#include "ns3/ptr.h" namespace ns3 { @@ -38,12 +39,12 @@ class TraceContext; /** * \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); virtual ~Ipv4L4Demux(); /** @@ -64,7 +65,7 @@ public: * 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 protocol); /** * \param protocolNumber number of protocol to lookup * in this L4 Demux @@ -74,19 +75,19 @@ public: * to forward packets up the stack to the right protocol. * It is also called from InternetNode::GetUdp for example. */ - Ipv4L4Protocol* PeekProtocol(int protocolNumber); + Ptr 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 protocol); private: virtual void DoDispose (void); - typedef std::list L4List_t; + typedef std::list > L4List_t; L4List_t m_protocols; - Node *m_node; + Ptr m_node; }; } //namespace ns3 diff --git a/src/internet-node/ipv4-l4-protocol.h b/src/internet-node/ipv4-l4-protocol.h index 8e1b4397e..f23aa510b 100644 --- a/src/internet-node/ipv4-l4-protocol.h +++ b/src/internet-node/ipv4-l4-protocol.h @@ -29,7 +29,6 @@ namespace ns3 { -class Node; class Packet; class Ipv4Address; class TraceResolver; diff --git a/src/internet-node/ipv4-loopback-interface.cc b/src/internet-node/ipv4-loopback-interface.cc index 37a4eaf37..97bffb066 100644 --- a/src/internet-node/ipv4-loopback-interface.cc +++ b/src/internet-node/ipv4-loopback-interface.cc @@ -27,16 +27,12 @@ namespace ns3 { -Ipv4LoopbackInterface::Ipv4LoopbackInterface (Node *node) +Ipv4LoopbackInterface::Ipv4LoopbackInterface (Ptr node) : Ipv4Interface (0), m_node (node) -{ - m_node->Ref (); -} +{} Ipv4LoopbackInterface::~Ipv4LoopbackInterface () -{ - m_node->Unref (); -} +{} TraceResolver * Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context) @@ -47,9 +43,8 @@ Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context) void Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest) { - IIpv4Private *ipv4 = m_node->QueryInterface (IIpv4Private::iid); - ipv4->Receive (packet, PeekDevice ()); - ipv4->Unref (); + Ptr ipv4 = m_node->QueryInterface (IIpv4Private::iid); + ipv4->Receive (packet, GetDevice ()); } }//namespace ns3 diff --git a/src/internet-node/ipv4-loopback-interface.h b/src/internet-node/ipv4-loopback-interface.h index c4dff8763..cc7609b4a 100644 --- a/src/internet-node/ipv4-loopback-interface.h +++ b/src/internet-node/ipv4-loopback-interface.h @@ -23,6 +23,7 @@ #define IPV4_LOOPBACK_INTERFACE_H #include "ipv4-interface.h" +#include "ns3/ptr.h" namespace ns3 { @@ -31,14 +32,14 @@ class Node; class Ipv4LoopbackInterface : public Ipv4Interface { public: - Ipv4LoopbackInterface (Node *node); + Ipv4LoopbackInterface (Ptr node); virtual ~Ipv4LoopbackInterface (); private: virtual void SendTo (Packet p, Ipv4Address dest); virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); - Node *m_node; + Ptr m_node; }; }//namespace ns3 diff --git a/src/internet-node/ipv4.cc b/src/internet-node/ipv4.cc index d049edcd7..14f58f99e 100644 --- a/src/internet-node/ipv4.cc +++ b/src/internet-node/ipv4.cc @@ -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 @@ namespace ns3 { const uint16_t Ipv4::PROT_NUMBER = 0x0800; -Ipv4::Ipv4(Node *node) +Ipv4::Ipv4(Ptr node) : L3Protocol (PROT_NUMBER, 4), m_nInterfaces (0), m_defaultTtl (64), @@ -51,12 +52,9 @@ Ipv4::Ipv4(Node *node) m_node (node) { SetupLoopback (); - m_node->Ref (); } Ipv4::~Ipv4 () -{ - DoDispose (); -} +{} void Ipv4::DoDispose (void) @@ -83,11 +81,7 @@ Ipv4::DoDispose (void) 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 @@ Ipv4::RemoveRoute (uint32_t index) uint32_t -Ipv4::AddInterface (NetDevice *device) +Ipv4::AddInterface (Ptr device) { Ipv4Interface *interface = new ArpIpv4Interface (m_node, device); return AddIpv4Interface (interface); @@ -351,11 +345,11 @@ Ipv4::GetNInterfaces (void) const } Ipv4Interface * -Ipv4::FindInterfaceForDevice (NetDevice const*device) +Ipv4::FindInterfaceForDevice (Ptr 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 @@ Ipv4::FindInterfaceForDevice (NetDevice const*device) } void -Ipv4::Receive(Packet& packet, NetDevice *device) +Ipv4::Receive(Packet& packet, Ptr 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 @@ Ipv4::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route bool -Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device) +Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device) { for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) @@ -465,7 +459,7 @@ Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device) 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 @@ Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device) void Ipv4::ForwardUp (Packet p, Ipv4Header const&ip) { - Ipv4L4Demux *demux = m_node->QueryInterface (Ipv4L4Demux::iid); - Ipv4L4Protocol *protocol = demux->PeekProtocol (ip.GetProtocol ()); - demux->Unref (); + Ptr demux = m_node->QueryInterface (Ipv4L4Demux::iid); + Ptr protocol = demux->GetProtocol (ip.GetProtocol ()); protocol->Receive (p, ip.GetSource (), ip.GetDestination ()); } diff --git a/src/internet-node/ipv4.h b/src/internet-node/ipv4.h index 84b63bf95..1b88f1863 100644 --- a/src/internet-node/ipv4.h +++ b/src/internet-node/ipv4.h @@ -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 @@ public: }; typedef ArrayTraceResolver::Index InterfaceIndex; - Ipv4(Node *node); + Ipv4(Ptr node); virtual ~Ipv4 (); /** @@ -164,7 +165,7 @@ public: * 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 device); /** * \param i index of interface to return * \returns the requested interface @@ -181,7 +182,7 @@ public: * Try to find an Ipv4Interface whose NetDevice is equal to * the input NetDevice. */ - Ipv4Interface *FindInterfaceForDevice (NetDevice const*device); + Ipv4Interface *FindInterfaceForDevice (Ptr device); /** @@ -191,7 +192,7 @@ public: * - 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 device); /** * \param packet packet to send @@ -219,7 +220,7 @@ protected: 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 device); void ForwardUp (Packet p, Ipv4Header const&ip); uint32_t AddIpv4Interface (Ipv4Interface *interface); void SetupLoopback (void); @@ -240,7 +241,7 @@ private: HostRoutes m_hostRoutes; NetworkRoutes m_networkRoutes; Ipv4Route *m_defaultRoute; - Node *m_node; + Ptr m_node; CallbackTraceSource m_txTrace; CallbackTraceSource m_rxTrace; CallbackTraceSource m_dropTrace; diff --git a/src/internet-node/l3-demux.cc b/src/internet-node/l3-demux.cc index 5f261aca5..e5912c64c 100644 --- a/src/internet-node/l3-demux.cc +++ b/src/internet-node/l3-demux.cc @@ -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) + : Interface (L3Demux::iid), m_node (node) -{ - m_node->Ref (); -} +{} L3Demux::~L3Demux() {} @@ -47,15 +45,11 @@ L3Demux::DoDispose (void) 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 @@ L3Demux::CreateTraceResolver (TraceContext const &context) const 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 p) { - p->Ref (); m_protocols.insert(L3Map_t::value_type(p->GetProtocolNumber (), p)); } -L3Protocol* -L3Demux::PeekProtocol (int p) +Ptr +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 } diff --git a/src/internet-node/l3-demux.h b/src/internet-node/l3-demux.h index 40f8318f5..477a43e92 100644 --- a/src/internet-node/l3-demux.h +++ b/src/internet-node/l3-demux.h @@ -28,7 +28,8 @@ #define L3_DEMUX_H #include -#include "ns3/ns-unknown.h" +#include "ns3/interface.h" +#include "ns3/ptr.h" namespace ns3 { @@ -40,12 +41,12 @@ class TraceContext; /** * \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); virtual ~L3Demux(); /** @@ -67,7 +68,7 @@ public: * 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 protocol); /** * \param protocolNumber number of protocol to lookup * in this L4 Demux @@ -77,20 +78,13 @@ public: * 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 GetProtocol (int protocolNumber); protected: virtual void DoDispose (void); private: - typedef std::map L3Map_t; + typedef std::map > L3Map_t; - Node *m_node; + Ptr m_node; L3Map_t m_protocols; }; diff --git a/src/internet-node/l3-protocol.h b/src/internet-node/l3-protocol.h index d309aca9a..56c6a5914 100644 --- a/src/internet-node/l3-protocol.h +++ b/src/internet-node/l3-protocol.h @@ -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 @@ public: * - 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 device) = 0; protected: virtual void DoDispose (void); diff --git a/src/internet-node/pcap-trace.cc b/src/internet-node/pcap-trace.cc index e3263fd4c..8ffe86555 100644 --- a/src/internet-node/pcap-trace.cc +++ b/src/internet-node/pcap-trace.cc @@ -84,7 +84,7 @@ PcapTrace::LogIp (TraceContext const &context, Packet const &p, uint32_t interfa { 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); } diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index 3ef89a090..233376318 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -26,7 +26,7 @@ namespace ns3 { -UdpSocket::UdpSocket (Node *node, Udp *udp) +UdpSocket::UdpSocket (Ptr node, Ptr udp) : m_endPoint (0), m_node (node), m_udp (udp), @@ -34,17 +34,10 @@ UdpSocket::UdpSocket (Node *node, Udp *udp) 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 @@ UdpSocket::~UdpSocket () 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 +UdpSocket::GetNode (void) const { return m_node; } @@ -76,17 +65,9 @@ UdpSocket::PeekNode (void) const 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 @@ UdpSocket::ShutdownRecv (void) } void -UdpSocket::DoClose(ns3::Callback closeCompleted) +UdpSocket::DoClose(ns3::Callback > closeCompleted) { // XXX: we should set the close state and check it in all API methods. if (!closeCompleted.IsNull ()) @@ -155,9 +136,9 @@ UdpSocket::DoClose(ns3::Callback closeCompleted) void UdpSocket::DoConnect(const Ipv4Address & address, uint16_t portNumber, - ns3::Callback connectionSucceeded, - ns3::Callback connectionFailed, - ns3::Callback halfClose) + ns3::Callback > connectionSucceeded, + ns3::Callback > connectionFailed, + ns3::Callback > halfClose) { m_defaultAddress = address; m_defaultPort = portNumber; @@ -168,9 +149,9 @@ UdpSocket::DoConnect(const Ipv4Address & address, m_connected = true; } int -UdpSocket::DoAccept(ns3::Callback connectionRequest, - ns3::Callback newConnectionCreated, - ns3::Callback closeRequested) +UdpSocket::DoAccept(ns3::Callback, const Ipv4Address&, uint16_t> connectionRequest, + ns3::Callback, const Ipv4Address&, uint16_t> newConnectionCreated, + ns3::Callback > closeRequested) { // calling accept on a udp socket is a programming error. m_errno = EOPNOTSUPP; @@ -179,7 +160,7 @@ UdpSocket::DoAccept(ns3::Callback c int UdpSocket::DoSend (const uint8_t* buffer, uint32_t size, - ns3::Callback dataSent) + ns3::Callback, uint32_t> dataSent) { if (!m_connected) { @@ -199,7 +180,7 @@ UdpSocket::DoSend (const uint8_t* buffer, } int UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport, - ns3::Callback dataSent) + ns3::Callback, uint32_t> dataSent) { if (m_endPoint == 0) { @@ -228,7 +209,7 @@ UdpSocket::DoSendTo(const Ipv4Address &address, uint16_t port, const uint8_t *buffer, uint32_t size, - ns3::Callback dataSent) + ns3::Callback, uint32_t> dataSent) { if (m_connected) { @@ -247,12 +228,12 @@ UdpSocket::DoSendTo(const Ipv4Address &address, return DoSendPacketTo (p, address, port, dataSent); } void -UdpSocket::DoRecv(ns3::Callback callback) +UdpSocket::DoRecv(ns3::Callback, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback) { m_rxCallback = callback; } void -UdpSocket::DoRecvDummy(ns3::Callback callback) +UdpSocket::DoRecvDummy(ns3::Callback, uint32_t,const Ipv4Address&, uint16_t> callback) { m_dummyRxCallback = callback; } diff --git a/src/internet-node/udp-socket.h b/src/internet-node/udp-socket.h index c75ff9ae6..9d2d5805e 100644 --- a/src/internet-node/udp-socket.h +++ b/src/internet-node/udp-socket.h @@ -24,6 +24,7 @@ #include #include "ns3/callback.h" #include "ns3/socket.h" +#include "ns3/ptr.h" namespace ns3 { @@ -38,11 +39,11 @@ public: /** * Create an unbound udp socket. */ - UdpSocket (Node *node, Udp *udp); + UdpSocket (Ptr node, Ptr udp); virtual ~UdpSocket (); virtual enum SocketErrno GetErrno (void) const; - virtual Node *PeekNode (void) const; + virtual Ptr GetNode (void) const; virtual int Bind (void); virtual int Bind (Ipv4Address address); virtual int Bind (uint16_t port); @@ -51,25 +52,25 @@ public: virtual int ShutdownRecv (void); private: - virtual void DoClose(ns3::Callback closeCompleted); + virtual void DoClose(ns3::Callback > closeCompleted); virtual void DoConnect(const Ipv4Address & address, uint16_t portNumber, - ns3::Callback connectionSucceeded, - ns3::Callback connectionFailed, - ns3::Callback halfClose); - virtual int DoAccept(ns3::Callback connectionRequest, - ns3::Callback newConnectionCreated, - ns3::Callback closeRequested); + ns3::Callback > connectionSucceeded, + ns3::Callback > connectionFailed, + ns3::Callback > halfClose); + virtual int DoAccept(ns3::Callback, const Ipv4Address&, uint16_t> connectionRequest, + ns3::Callback, const Ipv4Address&, uint16_t> newConnectionCreated, + ns3::Callback > closeRequested); virtual int DoSend (const uint8_t* buffer, uint32_t size, - ns3::Callback dataSent); + ns3::Callback, uint32_t> dataSent); virtual int DoSendTo(const Ipv4Address &address, uint16_t port, const uint8_t *buffer, uint32_t size, - ns3::Callback dataSent); - virtual void DoRecv(ns3::Callback); - virtual void DoRecvDummy(ns3::Callback); + ns3::Callback, uint32_t> dataSent); + virtual void DoRecv(ns3::Callback, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t>); + virtual void DoRecvDummy(ns3::Callback, uint32_t,const Ipv4Address&, uint16_t>); private: friend class Udp; @@ -78,15 +79,15 @@ private: 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 dataSent); + ns3::Callback, uint32_t> dataSent); Ipv4EndPoint *m_endPoint; - Node *m_node; - Udp *m_udp; + Ptr m_node; + Ptr m_udp; Ipv4Address m_defaultAddress; uint16_t m_defaultPort; - Callback m_dummyRxCallback; - Callback m_rxCallback; + Callback,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback; + Callback,uint8_t const*,uint32_t,const Ipv4Address &,uint16_t> m_rxCallback; enum SocketErrno m_errno; bool m_shutdownSend; bool m_shutdownRecv; diff --git a/src/internet-node/udp.cc b/src/internet-node/udp.cc index 9261aa9a6..8a0ffc55a 100644 --- a/src/internet-node/udp.cc +++ b/src/internet-node/udp.cc @@ -38,13 +38,11 @@ namespace ns3 { /* see http://www.iana.org/assignments/protocol-numbers */ const uint8_t Udp::PROT_NUMBER = 17; -Udp::Udp (Node *node) +Udp::Udp (Ptr node) : Ipv4L4Protocol (PROT_NUMBER, 2), m_node (node), m_endPoints (new Ipv4EndPointDemux ()) -{ - m_node->Ref (); -} +{} Udp::~Udp () {} @@ -63,18 +61,15 @@ Udp::DoDispose (void) delete m_endPoints; m_endPoints = 0; } - if (m_node != 0) - { - m_node->Unref (); - m_node = 0; - } + m_node = 0; Ipv4L4Protocol::DoDispose (); } -Socket * +Ptr Udp::CreateSocket (void) { - return new UdpSocket (m_node, this); + Ptr socket = MakeNewObject (m_node, this); + return socket; } Ipv4EndPoint * @@ -142,11 +137,10 @@ Udp::Send (Packet packet, packet.AddHeader (udpHeader); - IIpv4Private *ipv4 = m_node->QueryInterface (IIpv4Private::iid); + Ptr ipv4 = m_node->QueryInterface (IIpv4Private::iid); if (ipv4 != 0) { ipv4->Send (packet, saddr, daddr, PROT_NUMBER); - ipv4->Unref (); } } diff --git a/src/internet-node/udp.h b/src/internet-node/udp.h index 191dd2b73..fdb707230 100644 --- a/src/internet-node/udp.h +++ b/src/internet-node/udp.h @@ -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 @@ class Udp : public Ipv4L4Protocol { public: static const uint8_t PROT_NUMBER; - Udp (Node *node); + Udp (Ptr node); virtual ~Udp (); virtual TraceResolver *CreateTraceResolver (TraceContext const &context); - Socket *CreateSocket (void); + Ptr CreateSocket (void); Ipv4EndPoint *Allocate (void); Ipv4EndPoint *Allocate (Ipv4Address address); @@ -67,7 +68,7 @@ public: protected: virtual void DoDispose (void); private: - Node *m_node; + Ptr m_node; Ipv4EndPointDemux *m_endPoints; }; diff --git a/src/node/application.cc b/src/node/application.cc new file mode 100644 index 000000000..3346da3c2 --- /dev/null +++ b/src/node/application.cc @@ -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 + */ + +// 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 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 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 + + diff --git a/src/node/application.h b/src/node/application.h new file mode 100644 index 000000000..f761467fe --- /dev/null +++ b/src/node/application.h @@ -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 + */ + +#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); + 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 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 m_node; +}; + +} //namespace ns3 +#endif diff --git a/src/node/channel.cc b/src/node/channel.cc index 690da0ce8..c5875b82e 100644 --- a/src/node/channel.cc +++ b/src/node/channel.cc @@ -27,14 +27,18 @@ NS_DEBUG_COMPONENT_DEFINE ("Channel"); 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 << ")"); } diff --git a/src/node/channel.h b/src/node/channel.h index 0afb4da0b..20671f9d5 100644 --- a/src/node/channel.h +++ b/src/node/channel.h @@ -24,7 +24,8 @@ #include #include -#include "ns3/object.h" +#include "ns3/interface.h" +#include "ns3/ptr.h" namespace ns3 { @@ -36,9 +37,10 @@ class NetDevice; * 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 @@ public: * * This method must be implemented by subclasses. */ - virtual NetDevice *GetDevice (uint32_t i) const = 0; + virtual Ptr GetDevice (uint32_t i) const = 0; protected: virtual ~Channel (); diff --git a/src/node/drop-tail.cc b/src/node/drop-tail.cc index db7a3bcab..8571bfe8a 100644 --- a/src/node/drop-tail.cc +++ b/src/node/drop-tail.cc @@ -27,12 +27,13 @@ namespace ns3 { 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 () : Queue (), @@ -47,11 +48,6 @@ DropTailQueue::~DropTailQueue () NS_DEBUG("DropTailQueue::~DropTailQueue ()"); } -DropTailQueue* DropTailQueue::Copy() const -{ - return new DropTailQueue(*this); -} - void DropTailQueue::SetMaxPackets (uint32_t npackets) { diff --git a/src/node/drop-tail.h b/src/node/drop-tail.h index 99e52e4f9..ae79b2350 100644 --- a/src/node/drop-tail.h +++ b/src/node/drop-tail.h @@ -23,6 +23,7 @@ #include #include "ns3/packet.h" #include "ns3/queue.h" +#include "ns3/component-manager.h" namespace ns3 { @@ -32,10 +33,10 @@ const int DTQ_NPACKETS_MAX_DEFAULT = 100; 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); diff --git a/src/node/i-ipv4.cc b/src/node/i-ipv4.cc index d3b41abcf..c0fea96a8 100644 --- a/src/node/i-ipv4.cc +++ b/src/node/i-ipv4.cc @@ -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 () diff --git a/src/node/i-ipv4.h b/src/node/i-ipv4.h index 11197de90..a04782119 100644 --- a/src/node/i-ipv4.h +++ b/src/node/i-ipv4.h @@ -23,7 +23,7 @@ #include #include "ns3/ipv4-address.h" -#include "ns3/ns-unknown.h" +#include "ns3/interface.h" namespace ns3 { @@ -31,10 +31,10 @@ class NetDevice; 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 @@ public: * 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 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 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; diff --git a/src/node/i-udp.cc b/src/node/i-udp.cc index 6f825e9a7..5bf31aa0d 100644 --- a/src/node/i-udp.cc +++ b/src/node/i-udp.cc @@ -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 diff --git a/src/node/i-udp.h b/src/node/i-udp.h index 85163935a..8fc071371 100644 --- a/src/node/i-udp.h +++ b/src/node/i-udp.h @@ -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 CreateSocket (void) = 0; }; } // namespace ns3 diff --git a/src/node/mac-address.h b/src/node/mac-address.h index 84ecf6ae5..4a88da1d0 100644 --- a/src/node/mac-address.h +++ b/src/node/mac-address.h @@ -19,10 +19,6 @@ * Author: Mathieu Lacage */ -/* - * This implementation borrowed from yans - */ - #ifndef MAC_ADDRESS_H #define MAC_ADDRESS_H diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 40ecc59ae..7f5033ba4 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -21,15 +21,19 @@ #include #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, const MacAddress& addr) : + Interface (NetDevice::iid), m_node (node), m_name(""), m_ifIndex (0), @@ -40,14 +44,11 @@ NetDevice::NetDevice(Node *node, const MacAddress& addr) : 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 @@ NetDevice::CreateTraceResolver (TraceContext const &context) return DoCreateTraceResolver (context); } -Channel * +Ptr NetDevice::GetChannel (void) const { return DoGetChannel (); @@ -228,8 +229,8 @@ NetDevice::NotifyLinkDown (void) } } -Node * -NetDevice::PeekNode (void) const +Ptr +NetDevice::GetNode (void) const { return m_node; } @@ -241,13 +242,15 @@ NetDevice::NeedsArp (void) const } void -NetDevice::SetReceiveCallback (Callback cb) +NetDevice::SetReceiveCallback (Callback,const Packet &,uint16_t> cb) { m_receiveCallback = cb; } void NetDevice::DoDispose() -{} +{ + m_node = 0; +} }; // namespace ns3 diff --git a/src/node/net-device.h b/src/node/net-device.h index cfb4a40e9..e85709f79 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -25,7 +25,8 @@ #include #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 @@ class Channel; * 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 @@ public: * returned can be zero if the NetDevice is not yet connected * to any channel. */ - Channel *GetChannel (void) const; + Ptr GetChannel (void) const; /** * \return the current MacAddress of this interface. @@ -109,7 +106,7 @@ public: /** * \param index ifIndex of the device */ - void SetIfIndex(const uint32_t); + void SetIfIndex(const uint32_t index); /** * \return index ifIndex of the device */ @@ -169,13 +166,28 @@ public: * base class to print the nodeid for example, it can invoke * this method. */ - Node* PeekNode (void) const; + Ptr 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 cb); + /** + * \param cb callback to invoke whenever a packet has been received and must + * be forwarded to the higher layers. + */ + void SetReceiveCallback (Callback,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, const MacAddress& addr); /** * Enable broadcast support. This method should be * called by subclasses from their constructor @@ -224,6 +236,12 @@ public: */ 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 @@ public: * 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 DoGetChannel (void) const = 0; + + Ptr m_node; std::string m_name; uint16_t m_ifIndex; MacAddress m_address; @@ -252,7 +290,7 @@ public: bool m_isMulticast; bool m_isPointToPoint; Callback m_linkChangeCallback; - Callback m_receiveCallback; + Callback,const Packet &,uint16_t> m_receiveCallback; }; }; // namespace ns3 diff --git a/src/node/node-list.cc b/src/node/node-list.cc index 5ea7d3a8b..4fed7eb5e 100644 --- a/src/node/node-list.cc +++ b/src/node/node-list.cc @@ -49,37 +49,37 @@ public: NodeListPriv (); ~NodeListPriv (); - uint32_t Add (Node *node); + uint32_t Add (Ptr node); NodeList::Iterator Begin (void); NodeList::Iterator End (void); TraceResolver *CreateTraceResolver (TraceContext const &context); Node *PeekNode (uint32_t n); + Ptr GetNode (uint32_t n); uint32_t GetNNodes (void); private: - std::vector m_nodes; + std::vector > m_nodes; }; NodeListPriv::NodeListPriv () {} NodeListPriv::~NodeListPriv () { - for (std::vector::iterator i = m_nodes.begin (); + for (std::vector >::iterator i = m_nodes.begin (); i != m_nodes.end (); i++) { - Node *node = *i; + Ptr 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) { uint32_t index = m_nodes.size (); - node->Ref (); m_nodes.push_back (node); return index; @@ -101,10 +101,17 @@ NodeListPriv::GetNNodes (void) } Node * NodeListPriv::PeekNode (uint32_t n) +{ + return PeekPointer (m_nodes[n]); +} + +Ptr +NodeListPriv::GetNode (uint32_t n) { return m_nodes[n]; } + TraceResolver * NodeListPriv::CreateTraceResolver (TraceContext const &context) { @@ -126,7 +133,7 @@ NodeListPriv::CreateTraceResolver (TraceContext const &context) namespace ns3 { uint32_t -NodeList::Add (Node *node) +NodeList::Add (Ptr node) { return SimulationSingleton::Get ()->Add (node); } @@ -145,10 +152,10 @@ NodeList::CreateTraceResolver (TraceContext const &context) { return SimulationSingleton::Get ()->CreateTraceResolver (context); } -Node * -NodeList::PeekNode (uint32_t n) +Ptr +NodeList::GetNode (uint32_t n) { - return SimulationSingleton::Get ()->PeekNode (n); + return SimulationSingleton::Get ()->GetNode (n); } diff --git a/src/node/node-list.h b/src/node/node-list.h index 57d8bf663..607a47d71 100644 --- a/src/node/node-list.h +++ b/src/node/node-list.h @@ -24,6 +24,7 @@ #include #include "ns3/array-trace-resolver.h" +#include "ns3/ptr.h" namespace ns3 { @@ -31,18 +32,48 @@ class Node; class TraceResolver; class TraceContext; +/** + * \brief the list of simulation nodes. + * + * Every Node created is automatically added to this list. + */ class NodeList { public: typedef ArrayTraceResolver::Index NodeIndex; - typedef std::vector::iterator Iterator; + typedef std::vector< Ptr >::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); + /** + * \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 GetNode (uint32_t n); }; }//namespace ns3 diff --git a/src/node/node.cc b/src/node/node.cc index baf74d17c..ca8871080 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -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() } Node::Node(uint32_t sid) - : NsUnknown (Node::iid), + : Interface (Node::iid), m_id(0), m_sid(sid) { @@ -50,6 +51,12 @@ Node::Node(uint32_t sid) Node::~Node () {} +TraceResolver * +Node::CreateTraceResolver (TraceContext const &context) +{ + return DoCreateTraceResolver (context); +} + uint32_t Node::GetId (void) const { @@ -62,23 +69,16 @@ Node::GetSystemId (void) const return m_sid; } -void -Node::SetSystemId(uint32_t s ) -{ - m_sid = s; -} - uint32_t -Node::AddDevice (NetDevice *device) +Node::AddDevice (Ptr device) { - device->Ref (); uint32_t index = m_devices.size (); m_devices.push_back (device); DoAddDevice (device); device->SetIfIndex(index); return index; } -NetDevice * +Ptr Node::GetDevice (uint32_t index) const { return m_devices[index]; @@ -89,17 +89,44 @@ Node::GetNDevices (void) const return m_devices.size (); } +uint32_t +Node::AddApplication (Ptr application) +{ + uint32_t index = m_applications.size (); + m_applications.push_back (application); + return index; +} +Ptr +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::iterator i = m_devices.begin (); + for (std::vector >::iterator i = m_devices.begin (); i != m_devices.end (); i++) { - NetDevice *device = *i; + Ptr device = *i; device->Dispose (); - device->Unref (); + *i = 0; } m_devices.clear (); - NsUnknown::DoDispose (); + for (std::vector >::iterator i = m_applications.begin (); + i != m_applications.end (); i++) + { + Ptr application = *i; + application->Dispose (); + *i = 0; + } + m_applications.clear (); + Interface::DoDispose (); } }//namespace ns3 diff --git a/src/node/node.h b/src/node/node.h index 4b072cc3e..d8d5ffecc 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -27,41 +27,145 @@ #include -#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; - uint32_t GetSystemId (void) const; - void SetSystemId(uint32_t s); - uint32_t AddDevice (NetDevice *device); - NetDevice *GetDevice (uint32_t index) const; + /** + * \returns the system id for parallel simulations associated + * to this node. + */ + uint32_t GetSystemId (void) 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 device); + /** + * \param index the index of the requested NetDevice + * \returns the requested NetDevice associated to this Node. + */ + Ptr 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); + /** + * \param index + * \returns the application associated to this requested index + * within this Node. + */ + Ptr 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 device) const = 0; uint32_t m_id; // Node id for this node uint32_t m_sid; // System id for this node - std::vector m_devices; + std::vector > m_devices; + std::vector > m_applications; }; } //namespace ns3 diff --git a/src/node/queue.cc b/src/node/queue.cc index ac4fcdff8..b63d9d7b3 100644 --- a/src/node/queue.cc +++ b/src/node/queue.cc @@ -19,16 +19,18 @@ #include "ns3/debug.h" #include "ns3/composite-trace-resolver.h" -#include "queue.h" #include "ns3/default-value.h" +#include "ns3/component-manager.h" +#include "queue.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 @@ Queue::Drop (const Packet& p) 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::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 = ComponentManager::Create (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 @@ Queue::GetDefault (void) static StringEnumDefaultValue value ("Queue", "Packet Queue"); return &value; } -Queue::List * -Queue::GetList (void) -{ - static List list; - return &list; -} }; // namespace ns3 diff --git a/src/node/queue.h b/src/node/queue.h index 9119832a9..cafd3808c 100644 --- a/src/node/queue.h +++ b/src/node/queue.h @@ -28,6 +28,7 @@ #include #include #include "ns3/packet.h" +#include "ns3/interface.h" #include "ns3/callback-trace-source.h" #include "ns3/trace-resolver.h" @@ -35,9 +36,11 @@ namespace ns3 { class StringEnumDefaultValue; -class Queue +class Queue : public Interface { public: + static const InterfaceId iid; + enum TraceType { ENQUEUE, DEQUEUE, @@ -46,8 +49,6 @@ public: Queue (); virtual ~Queue (); - virtual Queue* Copy() const = 0; - TraceResolver *CreateTraceResolver (TraceContext const &context); bool IsEmpty (void); @@ -112,22 +113,13 @@ private: 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 CreateDefault (void); + static void Add (const std::string &name); + static void AddDefault (const std::string &name); private: typedef std::list > 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 diff --git a/src/node/socket.cc b/src/node/socket.cc index 577bb8bae..75cd3a023 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -6,7 +6,7 @@ Socket::~Socket () {} void -Socket::Close(Callback closeCompleted) +Socket::Close(Callback > closeCompleted) { DoClose (closeCompleted); } @@ -14,23 +14,23 @@ Socket::Close(Callback closeCompleted) void Socket::Connect(const Ipv4Address & address, uint16_t portNumber, - Callback connectionSucceeded, - Callback connectionFailed, - Callback halfClose) + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose) { DoConnect (address, portNumber, connectionSucceeded, connectionFailed, halfClose); } int -Socket::Accept(Callback connectionRequest, - Callback newConnectionCreated, - Callback closeRequested) +Socket::Accept(Callback, const Ipv4Address&, uint16_t> connectionRequest, + Callback, const Ipv4Address&, uint16_t> newConnectionCreated, + Callback > closeRequested) { return DoAccept (connectionRequest, newConnectionCreated, closeRequested); } int Socket::Send (const uint8_t* buffer, uint32_t size, - Callback dataSent) + Callback, uint32_t> dataSent) { return DoSend (buffer, size, dataSent); } @@ -39,42 +39,42 @@ Socket::SendTo(const Ipv4Address &address, uint16_t port, const uint8_t *buffer, uint32_t size, - Callback dataSent) + Callback, uint32_t> dataSent) { return DoSendTo (address, port, buffer, size, dataSent); } void -Socket::Recv(Callback callback) +Socket::Recv(Callback, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback) { DoRecv (callback); } void -Socket::RecvDummy(Callback callback) +Socket::RecvDummy(Callback, uint32_t,const Ipv4Address&, uint16_t> callback) { DoRecvDummy (callback); } bool -Socket::RefuseAllConnections (Socket* socket, const Ipv4Address& address, uint16_t port) +Socket::RefuseAllConnections (Ptr socket, const Ipv4Address& address, uint16_t port) { return false; } void -Socket::DummyCallbackVoidSocket (Socket *socket) +Socket::DummyCallbackVoidSocket (Ptr socket) {} void -Socket::DummyCallbackVoidSocketUi32 (Socket *socket, uint32_t) +Socket::DummyCallbackVoidSocketUi32 (Ptr socket, uint32_t) {} void -Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Socket *socket, uint32_t, const Ipv4Address &, uint16_t) +Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr socket, uint32_t, const Ipv4Address &, uint16_t) {} void -Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Socket *socket, const uint8_t *, uint32_t, +Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr socket, const uint8_t *, uint32_t, const Ipv4Address &, uint16_t) {} void -Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Socket *socket, const Ipv4Address &, uint16_t) +Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Ptr socket, const Ipv4Address &, uint16_t) {} diff --git a/src/node/socket.h b/src/node/socket.h index 950318505..aacafc8f1 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -22,6 +22,7 @@ #define __SOCKET_H__ #include "ns3/callback.h" +#include "ns3/ptr.h" #include "ipv4-address.h" #include "ns3/object.h" #include @@ -65,7 +66,7 @@ public: /** * \returns the node this socket is associated with. */ - virtual Node *PeekNode (void) const = 0; + virtual Ptr GetNode (void) const = 0; /** * Allocate a free port number and @@ -113,7 +114,7 @@ public: * After the Close call, the socket is no longer valid, and cannot * safely be used for subsequent operations. */ - void Close(Callback closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket)); + void Close(Callback > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket)); /** * \returns zero on success, -1 on failure. @@ -146,9 +147,9 @@ public: */ void Connect(const Ipv4Address & address, uint16_t portNumber, - Callback connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket), - Callback connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket), - Callback halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket)); + Callback > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket), + Callback > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket), + Callback > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket)); /** * \brief Accept connection requests from remote hosts @@ -169,11 +170,11 @@ public: * \param closeRequested Callback for connection close request from peer. * XXX: when is this callback invoked ? */ - int Accept(Callback connectionRequest = + int Accept(Callback, const Ipv4Address&, uint16_t> connectionRequest = MakeCallback(&Socket::RefuseAllConnections), - Callback newConnectionCreated = + Callback, const Ipv4Address&, uint16_t> newConnectionCreated = MakeCallback (&Socket::DummyCallbackVoidSocketIpv4AddressUi16), - Callback closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket)); + Callback > closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket)); /** * \brief Send data (or dummy data) to the remote host @@ -185,7 +186,7 @@ public: */ int Send (const uint8_t* buffer, uint32_t size, - Callback dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32)); + Callback, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32)); /** * \brief Send data to a specified peer. @@ -201,59 +202,59 @@ public: uint16_t port, const uint8_t *buffer, uint32_t size, - Callback dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32)); + Callback, 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 Recv(Callback, 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 RecvDummy(Callback, uint32_t,const Ipv4Address&, uint16_t> receivedData = MakeCallback (&Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16)); private: - virtual void DoClose(Callback closeCompleted) = 0; + virtual void DoClose(Callback > closeCompleted) = 0; virtual void DoConnect(const Ipv4Address & address, uint16_t portNumber, - Callback connectionSucceeded, - Callback connectionFailed, - Callback halfClose) = 0; - virtual int DoAccept(Callback connectionRequest, - Callback newConnectionCreated, - Callback closeRequested) = 0; + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose) = 0; + virtual int DoAccept(Callback, const Ipv4Address&, uint16_t> connectionRequest, + Callback, const Ipv4Address&, uint16_t> newConnectionCreated, + Callback > closeRequested) = 0; virtual int DoSend (const uint8_t* buffer, uint32_t size, - Callback dataSent) = 0; + Callback, uint32_t> dataSent) = 0; virtual int DoSendTo(const Ipv4Address &address, uint16_t port, const uint8_t *buffer, uint32_t size, - Callback dataSent) = 0; - virtual void DoRecv(Callback receive) = 0; - virtual void DoRecvDummy(Callback) = 0; + Callback, uint32_t> dataSent) = 0; + virtual void DoRecv(Callback, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0; + virtual void DoRecvDummy(Callback, 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, const Ipv4Address& address, uint16_t port); + static void DummyCallbackVoidSocket (Ptr socket); + static void DummyCallbackVoidSocketUi32 (Ptr socket, uint32_t); + static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr socket, uint32_t, const Ipv4Address &, uint16_t); + static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr socket, const uint8_t *, uint32_t, const Ipv4Address &, uint16_t); - static void DummyCallbackVoidSocketIpv4AddressUi16 (Socket *socket, const Ipv4Address &, uint16_t); + static void DummyCallbackVoidSocketIpv4AddressUi16 (Ptr socket, const Ipv4Address &, uint16_t); }; } //namespace ns3 diff --git a/src/node/wscript b/src/node/wscript index 936c0e09b..c1dc79598 100644 --- a/src/node/wscript +++ b/src/node/wscript @@ -20,6 +20,7 @@ def build(bld): 'socket.cc', 'i-udp.cc', 'i-ipv4.cc', + 'application.cc', ] headers = bld.create_obj('ns3header') @@ -37,4 +38,5 @@ def build(bld): 'socket.h', 'i-udp.h', 'i-ipv4.h', + 'application.h', ]