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/gnuplot.h"
46 #include "ns3/command-line.h"
47 #include "ns3/yans-wifi-helper.h"
48 #include "ns3/ssid.h"
49 #include "ns3/propagation-loss-model.h"
50 #include "ns3/propagation-delay-model.h"
51 #include "ns3/rng-seed-manager.h"
52 #include "ns3/mobility-helper.h"
53 #include "ns3/wifi-net-device.h"
54 #include "ns3/packet-socket-helper.h"
55 #include "ns3/packet-socket-client.h"
56 #include "ns3/packet-socket-server.h"
57 #include "ns3/ht-configuration.h"
58 #include "ns3/he-configuration.h"
59 
60 using namespace ns3;
61 
62 NS_LOG_COMPONENT_DEFINE ("WifiManagerExample");
63 
64 // 290K @ 20 MHz
65 const double NOISE_DBM_Hz = -174.0;
67 
68 double g_intervalBytes = 0;
69 uint64_t g_intervalRate = 0;
70 
71 void
73 {
74  g_intervalBytes += pkt->GetSize ();
75 }
76 
77 void
78 RateChange (uint64_t oldVal, uint64_t newVal)
79 {
80  NS_LOG_DEBUG ("Change from " << oldVal << " to " << newVal);
81  g_intervalRate = newVal;
82 }
83 
85 struct Step
86 {
87  double stepSize;
88  double stepTime;
89 };
90 
93 {
95  {
96  m_name = "none";
97  }
110  StandardInfo (std::string name, WifiStandard standard, uint16_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
111  : m_name (name),
112  m_standard (standard),
113  m_width (width),
114  m_snrLow (snrLow),
115  m_snrHigh (snrHigh),
116  m_xMin (xMin),
117  m_xMax (xMax),
118  m_yMax (yMax)
119  {
120  }
121  std::string m_name;
123  uint16_t m_width;
124  double m_snrLow;
125  double m_snrHigh;
126  double m_xMin;
127  double m_xMax;
128  double m_yMax;
129 };
130 
131 void
132 ChangeSignalAndReportRate (Ptr<FixedRssLossModel> rssModel, Step step, double rss, Gnuplot2dDataset& rateDataset, Gnuplot2dDataset& actualDataset)
133 {
134  NS_LOG_FUNCTION (rssModel << step.stepSize << step.stepTime << rss);
135  double snr = rss - noiseDbm;
136  rateDataset.Add (snr, g_intervalRate / 1e6);
137  // Calculate received rate since last interval
138  double currentRate = ((g_intervalBytes * 8) / step.stepTime) / 1e6; // Mb/s
139  actualDataset.Add (snr, currentRate);
140  rssModel->SetRss (rss - step.stepSize);
141  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);
142  g_intervalBytes = 0;
143  Simulator::Schedule (Seconds (step.stepTime), &ChangeSignalAndReportRate, rssModel, step, (rss - step.stepSize), rateDataset, actualDataset);
144 }
145 
146 int main (int argc, char *argv[])
147 {
148  std::vector <StandardInfo> serverStandards;
149  std::vector <StandardInfo> clientStandards;
150  uint32_t steps;
151  uint32_t rtsThreshold = 999999; // disabled even for large A-MPDU
152  uint32_t maxAmpduSize = 65535;
153  double stepSize = 1; // dBm
154  double stepTime = 1; // seconds
155  uint32_t packetSize = 1024; // bytes
156  bool broadcast = 0;
157  int ap1_x = 0;
158  int ap1_y = 0;
159  int sta1_x = 5;
160  int sta1_y = 0;
161  uint16_t serverNss = 1;
162  uint16_t clientNss = 1;
163  uint16_t serverShortGuardInterval = 800;
164  uint16_t clientShortGuardInterval = 800;
165  uint16_t serverChannelWidth = 0; // use default for standard and band
166  uint16_t clientChannelWidth = 0; // use default for standard and band
167  std::string wifiManager ("Ideal");
168  std::string standard ("802.11a");
169  StandardInfo serverSelectedStandard;
170  StandardInfo clientSelectedStandard;
171  bool infrastructure = false;
172  uint32_t maxSlrc = 7;
173  uint32_t maxSsrc = 7;
174 
175  CommandLine cmd (__FILE__);
176  cmd.AddValue ("maxSsrc", "The maximum number of retransmission attempts for a RTS packet", maxSsrc);
177  cmd.AddValue ("maxSlrc", "The maximum number of retransmission attempts for a Data packet", maxSlrc);
178  cmd.AddValue ("rtsThreshold", "RTS threshold", rtsThreshold);
179  cmd.AddValue ("maxAmpduSize", "Max A-MPDU size", maxAmpduSize);
180  cmd.AddValue ("stepSize", "Power between steps (dBm)", stepSize);
181  cmd.AddValue ("stepTime", "Time on each step (seconds)", stepTime);
182  cmd.AddValue ("broadcast", "Send broadcast instead of unicast", broadcast);
183  cmd.AddValue ("serverChannelWidth", "Set channel width of the server (valid only for 802.11n or ac)", serverChannelWidth);
184  cmd.AddValue ("clientChannelWidth", "Set channel width of the client (valid only for 802.11n or ac)", clientChannelWidth);
185  cmd.AddValue ("serverNss", "Set nss of the server (valid only for 802.11n or ac)", serverNss);
186  cmd.AddValue ("clientNss", "Set nss of the client (valid only for 802.11n or ac)", clientNss);
187  cmd.AddValue ("serverShortGuardInterval", "Set short guard interval of the server (802.11n/ac/ax) in nanoseconds", serverShortGuardInterval);
188  cmd.AddValue ("clientShortGuardInterval", "Set short guard interval of the client (802.11n/ac/ax) in nanoseconds", clientShortGuardInterval);
189  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);
190  cmd.AddValue ("wifiManager", "Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa, ThompsonSampling)", wifiManager);
191  cmd.AddValue ("infrastructure", "Use infrastructure instead of adhoc", infrastructure);
192  cmd.Parse (argc,argv);
193 
194  // Print out some explanation of what this program does
195  std::cout << std::endl << "This program demonstrates and plots the operation of different " << std::endl;
196  std::cout << "Wi-Fi rate controls on different station configurations," << std::endl;
197  std::cout << "by stepping down the received signal strength across a wide range" << std::endl;
198  std::cout << "and observing the adjustment of the rate." << std::endl;
199  std::cout << "Run 'wifi-manager-example --PrintHelp' to show program options." << std::endl << std::endl;
200 
201  if (infrastructure == false)
202  {
203  NS_ABORT_MSG_IF (serverNss != clientNss, "In ad hoc mode, we assume sender and receiver are similarly configured");
204  }
205 
206  if (standard == "802.11b")
207  {
208  if (serverChannelWidth == 0)
209  {
211  }
212  NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22, "Invalid channel width for standard " << standard);
213  NS_ABORT_MSG_IF (serverNss != 1, "Invalid nss for standard " << standard);
214  if (clientChannelWidth == 0)
215  {
217  }
218  NS_ABORT_MSG_IF (clientChannelWidth != 22 && clientChannelWidth != 22, "Invalid channel width for standard " << standard);
219  NS_ABORT_MSG_IF (clientNss != 1, "Invalid nss for standard " << standard);
220  }
221  else if (standard == "802.11a" || standard == "802.11g")
222  {
223  if (serverChannelWidth == 0)
224  {
226  }
227  NS_ABORT_MSG_IF (serverChannelWidth != 20, "Invalid channel width for standard " << standard);
228  NS_ABORT_MSG_IF (serverNss != 1, "Invalid nss for standard " << standard);
229  if (clientChannelWidth == 0)
230  {
232  }
233  NS_ABORT_MSG_IF (clientChannelWidth != 20, "Invalid channel width for standard " << standard);
234  NS_ABORT_MSG_IF (clientNss != 1, "Invalid nss for standard " << standard);
235  }
236  else if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz")
237  {
238  WifiPhyBand band = (standard == "802.11n-2.4GHz" ? WIFI_PHY_BAND_2_4GHZ : WIFI_PHY_BAND_5GHZ);
239  if (serverChannelWidth == 0)
240  {
241  serverChannelWidth = GetDefaultChannelWidth (WIFI_PHY_STANDARD_80211n, band);
242  }
243  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40, "Invalid channel width for standard " << standard);
244  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
245  if (clientChannelWidth == 0)
246  {
247  clientChannelWidth = GetDefaultChannelWidth (WIFI_PHY_STANDARD_80211n, band);
248  }
249  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40, "Invalid channel width for standard " << standard);
250  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
251  }
252  else if (standard == "802.11ac")
253  {
254  if (serverChannelWidth == 0)
255  {
257  }
258  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, "Invalid channel width for standard " << standard);
259  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
260  if (clientChannelWidth == 0)
261  {
263  }
264  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, "Invalid channel width for standard " << standard);
265  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
266  }
267  else if (standard == "802.11ax-6GHz" ||standard == "802.11ax-5GHz" || standard == "802.11ax-2.4GHz")
268  {
269  WifiPhyBand band = (standard == "802.11ax-2.4GHz" ? WIFI_PHY_BAND_2_4GHZ : standard == "802.11ax-6GHz" ? WIFI_PHY_BAND_6GHZ : WIFI_PHY_BAND_5GHZ);
270  if (serverChannelWidth == 0)
271  {
272  serverChannelWidth = GetDefaultChannelWidth (WIFI_PHY_STANDARD_80211ax, band);
273  }
274  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, "Invalid channel width for standard " << standard);
275  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
276  if (clientChannelWidth == 0)
277  {
278  clientChannelWidth = GetDefaultChannelWidth (WIFI_PHY_STANDARD_80211ax, band);
279  }
280  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, "Invalid channel width for standard " << standard);
281  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
282  }
283 
284  // As channel width increases, scale up plot's yRange value
285  uint32_t channelRateFactor = std::max (clientChannelWidth, serverChannelWidth) / 20;
286  channelRateFactor = channelRateFactor * std::max (clientNss, serverNss);
287 
288  // The first number is channel width, second is minimum SNR, third is maximum
289  // SNR, fourth and fifth provide xrange axis limits, and sixth the yaxis
290  // maximum
291  serverStandards.push_back (StandardInfo ("802.11a", WIFI_STANDARD_80211a, 20, 3, 27, 0, 30, 60));
292  serverStandards.push_back (StandardInfo ("802.11b", WIFI_STANDARD_80211b, 22, -5, 11, -6, 15, 15));
293  serverStandards.push_back (StandardInfo ("802.11g", WIFI_STANDARD_80211g, 20, -5, 27, -6, 30, 60));
294  serverStandards.push_back (StandardInfo ("802.11n-5GHz", WIFI_STANDARD_80211n_5GHZ, serverChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
295  serverStandards.push_back (StandardInfo ("802.11n-2.4GHz", WIFI_STANDARD_80211n_2_4GHZ, serverChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
296  serverStandards.push_back (StandardInfo ("802.11ac", WIFI_STANDARD_80211ac, serverChannelWidth, 5, 50, 0, 55, 120 * channelRateFactor));
297  serverStandards.push_back (StandardInfo ("802.11p-10MHz", WIFI_STANDARD_80211p, 10, 3, 27, 0, 30, 60));
298  serverStandards.push_back (StandardInfo ("802.11p-5MHz", WIFI_STANDARD_80211p, 5, 3, 27, 0, 30, 60));
299  serverStandards.push_back (StandardInfo ("802.11ax-6GHz", WIFI_STANDARD_80211ax_6GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
300  serverStandards.push_back (StandardInfo ("802.11ax-5GHz", WIFI_STANDARD_80211ax_5GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
301  serverStandards.push_back (StandardInfo ("802.11ax-2.4GHz", WIFI_STANDARD_80211ax_2_4GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
302 
303  clientStandards.push_back (StandardInfo ("802.11a", WIFI_STANDARD_80211a, 20, 3, 27, 0, 30, 60));
304  clientStandards.push_back (StandardInfo ("802.11b", WIFI_STANDARD_80211b, 22, -5, 11, -6, 15, 15));
305  clientStandards.push_back (StandardInfo ("802.11g", WIFI_STANDARD_80211g, 20, -5, 27, -6, 30, 60));
306  clientStandards.push_back (StandardInfo ("802.11n-5GHz", WIFI_STANDARD_80211n_5GHZ, clientChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
307  clientStandards.push_back (StandardInfo ("802.11n-2.4GHz", WIFI_STANDARD_80211n_2_4GHZ, clientChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
308  clientStandards.push_back (StandardInfo ("802.11ac", WIFI_STANDARD_80211ac, clientChannelWidth, 5, 50, 0, 55, 120 * channelRateFactor));
309  clientStandards.push_back (StandardInfo ("802.11p-10MHz", WIFI_STANDARD_80211p, 10, 3, 27, 0, 30, 60));
310  clientStandards.push_back (StandardInfo ("802.11p-5MHz", WIFI_STANDARD_80211p, 5, 3, 27, 0, 30, 60));
311  clientStandards.push_back (StandardInfo ("802.11ax-6GHz", WIFI_STANDARD_80211ax_6GHZ, clientChannelWidth, 5, 55, 0, 60, 160 * channelRateFactor));
312  clientStandards.push_back (StandardInfo ("802.11ax-5GHz", WIFI_STANDARD_80211ax_5GHZ, clientChannelWidth, 5, 55, 0, 60, 160 * channelRateFactor));
313  clientStandards.push_back (StandardInfo ("802.11ax-2.4GHz", WIFI_STANDARD_80211ax_2_4GHZ, clientChannelWidth, 5, 55, 0, 60, 160 * channelRateFactor));
314 
315  for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size (); i++)
316  {
317  if (standard == serverStandards[i].m_name)
318  {
319  serverSelectedStandard = serverStandards[i];
320  }
321  }
322  for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size (); i++)
323  {
324  if (standard == clientStandards[i].m_name)
325  {
326  clientSelectedStandard = clientStandards[i];
327  }
328  }
329 
330  NS_ABORT_MSG_IF (serverSelectedStandard.m_name == "none", "Standard " << standard << " not found");
331  NS_ABORT_MSG_IF (clientSelectedStandard.m_name == "none", "Standard " << standard << " not found");
332  std::cout << "Testing " << serverSelectedStandard.m_name << " with " << wifiManager << " ..." << std::endl;
333  NS_ABORT_MSG_IF (clientSelectedStandard.m_snrLow >= clientSelectedStandard.m_snrHigh, "SNR values in wrong order");
334  steps = static_cast<uint32_t> (std::abs (static_cast<double> (clientSelectedStandard.m_snrHigh - clientSelectedStandard.m_snrLow ) / stepSize) + 1);
335  NS_LOG_DEBUG ("Using " << steps << " steps for SNR range " << clientSelectedStandard.m_snrLow << ":" << clientSelectedStandard.m_snrHigh);
336  Ptr<Node> clientNode = CreateObject<Node> ();
337  Ptr<Node> serverNode = CreateObject<Node> ();
338 
339  std::string plotName = "wifi-manager-example-";
340  std::string dataName = "wifi-manager-example-";
341  plotName += wifiManager;
342  dataName += wifiManager;
343  plotName += "-";
344  dataName += "-";
345  plotName += standard;
346  dataName += standard;
347  if (standard == "802.11n-5GHz"
348  || standard == "802.11n-2.4GHz"
349  || standard == "802.11ac"
350  || standard == "802.11ax-6GHz"
351  || standard == "802.11ax-5GHz"
352  || standard == "802.11ax-2.4GHz")
353  {
354  plotName += "-server_";
355  dataName += "-server_";
356  std::ostringstream oss;
357  oss << serverChannelWidth << "MHz_" << serverShortGuardInterval << "ns_" << serverNss << "SS";
358  plotName += oss.str ();
359  dataName += oss.str ();
360  plotName += "-client_";
361  dataName += "-client_";
362  oss.str ("");
363  oss << clientChannelWidth << "MHz_" << clientShortGuardInterval << "ns_" << clientNss << "SS";
364  plotName += oss.str ();
365  dataName += oss.str ();
366  }
367  plotName += ".eps";
368  dataName += ".plt";
369  std::ofstream outfile (dataName.c_str ());
370  Gnuplot gnuplot = Gnuplot (plotName);
371 
372  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue (maxSlrc));
373  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSsrc", UintegerValue (maxSsrc));
374  Config::SetDefault ("ns3::MinstrelWifiManager::PrintStats", BooleanValue (true));
375  Config::SetDefault ("ns3::MinstrelWifiManager::PrintSamples", BooleanValue (true));
376  Config::SetDefault ("ns3::MinstrelHtWifiManager::PrintStats", BooleanValue (true));
377 
379  wifi.SetStandard (serverSelectedStandard.m_standard);
380  YansWifiPhyHelper wifiPhy;
381 
382  Ptr<YansWifiChannel> wifiChannel = CreateObject<YansWifiChannel> ();
383  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
384  wifiChannel->SetPropagationDelayModel (delayModel);
385  Ptr<FixedRssLossModel> rssLossModel = CreateObject<FixedRssLossModel> ();
386  wifiChannel->SetPropagationLossModel (rssLossModel);
387  wifiPhy.SetChannel (wifiChannel);
388 
389  wifi.SetRemoteStationManager ("ns3::" + wifiManager + "WifiManager", "RtsCtsThreshold", UintegerValue (rtsThreshold));
390 
391  NetDeviceContainer serverDevice;
392  NetDeviceContainer clientDevice;
393 
394  WifiMacHelper wifiMac;
395  if (infrastructure)
396  {
397  Ssid ssid = Ssid ("ns-3-ssid");
398  wifiMac.SetType ("ns3::StaWifiMac",
399  "Ssid", SsidValue (ssid));
400  wifiPhy.Set ("ChannelWidth", UintegerValue (serverSelectedStandard.m_width));
401  serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
402  wifiMac.SetType ("ns3::ApWifiMac",
403  "Ssid", SsidValue (ssid));
404  wifiPhy.Set ("ChannelWidth", UintegerValue (clientSelectedStandard.m_width));
405  clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
406  }
407  else
408  {
409  wifiMac.SetType ("ns3::AdhocWifiMac");
410  wifiPhy.Set ("ChannelWidth", UintegerValue (serverSelectedStandard.m_width));
411  serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
412  wifiPhy.Set ("ChannelWidth", UintegerValue (clientSelectedStandard.m_width));
413  clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
414  }
415 
418  wifi.AssignStreams (serverDevice, 100);
419  wifi.AssignStreams (clientDevice, 100);
420 
421  Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize", UintegerValue (maxAmpduSize));
422 
423  Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::" + wifiManager + "WifiManager/Rate", MakeCallback (&RateChange));
424 
425  // Configure the mobility.
427  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
428  //Initial position of AP and STA
429  positionAlloc->Add (Vector (ap1_x, ap1_y, 0.0));
430  NS_LOG_INFO ("Setting initial AP position to " << Vector (ap1_x, ap1_y, 0.0));
431  positionAlloc->Add (Vector (sta1_x, sta1_y, 0.0));
432  NS_LOG_INFO ("Setting initial STA position to " << Vector (sta1_x, sta1_y, 0.0));
433  mobility.SetPositionAllocator (positionAlloc);
434  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
435  mobility.Install (clientNode);
436  mobility.Install (serverNode);
437 
438  Gnuplot2dDataset rateDataset (clientSelectedStandard.m_name + std::string ("-rate selected"));
439  Gnuplot2dDataset actualDataset (clientSelectedStandard.m_name + std::string ("-observed"));
440  Step step;
441  step.stepSize = stepSize;
442  step.stepTime = stepTime;
443 
444  // Perform post-install configuration from defaults for channel width,
445  // guard interval, and nss, if necessary
446  // Obtain pointer to the WifiPhy
447  Ptr<NetDevice> ndClient = clientDevice.Get (0);
448  Ptr<NetDevice> ndServer = serverDevice.Get (0);
449  Ptr<WifiNetDevice> wndClient = ndClient->GetObject<WifiNetDevice> ();
450  Ptr<WifiNetDevice> wndServer = ndServer->GetObject<WifiNetDevice> ();
451  Ptr<WifiPhy> wifiPhyPtrClient = wndClient->GetPhy ();
452  Ptr<WifiPhy> wifiPhyPtrServer = wndServer->GetPhy ();
453  uint8_t t_clientNss = static_cast<uint8_t> (clientNss);
454  uint8_t t_serverNss = static_cast<uint8_t> (serverNss);
455  wifiPhyPtrClient->SetNumberOfAntennas (t_clientNss);
456  wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams (t_clientNss);
457  wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams (t_clientNss);
458  wifiPhyPtrServer->SetNumberOfAntennas (t_serverNss);
459  wifiPhyPtrServer->SetMaxSupportedTxSpatialStreams (t_serverNss);
460  wifiPhyPtrServer->SetMaxSupportedRxSpatialStreams (t_serverNss);
461  // Only set the guard interval for HT and VHT modes
462  if (serverSelectedStandard.m_name == "802.11n-5GHz"
463  || serverSelectedStandard.m_name == "802.11n-2.4GHz"
464  || serverSelectedStandard.m_name == "802.11ac")
465  {
466  Ptr<HtConfiguration> clientHtConfiguration = wndClient->GetHtConfiguration ();
467  clientHtConfiguration->SetShortGuardIntervalSupported (clientShortGuardInterval == 400);
468  Ptr<HtConfiguration> serverHtConfiguration = wndServer->GetHtConfiguration ();
469  serverHtConfiguration->SetShortGuardIntervalSupported (serverShortGuardInterval == 400);
470  }
471  else if (serverSelectedStandard.m_name == "802.11ax-6GHz"
472  || serverSelectedStandard.m_name == "802.11ax-5GHz"
473  || serverSelectedStandard.m_name == "802.11ax-2.4GHz")
474  {
475  wndServer->GetHeConfiguration ()->SetGuardInterval (NanoSeconds (serverShortGuardInterval));
476  wndClient->GetHeConfiguration ()->SetGuardInterval (NanoSeconds (clientShortGuardInterval));
477  }
478  NS_LOG_DEBUG ("Channel width " << wifiPhyPtrClient->GetChannelWidth () << " noiseDbm " << noiseDbm);
479  NS_LOG_DEBUG ("NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams ());
480 
481  // Configure signal and noise, and schedule first iteration
482  noiseDbm += 10 * log10 (clientSelectedStandard.m_width * 1000000);
483  double rssCurrent = (clientSelectedStandard.m_snrHigh + noiseDbm);
484  rssLossModel->SetRss (rssCurrent);
485  NS_LOG_INFO ("Setting initial Rss to " << rssCurrent);
486  //Move the STA by stepsSize meters every stepTime seconds
487  Simulator::Schedule (Seconds (0.5 + stepTime), &ChangeSignalAndReportRate, rssLossModel, step, rssCurrent, rateDataset, actualDataset);
488 
489  PacketSocketHelper packetSocketHelper;
490  packetSocketHelper.Install (serverNode);
491  packetSocketHelper.Install (clientNode);
492 
493  PacketSocketAddress socketAddr;
494  socketAddr.SetSingleDevice (serverDevice.Get (0)->GetIfIndex ());
495  if (broadcast)
496  {
497  socketAddr.SetPhysicalAddress (serverDevice.Get (0)->GetBroadcast ());
498  }
499  else
500  {
501  socketAddr.SetPhysicalAddress (serverDevice.Get (0)->GetAddress ());
502  }
503  // Arbitrary protocol type.
504  // Note: PacketSocket doesn't have any L4 multiplexing or demultiplexing
505  // The only mux/demux is based on the protocol field
506  socketAddr.SetProtocol (1);
507 
508  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
509  client->SetRemote (socketAddr);
510  client->SetStartTime (Seconds (0.5)); // allow simulation warmup
511  client->SetAttribute ("MaxPackets", UintegerValue (0)); // unlimited
512  client->SetAttribute ("PacketSize", UintegerValue (packetSize));
513 
514  // Set a maximum rate 10% above the yMax specified for the selected standard
515  double rate = clientSelectedStandard.m_yMax * 1e6 * 1.10;
516  double clientInterval = static_cast<double> (packetSize) * 8 / rate;
517  NS_LOG_DEBUG ("Setting interval to " << clientInterval << " sec for rate of " << rate << " bits/sec");
518 
519  client->SetAttribute ("Interval", TimeValue (Seconds (clientInterval)));
520  clientNode->AddApplication (client);
521 
522  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
523  server->SetLocal (socketAddr);
524  server->TraceConnectWithoutContext ("Rx", MakeCallback (&PacketRx));
525  serverNode->AddApplication (server);
526 
527  Simulator::Stop (Seconds ((steps + 1) * stepTime));
528  Simulator::Run ();
530 
531  gnuplot.AddDataset (rateDataset);
532  gnuplot.AddDataset (actualDataset);
533 
534  std::ostringstream xMinStr, xMaxStr, yMaxStr;
535  std::string xRangeStr ("set xrange [");
536  xMinStr << clientSelectedStandard.m_xMin;
537  xRangeStr.append (xMinStr.str ());
538  xRangeStr.append (":");
539  xMaxStr << clientSelectedStandard.m_xMax;
540  xRangeStr.append (xMaxStr.str ());
541  xRangeStr.append ("]");
542  std::string yRangeStr ("set yrange [0:");
543  yMaxStr << clientSelectedStandard.m_yMax;
544  yRangeStr.append (yMaxStr.str ());
545  yRangeStr.append ("]");
546 
547  std::string title ("Results for ");
548  title.append (standard);
549  title.append (" with ");
550  title.append (wifiManager);
551  title.append ("\\n");
552  if (standard == "802.11n-5GHz"
553  || standard == "802.11n-2.4GHz"
554  || standard == "802.11ac"
555  || standard == "802.11ax-6GHz"
556  || standard == "802.11ax-5GHz"
557  || standard == "802.11ax-2.4GHz")
558  {
559  std::ostringstream serverGiStrStr;
560  std::ostringstream serverWidthStrStr;
561  std::ostringstream serverNssStrStr;
562  title.append ("server: width=");
563  serverWidthStrStr << serverSelectedStandard.m_width;
564  title.append (serverWidthStrStr.str ());
565  title.append ("MHz");
566  title.append (" GI=");
567  serverGiStrStr << serverShortGuardInterval;
568  title.append (serverGiStrStr.str ());
569  title.append ("ns");
570  title.append (" nss=");
571  serverNssStrStr << serverNss;
572  title.append (serverNssStrStr.str ());
573  title.append ("\\n");
574  std::ostringstream clientGiStrStr;
575  std::ostringstream clientWidthStrStr;
576  std::ostringstream clientNssStrStr;
577  title.append ("client: width=");
578  clientWidthStrStr << clientSelectedStandard.m_width;
579  title.append (clientWidthStrStr.str ());
580  title.append ("MHz");
581  title.append (" GI=");
582  clientGiStrStr << clientShortGuardInterval;
583  title.append (clientGiStrStr.str ());
584  title.append ("ns");
585  title.append (" nss=");
586  clientNssStrStr << clientNss;
587  title.append (clientNssStrStr.str ());
588  }
589  gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
590  gnuplot.SetLegend ("SNR (dB)", "Rate (Mb/s)");
591  gnuplot.SetTitle (title);
592  gnuplot.SetExtra (xRangeStr);
593  gnuplot.AppendExtra (yRangeStr);
594  gnuplot.AppendExtra ("set key top left");
595  gnuplot.GenerateOutput (outfile);
596  outfile.close ();
597 
598  return 0;
599 }
600 
#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:228
Class to represent a 2D points plot.
Definition: gnuplot.h:118
void Add(double x, double y)
Definition: gnuplot.cc:359
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:756
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:736
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:724
void AppendExtra(const std::string &extra)
Definition: gnuplot.cc:749
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:762
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:743
void SetTitle(const std::string &title)
Definition: gnuplot.cc:730
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:159
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
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.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:105
@ S
second
Definition: nstime.h:115
AttributeValue implementation for Time.
Definition: nstime.h:1353
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:327
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:140
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1364
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1409
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1378
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 NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
WifiStandard
Identifies the allowed configurations that a Wifi device is configured to use.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
@ WIFI_PHY_STANDARD_80211b
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
@ WIFI_PHY_STANDARD_80211ac
VHT PHY (clause 22)
@ WIFI_PHY_STANDARD_80211ax
HE PHY (clause 26)
@ WIFI_PHY_STANDARD_80211g
ERP-OFDM PHY (Clause 19, Section 19.5)
@ WIFI_PHY_STANDARD_80211n
HT PHY (clause 20)
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211n_5GHZ
@ WIFI_STANDARD_80211ax_5GHZ
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211n_2_4GHZ
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax_2_4GHZ
@ WIFI_STANDARD_80211ax_6GHZ
@ 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(WifiPhyStandard 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:1642
cmd
Definition: second.py:35
ssid
Definition: third.py:100
wifi
Definition: third.py:96
mobility
Definition: third.py:108
StandardInfo structure.
std::string m_name
name
StandardInfo(std::string name, WifiStandard standard, 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
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