A Discrete-Event Network Simulator
API
wifi-manager-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 University of Washington
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Tom Henderson <tomhend@u.washington.edu>
18 * Matías Richart <mrichart@fing.edu.uy>
19 * Sébastien Deronne <sebastien.deronne@gmail.com>
20 */
21
22// Test the operation of a wifi manager as the SNR is varied, and create
23// a gnuplot output file for plotting.
24//
25// The test consists of a device acting as server and a device as client generating traffic.
26//
27// The output consists of a plot of the rate observed and selected at the client device.
28//
29// By default, the 802.11a standard using IdealWifiManager is plotted. Several command line
30// arguments can change the following options:
31// --wifiManager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa,
32// ThompsonSampling)
33// --standard (802.11a, 802.11b, 802.11g, 802.11p-10MHz, 802.11p-5MHz, 802.11n-5GHz, 802.11n-2.4GHz,
34// 802.11ac, 802.11ax-6GHz, 802.11ax-5GHz, 802.11ax-2.4GHz)
35// --serverShortGuardInterval and --clientShortGuardInterval (for 802.11n/ac)
36// --serverNss and --clientNss (for 802.11n/ac)
37// --serverChannelWidth and --clientChannelWidth (for 802.11n/ac)
38// --broadcast instead of unicast (default is unicast)
39// --rtsThreshold (by default, value of 99999 disables it)
40
41#include "ns3/boolean.h"
42#include "ns3/command-line.h"
43#include "ns3/config.h"
44#include "ns3/double.h"
45#include "ns3/enum.h"
46#include "ns3/gnuplot.h"
47#include "ns3/he-configuration.h"
48#include "ns3/ht-configuration.h"
49#include "ns3/log.h"
50#include "ns3/mobility-helper.h"
51#include "ns3/packet-socket-client.h"
52#include "ns3/packet-socket-helper.h"
53#include "ns3/packet-socket-server.h"
54#include "ns3/propagation-delay-model.h"
55#include "ns3/propagation-loss-model.h"
56#include "ns3/rng-seed-manager.h"
57#include "ns3/ssid.h"
58#include "ns3/tuple.h"
59#include "ns3/uinteger.h"
60#include "ns3/wifi-net-device.h"
61#include "ns3/yans-wifi-helper.h"
62
63using namespace ns3;
64
65NS_LOG_COMPONENT_DEFINE("WifiManagerExample");
66
67// 290K @ 20 MHz
68const double NOISE_DBM_Hz = -174.0;
70
71double g_intervalBytes = 0;
72uint64_t g_intervalRate = 0;
73
80void
82{
83 g_intervalBytes += pkt->GetSize();
84}
85
92void
93RateChange(uint64_t oldVal, uint64_t newVal)
94{
95 NS_LOG_DEBUG("Change from " << oldVal << " to " << newVal);
96 g_intervalRate = newVal;
97}
98
100struct Step
101{
102 double stepSize;
103 double stepTime;
104};
105
108{
110 {
111 m_name = "none";
112 }
113
127 StandardInfo(std::string name,
128 WifiStandard standard,
129 WifiPhyBand band,
130 uint16_t width,
131 double snrLow,
132 double snrHigh,
133 double xMin,
134 double xMax,
135 double yMax)
136 : m_name(name),
137 m_standard(standard),
138 m_band(band),
139 m_width(width),
140 m_snrLow(snrLow),
141 m_snrHigh(snrHigh),
142 m_xMin(xMin),
143 m_xMax(xMax),
144 m_yMax(yMax)
145 {
146 }
147
148 std::string m_name;
151 uint16_t m_width;
152 double m_snrLow;
153 double m_snrHigh;
154 double m_xMin;
155 double m_xMax;
156 double m_yMax;
157};
158
168void
170 Step step,
171 double rss,
172 Gnuplot2dDataset& rateDataset,
173 Gnuplot2dDataset& actualDataset)
174{
175 NS_LOG_FUNCTION(rssModel << step.stepSize << step.stepTime << rss);
176 double snr = rss - noiseDbm;
177 rateDataset.Add(snr, g_intervalRate / 1e6);
178 // Calculate received rate since last interval
179 double currentRate = ((g_intervalBytes * 8) / step.stepTime) / 1e6; // Mb/s
180 actualDataset.Add(snr, currentRate);
181 rssModel->SetRss(rss - step.stepSize);
182 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << "; selected rate "
183 << (g_intervalRate / 1e6) << "; observed rate " << currentRate
184 << "; setting new power to " << rss - step.stepSize);
185 g_intervalBytes = 0;
186 Simulator::Schedule(Seconds(step.stepTime),
188 rssModel,
189 step,
190 (rss - step.stepSize),
191 rateDataset,
192 actualDataset);
193}
194
195int
196main(int argc, char* argv[])
197{
198 std::vector<StandardInfo> serverStandards;
199 std::vector<StandardInfo> clientStandards;
200 uint32_t steps;
201 uint32_t rtsThreshold = 999999; // disabled even for large A-MPDU
202 uint32_t maxAmpduSize = 65535;
203 double stepSize = 1; // dBm
204 double stepTime = 1; // seconds
205 uint32_t packetSize = 1024; // bytes
206 bool broadcast = 0;
207 int ap1_x = 0;
208 int ap1_y = 0;
209 int sta1_x = 5;
210 int sta1_y = 0;
211 uint16_t serverNss = 1;
212 uint16_t clientNss = 1;
213 uint16_t serverShortGuardInterval = 800;
214 uint16_t clientShortGuardInterval = 800;
215 uint16_t serverChannelWidth = 0; // use default for standard and band
216 uint16_t clientChannelWidth = 0; // use default for standard and band
217 std::string wifiManager("Ideal");
218 std::string standard("802.11a");
219 StandardInfo serverSelectedStandard;
220 StandardInfo clientSelectedStandard;
221 bool infrastructure = false;
222 uint32_t maxSlrc = 7;
223 uint32_t maxSsrc = 7;
224
225 CommandLine cmd(__FILE__);
226 cmd.AddValue("maxSsrc",
227 "The maximum number of retransmission attempts for a RTS packet",
228 maxSsrc);
229 cmd.AddValue("maxSlrc",
230 "The maximum number of retransmission attempts for a Data packet",
231 maxSlrc);
232 cmd.AddValue("rtsThreshold", "RTS threshold", rtsThreshold);
233 cmd.AddValue("maxAmpduSize", "Max A-MPDU size", maxAmpduSize);
234 cmd.AddValue("stepSize", "Power between steps (dBm)", stepSize);
235 cmd.AddValue("stepTime", "Time on each step (seconds)", stepTime);
236 cmd.AddValue("broadcast", "Send broadcast instead of unicast", broadcast);
237 cmd.AddValue("serverChannelWidth",
238 "Set channel width of the server (valid only for 802.11n or ac)",
239 serverChannelWidth);
240 cmd.AddValue("clientChannelWidth",
241 "Set channel width of the client (valid only for 802.11n or ac)",
242 clientChannelWidth);
243 cmd.AddValue("serverNss", "Set nss of the server (valid only for 802.11n or ac)", serverNss);
244 cmd.AddValue("clientNss", "Set nss of the client (valid only for 802.11n or ac)", clientNss);
245 cmd.AddValue("serverShortGuardInterval",
246 "Set short guard interval of the server (802.11n/ac/ax) in nanoseconds",
247 serverShortGuardInterval);
248 cmd.AddValue("clientShortGuardInterval",
249 "Set short guard interval of the client (802.11n/ac/ax) in nanoseconds",
250 clientShortGuardInterval);
251 cmd.AddValue(
252 "standard",
253 "Set standard (802.11a, 802.11b, 802.11g, 802.11p-10MHz, 802.11p-5MHz, 802.11n-5GHz, "
254 "802.11n-2.4GHz, 802.11ac, 802.11ax-6GHz, 802.11ax-5GHz, 802.11ax-2.4GHz)",
255 standard);
256 cmd.AddValue("wifiManager",
257 "Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, "
258 "MinstrelHt, Onoe, Rraa, ThompsonSampling)",
259 wifiManager);
260 cmd.AddValue("infrastructure", "Use infrastructure instead of adhoc", infrastructure);
261 cmd.Parse(argc, argv);
262
263 // Print out some explanation of what this program does
264 std::cout << std::endl
265 << "This program demonstrates and plots the operation of different " << std::endl;
266 std::cout << "Wi-Fi rate controls on different station configurations," << std::endl;
267 std::cout << "by stepping down the received signal strength across a wide range" << std::endl;
268 std::cout << "and observing the adjustment of the rate." << std::endl;
269 std::cout << "Run 'wifi-manager-example --PrintHelp' to show program options." << std::endl
270 << std::endl;
271
272 if (infrastructure == false)
273 {
274 NS_ABORT_MSG_IF(serverNss != clientNss,
275 "In ad hoc mode, we assume sender and receiver are similarly configured");
276 }
277
278 if (standard == "802.11b")
279 {
280 if (serverChannelWidth == 0)
281 {
283 }
284 NS_ABORT_MSG_IF(serverChannelWidth != 22 && serverChannelWidth != 22,
285 "Invalid channel width for standard " << standard);
286 NS_ABORT_MSG_IF(serverNss != 1, "Invalid nss for standard " << standard);
287 if (clientChannelWidth == 0)
288 {
290 }
291 NS_ABORT_MSG_IF(clientChannelWidth != 22 && clientChannelWidth != 22,
292 "Invalid channel width for standard " << standard);
293 NS_ABORT_MSG_IF(clientNss != 1, "Invalid nss for standard " << standard);
294 }
295 else if (standard == "802.11a" || standard == "802.11g")
296 {
297 if (serverChannelWidth == 0)
298 {
300 }
301 NS_ABORT_MSG_IF(serverChannelWidth != 20,
302 "Invalid channel width for standard " << standard);
303 NS_ABORT_MSG_IF(serverNss != 1, "Invalid nss for standard " << standard);
304 if (clientChannelWidth == 0)
305 {
307 }
308 NS_ABORT_MSG_IF(clientChannelWidth != 20,
309 "Invalid channel width for standard " << standard);
310 NS_ABORT_MSG_IF(clientNss != 1, "Invalid nss for standard " << standard);
311 }
312 else if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz")
313 {
314 WifiPhyBand band =
315 (standard == "802.11n-2.4GHz" ? WIFI_PHY_BAND_2_4GHZ : WIFI_PHY_BAND_5GHZ);
316 if (serverChannelWidth == 0)
317 {
318 serverChannelWidth = GetDefaultChannelWidth(WIFI_STANDARD_80211n, band);
319 }
320 NS_ABORT_MSG_IF(serverChannelWidth != 20 && serverChannelWidth != 40,
321 "Invalid channel width for standard " << standard);
322 NS_ABORT_MSG_IF(serverNss == 0 || serverNss > 4,
323 "Invalid nss " << serverNss << " for standard " << standard);
324 if (clientChannelWidth == 0)
325 {
326 clientChannelWidth = GetDefaultChannelWidth(WIFI_STANDARD_80211n, band);
327 }
328 NS_ABORT_MSG_IF(clientChannelWidth != 20 && clientChannelWidth != 40,
329 "Invalid channel width for standard " << standard);
330 NS_ABORT_MSG_IF(clientNss == 0 || clientNss > 4,
331 "Invalid nss " << clientNss << " for standard " << standard);
332 }
333 else if (standard == "802.11ac")
334 {
335 if (serverChannelWidth == 0)
336 {
338 }
339 NS_ABORT_MSG_IF(serverChannelWidth != 20 && serverChannelWidth != 40 &&
340 serverChannelWidth != 80 && serverChannelWidth != 160,
341 "Invalid channel width for standard " << standard);
342 NS_ABORT_MSG_IF(serverNss == 0 || serverNss > 4,
343 "Invalid nss " << serverNss << " for standard " << standard);
344 if (clientChannelWidth == 0)
345 {
347 }
348 NS_ABORT_MSG_IF(clientChannelWidth != 20 && clientChannelWidth != 40 &&
349 clientChannelWidth != 80 && clientChannelWidth != 160,
350 "Invalid channel width for standard " << standard);
351 NS_ABORT_MSG_IF(clientNss == 0 || clientNss > 4,
352 "Invalid nss " << clientNss << " for standard " << standard);
353 }
354 else if (standard == "802.11ax-6GHz" || standard == "802.11ax-5GHz" ||
355 standard == "802.11ax-2.4GHz")
356 {
357 WifiPhyBand band = (standard == "802.11ax-2.4GHz" ? WIFI_PHY_BAND_2_4GHZ
358 : standard == "802.11ax-6GHz" ? WIFI_PHY_BAND_6GHZ
360 if (serverChannelWidth == 0)
361 {
362 serverChannelWidth = GetDefaultChannelWidth(WIFI_STANDARD_80211ax, band);
363 }
364 NS_ABORT_MSG_IF(serverChannelWidth != 20 && serverChannelWidth != 40 &&
365 serverChannelWidth != 80 && serverChannelWidth != 160,
366 "Invalid channel width for standard " << standard);
367 NS_ABORT_MSG_IF(serverNss == 0 || serverNss > 4,
368 "Invalid nss " << serverNss << " for standard " << standard);
369 if (clientChannelWidth == 0)
370 {
371 clientChannelWidth = GetDefaultChannelWidth(WIFI_STANDARD_80211ax, band);
372 }
373 NS_ABORT_MSG_IF(clientChannelWidth != 20 && clientChannelWidth != 40 &&
374 clientChannelWidth != 80 && clientChannelWidth != 160,
375 "Invalid channel width for standard " << standard);
376 NS_ABORT_MSG_IF(clientNss == 0 || clientNss > 4,
377 "Invalid nss " << clientNss << " for standard " << standard);
378 }
379
380 // As channel width increases, scale up plot's yRange value
381 uint32_t channelRateFactor = std::max(clientChannelWidth, serverChannelWidth) / 20;
382 channelRateFactor = channelRateFactor * std::max(clientNss, serverNss);
383
384 // The first number is channel width, second is minimum SNR, third is maximum
385 // SNR, fourth and fifth provide xrange axis limits, and sixth the yaxis
386 // maximum
387 serverStandards = {
388 StandardInfo("802.11a", WIFI_STANDARD_80211a, WIFI_PHY_BAND_5GHZ, 20, 3, 27, 0, 30, 60),
389 StandardInfo("802.11b", WIFI_STANDARD_80211b, WIFI_PHY_BAND_2_4GHZ, 22, -5, 11, -6, 15, 15),
390 StandardInfo("802.11g", WIFI_STANDARD_80211g, WIFI_PHY_BAND_2_4GHZ, 20, -5, 27, -6, 30, 60),
391 StandardInfo("802.11n-5GHz",
394 serverChannelWidth,
395 3,
396 30,
397 0,
398 35,
399 80 * channelRateFactor),
400 StandardInfo("802.11n-2.4GHz",
403 serverChannelWidth,
404 3,
405 30,
406 0,
407 35,
408 80 * channelRateFactor),
409 StandardInfo("802.11ac",
412 serverChannelWidth,
413 5,
414 50,
415 0,
416 55,
417 120 * channelRateFactor),
418 StandardInfo("802.11p-10MHz",
421 10,
422 3,
423 27,
424 0,
425 30,
426 60),
427 StandardInfo("802.11p-5MHz", WIFI_STANDARD_80211p, WIFI_PHY_BAND_5GHZ, 5, 3, 27, 0, 30, 60),
428 StandardInfo("802.11ax-6GHz",
431 serverChannelWidth,
432 5,
433 55,
434 0,
435 60,
436 120 * channelRateFactor),
437 StandardInfo("802.11ax-5GHz",
440 serverChannelWidth,
441 5,
442 55,
443 0,
444 60,
445 120 * channelRateFactor),
446 StandardInfo("802.11ax-2.4GHz",
449 serverChannelWidth,
450 5,
451 55,
452 0,
453 60,
454 120 * channelRateFactor),
455 };
456
457 clientStandards = {
458 StandardInfo("802.11a", WIFI_STANDARD_80211a, WIFI_PHY_BAND_5GHZ, 20, 3, 27, 0, 30, 60),
459 StandardInfo("802.11b", WIFI_STANDARD_80211b, WIFI_PHY_BAND_2_4GHZ, 22, -5, 11, -6, 15, 15),
460 StandardInfo("802.11g", WIFI_STANDARD_80211g, WIFI_PHY_BAND_2_4GHZ, 20, -5, 27, -6, 30, 60),
461 StandardInfo("802.11n-5GHz",
464 clientChannelWidth,
465 3,
466 30,
467 0,
468 35,
469 80 * channelRateFactor),
470 StandardInfo("802.11n-2.4GHz",
473 clientChannelWidth,
474 3,
475 30,
476 0,
477 35,
478 80 * channelRateFactor),
479 StandardInfo("802.11ac",
482 clientChannelWidth,
483 5,
484 50,
485 0,
486 55,
487 120 * channelRateFactor),
488 StandardInfo("802.11p-10MHz",
491 10,
492 3,
493 27,
494 0,
495 30,
496 60),
497 StandardInfo("802.11p-5MHz", WIFI_STANDARD_80211p, WIFI_PHY_BAND_5GHZ, 5, 3, 27, 0, 30, 60),
498 StandardInfo("802.11ax-6GHz",
501 clientChannelWidth,
502 5,
503 55,
504 0,
505 60,
506 160 * channelRateFactor),
507 StandardInfo("802.11ax-5GHz",
510 clientChannelWidth,
511 5,
512 55,
513 0,
514 60,
515 160 * channelRateFactor),
516 StandardInfo("802.11ax-2.4GHz",
519 clientChannelWidth,
520 5,
521 55,
522 0,
523 60,
524 160 * channelRateFactor),
525 };
526
527 for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size(); i++)
528 {
529 if (standard == serverStandards[i].m_name)
530 {
531 serverSelectedStandard = serverStandards[i];
532 }
533 }
534 for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size(); i++)
535 {
536 if (standard == clientStandards[i].m_name)
537 {
538 clientSelectedStandard = clientStandards[i];
539 }
540 }
541
542 NS_ABORT_MSG_IF(serverSelectedStandard.m_name == "none",
543 "Standard " << standard << " not found");
544 NS_ABORT_MSG_IF(clientSelectedStandard.m_name == "none",
545 "Standard " << standard << " not found");
546 std::cout << "Testing " << serverSelectedStandard.m_name << " with " << wifiManager << " ..."
547 << std::endl;
548 NS_ABORT_MSG_IF(clientSelectedStandard.m_snrLow >= clientSelectedStandard.m_snrHigh,
549 "SNR values in wrong order");
550 steps = static_cast<uint32_t>(std::abs(static_cast<double>(clientSelectedStandard.m_snrHigh -
551 clientSelectedStandard.m_snrLow) /
552 stepSize) +
553 1);
554 NS_LOG_DEBUG("Using " << steps << " steps for SNR range " << clientSelectedStandard.m_snrLow
555 << ":" << clientSelectedStandard.m_snrHigh);
556 Ptr<Node> clientNode = CreateObject<Node>();
557 Ptr<Node> serverNode = CreateObject<Node>();
558
559 std::string plotName = "wifi-manager-example-";
560 std::string dataName = "wifi-manager-example-";
561 plotName += wifiManager;
562 dataName += wifiManager;
563 plotName += "-";
564 dataName += "-";
565 plotName += standard;
566 dataName += standard;
567 if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz" || standard == "802.11ac" ||
568 standard == "802.11ax-6GHz" || standard == "802.11ax-5GHz" || standard == "802.11ax-2.4GHz")
569 {
570 plotName += "-server_";
571 dataName += "-server_";
572 std::ostringstream oss;
573 oss << serverChannelWidth << "MHz_" << serverShortGuardInterval << "ns_" << serverNss
574 << "SS";
575 plotName += oss.str();
576 dataName += oss.str();
577 plotName += "-client_";
578 dataName += "-client_";
579 oss.str("");
580 oss << clientChannelWidth << "MHz_" << clientShortGuardInterval << "ns_" << clientNss
581 << "SS";
582 plotName += oss.str();
583 dataName += oss.str();
584 }
585 plotName += ".eps";
586 dataName += ".plt";
587 std::ofstream outfile(dataName);
588 Gnuplot gnuplot = Gnuplot(plotName);
589
590 Config::SetDefault("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue(maxSlrc));
591 Config::SetDefault("ns3::WifiRemoteStationManager::MaxSsrc", UintegerValue(maxSsrc));
592 Config::SetDefault("ns3::MinstrelWifiManager::PrintStats", BooleanValue(true));
593 Config::SetDefault("ns3::MinstrelWifiManager::PrintSamples", BooleanValue(true));
594 Config::SetDefault("ns3::MinstrelHtWifiManager::PrintStats", BooleanValue(true));
595
597 wifi.SetStandard(serverSelectedStandard.m_standard);
598 YansWifiPhyHelper wifiPhy;
599
600 Ptr<YansWifiChannel> wifiChannel = CreateObject<YansWifiChannel>();
602 CreateObject<ConstantSpeedPropagationDelayModel>();
603 wifiChannel->SetPropagationDelayModel(delayModel);
604 Ptr<FixedRssLossModel> rssLossModel = CreateObject<FixedRssLossModel>();
605 wifiChannel->SetPropagationLossModel(rssLossModel);
606 wifiPhy.SetChannel(wifiChannel);
607
608 wifi.SetRemoteStationManager("ns3::" + wifiManager + "WifiManager",
609 "RtsCtsThreshold",
610 UintegerValue(rtsThreshold));
611
612 NetDeviceContainer serverDevice;
613 NetDeviceContainer clientDevice;
614
616
617 WifiMacHelper wifiMac;
618 if (infrastructure)
619 {
620 Ssid ssid = Ssid("ns-3-ssid");
621 wifiMac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
622 channelValue.Set(WifiPhy::ChannelTuple{0,
623 serverSelectedStandard.m_width,
624 serverSelectedStandard.m_band,
625 0});
626 wifiPhy.Set("ChannelSettings", channelValue);
627 serverDevice = wifi.Install(wifiPhy, wifiMac, serverNode);
628
629 wifiMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
630 channelValue.Set(WifiPhy::ChannelTuple{0,
631 clientSelectedStandard.m_width,
632 clientSelectedStandard.m_band,
633 0});
634 clientDevice = wifi.Install(wifiPhy, wifiMac, clientNode);
635 }
636 else
637 {
638 wifiMac.SetType("ns3::AdhocWifiMac");
639 channelValue.Set(WifiPhy::ChannelTuple{0,
640 serverSelectedStandard.m_width,
641 serverSelectedStandard.m_band,
642 0});
643 wifiPhy.Set("ChannelSettings", channelValue);
644 serverDevice = wifi.Install(wifiPhy, wifiMac, serverNode);
645
646 channelValue.Set(WifiPhy::ChannelTuple{0,
647 clientSelectedStandard.m_width,
648 clientSelectedStandard.m_band,
649 0});
650 clientDevice = wifi.Install(wifiPhy, wifiMac, clientNode);
651 }
652
653 RngSeedManager::SetSeed(1);
654 RngSeedManager::SetRun(2);
655 wifi.AssignStreams(serverDevice, 100);
656 wifi.AssignStreams(clientDevice, 100);
657
658 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize",
659 UintegerValue(maxAmpduSize));
660
662 "/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::" + wifiManager +
663 "WifiManager/Rate",
665
666 // Configure the mobility.
668 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
669 // Initial position of AP and STA
670 positionAlloc->Add(Vector(ap1_x, ap1_y, 0.0));
671 NS_LOG_INFO("Setting initial AP position to " << Vector(ap1_x, ap1_y, 0.0));
672 positionAlloc->Add(Vector(sta1_x, sta1_y, 0.0));
673 NS_LOG_INFO("Setting initial STA position to " << Vector(sta1_x, sta1_y, 0.0));
674 mobility.SetPositionAllocator(positionAlloc);
675 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
676 mobility.Install(clientNode);
677 mobility.Install(serverNode);
678
679 Gnuplot2dDataset rateDataset(clientSelectedStandard.m_name + std::string("-rate selected"));
680 Gnuplot2dDataset actualDataset(clientSelectedStandard.m_name + std::string("-observed"));
681 Step step;
682 step.stepSize = stepSize;
683 step.stepTime = stepTime;
684
685 // Perform post-install configuration from defaults for channel width,
686 // guard interval, and nss, if necessary
687 // Obtain pointer to the WifiPhy
688 Ptr<NetDevice> ndClient = clientDevice.Get(0);
689 Ptr<NetDevice> ndServer = serverDevice.Get(0);
690 Ptr<WifiNetDevice> wndClient = ndClient->GetObject<WifiNetDevice>();
691 Ptr<WifiNetDevice> wndServer = ndServer->GetObject<WifiNetDevice>();
692 Ptr<WifiPhy> wifiPhyPtrClient = wndClient->GetPhy();
693 Ptr<WifiPhy> wifiPhyPtrServer = wndServer->GetPhy();
694 uint8_t t_clientNss = static_cast<uint8_t>(clientNss);
695 uint8_t t_serverNss = static_cast<uint8_t>(serverNss);
696 wifiPhyPtrClient->SetNumberOfAntennas(t_clientNss);
697 wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams(t_clientNss);
698 wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams(t_clientNss);
699 wifiPhyPtrServer->SetNumberOfAntennas(t_serverNss);
700 wifiPhyPtrServer->SetMaxSupportedTxSpatialStreams(t_serverNss);
701 wifiPhyPtrServer->SetMaxSupportedRxSpatialStreams(t_serverNss);
702 // Only set the guard interval for HT and VHT modes
703 if (serverSelectedStandard.m_name == "802.11n-5GHz" ||
704 serverSelectedStandard.m_name == "802.11n-2.4GHz" ||
705 serverSelectedStandard.m_name == "802.11ac")
706 {
707 Ptr<HtConfiguration> clientHtConfiguration = wndClient->GetHtConfiguration();
708 clientHtConfiguration->SetShortGuardIntervalSupported(clientShortGuardInterval == 400);
709 Ptr<HtConfiguration> serverHtConfiguration = wndServer->GetHtConfiguration();
710 serverHtConfiguration->SetShortGuardIntervalSupported(serverShortGuardInterval == 400);
711 }
712 else if (serverSelectedStandard.m_name == "802.11ax-6GHz" ||
713 serverSelectedStandard.m_name == "802.11ax-5GHz" ||
714 serverSelectedStandard.m_name == "802.11ax-2.4GHz")
715 {
716 wndServer->GetHeConfiguration()->SetGuardInterval(NanoSeconds(serverShortGuardInterval));
717 wndClient->GetHeConfiguration()->SetGuardInterval(NanoSeconds(clientShortGuardInterval));
718 }
719 NS_LOG_DEBUG("Channel width " << wifiPhyPtrClient->GetChannelWidth() << " noiseDbm "
720 << noiseDbm);
721 NS_LOG_DEBUG("NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams());
722
723 // Configure signal and noise, and schedule first iteration
724 noiseDbm += 10 * log10(clientSelectedStandard.m_width * 1000000);
725 double rssCurrent = (clientSelectedStandard.m_snrHigh + noiseDbm);
726 rssLossModel->SetRss(rssCurrent);
727 NS_LOG_INFO("Setting initial Rss to " << rssCurrent);
728 // Move the STA by stepsSize meters every stepTime seconds
729 Simulator::Schedule(Seconds(0.5 + stepTime),
731 rssLossModel,
732 step,
733 rssCurrent,
734 rateDataset,
735 actualDataset);
736
737 PacketSocketHelper packetSocketHelper;
738 packetSocketHelper.Install(serverNode);
739 packetSocketHelper.Install(clientNode);
740
741 PacketSocketAddress socketAddr;
742 socketAddr.SetSingleDevice(serverDevice.Get(0)->GetIfIndex());
743 if (broadcast)
744 {
745 socketAddr.SetPhysicalAddress(serverDevice.Get(0)->GetBroadcast());
746 }
747 else
748 {
749 socketAddr.SetPhysicalAddress(serverDevice.Get(0)->GetAddress());
750 }
751 // Arbitrary protocol type.
752 // Note: PacketSocket doesn't have any L4 multiplexing or demultiplexing
753 // The only mux/demux is based on the protocol field
754 socketAddr.SetProtocol(1);
755
756 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
757 client->SetRemote(socketAddr);
758 client->SetStartTime(Seconds(0.5)); // allow simulation warmup
759 client->SetAttribute("MaxPackets", UintegerValue(0)); // unlimited
760 client->SetAttribute("PacketSize", UintegerValue(packetSize));
761
762 // Set a maximum rate 10% above the yMax specified for the selected standard
763 double rate = clientSelectedStandard.m_yMax * 1e6 * 1.10;
764 double clientInterval = static_cast<double>(packetSize) * 8 / rate;
765 NS_LOG_DEBUG("Setting interval to " << clientInterval << " sec for rate of " << rate
766 << " bits/sec");
767
768 client->SetAttribute("Interval", TimeValue(Seconds(clientInterval)));
769 clientNode->AddApplication(client);
770
771 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
772 server->SetLocal(socketAddr);
773 server->TraceConnectWithoutContext("Rx", MakeCallback(&PacketRx));
774 serverNode->AddApplication(server);
775
776 Simulator::Stop(Seconds((steps + 1) * stepTime));
777 Simulator::Run();
778 Simulator::Destroy();
779
780 gnuplot.AddDataset(rateDataset);
781 gnuplot.AddDataset(actualDataset);
782
783 std::ostringstream xMinStr;
784 std::ostringstream xMaxStr;
785 std::ostringstream yMaxStr;
786 std::string xRangeStr("set xrange [");
787 xMinStr << clientSelectedStandard.m_xMin;
788 xRangeStr.append(xMinStr.str());
789 xRangeStr.append(":");
790 xMaxStr << clientSelectedStandard.m_xMax;
791 xRangeStr.append(xMaxStr.str());
792 xRangeStr.append("]");
793 std::string yRangeStr("set yrange [0:");
794 yMaxStr << clientSelectedStandard.m_yMax;
795 yRangeStr.append(yMaxStr.str());
796 yRangeStr.append("]");
797
798 std::string title("Results for ");
799 title.append(standard);
800 title.append(" with ");
801 title.append(wifiManager);
802 title.append("\\n");
803 if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz" || standard == "802.11ac" ||
804 standard == "802.11ax-6GHz" || standard == "802.11ax-5GHz" || standard == "802.11ax-2.4GHz")
805 {
806 std::ostringstream serverGiStrStr;
807 std::ostringstream serverWidthStrStr;
808 std::ostringstream serverNssStrStr;
809 title.append("server: width=");
810 serverWidthStrStr << serverSelectedStandard.m_width;
811 title.append(serverWidthStrStr.str());
812 title.append("MHz");
813 title.append(" GI=");
814 serverGiStrStr << serverShortGuardInterval;
815 title.append(serverGiStrStr.str());
816 title.append("ns");
817 title.append(" nss=");
818 serverNssStrStr << serverNss;
819 title.append(serverNssStrStr.str());
820 title.append("\\n");
821 std::ostringstream clientGiStrStr;
822 std::ostringstream clientWidthStrStr;
823 std::ostringstream clientNssStrStr;
824 title.append("client: width=");
825 clientWidthStrStr << clientSelectedStandard.m_width;
826 title.append(clientWidthStrStr.str());
827 title.append("MHz");
828 title.append(" GI=");
829 clientGiStrStr << clientShortGuardInterval;
830 title.append(clientGiStrStr.str());
831 title.append("ns");
832 title.append(" nss=");
833 clientNssStrStr << clientNss;
834 title.append(clientNssStrStr.str());
835 }
836 gnuplot.SetTerminal("postscript eps color enh \"Times-BoldItalic\"");
837 gnuplot.SetLegend("SNR (dB)", "Rate (Mb/s)");
838 gnuplot.SetTitle(title);
839 gnuplot.SetExtra(xRangeStr);
840 gnuplot.AppendExtra(yRangeStr);
841 gnuplot.AppendExtra("set key top left");
842 gnuplot.GenerateOutput(outfile);
843 outfile.close();
844
845 return 0;
846}
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:92
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:232
Class to represent a 2D points plot.
Definition: gnuplot.h:116
void Add(double x, double y)
Definition: gnuplot.cc:377
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:370
void AddDataset(const GnuplotDataset &dataset)
Definition: gnuplot.cc:796
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:776
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:764
void AppendExtra(const std::string &extra)
Definition: gnuplot.cc:789
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:802
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:783
void SetTitle(const std::string &title)
Definition: gnuplot.cc:770
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
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.
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
AttributeValue implementation for Time.
Definition: nstime.h:1425
Hold objects of type std::tuple<Args...>.
Definition: tuple.h:69
void Set(const result_type &value)
Set the stored values.
Definition: tuple.h:318
Hold an unsigned integer type.
Definition: uinteger.h:45
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
helps to create WifiNetDevice objects
Definition: wifi-helper.h:325
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
Hold together all Wifi-related objects.
Ptr< HtConfiguration > GetHtConfiguration() const
Ptr< HeConfiguration > GetHeConfiguration() const
Ptr< WifiPhy > GetPhy() const
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:163
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1175
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1225
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1193
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:869
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:951
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:877
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:275
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1374
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
@ 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.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
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:691
uint16_t GetDefaultChannelWidth(WifiStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
cmd
Definition: second.py:33
ssid
Definition: third.py:86
wifi
Definition: third.py:88
mobility
Definition: third.py:96
StandardInfo structure.
std::string m_name
name
StandardInfo(std::string name, WifiStandard standard, WifiPhyBand band, uint16_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
Constructor.
uint16_t m_width
channel width
double m_yMax
Y maximum.
WifiStandard m_standard
standard
WifiPhyBand m_band
PHY band.
double m_snrHigh
highest SNR
double m_xMax
X maximum.
double m_xMin
X minimum.
double m_snrLow
lowest SNR
Step structure.
double stepSize
step size in dBm
double stepTime
step size in seconds
uint64_t g_intervalRate
Rate in an interval.
void RateChange(uint64_t oldVal, uint64_t newVal)
Rate changed.
const double NOISE_DBM_Hz
Default value for noise.
void PacketRx(Ptr< const Packet > pkt, const Address &addr)
Packet received.
double g_intervalBytes
Bytes received in an interval.
double noiseDbm
Value for noise.
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, Step step, double rss, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
Change the signal model and report the rate.
static const uint32_t packetSize
Packet size generated at the AP.