00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "ns3/log.h"
00026 #include "ns3/address.h"
00027 #include "ns3/node.h"
00028 #include "ns3/nstime.h"
00029 #include "ns3/data-rate.h"
00030 #include "ns3/random-variable.h"
00031 #include "ns3/socket.h"
00032 #include "ns3/simulator.h"
00033 #include "ns3/socket-factory.h"
00034 #include "ns3/packet.h"
00035 #include "ns3/uinteger.h"
00036 #include "ns3/trace-source-accessor.h"
00037 #include "onoff-application.h"
00038 #include "ns3/udp-socket-factory.h"
00039
00040 NS_LOG_COMPONENT_DEFINE ("OnOffApplication");
00041
00042 using namespace std;
00043
00044 namespace ns3 {
00045
00046 NS_OBJECT_ENSURE_REGISTERED (OnOffApplication);
00047
00048 TypeId
00049 OnOffApplication::GetTypeId (void)
00050 {
00051 static TypeId tid = TypeId ("ns3::OnOffApplication")
00052 .SetParent<Application> ()
00053 .AddConstructor<OnOffApplication> ()
00054 .AddAttribute ("DataRate", "The data rate in on state.",
00055 DataRateValue (DataRate ("500kb/s")),
00056 MakeDataRateAccessor (&OnOffApplication::m_cbrRate),
00057 MakeDataRateChecker ())
00058 .AddAttribute ("PacketSize", "The size of packets sent in on state",
00059 UintegerValue (512),
00060 MakeUintegerAccessor (&OnOffApplication::m_pktSize),
00061 MakeUintegerChecker<uint32_t> (1))
00062 .AddAttribute ("Jitter", "RandomVariable used to add delay jitter (in seconds) to the sending period.",
00063 RandomVariableValue (ConstantVariable (0.0)),
00064 MakeRandomVariableAccessor (&OnOffApplication::m_jitter),
00065 MakeRandomVariableChecker ())
00066 .AddAttribute ("Remote", "The address of the destination",
00067 AddressValue (),
00068 MakeAddressAccessor (&OnOffApplication::m_peer),
00069 MakeAddressChecker ())
00070 .AddAttribute ("OnTime", "A RandomVariable used to pick the duration of the 'On' state.",
00071 RandomVariableValue (ConstantVariable (1.0)),
00072 MakeRandomVariableAccessor (&OnOffApplication::m_onTime),
00073 MakeRandomVariableChecker ())
00074 .AddAttribute ("OffTime", "A RandomVariable used to pick the duration of the 'Off' state.",
00075 RandomVariableValue (ConstantVariable (1.0)),
00076 MakeRandomVariableAccessor (&OnOffApplication::m_offTime),
00077 MakeRandomVariableChecker ())
00078 .AddAttribute ("MaxBytes",
00079 "The total number of bytes to send. Once these bytes are sent, "
00080 "no packet is sent again, even in on state. The value zero means "
00081 "that there is no limit.",
00082 UintegerValue (0),
00083 MakeUintegerAccessor (&OnOffApplication::m_maxBytes),
00084 MakeUintegerChecker<uint32_t> ())
00085 .AddAttribute ("Protocol", "The type of protocol to use.",
00086 TypeIdValue (UdpSocketFactory::GetTypeId ()),
00087 MakeTypeIdAccessor (&OnOffApplication::m_tid),
00088 MakeTypeIdChecker ())
00089 .AddTraceSource ("Tx", "A new packet is created and is sent",
00090 MakeTraceSourceAccessor (&OnOffApplication::m_txTrace))
00091 ;
00092 return tid;
00093 }
00094
00095
00096 OnOffApplication::OnOffApplication ()
00097 {
00098 NS_LOG_FUNCTION_NOARGS ();
00099 m_socket = 0;
00100 m_connected = false;
00101 m_residualBits = 0;
00102 m_lastStartTime = Seconds (0);
00103 m_totBytes = 0;
00104 }
00105
00106 OnOffApplication::~OnOffApplication()
00107 {
00108 NS_LOG_FUNCTION_NOARGS ();
00109 }
00110
00111 void
00112 OnOffApplication::SetMaxBytes(uint32_t maxBytes)
00113 {
00114 NS_LOG_FUNCTION (this << maxBytes);
00115 m_maxBytes = maxBytes;
00116 }
00117
00118
00119 void
00120 OnOffApplication::DoDispose (void)
00121 {
00122 NS_LOG_FUNCTION_NOARGS ();
00123
00124 m_socket = 0;
00125
00126 Application::DoDispose ();
00127 }
00128
00129
00130 void OnOffApplication::StartApplication()
00131 {
00132 NS_LOG_FUNCTION_NOARGS ();
00133
00134
00135 if (!m_socket)
00136 {
00137 m_socket = Socket::CreateSocket (GetNode(), m_tid);
00138 m_socket->Bind ();
00139 m_socket->Connect (m_peer);
00140 }
00141
00142 CancelEvents ();
00143
00144
00145
00146 ScheduleStartEvent();
00147 }
00148
00149 void OnOffApplication::StopApplication()
00150 {
00151 NS_LOG_FUNCTION_NOARGS ();
00152
00153 CancelEvents ();
00154 if(m_socket != 0)
00155 {
00156 m_socket->Close ();
00157 }
00158 else
00159 {
00160 NS_LOG_WARN("OnOffApplication found null socket to close in StopApplication");
00161 }
00162 }
00163
00164 void OnOffApplication::CancelEvents ()
00165 {
00166 NS_LOG_FUNCTION_NOARGS ();
00167
00168 if (m_sendEvent.IsRunning ())
00169 {
00170
00171 Time delta(Simulator::Now() - m_lastStartTime);
00172 Scalar bits = delta * Scalar (m_cbrRate.GetBitRate ()) / Seconds (1.0);
00173 m_residualBits += (uint32_t)bits.GetDouble ();
00174 }
00175 Simulator::Cancel(m_sendEvent);
00176 Simulator::Cancel(m_startStopEvent);
00177 }
00178
00179
00180 void OnOffApplication::StartSending()
00181 {
00182 NS_LOG_FUNCTION_NOARGS ();
00183
00184 ScheduleNextTx();
00185 ScheduleStopEvent();
00186 }
00187
00188 void OnOffApplication::StopSending()
00189 {
00190 NS_LOG_FUNCTION_NOARGS ();
00191 CancelEvents();
00192
00193 ScheduleStartEvent();
00194 }
00195
00196
00197 void OnOffApplication::ScheduleNextTx()
00198 {
00199 NS_LOG_FUNCTION_NOARGS ();
00200
00201 if (m_maxBytes == 0 || m_totBytes < m_maxBytes)
00202 {
00203 uint32_t bits = m_pktSize * 8 - m_residualBits;
00204 NS_LOG_LOGIC ("bits = " << bits);
00205
00206
00207 Time nextTime = Seconds (bits / static_cast<double>(m_cbrRate.GetBitRate()));
00208 nextTime += Seconds( m_jitter.GetValue() );
00209 if (!nextTime.IsPositive()) nextTime = Seconds(0);
00210 NS_LOG_LOGIC ("nextTime = " << nextTime);
00211
00212 m_sendEvent = Simulator::Schedule(nextTime,
00213 &OnOffApplication::SendPacket, this);
00214 }
00215 else
00216 {
00217 StopApplication();
00218 }
00219 }
00220
00221 void OnOffApplication::ScheduleStartEvent()
00222 {
00223 NS_LOG_FUNCTION_NOARGS ();
00224
00225 Time offInterval = Seconds(m_offTime.GetValue());
00226 NS_LOG_LOGIC ("start at " << offInterval);
00227 m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this);
00228 }
00229
00230 void OnOffApplication::ScheduleStopEvent()
00231 {
00232 NS_LOG_FUNCTION_NOARGS ();
00233
00234 Time onInterval = Seconds(m_onTime.GetValue());
00235 NS_LOG_LOGIC ("stop at " << onInterval);
00236 m_startStopEvent = Simulator::Schedule(onInterval, &OnOffApplication::StopSending, this);
00237 }
00238
00239
00240 void OnOffApplication::SendPacket()
00241 {
00242 NS_LOG_FUNCTION_NOARGS ();
00243 NS_LOG_LOGIC ("sending packet at " << Simulator::Now());
00244 NS_ASSERT (m_sendEvent.IsExpired ());
00245 Ptr<Packet> packet = Create<Packet> (m_pktSize);
00246 m_txTrace (packet);
00247 m_socket->Send (packet);
00248 m_totBytes += m_pktSize;
00249 m_lastStartTime = Simulator::Now();
00250 m_residualBits = 0;
00251 ScheduleNextTx();
00252 }
00253
00254 void OnOffApplication::ConnectionSucceeded(Ptr<Socket>)
00255 {
00256 NS_LOG_FUNCTION_NOARGS ();
00257
00258 m_connected = true;
00259 ScheduleStartEvent();
00260 }
00261
00262 void OnOffApplication::ConnectionFailed(Ptr<Socket>)
00263 {
00264 NS_LOG_FUNCTION_NOARGS ();
00265 cout << "OnOffApplication, Connection Failed" << endl;
00266 }
00267
00268 }