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
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",
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
131 wifiApNode.Create(1);
132
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 {
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
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
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",
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");
572
575
576 /* Setting applications */
577 uint16_t port = 9;
579 ApplicationContainer serverApp = server.Install(wifiStaNode.Get(0));
580 serverApp.Start(Seconds(0));
581 serverApp.Stop(simulationTime + Seconds(1));
582 const auto packetInterval = payloadSize * 8.0 / (datarate * 1e6);
583
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));
590 clientApp.Stop(simulationTime + Seconds(1));
591
592 if (enablePcap)
593 {
594 auto& phy =
595 (wifiType == "ns3::YansWifiPhy" ? dynamic_cast<WifiPhyHelper&>(yansPhy)
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));
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.
AttributeValue implementation for Boolean.
Definition boolean.h:26
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.
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
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.
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
AttributeValue implementation for Time.
Definition nstime.h:1431
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
@ 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.
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 > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
@ 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.
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