A Discrete-Event Network Simulator
API
wifi-manager-example.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2016 University of Washington
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Tom Henderson <tomhend@u.washington.edu>
19 * Matías Richart <mrichart@fing.edu.uy>
20 * Sébastien Deronne <sebastien.deronne@gmail.com>
21 */
22
23// Test the operation of a wifi manager as the SNR is varied, and create
24// a gnuplot output file for plotting.
25//
26// The test consists of a device acting as server and a device as client generating traffic.
27//
28// The output consists of a plot of the rate observed and selected at the client device.
29//
30// By default, the 802.11a standard using IdealWifiManager is plotted. Several command line
31// arguments can change the following options:
32// --wifiManager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa, ThompsonSampling)
33// --standard (802.11a, 802.11b, 802.11g, 802.11p-10MHz, 802.11p-5MHz, 802.11n-5GHz, 802.11n-2.4GHz, 802.11ac, 802.11ax-6GHz, 802.11ax-5GHz, 802.11ax-2.4GHz)
34// --serverShortGuardInterval and --clientShortGuardInterval (for 802.11n/ac)
35// --serverNss and --clientNss (for 802.11n/ac)
36// --serverChannelWidth and --clientChannelWidth (for 802.11n/ac)
37// --broadcast instead of unicast (default is unicast)
38// --rtsThreshold (by default, value of 99999 disables it)
39
40#include "ns3/log.h"
41#include "ns3/config.h"
42#include "ns3/uinteger.h"
43#include "ns3/boolean.h"
44#include "ns3/double.h"
45#include "ns3/enum.h"
46#include "ns3/tuple.h"
47#include "ns3/gnuplot.h"
48#include "ns3/command-line.h"
49#include "ns3/yans-wifi-helper.h"
50#include "ns3/ssid.h"
51#include "ns3/propagation-loss-model.h"
52#include "ns3/propagation-delay-model.h"
53#include "ns3/rng-seed-manager.h"
54#include "ns3/mobility-helper.h"
55#include "ns3/wifi-net-device.h"
56#include "ns3/packet-socket-helper.h"
57#include "ns3/packet-socket-client.h"
58#include "ns3/packet-socket-server.h"
59#include "ns3/ht-configuration.h"
60#include "ns3/he-configuration.h"
61
62using namespace ns3;
63
64NS_LOG_COMPONENT_DEFINE ("WifiManagerExample");
65
66// 290K @ 20 MHz
67const double NOISE_DBM_Hz = -174.0;
69
70double g_intervalBytes = 0;
71uint64_t g_intervalRate = 0;
72
73void
75{
76 g_intervalBytes += pkt->GetSize ();
77}
78
79void
80RateChange (uint64_t oldVal, uint64_t newVal)
81{
82 NS_LOG_DEBUG ("Change from " << oldVal << " to " << newVal);
83 g_intervalRate = newVal;
84}
85
87struct Step
88{
89 double stepSize;
90 double stepTime;
91};
92
95{
97 {
98 m_name = "none";
99 }
113 StandardInfo (std::string name, WifiStandard standard, WifiPhyBand band, uint16_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
114 : m_name (name),
115 m_standard (standard),
116 m_band (band),
117 m_width (width),
118 m_snrLow (snrLow),
119 m_snrHigh (snrHigh),
120 m_xMin (xMin),
121 m_xMax (xMax),
122 m_yMax (yMax)
123 {
124 }
125 std::string m_name;
128 uint16_t m_width;
129 double m_snrLow;
130 double m_snrHigh;
131 double m_xMin;
132 double m_xMax;
133 double m_yMax;
134};
135
136void
137ChangeSignalAndReportRate (Ptr<FixedRssLossModel> rssModel, Step step, double rss, Gnuplot2dDataset& rateDataset, Gnuplot2dDataset& actualDataset)
138{
139 NS_LOG_FUNCTION (rssModel << step.stepSize << step.stepTime << rss);
140 double snr = rss - noiseDbm;
141 rateDataset.Add (snr, g_intervalRate / 1e6);
142 // Calculate received rate since last interval
143 double currentRate = ((g_intervalBytes * 8) / step.stepTime) / 1e6; // Mb/s
144 actualDataset.Add (snr, currentRate);
145 rssModel->SetRss (rss - step.stepSize);
146 NS_LOG_INFO ("At time " << Simulator::Now ().As (Time::S) << "; selected rate " << (g_intervalRate / 1e6) << "; observed rate " << currentRate << "; setting new power to " << rss - step.stepSize);
147 g_intervalBytes = 0;
148 Simulator::Schedule (Seconds (step.stepTime), &ChangeSignalAndReportRate, rssModel, step, (rss - step.stepSize), rateDataset, actualDataset);
149}
150
151int main (int argc, char *argv[])
152{
153 std::vector <StandardInfo> serverStandards;
154 std::vector <StandardInfo> clientStandards;
155 uint32_t steps;
156 uint32_t rtsThreshold = 999999; // disabled even for large A-MPDU
157 uint32_t maxAmpduSize = 65535;
158 double stepSize = 1; // dBm
159 double stepTime = 1; // seconds
160 uint32_t packetSize = 1024; // bytes
161 bool broadcast = 0;
162 int ap1_x = 0;
163 int ap1_y = 0;
164 int sta1_x = 5;
165 int sta1_y = 0;
166 uint16_t serverNss = 1;
167 uint16_t clientNss = 1;
168 uint16_t serverShortGuardInterval = 800;
169 uint16_t clientShortGuardInterval = 800;
170 uint16_t serverChannelWidth = 0; // use default for standard and band
171 uint16_t clientChannelWidth = 0; // use default for standard and band
172 std::string wifiManager ("Ideal");
173 std::string standard ("802.11a");
174 StandardInfo serverSelectedStandard;
175 StandardInfo clientSelectedStandard;
176 bool infrastructure = false;
177 uint32_t maxSlrc = 7;
178 uint32_t maxSsrc = 7;
179
180 CommandLine cmd (__FILE__);
181 cmd.AddValue ("maxSsrc", "The maximum number of retransmission attempts for a RTS packet", maxSsrc);
182 cmd.AddValue ("maxSlrc", "The maximum number of retransmission attempts for a Data packet", maxSlrc);
183 cmd.AddValue ("rtsThreshold", "RTS threshold", rtsThreshold);
184 cmd.AddValue ("maxAmpduSize", "Max A-MPDU size", maxAmpduSize);
185 cmd.AddValue ("stepSize", "Power between steps (dBm)", stepSize);
186 cmd.AddValue ("stepTime", "Time on each step (seconds)", stepTime);
187 cmd.AddValue ("broadcast", "Send broadcast instead of unicast", broadcast);
188 cmd.AddValue ("serverChannelWidth", "Set channel width of the server (valid only for 802.11n or ac)", serverChannelWidth);
189 cmd.AddValue ("clientChannelWidth", "Set channel width of the client (valid only for 802.11n or ac)", clientChannelWidth);
190 cmd.AddValue ("serverNss", "Set nss of the server (valid only for 802.11n or ac)", serverNss);
191 cmd.AddValue ("clientNss", "Set nss of the client (valid only for 802.11n or ac)", clientNss);
192 cmd.AddValue ("serverShortGuardInterval", "Set short guard interval of the server (802.11n/ac/ax) in nanoseconds", serverShortGuardInterval);
193 cmd.AddValue ("clientShortGuardInterval", "Set short guard interval of the client (802.11n/ac/ax) in nanoseconds", clientShortGuardInterval);
194 cmd.AddValue ("standard", "Set standard (802.11a, 802.11b, 802.11g, 802.11p-10MHz, 802.11p-5MHz, 802.11n-5GHz, 802.11n-2.4GHz, 802.11ac, 802.11ax-6GHz, 802.11ax-5GHz, 802.11ax-2.4GHz)", standard);
195 cmd.AddValue ("wifiManager", "Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa, ThompsonSampling)", wifiManager);
196 cmd.AddValue ("infrastructure", "Use infrastructure instead of adhoc", infrastructure);
197 cmd.Parse (argc,argv);
198
199 // Print out some explanation of what this program does
200 std::cout << std::endl << "This program demonstrates and plots the operation of different " << std::endl;
201 std::cout << "Wi-Fi rate controls on different station configurations," << std::endl;
202 std::cout << "by stepping down the received signal strength across a wide range" << std::endl;
203 std::cout << "and observing the adjustment of the rate." << std::endl;
204 std::cout << "Run 'wifi-manager-example --PrintHelp' to show program options." << std::endl << std::endl;
205
206 if (infrastructure == false)
207 {
208 NS_ABORT_MSG_IF (serverNss != clientNss, "In ad hoc mode, we assume sender and receiver are similarly configured");
209 }
210
211 if (standard == "802.11b")
212 {
213 if (serverChannelWidth == 0)
214 {
216 }
217 NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22, "Invalid channel width for standard " << standard);
218 NS_ABORT_MSG_IF (serverNss != 1, "Invalid nss for standard " << standard);
219 if (clientChannelWidth == 0)
220 {
222 }
223 NS_ABORT_MSG_IF (clientChannelWidth != 22 && clientChannelWidth != 22, "Invalid channel width for standard " << standard);
224 NS_ABORT_MSG_IF (clientNss != 1, "Invalid nss for standard " << standard);
225 }
226 else if (standard == "802.11a" || standard == "802.11g")
227 {
228 if (serverChannelWidth == 0)
229 {
231 }
232 NS_ABORT_MSG_IF (serverChannelWidth != 20, "Invalid channel width for standard " << standard);
233 NS_ABORT_MSG_IF (serverNss != 1, "Invalid nss for standard " << standard);
234 if (clientChannelWidth == 0)
235 {
237 }
238 NS_ABORT_MSG_IF (clientChannelWidth != 20, "Invalid channel width for standard " << standard);
239 NS_ABORT_MSG_IF (clientNss != 1, "Invalid nss for standard " << standard);
240 }
241 else if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz")
242 {
243 WifiPhyBand band = (standard == "802.11n-2.4GHz" ? WIFI_PHY_BAND_2_4GHZ : WIFI_PHY_BAND_5GHZ);
244 if (serverChannelWidth == 0)
245 {
246 serverChannelWidth = GetDefaultChannelWidth (WIFI_STANDARD_80211n, band);
247 }
248 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40, "Invalid channel width for standard " << standard);
249 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
250 if (clientChannelWidth == 0)
251 {
252 clientChannelWidth = GetDefaultChannelWidth (WIFI_STANDARD_80211n, band);
253 }
254 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40, "Invalid channel width for standard " << standard);
255 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
256 }
257 else if (standard == "802.11ac")
258 {
259 if (serverChannelWidth == 0)
260 {
262 }
263 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, "Invalid channel width for standard " << standard);
264 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
265 if (clientChannelWidth == 0)
266 {
268 }
269 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, "Invalid channel width for standard " << standard);
270 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
271 }
272 else if (standard == "802.11ax-6GHz" ||standard == "802.11ax-5GHz" || standard == "802.11ax-2.4GHz")
273 {
274 WifiPhyBand band = (standard == "802.11ax-2.4GHz" ? WIFI_PHY_BAND_2_4GHZ : standard == "802.11ax-6GHz" ? WIFI_PHY_BAND_6GHZ : WIFI_PHY_BAND_5GHZ);
275 if (serverChannelWidth == 0)
276 {
277 serverChannelWidth = GetDefaultChannelWidth (WIFI_STANDARD_80211ax, band);
278 }
279 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, "Invalid channel width for standard " << standard);
280 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
281 if (clientChannelWidth == 0)
282 {
283 clientChannelWidth = GetDefaultChannelWidth (WIFI_STANDARD_80211ax, band);
284 }
285 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, "Invalid channel width for standard " << standard);
286 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
287 }
288
289 // As channel width increases, scale up plot's yRange value
290 uint32_t channelRateFactor = std::max (clientChannelWidth, serverChannelWidth) / 20;
291 channelRateFactor = channelRateFactor * std::max (clientNss, serverNss);
292
293 // The first number is channel width, second is minimum SNR, third is maximum
294 // SNR, fourth and fifth provide xrange axis limits, and sixth the yaxis
295 // maximum
296 serverStandards.push_back (StandardInfo ("802.11a", WIFI_STANDARD_80211a, WIFI_PHY_BAND_5GHZ, 20, 3, 27, 0, 30, 60));
297 serverStandards.push_back (StandardInfo ("802.11b", WIFI_STANDARD_80211b, WIFI_PHY_BAND_2_4GHZ, 22, -5, 11, -6, 15, 15));
298 serverStandards.push_back (StandardInfo ("802.11g", WIFI_STANDARD_80211g, WIFI_PHY_BAND_2_4GHZ, 20, -5, 27, -6, 30, 60));
299 serverStandards.push_back (StandardInfo ("802.11n-5GHz", WIFI_STANDARD_80211n, WIFI_PHY_BAND_5GHZ, serverChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
300 serverStandards.push_back (StandardInfo ("802.11n-2.4GHz", WIFI_STANDARD_80211n, WIFI_PHY_BAND_2_4GHZ, serverChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
301 serverStandards.push_back (StandardInfo ("802.11ac", WIFI_STANDARD_80211ac, WIFI_PHY_BAND_5GHZ, serverChannelWidth, 5, 50, 0, 55, 120 * channelRateFactor));
302 serverStandards.push_back (StandardInfo ("802.11p-10MHz", WIFI_STANDARD_80211p, WIFI_PHY_BAND_5GHZ, 10, 3, 27, 0, 30, 60));
303 serverStandards.push_back (StandardInfo ("802.11p-5MHz", WIFI_STANDARD_80211p, WIFI_PHY_BAND_5GHZ, 5, 3, 27, 0, 30, 60));
304 serverStandards.push_back (StandardInfo ("802.11ax-6GHz", WIFI_STANDARD_80211ax, WIFI_PHY_BAND_6GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
305 serverStandards.push_back (StandardInfo ("802.11ax-5GHz", WIFI_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
306 serverStandards.push_back (StandardInfo ("802.11ax-2.4GHz", WIFI_STANDARD_80211ax, WIFI_PHY_BAND_2_4GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
307
308 clientStandards.push_back (StandardInfo ("802.11a", WIFI_STANDARD_80211a, WIFI_PHY_BAND_5GHZ, 20, 3, 27, 0, 30, 60));
309 clientStandards.push_back (StandardInfo ("802.11b", WIFI_STANDARD_80211b, WIFI_PHY_BAND_2_4GHZ, 22, -5, 11, -6, 15, 15));
310 clientStandards.push_back (StandardInfo ("802.11g", WIFI_STANDARD_80211g, WIFI_PHY_BAND_2_4GHZ, 20, -5, 27, -6, 30, 60));
311 clientStandards.push_back (StandardInfo ("802.11n-5GHz", WIFI_STANDARD_80211n, WIFI_PHY_BAND_5GHZ, clientChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
312 clientStandards.push_back (StandardInfo ("802.11n-2.4GHz", WIFI_STANDARD_80211n, WIFI_PHY_BAND_2_4GHZ, clientChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
313 clientStandards.push_back (StandardInfo ("802.11ac", WIFI_STANDARD_80211ac, WIFI_PHY_BAND_5GHZ, clientChannelWidth, 5, 50, 0, 55, 120 * channelRateFactor));
314 clientStandards.push_back (StandardInfo ("802.11p-10MHz", WIFI_STANDARD_80211p, WIFI_PHY_BAND_5GHZ, 10, 3, 27, 0, 30, 60));
315 clientStandards.push_back (StandardInfo ("802.11p-5MHz", WIFI_STANDARD_80211p, WIFI_PHY_BAND_5GHZ, 5, 3, 27, 0, 30, 60));
316 clientStandards.push_back (StandardInfo ("802.11ax-6GHz", WIFI_STANDARD_80211ax, WIFI_PHY_BAND_6GHZ, clientChannelWidth, 5, 55, 0, 60, 160 * channelRateFactor));
317 clientStandards.push_back (StandardInfo ("802.11ax-5GHz", WIFI_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ, clientChannelWidth, 5, 55, 0, 60, 160 * channelRateFactor));
318 clientStandards.push_back (StandardInfo ("802.11ax-2.4GHz", WIFI_STANDARD_80211ax, WIFI_PHY_BAND_2_4GHZ, clientChannelWidth, 5, 55, 0, 60, 160 * channelRateFactor));
319
320 for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size (); i++)
321 {
322 if (standard == serverStandards[i].m_name)
323 {
324 serverSelectedStandard = serverStandards[i];
325 }
326 }
327 for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size (); i++)
328 {
329 if (standard == clientStandards[i].m_name)
330 {
331 clientSelectedStandard = clientStandards[i];
332 }
333 }
334
335 NS_ABORT_MSG_IF (serverSelectedStandard.m_name == "none", "Standard " << standard << " not found");
336 NS_ABORT_MSG_IF (clientSelectedStandard.m_name == "none", "Standard " << standard << " not found");
337 std::cout << "Testing " << serverSelectedStandard.m_name << " with " << wifiManager << " ..." << std::endl;
338 NS_ABORT_MSG_IF (clientSelectedStandard.m_snrLow >= clientSelectedStandard.m_snrHigh, "SNR values in wrong order");
339 steps = static_cast<uint32_t> (std::abs (static_cast<double> (clientSelectedStandard.m_snrHigh - clientSelectedStandard.m_snrLow ) / stepSize) + 1);
340 NS_LOG_DEBUG ("Using " << steps << " steps for SNR range " << clientSelectedStandard.m_snrLow << ":" << clientSelectedStandard.m_snrHigh);
341 Ptr<Node> clientNode = CreateObject<Node> ();
342 Ptr<Node> serverNode = CreateObject<Node> ();
343
344 std::string plotName = "wifi-manager-example-";
345 std::string dataName = "wifi-manager-example-";
346 plotName += wifiManager;
347 dataName += wifiManager;
348 plotName += "-";
349 dataName += "-";
350 plotName += standard;
351 dataName += standard;
352 if (standard == "802.11n-5GHz"
353 || standard == "802.11n-2.4GHz"
354 || standard == "802.11ac"
355 || standard == "802.11ax-6GHz"
356 || standard == "802.11ax-5GHz"
357 || standard == "802.11ax-2.4GHz")
358 {
359 plotName += "-server_";
360 dataName += "-server_";
361 std::ostringstream oss;
362 oss << serverChannelWidth << "MHz_" << serverShortGuardInterval << "ns_" << serverNss << "SS";
363 plotName += oss.str ();
364 dataName += oss.str ();
365 plotName += "-client_";
366 dataName += "-client_";
367 oss.str ("");
368 oss << clientChannelWidth << "MHz_" << clientShortGuardInterval << "ns_" << clientNss << "SS";
369 plotName += oss.str ();
370 dataName += oss.str ();
371 }
372 plotName += ".eps";
373 dataName += ".plt";
374 std::ofstream outfile (dataName.c_str ());
375 Gnuplot gnuplot = Gnuplot (plotName);
376
377 Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue (maxSlrc));
378 Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSsrc", UintegerValue (maxSsrc));
379 Config::SetDefault ("ns3::MinstrelWifiManager::PrintStats", BooleanValue (true));
380 Config::SetDefault ("ns3::MinstrelWifiManager::PrintSamples", BooleanValue (true));
381 Config::SetDefault ("ns3::MinstrelHtWifiManager::PrintStats", BooleanValue (true));
382
384 wifi.SetStandard (serverSelectedStandard.m_standard);
385 YansWifiPhyHelper wifiPhy;
386
387 Ptr<YansWifiChannel> wifiChannel = CreateObject<YansWifiChannel> ();
388 Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
389 wifiChannel->SetPropagationDelayModel (delayModel);
390 Ptr<FixedRssLossModel> rssLossModel = CreateObject<FixedRssLossModel> ();
391 wifiChannel->SetPropagationLossModel (rssLossModel);
392 wifiPhy.SetChannel (wifiChannel);
393
394 wifi.SetRemoteStationManager ("ns3::" + wifiManager + "WifiManager", "RtsCtsThreshold", UintegerValue (rtsThreshold));
395
396 NetDeviceContainer serverDevice;
397 NetDeviceContainer clientDevice;
398
400
401 WifiMacHelper wifiMac;
402 if (infrastructure)
403 {
404 Ssid ssid = Ssid ("ns-3-ssid");
405 wifiMac.SetType ("ns3::StaWifiMac",
406 "Ssid", SsidValue (ssid));
407 channelValue.Set (WifiPhy::ChannelTuple {0, serverSelectedStandard.m_width,
408 serverSelectedStandard.m_band, 0});
409 wifiPhy.Set ("ChannelSettings", channelValue);
410 serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
411
412 wifiMac.SetType ("ns3::ApWifiMac",
413 "Ssid", SsidValue (ssid));
414 channelValue.Set (WifiPhy::ChannelTuple {0, clientSelectedStandard.m_width,
415 clientSelectedStandard.m_band, 0});
416 clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
417 }
418 else
419 {
420 wifiMac.SetType ("ns3::AdhocWifiMac");
421 channelValue.Set (WifiPhy::ChannelTuple {0, serverSelectedStandard.m_width,
422 serverSelectedStandard.m_band, 0});
423 wifiPhy.Set ("ChannelSettings", channelValue);
424 serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
425
426 channelValue.Set (WifiPhy::ChannelTuple {0, clientSelectedStandard.m_width,
427 clientSelectedStandard.m_band, 0});
428 clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
429 }
430
431 RngSeedManager::SetSeed (1);
432 RngSeedManager::SetRun (2);
433 wifi.AssignStreams (serverDevice, 100);
434 wifi.AssignStreams (clientDevice, 100);
435
436 Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize", UintegerValue (maxAmpduSize));
437
438 Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::" + wifiManager + "WifiManager/Rate", MakeCallback (&RateChange));
439
440 // Configure the mobility.
442 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
443 //Initial position of AP and STA
444 positionAlloc->Add (Vector (ap1_x, ap1_y, 0.0));
445 NS_LOG_INFO ("Setting initial AP position to " << Vector (ap1_x, ap1_y, 0.0));
446 positionAlloc->Add (Vector (sta1_x, sta1_y, 0.0));
447 NS_LOG_INFO ("Setting initial STA position to " << Vector (sta1_x, sta1_y, 0.0));
448 mobility.SetPositionAllocator (positionAlloc);
449 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
450 mobility.Install (clientNode);
451 mobility.Install (serverNode);
452
453 Gnuplot2dDataset rateDataset (clientSelectedStandard.m_name + std::string ("-rate selected"));
454 Gnuplot2dDataset actualDataset (clientSelectedStandard.m_name + std::string ("-observed"));
455 Step step;
456 step.stepSize = stepSize;
457 step.stepTime = stepTime;
458
459 // Perform post-install configuration from defaults for channel width,
460 // guard interval, and nss, if necessary
461 // Obtain pointer to the WifiPhy
462 Ptr<NetDevice> ndClient = clientDevice.Get (0);
463 Ptr<NetDevice> ndServer = serverDevice.Get (0);
464 Ptr<WifiNetDevice> wndClient = ndClient->GetObject<WifiNetDevice> ();
465 Ptr<WifiNetDevice> wndServer = ndServer->GetObject<WifiNetDevice> ();
466 Ptr<WifiPhy> wifiPhyPtrClient = wndClient->GetPhy ();
467 Ptr<WifiPhy> wifiPhyPtrServer = wndServer->GetPhy ();
468 uint8_t t_clientNss = static_cast<uint8_t> (clientNss);
469 uint8_t t_serverNss = static_cast<uint8_t> (serverNss);
470 wifiPhyPtrClient->SetNumberOfAntennas (t_clientNss);
471 wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams (t_clientNss);
472 wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams (t_clientNss);
473 wifiPhyPtrServer->SetNumberOfAntennas (t_serverNss);
474 wifiPhyPtrServer->SetMaxSupportedTxSpatialStreams (t_serverNss);
475 wifiPhyPtrServer->SetMaxSupportedRxSpatialStreams (t_serverNss);
476 // Only set the guard interval for HT and VHT modes
477 if (serverSelectedStandard.m_name == "802.11n-5GHz"
478 || serverSelectedStandard.m_name == "802.11n-2.4GHz"
479 || serverSelectedStandard.m_name == "802.11ac")
480 {
481 Ptr<HtConfiguration> clientHtConfiguration = wndClient->GetHtConfiguration ();
482 clientHtConfiguration->SetShortGuardIntervalSupported (clientShortGuardInterval == 400);
483 Ptr<HtConfiguration> serverHtConfiguration = wndServer->GetHtConfiguration ();
484 serverHtConfiguration->SetShortGuardIntervalSupported (serverShortGuardInterval == 400);
485 }
486 else if (serverSelectedStandard.m_name == "802.11ax-6GHz"
487 || serverSelectedStandard.m_name == "802.11ax-5GHz"
488 || serverSelectedStandard.m_name == "802.11ax-2.4GHz")
489 {
490 wndServer->GetHeConfiguration ()->SetGuardInterval (NanoSeconds (serverShortGuardInterval));
491 wndClient->GetHeConfiguration ()->SetGuardInterval (NanoSeconds (clientShortGuardInterval));
492 }
493 NS_LOG_DEBUG ("Channel width " << wifiPhyPtrClient->GetChannelWidth () << " noiseDbm " << noiseDbm);
494 NS_LOG_DEBUG ("NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams ());
495
496 // Configure signal and noise, and schedule first iteration
497 noiseDbm += 10 * log10 (clientSelectedStandard.m_width * 1000000);
498 double rssCurrent = (clientSelectedStandard.m_snrHigh + noiseDbm);
499 rssLossModel->SetRss (rssCurrent);
500 NS_LOG_INFO ("Setting initial Rss to " << rssCurrent);
501 //Move the STA by stepsSize meters every stepTime seconds
502 Simulator::Schedule (Seconds (0.5 + stepTime), &ChangeSignalAndReportRate, rssLossModel, step, rssCurrent, rateDataset, actualDataset);
503
504 PacketSocketHelper packetSocketHelper;
505 packetSocketHelper.Install (serverNode);
506 packetSocketHelper.Install (clientNode);
507
508 PacketSocketAddress socketAddr;
509 socketAddr.SetSingleDevice (serverDevice.Get (0)->GetIfIndex ());
510 if (broadcast)
511 {
512 socketAddr.SetPhysicalAddress (serverDevice.Get (0)->GetBroadcast ());
513 }
514 else
515 {
516 socketAddr.SetPhysicalAddress (serverDevice.Get (0)->GetAddress ());
517 }
518 // Arbitrary protocol type.
519 // Note: PacketSocket doesn't have any L4 multiplexing or demultiplexing
520 // The only mux/demux is based on the protocol field
521 socketAddr.SetProtocol (1);
522
523 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
524 client->SetRemote (socketAddr);
525 client->SetStartTime (Seconds (0.5)); // allow simulation warmup
526 client->SetAttribute ("MaxPackets", UintegerValue (0)); // unlimited
527 client->SetAttribute ("PacketSize", UintegerValue (packetSize));
528
529 // Set a maximum rate 10% above the yMax specified for the selected standard
530 double rate = clientSelectedStandard.m_yMax * 1e6 * 1.10;
531 double clientInterval = static_cast<double> (packetSize) * 8 / rate;
532 NS_LOG_DEBUG ("Setting interval to " << clientInterval << " sec for rate of " << rate << " bits/sec");
533
534 client->SetAttribute ("Interval", TimeValue (Seconds (clientInterval)));
535 clientNode->AddApplication (client);
536
537 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
538 server->SetLocal (socketAddr);
539 server->TraceConnectWithoutContext ("Rx", MakeCallback (&PacketRx));
540 serverNode->AddApplication (server);
541
542 Simulator::Stop (Seconds ((steps + 1) * stepTime));
543 Simulator::Run ();
544 Simulator::Destroy ();
545
546 gnuplot.AddDataset (rateDataset);
547 gnuplot.AddDataset (actualDataset);
548
549 std::ostringstream xMinStr, xMaxStr, yMaxStr;
550 std::string xRangeStr ("set xrange [");
551 xMinStr << clientSelectedStandard.m_xMin;
552 xRangeStr.append (xMinStr.str ());
553 xRangeStr.append (":");
554 xMaxStr << clientSelectedStandard.m_xMax;
555 xRangeStr.append (xMaxStr.str ());
556 xRangeStr.append ("]");
557 std::string yRangeStr ("set yrange [0:");
558 yMaxStr << clientSelectedStandard.m_yMax;
559 yRangeStr.append (yMaxStr.str ());
560 yRangeStr.append ("]");
561
562 std::string title ("Results for ");
563 title.append (standard);
564 title.append (" with ");
565 title.append (wifiManager);
566 title.append ("\\n");
567 if (standard == "802.11n-5GHz"
568 || standard == "802.11n-2.4GHz"
569 || standard == "802.11ac"
570 || standard == "802.11ax-6GHz"
571 || standard == "802.11ax-5GHz"
572 || standard == "802.11ax-2.4GHz")
573 {
574 std::ostringstream serverGiStrStr;
575 std::ostringstream serverWidthStrStr;
576 std::ostringstream serverNssStrStr;
577 title.append ("server: width=");
578 serverWidthStrStr << serverSelectedStandard.m_width;
579 title.append (serverWidthStrStr.str ());
580 title.append ("MHz");
581 title.append (" GI=");
582 serverGiStrStr << serverShortGuardInterval;
583 title.append (serverGiStrStr.str ());
584 title.append ("ns");
585 title.append (" nss=");
586 serverNssStrStr << serverNss;
587 title.append (serverNssStrStr.str ());
588 title.append ("\\n");
589 std::ostringstream clientGiStrStr;
590 std::ostringstream clientWidthStrStr;
591 std::ostringstream clientNssStrStr;
592 title.append ("client: width=");
593 clientWidthStrStr << clientSelectedStandard.m_width;
594 title.append (clientWidthStrStr.str ());
595 title.append ("MHz");
596 title.append (" GI=");
597 clientGiStrStr << clientShortGuardInterval;
598 title.append (clientGiStrStr.str ());
599 title.append ("ns");
600 title.append (" nss=");
601 clientNssStrStr << clientNss;
602 title.append (clientNssStrStr.str ());
603 }
604 gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
605 gnuplot.SetLegend ("SNR (dB)", "Rate (Mb/s)");
606 gnuplot.SetTitle (title);
607 gnuplot.SetExtra (xRangeStr);
608 gnuplot.AppendExtra (yRangeStr);
609 gnuplot.AppendExtra ("set key top left");
610 gnuplot.GenerateOutput (outfile);
611 outfile.close ();
612
613 return 0;
614}
615
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:229
Class to represent a 2D points plot.
Definition: gnuplot.h:118
void Add(double x, double y)
Definition: gnuplot.cc:361
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:372
void AddDataset(const GnuplotDataset &dataset)
Definition: gnuplot.cc:758
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:738
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:726
void AppendExtra(const std::string &extra)
Definition: gnuplot.cc:751
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:764
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:745
void SetTitle(const std::string &title)
Definition: gnuplot.cc:732
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.
virtual Address GetBroadcast(void) const =0
virtual Address GetAddress(void) const =0
virtual uint32_t GetIfIndex(void) const =0
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
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:1308
Hold objects of type std::tuple<Args...>.
Definition: tuple.h:70
void Set(const result_type &value)
Set the stored values.
Definition: tuple.h:325
Hold an unsigned integer type.
Definition: uinteger.h:44
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
helps to create WifiNetDevice objects
Definition: wifi-helper.h:323
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
Hold together all Wifi-related objects.
Ptr< HtConfiguration > GetHtConfiguration(void) const
Ptr< WifiPhy > GetPhy(void) const
Ptr< HeConfiguration > GetHeConfiguration(void) const
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:141
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1060
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1105
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1074
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:832
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:849
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:901
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:839
#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:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#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:281
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
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.
uint16_t GetDefaultChannelWidth(WifiStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
cmd
Definition: second.py:35
ssid
Definition: third.py:97
wifi
Definition: third.py:99
mobility
Definition: third.py:107
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
void RateChange(uint64_t oldVal, uint64_t newVal)
const double NOISE_DBM_Hz
void PacketRx(Ptr< const Packet > pkt, const Address &addr)
double g_intervalBytes
double noiseDbm
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, Step step, double rss, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
static const uint32_t packetSize
Pcket size generated at the AP.