A Discrete-Event Network Simulator
API
wifi-example-sim.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * Authors: Joe Kopena <tjkopena@cs.drexel.edu>
17  *
18  * This program conducts a simple experiment: It places two nodes at a
19  * parameterized distance apart. One node generates packets and the
20  * other node receives. The stat framework collects data on packet
21  * loss. Outside of this program, a control script uses that data to
22  * produce graphs presenting performance at the varying distances.
23  * This isn't a typical simulation but is a common "experiment"
24  * performed in real life and serves as an accessible exemplar for the
25  * stat framework. It also gives some intuition on the behavior and
26  * basic reasonability of the NS-3 WiFi models.
27  *
28  * Applications used by this program are in test02-apps.h and
29  * test02-apps.cc, which should be in the same place as this file.
30  *
31  */
32 
33 #include <ctime>
34 
35 #include <sstream>
36 
37 #include "ns3/core-module.h"
38 #include "ns3/network-module.h"
39 #include "ns3/mobility-module.h"
40 #include "ns3/wifi-module.h"
41 #include "ns3/internet-module.h"
42 
43 #include "ns3/stats-module.h"
44 
45 #include "wifi-example-apps.h"
46 
47 using namespace ns3;
48 using namespace std;
49 
50 NS_LOG_COMPONENT_DEFINE ("WiFiDistanceExperiment");
51 
53  std::string path, Ptr<const Packet> packet) {
54  NS_LOG_INFO ("Sent frame counted in " <<
55  datac->GetKey ());
56  datac->Update ();
57  // end TxCallback
58 }
59 
60 
61 
62 
63 //----------------------------------------------------------------------
64 //-- main
65 //----------------------------------------------
66 int main (int argc, char *argv[]) {
67 
68  double distance = 50.0;
69  string format ("omnet");
70 
71  string experiment ("wifi-distance-test");
72  string strategy ("wifi-default");
73  string input;
74  string runID;
75 
76  {
77  stringstream sstr;
78  sstr << "run-" << time (NULL);
79  runID = sstr.str ();
80  }
81 
82  // Set up command line parameters used to control the experiment.
84  cmd.AddValue ("distance", "Distance apart to place nodes (in meters).",
85  distance);
86  cmd.AddValue ("format", "Format to use for data output.",
87  format);
88  cmd.AddValue ("experiment", "Identifier for experiment.",
89  experiment);
90  cmd.AddValue ("strategy", "Identifier for strategy.",
91  strategy);
92  cmd.AddValue ("run", "Identifier for run.",
93  runID);
94  cmd.Parse (argc, argv);
95 
96  if (format != "omnet" && format != "db") {
97  NS_LOG_ERROR ("Unknown output format '" << format << "'");
98  return -1;
99  }
100 
101  #ifndef STATS_HAS_SQLITE3
102  if (format == "db") {
103  NS_LOG_ERROR ("sqlite support not compiled in.");
104  return -1;
105  }
106  #endif
107 
108  {
109  stringstream sstr ("");
110  sstr << distance;
111  input = sstr.str ();
112  }
113 
114 
115 
116 
117  //------------------------------------------------------------
118  //-- Create nodes and network stacks
119  //--------------------------------------------
120  NS_LOG_INFO ("Creating nodes.");
122  nodes.Create (2);
123 
124  NS_LOG_INFO ("Installing WiFi and Internet stack.");
126  WifiMacHelper wifiMac;
127  wifiMac.SetType ("ns3::AdhocWifiMac");
130  wifiPhy.SetChannel (wifiChannel.Create ());
131  NetDeviceContainer nodeDevices = wifi.Install (wifiPhy, wifiMac, nodes);
132 
133  InternetStackHelper internet;
134  internet.Install (nodes);
135  Ipv4AddressHelper ipAddrs;
136  ipAddrs.SetBase ("192.168.0.0", "255.255.255.0");
137  ipAddrs.Assign (nodeDevices);
138 
139 
140 
141 
142  //------------------------------------------------------------
143  //-- Setup physical layout
144  //--------------------------------------------
145  NS_LOG_INFO ("Installing static mobility; distance " << distance << " .");
147  Ptr<ListPositionAllocator> positionAlloc =
148  CreateObject<ListPositionAllocator>();
149  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
150  positionAlloc->Add (Vector (0.0, distance, 0.0));
151  mobility.SetPositionAllocator (positionAlloc);
152  mobility.Install (nodes);
153 
154 
155 
156 
157  //------------------------------------------------------------
158  //-- Create a custom traffic source and sink
159  //--------------------------------------------
160  NS_LOG_INFO ("Create traffic source & sink.");
161  Ptr<Node> appSource = NodeList::GetNode (0);
162  Ptr<Sender> sender = CreateObject<Sender>();
163  appSource->AddApplication (sender);
164  sender->SetStartTime (Seconds (1));
165 
166  Ptr<Node> appSink = NodeList::GetNode (1);
167  Ptr<Receiver> receiver = CreateObject<Receiver>();
168  appSink->AddApplication (receiver);
169  receiver->SetStartTime (Seconds (0));
170 
171  Config::Set ("/NodeList/*/ApplicationList/*/$Sender/Destination",
172  Ipv4AddressValue ("192.168.0.2"));
173 
174 
175 
176 
177  //------------------------------------------------------------
178  //-- Setup stats and data collection
179  //--------------------------------------------
180 
181  // Create a DataCollector object to hold information about this run.
183  data.DescribeRun (experiment,
184  strategy,
185  input,
186  runID);
187 
188  // Add any information we wish to record about this run.
189  data.AddMetadata ("author", "tjkopena");
190 
191 
192  // Create a counter to track how many frames are generated. Updates
193  // are triggered by the trace signal generated by the WiFi MAC model
194  // object. Here we connect the counter to the signal via the simple
195  // TxCallback() glue function defined above.
197  CreateObject<CounterCalculator<uint32_t> >();
198  totalTx->SetKey ("wifi-tx-frames");
199  totalTx->SetContext ("node[0]");
200  Config::Connect ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
201  MakeBoundCallback (&TxCallback, totalTx));
202  data.AddDataCalculator (totalTx);
203 
204  // This is similar, but creates a counter to track how many frames
205  // are received. Instead of our own glue function, this uses a
206  // method of an adapter class to connect a counter directly to the
207  // trace signal generated by the WiFi MAC.
209  CreateObject<PacketCounterCalculator>();
210  totalRx->SetKey ("wifi-rx-frames");
211  totalRx->SetContext ("node[1]");
212  Config::Connect ("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
214  totalRx));
215  data.AddDataCalculator (totalRx);
216 
217 
218 
219 
220  // This counter tracks how many packets---as opposed to frames---are
221  // generated. This is connected directly to a trace signal provided
222  // by our Sender class.
224  CreateObject<PacketCounterCalculator>();
225  appTx->SetKey ("sender-tx-packets");
226  appTx->SetContext ("node[0]");
227  Config::Connect ("/NodeList/0/ApplicationList/*/$Sender/Tx",
229  appTx));
230  data.AddDataCalculator (appTx);
231 
232  // Here a counter for received packets is directly manipulated by
233  // one of the custom objects in our simulation, the Receiver
234  // Application. The Receiver object is given a pointer to the
235  // counter and calls its Update() method whenever a packet arrives.
236  Ptr<CounterCalculator<> > appRx =
237  CreateObject<CounterCalculator<> >();
238  appRx->SetKey ("receiver-rx-packets");
239  appRx->SetContext ("node[1]");
240  receiver->SetCounter (appRx);
241  data.AddDataCalculator (appRx);
242 
243 
244 
245 
259  // This DataCalculator connects directly to the transmit trace
260  // provided by our Sender Application. It records some basic
261  // statistics about the sizes of the packets received (min, max,
262  // avg, total # bytes), although in this scenaro they're fixed.
264  CreateObject<PacketSizeMinMaxAvgTotalCalculator>();
265  appTxPkts->SetKey ("tx-pkt-size");
266  appTxPkts->SetContext ("node[0]");
267  Config::Connect ("/NodeList/0/ApplicationList/*/$Sender/Tx",
270  appTxPkts));
271  data.AddDataCalculator (appTxPkts);
272 
273 
274  // Here we directly manipulate another DataCollector tracking min,
275  // max, total, and average propagation delays. Check out the Sender
276  // and Receiver classes to see how packets are tagged with
277  // timestamps to do this.
279  CreateObject<TimeMinMaxAvgTotalCalculator>();
280  delayStat->SetKey ("delay");
281  delayStat->SetContext (".");
282  receiver->SetDelayTracker (delayStat);
283  data.AddDataCalculator (delayStat);
284 
285 
286 
287 
288  //------------------------------------------------------------
289  //-- Run the simulation
290  //--------------------------------------------
291  NS_LOG_INFO ("Run Simulation.");
292  Simulator::Run ();
293 
294 
295 
296 
297  //------------------------------------------------------------
298  //-- Generate statistics output.
299  //--------------------------------------------
300 
301  // Pick an output writer based in the requested format.
302  Ptr<DataOutputInterface> output = 0;
303  if (format == "omnet") {
304  NS_LOG_INFO ("Creating omnet formatted data output.");
305  output = CreateObject<OmnetDataOutput>();
306  } else if (format == "db") {
307  #ifdef STATS_HAS_SQLITE3
308  NS_LOG_INFO ("Creating sqlite formatted data output.");
309  output = CreateObject<SqliteDataOutput>();
310  #endif
311  } else {
312  NS_LOG_ERROR ("Unknown output format " << format);
313  }
314 
315  // Finally, have that writer interrogate the DataCollector and save
316  // the results.
317  if (output != 0)
318  output->Output (data);
319 
320  // Free any memory here at the end of this example.
322 
323  // end main
324 }
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
void experiment(bool enableCtsRts)
Run single 10 seconds experiment with enabled or disabled RTS/CTS mechanism.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
Ptr< YansWifiChannel > Create(void) const
virtual void Output(DataCollector &dc)=0
Outputs information from the provided DataCollector.
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:241
Make it easy to create and manage PHY objects for the yans model.
static YansWifiChannelHelper Default(void)
Create a channel helper in a default working state.
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:769
void SetKey(const std::string key)
Sets the DataCalculator key to the provided key.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1686
static void Run(void)
Run the simulation.
Definition: simulator.cc:201
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
static YansWifiPhyHelper Default(void)
Create a phy helper in a default working state.
STL namespace.
helps to create WifiNetDevice objects
Definition: wifi-helper.h:231
void TxCallback(Ptr< CounterCalculator< uint32_t > > datac, std::string path, Ptr< const Packet > packet)
tuple cmd
Definition: second.py:35
void PacketUpdate(std::string path, Ptr< const Packet > packet)
Increments the packet stats by the size of the packet.
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer c) const
Definition: wifi-helper.cc:712
tuple nodes
Definition: first.py:25
void SetChannel(Ptr< YansWifiChannel > channel)
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
tuple mobility
Definition: third.py:101
uint8_t data[writeSize]
void AddDataCalculator(Ptr< DataCalculator > datac)
Add a DataCalculator object to the DataCollector.
holds a vector of ns3::NetDevice pointers
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
void AddMetadata(std::string key, std::string value)
Add the key and the value as a pair of strings to the metadata list.
Parse command-line arguments.
Definition: command-line.h:205
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:835
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:165
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void PacketUpdate(std::string path, Ptr< const Packet > packet)
Increments the packet counter by one.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
void SetDelayTracker(Ptr< TimeMinMaxAvgTotalCalculator > delay)
manage and create wifi channel objects for the yans model.
AttributeValue implementation for Ipv4Address.
Definition: ipv4-address.h:327
create MAC layers for a ns3::WifiNetDevice.
virtual void SetType(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue(), std::string n10="", const AttributeValue &v10=EmptyAttributeValue())
Helper class used to assign positions and mobility models to nodes.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:495
Collects data.
void SetContext(const std::string context)
Sets the DataCalculator context to the provided context.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void Add(Vector v)
Add a position to the list of positions.
void DescribeRun(std::string experiment, std::string strategy, std::string input, std::string runID, std::string description="")
Provide specific parameters to the DataCollector.
void Parse(int argc, char *argv[])
Parse the program arguments.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:220
tuple wifi
Definition: third.py:89
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
void SetCounter(Ptr< CounterCalculator<> > calc)