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.