41 #include "ns3/config.h"
42 #include "ns3/uinteger.h"
43 #include "ns3/boolean.h"
44 #include "ns3/double.h"
46 #include "ns3/tuple.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);
115 m_standard (standard),
144 actualDataset.
Add (snr, currentRate);
145 rssModel->SetRss (rss - step.
stepSize);
151 int main (
int argc,
char *argv[])
153 std::vector <StandardInfo> serverStandards;
154 std::vector <StandardInfo> clientStandards;
156 uint32_t rtsThreshold = 999999;
157 uint32_t maxAmpduSize = 65535;
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;
177 uint32_t maxSlrc = 7;
178 uint32_t maxSsrc = 7;
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);
433 wifi.AssignStreams (serverDevice, 100);
434 wifi.AssignStreams (clientDevice, 100);
444 positionAlloc->Add (Vector (ap1_x, ap1_y, 0.0));
445 NS_LOG_INFO (
"Setting initial AP position to " << 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);
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.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Run(void)
Run the simulation.
static Time Now(void)
Return the current simulation virtual time.
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.
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 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