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/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, WifiPhyStandard 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, struct 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 = 20;
166  uint16_t clientChannelWidth = 20;
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 
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.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);
190  cmd.AddValue ("wifiManager", "Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa)", 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  NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22, "Invalid channel width for standard " << standard);
209  NS_ABORT_MSG_IF (serverNss != 1, "Invalid nss for standard " << standard);
210  NS_ABORT_MSG_IF (clientChannelWidth != 22 && clientChannelWidth != 22, "Invalid channel width for standard " << standard);
211  NS_ABORT_MSG_IF (clientNss != 1, "Invalid nss for standard " << standard);
212  }
213  else if (standard == "802.11a" || standard == "802.11g")
214  {
215  NS_ABORT_MSG_IF (serverChannelWidth != 20, "Invalid channel width for standard " << standard);
216  NS_ABORT_MSG_IF (serverNss != 1, "Invalid nss for standard " << standard);
217  NS_ABORT_MSG_IF (clientChannelWidth != 20, "Invalid channel width for standard " << standard);
218  NS_ABORT_MSG_IF (clientNss != 1, "Invalid nss for standard " << standard);
219  }
220  else if (standard == "802.11n-5GHz" || standard == "802.11n-2.4GHz")
221  {
222  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40, "Invalid channel width for standard " << standard);
223  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
224  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40, "Invalid channel width for standard " << standard);
225  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
226  }
227  else if (standard == "802.11ac")
228  {
229  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, "Invalid channel width for standard " << standard);
230  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
231  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, "Invalid channel width for standard " << standard);
232  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
233  }
234  else if (standard == "802.11ax-5GHz" || standard == "802.11ax-2.4GHz")
235  {
236  NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, "Invalid channel width for standard " << standard);
237  NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, "Invalid nss " << serverNss << " for standard " << standard);
238  NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, "Invalid channel width for standard " << standard);
239  NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, "Invalid nss " << clientNss << " for standard " << standard);
240  }
241 
242  // As channel width increases, scale up plot's yRange value
243  uint32_t channelRateFactor = std::max (clientChannelWidth, serverChannelWidth) / 20;
244  channelRateFactor = channelRateFactor * std::max (clientNss, serverNss);
245 
246  // The first number is channel width, second is minimum SNR, third is maximum
247  // SNR, fourth and fifth provide xrange axis limits, and sixth the yaxis
248  // maximum
249  serverStandards.push_back (StandardInfo ("802.11a", WIFI_PHY_STANDARD_80211a, 20, 3, 27, 0, 30, 60));
250  serverStandards.push_back (StandardInfo ("802.11b", WIFI_PHY_STANDARD_80211b, 22, -5, 11, -6, 15, 15));
251  serverStandards.push_back (StandardInfo ("802.11g", WIFI_PHY_STANDARD_80211g, 20, -5, 27, -6, 30, 60));
252  serverStandards.push_back (StandardInfo ("802.11n-5GHz", WIFI_PHY_STANDARD_80211n_5GHZ, serverChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
253  serverStandards.push_back (StandardInfo ("802.11n-2.4GHz", WIFI_PHY_STANDARD_80211n_2_4GHZ, serverChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
254  serverStandards.push_back (StandardInfo ("802.11ac", WIFI_PHY_STANDARD_80211ac, serverChannelWidth, 5, 50, 0, 55, 120 * channelRateFactor));
255  serverStandards.push_back (StandardInfo ("802.11-holland", WIFI_PHY_STANDARD_holland, 20, 3, 27, 0, 30, 60));
256  serverStandards.push_back (StandardInfo ("802.11-10MHz", WIFI_PHY_STANDARD_80211_10MHZ, 10, 3, 27, 0, 30, 60));
257  serverStandards.push_back (StandardInfo ("802.11-5MHz", WIFI_PHY_STANDARD_80211_5MHZ, 5, 3, 27, 0, 30, 60));
258  serverStandards.push_back (StandardInfo ("802.11ax-5GHz", WIFI_PHY_STANDARD_80211ax_5GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
259  serverStandards.push_back (StandardInfo ("802.11ax-2.4GHz", WIFI_PHY_STANDARD_80211ax_2_4GHZ, serverChannelWidth, 5, 55, 0, 60, 120 * channelRateFactor));
260 
261  clientStandards.push_back (StandardInfo ("802.11a", WIFI_PHY_STANDARD_80211a, 20, 3, 27, 0, 30, 60));
262  clientStandards.push_back (StandardInfo ("802.11b", WIFI_PHY_STANDARD_80211b, 22, -5, 11, -6, 15, 15));
263  clientStandards.push_back (StandardInfo ("802.11g", WIFI_PHY_STANDARD_80211g, 20, -5, 27, -6, 30, 60));
264  clientStandards.push_back (StandardInfo ("802.11n-5GHz", WIFI_PHY_STANDARD_80211n_5GHZ, clientChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
265  clientStandards.push_back (StandardInfo ("802.11n-2.4GHz", WIFI_PHY_STANDARD_80211n_2_4GHZ, clientChannelWidth, 3, 30, 0, 35, 80 * channelRateFactor));
266  clientStandards.push_back (StandardInfo ("802.11ac", WIFI_PHY_STANDARD_80211ac, clientChannelWidth, 5, 50, 0, 55, 120 * channelRateFactor));
267  clientStandards.push_back (StandardInfo ("802.11-holland", WIFI_PHY_STANDARD_holland, 20, 3, 27, 0, 30, 60));
268  clientStandards.push_back (StandardInfo ("802.11-10MHz", WIFI_PHY_STANDARD_80211_10MHZ, 10, 3, 27, 0, 30, 60));
269  clientStandards.push_back (StandardInfo ("802.11-5MHz", WIFI_PHY_STANDARD_80211_5MHZ, 5, 3, 27, 0, 30, 60));
270  clientStandards.push_back (StandardInfo ("802.11ax-5GHz", WIFI_PHY_STANDARD_80211ax_5GHZ, clientChannelWidth, 5, 55, 0, 60, 160 * channelRateFactor));
271  clientStandards.push_back (StandardInfo ("802.11ax-2.4GHz", WIFI_PHY_STANDARD_80211ax_2_4GHZ, clientChannelWidth, 5, 55, 0, 60, 160 * channelRateFactor));
272 
273  for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size (); i++)
274  {
275  if (standard == serverStandards[i].m_name)
276  {
277  serverSelectedStandard = serverStandards[i];
278  }
279  }
280  for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size (); i++)
281  {
282  if (standard == clientStandards[i].m_name)
283  {
284  clientSelectedStandard = clientStandards[i];
285  }
286  }
287 
288  NS_ABORT_MSG_IF (serverSelectedStandard.m_name == "none", "Standard " << standard << " not found");
289  NS_ABORT_MSG_IF (clientSelectedStandard.m_name == "none", "Standard " << standard << " not found");
290  std::cout << "Testing " << serverSelectedStandard.m_name << " with " << wifiManager << " ..." << std::endl;
291  NS_ABORT_MSG_IF (clientSelectedStandard.m_snrLow >= clientSelectedStandard.m_snrHigh, "SNR values in wrong order");
292  steps = static_cast<uint32_t> (std::abs (static_cast<double> (clientSelectedStandard.m_snrHigh - clientSelectedStandard.m_snrLow ) / stepSize) + 1);
293  NS_LOG_DEBUG ("Using " << steps << " steps for SNR range " << clientSelectedStandard.m_snrLow << ":" << clientSelectedStandard.m_snrHigh);
294  Ptr<Node> clientNode = CreateObject<Node> ();
295  Ptr<Node> serverNode = CreateObject<Node> ();
296 
297  std::string plotName = "wifi-manager-example-";
298  std::string dataName = "wifi-manager-example-";
299  plotName += wifiManager;
300  dataName += wifiManager;
301  plotName += "-";
302  dataName += "-";
303  plotName += standard;
304  dataName += standard;
305  if (standard == "802.11n-5GHz"
306  || standard == "802.11n-2.4GHz"
307  || standard == "802.11ac"
308  || standard == "802.11ax-5GHz"
309  || standard == "802.11ax-2.4GHz")
310  {
311  plotName += "-server_";
312  dataName += "-server_";
313  std::ostringstream oss;
314  oss << serverChannelWidth << "MHz_" << serverShortGuardInterval << "ns_" << serverNss << "SS";
315  plotName += oss.str ();
316  dataName += oss.str ();
317  plotName += "-client_";
318  dataName += "-client_";
319  oss.str ("");
320  oss << clientChannelWidth << "MHz_" << clientShortGuardInterval << "ns_" << clientNss << "SS";
321  plotName += oss.str ();
322  dataName += oss.str ();
323  }
324  plotName += ".eps";
325  dataName += ".plt";
326  std::ofstream outfile (dataName.c_str ());
327  Gnuplot gnuplot = Gnuplot (plotName);
328 
329  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue (maxSlrc));
330  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSsrc", UintegerValue (maxSsrc));
331  Config::SetDefault ("ns3::MinstrelWifiManager::PrintStats", BooleanValue (true));
332  Config::SetDefault ("ns3::MinstrelWifiManager::PrintSamples", BooleanValue (true));
333  Config::SetDefault ("ns3::MinstrelHtWifiManager::PrintStats", BooleanValue (true));
334 
336  wifi.SetStandard (serverSelectedStandard.m_standard);
338 
339  Ptr<YansWifiChannel> wifiChannel = CreateObject<YansWifiChannel> ();
340  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
341  wifiChannel->SetPropagationDelayModel (delayModel);
342  Ptr<FixedRssLossModel> rssLossModel = CreateObject<FixedRssLossModel> ();
343  wifiChannel->SetPropagationLossModel (rssLossModel);
344  wifiPhy.SetChannel (wifiChannel);
345 
346  wifi.SetRemoteStationManager ("ns3::" + wifiManager + "WifiManager", "RtsCtsThreshold", UintegerValue (rtsThreshold));
347 
348  NetDeviceContainer serverDevice;
349  NetDeviceContainer clientDevice;
350 
351  WifiMacHelper wifiMac;
352  if (infrastructure)
353  {
354  Ssid ssid = Ssid ("ns-3-ssid");
355  wifiMac.SetType ("ns3::StaWifiMac",
356  "Ssid", SsidValue (ssid));
357  serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
358  wifiMac.SetType ("ns3::ApWifiMac",
359  "Ssid", SsidValue (ssid));
360  clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
361  }
362  else
363  {
364  wifiMac.SetType ("ns3::AdhocWifiMac");
365  serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
366  clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
367  }
368 
371  wifi.AssignStreams (serverDevice, 100);
372  wifi.AssignStreams (clientDevice, 100);
373 
374  Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize", UintegerValue (maxAmpduSize));
375 
376  Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::" + wifiManager + "WifiManager/Rate", MakeCallback (&RateChange));
377 
378  // Configure the mobility.
380  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
381  //Initial position of AP and STA
382  positionAlloc->Add (Vector (ap1_x, ap1_y, 0.0));
383  NS_LOG_INFO ("Setting initial AP position to " << Vector (ap1_x, ap1_y, 0.0));
384  positionAlloc->Add (Vector (sta1_x, sta1_y, 0.0));
385  NS_LOG_INFO ("Setting initial STA position to " << Vector (sta1_x, sta1_y, 0.0));
386  mobility.SetPositionAllocator (positionAlloc);
387  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
388  mobility.Install (clientNode);
389  mobility.Install (serverNode);
390 
391  Gnuplot2dDataset rateDataset (clientSelectedStandard.m_name + std::string ("-rate selected"));
392  Gnuplot2dDataset actualDataset (clientSelectedStandard.m_name + std::string ("-observed"));
393  struct Step step;
394  step.stepSize = stepSize;
395  step.stepTime = stepTime;
396 
397  // Perform post-install configuration from defaults for channel width,
398  // guard interval, and nss, if necessary
399  // Obtain pointer to the WifiPhy
400  Ptr<NetDevice> ndClient = clientDevice.Get (0);
401  Ptr<NetDevice> ndServer = serverDevice.Get (0);
402  Ptr<WifiNetDevice> wndClient = ndClient->GetObject<WifiNetDevice> ();
403  Ptr<WifiNetDevice> wndServer = ndServer->GetObject<WifiNetDevice> ();
404  Ptr<WifiPhy> wifiPhyPtrClient = wndClient->GetPhy ();
405  Ptr<WifiPhy> wifiPhyPtrServer = wndServer->GetPhy ();
406  uint8_t t_clientNss = static_cast<uint8_t> (clientNss);
407  uint8_t t_serverNss = static_cast<uint8_t> (serverNss);
408  wifiPhyPtrClient->SetNumberOfAntennas (t_clientNss);
409  wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams (t_clientNss);
410  wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams (t_clientNss);
411  wifiPhyPtrServer->SetNumberOfAntennas (t_serverNss);
412  wifiPhyPtrServer->SetMaxSupportedTxSpatialStreams (t_serverNss);
413  wifiPhyPtrServer->SetMaxSupportedRxSpatialStreams (t_serverNss);
414  // Only set the channel width and guard interval for HT and VHT modes
415  if (serverSelectedStandard.m_name == "802.11n-5GHz"
416  || serverSelectedStandard.m_name == "802.11n-2.4GHz"
417  || serverSelectedStandard.m_name == "802.11ac")
418  {
419  wifiPhyPtrServer->SetChannelWidth (serverSelectedStandard.m_width);
420  wifiPhyPtrClient->SetChannelWidth (clientSelectedStandard.m_width);
421  Ptr<HtConfiguration> clientHtConfiguration = wndClient->GetHtConfiguration ();
422  clientHtConfiguration->SetShortGuardIntervalSupported (clientShortGuardInterval == 400);
423  Ptr<HtConfiguration> serverHtConfiguration = wndServer->GetHtConfiguration ();
424  serverHtConfiguration->SetShortGuardIntervalSupported (serverShortGuardInterval == 400);
425  }
426  else if (serverSelectedStandard.m_name == "802.11ax-5GHz"
427  || serverSelectedStandard.m_name == "802.11ax-2.4GHz")
428  {
429  wifiPhyPtrServer->SetChannelWidth (serverSelectedStandard.m_width);
430  wifiPhyPtrClient->SetChannelWidth (clientSelectedStandard.m_width);
431  wndServer->GetHeConfiguration ()->SetGuardInterval (NanoSeconds (clientShortGuardInterval));
432  wndClient->GetHeConfiguration ()->SetGuardInterval (NanoSeconds (clientShortGuardInterval));
433  }
434  NS_LOG_DEBUG ("Channel width " << wifiPhyPtrClient->GetChannelWidth () << " noiseDbm " << noiseDbm);
435  NS_LOG_DEBUG ("NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams ());
436 
437  // Configure signal and noise, and schedule first iteration
438  noiseDbm += 10 * log10 (clientSelectedStandard.m_width * 1000000);
439  double rssCurrent = (clientSelectedStandard.m_snrHigh + noiseDbm);
440  rssLossModel->SetRss (rssCurrent);
441  NS_LOG_INFO ("Setting initial Rss to " << rssCurrent);
442  //Move the STA by stepsSize meters every stepTime seconds
443  Simulator::Schedule (Seconds (0.5 + stepTime), &ChangeSignalAndReportRate, rssLossModel, step, rssCurrent, rateDataset, actualDataset);
444 
445  PacketSocketHelper packetSocketHelper;
446  packetSocketHelper.Install (serverNode);
447  packetSocketHelper.Install (clientNode);
448 
449  PacketSocketAddress socketAddr;
450  socketAddr.SetSingleDevice (serverDevice.Get (0)->GetIfIndex ());
451  if (broadcast)
452  {
453  socketAddr.SetPhysicalAddress (serverDevice.Get (0)->GetBroadcast ());
454  }
455  else
456  {
457  socketAddr.SetPhysicalAddress (serverDevice.Get (0)->GetAddress ());
458  }
459  // Arbitrary protocol type.
460  // Note: PacketSocket doesn't have any L4 multiplexing or demultiplexing
461  // The only mux/demux is based on the protocol field
462  socketAddr.SetProtocol (1);
463 
464  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
465  client->SetRemote (socketAddr);
466  client->SetStartTime (Seconds (0.5)); // allow simulation warmup
467  client->SetAttribute ("MaxPackets", UintegerValue (0)); // unlimited
468  client->SetAttribute ("PacketSize", UintegerValue (packetSize));
469 
470  // Set a maximum rate 10% above the yMax specified for the selected standard
471  double rate = clientSelectedStandard.m_yMax * 1e6 * 1.10;
472  double clientInterval = static_cast<double> (packetSize) * 8 / rate;
473  NS_LOG_DEBUG ("Setting interval to " << clientInterval << " sec for rate of " << rate << " bits/sec");
474 
475  client->SetAttribute ("Interval", TimeValue (Seconds (clientInterval)));
476  clientNode->AddApplication (client);
477 
478  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
479  server->SetLocal (socketAddr);
481  serverNode->AddApplication (server);
482 
483  Simulator::Stop (Seconds ((steps + 1) * stepTime));
484  Simulator::Run ();
486 
487  gnuplot.AddDataset (rateDataset);
488  gnuplot.AddDataset (actualDataset);
489 
490  std::ostringstream xMinStr, xMaxStr, yMaxStr;
491  std::string xRangeStr ("set xrange [");
492  xMinStr << clientSelectedStandard.m_xMin;
493  xRangeStr.append (xMinStr.str ());
494  xRangeStr.append (":");
495  xMaxStr << clientSelectedStandard.m_xMax;
496  xRangeStr.append (xMaxStr.str ());
497  xRangeStr.append ("]");
498  std::string yRangeStr ("set yrange [0:");
499  yMaxStr << clientSelectedStandard.m_yMax;
500  yRangeStr.append (yMaxStr.str ());
501  yRangeStr.append ("]");
502 
503  std::string title ("Results for ");
504  title.append (standard);
505  title.append (" with ");
506  title.append (wifiManager);
507  title.append ("\\n");
508  if (standard == "802.11n-5GHz"
509  || standard == "802.11n-2.4GHz"
510  || standard == "802.11ac"
511  || standard == "802.11n-5GHz"
512  || standard == "802.11ax-2.4GHz")
513  {
514  std::ostringstream serverGiStrStr;
515  std::ostringstream serverWidthStrStr;
516  std::ostringstream serverNssStrStr;
517  title.append ("server: width=");
518  serverWidthStrStr << serverSelectedStandard.m_width;
519  title.append (serverWidthStrStr.str ());
520  title.append ("MHz");
521  title.append (" GI=");
522  serverGiStrStr << serverShortGuardInterval;
523  title.append (serverGiStrStr.str ());
524  title.append ("ns");
525  title.append (" nss=");
526  serverNssStrStr << serverNss;
527  title.append (serverNssStrStr.str ());
528  title.append ("\\n");
529  std::ostringstream clientGiStrStr;
530  std::ostringstream clientWidthStrStr;
531  std::ostringstream clientNssStrStr;
532  title.append ("client: width=");
533  clientWidthStrStr << clientSelectedStandard.m_width;
534  title.append (clientWidthStrStr.str ());
535  title.append ("MHz");
536  title.append (" GI=");
537  clientGiStrStr << clientShortGuardInterval;
538  title.append (clientGiStrStr.str ());
539  title.append ("ns");
540  title.append (" nss=");
541  clientNssStrStr << clientNss;
542  title.append (clientNssStrStr.str ());
543  }
544  gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
545  gnuplot.SetLegend ("SNR (dB)", "Rate (Mb/s)");
546  gnuplot.SetTitle (title);
547  gnuplot.SetExtra (xRangeStr);
548  gnuplot.AppendExtra (yRangeStr);
549  gnuplot.AppendExtra ("set key top left");
550  gnuplot.GenerateOutput (outfile);
551  outfile.close ();
552 
553  return 0;
554 }
555 
ERP-OFDM PHY (Clause 19, Section 19.5)
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
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 "...
OFDM PHY for the 5 GHz band (Clause 17 with 5 MHz channel bandwidth)
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)
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.
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:807
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:170
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
HE PHY for the 2.4 GHz band (clause 26)
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:281
cmd
Definition: second.py:35
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:300
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, struct Step step, double rss, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
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)
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
void SetPropagationDelayModel(const Ptr< PropagationDelayModel > delay)
HE PHY for the 5 GHz band (clause 26)
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1390
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:1132
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1094
Hold an unsigned integer type.
Definition: uinteger.h:44
Step structure.
ssid
Definition: third.py:100
holds a vector of ns3::NetDevice pointers
std::string m_name
name
Hold together all Wifi-related objects.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1610
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:862
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:212
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:134
This is intended to be the configuration used in this paper: Gavin Holland, Nitin Vaidya and Paramvir...
double m_snrHigh
highest SNR
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:464
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:295
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.
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1431
create MAC layers for a ns3::WifiNetDevice.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
StandardInfo(std::string name, WifiPhyStandard standard, uint16_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
Constructor.
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.
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:1412
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
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:178
virtual void SetChannelWidth(uint16_t channelWidth)
Definition: wifi-phy.cc:1378
WifiPhyStandard m_standard
standard
#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:1070
AttributeValue implementation for Ssid.
Definition: ssid.h:105
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:812
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.
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1398
second
Definition: nstime.h:114
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:187
Ptr< HtConfiguration > GetHtConfiguration(void) const
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69