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);
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 
ERP-OFDM PHY (Clause 19, Section 19.5)
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:140
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetType(std::string type, Args &&... args)
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Ptr< HeConfiguration > GetHeConfiguration(void) const
void SetLocal(PacketSocketAddress addr)
set the local address and protocol to be used
void SetPropagationLossModel(const Ptr< PropagationLossModel > loss)
Class to represent a 2D points plot.
Definition: gnuplot.h:117
double m_yMax
Y maximum.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
Make it easy to create and manage PHY objects for the YANS model.
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:839
static const uint32_t packetSize
void SetShortGuardIntervalSupported(bool enable)
Enable or disable SGI support.
an address for a packet socket
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
double m_snrLow
lowest SNR
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
cmd
Definition: second.py:35
const double NOISE_DBM_Hz
The 5 GHz band.
Definition: wifi-phy-band.h:37
double stepSize
step size in dBm
helps to create WifiNetDevice objects
Definition: wifi-helper.h:326
Give ns3::PacketSocket powers to ns3::Node.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
static void SetRun(uint64_t run)
Set the run number of simulation.
a polymophic address class
Definition: address.h:90
mobility
Definition: third.py:108
void SetChannel(Ptr< YansWifiChannel > channel)
void SetPropagationDelayModel(const Ptr< PropagationDelayModel > delay)
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:371
#define max(a, b)
Definition: 80211b.c:43
AttributeValue implementation for Time.
Definition: nstime.h:1353
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
Hold an unsigned integer type.
Definition: uinteger.h:44
Step structure.
ssid
Definition: third.py:100
holds a vector of ns3::NetDevice pointers
WifiStandard m_standard
standard
std::string m_name
name
Hold together all Wifi-related objects.
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, Step step, double rss, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:901
void Add(double x, double y)
Definition: gnuplot.cc:359
void PacketRx(Ptr< const Packet > pkt, const Address &addr)
Parse command-line arguments.
Definition: command-line.h:227
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
double m_snrHigh
highest SNR
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
double noiseDbm
Ptr< WifiPhy > GetPhy(void) const
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPhysicalAddress(const Address address)
Set the destination address.
WifiStandard
Identifies the allowed configurations that a Wifi device is configured to use.
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1409
create MAC layers for a ns3::WifiNetDevice.
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
double m_xMax
X maximum.
static void SetSeed(uint32_t seed)
Set the seed.
StandardInfo structure.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:32
wifi
Definition: third.py:96
Helper class used to assign positions and mobility models to nodes.
uint16_t m_width
channel width
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1378
double m_xMin
X minimum.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
void SetRemote(PacketSocketAddress addr)
set the remote address and protocol to be used
uint16_t GetDefaultChannelWidth(WifiPhyStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
double g_intervalBytes
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
AttributeValue implementation for Ssid.
Definition: ssid.h:105
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
double stepTime
step size in seconds
void SetProtocol(uint16_t protocol)
Set the protocol.
void Add(Vector v)
Add a position to the list of positions.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
StandardInfo(std::string name, WifiStandard standard, uint16_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
Constructor.
The 6 GHz band.
Definition: wifi-phy-band.h:39
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1364
second
Definition: nstime.h:115
void RateChange(uint64_t oldVal, uint64_t newVal)
uint64_t g_intervalRate
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
Ptr< HtConfiguration > GetHtConfiguration(void) const
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
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