A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-manager-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Tom Henderson <tomhend@u.washington.edu>
7 * Matías Richart <mrichart@fing.edu.uy>
8 * Sébastien Deronne <sebastien.deronne@gmail.com>
9 */
10
11// Test the operation of a wifi manager as the SNR is varied, and create
12// a gnuplot output file for plotting.
13//
14// The test consists of a device acting as server and a device as client generating traffic.
15//
16// The output consists of a plot of the rate observed and selected at the client device.
17// A special FixedRss propagation loss model is used to set a specific receive
18// power on the receiver. The noise power is exclusively the thermal noise
19// for the channel bandwidth (no noise figure is configured). Furthermore,
20// the CCA sensitivity attribute in WifiPhy can prevent signals from being
21// received even though the error model would permit it. Therefore, for
22// the purpose of this example, the CCA sensitivity is lowered to a value
23// that disables it, and furthermore, the preamble detection model (which
24// also contains a similar threshold) is disabled.
25//
26// By default, the 802.11a standard using IdealWifiManager is plotted. Several command line
27// arguments can change the following options:
28// --wifiManager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa,
29// ThompsonSampling)
30// --standard (802.11a, 802.11b, 802.11g, 802.11p-10MHz, 802.11p-5MHz, 802.11n-5GHz, 802.11n-2.4GHz,
31// 802.11ac, 802.11ax-6GHz, 802.11ax-5GHz, 802.11ax-2.4GHz)
32// --serverShortGuardInterval and --clientShortGuardInterval (for 802.11n/ac)
33// --serverNss and --clientNss (for 802.11n/ac)
34// --serverChannelWidth and --clientChannelWidth (for 802.11n/ac)
35// --broadcast instead of unicast (default is unicast)
36// --rtsThreshold (by default, value of 99999 disables it)
37
38#include "ns3/attribute-container.h"
39#include "ns3/boolean.h"
40#include "ns3/command-line.h"
41#include "ns3/config.h"
42#include "ns3/double.h"
43#include "ns3/enum.h"
44#include "ns3/gnuplot.h"
45#include "ns3/he-configuration.h"
46#include "ns3/ht-configuration.h"
47#include "ns3/log.h"
48#include "ns3/mobility-helper.h"
49#include "ns3/packet-socket-client.h"
50#include "ns3/packet-socket-helper.h"
51#include "ns3/packet-socket-server.h"
52#include "ns3/propagation-delay-model.h"
53#include "ns3/propagation-loss-model.h"
54#include "ns3/rng-seed-manager.h"
55#include "ns3/ssid.h"
56#include "ns3/tuple.h"
57#include "ns3/uinteger.h"
58#include "ns3/wifi-mac.h"
59#include "ns3/wifi-net-device.h"
60#include "ns3/yans-wifi-helper.h"
61
62using namespace ns3;
63
64NS_LOG_COMPONENT_DEFINE("WifiManagerExample");
65
66double g_intervalBytes = 0; //!< Bytes received in an interval.
67uint64_t g_intervalRate = 0; //!< Rate in an interval.
68
69/**
70 * Packet received.
71 *
72 * @param pkt The packet.
73 * @param addr The sender address.
74 */
75void
77{
78 g_intervalBytes += pkt->GetSize();
79}
80
81/**
82 * Rate changed.
83 *
84 * @param oldVal Old value.
85 * @param newVal New value.
86 */
87void
88RateChange(uint64_t oldVal, uint64_t newVal)
89{
90 NS_LOG_DEBUG("Change from " << oldVal << " to " << newVal);
92}
93
94/// Step structure
95struct Step
96{
97 dBm_u stepSize; ///< step size
98 double stepTime; ///< step size in seconds
99};
100
101/// StandardInfo structure
103{
105 {
106 m_name = "none";
107 }
108
109 /**
110 * Constructor
111 *
112 * @param name reference name
113 * @param standard wifi standard
114 * @param band PHY band
115 * @param width channel width
116 * @param snrLow SNR low
117 * @param snrHigh SNR high
118 * @param xMin x minimum
119 * @param xMax x maximum
120 * @param yMax y maximum
121 */
122 StandardInfo(std::string name,
123 WifiStandard standard,
124 WifiPhyBand band,
125 MHz_u width,
126 dB_u snrLow,
128 double xMin,
129 double xMax,
130 double yMax)
131 : m_name(name),
132 m_standard(standard),
133 m_band(band),
134 m_width(width),
137 m_xMin(xMin),
138 m_xMax(xMax),
139 m_yMax(yMax)
140 {
141 }
142
143 std::string m_name; ///< name
145 WifiPhyBand m_band; ///< PHY band
146 MHz_u m_width; ///< channel width
147 dB_u m_snrLow; ///< lowest SNR
148 dB_u m_snrHigh; ///< highest SNR
149 double m_xMin; ///< X minimum
150 double m_xMax; ///< X maximum
151 double m_yMax; ///< Y maximum
152};
153
154/**
155 * Change the signal model and report the rate.
156 *
157 * @param rssModel The new RSS model.
158 * @param step The step to use.
159 * @param rss The RSS.
160 * @param noise The noise.
161 * @param rateDataset The rate dataset.
162 * @param actualDataset The actual dataset.
163 */
164void
166 Step step,
167 dBm_u rss,
168 dBm_u noise,
171{
172 NS_LOG_FUNCTION(rssModel << step.stepSize << step.stepTime << rss);
173 dB_u snr{rss - noise};
174 rateDataset.Add(snr, g_intervalRate / 1e6);
175 // Calculate received rate since last interval
176 double currentRate = ((g_intervalBytes * 8) / step.stepTime) / 1e6; // Mb/s
177 actualDataset.Add(snr, currentRate);
178 rssModel->SetRss(rss - step.stepSize);
179 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << "; selected rate "
180 << (g_intervalRate / 1e6) << "; observed rate " << currentRate
181 << "; setting new power to " << rss - step.stepSize);
182 g_intervalBytes = 0;
185 rssModel,
186 step,
187 (rss - step.stepSize),
188 noise,
191}
192
193int
194main(int argc, char* argv[])
195{
196 std::vector<StandardInfo> serverStandards;
197 std::vector<StandardInfo> clientStandards;
199 uint32_t rtsThreshold = 999999; // disabled even for large A-MPDU
200 uint32_t maxAmpduSize = 65535;
201 dBm_u stepSize{1};
202 double stepTime = 1; // seconds
203 uint32_t packetSize = 1024; // bytes
204 bool broadcast = false;
205 int ap1_x = 0;
206 int ap1_y = 0;
207 int sta1_x = 5;
208 int sta1_y = 0;
209 uint16_t serverNss = 1;
210 uint16_t clientNss = 1;
211 uint16_t serverShortGuardInterval = 800;
212 uint16_t clientShortGuardInterval = 800;
213 MHz_u serverChannelWidth{0}; // use default for standard and band
214 MHz_u clientChannelWidth{0}; // use default for standard and band
215 std::string wifiManager("Ideal");
216 std::string standard("802.11a");
219 bool infrastructure = false;
221
224
226 cmd.AddValue("maxRetryCount",
227 "The maximum number of retransmission attempts for a Data packet",
229 cmd.AddValue("rtsThreshold", "RTS threshold", rtsThreshold);
230 cmd.AddValue("maxAmpduSize", "Max A-MPDU size", maxAmpduSize);
231 cmd.AddValue("stepSize", "Power between steps (dBm)", stepSize);
232 cmd.AddValue("stepTime", "Time on each step (seconds)", stepTime);
233 cmd.AddValue("broadcast", "Send broadcast instead of unicast", broadcast);
234 cmd.AddValue("serverChannelWidth",
235 "Set channel width of the server (valid only for 802.11n or ac)",
237 cmd.AddValue("clientChannelWidth",
238 "Set channel width of the client (valid only for 802.11n or ac)",
240 cmd.AddValue("serverNss", "Set nss of the server (valid only for 802.11n or ac)", serverNss);
241 cmd.AddValue("clientNss", "Set nss of the client (valid only for 802.11n or ac)", clientNss);
242 cmd.AddValue("serverShortGuardInterval",
243 "Set short guard interval of the server (802.11n/ac/ax) in nanoseconds",
245 cmd.AddValue("clientShortGuardInterval",
246 "Set short guard interval of the client (802.11n/ac/ax) in nanoseconds",
248 cmd.AddValue(
249 "standard",
250 "Set standard (802.11a, 802.11b, 802.11g, 802.11p-10MHz, 802.11p-5MHz, 802.11n-5GHz, "
251 "802.11n-2.4GHz, 802.11ac, 802.11ax-6GHz, 802.11ax-5GHz, 802.11ax-2.4GHz)",
252 standard);
253 cmd.AddValue("wifiManager",
254 "Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, "
255 "MinstrelHt, Onoe, Rraa, ThompsonSampling)",
257 cmd.AddValue("infrastructure", "Use infrastructure instead of adhoc", infrastructure);
258 cmd.Parse(argc, argv);
259
260 // Print out some explanation of what this program does
261 std::cout << std::endl
262 << "This program demonstrates and plots the operation of different " << std::endl;
263 std::cout << "Wi-Fi rate controls on different station configurations," << std::endl;
264 std::cout << "by stepping down the received signal strength across a wide range" << std::endl;
265 std::cout << "and observing the adjustment of the rate." << std::endl;
266 std::cout << "Run 'wifi-manager-example --PrintHelp' to show program options." << std::endl
267 << std::endl;
268
269 if (!infrastructure)
270 {
272 "In ad hoc mode, we assume sender and receiver are similarly configured");
273 }
274
275 if (standard == "802.11b")
276 {
277 if (serverChannelWidth == MHz_u{0})
278 {
280 }
282 "Invalid channel width for standard " << standard);
283 NS_ABORT_MSG_IF(serverNss != 1, "Invalid nss for standard " << standard);
284 if (clientChannelWidth == MHz_u{0})
285 {
287 }
289 "Invalid channel width for standard " << standard);
290 NS_ABORT_MSG_IF(clientNss != 1, "Invalid nss for standard " << standard);
291 }
292 else if (standard == "802.11a" || standard == "802.11g")
293 {
294 if (serverChannelWidth == MHz_u{0})
295 {
297 }
299 "Invalid channel width for standard " << standard);
300 NS_ABORT_MSG_IF(serverNss != 1, "Invalid nss for standard " << standard);
301 if (clientChannelWidth == MHz_u{0})
302 {
304 }
306 "Invalid channel width for standard " << standard);
307 NS_ABORT_MSG_IF(clientNss != 1, "Invalid nss for standard " << standard);
308 }
309 else if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz")
310 {
311 WifiPhyBand band =
312 (standard == "802.11n-2.4GHz" ? WIFI_PHY_BAND_2_4GHZ : WIFI_PHY_BAND_5GHZ);
313 if (serverChannelWidth == MHz_u{0})
314 {
316 }
318 "Invalid channel width for standard " << standard);
320 "Invalid nss " << serverNss << " for standard " << standard);
321 if (clientChannelWidth == MHz_u{0})
322 {
324 }
326 "Invalid channel width for standard " << standard);
328 "Invalid nss " << clientNss << " for standard " << standard);
329 }
330 else if (standard == "802.11ac")
331 {
332 if (serverChannelWidth == MHz_u{0})
333 {
335 }
338 "Invalid channel width for standard " << standard);
340 "Invalid nss " << serverNss << " for standard " << standard);
341 if (clientChannelWidth == MHz_u{0})
342 {
344 }
347 "Invalid channel width for standard " << standard);
349 "Invalid nss " << clientNss << " for standard " << standard);
350 }
351 else if (standard == "802.11ax-6GHz" || standard == "802.11ax-5GHz" ||
352 standard == "802.11ax-2.4GHz")
353 {
354 WifiPhyBand band = (standard == "802.11ax-2.4GHz" ? WIFI_PHY_BAND_2_4GHZ
355 : standard == "802.11ax-6GHz" ? WIFI_PHY_BAND_6GHZ
357 if (serverChannelWidth == MHz_u{0})
358 {
360 }
363 "Invalid channel width for standard " << standard);
365 "Invalid nss " << serverNss << " for standard " << standard);
366 if (clientChannelWidth == MHz_u{0})
367 {
369 }
372 "Invalid channel width for standard " << standard);
374 "Invalid nss " << clientNss << " for standard " << standard);
375 }
376
377 // As channel width increases, scale up plot's yRange value
380
381 // The first number is channel width, second is minimum SNR, third is maximum
382 // SNR, fourth and fifth provide xrange axis limits, and sixth the yaxis
383 // maximum
385 StandardInfo("802.11a",
388 MHz_u{20},
389 dB_u{3},
390 dB_u{27},
391 0,
392 30,
393 60),
394 StandardInfo("802.11b",
397 MHz_u{22},
398 dB_u{-5},
399 dB_u{11},
400 -6,
401 15,
402 15),
403 StandardInfo("802.11g",
406 MHz_u{20},
407 dB_u{-5},
408 dB_u{27},
409 -6,
410 30,
411 60),
412 StandardInfo("802.11n-5GHz",
416 dB_u{3},
417 dB_u{30},
418 0,
419 35,
420 80 * channelRateFactor),
421 StandardInfo("802.11n-2.4GHz",
425 dB_u{3},
426 dB_u{30},
427 0,
428 35,
429 80 * channelRateFactor),
430 StandardInfo("802.11ac",
434 dB_u{5},
435 dB_u{50},
436 0,
437 55,
438 120 * channelRateFactor),
439 StandardInfo("802.11p-10MHz",
442 MHz_u{10},
443 dB_u{3},
444 dB_u{27},
445 0,
446 30,
447 60),
448 StandardInfo("802.11p-5MHz",
451 MHz_u{5},
452 dB_u{3},
453 dB_u{27},
454 0,
455 30,
456 60),
457 StandardInfo("802.11ax-6GHz",
461 dB_u{5},
462 dB_u{55},
463 0,
464 60,
465 120 * channelRateFactor),
466 StandardInfo("802.11ax-5GHz",
470 dB_u{5},
471 dB_u{55},
472 0,
473 60,
474 120 * channelRateFactor),
475 StandardInfo("802.11ax-2.4GHz",
479 dB_u{5},
480 dB_u{55},
481 0,
482 60,
483 120 * channelRateFactor),
484 };
485
487 StandardInfo("802.11a",
490 MHz_u{20},
491 dB_u{3},
492 dB_u{27},
493 0,
494 30,
495 60),
496 StandardInfo("802.11b",
499 MHz_u{22},
500 dB_u{-5},
501 dB_u{11},
502 -6,
503 15,
504 15),
505 StandardInfo("802.11g",
508 MHz_u{20},
509 dB_u{-5},
510 dB_u{27},
511 -6,
512 30,
513 60),
514 StandardInfo("802.11n-5GHz",
518 dB_u{3},
519 dB_u{30},
520 0,
521 35,
522 80 * channelRateFactor),
523 StandardInfo("802.11n-2.4GHz",
527 dB_u{3},
528 dB_u{30},
529 0,
530 35,
531 80 * channelRateFactor),
532 StandardInfo("802.11ac",
536 dB_u{5},
537 dB_u{50},
538 0,
539 55,
540 120 * channelRateFactor),
541 StandardInfo("802.11p-10MHz",
544 MHz_u{10},
545 dB_u{3},
546 dB_u{27},
547 0,
548 30,
549 60),
550 StandardInfo("802.11p-5MHz",
553 MHz_u{5},
554 dB_u{3},
555 dB_u{27},
556 0,
557 30,
558 60),
559 StandardInfo("802.11ax-6GHz",
563 dB_u{5},
564 dB_u{55},
565 0,
566 60,
567 160 * channelRateFactor),
568 StandardInfo("802.11ax-5GHz",
572 dB_u{5},
573 dB_u{55},
574 0,
575 60,
576 160 * channelRateFactor),
577 StandardInfo("802.11ax-2.4GHz",
581 dB_u{5},
582 dB_u{55},
583 0,
584 60,
585 160 * channelRateFactor),
586 };
587
588 for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size(); i++)
589 {
590 if (standard == serverStandards[i].m_name)
591 {
593 }
594 }
595 for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size(); i++)
596 {
597 if (standard == clientStandards[i].m_name)
598 {
600 }
601 }
602
604 "Standard " << standard << " not found");
606 "Standard " << standard << " not found");
607 std::cout << "Testing " << serverSelectedStandard.m_name << " with " << wifiManager << " ..."
608 << std::endl;
610 "SNR values in wrong order");
611 steps = static_cast<uint32_t>(std::abs(static_cast<double>(clientSelectedStandard.m_snrHigh -
612 clientSelectedStandard.m_snrLow) /
613 stepSize) +
614 1);
615 NS_LOG_DEBUG("Using " << steps << " steps for SNR range " << clientSelectedStandard.m_snrLow
616 << ":" << clientSelectedStandard.m_snrHigh);
619
620 std::string plotName = "wifi-manager-example-";
621 std::string dataName = "wifi-manager-example-";
624 plotName += "-";
625 dataName += "-";
626 plotName += standard;
627 dataName += standard;
628 if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz" || standard == "802.11ac" ||
629 standard == "802.11ax-6GHz" || standard == "802.11ax-5GHz" || standard == "802.11ax-2.4GHz")
630 {
631 plotName += "-server_";
632 dataName += "-server_";
633 std::ostringstream oss;
634 oss << serverChannelWidth << "MHz_" << serverShortGuardInterval << "ns_" << serverNss
635 << "SS";
636 plotName += oss.str();
637 dataName += oss.str();
638 plotName += "-client_";
639 dataName += "-client_";
640 oss.str("");
641 oss << clientChannelWidth << "MHz_" << clientShortGuardInterval << "ns_" << clientNss
642 << "SS";
643 plotName += oss.str();
644 dataName += oss.str();
645 }
646 plotName += ".eps";
647 dataName += ".plt";
648 std::ofstream outfile(dataName);
649 Gnuplot gnuplot = Gnuplot(plotName);
650
651 Config::SetDefault("ns3::WifiMac::FrameRetryLimit", UintegerValue(maxRetryCount));
652 Config::SetDefault("ns3::MinstrelWifiManager::PrintStats", BooleanValue(true));
653 Config::SetDefault("ns3::MinstrelWifiManager::PrintSamples", BooleanValue(true));
654 Config::SetDefault("ns3::MinstrelHtWifiManager::PrintStats", BooleanValue(true));
655 // Disable the default noise figure of 7 dBm in WifiPhy; the calculations
656 // of SNR below assume that the only noise is thermal noise
657 Config::SetDefault("ns3::WifiPhy::RxNoiseFigure", DoubleValue(0));
658
659 // By default, the CCA sensitivity is -82 dBm, meaning if the RSS is
660 // below this value, the receiver will reject the Wi-Fi frame.
661 // However, we want to probe the error model down to low SNR values,
662 // and we have disabled the noise figure, so the noise level in 20 MHz
663 // will be about -101 dBm. Therefore, lower the CCA sensitivity to a
664 // value that disables it (e.g. -110 dBm)
665 Config::SetDefault("ns3::WifiPhy::CcaSensitivity", DoubleValue(-110));
666
668 wifi.SetStandard(serverSelectedStandard.m_standard);
670 // Disable the preamble detection model for the same reason that we
671 // disabled CCA sensitivity above-- we want to enable reception at low SNR
673
677 wifiChannel->SetPropagationDelayModel(delayModel);
679 wifiChannel->SetPropagationLossModel(rssLossModel);
680 wifiPhy.SetChannel(wifiChannel);
681
682 wifi.SetRemoteStationManager("ns3::" + wifiManager + "WifiManager",
683 "RtsCtsThreshold",
684 UintegerValue(rtsThreshold));
685
688
691 ';'>
693
695 if (infrastructure)
696 {
697 Ssid ssid = Ssid("ns-3-ssid");
698 wifiMac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
700 {0, serverSelectedStandard.m_width, serverSelectedStandard.m_band, 0}});
701 wifiPhy.Set("ChannelSettings", channelValue);
703
704 wifiMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
706 {0, clientSelectedStandard.m_width, clientSelectedStandard.m_band, 0}});
707 wifiPhy.Set("ChannelSettings", channelValue);
709 }
710 else
711 {
712 wifiMac.SetType("ns3::AdhocWifiMac");
714 {0, serverSelectedStandard.m_width, serverSelectedStandard.m_band, 0}});
715 wifiPhy.Set("ChannelSettings", channelValue);
717
719 {0, clientSelectedStandard.m_width, clientSelectedStandard.m_band, 0}});
720 wifiPhy.Set("ChannelSettings", channelValue);
722 }
723
726
727 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize",
728 UintegerValue(maxAmpduSize));
729
731 "/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::" + wifiManager +
732 "WifiManager/Rate",
734
735 // Configure the mobility.
738 // Initial position of AP and STA
739 positionAlloc->Add(Vector(ap1_x, ap1_y, 0.0));
740 NS_LOG_INFO("Setting initial AP position to " << Vector(ap1_x, ap1_y, 0.0));
741 positionAlloc->Add(Vector(sta1_x, sta1_y, 0.0));
742 NS_LOG_INFO("Setting initial STA position to " << Vector(sta1_x, sta1_y, 0.0));
743 mobility.SetPositionAllocator(positionAlloc);
744 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
745 mobility.Install(clientNode);
746 mobility.Install(serverNode);
747
748 Gnuplot2dDataset rateDataset(clientSelectedStandard.m_name + std::string("-rate selected"));
749 Gnuplot2dDataset actualDataset(clientSelectedStandard.m_name + std::string("-observed"));
750 Step step;
751 step.stepSize = stepSize;
752 step.stepTime = stepTime;
753
754 // Perform post-install configuration from defaults for channel width,
755 // guard interval, and nss, if necessary
756 // Obtain pointer to the WifiPhy
763 auto t_clientNss = static_cast<uint8_t>(clientNss);
764 auto t_serverNss = static_cast<uint8_t>(serverNss);
765 wifiPhyPtrClient->SetNumberOfAntennas(t_clientNss);
766 wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams(t_clientNss);
767 wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams(t_clientNss);
768 wifiPhyPtrServer->SetNumberOfAntennas(t_serverNss);
769 wifiPhyPtrServer->SetMaxSupportedTxSpatialStreams(t_serverNss);
770 wifiPhyPtrServer->SetMaxSupportedRxSpatialStreams(t_serverNss);
771 // Only set the guard interval for HT and VHT modes
772 if (serverSelectedStandard.m_name == "802.11n-5GHz" ||
773 serverSelectedStandard.m_name == "802.11n-2.4GHz" ||
774 serverSelectedStandard.m_name == "802.11ac")
775 {
777 clientHtConfiguration->m_sgiSupported = (clientShortGuardInterval == 400);
779 serverHtConfiguration->m_sgiSupported = (serverShortGuardInterval == 400);
780 }
781 else if (serverSelectedStandard.m_name == "802.11ax-6GHz" ||
782 serverSelectedStandard.m_name == "802.11ax-5GHz" ||
783 serverSelectedStandard.m_name == "802.11ax-2.4GHz")
784 {
785 wndServer->GetHeConfiguration()->SetGuardInterval(NanoSeconds(serverShortGuardInterval));
786 wndClient->GetHeConfiguration()->SetGuardInterval(NanoSeconds(clientShortGuardInterval));
787 }
788
789 // Configure signal and noise, and schedule first iteration
790 const auto BOLTZMANN = 1.3803e-23;
791 const dBm_per_Hz_u noiseDensity = WToDbm(BOLTZMANN * 290); // 290K @ 20 MHz
792 const dBm_u noise = noiseDensity + (10 * log10(clientSelectedStandard.m_width * 1000000));
793
794 NS_LOG_DEBUG("Channel width " << wifiPhyPtrClient->GetChannelWidth() << " noise " << noise);
795 NS_LOG_DEBUG("NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams());
796
797 const dBm_u rssCurrent = (clientSelectedStandard.m_snrHigh + noise);
798 rssLossModel->SetRss(rssCurrent);
799 NS_LOG_INFO("Setting initial Rss to " << rssCurrent);
800 // Move the STA by stepsSize meters every stepTime seconds
801 Simulator::Schedule(Seconds(0.5 + stepTime),
804 step,
806 noise,
809
813
815 socketAddr.SetSingleDevice(serverDevice.Get(0)->GetIfIndex());
816 if (broadcast)
817 {
818 socketAddr.SetPhysicalAddress(serverDevice.Get(0)->GetBroadcast());
819 }
820 else
821 {
822 socketAddr.SetPhysicalAddress(serverDevice.Get(0)->GetAddress());
823 }
824 // Arbitrary protocol type.
825 // Note: PacketSocket doesn't have any L4 multiplexing or demultiplexing
826 // The only mux/demux is based on the protocol field
827 socketAddr.SetProtocol(1);
828
830 client->SetRemote(socketAddr);
831 client->SetStartTime(Seconds(0.5)); // allow simulation warmup
832 client->SetAttribute("MaxPackets", UintegerValue(0)); // unlimited
833 client->SetAttribute("PacketSize", UintegerValue(packetSize));
834
835 // Set a maximum rate 10% above the yMax specified for the selected standard
836 double rate = clientSelectedStandard.m_yMax * 1e6 * 1.10;
837 double clientInterval = static_cast<double>(packetSize) * 8 / rate;
838 NS_LOG_DEBUG("Setting interval to " << clientInterval << " sec for rate of " << rate
839 << " bits/sec");
840
841 client->SetAttribute("Interval", TimeValue(Seconds(clientInterval)));
842 clientNode->AddApplication(client);
843
845 server->SetLocal(socketAddr);
846 server->TraceConnectWithoutContext("Rx", MakeCallback(&PacketRx));
847 serverNode->AddApplication(server);
848
849 Simulator::Stop(Seconds((steps + 1) * stepTime));
851
853 {
854 NS_ABORT_MSG_UNLESS(wndClient->GetMac()->GetBaAgreementEstablishedAsOriginator(
855 wndServer->GetMac()->GetAddress(),
856 0),
857 "Expected BA agreement established for standard "
858 << serverSelectedStandard.m_standard);
859 }
860
862
863 gnuplot.AddDataset(rateDataset);
864 gnuplot.AddDataset(actualDataset);
865
866 std::ostringstream xMinStr;
867 std::ostringstream xMaxStr;
868 std::ostringstream yMaxStr;
869 std::string xRangeStr("set xrange [");
871 xRangeStr.append(xMinStr.str());
872 xRangeStr.append(":");
874 xRangeStr.append(xMaxStr.str());
875 xRangeStr.append("]");
876 std::string yRangeStr("set yrange [0:");
878 yRangeStr.append(yMaxStr.str());
879 yRangeStr.append("]");
880
881 std::string title("Results for ");
882 title.append(standard);
883 title.append(" with ");
884 title.append(wifiManager);
885 title.append("\\n");
886 if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz" || standard == "802.11ac" ||
887 standard == "802.11ax-6GHz" || standard == "802.11ax-5GHz" || standard == "802.11ax-2.4GHz")
888 {
889 std::ostringstream serverGiStrStr;
890 std::ostringstream serverWidthStrStr;
891 std::ostringstream serverNssStrStr;
892 title.append("server: width=");
894 title.append(serverWidthStrStr.str());
895 title.append("MHz");
896 title.append(" GI=");
898 title.append(serverGiStrStr.str());
899 title.append("ns");
900 title.append(" nss=");
902 title.append(serverNssStrStr.str());
903 title.append("\\n");
904 std::ostringstream clientGiStrStr;
905 std::ostringstream clientWidthStrStr;
906 std::ostringstream clientNssStrStr;
907 title.append("client: width=");
909 title.append(clientWidthStrStr.str());
910 title.append("MHz");
911 title.append(" GI=");
913 title.append(clientGiStrStr.str());
914 title.append("ns");
915 title.append(" nss=");
917 title.append(clientNssStrStr.str());
918 }
919 gnuplot.SetTerminal("postscript eps color enh \"Times-BoldItalic\"");
920 gnuplot.SetLegend("SNR (dB)", "Rate (Mb/s)");
921 gnuplot.SetTitle(title);
922 gnuplot.SetExtra(xRangeStr);
923 gnuplot.AppendExtra(yRangeStr);
924 gnuplot.AppendExtra("set key top left");
925 gnuplot.GenerateOutput(outfile);
926 outfile.close();
927
928 return 0;
929}
a polymophic address class
Definition address.h:90
A container for one type of attribute.
AttributeValue implementation for Boolean.
Definition boolean.h:26
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Class to represent a 2D points plot.
Definition gnuplot.h:105
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition gnuplot.h:360
void AddDataset(const GnuplotDataset &dataset)
Definition gnuplot.cc:788
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition gnuplot.cc:768
void SetTerminal(const std::string &terminal)
Definition gnuplot.cc:756
void AppendExtra(const std::string &extra)
Definition gnuplot.cc:781
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition gnuplot.cc:794
void SetExtra(const std::string &extra)
Definition gnuplot.cc:775
void SetTitle(const std::string &title)
Definition gnuplot.cc:762
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
an address for a packet socket
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
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
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
@ S
second
Definition nstime.h:105
AttributeValue implementation for Time.
Definition nstime.h:1431
AttributeValue implementation for Tuple.
Definition tuple.h:67
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
create MAC layers for a ns3::WifiNetDevice.
Hold together all Wifi-related objects.
void DisablePreambleDetectionModel()
Disable the preamble detection model on all links.
std::vector< ChannelTuple > ChannelSegments
segments identifying an operating channel
Definition wifi-phy.h:947
Make it easy to create and manage PHY objects for the YANS model.
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_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition abort.h:133
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
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 NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1380
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyBand
Identifies the PHY band.
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
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
dBm_u WToDbm(Watt_u val)
Convert from Watts to dBm.
Definition wifi-utils.cc:39
MHz_u GetDefaultChannelWidth(WifiStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
ssid
Definition third.py:82
wifi
Definition third.py:84
mobility
Definition third.py:92
StandardInfo structure.
std::string m_name
name
StandardInfo(std::string name, WifiStandard standard, WifiPhyBand band, MHz_u width, dB_u snrLow, dB_u snrHigh, double xMin, double xMax, double yMax)
Constructor.
double m_yMax
Y maximum.
WifiStandard m_standard
standard
WifiPhyBand m_band
PHY band.
double m_xMax
X maximum.
dB_u m_snrHigh
highest SNR
double m_xMin
X minimum.
MHz_u m_width
channel width
dB_u m_snrLow
lowest SNR
Step structure.
dBm_u stepSize
step size
double stepTime
step size in seconds
uint64_t g_intervalRate
Rate in an interval.
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, Step step, dBm_u rss, dBm_u noise, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
Change the signal model and report the rate.
void RateChange(uint64_t oldVal, uint64_t newVal)
Rate changed.
void PacketRx(Ptr< const Packet > pkt, const Address &addr)
Packet received.
double g_intervalBytes
Bytes received in an interval.
static const uint32_t packetSize
Packet size generated at the AP.