49 #include "ns3/boolean.h"
50 #include "ns3/command-line.h"
51 #include "ns3/config.h"
52 #include "ns3/double.h"
54 #include "ns3/gnuplot.h"
55 #include "ns3/he-configuration.h"
56 #include "ns3/ht-configuration.h"
58 #include "ns3/mobility-helper.h"
59 #include "ns3/packet-socket-client.h"
60 #include "ns3/packet-socket-helper.h"
61 #include "ns3/packet-socket-server.h"
62 #include "ns3/propagation-delay-model.h"
63 #include "ns3/propagation-loss-model.h"
64 #include "ns3/rng-seed-manager.h"
66 #include "ns3/tuple.h"
67 #include "ns3/uinteger.h"
68 #include "ns3/wifi-net-device.h"
69 #include "ns3/yans-wifi-helper.h"
103 NS_LOG_DEBUG(
"Change from " << oldVal <<
" to " << newVal);
145 m_standard(standard),
188 actualDataset.
Add(snr, currentRate);
189 rssModel->SetRss(rss - step.
stepSize);
192 <<
"; setting new power to " << rss - step.
stepSize);
204 main(
int argc,
char* argv[])
206 std::vector<StandardInfo> serverStandards;
207 std::vector<StandardInfo> clientStandards;
209 uint32_t rtsThreshold = 999999;
210 uint32_t maxAmpduSize = 65535;
214 bool broadcast =
false;
219 uint16_t serverNss = 1;
220 uint16_t clientNss = 1;
221 uint16_t serverShortGuardInterval = 800;
222 uint16_t clientShortGuardInterval = 800;
223 uint16_t serverChannelWidth = 0;
224 uint16_t clientChannelWidth = 0;
225 std::string wifiManager(
"Ideal");
226 std::string standard(
"802.11a");
229 bool infrastructure =
false;
230 uint32_t maxSlrc = 7;
231 uint32_t maxSsrc = 7;
234 cmd.AddValue(
"maxSsrc",
235 "The maximum number of retransmission attempts for a RTS packet",
237 cmd.AddValue(
"maxSlrc",
238 "The maximum number of retransmission attempts for a Data packet",
240 cmd.AddValue(
"rtsThreshold",
"RTS threshold", rtsThreshold);
241 cmd.AddValue(
"maxAmpduSize",
"Max A-MPDU size", maxAmpduSize);
242 cmd.AddValue(
"stepSize",
"Power between steps (dBm)", stepSize);
243 cmd.AddValue(
"stepTime",
"Time on each step (seconds)", stepTime);
244 cmd.AddValue(
"broadcast",
"Send broadcast instead of unicast", broadcast);
245 cmd.AddValue(
"serverChannelWidth",
246 "Set channel width of the server (valid only for 802.11n or ac)",
248 cmd.AddValue(
"clientChannelWidth",
249 "Set channel width of the client (valid only for 802.11n or ac)",
251 cmd.AddValue(
"serverNss",
"Set nss of the server (valid only for 802.11n or ac)", serverNss);
252 cmd.AddValue(
"clientNss",
"Set nss of the client (valid only for 802.11n or ac)", clientNss);
253 cmd.AddValue(
"serverShortGuardInterval",
254 "Set short guard interval of the server (802.11n/ac/ax) in nanoseconds",
255 serverShortGuardInterval);
256 cmd.AddValue(
"clientShortGuardInterval",
257 "Set short guard interval of the client (802.11n/ac/ax) in nanoseconds",
258 clientShortGuardInterval);
261 "Set standard (802.11a, 802.11b, 802.11g, 802.11p-10MHz, 802.11p-5MHz, 802.11n-5GHz, "
262 "802.11n-2.4GHz, 802.11ac, 802.11ax-6GHz, 802.11ax-5GHz, 802.11ax-2.4GHz)",
264 cmd.AddValue(
"wifiManager",
265 "Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, "
266 "MinstrelHt, Onoe, Rraa, ThompsonSampling)",
268 cmd.AddValue(
"infrastructure",
"Use infrastructure instead of adhoc", infrastructure);
269 cmd.Parse(argc, argv);
272 std::cout << std::endl
273 <<
"This program demonstrates and plots the operation of different " << std::endl;
274 std::cout <<
"Wi-Fi rate controls on different station configurations," << std::endl;
275 std::cout <<
"by stepping down the received signal strength across a wide range" << std::endl;
276 std::cout <<
"and observing the adjustment of the rate." << std::endl;
277 std::cout <<
"Run 'wifi-manager-example --PrintHelp' to show program options." << std::endl
283 "In ad hoc mode, we assume sender and receiver are similarly configured");
286 if (standard ==
"802.11b")
288 if (serverChannelWidth == 0)
293 "Invalid channel width for standard " << standard);
294 NS_ABORT_MSG_IF(serverNss != 1,
"Invalid nss for standard " << standard);
295 if (clientChannelWidth == 0)
300 "Invalid channel width for standard " << standard);
301 NS_ABORT_MSG_IF(clientNss != 1,
"Invalid nss for standard " << standard);
303 else if (standard ==
"802.11a" || standard ==
"802.11g")
305 if (serverChannelWidth == 0)
310 "Invalid channel width for standard " << standard);
311 NS_ABORT_MSG_IF(serverNss != 1,
"Invalid nss for standard " << standard);
312 if (clientChannelWidth == 0)
317 "Invalid channel width for standard " << standard);
318 NS_ABORT_MSG_IF(clientNss != 1,
"Invalid nss for standard " << standard);
320 else if (standard ==
"802.11n-5GHz" || standard ==
"802.11n-2.4GHz")
324 if (serverChannelWidth == 0)
329 "Invalid channel width for standard " << standard);
331 "Invalid nss " << serverNss <<
" for standard " << standard);
332 if (clientChannelWidth == 0)
337 "Invalid channel width for standard " << standard);
339 "Invalid nss " << clientNss <<
" for standard " << standard);
341 else if (standard ==
"802.11ac")
343 if (serverChannelWidth == 0)
347 NS_ABORT_MSG_IF(serverChannelWidth != 20 && serverChannelWidth != 40 &&
348 serverChannelWidth != 80 && serverChannelWidth != 160,
349 "Invalid channel width for standard " << standard);
351 "Invalid nss " << serverNss <<
" for standard " << standard);
352 if (clientChannelWidth == 0)
356 NS_ABORT_MSG_IF(clientChannelWidth != 20 && clientChannelWidth != 40 &&
357 clientChannelWidth != 80 && clientChannelWidth != 160,
358 "Invalid channel width for standard " << standard);
360 "Invalid nss " << clientNss <<
" for standard " << standard);
362 else if (standard ==
"802.11ax-6GHz" || standard ==
"802.11ax-5GHz" ||
363 standard ==
"802.11ax-2.4GHz")
368 if (serverChannelWidth == 0)
372 NS_ABORT_MSG_IF(serverChannelWidth != 20 && serverChannelWidth != 40 &&
373 serverChannelWidth != 80 && serverChannelWidth != 160,
374 "Invalid channel width for standard " << standard);
376 "Invalid nss " << serverNss <<
" for standard " << standard);
377 if (clientChannelWidth == 0)
381 NS_ABORT_MSG_IF(clientChannelWidth != 20 && clientChannelWidth != 40 &&
382 clientChannelWidth != 80 && clientChannelWidth != 160,
383 "Invalid channel width for standard " << standard);
385 "Invalid nss " << clientNss <<
" for standard " << standard);
389 uint32_t channelRateFactor =
std::max(clientChannelWidth, serverChannelWidth) / 20;
390 channelRateFactor = channelRateFactor *
std::max(clientNss, serverNss);
407 80 * channelRateFactor),
416 80 * channelRateFactor),
425 120 * channelRateFactor),
444 120 * channelRateFactor),
453 120 * channelRateFactor),
462 120 * channelRateFactor),
477 80 * channelRateFactor),
486 80 * channelRateFactor),
495 120 * channelRateFactor),
514 160 * channelRateFactor),
523 160 * channelRateFactor),
532 160 * channelRateFactor),
535 for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size(); i++)
537 if (standard == serverStandards[i].m_name)
539 serverSelectedStandard = serverStandards[i];
542 for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size(); i++)
544 if (standard == clientStandards[i].m_name)
546 clientSelectedStandard = clientStandards[i];
551 "Standard " << standard <<
" not found");
553 "Standard " << standard <<
" not found");
554 std::cout <<
"Testing " << serverSelectedStandard.
m_name <<
" with " << wifiManager <<
" ..."
557 "SNR values in wrong order");
558 steps =
static_cast<uint32_t
>(std::abs(
static_cast<double>(clientSelectedStandard.
m_snrHigh -
563 <<
":" << clientSelectedStandard.
m_snrHigh);
564 Ptr<Node> clientNode = CreateObject<Node>();
565 Ptr<Node> serverNode = CreateObject<Node>();
567 std::string plotName =
"wifi-manager-example-";
568 std::string dataName =
"wifi-manager-example-";
569 plotName += wifiManager;
570 dataName += wifiManager;
573 plotName += standard;
574 dataName += standard;
575 if (standard ==
"802.11n-5GHz" || standard ==
"802.11n-2.4GHz" || standard ==
"802.11ac" ||
576 standard ==
"802.11ax-6GHz" || standard ==
"802.11ax-5GHz" || standard ==
"802.11ax-2.4GHz")
578 plotName +=
"-server_";
579 dataName +=
"-server_";
580 std::ostringstream oss;
581 oss << serverChannelWidth <<
"MHz_" << serverShortGuardInterval <<
"ns_" << serverNss
583 plotName += oss.str();
584 dataName += oss.str();
585 plotName +=
"-client_";
586 dataName +=
"-client_";
588 oss << clientChannelWidth <<
"MHz_" << clientShortGuardInterval <<
"ns_" << clientNss
590 plotName += oss.str();
591 dataName += oss.str();
595 std::ofstream outfile(dataName);
625 CreateObject<ConstantSpeedPropagationDelayModel>();
626 wifiChannel->SetPropagationDelayModel(delayModel);
628 wifiChannel->SetPropagationLossModel(rssLossModel);
631 wifi.SetRemoteStationManager(
"ns3::" + wifiManager +
"WifiManager",
644 wifiMac.
SetType(
"ns3::StaWifiMac",
"Ssid", SsidValue(
ssid));
646 serverSelectedStandard.
m_width,
647 serverSelectedStandard.
m_band,
649 wifiPhy.
Set(
"ChannelSettings", channelValue);
650 serverDevice =
wifi.Install(wifiPhy, wifiMac, serverNode);
652 wifiMac.
SetType(
"ns3::ApWifiMac",
"Ssid", SsidValue(
ssid));
654 clientSelectedStandard.
m_width,
655 clientSelectedStandard.
m_band,
657 clientDevice =
wifi.Install(wifiPhy, wifiMac, clientNode);
661 wifiMac.
SetType(
"ns3::AdhocWifiMac");
663 serverSelectedStandard.
m_width,
664 serverSelectedStandard.
m_band,
666 wifiPhy.
Set(
"ChannelSettings", channelValue);
667 serverDevice =
wifi.Install(wifiPhy, wifiMac, serverNode);
670 clientSelectedStandard.
m_width,
671 clientSelectedStandard.
m_band,
673 clientDevice =
wifi.Install(wifiPhy, wifiMac, clientNode);
678 wifi.AssignStreams(serverDevice, 100);
679 wifi.AssignStreams(clientDevice, 100);
681 Config::Set(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize",
685 "/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::" + wifiManager +
693 positionAlloc->Add(Vector(ap1_x, ap1_y, 0.0));
694 NS_LOG_INFO(
"Setting initial AP position to " << Vector(ap1_x, ap1_y, 0.0));
695 positionAlloc->Add(Vector(sta1_x, sta1_y, 0.0));
696 NS_LOG_INFO(
"Setting initial STA position to " << Vector(sta1_x, sta1_y, 0.0));
697 mobility.SetPositionAllocator(positionAlloc);
698 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
717 auto t_clientNss =
static_cast<uint8_t
>(clientNss);
718 auto t_serverNss =
static_cast<uint8_t
>(serverNss);
720 wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams(t_clientNss);
721 wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams(t_clientNss);
726 if (serverSelectedStandard.
m_name ==
"802.11n-5GHz" ||
727 serverSelectedStandard.
m_name ==
"802.11n-2.4GHz" ||
728 serverSelectedStandard.
m_name ==
"802.11ac")
731 clientHtConfiguration->SetShortGuardIntervalSupported(clientShortGuardInterval == 400);
733 serverHtConfiguration->SetShortGuardIntervalSupported(serverShortGuardInterval == 400);
735 else if (serverSelectedStandard.
m_name ==
"802.11ax-6GHz" ||
736 serverSelectedStandard.
m_name ==
"802.11ax-5GHz" ||
737 serverSelectedStandard.
m_name ==
"802.11ax-2.4GHz")
739 wndServer->GetHeConfiguration()->SetGuardInterval(
NanoSeconds(serverShortGuardInterval));
742 NS_LOG_DEBUG(
"Channel width " << wifiPhyPtrClient->GetChannelWidth() <<
" noiseDbm "
744 NS_LOG_DEBUG(
"NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams());
749 rssLossModel->SetRss(rssCurrent);
750 NS_LOG_INFO(
"Setting initial Rss to " << rssCurrent);
761 packetSocketHelper.
Install(serverNode);
762 packetSocketHelper.
Install(clientNode);
780 client->SetRemote(socketAddr);
786 double rate = clientSelectedStandard.
m_yMax * 1e6 * 1.10;
787 double clientInterval =
static_cast<double>(
packetSize) * 8 / rate;
788 NS_LOG_DEBUG(
"Setting interval to " << clientInterval <<
" sec for rate of " << rate
795 server->SetLocal(socketAddr);
806 std::ostringstream xMinStr;
807 std::ostringstream xMaxStr;
808 std::ostringstream yMaxStr;
809 std::string xRangeStr(
"set xrange [");
810 xMinStr << clientSelectedStandard.
m_xMin;
811 xRangeStr.append(xMinStr.str());
812 xRangeStr.append(
":");
813 xMaxStr << clientSelectedStandard.
m_xMax;
814 xRangeStr.append(xMaxStr.str());
815 xRangeStr.append(
"]");
816 std::string yRangeStr(
"set yrange [0:");
817 yMaxStr << clientSelectedStandard.
m_yMax;
818 yRangeStr.append(yMaxStr.str());
819 yRangeStr.append(
"]");
821 std::string title(
"Results for ");
822 title.append(standard);
823 title.append(
" with ");
824 title.append(wifiManager);
826 if (standard ==
"802.11n-5GHz" || standard ==
"802.11n-2.4GHz" || standard ==
"802.11ac" ||
827 standard ==
"802.11ax-6GHz" || standard ==
"802.11ax-5GHz" || standard ==
"802.11ax-2.4GHz")
829 std::ostringstream serverGiStrStr;
830 std::ostringstream serverWidthStrStr;
831 std::ostringstream serverNssStrStr;
832 title.append(
"server: width=");
833 serverWidthStrStr << serverSelectedStandard.
m_width;
834 title.append(serverWidthStrStr.str());
836 title.append(
" GI=");
837 serverGiStrStr << serverShortGuardInterval;
838 title.append(serverGiStrStr.str());
840 title.append(
" nss=");
841 serverNssStrStr << serverNss;
842 title.append(serverNssStrStr.str());
844 std::ostringstream clientGiStrStr;
845 std::ostringstream clientWidthStrStr;
846 std::ostringstream clientNssStrStr;
847 title.append(
"client: width=");
848 clientWidthStrStr << clientSelectedStandard.
m_width;
849 title.append(clientWidthStrStr.str());
851 title.append(
" GI=");
852 clientGiStrStr << clientShortGuardInterval;
853 title.append(clientGiStrStr.str());
855 title.append(
" nss=");
856 clientNssStrStr << clientNss;
857 title.append(clientNssStrStr.str());
859 gnuplot.
SetTerminal(
"postscript eps color enh \"Times-BoldItalic\"");
860 gnuplot.
SetLegend(
"SNR (dB)",
"Rate (Mb/s)");
a polymophic address class
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
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.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
uint32_t GetSize() 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 EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
The IEEE 802.11 SSID Information Element.
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() const
Ptr< HeConfiguration > GetHeConfiguration() const
Ptr< WifiPhy > GetPhy() const
void Set(std::string name, const AttributeValue &v)
void DisablePreambleDetectionModel()
Disable the preamble detection model on all links.
void SetNumberOfAntennas(uint8_t antennas)
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
std::tuple< uint8_t, uint16_t, WifiPhyBand, 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.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
uint16_t GetDefaultChannelWidth(WifiStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
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
uint64_t g_intervalRate
Rate in an interval.
void RateChange(uint64_t oldVal, uint64_t newVal)
Rate changed.
const double NOISE_DBM_Hz
Default value for noise.
void PacketRx(Ptr< const Packet > pkt, const Address &addr)
Packet received.
double g_intervalBytes
Bytes received in an interval.
double noiseDbm
Value for noise.
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, Step step, double rss, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
Change the signal model and report the rate.
static const uint32_t packetSize
Packet size generated at the AP.