A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-spectrum-saturation-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/log.h"
21#include "ns3/mobility-helper.h"
22#include "ns3/multi-model-spectrum-channel.h"
23#include "ns3/propagation-loss-model.h"
24#include "ns3/spectrum-wifi-helper.h"
25#include "ns3/ssid.h"
26#include "ns3/string.h"
27#include "ns3/udp-client-server-helper.h"
28#include "ns3/udp-server.h"
29#include "ns3/uinteger.h"
30#include "ns3/yans-wifi-channel.h"
31#include "ns3/yans-wifi-helper.h"
32
33#include <iomanip>
34
35// This is a simple example of an IEEE 802.11n Wi-Fi network.
36//
37// The main use case is to enable and test SpectrumWifiPhy vs YansWifiPhy
38// under saturation conditions (for max throughput).
39//
40// Network topology:
41//
42// Wi-Fi 192.168.1.0
43//
44// STA AP
45// * <-- distance --> *
46// | |
47// n1 n2
48//
49// Users may vary the following command-line arguments in addition to the
50// attributes, global values, and default values typically available:
51//
52// --simulationTime: Simulation time [10s]
53// --distance: meters separation between nodes [1]
54// --index: restrict index to single value between 0 and 31 [256]
55// --wifiType: select ns3::SpectrumWifiPhy or ns3::YansWifiPhy [ns3::SpectrumWifiPhy]
56// --errorModelType: select ns3::NistErrorRateModel or ns3::YansErrorRateModel
57// [ns3::NistErrorRateModel]
58// --enablePcap: enable pcap output [false]
59//
60// By default, the program will step through 64 index values, corresponding
61// to the following MCS, channel width, and guard interval combinations:
62// index 0-7: MCS 0-7, long guard interval, 20 MHz channel
63// index 8-15: MCS 0-7, short guard interval, 20 MHz channel
64// index 16-23: MCS 0-7, long guard interval, 40 MHz channel
65// index 24-31: MCS 0-7, short guard interval, 40 MHz channel
66// index 32-39: MCS 8-15, long guard interval, 20 MHz channel
67// index 40-47: MCS 8-15, short guard interval, 20 MHz channel
68// index 48-55: MCS 8-15, long guard interval, 40 MHz channel
69// index 56-63: MCS 8-15, short guard interval, 40 MHz channel
70// and send packets at a high rate using each MCS, using the SpectrumWifiPhy
71// and the NistErrorRateModel, at a distance of 1 meter. The program outputs
72// results such as:
73//
74// wifiType: ns3::SpectrumWifiPhy distance: 1m
75// index MCS width Rate (Mb/s) Tput (Mb/s) Received
76// 0 0 20 6.5 5.96219 5063
77// 1 1 20 13 11.9491 10147
78// 2 2 20 19.5 17.9184 15216
79// 3 3 20 26 23.9253 20317
80// ...
81//
82// selection of index values 32-63 will result in MCS selection 8-15
83// involving two spatial streams
84
85using namespace ns3;
86
87NS_LOG_COMPONENT_DEFINE("WifiSpectrumSaturationExample");
88
89int
90main(int argc, char* argv[])
91{
92 meter_u distance{1};
93 Time simulationTime{"10s"};
94 uint16_t index{256};
95 uint32_t channelWidth{0};
96 std::string wifiType{"ns3::SpectrumWifiPhy"};
97 std::string errorModelType{"ns3::NistErrorRateModel"};
98 bool enablePcap{false};
99
100 CommandLine cmd(__FILE__);
101 cmd.AddValue("simulationTime", "Simulation time", simulationTime);
102 cmd.AddValue("distance", "meters separation between nodes", distance);
103 cmd.AddValue("index", "restrict index to single value between 0 and 63", index);
104 cmd.AddValue("wifiType", "select ns3::SpectrumWifiPhy or ns3::YansWifiPhy", wifiType);
105 cmd.AddValue("errorModelType",
106 "select ns3::NistErrorRateModel or ns3::YansErrorRateModel",
107 errorModelType);
108 cmd.AddValue("enablePcap", "enable pcap output", enablePcap);
109 cmd.Parse(argc, argv);
110
111 uint16_t startIndex = 0;
112 uint16_t stopIndex = 63;
113 if (index < 64)
114 {
115 startIndex = index;
116 stopIndex = index;
117 }
118
119 std::cout << "wifiType: " << wifiType << " distance: " << distance << "m" << std::endl;
120 std::cout << std::setw(5) << "index" << std::setw(6) << "MCS" << std::setw(8) << "width"
121 << std::setw(12) << "Rate (Mb/s)" << std::setw(12) << "Tput (Mb/s)" << std::setw(10)
122 << "Received " << std::endl;
123 for (uint16_t i = startIndex; i <= stopIndex; i++)
124 {
125 uint32_t payloadSize;
126 payloadSize = 1472; // 1500 bytes IPv4
127
128 NodeContainer wifiStaNode;
129 wifiStaNode.Create(1);
131 wifiApNode.Create(1);
132
133 YansWifiPhyHelper yansPhy;
134 SpectrumWifiPhyHelper spectrumPhy;
135 if (wifiType == "ns3::YansWifiPhy")
136 {
138 channel.AddPropagationLoss("ns3::FriisPropagationLossModel");
139 channel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
140 yansPhy.SetChannel(channel.Create());
141 yansPhy.Set("TxPowerStart", DoubleValue(1));
142 yansPhy.Set("TxPowerEnd", DoubleValue(1));
143
144 if (i > 31 && i <= 63)
145 {
146 yansPhy.Set("Antennas", UintegerValue(2));
147 yansPhy.Set("MaxSupportedTxSpatialStreams", UintegerValue(2));
148 yansPhy.Set("MaxSupportedRxSpatialStreams", UintegerValue(2));
149 }
150 }
151 else if (wifiType == "ns3::SpectrumWifiPhy")
152 {
153 Ptr<MultiModelSpectrumChannel> spectrumChannel =
156 spectrumChannel->AddPropagationLossModel(lossModel);
157
160 spectrumChannel->SetPropagationDelayModel(delayModel);
161
162 spectrumPhy.SetChannel(spectrumChannel);
163 spectrumPhy.SetErrorRateModel(errorModelType);
164 spectrumPhy.Set("TxPowerStart", DoubleValue(1));
165 spectrumPhy.Set("TxPowerEnd", DoubleValue(1));
166
167 if (i > 31 && i <= 63)
168 {
169 spectrumPhy.Set("Antennas", UintegerValue(2));
170 spectrumPhy.Set("MaxSupportedTxSpatialStreams", UintegerValue(2));
171 spectrumPhy.Set("MaxSupportedRxSpatialStreams", UintegerValue(2));
172 }
173 }
174 else
175 {
176 NS_FATAL_ERROR("Unsupported WiFi type " << wifiType);
177 }
178
180 wifi.SetStandard(WIFI_STANDARD_80211n);
182
183 Ssid ssid = Ssid("ns380211n");
184
185 double datarate = 0;
187 if (i == 0)
188 {
189 DataRate = StringValue("HtMcs0");
190 datarate = 6.5;
191 }
192 else if (i == 1)
193 {
194 DataRate = StringValue("HtMcs1");
195 datarate = 13;
196 }
197 else if (i == 2)
198 {
199 DataRate = StringValue("HtMcs2");
200 datarate = 19.5;
201 }
202 else if (i == 3)
203 {
204 DataRate = StringValue("HtMcs3");
205 datarate = 26;
206 }
207 else if (i == 4)
208 {
209 DataRate = StringValue("HtMcs4");
210 datarate = 39;
211 }
212 else if (i == 5)
213 {
214 DataRate = StringValue("HtMcs5");
215 datarate = 52;
216 }
217 else if (i == 6)
218 {
219 DataRate = StringValue("HtMcs6");
220 datarate = 58.5;
221 }
222 else if (i == 7)
223 {
224 DataRate = StringValue("HtMcs7");
225 datarate = 65;
226 }
227 else if (i == 8)
228 {
229 DataRate = StringValue("HtMcs0");
230 datarate = 7.2;
231 }
232 else if (i == 9)
233 {
234 DataRate = StringValue("HtMcs1");
235 datarate = 14.4;
236 }
237 else if (i == 10)
238 {
239 DataRate = StringValue("HtMcs2");
240 datarate = 21.7;
241 }
242 else if (i == 11)
243 {
244 DataRate = StringValue("HtMcs3");
245 datarate = 28.9;
246 }
247 else if (i == 12)
248 {
249 DataRate = StringValue("HtMcs4");
250 datarate = 43.3;
251 }
252 else if (i == 13)
253 {
254 DataRate = StringValue("HtMcs5");
255 datarate = 57.8;
256 }
257 else if (i == 14)
258 {
259 DataRate = StringValue("HtMcs6");
260 datarate = 65;
261 }
262 else if (i == 15)
263 {
264 DataRate = StringValue("HtMcs7");
265 datarate = 72.2;
266 }
267 else if (i == 16)
268 {
269 DataRate = StringValue("HtMcs0");
270 datarate = 13.5;
271 }
272 else if (i == 17)
273 {
274 DataRate = StringValue("HtMcs1");
275 datarate = 27;
276 }
277 else if (i == 18)
278 {
279 DataRate = StringValue("HtMcs2");
280 datarate = 40.5;
281 }
282 else if (i == 19)
283 {
284 DataRate = StringValue("HtMcs3");
285 datarate = 54;
286 }
287 else if (i == 20)
288 {
289 DataRate = StringValue("HtMcs4");
290 datarate = 81;
291 }
292 else if (i == 21)
293 {
294 DataRate = StringValue("HtMcs5");
295 datarate = 108;
296 }
297 else if (i == 22)
298 {
299 DataRate = StringValue("HtMcs6");
300 datarate = 121.5;
301 }
302 else if (i == 23)
303 {
304 DataRate = StringValue("HtMcs7");
305 datarate = 135;
306 }
307 else if (i == 24)
308 {
309 DataRate = StringValue("HtMcs0");
310 datarate = 15;
311 }
312 else if (i == 25)
313 {
314 DataRate = StringValue("HtMcs1");
315 datarate = 30;
316 }
317 else if (i == 26)
318 {
319 DataRate = StringValue("HtMcs2");
320 datarate = 45;
321 }
322 else if (i == 27)
323 {
324 DataRate = StringValue("HtMcs3");
325 datarate = 60;
326 }
327 else if (i == 28)
328 {
329 DataRate = StringValue("HtMcs4");
330 datarate = 90;
331 }
332 else if (i == 29)
333 {
334 DataRate = StringValue("HtMcs5");
335 datarate = 120;
336 }
337 else if (i == 30)
338 {
339 DataRate = StringValue("HtMcs6");
340 datarate = 135;
341 }
342 else if (i == 31)
343 {
344 DataRate = StringValue("HtMcs7");
345 datarate = 150;
346 }
347 else if (i == 32)
348 {
349 DataRate = StringValue("HtMcs8");
350 datarate = 13;
351 }
352 else if (i == 33)
353 {
354 DataRate = StringValue("HtMcs9");
355 datarate = 26;
356 }
357 else if (i == 34)
358 {
359 DataRate = StringValue("HtMcs10");
360 datarate = 39;
361 }
362 else if (i == 35)
363 {
364 DataRate = StringValue("HtMcs11");
365 datarate = 52;
366 }
367 else if (i == 36)
368 {
369 DataRate = StringValue("HtMcs12");
370 datarate = 78;
371 }
372 else if (i == 37)
373 {
374 DataRate = StringValue("HtMcs13");
375 datarate = 104;
376 }
377 else if (i == 38)
378 {
379 DataRate = StringValue("HtMcs14");
380 datarate = 117;
381 }
382 else if (i == 39)
383 {
384 DataRate = StringValue("HtMcs15");
385 datarate = 130;
386 }
387 else if (i == 40)
388 {
389 DataRate = StringValue("HtMcs8");
390 datarate = 14.4;
391 }
392 else if (i == 41)
393 {
394 DataRate = StringValue("HtMcs9");
395 datarate = 28.9;
396 }
397 else if (i == 42)
398 {
399 DataRate = StringValue("HtMcs10");
400 datarate = 43.3;
401 }
402 else if (i == 43)
403 {
404 DataRate = StringValue("HtMcs11");
405 datarate = 57.8;
406 }
407 else if (i == 44)
408 {
409 DataRate = StringValue("HtMcs12");
410 datarate = 86.7;
411 }
412 else if (i == 45)
413 {
414 DataRate = StringValue("HtMcs13");
415 datarate = 115.6;
416 }
417 else if (i == 46)
418 {
419 DataRate = StringValue("HtMcs14");
420 datarate = 130.3;
421 }
422 else if (i == 47)
423 {
424 DataRate = StringValue("HtMcs15");
425 datarate = 144.4;
426 }
427 else if (i == 48)
428 {
429 DataRate = StringValue("HtMcs8");
430 datarate = 27;
431 }
432 else if (i == 49)
433 {
434 DataRate = StringValue("HtMcs9");
435 datarate = 54;
436 }
437 else if (i == 50)
438 {
439 DataRate = StringValue("HtMcs10");
440 datarate = 81;
441 }
442 else if (i == 51)
443 {
444 DataRate = StringValue("HtMcs11");
445 datarate = 108;
446 }
447 else if (i == 52)
448 {
449 DataRate = StringValue("HtMcs12");
450 datarate = 162;
451 }
452 else if (i == 53)
453 {
454 DataRate = StringValue("HtMcs13");
455 datarate = 216;
456 }
457 else if (i == 54)
458 {
459 DataRate = StringValue("HtMcs14");
460 datarate = 243;
461 }
462 else if (i == 55)
463 {
464 DataRate = StringValue("HtMcs15");
465 datarate = 270;
466 }
467 else if (i == 56)
468 {
469 DataRate = StringValue("HtMcs8");
470 datarate = 30;
471 }
472 else if (i == 57)
473 {
474 DataRate = StringValue("HtMcs9");
475 datarate = 60;
476 }
477 else if (i == 58)
478 {
479 DataRate = StringValue("HtMcs10");
480 datarate = 90;
481 }
482 else if (i == 59)
483 {
484 DataRate = StringValue("HtMcs11");
485 datarate = 120;
486 }
487 else if (i == 60)
488 {
489 DataRate = StringValue("HtMcs12");
490 datarate = 180;
491 }
492 else if (i == 61)
493 {
494 DataRate = StringValue("HtMcs13");
495 datarate = 240;
496 }
497 else if (i == 62)
498 {
499 DataRate = StringValue("HtMcs14");
500 datarate = 270;
501 }
502 else if (i == 63)
503 {
504 DataRate = StringValue("HtMcs15");
505 datarate = 300;
506 }
507 else
508 {
509 NS_FATAL_ERROR("Illegal index i " << i);
510 }
511
512 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
513 "DataMode",
514 DataRate,
515 "ControlMode",
516 DataRate);
517
518 NetDeviceContainer staDevice;
519 NetDeviceContainer apDevice;
520
521 channelWidth = (i <= 15 || (i > 31 && i <= 47) ? 20 : 40);
522 std::string channelStr = "{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}";
523
524 if (wifiType == "ns3::YansWifiPhy")
525 {
526 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
527 yansPhy.Set("ChannelSettings", StringValue(channelStr));
528
529 staDevice = wifi.Install(yansPhy, mac, wifiStaNode);
530 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
531 yansPhy.Set("ChannelSettings", StringValue(channelStr));
532 apDevice = wifi.Install(yansPhy, mac, wifiApNode);
533 }
534 else if (wifiType == "ns3::SpectrumWifiPhy")
535 {
536 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
537 spectrumPhy.Set("ChannelSettings", StringValue(channelStr));
538 staDevice = wifi.Install(spectrumPhy, mac, wifiStaNode);
539 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
540 spectrumPhy.Set("ChannelSettings", StringValue(channelStr));
541 apDevice = wifi.Install(spectrumPhy, mac, wifiApNode);
542 }
543
544 bool shortGuardIntervalSupported =
545 (i > 7 && i <= 15) || (i > 23 && i <= 31) || (i > 39 && i <= 47) || (i > 55);
546 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/"
547 "ShortGuardIntervalSupported",
548 BooleanValue(shortGuardIntervalSupported));
549
550 // mobility.
553
554 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
555 positionAlloc->Add(Vector(distance, 0.0, 0.0));
556 mobility.SetPositionAllocator(positionAlloc);
557
558 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
559
560 mobility.Install(wifiApNode);
561 mobility.Install(wifiStaNode);
562
563 /* Internet stack*/
565 stack.Install(wifiApNode);
566 stack.Install(wifiStaNode);
567
569 address.SetBase("192.168.1.0", "255.255.255.0");
570 Ipv4InterfaceContainer staNodeInterface;
571 Ipv4InterfaceContainer apNodeInterface;
572
573 staNodeInterface = address.Assign(staDevice);
574 apNodeInterface = address.Assign(apDevice);
575
576 /* Setting applications */
577 uint16_t port = 9;
579 ApplicationContainer serverApp = server.Install(wifiStaNode.Get(0));
580 serverApp.Start(Seconds(0.0));
581 serverApp.Stop(simulationTime + Seconds(1.0));
582 const auto packetInterval = payloadSize * 8.0 / (datarate * 1e6);
583
584 UdpClientHelper client(staNodeInterface.GetAddress(0), port);
585 client.SetAttribute("MaxPackets", UintegerValue(4294967295U));
586 client.SetAttribute("Interval", TimeValue(Seconds(packetInterval)));
587 client.SetAttribute("PacketSize", UintegerValue(payloadSize));
588 ApplicationContainer clientApp = client.Install(wifiApNode.Get(0));
589 clientApp.Start(Seconds(1.0));
590 clientApp.Stop(simulationTime + Seconds(1.0));
591
592 if (enablePcap)
593 {
594 auto& phy =
595 (wifiType == "ns3::YansWifiPhy" ? dynamic_cast<WifiPhyHelper&>(yansPhy)
596 : dynamic_cast<WifiPhyHelper&>(spectrumPhy));
597 phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
598 std::stringstream ss;
599 ss << "wifi-spectrum-saturation-example-" << i;
600 phy.EnablePcap(ss.str(), apDevice);
601 }
602
603 Simulator::Stop(simulationTime + Seconds(1.0));
605
606 double totalPacketsThrough = DynamicCast<UdpServer>(serverApp.Get(0))->GetReceived();
607 auto throughput =
608 totalPacketsThrough * payloadSize * 8 / simulationTime.GetMicroSeconds(); // Mbit/s
609 std::cout << std::setw(5) << i << std::setw(6) << (i % 8) + 8 * (i / 32) << std::setw(8)
610 << channelWidth << std::setw(10) << datarate << std::setw(12) << throughput
611 << std::setw(8) << totalPacketsThrough << std::endl;
613 }
614 return 0;
615}
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
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
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.
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.
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 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.
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
std::ofstream throughput