41#include "ns3/config.h" 
   42#include "ns3/uinteger.h" 
   43#include "ns3/boolean.h" 
   44#include "ns3/double.h" 
   47#include "ns3/gnuplot.h" 
   48#include "ns3/command-line.h" 
   49#include "ns3/yans-wifi-helper.h" 
   51#include "ns3/propagation-loss-model.h" 
   52#include "ns3/propagation-delay-model.h" 
   53#include "ns3/rng-seed-manager.h" 
   54#include "ns3/mobility-helper.h" 
   55#include "ns3/wifi-net-device.h" 
   56#include "ns3/packet-socket-helper.h" 
   57#include "ns3/packet-socket-client.h" 
   58#include "ns3/packet-socket-server.h" 
   59#include "ns3/ht-configuration.h" 
   60#include "ns3/he-configuration.h" 
   82  NS_LOG_DEBUG (
"Change from " << oldVal << 
" to " << newVal);
 
  144  actualDataset.
Add (snr, currentRate);
 
  145  rssModel->SetRss (rss - step.
stepSize);
 
  151int main (
int argc, 
char *argv[])
 
  153  std::vector <StandardInfo> serverStandards;
 
  154  std::vector <StandardInfo> clientStandards;
 
  166  uint16_t serverNss = 1;
 
  167  uint16_t clientNss = 1;
 
  168  uint16_t serverShortGuardInterval = 800;
 
  169  uint16_t clientShortGuardInterval = 800;
 
  170  uint16_t serverChannelWidth = 0;  
 
  171  uint16_t clientChannelWidth = 0;  
 
  172  std::string wifiManager (
"Ideal");
 
  173  std::string standard (
"802.11a");
 
  176  bool infrastructure = 
false;
 
  181  cmd.AddValue (
"maxSsrc", 
"The maximum number of retransmission attempts for a RTS packet", maxSsrc);
 
  182  cmd.AddValue (
"maxSlrc", 
"The maximum number of retransmission attempts for a Data packet", maxSlrc);
 
  183  cmd.AddValue (
"rtsThreshold", 
"RTS threshold", rtsThreshold);
 
  184  cmd.AddValue (
"maxAmpduSize", 
"Max A-MPDU size", maxAmpduSize);
 
  185  cmd.AddValue (
"stepSize", 
"Power between steps (dBm)", stepSize);
 
  186  cmd.AddValue (
"stepTime", 
"Time on each step (seconds)", stepTime);
 
  187  cmd.AddValue (
"broadcast", 
"Send broadcast instead of unicast", broadcast);
 
  188  cmd.AddValue (
"serverChannelWidth", 
"Set channel width of the server (valid only for 802.11n or ac)", serverChannelWidth);
 
  189  cmd.AddValue (
"clientChannelWidth", 
"Set channel width of the client (valid only for 802.11n or ac)", clientChannelWidth);
 
  190  cmd.AddValue (
"serverNss", 
"Set nss of the server (valid only for 802.11n or ac)", serverNss);
 
  191  cmd.AddValue (
"clientNss", 
"Set nss of the client (valid only for 802.11n or ac)", clientNss);
 
  192  cmd.AddValue (
"serverShortGuardInterval", 
"Set short guard interval of the server (802.11n/ac/ax) in nanoseconds", serverShortGuardInterval);
 
  193  cmd.AddValue (
"clientShortGuardInterval", 
"Set short guard interval of the client (802.11n/ac/ax) in nanoseconds", clientShortGuardInterval);
 
  194  cmd.AddValue (
"standard", 
"Set standard (802.11a, 802.11b, 802.11g, 802.11p-10MHz, 802.11p-5MHz, 802.11n-5GHz, 802.11n-2.4GHz, 802.11ac, 802.11ax-6GHz, 802.11ax-5GHz, 802.11ax-2.4GHz)", standard);
 
  195  cmd.AddValue (
"wifiManager", 
"Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa, ThompsonSampling)", wifiManager);
 
  196  cmd.AddValue (
"infrastructure", 
"Use infrastructure instead of adhoc", infrastructure);
 
  197  cmd.Parse (argc,argv);
 
  200  std::cout << std::endl << 
"This program demonstrates and plots the operation of different " << std::endl;
 
  201  std::cout << 
"Wi-Fi rate controls on different station configurations," << std::endl;
 
  202  std::cout << 
"by stepping down the received signal strength across a wide range" << std::endl;
 
  203  std::cout << 
"and observing the adjustment of the rate." << std::endl;
 
  204  std::cout << 
"Run 'wifi-manager-example --PrintHelp' to show program options." << std::endl << std::endl;
 
  206  if (infrastructure == 
false)
 
  208      NS_ABORT_MSG_IF (serverNss != clientNss, 
"In ad hoc mode, we assume sender and receiver are similarly configured");
 
  211  if (standard == 
"802.11b")
 
  213      if (serverChannelWidth == 0)
 
  217      NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22, 
"Invalid channel width for standard " << standard);
 
  218      NS_ABORT_MSG_IF (serverNss != 1, 
"Invalid nss for standard " << standard);
 
  219      if (clientChannelWidth == 0)
 
  223      NS_ABORT_MSG_IF (clientChannelWidth != 22 && clientChannelWidth != 22, 
"Invalid channel width for standard " << standard);
 
  224      NS_ABORT_MSG_IF (clientNss != 1, 
"Invalid nss for standard " << standard);
 
  226  else if (standard == 
"802.11a" || standard == 
"802.11g")
 
  228      if (serverChannelWidth == 0)
 
  232      NS_ABORT_MSG_IF (serverChannelWidth != 20, 
"Invalid channel width for standard " << standard);
 
  233      NS_ABORT_MSG_IF (serverNss != 1, 
"Invalid nss for standard " << standard);
 
  234      if (clientChannelWidth == 0)
 
  238      NS_ABORT_MSG_IF (clientChannelWidth != 20, 
"Invalid channel width for standard " << standard);
 
  239      NS_ABORT_MSG_IF (clientNss != 1, 
"Invalid nss for standard " << standard);
 
  241  else if (standard == 
"802.11n-5GHz" || standard == 
"802.11n-2.4GHz")
 
  244      if (serverChannelWidth == 0)
 
  248      NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40, 
"Invalid channel width for standard " << standard);
 
  249      NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, 
"Invalid nss " << serverNss << 
" for standard " << standard);
 
  250      if (clientChannelWidth == 0)
 
  254      NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40, 
"Invalid channel width for standard " << standard);
 
  255      NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, 
"Invalid nss " << clientNss << 
" for standard " << standard);
 
  257  else if (standard == 
"802.11ac")
 
  259      if (serverChannelWidth == 0)
 
  263      NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, 
"Invalid channel width for standard " << standard);
 
  264      NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, 
"Invalid nss " << serverNss << 
" for standard " << standard);
 
  265      if (clientChannelWidth == 0)
 
  269      NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, 
"Invalid channel width for standard " << standard);
 
  270      NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, 
"Invalid nss " << clientNss << 
" for standard " << standard);
 
  272  else if (standard == 
"802.11ax-6GHz" ||standard == 
"802.11ax-5GHz" || standard == 
"802.11ax-2.4GHz")
 
  275      if (serverChannelWidth == 0)
 
  279      NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160, 
"Invalid channel width for standard " << standard);
 
  280      NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4, 
"Invalid nss " << serverNss << 
" for standard " << standard);
 
  281      if (clientChannelWidth == 0)
 
  285      NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160, 
"Invalid channel width for standard " << standard);
 
  286      NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4, 
"Invalid nss " << clientNss << 
" for standard " << standard);
 
  290  uint32_t channelRateFactor = 
std::max (clientChannelWidth, serverChannelWidth) / 20;
 
  291  channelRateFactor = channelRateFactor * 
std::max (clientNss, serverNss);
 
  320  for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size (); i++)
 
  322      if (standard == serverStandards[i].m_name)
 
  324          serverSelectedStandard = serverStandards[i];
 
  327  for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size (); i++)
 
  329      if (standard == clientStandards[i].m_name)
 
  331          clientSelectedStandard = clientStandards[i];
 
  337  std::cout << 
"Testing " << serverSelectedStandard.
m_name << 
" with " << wifiManager << 
" ..." << std::endl;
 
  339  steps = 
static_cast<uint32_t> (std::abs (
static_cast<double> (clientSelectedStandard.
m_snrHigh - clientSelectedStandard.
m_snrLow ) / stepSize) + 1);
 
  341  Ptr<Node> clientNode = CreateObject<Node> ();
 
  342  Ptr<Node> serverNode = CreateObject<Node> ();
 
  344  std::string plotName = 
"wifi-manager-example-";
 
  345  std::string dataName = 
"wifi-manager-example-";
 
  346  plotName += wifiManager;
 
  347  dataName += wifiManager;
 
  350  plotName += standard;
 
  351  dataName += standard;
 
  352  if (standard == 
"802.11n-5GHz" 
  353      || standard == 
"802.11n-2.4GHz" 
  354      || standard == 
"802.11ac" 
  355      || standard == 
"802.11ax-6GHz" 
  356      || standard == 
"802.11ax-5GHz" 
  357      || standard == 
"802.11ax-2.4GHz")
 
  359      plotName += 
"-server_";
 
  360      dataName += 
"-server_";
 
  361      std::ostringstream oss;
 
  362      oss << serverChannelWidth << 
"MHz_" << serverShortGuardInterval << 
"ns_" << serverNss << 
"SS";
 
  363      plotName += oss.str ();
 
  364      dataName += oss.str ();
 
  365      plotName += 
"-client_";
 
  366      dataName += 
"-client_";
 
  368      oss << clientChannelWidth << 
"MHz_" << clientShortGuardInterval << 
"ns_" << clientNss << 
"SS";
 
  369      plotName += oss.str ();
 
  370      dataName += oss.str ();
 
  374  std::ofstream outfile (dataName.c_str ());
 
  389  wifiChannel->SetPropagationDelayModel (delayModel);
 
  391  wifiChannel->SetPropagationLossModel (rssLossModel);
 
  394  wifi.SetRemoteStationManager (
"ns3::" + wifiManager + 
"WifiManager", 
"RtsCtsThreshold", 
UintegerValue (rtsThreshold));
 
  405      wifiMac.
SetType (
"ns3::StaWifiMac",
 
  408                                               serverSelectedStandard.
m_band, 0});
 
  409      wifiPhy.
Set (
"ChannelSettings", channelValue);
 
  410      serverDevice = 
wifi.Install (wifiPhy, wifiMac, serverNode);
 
  412      wifiMac.
SetType (
"ns3::ApWifiMac",
 
  415                                               clientSelectedStandard.
m_band, 0});
 
  416      clientDevice = 
wifi.Install (wifiPhy, wifiMac, clientNode);
 
  420      wifiMac.
SetType (
"ns3::AdhocWifiMac");
 
  422                                               serverSelectedStandard.
m_band, 0});
 
  423      wifiPhy.
Set (
"ChannelSettings", channelValue);
 
  424      serverDevice = 
wifi.Install (wifiPhy, wifiMac, serverNode);
 
  427                                               clientSelectedStandard.
m_band, 0});
 
  428      clientDevice = 
wifi.Install (wifiPhy, wifiMac, clientNode);
 
  431  RngSeedManager::SetSeed (1);
 
  432  RngSeedManager::SetRun (2);
 
  433  wifi.AssignStreams (serverDevice, 100);
 
  434  wifi.AssignStreams (clientDevice, 100);
 
  444  positionAlloc->Add (
Vector (ap1_x, ap1_y, 0.0));
 
  446  positionAlloc->Add (
Vector (sta1_x, sta1_y, 0.0));
 
  447  NS_LOG_INFO (
"Setting initial STA position to " << 
Vector (sta1_x, sta1_y, 0.0));
 
  448  mobility.SetPositionAllocator (positionAlloc);
 
  449  mobility.SetMobilityModel (
"ns3::ConstantPositionMobilityModel");
 
  468  uint8_t t_clientNss = 
static_cast<uint8_t
> (clientNss);
 
  469  uint8_t t_serverNss = 
static_cast<uint8_t
> (serverNss);
 
  471  wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams (t_clientNss);
 
  472  wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams (t_clientNss);
 
  477  if (serverSelectedStandard.
m_name == 
"802.11n-5GHz" 
  478      || serverSelectedStandard.
m_name == 
"802.11n-2.4GHz" 
  479      || serverSelectedStandard.
m_name == 
"802.11ac")
 
  482      clientHtConfiguration->SetShortGuardIntervalSupported (clientShortGuardInterval == 400);
 
  484      serverHtConfiguration->SetShortGuardIntervalSupported (serverShortGuardInterval == 400);
 
  486  else if (serverSelectedStandard.
m_name == 
"802.11ax-6GHz" 
  487           || serverSelectedStandard.
m_name == 
"802.11ax-5GHz" 
  488           || serverSelectedStandard.
m_name == 
"802.11ax-2.4GHz")
 
  490      wndServer->GetHeConfiguration ()->SetGuardInterval (
NanoSeconds (serverShortGuardInterval));
 
  493  NS_LOG_DEBUG (
"Channel width " << wifiPhyPtrClient->GetChannelWidth () << 
" noiseDbm " << 
noiseDbm);
 
  494  NS_LOG_DEBUG (
"NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams ());
 
  499  rssLossModel->SetRss (rssCurrent);
 
  500  NS_LOG_INFO (
"Setting initial Rss to " << rssCurrent);
 
  505  packetSocketHelper.
Install (serverNode);
 
  506  packetSocketHelper.
Install (clientNode);
 
  524  client->SetRemote (socketAddr);
 
  525  client->SetStartTime (
Seconds (0.5));  
 
  530  double rate = clientSelectedStandard.
m_yMax * 1e6 * 1.10;
 
  531  double clientInterval = 
static_cast<double> (
packetSize) * 8 / rate;
 
  532  NS_LOG_DEBUG (
"Setting interval to " << clientInterval << 
" sec for rate of " << rate << 
" bits/sec");
 
  538  server->SetLocal (socketAddr);
 
  542  Simulator::Stop (
Seconds ((steps + 1) * stepTime));
 
  544  Simulator::Destroy ();
 
  549  std::ostringstream xMinStr, xMaxStr, yMaxStr;
 
  550  std::string xRangeStr (
"set xrange [");
 
  551  xMinStr << clientSelectedStandard.
m_xMin;
 
  552  xRangeStr.append (xMinStr.str ());
 
  553  xRangeStr.append (
":");
 
  554  xMaxStr << clientSelectedStandard.
m_xMax;
 
  555  xRangeStr.append (xMaxStr.str ());
 
  556  xRangeStr.append (
"]");
 
  557  std::string yRangeStr (
"set yrange [0:");
 
  558  yMaxStr << clientSelectedStandard.
m_yMax;
 
  559  yRangeStr.append (yMaxStr.str ());
 
  560  yRangeStr.append (
"]");
 
  562  std::string title (
"Results for ");
 
  563  title.append (standard);
 
  564  title.append (
" with ");
 
  565  title.append (wifiManager);
 
  566  title.append (
"\\n");
 
  567  if (standard == 
"802.11n-5GHz" 
  568      || standard == 
"802.11n-2.4GHz" 
  569      || standard == 
"802.11ac" 
  570      || standard == 
"802.11ax-6GHz" 
  571      || standard == 
"802.11ax-5GHz" 
  572      || standard == 
"802.11ax-2.4GHz")
 
  574      std::ostringstream serverGiStrStr;
 
  575      std::ostringstream serverWidthStrStr;
 
  576      std::ostringstream serverNssStrStr;
 
  577      title.append (
"server: width=");
 
  578      serverWidthStrStr << serverSelectedStandard.
m_width;
 
  579      title.append (serverWidthStrStr.str ());
 
  580      title.append (
"MHz");
 
  581      title.append (
" GI=");
 
  582      serverGiStrStr << serverShortGuardInterval;
 
  583      title.append (serverGiStrStr.str ());
 
  585      title.append (
" nss=");
 
  586      serverNssStrStr << serverNss;
 
  587      title.append (serverNssStrStr.str ());
 
  588      title.append (
"\\n");
 
  589      std::ostringstream clientGiStrStr;
 
  590      std::ostringstream clientWidthStrStr;
 
  591      std::ostringstream clientNssStrStr;
 
  592      title.append (
"client: width=");
 
  593      clientWidthStrStr << clientSelectedStandard.
m_width;
 
  594      title.append (clientWidthStrStr.str ());
 
  595      title.append (
"MHz");
 
  596      title.append (
" GI=");
 
  597      clientGiStrStr << clientShortGuardInterval;
 
  598      title.append (clientGiStrStr.str ());
 
  600      title.append (
" nss=");
 
  601      clientNssStrStr << clientNss;
 
  602      title.append (clientNssStrStr.str ());
 
  604  gnuplot.
SetTerminal (
"postscript eps color enh \"Times-BoldItalic\"");
 
  605  gnuplot.
SetLegend (
"SNR (dB)", 
"Rate (Mb/s)");
 
a polymophic address class
AttributeValue implementation for Boolean.
Parse command-line arguments.
Class to represent a 2D points plot.
void Add(double x, double y)
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
void AddDataset(const GnuplotDataset &dataset)
void SetLegend(const std::string &xLegend, const std::string &yLegend)
void SetTerminal(const std::string &terminal)
void AppendExtra(const std::string &extra)
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
void SetExtra(const std::string &extra)
void SetTitle(const std::string &title)
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
virtual Address GetBroadcast(void) const =0
virtual Address GetAddress(void) const =0
virtual uint32_t GetIfIndex(void) const =0
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
The IEEE 802.11 SSID Information Element.
AttributeValue implementation for Ssid.
AttributeValue implementation for Time.
Hold objects of type std::tuple<Args...>.
void Set(const result_type &value)
Set the stored values.
Hold an unsigned integer type.
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
helps to create WifiNetDevice objects
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
Hold together all Wifi-related objects.
Ptr< HtConfiguration > GetHtConfiguration(void) const
Ptr< WifiPhy > GetPhy(void) const
Ptr< HeConfiguration > GetHeConfiguration(void) const
void Set(std::string name, const AttributeValue &v)
void SetNumberOfAntennas(uint8_t antennas)
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
void SetDefault(std::string name, const AttributeValue &value)
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
void Set(std::string path, const AttributeValue &value)
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyBand
Identifies the PHY band.
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint16_t GetDefaultChannelWidth(WifiStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
StandardInfo(std::string name, WifiStandard standard, WifiPhyBand band, uint16_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
Constructor.
uint16_t m_width
channel width
WifiStandard m_standard
standard
WifiPhyBand m_band
PHY band.
double m_snrHigh
highest SNR
double m_snrLow
lowest SNR
double stepSize
step size in dBm
double stepTime
step size in seconds
void RateChange(uint64_t oldVal, uint64_t newVal)
const double NOISE_DBM_Hz
void PacketRx(Ptr< const Packet > pkt, const Address &addr)
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, Step step, double rss, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
static const uint32_t packetSize
Pcket size generated at the AP.