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 #include <sstream>
35 #include "ns3/core-module.h"
36 #include "ns3/network-module.h"
37 #include "ns3/mobility-module.h"
38 #include "ns3/internet-module.h"
39 #include "ns3/stats-module.h"
40 #include "ns3/yans-wifi-helper.h"
41 #include "wifi-example-apps.h"
42 
43 using namespace ns3;
44 using namespace std;
45 
46 NS_LOG_COMPONENT_DEFINE ("WiFiDistanceExperiment");
47 
49  std::string path, Ptr<const Packet> packet) {
50  NS_LOG_INFO ("Sent frame counted in " <<
51  datac->GetKey ());
52  datac->Update ();
53  // end TxCallback
54 }
55 
56 
57 
58 
59 //----------------------------------------------------------------------
60 //-- main
61 //----------------------------------------------
62 int main (int argc, char *argv[]) {
63 
64  double distance = 50.0;
65  string format ("omnet");
66 
67  string experiment ("wifi-distance-test");
68  string strategy ("wifi-default");
69  string input;
70  string runID;
71 
72  {
73  stringstream sstr;
74  sstr << "run-" << time (NULL);
75  runID = sstr.str ();
76  }
77 
78  // Set up command line parameters used to control the experiment.
80  cmd.AddValue ("distance", "Distance apart to place nodes (in meters).",
81  distance);
82  cmd.AddValue ("format", "Format to use for data output.",
83  format);
84  cmd.AddValue ("experiment", "Identifier for experiment.",
85  experiment);
86  cmd.AddValue ("strategy", "Identifier for strategy.",
87  strategy);
88  cmd.AddValue ("run", "Identifier for run.",
89  runID);
90  cmd.Parse (argc, argv);
91 
92  if (format != "omnet" && format != "db") {
93  NS_LOG_ERROR ("Unknown output format '" << format << "'");
94  return -1;
95  }
96 
97  #ifndef STATS_HAS_SQLITE3
98  if (format == "db") {
99  NS_LOG_ERROR ("sqlite support not compiled in.");
100  return -1;
101  }
102  #endif
103 
104  {
105  stringstream sstr ("");
106  sstr << distance;
107  input = sstr.str ();
108  }
109 
110 
111 
112 
113  //------------------------------------------------------------
114  //-- Create nodes and network stacks
115  //--------------------------------------------
116  NS_LOG_INFO ("Creating nodes.");
118  nodes.Create (2);
119 
120  NS_LOG_INFO ("Installing WiFi and Internet stack.");
122  WifiMacHelper wifiMac;
123  wifiMac.SetType ("ns3::AdhocWifiMac");
126  wifiPhy.SetChannel (wifiChannel.Create ());
127  NetDeviceContainer nodeDevices = wifi.Install (wifiPhy, wifiMac, nodes);
128 
129  InternetStackHelper internet;
130  internet.Install (nodes);
131  Ipv4AddressHelper ipAddrs;
132  ipAddrs.SetBase ("192.168.0.0", "255.255.255.0");
133  ipAddrs.Assign (nodeDevices);
134 
135 
136 
137 
138  //------------------------------------------------------------
139  //-- Setup physical layout
140  //--------------------------------------------
141  NS_LOG_INFO ("Installing static mobility; distance " << distance << " .");
143  Ptr<ListPositionAllocator> positionAlloc =
144  CreateObject<ListPositionAllocator>();
145  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
146  positionAlloc->Add (Vector (0.0, distance, 0.0));
147  mobility.SetPositionAllocator (positionAlloc);
148  mobility.Install (nodes);
149 
150 
151 
152 
153  //------------------------------------------------------------
154  //-- Create a custom traffic source and sink
155  //--------------------------------------------
156  NS_LOG_INFO ("Create traffic source & sink.");
157  Ptr<Node> appSource = NodeList::GetNode (0);
158  Ptr<Sender> sender = CreateObject<Sender>();
159  appSource->AddApplication (sender);
160  sender->SetStartTime (Seconds (1));
161 
162  Ptr<Node> appSink = NodeList::GetNode (1);
163  Ptr<Receiver> receiver = CreateObject<Receiver>();
164  appSink->AddApplication (receiver);
165  receiver->SetStartTime (Seconds (0));
166 
167  Config::Set ("/NodeList/*/ApplicationList/*/$Sender/Destination",
168  Ipv4AddressValue ("192.168.0.2"));
169 
170 
171 
172 
173  //------------------------------------------------------------
174  //-- Setup stats and data collection
175  //--------------------------------------------
176 
177  // Create a DataCollector object to hold information about this run.
179  data.DescribeRun (experiment,
180  strategy,
181  input,
182  runID);
183 
184  // Add any information we wish to record about this run.
185  data.AddMetadata ("author", "tjkopena");
186 
187 
188  // Create a counter to track how many frames are generated. Updates
189  // are triggered by the trace signal generated by the WiFi MAC model
190  // object. Here we connect the counter to the signal via the simple
191  // TxCallback() glue function defined above.
193  CreateObject<CounterCalculator<uint32_t> >();
194  totalTx->SetKey ("wifi-tx-frames");
195  totalTx->SetContext ("node[0]");
196  Config::Connect ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
197  MakeBoundCallback (&TxCallback, totalTx));
198  data.AddDataCalculator (totalTx);
199 
200  // This is similar, but creates a counter to track how many frames
201  // are received. Instead of our own glue function, this uses a
202  // method of an adapter class to connect a counter directly to the
203  // trace signal generated by the WiFi MAC.
205  CreateObject<PacketCounterCalculator>();
206  totalRx->SetKey ("wifi-rx-frames");
207  totalRx->SetContext ("node[1]");
208  Config::Connect ("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
210  totalRx));
211  data.AddDataCalculator (totalRx);
212 
213 
214 
215 
216  // This counter tracks how many packets---as opposed to frames---are
217  // generated. This is connected directly to a trace signal provided
218  // by our Sender class.
220  CreateObject<PacketCounterCalculator>();
221  appTx->SetKey ("sender-tx-packets");
222  appTx->SetContext ("node[0]");
223  Config::Connect ("/NodeList/0/ApplicationList/*/$Sender/Tx",
225  appTx));
226  data.AddDataCalculator (appTx);
227 
228  // Here a counter for received packets is directly manipulated by
229  // one of the custom objects in our simulation, the Receiver
230  // Application. The Receiver object is given a pointer to the
231  // counter and calls its Update() method whenever a packet arrives.
232  Ptr<CounterCalculator<> > appRx =
233  CreateObject<CounterCalculator<> >();
234  appRx->SetKey ("receiver-rx-packets");
235  appRx->SetContext ("node[1]");
236  receiver->SetCounter (appRx);
237  data.AddDataCalculator (appRx);
238 
239 
240 
241 
255  // This DataCalculator connects directly to the transmit trace
256  // provided by our Sender Application. It records some basic
257  // statistics about the sizes of the packets received (min, max,
258  // avg, total # bytes), although in this scenaro they're fixed.
260  CreateObject<PacketSizeMinMaxAvgTotalCalculator>();
261  appTxPkts->SetKey ("tx-pkt-size");
262  appTxPkts->SetContext ("node[0]");
263  Config::Connect ("/NodeList/0/ApplicationList/*/$Sender/Tx",
266  appTxPkts));
267  data.AddDataCalculator (appTxPkts);
268 
269 
270  // Here we directly manipulate another DataCollector tracking min,
271  // max, total, and average propagation delays. Check out the Sender
272  // and Receiver classes to see how packets are tagged with
273  // timestamps to do this.
275  CreateObject<TimeMinMaxAvgTotalCalculator>();
276  delayStat->SetKey ("delay");
277  delayStat->SetContext (".");
278  receiver->SetDelayTracker (delayStat);
279  data.AddDataCalculator (delayStat);
280 
281 
282 
283 
284  //------------------------------------------------------------
285  //-- Run the simulation
286  //--------------------------------------------
287  NS_LOG_INFO ("Run Simulation.");
288  Simulator::Run ();
289 
290 
291 
292 
293  //------------------------------------------------------------
294  //-- Generate statistics output.
295  //--------------------------------------------
296 
297  // Pick an output writer based in the requested format.
298  Ptr<DataOutputInterface> output = 0;
299  if (format == "omnet") {
300  NS_LOG_INFO ("Creating omnet formatted data output.");
301  output = CreateObject<OmnetDataOutput>();
302  } else if (format == "db") {
303  #ifdef STATS_HAS_SQLITE3
304  NS_LOG_INFO ("Creating sqlite formatted data output.");
305  output = CreateObject<SqliteDataOutput>();
306  #endif
307  } else {
308  NS_LOG_ERROR ("Unknown output format " << format);
309  }
310 
311  // Finally, have that writer interrogate the DataCollector and save
312  // the results.
313  if (output != 0)
314  output->Output (data);
315 
316  // Free any memory here at the end of this example.
318 
319  // end main
320 }
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
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:805
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:170
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
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:280
cmd
Definition: second.py:35
static YansWifiPhyHelper Default(void)
Create a phy helper in a default working state.
STL namespace.
helps to create WifiNetDevice objects
Definition: wifi-helper.h:299
void TxCallback(Ptr< CounterCalculator< uint32_t > > datac, std::string path, Ptr< const Packet > packet)
void PacketUpdate(std::string path, Ptr< const Packet > packet)
Increments the packet stats by the size of the packet.
Ptr< YansWifiChannel > Create(void) const
mobility
Definition: third.py:101
void SetChannel(Ptr< YansWifiChannel > channel)
nodes
Definition: first.py:25
uint8_t data[writeSize]
holds a vector of ns3::NetDevice pointers
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
Parse command-line arguments.
Definition: command-line.h:213
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:871
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:134
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 SetDelayTracker(Ptr< TimeMinMaxAvgTotalCalculator > delay)
manage and create wifi channel objects for the yans model.
AttributeValue implementation for Ipv4Address.
Definition: ipv4-address.h:329
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())
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
wifi
Definition: third.py:89
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 experiment(std::string queue_disc_type)
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:1062
void Add(Vector v)
Add a position to the list of positions.
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:256
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)