OLD | NEW |
(Empty) | |
| 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 //Modified by: NIST |
| 25 |
| 26 #include "ns3/log.h" |
| 27 #include "ns3/address.h" |
| 28 #include "ns3/inet-socket-address.h" |
| 29 #include "ns3/inet6-socket-address.h" |
| 30 #include "ns3/packet-socket-address.h" |
| 31 #include "ns3/node.h" |
| 32 #include "ns3/nstime.h" |
| 33 #include "ns3/data-rate.h" |
| 34 #include "ns3/random-variable-stream.h" |
| 35 #include "ns3/socket.h" |
| 36 #include "ns3/simulator.h" |
| 37 #include "ns3/socket-factory.h" |
| 38 #include "ns3/packet.h" |
| 39 #include "ns3/uinteger.h" |
| 40 #include "ns3/trace-source-accessor.h" |
| 41 #include "nist-onoff-application.h" |
| 42 #include "ns3/udp-socket-factory.h" |
| 43 #include "ns3/string.h" |
| 44 #include "ns3/pointer.h" |
| 45 |
| 46 namespace ns3 { |
| 47 |
| 48 NS_LOG_COMPONENT_DEFINE ("NistOnOffApplication"); |
| 49 |
| 50 NS_OBJECT_ENSURE_REGISTERED (NistOnOffApplication); |
| 51 |
| 52 TypeId |
| 53 NistOnOffApplication::GetTypeId (void) |
| 54 { |
| 55 static TypeId tid = TypeId ("ns3::NistOnOffApplication") |
| 56 .SetParent<Application> () |
| 57 .AddConstructor<NistOnOffApplication> () |
| 58 .AddAttribute ("DataRate", "The data rate in on state.", |
| 59 DataRateValue (DataRate ("500kb/s")), |
| 60 MakeDataRateAccessor (&NistOnOffApplication::m_cbrRate), |
| 61 MakeDataRateChecker ()) |
| 62 .AddAttribute ("PacketSize", "The size of packets sent in on state", |
| 63 UintegerValue (512), |
| 64 MakeUintegerAccessor (&NistOnOffApplication::m_pktSize), |
| 65 MakeUintegerChecker<uint32_t> (1)) |
| 66 .AddAttribute ("Remote", "The address of the destination", |
| 67 AddressValue (), |
| 68 MakeAddressAccessor (&NistOnOffApplication::m_peer), |
| 69 MakeAddressChecker ()) |
| 70 .AddAttribute ("OnTime", "A RandomVariableStream used to pick the duration o
f the 'On' state.", |
| 71 StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"), |
| 72 MakePointerAccessor (&NistOnOffApplication::m_onTime), |
| 73 MakePointerChecker <RandomVariableStream>()) |
| 74 .AddAttribute ("OffTime", "A RandomVariableStream used to pick the duration
of the 'Off' state.", |
| 75 StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"), |
| 76 MakePointerAccessor (&NistOnOffApplication::m_offTime), |
| 77 MakePointerChecker <RandomVariableStream>()) |
| 78 .AddAttribute ("MaxBytes",· |
| 79 "The total number of bytes to send. Once these bytes are sent
, " |
| 80 "no packet is sent again, even in on state. The value zero me
ans " |
| 81 "that there is no limit.", |
| 82 UintegerValue (0), |
| 83 MakeUintegerAccessor (&NistOnOffApplication::m_maxBytes), |
| 84 MakeUintegerChecker<uint32_t> ()) |
| 85 .AddAttribute ("Protocol", "The type of protocol to use.", |
| 86 TypeIdValue (UdpSocketFactory::GetTypeId ()), |
| 87 MakeTypeIdAccessor (&NistOnOffApplication::m_tid), |
| 88 MakeTypeIdChecker ()) |
| 89 .AddTraceSource ("Tx", "A new packet is created and is sent", |
| 90 MakeTraceSourceAccessor (&NistOnOffApplication::m_txTrace), |
| 91 "ns3::Packet::TracedCallback") |
| 92 .AddTraceSource ("TxWithAddresses", "A new packet is created and is sent", |
| 93 MakeTraceSourceAccessor (&NistOnOffApplication::m_txTraceWi
thAddresses), |
| 94 "ns3::NistOnOffApplication::PacketAddressTracedCallback") |
| 95 ; |
| 96 return tid; |
| 97 } |
| 98 |
| 99 |
| 100 NistOnOffApplication::NistOnOffApplication () |
| 101 : m_socket (0), |
| 102 m_connected (false), |
| 103 m_residualBits (0), |
| 104 m_lastStartTime (Seconds (0)), |
| 105 m_totBytes (0) |
| 106 { |
| 107 NS_LOG_FUNCTION (this); |
| 108 } |
| 109 |
| 110 NistOnOffApplication::~NistOnOffApplication() |
| 111 { |
| 112 NS_LOG_FUNCTION (this); |
| 113 } |
| 114 |
| 115 void· |
| 116 NistOnOffApplication::SetMaxBytes (uint32_t maxBytes) |
| 117 { |
| 118 NS_LOG_FUNCTION (this << maxBytes); |
| 119 m_maxBytes = maxBytes; |
| 120 } |
| 121 |
| 122 Ptr<Socket> |
| 123 NistOnOffApplication::GetSocket (void) const |
| 124 { |
| 125 NS_LOG_FUNCTION (this); |
| 126 return m_socket; |
| 127 } |
| 128 |
| 129 int64_t· |
| 130 NistOnOffApplication::AssignStreams (int64_t stream) |
| 131 { |
| 132 NS_LOG_FUNCTION (this << stream); |
| 133 m_onTime->SetStream (stream); |
| 134 m_offTime->SetStream (stream + 1); |
| 135 return 2; |
| 136 } |
| 137 |
| 138 void |
| 139 NistOnOffApplication::DoDispose (void) |
| 140 { |
| 141 NS_LOG_FUNCTION (this); |
| 142 |
| 143 m_socket = 0; |
| 144 // chain up |
| 145 Application::DoDispose (); |
| 146 } |
| 147 |
| 148 // Application Methods |
| 149 void NistOnOffApplication::StartApplication () // Called at time specified by St
art |
| 150 { |
| 151 NS_LOG_FUNCTION (this); |
| 152 |
| 153 // Create the socket if not already |
| 154 if (!m_socket) |
| 155 { |
| 156 m_socket = Socket::CreateSocket (GetNode (), m_tid); |
| 157 if (Inet6SocketAddress::IsMatchingType (m_peer)) |
| 158 { |
| 159 m_socket->Bind6 (); |
| 160 } |
| 161 else if (InetSocketAddress::IsMatchingType (m_peer) || |
| 162 PacketSocketAddress::IsMatchingType (m_peer)) |
| 163 { |
| 164 m_socket->Bind (); |
| 165 } |
| 166 m_socket->Connect (m_peer); |
| 167 m_socket->SetAllowBroadcast (true); |
| 168 m_socket->ShutdownRecv (); |
| 169 |
| 170 m_socket->SetConnectCallback ( |
| 171 MakeCallback (&NistOnOffApplication::ConnectionSucceeded, this), |
| 172 MakeCallback (&NistOnOffApplication::ConnectionFailed, this)); |
| 173 } |
| 174 m_cbrRateFailSafe = m_cbrRate; |
| 175 |
| 176 // Insure no pending event |
| 177 CancelEvents (); |
| 178 // If we are not yet connected, there is nothing to do here |
| 179 // The ConnectionComplete upcall will start timers at that time |
| 180 //if (!m_connected) return; |
| 181 ScheduleStartEvent (); |
| 182 } |
| 183 |
| 184 void NistOnOffApplication::StopApplication () // Called at time specified by Sto
p |
| 185 { |
| 186 NS_LOG_FUNCTION (this); |
| 187 |
| 188 CancelEvents (); |
| 189 if(m_socket != 0) |
| 190 { |
| 191 m_socket->Close (); |
| 192 } |
| 193 else |
| 194 { |
| 195 NS_LOG_WARN ("NistOnOffApplication found null socket to close in StopAppli
cation"); |
| 196 } |
| 197 } |
| 198 |
| 199 void NistOnOffApplication::CancelEvents () |
| 200 { |
| 201 NS_LOG_FUNCTION (this); |
| 202 |
| 203 if (m_sendEvent.IsRunning () && m_cbrRateFailSafe == m_cbrRate ) |
| 204 { // Cancel the pending send packet event |
| 205 // Calculate residual bits since last packet sent |
| 206 Time delta (Simulator::Now () - m_lastStartTime); |
| 207 int64x64_t bits = delta.To (Time::S) * m_cbrRate.GetBitRate (); |
| 208 m_residualBits += bits.GetHigh (); |
| 209 } |
| 210 m_cbrRateFailSafe = m_cbrRate; |
| 211 Simulator::Cancel (m_sendEvent); |
| 212 Simulator::Cancel (m_startStopEvent); |
| 213 } |
| 214 |
| 215 // Event handlers |
| 216 void NistOnOffApplication::StartSending () |
| 217 { |
| 218 NS_LOG_FUNCTION (this); |
| 219 m_lastStartTime = Simulator::Now (); |
| 220 ScheduleNextTx (); // Schedule the send packet event |
| 221 ScheduleStopEvent (); |
| 222 } |
| 223 |
| 224 void NistOnOffApplication::StopSending () |
| 225 { |
| 226 NS_LOG_FUNCTION (this); |
| 227 CancelEvents (); |
| 228 |
| 229 ScheduleStartEvent (); |
| 230 } |
| 231 |
| 232 // Private helpers |
| 233 void NistOnOffApplication::ScheduleNextTx () |
| 234 { |
| 235 NS_LOG_FUNCTION (this); |
| 236 |
| 237 if (m_maxBytes == 0 || m_totBytes < m_maxBytes) |
| 238 { |
| 239 uint32_t bits = m_pktSize * 8 - m_residualBits; |
| 240 NS_LOG_LOGIC ("bits = " << bits); |
| 241 Time nextTime (Seconds (bits / |
| 242 static_cast<double>(m_cbrRate.GetBitRate ()))); //
Time till next packet |
| 243 NS_LOG_LOGIC ("nextTime = " << nextTime); |
| 244 m_sendEvent = Simulator::Schedule (nextTime, |
| 245 &NistOnOffApplication::SendPacket, this
); |
| 246 } |
| 247 else |
| 248 { // All done, cancel any pending events |
| 249 StopApplication (); |
| 250 } |
| 251 } |
| 252 |
| 253 void NistOnOffApplication::ScheduleStartEvent () |
| 254 { // Schedules the event to start sending data (switch to the "On" state) |
| 255 NS_LOG_FUNCTION (this); |
| 256 |
| 257 Time offInterval = Seconds (m_offTime->GetValue ()); |
| 258 NS_LOG_LOGIC ("start at " << offInterval); |
| 259 m_startStopEvent = Simulator::Schedule (offInterval, &NistOnOffApplication::St
artSending, this); |
| 260 } |
| 261 |
| 262 void NistOnOffApplication::ScheduleStopEvent () |
| 263 { // Schedules the event to stop sending data (switch to "Off" state) |
| 264 NS_LOG_FUNCTION (this); |
| 265 |
| 266 Time onInterval = Seconds (m_onTime->GetValue ()); |
| 267 NS_LOG_LOGIC ("stop at " << onInterval); |
| 268 m_startStopEvent = Simulator::Schedule (onInterval, &NistOnOffApplication::Sto
pSending, this); |
| 269 } |
| 270 |
| 271 |
| 272 void NistOnOffApplication::SendPacket () |
| 273 { |
| 274 NS_LOG_FUNCTION (this); |
| 275 |
| 276 NS_ASSERT (m_sendEvent.IsExpired ()); |
| 277 Ptr<Packet> packet = Create<Packet> (m_pktSize); |
| 278 m_txTrace (packet); |
| 279 m_socket->Send (packet); |
| 280 m_totBytes += m_pktSize; |
| 281 Address localAddress; |
| 282 m_socket->GetSockName (localAddress); |
| 283 if (InetSocketAddress::IsMatchingType (m_peer)) |
| 284 { |
| 285 NS_LOG_INFO ("At time " << Simulator::Now ().GetSeconds () |
| 286 << "s on-off application sent " |
| 287 << packet->GetSize () << " bytes to " |
| 288 << InetSocketAddress::ConvertFrom(m_peer).GetIpv4 () |
| 289 << " port " << InetSocketAddress::ConvertFrom (m_peer).GetPor
t () |
| 290 << " total Tx " << m_totBytes << " bytes"); |
| 291 m_txTraceWithAddresses (packet, localAddress, InetSocketAddress::ConvertFr
om (m_peer)); |
| 292 } |
| 293 else if (Inet6SocketAddress::IsMatchingType (m_peer)) |
| 294 { |
| 295 NS_LOG_INFO ("At time " << Simulator::Now ().GetSeconds () |
| 296 << "s on-off application sent " |
| 297 << packet->GetSize () << " bytes to " |
| 298 << Inet6SocketAddress::ConvertFrom(m_peer).GetIpv6 () |
| 299 << " port " << Inet6SocketAddress::ConvertFrom (m_peer).GetPo
rt () |
| 300 << " total Tx " << m_totBytes << " bytes"); |
| 301 m_txTraceWithAddresses (packet, localAddress, Inet6SocketAddress::ConvertF
rom(m_peer)); |
| 302 } |
| 303 m_lastStartTime = Simulator::Now (); |
| 304 m_residualBits = 0; |
| 305 ScheduleNextTx (); |
| 306 } |
| 307 |
| 308 |
| 309 void NistOnOffApplication::ConnectionSucceeded (Ptr<Socket> socket) |
| 310 { |
| 311 NS_LOG_FUNCTION (this << socket); |
| 312 m_connected = true; |
| 313 } |
| 314 |
| 315 void NistOnOffApplication::ConnectionFailed (Ptr<Socket> socket) |
| 316 { |
| 317 NS_LOG_FUNCTION (this << socket); |
| 318 } |
| 319 |
| 320 |
| 321 } // Namespace ns3 |
OLD | NEW |