A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-spectrum-per-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 MIRKO BANCHI
3 * Copyright (c) 2015 University of Washington
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Authors: Mirko Banchi <mk.banchi@gmail.com>
8 * Sebastien Deronne <sebastien.deronne@gmail.com>
9 * Tom Henderson <tomhend@u.washington.edu>
10 *
11 * Adapted from wifi-ht-network.cc example
12 */
13
14#include "ns3/boolean.h"
15#include "ns3/command-line.h"
16#include "ns3/config.h"
17#include "ns3/double.h"
18#include "ns3/internet-stack-helper.h"
19#include "ns3/ipv4-address-helper.h"
20#include "ns3/ipv4-global-routing-helper.h"
21#include "ns3/log.h"
22#include "ns3/mobility-helper.h"
23#include "ns3/multi-model-spectrum-channel.h"
24#include "ns3/on-off-helper.h"
25#include "ns3/packet-sink-helper.h"
26#include "ns3/packet-sink.h"
27#include "ns3/propagation-loss-model.h"
28#include "ns3/spectrum-wifi-helper.h"
29#include "ns3/ssid.h"
30#include "ns3/string.h"
31#include "ns3/udp-client-server-helper.h"
32#include "ns3/udp-server.h"
33#include "ns3/uinteger.h"
34#include "ns3/yans-wifi-channel.h"
35#include "ns3/yans-wifi-helper.h"
36
37#include <iomanip>
38
39// This is a simple example of an IEEE 802.11n Wi-Fi network.
40//
41// The main use case is to enable and test SpectrumWifiPhy vs YansWifiPhy
42// for packet error ratio
43//
44// Network topology:
45//
46// Wi-Fi 192.168.1.0
47//
48// STA AP
49// * <-- distance --> *
50// | |
51// n1 n2
52//
53// Users may vary the following command-line arguments in addition to the
54// attributes, global values, and default values typically available:
55//
56// --simulationTime: Simulation time [10s]
57// --udp: UDP if set to 1, TCP otherwise [true]
58// --distance: meters separation between nodes [50]
59// --index: restrict index to single value between 0 and 31 [256]
60// --wifiType: select ns3::SpectrumWifiPhy or ns3::YansWifiPhy [ns3::SpectrumWifiPhy]
61// --errorModelType: select ns3::NistErrorRateModel or ns3::YansErrorRateModel
62// [ns3::NistErrorRateModel]
63// --enablePcap: enable pcap output [false]
64//
65// By default, the program will step through 32 index values, corresponding
66// to the following MCS, channel width, and guard interval combinations:
67// index 0-7: MCS 0-7, long guard interval, 20 MHz channel
68// index 8-15: MCS 0-7, short guard interval, 20 MHz channel
69// index 16-23: MCS 0-7, long guard interval, 40 MHz channel
70// index 24-31: MCS 0-7, short guard interval, 40 MHz channel
71// and send UDP for 10 seconds using each MCS, using the SpectrumWifiPhy and the
72// NistErrorRateModel, at a distance of 50 meters. The program outputs
73// results such as:
74//
75// wifiType: ns3::SpectrumWifiPhy distance: 50m; time: 10; TxPower: 1 dBm (1.3 mW)
76// index MCS Rate (Mb/s) Tput (Mb/s) Received Signal (dBm) Noise (dBm) SNR (dB)
77// 0 0 6.50 5.77 7414 -79.71 -93.97 14.25
78// 1 1 13.00 11.58 14892 -79.71 -93.97 14.25
79// 2 2 19.50 17.39 22358 -79.71 -93.97 14.25
80// 3 3 26.00 22.96 29521 -79.71 -93.97 14.25
81// ...
82//
83
84using namespace ns3;
85
86// Global variables for use in callbacks.
87double g_signalDbmAvg; //!< Average signal power [dBm]
88double g_noiseDbmAvg; //!< Average noise power [dBm]
89uint32_t g_samples; //!< Number of samples
90
91/**
92 * Monitor sniffer Rx trace
93 *
94 * \param packet The sensed packet.
95 * \param channelFreqMhz The channel frequency [MHz].
96 * \param txVector The Tx vector.
97 * \param aMpdu The aMPDU.
98 * \param signalNoise The signal and noise dBm.
99 * \param staId The STA ID.
100 */
101void
103 uint16_t channelFreqMhz,
104 WifiTxVector txVector,
105 MpduInfo aMpdu,
106 SignalNoiseDbm signalNoise,
107 uint16_t staId)
108
109{
110 g_samples++;
111 g_signalDbmAvg += ((signalNoise.signal - g_signalDbmAvg) / g_samples);
112 g_noiseDbmAvg += ((signalNoise.noise - g_noiseDbmAvg) / g_samples);
113}
114
115NS_LOG_COMPONENT_DEFINE("WifiSpectrumPerExample");
116
117int
118main(int argc, char* argv[])
119{
120 bool udp{true};
121 meter_u distance{50};
122 Time simulationTime{"10s"};
123 uint16_t index{256};
124 std::string wifiType{"ns3::SpectrumWifiPhy"};
125 std::string errorModelType{"ns3::NistErrorRateModel"};
126 bool enablePcap{false};
127 const uint32_t tcpPacketSize{1448};
128
129 CommandLine cmd(__FILE__);
130 cmd.AddValue("simulationTime", "Simulation time", simulationTime);
131 cmd.AddValue("udp", "UDP if set to 1, TCP otherwise", udp);
132 cmd.AddValue("distance", "meters separation between nodes", distance);
133 cmd.AddValue("index", "restrict index to single value between 0 and 31", index);
134 cmd.AddValue("wifiType", "select ns3::SpectrumWifiPhy or ns3::YansWifiPhy", wifiType);
135 cmd.AddValue("errorModelType",
136 "select ns3::NistErrorRateModel or ns3::YansErrorRateModel",
137 errorModelType);
138 cmd.AddValue("enablePcap", "enable pcap output", enablePcap);
139 cmd.Parse(argc, argv);
140
141 uint16_t startIndex = 0;
142 uint16_t stopIndex = 31;
143 if (index < 32)
144 {
145 startIndex = index;
146 stopIndex = index;
147 }
148
149 std::cout << "wifiType: " << wifiType << " distance: " << distance
150 << "m; time: " << simulationTime << "; TxPower: 1 dBm (1.3 mW)" << std::endl;
151 std::cout << std::setw(5) << "index" << std::setw(6) << "MCS" << std::setw(13) << "Rate (Mb/s)"
152 << std::setw(12) << "Tput (Mb/s)" << std::setw(10) << "Received " << std::setw(12)
153 << "Signal (dBm)" << std::setw(12) << "Noise (dBm)" << std::setw(9) << "SNR (dB)"
154 << std::endl;
155 for (uint16_t i = startIndex; i <= stopIndex; i++)
156 {
157 uint32_t payloadSize;
158 if (udp)
159 {
160 payloadSize = 972; // 1000 bytes IPv4
161 }
162 else
163 {
164 payloadSize = 1448; // 1500 bytes IPv6
165 Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(payloadSize));
166 }
167
168 NodeContainer wifiStaNode;
169 wifiStaNode.Create(1);
171 wifiApNode.Create(1);
172
173 YansWifiPhyHelper yansPhy;
174 SpectrumWifiPhyHelper spectrumPhy;
175 if (wifiType == "ns3::YansWifiPhy")
176 {
178 channel.AddPropagationLoss("ns3::FriisPropagationLossModel",
179 "Frequency",
180 DoubleValue(5.180e9));
181 channel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
182 yansPhy.SetChannel(channel.Create());
183 yansPhy.Set("TxPowerStart", DoubleValue(1)); // dBm (1.26 mW)
184 yansPhy.Set("TxPowerEnd", DoubleValue(1));
185 }
186 else if (wifiType == "ns3::SpectrumWifiPhy")
187 {
188 Ptr<MultiModelSpectrumChannel> spectrumChannel =
191 lossModel->SetFrequency(5.180e9);
192 spectrumChannel->AddPropagationLossModel(lossModel);
193
196 spectrumChannel->SetPropagationDelayModel(delayModel);
197
198 spectrumPhy.SetChannel(spectrumChannel);
199 spectrumPhy.SetErrorRateModel(errorModelType);
200 spectrumPhy.Set("TxPowerStart", DoubleValue(1)); // dBm (1.26 mW)
201 spectrumPhy.Set("TxPowerEnd", DoubleValue(1));
202 }
203 else
204 {
205 NS_FATAL_ERROR("Unsupported WiFi type " << wifiType);
206 }
207
209 wifi.SetStandard(WIFI_STANDARD_80211n);
211
212 Ssid ssid = Ssid("ns380211n");
213
214 double datarate = 0;
216 if (i == 0)
217 {
218 DataRate = StringValue("HtMcs0");
219 datarate = 6.5;
220 }
221 else if (i == 1)
222 {
223 DataRate = StringValue("HtMcs1");
224 datarate = 13;
225 }
226 else if (i == 2)
227 {
228 DataRate = StringValue("HtMcs2");
229 datarate = 19.5;
230 }
231 else if (i == 3)
232 {
233 DataRate = StringValue("HtMcs3");
234 datarate = 26;
235 }
236 else if (i == 4)
237 {
238 DataRate = StringValue("HtMcs4");
239 datarate = 39;
240 }
241 else if (i == 5)
242 {
243 DataRate = StringValue("HtMcs5");
244 datarate = 52;
245 }
246 else if (i == 6)
247 {
248 DataRate = StringValue("HtMcs6");
249 datarate = 58.5;
250 }
251 else if (i == 7)
252 {
253 DataRate = StringValue("HtMcs7");
254 datarate = 65;
255 }
256 else if (i == 8)
257 {
258 DataRate = StringValue("HtMcs0");
259 datarate = 7.2;
260 }
261 else if (i == 9)
262 {
263 DataRate = StringValue("HtMcs1");
264 datarate = 14.4;
265 }
266 else if (i == 10)
267 {
268 DataRate = StringValue("HtMcs2");
269 datarate = 21.7;
270 }
271 else if (i == 11)
272 {
273 DataRate = StringValue("HtMcs3");
274 datarate = 28.9;
275 }
276 else if (i == 12)
277 {
278 DataRate = StringValue("HtMcs4");
279 datarate = 43.3;
280 }
281 else if (i == 13)
282 {
283 DataRate = StringValue("HtMcs5");
284 datarate = 57.8;
285 }
286 else if (i == 14)
287 {
288 DataRate = StringValue("HtMcs6");
289 datarate = 65;
290 }
291 else if (i == 15)
292 {
293 DataRate = StringValue("HtMcs7");
294 datarate = 72.2;
295 }
296 else if (i == 16)
297 {
298 DataRate = StringValue("HtMcs0");
299 datarate = 13.5;
300 }
301 else if (i == 17)
302 {
303 DataRate = StringValue("HtMcs1");
304 datarate = 27;
305 }
306 else if (i == 18)
307 {
308 DataRate = StringValue("HtMcs2");
309 datarate = 40.5;
310 }
311 else if (i == 19)
312 {
313 DataRate = StringValue("HtMcs3");
314 datarate = 54;
315 }
316 else if (i == 20)
317 {
318 DataRate = StringValue("HtMcs4");
319 datarate = 81;
320 }
321 else if (i == 21)
322 {
323 DataRate = StringValue("HtMcs5");
324 datarate = 108;
325 }
326 else if (i == 22)
327 {
328 DataRate = StringValue("HtMcs6");
329 datarate = 121.5;
330 }
331 else if (i == 23)
332 {
333 DataRate = StringValue("HtMcs7");
334 datarate = 135;
335 }
336 else if (i == 24)
337 {
338 DataRate = StringValue("HtMcs0");
339 datarate = 15;
340 }
341 else if (i == 25)
342 {
343 DataRate = StringValue("HtMcs1");
344 datarate = 30;
345 }
346 else if (i == 26)
347 {
348 DataRate = StringValue("HtMcs2");
349 datarate = 45;
350 }
351 else if (i == 27)
352 {
353 DataRate = StringValue("HtMcs3");
354 datarate = 60;
355 }
356 else if (i == 28)
357 {
358 DataRate = StringValue("HtMcs4");
359 datarate = 90;
360 }
361 else if (i == 29)
362 {
363 DataRate = StringValue("HtMcs5");
364 datarate = 120;
365 }
366 else if (i == 30)
367 {
368 DataRate = StringValue("HtMcs6");
369 datarate = 135;
370 }
371 else
372 {
373 DataRate = StringValue("HtMcs7");
374 datarate = 150;
375 }
376
377 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
378 "DataMode",
379 DataRate,
380 "ControlMode",
381 DataRate);
382
383 NetDeviceContainer staDevice;
384 NetDeviceContainer apDevice;
385
386 if (wifiType == "ns3::YansWifiPhy")
387 {
388 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
389 yansPhy.Set(
390 "ChannelSettings",
391 StringValue(std::string("{0, ") + (i <= 15 ? "20" : "40") + ", BAND_5GHZ, 0}"));
392 staDevice = wifi.Install(yansPhy, mac, wifiStaNode);
393 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
394 apDevice = wifi.Install(yansPhy, mac, wifiApNode);
395 }
396 else if (wifiType == "ns3::SpectrumWifiPhy")
397 {
398 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
399 spectrumPhy.Set(
400 "ChannelSettings",
401 StringValue(std::string("{0, ") + (i <= 15 ? "20" : "40") + ", BAND_5GHZ, 0}"));
402 staDevice = wifi.Install(spectrumPhy, mac, wifiStaNode);
403 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
404 apDevice = wifi.Install(spectrumPhy, mac, wifiApNode);
405 }
406
407 bool shortGuardIntervalSupported = (i > 7 && i <= 15) || (i > 23);
408 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/"
409 "ShortGuardIntervalSupported",
410 BooleanValue(shortGuardIntervalSupported));
411
412 // mobility.
415
416 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
417 positionAlloc->Add(Vector(distance, 0.0, 0.0));
418 mobility.SetPositionAllocator(positionAlloc);
419
420 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
421
422 mobility.Install(wifiApNode);
423 mobility.Install(wifiStaNode);
424
425 /* Internet stack*/
427 stack.Install(wifiApNode);
428 stack.Install(wifiStaNode);
429
431 address.SetBase("192.168.1.0", "255.255.255.0");
432 Ipv4InterfaceContainer staNodeInterface;
433 Ipv4InterfaceContainer apNodeInterface;
434
435 staNodeInterface = address.Assign(staDevice);
436 apNodeInterface = address.Assign(apDevice);
437
438 /* Setting applications */
439 ApplicationContainer serverApp;
440 if (udp)
441 {
442 // UDP flow
443 uint16_t port = 9;
445 serverApp = server.Install(wifiStaNode.Get(0));
446 serverApp.Start(Seconds(0.0));
447 serverApp.Stop(simulationTime + Seconds(1.0));
448 const auto packetInterval = payloadSize * 8.0 / (datarate * 1e6);
449
450 UdpClientHelper client(staNodeInterface.GetAddress(0), port);
451 client.SetAttribute("MaxPackets", UintegerValue(4294967295U));
452 client.SetAttribute("Interval", TimeValue(Seconds(packetInterval)));
453 client.SetAttribute("PacketSize", UintegerValue(payloadSize));
454 ApplicationContainer clientApp = client.Install(wifiApNode.Get(0));
455 clientApp.Start(Seconds(1.0));
456 clientApp.Stop(simulationTime + Seconds(1.0));
457 }
458 else
459 {
460 // TCP flow
461 uint16_t port = 50000;
463 PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory", localAddress);
464 serverApp = packetSinkHelper.Install(wifiStaNode.Get(0));
465 serverApp.Start(Seconds(0.0));
466 serverApp.Stop(simulationTime + Seconds(1.0));
467
468 OnOffHelper onoff("ns3::TcpSocketFactory", Ipv4Address::GetAny());
469 onoff.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
470 onoff.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]"));
471 onoff.SetAttribute("PacketSize", UintegerValue(payloadSize));
472 onoff.SetAttribute("DataRate", DataRateValue(datarate * 1e6));
474 onoff.SetAttribute("Remote", remoteAddress);
475 ApplicationContainer clientApp = onoff.Install(wifiApNode.Get(0));
476 clientApp.Start(Seconds(1.0));
477 clientApp.Stop(simulationTime + Seconds(1.0));
478 }
479
480 Config::ConnectWithoutContext("/NodeList/0/DeviceList/*/Phy/MonitorSnifferRx",
482
483 if (enablePcap)
484 {
485 auto& phy = wifiType == "ns3::YansWifiPhy" ? dynamic_cast<WifiPhyHelper&>(yansPhy)
486 : dynamic_cast<WifiPhyHelper&>(spectrumPhy);
487
488 phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
489 std::stringstream ss;
490 ss << "wifi-spectrum-per-example-" << i;
491 phy.EnablePcap(ss.str(), apDevice);
492 }
493
494 g_signalDbmAvg = 0;
495 g_noiseDbmAvg = 0;
496 g_samples = 0;
497
498 Simulator::Stop(simulationTime + Seconds(1.0));
500
501 auto throughput = 0.0;
502 uint64_t totalPacketsThrough = 0;
503 if (udp)
504 {
505 // UDP
506 totalPacketsThrough = DynamicCast<UdpServer>(serverApp.Get(0))->GetReceived();
507 throughput =
508 totalPacketsThrough * payloadSize * 8 / simulationTime.GetMicroSeconds(); // Mbit/s
509 }
510 else
511 {
512 // TCP
513 auto totalBytesRx = DynamicCast<PacketSink>(serverApp.Get(0))->GetTotalRx();
514 totalPacketsThrough = static_cast<uint64_t>(totalBytesRx / tcpPacketSize);
515 throughput = totalBytesRx * 8 / simulationTime.GetMicroSeconds(); // Mbit/s
516 }
517 std::cout << std::setw(5) << i << std::setw(6) << (i % 8) << std::setprecision(2)
518 << std::fixed << std::setw(10) << datarate << std::setw(12) << throughput
519 << std::setw(8) << totalPacketsThrough;
520 if (totalPacketsThrough > 0)
521 {
522 std::cout << std::setw(12) << g_signalDbmAvg << std::setw(12) << g_noiseDbmAvg
523 << std::setw(12) << (g_signalDbmAvg - g_noiseDbmAvg) << std::endl;
524 }
525 else
526 {
527 std::cout << std::setw(12) << "N/A" << std::setw(12) << "N/A" << std::setw(12) << "N/A"
528 << std::endl;
529 }
531 }
532 return 0;
533}
a polymophic address class
Definition address.h:90
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Parse command-line arguments.
Class for representing data rates.
Definition data-rate.h:78
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
static Ipv4Address GetAny()
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
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.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
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
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(const Ptr< SpectrumChannel > channel)
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Create a client application which sends UDP packets carrying a 32bit sequence number and a 64 bit tim...
Create a server application which waits for input UDP packets and uses the information carried into t...
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
create MAC layers for a ns3::WifiNetDevice.
create PHY objects
Definition wifi-helper.h:39
void Set(std::string name, const AttributeValue &v)
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
manage and create wifi channel objects for the YANS model.
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
uint16_t port
Definition dsdv-manet.cc:33
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:943
void Set(std::string path, const AttributeValue &value)
Definition config.cc:869
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
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
@ WIFI_STANDARD_80211n
address
Definition first.py:36
stack
Definition first.py:33
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
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
ssid
Definition third.py:82
channel
Definition third.py:77
mac
Definition third.py:81
wifi
Definition third.py:84
wifiApNode
Definition third.py:75
mobility
Definition third.py:92
phy
Definition third.py:78
MpduInfo structure.
Definition wifi-types.h:65
SignalNoiseDbm structure.
Definition wifi-types.h:58
dBm_u noise
noise power
Definition wifi-types.h:60
dBm_u signal
signal strength
Definition wifi-types.h:59
std::ofstream throughput
double g_signalDbmAvg
Average signal power [dBm].
double g_noiseDbmAvg
Average noise power [dBm].
uint32_t g_samples
Number of samples.
void MonitorSniffRx(Ptr< const Packet > packet, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
Monitor sniffer Rx trace.