From d52242c4ae99813edac714d5cda1b97af45687d5 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 21 Mar 2007 23:17:11 -0700 Subject: [PATCH] OnOffApplication functioning; some Node class cleanup --- SConstruct | 4 ++ examples/simple-serial.cc | 17 ++++++++- src/node/application.cc | 3 +- src/node/application.h | 4 +- src/node/internet-node.cc | 7 ++++ src/node/node-list.cc | 5 ++- src/node/node-list.h | 1 + src/node/node.cc | 28 +++++--------- src/node/node.h | 9 +++-- src/node/onoff-application.cc | 52 ++++++++++++------------- src/node/onoff-application.h | 72 ++++++++--------------------------- 11 files changed, 91 insertions(+), 111 deletions(-) diff --git a/SConstruct b/SConstruct index e938e91c6..dfd93dcd7 100644 --- a/SConstruct +++ b/SConstruct @@ -204,6 +204,7 @@ node.add_sources ([ 'udp.cc', 'arp-header.cc', 'application.cc', + 'onoff-application.cc', 'arp-cache.cc', 'arp-ipv4-interface.cc', 'arp.cc', @@ -223,6 +224,7 @@ node.add_headers ([ 'udp.h', 'ipv4-l4-protocol.h', 'application.h', + 'onoff-application.h', 'arp-header.h', 'arp-cache-cache.h', 'arp.h', @@ -254,6 +256,8 @@ node.add_inst_headers ([ 'udp-header.h', 'channel.h', 'node-list.h', + 'application.h', + 'onoff-application.h', ]) p2p = build.Ns3Module ('p2p', 'src/devices/p2p') diff --git a/examples/simple-serial.cc b/examples/simple-serial.cc index 08d7ec902..e8277a875 100644 --- a/examples/simple-serial.cc +++ b/examples/simple-serial.cc @@ -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 @@ int main (int argc, char *argv[]) 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 @@ int main (int argc, char *argv[]) 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 @@ int main (int argc, char *argv[]) PrintTraffic (sink1); GenerateTraffic (source3, 100); - Simulator::StopAt (Seconds(3.0)); + Simulator::StopAt (Seconds(10.0)); Simulator::Run (); diff --git a/src/node/application.cc b/src/node/application.cc index ffeebcaad..4cdb8d6fa 100644 --- a/src/node/application.cc +++ b/src/node/application.cc @@ -37,9 +37,10 @@ namespace ns3 { // 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) diff --git a/src/node/application.h b/src/node/application.h index 834f0062e..065c898b4 100644 --- a/src/node/application.h +++ b/src/node/application.h @@ -53,12 +53,12 @@ namespace ns3 { class Node; -class NodeReference; class RandomVariable; +class NodeReference; class Application { public: - Application(); + Application(const Node&); Application(const Application&); // Copy constructor Application& operator=(const Application&); // Assignment operator virtual ~Application(); diff --git a/src/node/internet-node.cc b/src/node/internet-node.cc index 3f902768a..1c4d5a645 100644 --- a/src/node/internet-node.cc +++ b/src/node/internet-node.cc @@ -34,6 +34,13 @@ namespace ns3 { +static class NodeStackInitializationClass { +public: + NodeStackInitializationClass () { + Node::PushNodePrototype (InternetNode ()); + } +} node_stack_initialization_class; + InternetNode::InternetNode() { // Instantiate the capabilities diff --git a/src/node/node-list.cc b/src/node/node-list.cc index 6fac78d7e..68f684585 100644 --- a/src/node/node-list.cc +++ b/src/node/node-list.cc @@ -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) diff --git a/src/node/node-list.h b/src/node/node-list.h index c954664da..11f5cbcc5 100644 --- a/src/node/node-list.h +++ b/src/node/node-list.h @@ -47,6 +47,7 @@ public: static Node *GetNode (uint32_t n); private: + static uint32_t g_nextId; // becomes Node::m_id static std::vector *GetNodes (void); static uint32_t GetNNodes (void); diff --git a/src/node/node.cc b/src/node/node.cc index 4dec08f56..6fde6c5c8 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -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 @@ Node::GetId (void) const { return m_id; } + +void +Node::SetId(uint32_t id ) +{ + m_id = id; +} + uint32_t Node::GetSystemId (void) const { @@ -68,11 +71,9 @@ Node::SetSystemId(uint32_t s ) // 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::Create(uint32_t sid) 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(const Node& n) 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 @@ void Node::ClearAll() 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 { diff --git a/src/node/node.h b/src/node/node.h index 20be77afc..f347b5e77 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -103,8 +103,10 @@ class Udp; class Arp; class TraceContext; class TraceResolver; +class NodeList; class Node { +friend class NodeList; public: typedef SmartVector SmartNodeVec_t; Node(); @@ -139,14 +141,16 @@ public: 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 @@ public: 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 }; diff --git a/src/node/onoff-application.cc b/src/node/onoff-application.cc index a8f71db17..a62b9d639 100644 --- a/src/node/onoff-application.cc +++ b/src/node/onoff-application.cc @@ -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 @@ uint32_t OnOffApplication::g_defaultSize = 512; // 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 @@ uint32_t OnOffApplication::g_defaultSize = 512; { } -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(const OnOffApplication& c) OnOffApplication::~OnOffApplication() { - delete m_l4Proto; delete m_socket; - delete m_peerIP; delete m_onTime; delete m_offTime; } @@ -149,29 +142,31 @@ void OnOffApplication::Handle(Event* e, Time_t t) #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 @@ void OnOffApplication::ScheduleNextTx() } else { // All done, cancel any pending events - StopApp(); + StopApplication(); } } @@ -239,24 +234,25 @@ void OnOffApplication::ScheduleStopEvent() 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 diff --git a/src/node/onoff-application.h b/src/node/onoff-application.h index 088fbeb9f..b4a6a942c 100644 --- a/src/node/onoff-application.h +++ b/src/node/onoff-application.h @@ -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 @@ private: 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