A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-example-sim.cc
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation;
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 *
15 * Authors: Joe Kopena <tjkopena@cs.drexel.edu>
16 *
17 * This program conducts a simple experiment: It places two nodes at a
18 * parameterized distance apart. One node generates packets and the
19 * other node receives. The stat framework collects data on packet
20 * loss. Outside of this program, a control script uses that data to
21 * produce graphs presenting performance at the varying distances.
22 * This isn't a typical simulation but is a common "experiment"
23 * performed in real life and serves as an accessible exemplar for the
24 * stat framework. It also gives some intuition on the behavior and
25 * basic reasonability of the NS-3 WiFi models.
26 *
27 * Applications used by this program are in test02-apps.h and
28 * test02-apps.cc, which should be in the same place as this file.
29 *
30 */
31
32#include "wifi-example-apps.h"
33
34#include "ns3/core-module.h"
35#include "ns3/internet-module.h"
36#include "ns3/mobility-module.h"
37#include "ns3/network-module.h"
38#include "ns3/stats-module.h"
39#include "ns3/wifi-module.h"
40
41#include <ctime>
42#include <sstream>
43
44using namespace ns3;
45
46NS_LOG_COMPONENT_DEFINE("WiFiDistanceExperiment");
47
55void
57{
58 NS_LOG_INFO("Sent frame counted in " << datac->GetKey());
59 datac->Update();
60}
61
62int
63main(int argc, char* argv[])
64{
65 double distance = 50.0;
66 std::string format("omnet");
67
68 std::string experiment("wifi-distance-test");
69 std::string strategy("wifi-default");
70 std::string input;
71 std::string runID;
72
73 {
74 std::stringstream sstr;
75 sstr << "run-" << time(nullptr);
76 runID = sstr.str();
77 }
78
79 // Set up command line parameters used to control the experiment.
80 CommandLine cmd(__FILE__);
81 cmd.AddValue("distance", "Distance apart to place nodes (in meters).", distance);
82 cmd.AddValue("format", "Format to use for data output.", format);
83 cmd.AddValue("experiment", "Identifier for experiment.", experiment);
84 cmd.AddValue("strategy", "Identifier for strategy.", strategy);
85 cmd.AddValue("run", "Identifier for run.", runID);
86 cmd.Parse(argc, argv);
87
88 if (format != "omnet" && format != "db")
89 {
90 NS_LOG_ERROR("Unknown output format '" << format << "'");
91 return -1;
92 }
93
94#ifndef HAVE_SQLITE3
95 if (format == "db")
96 {
97 NS_LOG_ERROR("sqlite support not compiled in.");
98 return -1;
99 }
100#endif
101
102 {
103 std::stringstream sstr("");
104 sstr << distance;
105 input = sstr.str();
106 }
107
108 //--------------------------------------------
109 //-- Create nodes and network stacks
110 //--------------------------------------------
111 NS_LOG_INFO("Creating nodes.");
113 nodes.Create(2);
114
115 NS_LOG_INFO("Installing WiFi and Internet stack.");
117 WifiMacHelper wifiMac;
118 wifiMac.SetType("ns3::AdhocWifiMac");
119 YansWifiPhyHelper wifiPhy;
121 wifiPhy.SetChannel(wifiChannel.Create());
122 NetDeviceContainer nodeDevices = wifi.Install(wifiPhy, wifiMac, nodes);
123
125 internet.Install(nodes);
126 Ipv4AddressHelper ipAddrs;
127 ipAddrs.SetBase("192.168.0.0", "255.255.255.0");
128 ipAddrs.Assign(nodeDevices);
129
130 //--------------------------------------------
131 //-- Setup physical layout
132 //--------------------------------------------
133 NS_LOG_INFO("Installing static mobility; distance " << distance << " .");
135 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
136 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
137 positionAlloc->Add(Vector(0.0, distance, 0.0));
138 mobility.SetPositionAllocator(positionAlloc);
139 mobility.Install(nodes);
140
141 //--------------------------------------------
142 //-- Create a custom traffic source and sink
143 //--------------------------------------------
144 NS_LOG_INFO("Create traffic source & sink.");
145 Ptr<Node> appSource = NodeList::GetNode(0);
146 Ptr<Sender> sender = CreateObject<Sender>();
147 appSource->AddApplication(sender);
148 sender->SetStartTime(Seconds(1));
149
150 Ptr<Node> appSink = NodeList::GetNode(1);
151 Ptr<Receiver> receiver = CreateObject<Receiver>();
152 appSink->AddApplication(receiver);
153 receiver->SetStartTime(Seconds(0));
154
155 Config::Set("/NodeList/*/ApplicationList/*/$Sender/Destination",
156 Ipv4AddressValue("192.168.0.2"));
157
158 //--------------------------------------------
159 //-- Setup stats and data collection
160 //--------------------------------------------
161
162 // Create a DataCollector object to hold information about this run.
164 data.DescribeRun(experiment, strategy, input, runID);
165
166 // Add any information we wish to record about this run.
167 data.AddMetadata("author", "tjkopena");
168
169 // Create a counter to track how many frames are generated. Updates
170 // are triggered by the trace signal generated by the WiFi MAC model
171 // object. Here we connect the counter to the signal via the simple
172 // TxCallback() glue function defined above.
173 Ptr<CounterCalculator<uint32_t>> totalTx = CreateObject<CounterCalculator<uint32_t>>();
174 totalTx->SetKey("wifi-tx-frames");
175 totalTx->SetContext("node[0]");
176 Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
177 MakeBoundCallback(&TxCallback, totalTx));
178 data.AddDataCalculator(totalTx);
179
180 // This is similar, but creates a counter to track how many frames
181 // are received. Instead of our own glue function, this uses a
182 // method of an adapter class to connect a counter directly to the
183 // trace signal generated by the WiFi MAC.
184 Ptr<PacketCounterCalculator> totalRx = CreateObject<PacketCounterCalculator>();
185 totalRx->SetKey("wifi-rx-frames");
186 totalRx->SetContext("node[1]");
187 Config::Connect("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
189 data.AddDataCalculator(totalRx);
190
191 // This counter tracks how many packets---as opposed to frames---are
192 // generated. This is connected directly to a trace signal provided
193 // by our Sender class.
194 Ptr<PacketCounterCalculator> appTx = CreateObject<PacketCounterCalculator>();
195 appTx->SetKey("sender-tx-packets");
196 appTx->SetContext("node[0]");
197 Config::Connect("/NodeList/0/ApplicationList/*/$Sender/Tx",
199 data.AddDataCalculator(appTx);
200
201 // Here a counter for received packets is directly manipulated by
202 // one of the custom objects in our simulation, the Receiver
203 // Application. The Receiver object is given a pointer to the
204 // counter and calls its Update() method whenever a packet arrives.
205 Ptr<CounterCalculator<>> appRx = CreateObject<CounterCalculator<>>();
206 appRx->SetKey("receiver-rx-packets");
207 appRx->SetContext("node[1]");
208 receiver->SetCounter(appRx);
209 data.AddDataCalculator(appRx);
210
211 // Just to show this is here...
212
213 /*
214 Ptr<MinMaxAvgTotalCalculator<uint32_t>> test =
215 CreateObject<MinMaxAvgTotalCalculator<uint32_t>>();
216 test->SetKey("test-dc");
217 data.AddDataCalculator(test);
218
219 test->Update(4);
220 test->Update(8);
221 test->Update(24);
222 test->Update(12);
223 */
224
225 // This DataCalculator connects directly to the transmit trace
226 // provided by our Sender Application. It records some basic
227 // statistics about the sizes of the packets received (min, max,
228 // avg, total # bytes), although in this scenario they're fixed.
230 CreateObject<PacketSizeMinMaxAvgTotalCalculator>();
231 appTxPkts->SetKey("tx-pkt-size");
232 appTxPkts->SetContext("node[0]");
233 Config::Connect("/NodeList/0/ApplicationList/*/$Sender/Tx",
235 data.AddDataCalculator(appTxPkts);
236
237 // Here we directly manipulate another DataCollector tracking min,
238 // max, total, and average propagation delays. Check out the Sender
239 // and Receiver classes to see how packets are tagged with
240 // timestamps to do this.
241 Ptr<TimeMinMaxAvgTotalCalculator> delayStat = CreateObject<TimeMinMaxAvgTotalCalculator>();
242 delayStat->SetKey("delay");
243 delayStat->SetContext(".");
244 receiver->SetDelayTracker(delayStat);
245 data.AddDataCalculator(delayStat);
246
247 //--------------------------------------------
248 //-- Run the simulation
249 //--------------------------------------------
250 NS_LOG_INFO("Run Simulation.");
252
253 //--------------------------------------------
254 //-- Generate statistics output.
255 //--------------------------------------------
256
257 // Pick an output writer based in the requested format.
258 Ptr<DataOutputInterface> output = nullptr;
259 if (format == "omnet")
260 {
261 NS_LOG_INFO("Creating omnet formatted data output.");
262 output = CreateObject<OmnetDataOutput>();
263 }
264 else if (format == "db")
265 {
266#ifdef HAVE_SQLITE3
267 NS_LOG_INFO("Creating sqlite formatted data output.");
268 output = CreateObject<SqliteDataOutput>();
269#endif
270 }
271 else
272 {
273 NS_LOG_ERROR("Unknown output format " << format);
274 }
275
276 // Finally, have that writer interrogate the DataCollector and save
277 // the results.
278 if (output)
279 {
280 output->Output(data);
281 }
282
283 // Free any memory here at the end of this example.
285
286 return 0;
287}
Parse command-line arguments.
Definition: command-line.h:232
Template class CounterCalculator.
Collects data.
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...
AttributeValue implementation for Ipv4Address.
Helper class used to assign positions and mobility models to nodes.
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.
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:251
void PacketUpdate(std::string path, Ptr< const Packet > packet)
Increments the packet counter by one.
void PacketUpdate(std::string path, Ptr< const Packet > packet)
Increments the packet stats by the size of the packet.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
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)
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:876
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#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
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1325
NodeContainer nodes
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
ns cmd
Definition: second.py:33
ns wifi
Definition: third.py:88
ns mobility
Definition: third.py:96
uint8_t data[writeSize]
void TxCallback(Ptr< CounterCalculator< uint32_t > > datac, std::string path, Ptr< const Packet > packet)
Function called when a packet is transmitted.