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
48/**
49 * Function called when a packet is transmitted.
50 *
51 * \param datac The counter of the number of transmitted packets.
52 * \param path The callback context.
53 * \param packet The transmitted packet.
54 */
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.
Definition: ipv4-address.h:341
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:77
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
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:978
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:880
#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:767
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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:706
ns cmd
Definition: second.py:40
ns wifi
Definition: third.py:95
ns mobility
Definition: third.py:105
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.