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)
33 // --standard (802.11a, 802.11b, 802.11g, 802.11n-5GHz, 802.11n-2.4GHz, 802.11ac, 802.11-holland, 802.11-10MHz, 802.11-5MHz)
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/core-module.h"
41 #include "ns3/network-module.h"
42 #include "ns3/wifi-module.h"
43 #include "ns3/stats-module.h"
44 #include "ns3/mobility-module.h"
45 #include "ns3/propagation-module.h"
46 #include "ns3/rng-seed-manager.h"
47 
48 using namespace ns3;
49 
50 NS_LOG_COMPONENT_DEFINE ("WifiManagerExample");
51 
52 // 290K @ 20 MHz
53 const double NOISE_DBM_Hz = -174.0;
55 
56 double g_intervalBytes = 0;
57 uint64_t g_intervalRate = 0;
58 
59 void
61 {
62  NS_LOG_DEBUG ("Received size " << pkt->GetSize ());
63  g_intervalBytes += pkt->GetSize ();
64 }
65 
66 void
67 RateChange (uint64_t oldVal, uint64_t newVal)
68 {
69  NS_LOG_DEBUG ("Change from " << oldVal << " to " << newVal);
70  g_intervalRate = newVal;
71 }
72 
73 void
74 RateChangeMinstrelHt (uint64_t newVal, Mac48Address dest)
75 {
76  NS_LOG_DEBUG ("Change to " << newVal);
77  g_intervalRate = newVal;
78 }
79 
81 struct Step
82 {
83  double stepSize;
84  double stepTime;
85 };
86 
89 {
91  {
92  m_name = "none";
93  }
106  StandardInfo (std::string name, WifiPhyStandard standard, uint8_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
107  : m_name (name),
108  m_standard (standard),
109  m_width (width),
110  m_snrLow (snrLow),
111  m_snrHigh (snrHigh),
112  m_xMin (xMin),
113  m_xMax (xMax),
114  m_yMax (yMax)
115  {
116  }
117  std::string m_name;
119  uint8_t m_width;
120  double m_snrLow;
121  double m_snrHigh;
122  double m_xMin;
123  double m_xMax;
124  double m_yMax;
125 };
126 
127 void
128 ChangeSignalAndReportRate (Ptr<FixedRssLossModel> rssModel, struct Step step, double rss, Gnuplot2dDataset& rateDataset, Gnuplot2dDataset& actualDataset)
129 {
130  NS_LOG_FUNCTION (rssModel << step.stepSize << step.stepTime << rss);
131  double snr = rss - noiseDbm;
132  rateDataset.Add (snr, g_intervalRate / 1000000.0);
133  // Calculate received rate since last interval
134  double currentRate = ((g_intervalBytes * 8) / step.stepTime) / 1e6; // Mb/s
135  actualDataset.Add (snr, currentRate);
136  rssModel->SetRss (rss - step.stepSize);
137  NS_LOG_INFO ("At time " << Simulator::Now ().As (Time::S) << "; observed rate " << currentRate << "; setting new power to " << rss - step.stepSize);
138  g_intervalBytes = 0;
139  Simulator::Schedule (Seconds (step.stepTime), &ChangeSignalAndReportRate, rssModel, step, (rss - step.stepSize), rateDataset, actualDataset);
140 }
141 
142 int main (int argc, char *argv[])
143 {
144  std::vector <StandardInfo> serverStandards;
145  std::vector <StandardInfo> clientStandards;
146  uint32_t steps;
147  uint32_t rtsThreshold = 999999; // disabled even for large A-MPDU
148  uint32_t maxAmpduSize = 65535;
149  double stepSize = 1; // dBm
150  double stepTime = 1; // seconds
151  uint32_t packetSize = 1024; // bytes
152  bool broadcast = 0;
153  int ap1_x = 0;
154  int ap1_y = 0;
155  int sta1_x = 5;
156  int sta1_y = 0;
157  uint16_t serverNss = 1;
158  uint16_t clientNss = 1;
159  uint16_t serverShortGuardInterval = 800;
160  uint16_t clientShortGuardInterval = 800;
161  uint16_t serverChannelWidth = 20;
162  uint16_t clientChannelWidth = 20;
163  std::string wifiManager ("Ideal");
164  std::string standard ("802.11a");
165  StandardInfo serverSelectedStandard;
166  StandardInfo clientSelectedStandard;
167  bool infrastructure = false;
168  uint32_t maxSlrc = 7;
169  uint32_t maxSsrc = 7;
170 
172  cmd.AddValue ("maxSsrc", "The maximum number of retransmission attempts for a RTS packet", maxSsrc);
173  cmd.AddValue ("maxSlrc", "The maximum number of retransmission attempts for a DATA packet", maxSlrc);
174  cmd.AddValue ("rtsThreshold", "RTS threshold", rtsThreshold);
175  cmd.AddValue ("maxAmpduSize", "Max A-MPDU size", maxAmpduSize);
176  cmd.AddValue ("stepSize", "Power between steps (dBm)", stepSize);
177  cmd.AddValue ("stepTime", "Time on each step (seconds)", stepTime);
178  cmd.AddValue ("broadcast", "Send broadcast instead of unicast", broadcast);
179  cmd.AddValue ("serverChannelWidth", "Set channel width of the server (valid only for 802.11n or ac)", serverChannelWidth);
180  cmd.AddValue ("clientChannelWidth", "Set channel width of the client (valid only for 802.11n or ac)", clientChannelWidth);
181  cmd.AddValue ("serverNss", "Set nss of the server (valid only for 802.11n or ac)", serverNss);
182  cmd.AddValue ("clientNss", "Set nss of the client (valid only for 802.11n or ac)", clientNss);
183  cmd.AddValue ("serverShortGuardInterval", "Set short guard interval of the server (802.11n/ac/ax) in nanoseconds", serverShortGuardInterval);
184  cmd.AddValue ("clientShortGuardInterval", "Set short guard interval of the client (802.11n/ac/ax) in nanoseconds", clientShortGuardInterval);
185  cmd.AddValue ("standard", "Set standard (802.11a, 802.11b, 802.11g, 802.11n-5GHz, 802.11n-2.4GHz, 802.11ac, 802.11-holland, 802.11-10MHz, 802.11-5MHz, 802.11ax-5GHz, 802.11ax-2.4GHz)", standard);
186  cmd.AddValue ("wifiManager", "Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa)", wifiManager);
187  cmd.AddValue ("infrastructure", "Use infrastructure instead of adhoc", infrastructure);
188  cmd.Parse (argc,argv);
189 
190  // Print out some explanation of what this program does
191  std::cout << std::endl << "This program demonstrates and plots the operation of different " << std::endl;
192  std::cout << "Wi-Fi rate controls on different station configurations," << std::endl;
193  std::cout << "by stepping down the received signal strength across a wide range" << std::endl;
194  std::cout << "and observing the adjustment of the rate." << std::endl;
195  std::cout << "Run 'wifi-manager-example --PrintHelp' to show program options."<< std::endl << std::endl;
196 
197  if (infrastructure == false)
198  {
199  NS_ABORT_MSG_IF (serverNss != clientNss, "In ad hoc mode, we assume sender and receiver are similarly configured");
200  }
201 
202  if (standard == "802.11b")
203  {
204  NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22, "Invalid channel width for standard " << standard);
205  NS_ABORT_MSG_IF (serverNss != 1, "Invalid nss for standard " << standard);
206  NS_ABORT_MSG_IF (clientChannelWidth != 22 && clientChannelWidth != 22, "Invalid channel width for standard " << standard);
207  NS_ABORT_MSG_IF (clientNss != 1, "Invalid nss for standard " << standard);
208  }
209  else if (standard == "802.11a" || standard == "802.11g")
210  {
211  NS_ABORT_MSG_IF (serverChannelWidth != 20, "Invalid channel width for standard " << standard);
212  NS_ABORT_MSG_IF (serverNss != 1, "Invalid nss for standard " << standard);
213  NS_ABORT_MSG_IF (clientChannelWidth != 20, "Invalid channel width for standard " << standard);
214  NS_ABORT_MSG_IF (clientNss != 1, "Invalid nss for standard " << standard);
215  }
216  else if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz")
217  {
218  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40, "Invalid channel width for standard " << standard);
219  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
220  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40, "Invalid channel width for standard " << standard);
221  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
222  }
223  else if (standard == "802.11ac")
224  {
225  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, "Invalid channel width for standard " << standard);
226  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
227  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, "Invalid channel width for standard " << standard);
228  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
229  }
230  else if (standard == "802.11ax-5GHz" || standard == "802.11ax-2.4GHz")
231  {
232  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, "Invalid channel width for standard " << standard);
233  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
234  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, "Invalid channel width for standard " << standard);
235  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
236  }
237 
238  std::string plotName = "wifi-manager-example-";
239  std::string dataName = "wifi-manager-example-";
240  plotName += wifiManager;
241  dataName += wifiManager;
242  plotName += "-";
243  dataName += "-";
244  plotName += standard;
245  dataName += standard;
246  if (standard == "802.11n-5GHz" ||
247  standard == "802.11n-2.4GHz" ||
248  standard == "802.11ac" ||
249  standard == "802.11ax-5GHz" ||
250  standard == "802.11ax-2.4GHz")
251  {
252  plotName += "-server=";
253  dataName += "-server=";
254  std::ostringstream oss;
255  oss << serverChannelWidth << "MHz_" << serverShortGuardInterval << "ns_" << serverNss << "SS";
256  plotName += oss.str ();
257  dataName += oss.str ();
258  plotName += "-client=";
259  dataName += "-client=";
260  oss.str("");
261  oss << clientChannelWidth << "MHz_" << clientShortGuardInterval << "ns_" << clientNss << "SS";
262  plotName += oss.str ();
263  dataName += oss.str ();
264  }
265  plotName += ".eps";
266  dataName += ".plt";
267  std::ofstream outfile (dataName.c_str ());
268  Gnuplot gnuplot = Gnuplot (plotName);
269 
270  // As channel width increases, scale up plot's yRange value
271  uint32_t channelRateFactor = std::max (clientChannelWidth, serverChannelWidth) / 20;
272  channelRateFactor = channelRateFactor * std::max (clientNss, serverNss);
273 
274  // The first number is channel width, second is minimum SNR, third is maximum
275  // SNR, fourth and fifth provide xrange axis limits, and sixth the yaxis
276  // maximum
277  serverStandards.push_back (StandardInfo ("802.11a", WIFI_PHY_STANDARD_80211a, 20, 3, 27, 0, 30, 60));
278  serverStandards.push_back (StandardInfo ("802.11b", WIFI_PHY_STANDARD_80211b, 22, -5, 11, -6, 15, 15));
279  serverStandards.push_back (StandardInfo ("802.11g", WIFI_PHY_STANDARD_80211g, 20, -5, 27, -6, 30, 60));
280  serverStandards.push_back (StandardInfo ("802.11n-5GHz", WIFI_PHY_STANDARD_80211n_5GHZ, serverChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
281  serverStandards.push_back (StandardInfo ("802.11n-2.4GHz", WIFI_PHY_STANDARD_80211n_2_4GHZ, serverChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
282  serverStandards.push_back (StandardInfo ("802.11ac", WIFI_PHY_STANDARD_80211ac, serverChannelWidth, 5, 35, 0, 40, 120 * channelRateFactor));
283  serverStandards.push_back (StandardInfo ("802.11-holland", WIFI_PHY_STANDARD_holland, 20, 3, 27, 0, 30, 60));
284  serverStandards.push_back (StandardInfo ("802.11-10MHz", WIFI_PHY_STANDARD_80211_10MHZ, 10, 3, 27, 0, 30, 60));
285  serverStandards.push_back (StandardInfo ("802.11-5MHz", WIFI_PHY_STANDARD_80211_5MHZ, 5, 3, 27, 0, 30, 60));
286  serverStandards.push_back (StandardInfo ("802.11ax-5GHz", WIFI_PHY_STANDARD_80211ax_5GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
287  serverStandards.push_back (StandardInfo ("802.11ax-2.4GHz", WIFI_PHY_STANDARD_80211ax_2_4GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
288 
289  clientStandards.push_back (StandardInfo ("802.11a", WIFI_PHY_STANDARD_80211a, 20, 3, 27, 0, 30, 60));
290  clientStandards.push_back (StandardInfo ("802.11b", WIFI_PHY_STANDARD_80211b, 22, -5, 11, -6, 15, 15));
291  clientStandards.push_back (StandardInfo ("802.11g", WIFI_PHY_STANDARD_80211g, 20, -5, 27, -6, 30, 60));
292  clientStandards.push_back (StandardInfo ("802.11n-5GHz", WIFI_PHY_STANDARD_80211n_5GHZ, clientChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
293  clientStandards.push_back (StandardInfo ("802.11n-2.4GHz", WIFI_PHY_STANDARD_80211n_2_4GHZ, clientChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
294  clientStandards.push_back (StandardInfo ("802.11ac", WIFI_PHY_STANDARD_80211ac, clientChannelWidth, 5, 35, 0, 40, 120 * channelRateFactor));
295  clientStandards.push_back (StandardInfo ("802.11-holland", WIFI_PHY_STANDARD_holland, 20, 3, 27, 0, 30, 60));
296  clientStandards.push_back (StandardInfo ("802.11-10MHz", WIFI_PHY_STANDARD_80211_10MHZ, 10, 3, 27, 0, 30, 60));
297  clientStandards.push_back (StandardInfo ("802.11-5MHz", WIFI_PHY_STANDARD_80211_5MHZ, 5, 3, 27, 0, 30, 60));
298  clientStandards.push_back (StandardInfo ("802.11ax-5GHz", WIFI_PHY_STANDARD_80211ax_5GHZ, clientChannelWidth, 5, 45, 0, 50, 160 * channelRateFactor));
299  clientStandards.push_back (StandardInfo ("802.11ax-2.4GHz", WIFI_PHY_STANDARD_80211ax_2_4GHZ, clientChannelWidth, 5, 45, 0, 50, 160 * channelRateFactor));
300 
301  for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size (); i++)
302  {
303  if (standard == serverStandards[i].m_name)
304  {
305  serverSelectedStandard = serverStandards[i];
306  }
307  }
308  for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size (); i++)
309  {
310  if (standard == clientStandards[i].m_name)
311  {
312  clientSelectedStandard = clientStandards[i];
313  }
314  }
315 
316  NS_ABORT_IF (serverSelectedStandard.m_name == "none");
317  NS_ABORT_IF (clientSelectedStandard.m_name == "none");
318  std::cout << "Testing " << serverSelectedStandard.m_name << " with " << wifiManager << " ..." << std::endl;
319  NS_ABORT_MSG_IF (clientSelectedStandard.m_snrLow >= clientSelectedStandard.m_snrHigh, "SNR values in wrong order");
320  steps = static_cast<uint32_t>(std::abs<double> ((clientSelectedStandard.m_snrHigh - clientSelectedStandard.m_snrLow ) / stepSize) + 1);
321  NS_LOG_DEBUG ("Using " << steps << " steps for SNR range " << clientSelectedStandard.m_snrLow << ":" << clientSelectedStandard.m_snrHigh);
322  Ptr<Node> clientNode = CreateObject<Node> ();
323  Ptr<Node> serverNode = CreateObject<Node> ();
324 
325  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue (maxSlrc));
326  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSsrc", UintegerValue (maxSsrc));
327 
329  wifi.SetStandard (serverSelectedStandard.m_standard);
331  wifiPhy.Set ("RxNoiseFigure", DoubleValue (0.0));
332  wifiPhy.Set ("EnergyDetectionThreshold", DoubleValue (-110.0));
333  wifiPhy.Set ("CcaMode1Threshold", DoubleValue (-110.0));
334 
335  Ptr<YansWifiChannel> wifiChannel = CreateObject<YansWifiChannel> ();
336  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
337  wifiChannel->SetPropagationDelayModel (delayModel);
338  Ptr<FixedRssLossModel> rssLossModel = CreateObject<FixedRssLossModel> ();
339  wifiChannel->SetPropagationLossModel (rssLossModel);
340  wifiPhy.SetChannel (wifiChannel);
341 
342  wifi.SetRemoteStationManager ("ns3::" + wifiManager + "WifiManager", "RtsCtsThreshold", UintegerValue (rtsThreshold));
343 
344  NetDeviceContainer serverDevice;
345  NetDeviceContainer clientDevice;
346 
347  WifiMacHelper wifiMac;
348  if (infrastructure)
349  {
350  Ssid ssid = Ssid ("ns-3-ssid");
351  wifiMac.SetType ("ns3::StaWifiMac",
352  "Ssid", SsidValue (ssid),
353  "ActiveProbing", BooleanValue (false));
354  serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
355  wifiMac.SetType ("ns3::ApWifiMac",
356  "Ssid", SsidValue (ssid),
357  "BeaconGeneration", BooleanValue (true));
358  clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
359  }
360  else
361  {
362  wifiMac.SetType ("ns3::AdhocWifiMac",
363  "BE_MaxAmpduSize", UintegerValue (maxAmpduSize));
364  serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
365  clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
366  }
367 
370  wifi.AssignStreams(serverDevice, 100);
371  wifi.AssignStreams(clientDevice, 100);
372 
373  if (wifiManager == "MinstrelHt")
374  {
375  Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::MinstrelHtWifiManager/RateChange", MakeCallback (&RateChangeMinstrelHt));
376  }
377  else
378  {
379  Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::" + wifiManager + "WifiManager/Rate", MakeCallback (&RateChange));
380  }
381  // Configure the mobility.
383  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
384  //Initial position of AP and STA
385  positionAlloc->Add (Vector (ap1_x, ap1_y, 0.0));
386  NS_LOG_INFO ("Setting initial AP position to " << Vector (ap1_x, ap1_y, 0.0));
387  positionAlloc->Add (Vector (sta1_x, sta1_y, 0.0));
388  NS_LOG_INFO ("Setting initial STA position to " << Vector (sta1_x, sta1_y, 0.0));
389  mobility.SetPositionAllocator (positionAlloc);
390  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
391  mobility.Install (clientNode);
392  mobility.Install (serverNode);
393 
394  Gnuplot2dDataset rateDataset (clientSelectedStandard.m_name + std::string ("-rate selected"));
395  Gnuplot2dDataset actualDataset (clientSelectedStandard.m_name + std::string ("-observed"));
396  struct Step step;
397  step.stepSize = stepSize;
398  step.stepTime = stepTime;
399 
400  // Perform post-install configuration from defaults for channel width,
401  // guard interval, and nss, if necessary
402  // Obtain pointer to the WifiPhy
403  Ptr<NetDevice> ndClient = clientDevice.Get (0);
404  Ptr<NetDevice> ndServer = serverDevice.Get (0);
405  Ptr<WifiNetDevice> wndClient = ndClient->GetObject<WifiNetDevice> ();
406  Ptr<WifiNetDevice> wndServer = ndServer->GetObject<WifiNetDevice> ();
407  Ptr<WifiPhy> wifiPhyPtrClient = wndClient->GetPhy ();
408  Ptr<WifiPhy> wifiPhyPtrServer = wndServer->GetPhy ();
409  wifiPhyPtrClient->SetNumberOfAntennas (clientNss);
410  wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams (clientNss);
411  wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams (clientNss);
412  wifiPhyPtrServer->SetNumberOfAntennas (serverNss);
413  wifiPhyPtrServer->SetMaxSupportedTxSpatialStreams (serverNss);
414  wifiPhyPtrServer->SetMaxSupportedRxSpatialStreams (serverNss);
415  // Only set the channel width and guard interval for HT and VHT modes
416  if (serverSelectedStandard.m_name == "802.11n-5GHz"
417  || serverSelectedStandard.m_name == "802.11n-2.4GHz"
418  || serverSelectedStandard.m_name == "802.11ac")
419  {
420  wifiPhyPtrServer->SetChannelWidth (serverSelectedStandard.m_width);
421  wifiPhyPtrServer->SetShortGuardInterval (serverShortGuardInterval == 400);
422  wifiPhyPtrClient->SetChannelWidth (clientSelectedStandard.m_width);
423  wifiPhyPtrClient->SetShortGuardInterval (clientShortGuardInterval == 400);
424  }
425  else if (serverSelectedStandard.m_name == "802.11ax-5GHz"
426  || serverSelectedStandard.m_name == "802.11ax-2.4GHz")
427  {
428  wifiPhyPtrServer->SetChannelWidth (serverSelectedStandard.m_width);
429  wifiPhyPtrServer->SetGuardInterval (NanoSeconds (serverShortGuardInterval));
430  wifiPhyPtrClient->SetChannelWidth (clientSelectedStandard.m_width);
431  wifiPhyPtrClient->SetGuardInterval (NanoSeconds (clientShortGuardInterval));
432  }
433  NS_LOG_DEBUG ("Channel width " << wifiPhyPtrClient->GetChannelWidth () << " noiseDbm " << noiseDbm);
434  NS_LOG_DEBUG ("NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams ());
435 
436  // Configure signal and noise, and schedule first iteration
437  noiseDbm += 10 * log10 (clientSelectedStandard.m_width * 1000000);
438  double rssCurrent = (clientSelectedStandard.m_snrHigh + noiseDbm);
439  rssLossModel->SetRss (rssCurrent);
440  NS_LOG_INFO ("Setting initial Rss to " << rssCurrent);
441  //Move the STA by stepsSize meters every stepTime seconds
442  Simulator::Schedule (Seconds (0.5 + stepTime), &ChangeSignalAndReportRate, rssLossModel, step, rssCurrent, rateDataset, actualDataset);
443 
444  PacketSocketHelper packetSocketHelper;
445  packetSocketHelper.Install (serverNode);
446  packetSocketHelper.Install (clientNode);
447 
448  PacketSocketAddress socketAddr;
449  socketAddr.SetSingleDevice (serverDevice.Get (0)->GetIfIndex ());
450  if (broadcast)
451  {
452  socketAddr.SetPhysicalAddress (serverDevice.Get (0)->GetBroadcast ());
453  }
454  else
455  {
456  socketAddr.SetPhysicalAddress (serverDevice.Get (0)->GetAddress ());
457  }
458  // Arbitrary protocol type.
459  // Note: PacketSocket doesn't have any L4 multiplexing or demultiplexing
460  // The only mux/demux is based on the protocol field
461  socketAddr.SetProtocol (1);
462 
463  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
464  client->SetRemote (socketAddr);
465  client->SetStartTime (Seconds (0.5)); // allow simulation warmup
466  client->SetAttribute ("MaxPackets", UintegerValue (0)); // unlimited
467  client->SetAttribute ("PacketSize", UintegerValue (packetSize));
468 
469  // Set a maximum rate 10% above the yMax specified for the selected standard
470  double rate = clientSelectedStandard.m_yMax * 1e6 * 1.10;
471  double clientInterval = static_cast<double> (packetSize) * 8 / rate;
472  NS_LOG_DEBUG ("Setting interval to " << clientInterval << " sec for rate of " << rate << " bits/sec");
473 
474  client->SetAttribute ("Interval", TimeValue (Seconds (clientInterval)));
475  clientNode->AddApplication (client);
476 
477  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
478  server->SetLocal (socketAddr);
480  serverNode->AddApplication (server);
481 
482  Simulator::Stop (Seconds ((steps + 1) * stepTime));
483  Simulator::Run ();
485 
486  gnuplot.AddDataset (rateDataset);
487  gnuplot.AddDataset (actualDataset);
488 
489  std::ostringstream xMinStr, xMaxStr, yMaxStr;
490  std::string xRangeStr ("set xrange [");
491  xMinStr << clientSelectedStandard.m_xMin;
492  xRangeStr.append (xMinStr.str ());
493  xRangeStr.append (":");
494  xMaxStr << clientSelectedStandard.m_xMax;
495  xRangeStr.append (xMaxStr.str ());
496  xRangeStr.append ("]");
497  std::string yRangeStr ("set yrange [0:");
498  yMaxStr << clientSelectedStandard.m_yMax;
499  yRangeStr.append (yMaxStr.str ());
500  yRangeStr.append ("]");
501 
502  std::string title ("Results for ");
503  title.append (standard);
504  title.append (" with ");
505  title.append (wifiManager);
506  title.append ("\\n");
507  if (standard == "802.11n-5GHz"
508  || standard == "802.11n-2.4GHz"
509  || standard == "802.11ac"
510  || standard == "802.11n-5GHz"
511  || standard == "802.11ax-2.4GHz")
512  {
513  std::ostringstream serverGiStrStr;
514  std::ostringstream serverWidthStrStr;
515  std::ostringstream serverNssStrStr;
516  title.append ("server: width=");
517  serverWidthStrStr << serverSelectedStandard.m_width;
518  title.append (serverWidthStrStr.str ());
519  title.append ("MHz");
520  title.append (" GI=");
521  serverGiStrStr << serverShortGuardInterval;
522  title.append (serverGiStrStr.str ());
523  title.append ("ns");
524  title.append (" nss=");
525  serverNssStrStr << serverNss;
526  title.append (serverNssStrStr.str ());
527  title.append ("\\n");
528  std::ostringstream clientGiStrStr;
529  std::ostringstream clientWidthStrStr;
530  std::ostringstream clientNssStrStr;
531  title.append ("client: width=");
532  clientWidthStrStr << clientSelectedStandard.m_width;
533  title.append (clientWidthStrStr.str ());
534  title.append ("MHz");
535  title.append (" GI=");
536  clientGiStrStr << clientShortGuardInterval;
537  title.append (clientGiStrStr.str ());
538  title.append ("ns");
539  title.append (" nss=");
540  clientNssStrStr << clientNss;
541  title.append (clientNssStrStr.str ());
542  }
543  gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
544  gnuplot.SetLegend ("SNR (dB)", "Rate (Mb/s)");
545  gnuplot.SetTitle (title);
546  gnuplot.SetExtra (xRangeStr);
547  gnuplot.AppendExtra (yRangeStr);
548  gnuplot.AppendExtra ("set key top left");
549  gnuplot.GenerateOutput (outfile);
550  outfile.close ();
551 
552  return 0;
553 }
554 
ERP-OFDM PHY (Clause 19, Section 19.5)
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:133
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
OFDM PHY for the 5 GHz band (Clause 17 with 5 MHz channel bandwidth)
AttributeValue implementation for Boolean.
Definition: boolean.h:36
void SetLocal(PacketSocketAddress addr)
set the local address and protocol to be used
void SetPropagationLossModel(const Ptr< PropagationLossModel > loss)
HT PHY for the 5 GHz band (clause 20)
Class to represent a 2D points plot.
Definition: gnuplot.h:117
double m_yMax
Y maximum.
void SetRemoteStationManager(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Definition: wifi-helper.cc:700
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
Make it easy to create and manage PHY objects for the yans model.
an address for a packet socket
static void Run(void)
Run the simulation.
Definition: simulator.cc:226
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
HE PHY for the 2.4 GHz band (clause 26)
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:821
second
Definition: nstime.h:114
OFDM PHY for the 5 GHz band (Clause 17 with 10 MHz channel bandwidth)
double m_snrLow
lowest SNR
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:277
const double NOISE_DBM_Hz
HT PHY for the 2.4 GHz band (clause 20)
static YansWifiPhyHelper Default(void)
Create a phy helper in a default working state.
double stepSize
step size in dBm
helps to create WifiNetDevice objects
Definition: wifi-helper.h:213
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, struct Step step, double rss, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
Give ns3::PacketSocket powers to ns3::Node.
tuple cmd
Definition: second.py:35
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
virtual void SetStandard(WifiPhyStandard standard)
Definition: wifi-helper.cc:723
void SetChannel(Ptr< YansWifiChannel > channel)
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
Ptr< WifiPhy > GetPhy(void) const
void SetPropagationDelayModel(const Ptr< PropagationDelayModel > delay)
HE PHY for the 5 GHz band (clause 26)
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
tuple mobility
Definition: third.py:101
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
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:45
AttributeValue implementation for Time.
Definition: nstime.h:1069
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1031
Hold an unsigned integer type.
Definition: uinteger.h:44
Step structure.
holds a vector of ns3::NetDevice pointers
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer::Iterator first, NodeContainer::Iterator last) const
Definition: wifi-helper.cc:729
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the Phy and Mac aspects ...
Definition: wifi-helper.cc:831
std::string m_name
name
Hold together all Wifi-related objects.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:832
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:205
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:190
This is intended to be the configuration used in this paper: Gavin Holland, Nitin Vaidya and Paramvir...
double m_snrHigh
highest SNR
void RateChangeMinstrelHt(uint64_t newVal, Mac48Address dest)
double noiseDbm
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
OFDM PHY for the 5 GHz band (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPhysicalAddress(const Address address)
Set the destination address.
virtual void SetChannelWidth(uint8_t channelwidth)
Definition: wifi-phy.cc:1266
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
void SetMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
void SetShortGuardInterval(bool shortGuardInterval)
Enable or disable support for HT/VHT short guard interval.
Definition: wifi-phy.cc:614
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1319
an EUI-48 address
Definition: mac48-address.h:43
tuple ssid
Definition: third.py:93
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
create MAC layers for a ns3::WifiNetDevice.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
void SetGuardInterval(Time guardInterval)
Definition: wifi-phy.cc:627
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
double m_xMax
X maximum.
virtual void SetType(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue(), std::string n10="", const AttributeValue &v10=EmptyAttributeValue())
static void SetSeed(uint32_t seed)
Set the seed.
StandardInfo structure.
Helper class used to assign positions and mobility models to nodes.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:77
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1300
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
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:498
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:234
WifiPhyStandard m_standard
standard
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
double g_intervalBytes
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1007
AttributeValue implementation for Ssid.
Definition: ssid.h:110
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:782
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 Parse(int argc, char *argv[])
Parse the program arguments.
tuple wifi
Definition: third.py:89
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1286
static const uint32_t packetSize
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
StandardInfo(std::string name, WifiPhyStandard standard, uint8_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
Constructor.
void RateChange(uint64_t oldVal, uint64_t newVal)
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
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
uint8_t m_width
channel width
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69