A Discrete-Event Network Simulator
API
manet-routing-compare.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 University of Kansas
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Justin Rohrer <rohrej@ittc.ku.edu>
18  *
19  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
20  * ResiliNets Research Group https://resilinets.org/
21  * Information and Telecommunication Technology Center (ITTC)
22  * and Department of Electrical Engineering and Computer Science
23  * The University of Kansas Lawrence, KS USA.
24  *
25  * Work supported in part by NSF FIND (Future Internet Design) Program
26  * under grant CNS-0626918 (Postmodern Internet Architecture),
27  * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
28  * US Department of Defense (DoD), and ITTC at The University of Kansas.
29  */
30 
31 /*
32  * This example program allows one to run ns-3 DSDV, AODV, or OLSR under
33  * a typical random waypoint mobility model.
34  *
35  * By default, the simulation runs for 200 simulated seconds, of which
36  * the first 50 are used for start-up time. The number of nodes is 50.
37  * Nodes move according to RandomWaypointMobilityModel with a speed of
38  * 20 m/s and no pause time within a 300x1500 m region. The WiFi is
39  * in ad hoc mode with a 2 Mb/s rate (802.11b) and a Friis loss model.
40  * The transmit power is set to 7.5 dBm.
41  *
42  * It is possible to change the mobility and density of the network by
43  * directly modifying the speed and the number of nodes. It is also
44  * possible to change the characteristics of the network by changing
45  * the transmit power (as power increases, the impact of mobility
46  * decreases and the effective density increases).
47  *
48  * By default, OLSR is used, but specifying a value of 2 for the protocol
49  * will cause AODV to be used, and specifying a value of 3 will cause
50  * DSDV to be used.
51  *
52  * By default, there are 10 source/sink data pairs sending UDP data
53  * at an application rate of 2.048 Kb/s each. This is typically done
54  * at a rate of 4 64-byte packets per second. Application data is
55  * started at a random time between 50 and 51 seconds and continues
56  * to the end of the simulation.
57  *
58  * The program outputs a few items:
59  * - packet receptions are notified to stdout such as:
60  * <timestamp> <node-id> received one packet from <src-address>
61  * - each second, the data reception statistics are tabulated and output
62  * to a comma-separated value (csv) file
63  * - some tracing and flow monitor configuration that used to work is
64  * left commented inline in the program
65  */
66 
67 #include "ns3/aodv-module.h"
68 #include "ns3/applications-module.h"
69 #include "ns3/core-module.h"
70 #include "ns3/dsdv-module.h"
71 #include "ns3/dsr-module.h"
72 #include "ns3/flow-monitor-module.h"
73 #include "ns3/internet-module.h"
74 #include "ns3/mobility-module.h"
75 #include "ns3/network-module.h"
76 #include "ns3/olsr-module.h"
77 #include "ns3/yans-wifi-helper.h"
78 
79 #include <fstream>
80 #include <iostream>
81 
82 using namespace ns3;
83 using namespace dsr;
84 
85 NS_LOG_COMPONENT_DEFINE("manet-routing-compare");
86 
93 {
94  public:
99  void Run();
100 
106  void CommandSetup(int argc, char** argv);
107 
108  private:
120  void ReceivePacket(Ptr<Socket> socket);
124  void CheckThroughput();
125 
126  uint32_t port{9};
127  uint32_t bytesTotal{0};
128  uint32_t packetsReceived{0};
129 
130  std::string m_CSVfileName{"manet-routing.output.csv"};
131  int m_nSinks{10};
132  std::string m_protocolName{"AODV"};
133  double m_txp{7.5};
134  bool m_traceMobility{false};
135  bool m_flowMonitor{false};
136 };
137 
139 {
140 }
141 
142 static inline std::string
143 PrintReceivedPacket(Ptr<Socket> socket, Ptr<Packet> packet, Address senderAddress)
144 {
145  std::ostringstream oss;
146 
147  oss << Simulator::Now().GetSeconds() << " " << socket->GetNode()->GetId();
148 
149  if (InetSocketAddress::IsMatchingType(senderAddress))
150  {
152  oss << " received one packet from " << addr.GetIpv4();
153  }
154  else
155  {
156  oss << " received one packet!";
157  }
158  return oss.str();
159 }
160 
161 void
163 {
164  Ptr<Packet> packet;
165  Address senderAddress;
166  while ((packet = socket->RecvFrom(senderAddress)))
167  {
168  bytesTotal += packet->GetSize();
169  packetsReceived += 1;
170  NS_LOG_UNCOND(PrintReceivedPacket(socket, packet, senderAddress));
171  }
172 }
173 
174 void
176 {
177  double kbs = (bytesTotal * 8.0) / 1000;
178  bytesTotal = 0;
179 
180  std::ofstream out(m_CSVfileName, std::ios::app);
181 
182  out << (Simulator::Now()).GetSeconds() << "," << kbs << "," << packetsReceived << ","
183  << m_nSinks << "," << m_protocolName << "," << m_txp << "" << std::endl;
184 
185  out.close();
186  packetsReceived = 0;
188 }
189 
192 {
193  TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
196  sink->Bind(local);
197  sink->SetRecvCallback(MakeCallback(&RoutingExperiment::ReceivePacket, this));
198 
199  return sink;
200 }
201 
202 void
203 RoutingExperiment::CommandSetup(int argc, char** argv)
204 {
205  CommandLine cmd(__FILE__);
206  cmd.AddValue("CSVfileName", "The name of the CSV output file name", m_CSVfileName);
207  cmd.AddValue("traceMobility", "Enable mobility tracing", m_traceMobility);
208  cmd.AddValue("protocol", "Routing protocol (OLSR, AODV, DSDV, DSR)", m_protocolName);
209  cmd.AddValue("flowMonitor", "enable FlowMonitor", m_flowMonitor);
210  cmd.Parse(argc, argv);
211 
212  std::vector<std::string> allowedProtocols{"OLSR", "AODV", "DSDV", "DSR"};
213 
214  if (std::find(std::begin(allowedProtocols), std::end(allowedProtocols), m_protocolName) ==
215  std::end(allowedProtocols))
216  {
217  NS_FATAL_ERROR("No such protocol:" << m_protocolName);
218  }
219 }
220 
221 int
222 main(int argc, char* argv[])
223 {
225  experiment.CommandSetup(argc, argv);
226  experiment.Run();
227 
228  return 0;
229 }
230 
231 void
233 {
235 
236  // blank out the last output file and write the column headers
237  std::ofstream out(m_CSVfileName);
238  out << "SimulationSecond,"
239  << "ReceiveRate,"
240  << "PacketsReceived,"
241  << "NumberOfSinks,"
242  << "RoutingProtocol,"
243  << "TransmissionPower" << std::endl;
244  out.close();
245 
246  int nWifis = 50;
247 
248  double TotalTime = 200.0;
249  std::string rate("2048bps");
250  std::string phyMode("DsssRate11Mbps");
251  std::string tr_name("manet-routing-compare");
252  int nodeSpeed = 20; // in m/s
253  int nodePause = 0; // in s
254 
255  Config::SetDefault("ns3::OnOffApplication::PacketSize", StringValue("64"));
256  Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue(rate));
257 
258  // Set Non-unicastMode rate to unicast mode
259  Config::SetDefault("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue(phyMode));
260 
261  NodeContainer adhocNodes;
262  adhocNodes.Create(nWifis);
263 
264  // setting up wifi phy and channel using helpers
266  wifi.SetStandard(WIFI_STANDARD_80211b);
267 
268  YansWifiPhyHelper wifiPhy;
269  YansWifiChannelHelper wifiChannel;
270  wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
271  wifiChannel.AddPropagationLoss("ns3::FriisPropagationLossModel");
272  wifiPhy.SetChannel(wifiChannel.Create());
273 
274  // Add a mac and disable rate control
275  WifiMacHelper wifiMac;
276  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
277  "DataMode",
278  StringValue(phyMode),
279  "ControlMode",
280  StringValue(phyMode));
281 
282  wifiPhy.Set("TxPowerStart", DoubleValue(m_txp));
283  wifiPhy.Set("TxPowerEnd", DoubleValue(m_txp));
284 
285  wifiMac.SetType("ns3::AdhocWifiMac");
286  NetDeviceContainer adhocDevices = wifi.Install(wifiPhy, wifiMac, adhocNodes);
287 
288  MobilityHelper mobilityAdhoc;
289  int64_t streamIndex = 0; // used to get consistent mobility across scenarios
290 
291  ObjectFactory pos;
292  pos.SetTypeId("ns3::RandomRectanglePositionAllocator");
293  pos.Set("X", StringValue("ns3::UniformRandomVariable[Min=0.0|Max=300.0]"));
294  pos.Set("Y", StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1500.0]"));
295 
296  Ptr<PositionAllocator> taPositionAlloc = pos.Create()->GetObject<PositionAllocator>();
297  streamIndex += taPositionAlloc->AssignStreams(streamIndex);
298 
299  std::stringstream ssSpeed;
300  ssSpeed << "ns3::UniformRandomVariable[Min=0.0|Max=" << nodeSpeed << "]";
301  std::stringstream ssPause;
302  ssPause << "ns3::ConstantRandomVariable[Constant=" << nodePause << "]";
303  mobilityAdhoc.SetMobilityModel("ns3::RandomWaypointMobilityModel",
304  "Speed",
305  StringValue(ssSpeed.str()),
306  "Pause",
307  StringValue(ssPause.str()),
308  "PositionAllocator",
309  PointerValue(taPositionAlloc));
310  mobilityAdhoc.SetPositionAllocator(taPositionAlloc);
311  mobilityAdhoc.Install(adhocNodes);
312  streamIndex += mobilityAdhoc.AssignStreams(adhocNodes, streamIndex);
313 
314  AodvHelper aodv;
316  DsdvHelper dsdv;
317  DsrHelper dsr;
318  DsrMainHelper dsrMain;
321 
322  if (m_protocolName == "OLSR")
323  {
324  list.Add(olsr, 100);
325  internet.SetRoutingHelper(list);
326  internet.Install(adhocNodes);
327  }
328  else if (m_protocolName == "AODV")
329  {
330  list.Add(aodv, 100);
331  internet.SetRoutingHelper(list);
332  internet.Install(adhocNodes);
333  }
334  else if (m_protocolName == "DSDV")
335  {
336  list.Add(dsdv, 100);
337  internet.SetRoutingHelper(list);
338  internet.Install(adhocNodes);
339  }
340  else if (m_protocolName == "DSR")
341  {
342  internet.Install(adhocNodes);
343  dsrMain.Install(dsr, adhocNodes);
344  if (m_flowMonitor)
345  {
346  NS_FATAL_ERROR("Error: FlowMonitor does not work with DSR. Terminating.");
347  }
348  }
349  else
350  {
351  NS_FATAL_ERROR("No such protocol:" << m_protocolName);
352  }
353 
354  NS_LOG_INFO("assigning ip address");
355 
356  Ipv4AddressHelper addressAdhoc;
357  addressAdhoc.SetBase("10.1.1.0", "255.255.255.0");
358  Ipv4InterfaceContainer adhocInterfaces;
359  adhocInterfaces = addressAdhoc.Assign(adhocDevices);
360 
361  OnOffHelper onoff1("ns3::UdpSocketFactory", Address());
362  onoff1.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1.0]"));
363  onoff1.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0.0]"));
364 
365  for (int i = 0; i < m_nSinks; i++)
366  {
367  Ptr<Socket> sink = SetupPacketReceive(adhocInterfaces.GetAddress(i), adhocNodes.Get(i));
368 
369  AddressValue remoteAddress(InetSocketAddress(adhocInterfaces.GetAddress(i), port));
370  onoff1.SetAttribute("Remote", remoteAddress);
371 
372  Ptr<UniformRandomVariable> var = CreateObject<UniformRandomVariable>();
373  ApplicationContainer temp = onoff1.Install(adhocNodes.Get(i + m_nSinks));
374  temp.Start(Seconds(var->GetValue(100.0, 101.0)));
375  temp.Stop(Seconds(TotalTime));
376  }
377 
378  std::stringstream ss;
379  ss << nWifis;
380  std::string nodes = ss.str();
381 
382  std::stringstream ss2;
383  ss2 << nodeSpeed;
384  std::string sNodeSpeed = ss2.str();
385 
386  std::stringstream ss3;
387  ss3 << nodePause;
388  std::string sNodePause = ss3.str();
389 
390  std::stringstream ss4;
391  ss4 << rate;
392  std::string sRate = ss4.str();
393 
394  // NS_LOG_INFO("Configure Tracing.");
395  // tr_name = tr_name + "_" + m_protocolName +"_" + nodes + "nodes_" + sNodeSpeed + "speed_" +
396  // sNodePause + "pause_" + sRate + "rate";
397 
398  // AsciiTraceHelper ascii;
399  // Ptr<OutputStreamWrapper> osw = ascii.CreateFileStream(tr_name + ".tr");
400  // wifiPhy.EnableAsciiAll(osw);
401  AsciiTraceHelper ascii;
402  MobilityHelper::EnableAsciiAll(ascii.CreateFileStream(tr_name + ".mob"));
403 
404  FlowMonitorHelper flowmonHelper;
405  Ptr<FlowMonitor> flowmon;
406  if (m_flowMonitor)
407  {
408  flowmon = flowmonHelper.InstallAll();
409  }
410 
411  NS_LOG_INFO("Run Simulation.");
412 
413  CheckThroughput();
414 
415  Simulator::Stop(Seconds(TotalTime));
416  Simulator::Run();
417 
418  if (m_flowMonitor)
419  {
420  flowmon->SerializeToXmlFile(tr_name + ".flowmon", false, false);
421  }
422 
424 }
Ptr< Socket > SetupPacketReceive(Ptr< Node > node)
Create a socket and prepare it for packet reception.
Routing experiment class.
void Run()
Run the experiment.
void CommandSetup(int argc, char **argv)
Handles the command-line parameters.
void CheckThroughput()
Compute the throughput.
void ReceivePacket(Ptr< Socket > socket)
Receive a packet.
Ptr< Socket > SetupPacketReceive(Ipv4Address addr, Ptr< Node > node)
Setup the receiving socket in a Sink Node.
a polymophic address class
Definition: address.h:101
Helper class that adds AODV routing to nodes.
Definition: aodv-helper.h:36
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Manage ASCII trace files for device models.
Definition: trace-helper.h:174
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
Parse command-line arguments.
Definition: command-line.h:232
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Helper class that adds DSDV routing to nodes.
Definition: dsdv-helper.h:47
DSR helper class to manage creation of DSR routing instance and to insert it on a node as a sublayer ...
Definition: dsr-helper.h:53
Helper class that adds DSR routing to nodes.
void Install(DsrHelper &dsrHelper, NodeContainer nodes)
Install routing to the nodes.
Helper to enable IP flow monitoring on a set of Nodes.
Ptr< FlowMonitor > InstallAll()
Enable flow monitoring on all nodes.
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Helper class that adds ns3::Ipv4ListRouting objects.
Helper class used to assign positions and mobility models to nodes.
int64_t AssignStreams(NodeContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the mobility models on t...
static void EnableAsciiAll(Ptr< OutputStreamWrapper > stream)
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void SetMobilityModel(std::string type, Ts &&... args)
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t GetId() const
Definition: node.cc:117
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Helper class that adds OLSR routing to nodes.
Definition: olsr-helper.h:42
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
static void EnablePrinting()
Enable printing packets metadata.
Definition: packet.cc:596
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Allocate a set of positions.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
virtual Ptr< Node > GetNode() const =0
Return the node this socket is associated with.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
Hold variables of type string.
Definition: string.h:56
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:835
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:163
manage and create wifi channel objects for the YANS model.
void SetPropagationDelay(std::string name, Ts &&... args)
void AddPropagationLoss(std::string name, Ts &&... args)
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
void experiment(std::string queue_disc_type)
uint16_t port
Definition: dsdv-manet.cc:44
void ReceivePacket(Ptr< Socket > socket)
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
@ WIFI_STANDARD_80211b
NodeContainer nodes
static std::string PrintReceivedPacket(Ptr< Socket > socket, Ptr< Packet > packet, Address senderAddress)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Definition: olsr.py:1
cmd
Definition: second.py:40
wifi
Definition: third.py:95
#define list
std::map< Mac48Address, uint64_t > packetsReceived
Map that stores the total packets received per STA (and addressed to that STA)
Definition: wifi-bianchi.cc:72
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55