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