A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
onoff-application.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 //
3 // Copyright (c) 2006 Georgia Tech Research Corporation
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 //
18 // Author: George F. Riley<riley@ece.gatech.edu>
19 //
20 
21 // ns3 - On/Off Data Source Application class
22 // George F. Riley, Georgia Tech, Spring 2007
23 // Adapted from ApplicationOnOff in GTNetS.
24 
25 #include "ns3/log.h"
26 #include "ns3/address.h"
27 #include "ns3/inet-socket-address.h"
28 #include "ns3/inet6-socket-address.h"
29 #include "ns3/packet-socket-address.h"
30 #include "ns3/node.h"
31 #include "ns3/nstime.h"
32 #include "ns3/data-rate.h"
33 #include "ns3/random-variable-stream.h"
34 #include "ns3/socket.h"
35 #include "ns3/simulator.h"
36 #include "ns3/socket-factory.h"
37 #include "ns3/packet.h"
38 #include "ns3/uinteger.h"
39 #include "ns3/trace-source-accessor.h"
40 #include "onoff-application.h"
41 #include "ns3/udp-socket-factory.h"
42 #include "ns3/string.h"
43 #include "ns3/pointer.h"
44 
45 NS_LOG_COMPONENT_DEFINE ("OnOffApplication");
46 
47 namespace ns3 {
48 
49 NS_OBJECT_ENSURE_REGISTERED (OnOffApplication);
50 
51 TypeId
52 OnOffApplication::GetTypeId (void)
53 {
54  static TypeId tid = TypeId ("ns3::OnOffApplication")
55  .SetParent<Application> ()
56  .AddConstructor<OnOffApplication> ()
57  .AddAttribute ("DataRate", "The data rate in on state.",
58  DataRateValue (DataRate ("500kb/s")),
59  MakeDataRateAccessor (&OnOffApplication::m_cbrRate),
60  MakeDataRateChecker ())
61  .AddAttribute ("PacketSize", "The size of packets sent in on state",
62  UintegerValue (512),
63  MakeUintegerAccessor (&OnOffApplication::m_pktSize),
64  MakeUintegerChecker<uint32_t> (1))
65  .AddAttribute ("Remote", "The address of the destination",
66  AddressValue (),
67  MakeAddressAccessor (&OnOffApplication::m_peer),
68  MakeAddressChecker ())
69  .AddAttribute ("OnTime", "A RandomVariableStream used to pick the duration of the 'On' state.",
70  StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
71  MakePointerAccessor (&OnOffApplication::m_onTime),
72  MakePointerChecker <RandomVariableStream>())
73  .AddAttribute ("OffTime", "A RandomVariableStream used to pick the duration of the 'Off' state.",
74  StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
75  MakePointerAccessor (&OnOffApplication::m_offTime),
76  MakePointerChecker <RandomVariableStream>())
77  .AddAttribute ("MaxBytes",
78  "The total number of bytes to send. Once these bytes are sent, "
79  "no packet is sent again, even in on state. The value zero means "
80  "that there is no limit.",
81  UintegerValue (0),
82  MakeUintegerAccessor (&OnOffApplication::m_maxBytes),
83  MakeUintegerChecker<uint32_t> ())
84  .AddAttribute ("Protocol", "The type of protocol to use.",
85  TypeIdValue (UdpSocketFactory::GetTypeId ()),
86  MakeTypeIdAccessor (&OnOffApplication::m_tid),
87  MakeTypeIdChecker ())
88  .AddTraceSource ("Tx", "A new packet is created and is sent",
89  MakeTraceSourceAccessor (&OnOffApplication::m_txTrace))
90  ;
91  return tid;
92 }
93 
94 
95 OnOffApplication::OnOffApplication ()
96  : m_socket (0),
97  m_connected (false),
98  m_residualBits (0),
99  m_lastStartTime (Seconds (0)),
100  m_totBytes (0)
101 {
102  NS_LOG_FUNCTION (this);
103 }
104 
105 OnOffApplication::~OnOffApplication()
106 {
107  NS_LOG_FUNCTION (this);
108 }
109 
110 void
111 OnOffApplication::SetMaxBytes (uint32_t maxBytes)
112 {
113  NS_LOG_FUNCTION (this << maxBytes);
114  m_maxBytes = maxBytes;
115 }
116 
119 {
120  NS_LOG_FUNCTION (this);
121  return m_socket;
122 }
123 
124 int64_t
126 {
127  NS_LOG_FUNCTION (this << stream);
128  m_onTime->SetStream (stream);
129  m_offTime->SetStream (stream + 1);
130  return 2;
131 }
132 
133 void
135 {
136  NS_LOG_FUNCTION (this);
137 
138  m_socket = 0;
139  // chain up
141 }
142 
143 // Application Methods
144 void OnOffApplication::StartApplication () // Called at time specified by Start
145 {
146  NS_LOG_FUNCTION (this);
147 
148  // Create the socket if not already
149  if (!m_socket)
150  {
151  m_socket = Socket::CreateSocket (GetNode (), m_tid);
153  {
154  m_socket->Bind6 ();
155  }
156  else if (InetSocketAddress::IsMatchingType (m_peer) ||
158  {
159  m_socket->Bind ();
160  }
161  m_socket->Connect (m_peer);
162  m_socket->SetAllowBroadcast (true);
163  m_socket->ShutdownRecv ();
164 
165  m_socket->SetConnectCallback (
166  MakeCallback (&OnOffApplication::ConnectionSucceeded, this),
167  MakeCallback (&OnOffApplication::ConnectionFailed, this));
168  }
169  // Insure no pending event
170  CancelEvents ();
171  // If we are not yet connected, there is nothing to do here
172  // The ConnectionComplete upcall will start timers at that time
173  //if (!m_connected) return;
174  ScheduleStartEvent ();
175 }
176 
177 void OnOffApplication::StopApplication () // Called at time specified by Stop
178 {
179  NS_LOG_FUNCTION (this);
180 
181  CancelEvents ();
182  if(m_socket != 0)
183  {
184  m_socket->Close ();
185  }
186  else
187  {
188  NS_LOG_WARN ("OnOffApplication found null socket to close in StopApplication");
189  }
190 }
191 
192 void OnOffApplication::CancelEvents ()
193 {
194  NS_LOG_FUNCTION (this);
195 
196  if (m_sendEvent.IsRunning ())
197  { // Cancel the pending send packet event
198  // Calculate residual bits since last packet sent
199  Time delta (Simulator::Now () - m_lastStartTime);
200  int64x64_t bits = delta.To (Time::S) * m_cbrRate.GetBitRate ();
201  m_residualBits += bits.GetHigh ();
202  }
203  Simulator::Cancel (m_sendEvent);
204  Simulator::Cancel (m_startStopEvent);
205 }
206 
207 // Event handlers
208 void OnOffApplication::StartSending ()
209 {
210  NS_LOG_FUNCTION (this);
211  m_lastStartTime = Simulator::Now ();
212  ScheduleNextTx (); // Schedule the send packet event
213  ScheduleStopEvent ();
214 }
215 
216 void OnOffApplication::StopSending ()
217 {
218  NS_LOG_FUNCTION (this);
219  CancelEvents ();
220 
221  ScheduleStartEvent ();
222 }
223 
224 // Private helpers
225 void OnOffApplication::ScheduleNextTx ()
226 {
227  NS_LOG_FUNCTION (this);
228 
229  if (m_maxBytes == 0 || m_totBytes < m_maxBytes)
230  {
231  uint32_t bits = m_pktSize * 8 - m_residualBits;
232  NS_LOG_LOGIC ("bits = " << bits);
233  Time nextTime (Seconds (bits /
234  static_cast<double>(m_cbrRate.GetBitRate ()))); // Time till next packet
235  NS_LOG_LOGIC ("nextTime = " << nextTime);
236  m_sendEvent = Simulator::Schedule (nextTime,
237  &OnOffApplication::SendPacket, this);
238  }
239  else
240  { // All done, cancel any pending events
241  StopApplication ();
242  }
243 }
244 
245 void OnOffApplication::ScheduleStartEvent ()
246 { // Schedules the event to start sending data (switch to the "On" state)
247  NS_LOG_FUNCTION (this);
248 
249  Time offInterval = Seconds (m_offTime->GetValue ());
250  NS_LOG_LOGIC ("start at " << offInterval);
251  m_startStopEvent = Simulator::Schedule (offInterval, &OnOffApplication::StartSending, this);
252 }
253 
254 void OnOffApplication::ScheduleStopEvent ()
255 { // Schedules the event to stop sending data (switch to "Off" state)
256  NS_LOG_FUNCTION (this);
257 
258  Time onInterval = Seconds (m_onTime->GetValue ());
259  NS_LOG_LOGIC ("stop at " << onInterval);
260  m_startStopEvent = Simulator::Schedule (onInterval, &OnOffApplication::StopSending, this);
261 }
262 
263 
264 void OnOffApplication::SendPacket ()
265 {
266  NS_LOG_FUNCTION (this);
267 
268  NS_ASSERT (m_sendEvent.IsExpired ());
269  Ptr<Packet> packet = Create<Packet> (m_pktSize);
270  m_txTrace (packet);
271  m_socket->Send (packet);
272  m_totBytes += m_pktSize;
274  {
275  NS_LOG_INFO ("At time " << Simulator::Now ().GetSeconds ()
276  << "s on-off application sent "
277  << packet->GetSize () << " bytes to "
279  << " port " << InetSocketAddress::ConvertFrom (m_peer).GetPort ()
280  << " total Tx " << m_totBytes << " bytes");
281  }
282  else if (Inet6SocketAddress::IsMatchingType (m_peer))
283  {
284  NS_LOG_INFO ("At time " << Simulator::Now ().GetSeconds ()
285  << "s on-off application sent "
286  << packet->GetSize () << " bytes to "
288  << " port " << Inet6SocketAddress::ConvertFrom (m_peer).GetPort ()
289  << " total Tx " << m_totBytes << " bytes");
290  }
291  m_lastStartTime = Simulator::Now ();
292  m_residualBits = 0;
293  ScheduleNextTx ();
294 }
295 
296 
297 void OnOffApplication::ConnectionSucceeded (Ptr<Socket> socket)
298 {
299  NS_LOG_FUNCTION (this << socket);
300  m_connected = true;
301 }
302 
303 void OnOffApplication::ConnectionFailed (Ptr<Socket> socket)
304 {
305  NS_LOG_FUNCTION (this << socket);
306 }
307 
308 
309 } // Namespace ns3
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
keep track of time unit.
Definition: nstime.h:149
Ipv4Address GetIpv4(void) const
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
virtual void StartApplication(void)
Application specific startup code.
virtual int Bind6()=0
Allocate a local IPv6 endpoint for this socket.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
#define NS_ASSERT(condition)
Definition: assert.h:64
static bool IsMatchingType(const Address &address)
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual int ShutdownRecv(void)=0
#define NS_LOG_INFO(msg)
Definition: log.h:264
static void Cancel(const EventId &id)
Definition: simulator.cc:267
bool IsRunning(void) const
Definition: event-id.cc:59
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
virtual double GetValue(void)=0
Returns a random double from the underlying distribution.
virtual void DoDispose(void)
Ptr< Node > GetNode() const
Definition: application.cc:103
Ptr< Socket > GetSocket(void) const
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
int64_t AssignStreams(int64_t stream)
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual void DoDispose(void)
Definition: application.cc:82
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
static InetSocketAddress ConvertFrom(const Address &address)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
uint64_t GetBitRate() const
Definition: data-rate.cc:235
void SetMaxBytes(uint32_t maxBytes)
static Time Now(void)
Definition: simulator.cc:179
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
#define NS_LOG_WARN(msg)
Definition: log.h:246
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
uint16_t GetPort(void) const
Get the port.
uint16_t GetPort(void) const
void SetConnectCallback(Callback< void, Ptr< Socket > > connectionSucceeded, Callback< void, Ptr< Socket > > connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
Definition: socket.cc:83
virtual void StopApplication(void)
Application specific shutdown code.
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual int Close(void)=0
Close a socket.
bool IsExpired(void) const
Definition: event-id.cc:53
static bool IsMatchingType(const Address &address)