OnOffApplication functioning; some Node class cleanup
authorTom Henderson <tomh@tomh.org>
Wed, 21 Mar 2007 23:17:11 -0700
changeset 359 91b7ad7fa784
parent 358 cefde4f0d6b2
child 360 7bffd987426c
OnOffApplication functioning; some Node class cleanup
SConstruct
examples/simple-serial.cc
src/node/application.cc
src/node/application.h
src/node/internet-node.cc
src/node/node-list.cc
src/node/node-list.h
src/node/node.cc
src/node/node.h
src/node/onoff-application.cc
src/node/onoff-application.h
--- a/SConstruct	Tue Mar 20 06:28:24 2007 -0700
+++ b/SConstruct	Wed Mar 21 23:17:11 2007 -0700
@@ -204,6 +204,7 @@
     'udp.cc',
     'arp-header.cc',
     'application.cc',
+    'onoff-application.cc',
     'arp-cache.cc',
     'arp-ipv4-interface.cc',
     'arp.cc',
@@ -223,6 +224,7 @@
     'udp.h',
     'ipv4-l4-protocol.h',
     'application.h',
+    'onoff-application.h',
     'arp-header.h',
     'arp-cache-cache.h',
     'arp.h',
@@ -254,6 +256,8 @@
     'udp-header.h',
     'channel.h',
     'node-list.h',
+    'application.h',
+    'onoff-application.h',
     ])
 
 p2p = build.Ns3Module ('p2p', 'src/devices/p2p')
--- a/examples/simple-serial.cc	Tue Mar 20 06:28:24 2007 -0700
+++ b/examples/simple-serial.cc	Wed Mar 21 23:17:11 2007 -0700
@@ -66,6 +66,8 @@
 #include "ns3/trace-root.h"
 #include "ns3/object-container.h"
 #include "ns3/serial-topology.h"
+#include "ns3/onoff-application.h"
+#include "ns3/random-variable.h"
 
 using namespace ns3;
 
@@ -242,6 +244,10 @@
       n3, Ipv4Address("10.1.3.2"), 
       1500000, MilliSeconds(10));
   
+  // To Do:
+  // avoid "new" calls, instead use application list
+  // OnOffSink
+  // use of rate and time objects
   DatagramSocket *source0 = new DatagramSocket (n0);
   DatagramSocket *source3 = new DatagramSocket (n3);
   DatagramSocket *sink3 = new DatagramSocket(n3);
@@ -249,6 +255,15 @@
   DatagramSocket *sink1 = new DatagramSocket(n1);
   sink1->Bind (80);
 
+#ifdef NOTYET
+  // This is functional and could soon replace the above DatagramSockets,
+  // but needs tuning
+  OnOffApplication* ooff = new OnOffApplication(*n0, Ipv4Address("10.1.2.2"), 
+  80, ConstantVariable(1), ConstantVariable(0), 1000, 210);
+  container.Acquire (ooff);
+  ooff->Start(Seconds(1.0));
+#endif
+
   container.Acquire (source0);
   container.Acquire (source3);
   container.Acquire (sink3);
@@ -271,7 +286,7 @@
   PrintTraffic (sink1);
   GenerateTraffic (source3, 100);
 
-  Simulator::StopAt (Seconds(3.0));
+  Simulator::StopAt (Seconds(10.0));
 
   Simulator::Run ();
     
--- a/src/node/application.cc	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/application.cc	Wed Mar 21 23:17:11 2007 -0700
@@ -37,9 +37,10 @@
 // Application Methods
 
 // \brief Application Constructor
-  Application::Application() : m_node(nil), m_startVar(nil), m_stopVar(nil),
+  Application::Application(const Node& n) : m_startVar(nil), m_stopVar(nil),
                                m_start(false), m_stop(false)
 {
+  SetNode(n);
 }
 
 Application::Application(const Application& o)
--- a/src/node/application.h	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/application.h	Wed Mar 21 23:17:11 2007 -0700
@@ -53,12 +53,12 @@
 namespace ns3 {
 
 class Node;
+class RandomVariable;
 class NodeReference;
-class RandomVariable;
   
 class Application {
 public:
-  Application();
+  Application(const Node&);
   Application(const Application&);  // Copy constructor
   Application& operator=(const Application&); // Assignment operator
   virtual ~Application();
--- a/src/node/internet-node.cc	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/internet-node.cc	Wed Mar 21 23:17:11 2007 -0700
@@ -34,6 +34,13 @@
 
 namespace ns3 {
 
+static class NodeStackInitializationClass {
+public:
+  NodeStackInitializationClass () {
+    Node::PushNodePrototype (InternetNode ());
+  }
+} node_stack_initialization_class;
+
 InternetNode::InternetNode()
 {
   // Instantiate the capabilities
--- a/src/node/node-list.cc	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/node-list.cc	Wed Mar 21 23:17:11 2007 -0700
@@ -27,10 +27,13 @@
 
 namespace ns3 {
 
-void 
+uint32_t NodeList::g_nextId = 0;
+
+void
 NodeList::Add (Node *node)
 {
   GetNodes ()->push_back (node);
+  node->SetId(g_nextId++);
 }
 NodeList::Iterator 
 NodeList::Begin (void)
--- a/src/node/node-list.h	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/node-list.h	Wed Mar 21 23:17:11 2007 -0700
@@ -47,6 +47,7 @@
   static Node *GetNode (uint32_t n);
 
 private:
+  static uint32_t g_nextId;	// becomes Node::m_id
   static std::vector<Node *> *GetNodes (void);
   static uint32_t GetNNodes (void);
   
--- a/src/node/node.cc	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/node.cc	Wed Mar 21 23:17:11 2007 -0700
@@ -23,25 +23,21 @@
 // George F. Riley, Georgia Tech, Fall 2006
 
 #include "node.h"
-#include "internet-node.h"
 #include "node-list.h"
 
 namespace ns3{
 
-uint32_t Node::g_nextId = 0;
 Node::SmartNodeVec_t Node::g_prototypes;  // The node prototypes stack
 Node::SmartNodeVec_t Node::g_nodes;       // All nodes
 
 Node::Node()
-  : m_id(g_nextId), m_sid(0)
+  : m_id(0), m_sid(0)
 {
-  g_nextId++;
 }
 
 Node::Node(uint32_t sid)
-  : m_id(g_nextId), m_sid(sid)
+  : m_id(0), m_sid(sid)
 { 
-  g_nextId++;
 }
   
 Node::~Node ()
@@ -53,6 +49,13 @@
 {
   return m_id;
 }
+
+void   
+Node::SetId(uint32_t id )
+{
+  m_id = id;
+}
+
 uint32_t 
 Node::GetSystemId (void) const
 {
@@ -68,11 +71,9 @@
 // Node stack creation and management routines.
 Node* Node::Create()
 {
-  if (g_prototypes.Empty()) CreateDefaultPrototype();
   Node* n = g_prototypes.Back()->Copy(); // Copy the top of the stack
-  n->m_id = g_nextId++;                  // Set unique node id
   g_nodes.Add(n);                        // Add to smart vector (mem mgmt)
-  NodeList::Add (n);                     // Add to global list of nodes
+  NodeList::Add (n);           // Add to global list of nodes
   return n;
 }
 
@@ -86,7 +87,6 @@
 
 Node* Node::GetNodePrototype()
 { // Get node* to top of prototypes stack
-  if (g_prototypes.Empty()) CreateDefaultPrototype();
   return g_prototypes.Back();
 }
 
@@ -98,7 +98,6 @@
 
 Node* Node::PushNodePrototype() 
 { // Replicate the top of the prototype stack
-  if (g_prototypes.Empty()) CreateDefaultPrototype();
   g_prototypes.Add(GetNodePrototype()->Copy());
   return g_prototypes.Back();
 }
@@ -114,13 +113,6 @@
   g_prototypes.Clear();
 }
 
-// Private method to ceate a reasonable default if stack is empty
-void Node::CreateDefaultPrototype()
-{
-  Node* n = new InternetNode();
-  g_prototypes.Add(n);
-}
-
 L3Demux*
 Node::GetL3Demux() const
 {
--- a/src/node/node.h	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/node.h	Wed Mar 21 23:17:11 2007 -0700
@@ -103,8 +103,10 @@
 class Arp;
 class TraceContext;
 class TraceResolver;
+class NodeList;
 
 class Node {
+friend class NodeList;
 public:
   typedef SmartVector<Node*> SmartNodeVec_t;
   Node();
@@ -139,14 +141,16 @@
   static const SmartNodeVec_t& Nodes(); // Get a vector of all nodes
   static void  ClearAll();          // Delete all nodes for memory leak checking
   static void  ClearAllPrototypes();// Delete the prototype stack
-private: 
-  static void  CreateDefaultPrototype(); // Create a "typical" prototype node
+
   // Global static variables
 private: 
   static uint32_t       g_nextId;     // Next available ID
   static SmartNodeVec_t g_nodes;      // Vector of all nodes created
   static SmartNodeVec_t g_prototypes; // Node prototype stack
 
+protected:
+  void SetId(uint32_t);            // NodeList::Add() calls this
+
 public:
   // Virtual "Getters" for each capability.
   // These exist to allow owners of a generic Node pointer to get
@@ -163,7 +167,6 @@
   virtual Arp *            GetArp (void) const;
   
 private:
-  static uint32_t m_nodeId;
   uint32_t    m_id;         // Node id for this node
   uint32_t    m_sid;        // System id for this node
 };
--- a/src/node/onoff-application.cc	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/onoff-application.cc	Wed Mar 21 23:17:11 2007 -0700
@@ -22,24 +22,19 @@
 // George F. Riley, Georgia Tech, Spring 2007
 // Adapted from ApplicationOnOff in GTNetS.
 
-#include "ipaddr.h"
-#include "l4protocol.h"
+#include "ipv4-address.h"
 #include "node.h"
 #include "node-reference.h"
 #include "ns3/nstime.h"
 #include "onoff-application.h"
 #include "ns3/random-variable.h"
-#include "socket.h"
-#include "udp.h"
-//#include "tcp.h"
+#include "datagram-socket.h"
 #include "ns3/simulator.h"
 
 using namespace std;
 
 namespace ns3 {
 
-#if 0
-  
 // Defaults for rate/size
 double   OnOffApplication::g_defaultRate = 500000.0;
 uint32_t OnOffApplication::g_defaultSize = 512;
@@ -48,16 +43,16 @@
 
 // Constructors
 
-  OnOffApplication::OnOffApplication(const IPAddr&  rip,   // Remote IP addr
-                                     PortId_t       rport, // Remote port
+  OnOffApplication::OnOffApplication(const Node& n, 
+                                     const Ipv4Address  rip,   // Remote IP addr
+                                     uint16_t       rport, // Remote port
                                      const  RandomVariable& ontime,
                                      const  RandomVariable& offtime,
                                      double   rate,
-                                     uint32_t size,
-                                     const  L4Protocol& l4p)
-    : m_l4Proto(l4p.Copy()),
+                                     uint32_t size)
+    :  Application(n), 
       m_socket(nil),      // Socket allocated on Start
-      m_peerIP(rip.Copy()),
+      m_peerIP(rip),
       m_peerPort(rport),
       m_connected(false),
       m_onTime(ontime.Copy()),
@@ -73,10 +68,10 @@
 {
 }
 
-OnOffApplication::OnOffApplication(const OnOffApplication& c)
-  : m_l4Proto(c.m_l4Proto->Copy()),
+OnOffApplication::OnOffApplication(const Node& n, const OnOffApplication& c)
+  : Application(n), 
     m_socket(nil),
-    m_peerIP(c.m_peerIP->Copy()),
+    m_peerIP(c.m_peerIP),
     m_peerPort(c.m_peerPort),
     m_connected(c.m_connected),
     m_onTime(c.m_onTime->Copy()),
@@ -94,9 +89,7 @@
 
 OnOffApplication::~OnOffApplication()
 {
-  delete m_l4Proto;
   delete m_socket;
-  delete m_peerIP;
   delete m_onTime;
   delete m_offTime;
 }
@@ -149,29 +142,31 @@
 #endif
 
 // Application Methods
-void OnOffApplication::StartApp()    // Called at time specified by Start
+void OnOffApplication::StartApplication()    // Called at time specified by Start
 {
   // Create the socket if not already
   if (!m_socket)
     { // Create the socket using the specified layer 4 protocol
 #ifdef NOTYET
       m_socket = GetNode()->GetKernel()->CreateGenericSocket(*m_l4Proto);
-#endif
       m_socket->Bind();  // Choose any available port local port
       m_socket->Connect(*m_peerIP, m_peerPort,
                         MakeCallback(&OnOffApplication::ConnectionSucceeded,
                                      this),
                         MakeCallback(&OnOffApplication::ConnectionFailed,
                                      this));
+#endif
+      m_socket = new DatagramSocket (GetNode());
+      m_socket->SetDefaultDestination(m_peerIP, m_peerPort);
     }
-  StopApp();                         // Insure no pending event
+  StopApplication();                         // Insure no pending event
   // If we are not yet connected, there is nothing to do here
   // The ConnectionComplete upcall will start timers at that time
-  if (!m_connected) return;
+  //if (!m_connected) return;
   ScheduleStartEvent();
 }
 
-void OnOffApplication::StopApp()     // Called at time specified by Stop
+void OnOffApplication::StopApplication()     // Called at time specified by Stop
 {
   if (m_startStopScheduled)
     { // Cancel the startStop event
@@ -217,7 +212,7 @@
     }
   else
     { // All done, cancel any pending events
-      StopApp();
+      StopApplication();
     }
 }
 
@@ -239,24 +234,25 @@
 void OnOffApplication::SendPacket()
 {
   m_sendScheduled = false;
+  m_socket->SendDummy(m_pktSize);
+#ifdef NOTYET
   m_socket->Send(0, m_pktSize); // Send the packet
+#endif
   m_totBytes += m_pktSize;
   m_lastStartTime = Simulator::Now();
   m_residualBits = 0;
   ScheduleNextTx();
 }
 
-void OnOffApplication::ConnectionSucceeded(Socket*)
+void OnOffApplication::ConnectionSucceeded(DatagramSocket*)
 {
   m_connected = true;
   ScheduleStartEvent();
 }
   
-void OnOffApplication::ConnectionFailed(Socket*)
+void OnOffApplication::ConnectionFailed(DatagramSocket*)
 {
   cout << "OnOffApplication, Connection Failed" << endl;
 }
 
-#endif
-
 } // Namespace ns3
--- a/src/node/onoff-application.h	Tue Mar 20 06:28:24 2007 -0700
+++ b/src/node/onoff-application.h	Wed Mar 21 23:17:11 2007 -0700
@@ -28,89 +28,49 @@
 #define __onoff_application_h__
 
 #include "application.h"
-#include "udp.h"
 #include "ns3/event-id.h"
 
 #define nil 0
 
 namespace ns3 {
 
-class IPAddr;
-class L4Protocol;
+class Ipv4Address;
 class RandomVariable;
-class Socket;
+class DatagramSocket;
 
-#if 0
-class Time;
-
-//Doc:ClassXRef
 class OnOffApplication : public Application {
-  //Doc:Class Defines an application that uses the on--off data generator
-  //Doc:Class model.
 
 public:
-  // Define a number of constructors for different needs
-  // Endpoints, on/off rng, l4 protocol
-  //Doc:Method
-  OnOffApplication(const IPAddr&,    // Peer IP Address
-                   PortId_t,         // Peer port
+  OnOffApplication(const Node& n,
+                   const Ipv4Address,  // Peer IP address
+                   uint16_t,           // Peer port
                    const RandomVariable&,     // Random variable for On time
                    const RandomVariable&,     // Random variable for Off time
                    double   = g_defaultRate,  // Data rate when on
-                   uint32_t = g_defaultSize,  // Size of packets
-                   const L4Protocol& = Udp(nil));// Layer 4 protocol to use
-    //Doc:Desc Constructor specifying destination IP/Port, a single random
-    //Doc:Desc number generator for both the {\em On} and {\em Off}
-    //Doc:Desc distributions, and a layer 4 protocol object.  Optionally
-    //Doc:Desc specifies bit rate (when {\em On} (defaults to a globally
-    //Doc:Desc specified default rate), and optionally a packet size
-    //Doc:Desc (defaults to a globally specified default size).  See
-    //Doc:Desc {\tt SetDefaultRate} and {\tt SetDefaultSize} below.
-    //Doc:Arg1 IPAddress of remote  endpoint (destination)
-    //Doc:Arg2 Port number for remote endpoing (destination)
-    //Doc:Arg3 Random number generator to use for {\em On} time period.
-    //Doc:Arg4 Random number generator to use for both {\em Off} time period.
-    //Doc:Arg5 Data rate to generate when {\em On}.
-    //Doc:Arg6 Packet size.
-    //Doc:Arg7 A layer 4 protocol object to copy.
+                   uint32_t = g_defaultSize);  // Size of packets
 
-  OnOffApplication(const OnOffApplication&); // Copy constructor
+  OnOffApplication(const Node& n, const OnOffApplication&); // Copy constructor
   virtual ~OnOffApplication();               // Destructor
-  virtual void StartApp();    // Called at time specified by Start
-  virtual void StopApp();     // Called at time specified by Stop
+  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
-  virtual L4Protocol* GetL4() const { return m_l4Proto;}
 
   // Event handlers
   void StartSending();
   void StopSending();
   void SendPacket();
 
-  //Doc:Method
   virtual void MaxBytes(uint32_t m) { m_maxBytes = m;}
-    //Doc:Desc Specify a maximum number of bytes to send, after which the
-    //Doc:Desc application shuts down.
-    //Doc:Arg1 Maximum number of bytes to send.
 
 public: // Static methods
-  //Doc:Method
   static void DefaultRate(double r) { g_defaultRate = r;}
-    //Doc:Desc Specify a default data rate to use for all On/Off applications
-    //Doc:Desc by default
-    //Doc:Arg1 The default data rate (when the application is {\em On}.
 
-  //Doc:Method
   static void DefaultSize(uint32_t s) { g_defaultSize = s;}
-    //Doc:Desc Specifies a default packet size to use for all
-    //Doc:Desc On/Off applcations
-    //Doc:Desc by default.
-    //Doc:Arg1 The default packet size.
 
 public:
-  L4Protocol*     m_l4Proto;      // Points to the specified Layer 4 protocol
-  Socket*         m_socket;       // Associated socket
-  IPAddr*         m_peerIP;       // PeerIP
-  PortId_t        m_peerPort;     // Peer port
+  DatagramSocket*         m_socket;       // Associated socket
+  Ipv4Address     m_peerIP;       // Peer IP address
+  uint16_t        m_peerPort;     // Peer port
   bool            m_connected;    // True if connected
   RandomVariable* m_onTime;       // rng for On Time
   RandomVariable* m_offTime;      // rng for Off Time
@@ -134,14 +94,12 @@
   void ScheduleNextTx();
   void ScheduleStartEvent();
   void ScheduleStopEvent();
-  void ConnectionSucceeded(Socket*);
-  void ConnectionFailed(Socket*);
-  void Ignore(Socket*);
+  void ConnectionSucceeded(DatagramSocket*);
+  void ConnectionFailed(DatagramSocket*);
+  void Ignore(DatagramSocket*);
 protected:
 };
 
-#endif
-
 } // namespace ns3
 
 #endif