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...
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: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:1344
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.