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"
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"
80 NS_LOG_DEBUG (
"Change from " << oldVal <<
" to " << newVal);
110 StandardInfo (std::string name,
WifiStandard standard, uint16_t width,
double snrLow,
double snrHigh,
double xMin,
double xMax,
double yMax)
112 m_standard (standard),
139 actualDataset.
Add (snr, currentRate);
140 rssModel->SetRss (rss - step.
stepSize);
146 int main (
int argc,
char *argv[])
148 std::vector <StandardInfo> serverStandards;
149 std::vector <StandardInfo> clientStandards;
151 uint32_t rtsThreshold = 999999;
152 uint32_t maxAmpduSize = 65535;
161 uint16_t serverNss = 1;
162 uint16_t clientNss = 1;
163 uint16_t serverShortGuardInterval = 800;
164 uint16_t clientShortGuardInterval = 800;
165 uint16_t serverChannelWidth = 0;
166 uint16_t clientChannelWidth = 0;
167 std::string wifiManager (
"Ideal");
168 std::string standard (
"802.11a");
171 bool infrastructure =
false;
172 uint32_t maxSlrc = 7;
173 uint32_t maxSsrc = 7;
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.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);
190 cmd.AddValue (
"wifiManager",
"Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa, ThompsonSampling)", wifiManager);
191 cmd.AddValue (
"infrastructure",
"Use infrastructure instead of adhoc", infrastructure);
192 cmd.Parse (argc,argv);
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;
201 if (infrastructure ==
false)
203 NS_ABORT_MSG_IF (serverNss != clientNss,
"In ad hoc mode, we assume sender and receiver are similarly configured");
206 if (standard ==
"802.11b")
208 if (serverChannelWidth == 0)
212 NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22,
"Invalid channel width for standard " << standard);
213 NS_ABORT_MSG_IF (serverNss != 1,
"Invalid nss for standard " << standard);
214 if (clientChannelWidth == 0)
218 NS_ABORT_MSG_IF (clientChannelWidth != 22 && clientChannelWidth != 22,
"Invalid channel width for standard " << standard);
219 NS_ABORT_MSG_IF (clientNss != 1,
"Invalid nss for standard " << standard);
221 else if (standard ==
"802.11a" || standard ==
"802.11g")
223 if (serverChannelWidth == 0)
227 NS_ABORT_MSG_IF (serverChannelWidth != 20,
"Invalid channel width for standard " << standard);
228 NS_ABORT_MSG_IF (serverNss != 1,
"Invalid nss for standard " << standard);
229 if (clientChannelWidth == 0)
233 NS_ABORT_MSG_IF (clientChannelWidth != 20,
"Invalid channel width for standard " << standard);
234 NS_ABORT_MSG_IF (clientNss != 1,
"Invalid nss for standard " << standard);
236 else if (standard ==
"802.11n-5GHz" || standard ==
"802.11n-2.4GHz")
239 if (serverChannelWidth == 0)
243 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40,
"Invalid channel width for standard " << standard);
244 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
245 if (clientChannelWidth == 0)
249 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40,
"Invalid channel width for standard " << standard);
250 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
252 else if (standard ==
"802.11ac")
254 if (serverChannelWidth == 0)
258 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160,
"Invalid channel width for standard " << standard);
259 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
260 if (clientChannelWidth == 0)
264 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160,
"Invalid channel width for standard " << standard);
265 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
267 else if (standard ==
"802.11ax-6GHz" ||standard ==
"802.11ax-5GHz" || standard ==
"802.11ax-2.4GHz")
270 if (serverChannelWidth == 0)
274 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160,
"Invalid channel width for standard " << standard);
275 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
276 if (clientChannelWidth == 0)
280 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160,
"Invalid channel width for standard " << standard);
281 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
285 uint32_t channelRateFactor =
std::max (clientChannelWidth, serverChannelWidth) / 20;
286 channelRateFactor = channelRateFactor *
std::max (clientNss, serverNss);
315 for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size (); i++)
317 if (standard == serverStandards[i].m_name)
319 serverSelectedStandard = serverStandards[i];
322 for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size (); i++)
324 if (standard == clientStandards[i].m_name)
326 clientSelectedStandard = clientStandards[i];
332 std::cout <<
"Testing " << serverSelectedStandard.
m_name <<
" with " << wifiManager <<
" ..." << std::endl;
334 steps =
static_cast<uint32_t
> (std::abs (
static_cast<double> (clientSelectedStandard.
m_snrHigh - clientSelectedStandard.
m_snrLow ) / stepSize) + 1);
336 Ptr<Node> clientNode = CreateObject<Node> ();
337 Ptr<Node> serverNode = CreateObject<Node> ();
339 std::string plotName =
"wifi-manager-example-";
340 std::string dataName =
"wifi-manager-example-";
341 plotName += wifiManager;
342 dataName += wifiManager;
345 plotName += standard;
346 dataName += standard;
347 if (standard ==
"802.11n-5GHz"
348 || standard ==
"802.11n-2.4GHz"
349 || standard ==
"802.11ac"
350 || standard ==
"802.11ax-6GHz"
351 || standard ==
"802.11ax-5GHz"
352 || standard ==
"802.11ax-2.4GHz")
354 plotName +=
"-server_";
355 dataName +=
"-server_";
356 std::ostringstream oss;
357 oss << serverChannelWidth <<
"MHz_" << serverShortGuardInterval <<
"ns_" << serverNss <<
"SS";
358 plotName += oss.str ();
359 dataName += oss.str ();
360 plotName +=
"-client_";
361 dataName +=
"-client_";
363 oss << clientChannelWidth <<
"MHz_" << clientShortGuardInterval <<
"ns_" << clientNss <<
"SS";
364 plotName += oss.str ();
365 dataName += oss.str ();
369 std::ofstream outfile (dataName.c_str ());
384 wifiChannel->SetPropagationDelayModel (delayModel);
386 wifiChannel->SetPropagationLossModel (rssLossModel);
389 wifi.SetRemoteStationManager (
"ns3::" + wifiManager +
"WifiManager",
"RtsCtsThreshold",
UintegerValue (rtsThreshold));
398 wifiMac.
SetType (
"ns3::StaWifiMac",
401 serverDevice =
wifi.Install (wifiPhy, wifiMac, serverNode);
402 wifiMac.
SetType (
"ns3::ApWifiMac",
405 clientDevice =
wifi.Install (wifiPhy, wifiMac, clientNode);
409 wifiMac.
SetType (
"ns3::AdhocWifiMac");
411 serverDevice =
wifi.Install (wifiPhy, wifiMac, serverNode);
413 clientDevice =
wifi.Install (wifiPhy, wifiMac, clientNode);
418 wifi.AssignStreams (serverDevice, 100);
419 wifi.AssignStreams (clientDevice, 100);
429 positionAlloc->Add (Vector (ap1_x, ap1_y, 0.0));
430 NS_LOG_INFO (
"Setting initial AP position to " << Vector (ap1_x, ap1_y, 0.0));
431 positionAlloc->Add (Vector (sta1_x, sta1_y, 0.0));
432 NS_LOG_INFO (
"Setting initial STA position to " << Vector (sta1_x, sta1_y, 0.0));
433 mobility.SetPositionAllocator (positionAlloc);
434 mobility.SetMobilityModel (
"ns3::ConstantPositionMobilityModel");
453 uint8_t t_clientNss =
static_cast<uint8_t
> (clientNss);
454 uint8_t t_serverNss =
static_cast<uint8_t
> (serverNss);
456 wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams (t_clientNss);
457 wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams (t_clientNss);
462 if (serverSelectedStandard.
m_name ==
"802.11n-5GHz"
463 || serverSelectedStandard.
m_name ==
"802.11n-2.4GHz"
464 || serverSelectedStandard.
m_name ==
"802.11ac")
467 clientHtConfiguration->SetShortGuardIntervalSupported (clientShortGuardInterval == 400);
469 serverHtConfiguration->SetShortGuardIntervalSupported (serverShortGuardInterval == 400);
471 else if (serverSelectedStandard.
m_name ==
"802.11ax-6GHz"
472 || serverSelectedStandard.
m_name ==
"802.11ax-5GHz"
473 || serverSelectedStandard.
m_name ==
"802.11ax-2.4GHz")
475 wndServer->GetHeConfiguration ()->SetGuardInterval (
NanoSeconds (serverShortGuardInterval));
478 NS_LOG_DEBUG (
"Channel width " << wifiPhyPtrClient->GetChannelWidth () <<
" noiseDbm " <<
noiseDbm);
479 NS_LOG_DEBUG (
"NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams ());
484 rssLossModel->SetRss (rssCurrent);
485 NS_LOG_INFO (
"Setting initial Rss to " << rssCurrent);
490 packetSocketHelper.
Install (serverNode);
491 packetSocketHelper.
Install (clientNode);
509 client->SetRemote (socketAddr);
510 client->SetStartTime (
Seconds (0.5));
515 double rate = clientSelectedStandard.
m_yMax * 1e6 * 1.10;
516 double clientInterval =
static_cast<double> (
packetSize) * 8 / rate;
517 NS_LOG_DEBUG (
"Setting interval to " << clientInterval <<
" sec for rate of " << rate <<
" bits/sec");
523 server->SetLocal (socketAddr);
534 std::ostringstream xMinStr, xMaxStr, yMaxStr;
535 std::string xRangeStr (
"set xrange [");
536 xMinStr << clientSelectedStandard.
m_xMin;
537 xRangeStr.append (xMinStr.str ());
538 xRangeStr.append (
":");
539 xMaxStr << clientSelectedStandard.
m_xMax;
540 xRangeStr.append (xMaxStr.str ());
541 xRangeStr.append (
"]");
542 std::string yRangeStr (
"set yrange [0:");
543 yMaxStr << clientSelectedStandard.
m_yMax;
544 yRangeStr.append (yMaxStr.str ());
545 yRangeStr.append (
"]");
547 std::string title (
"Results for ");
548 title.append (standard);
549 title.append (
" with ");
550 title.append (wifiManager);
551 title.append (
"\\n");
552 if (standard ==
"802.11n-5GHz"
553 || standard ==
"802.11n-2.4GHz"
554 || standard ==
"802.11ac"
555 || standard ==
"802.11ax-6GHz"
556 || standard ==
"802.11ax-5GHz"
557 || standard ==
"802.11ax-2.4GHz")
559 std::ostringstream serverGiStrStr;
560 std::ostringstream serverWidthStrStr;
561 std::ostringstream serverNssStrStr;
562 title.append (
"server: width=");
563 serverWidthStrStr << serverSelectedStandard.
m_width;
564 title.append (serverWidthStrStr.str ());
565 title.append (
"MHz");
566 title.append (
" GI=");
567 serverGiStrStr << serverShortGuardInterval;
568 title.append (serverGiStrStr.str ());
570 title.append (
" nss=");
571 serverNssStrStr << serverNss;
572 title.append (serverNssStrStr.str ());
573 title.append (
"\\n");
574 std::ostringstream clientGiStrStr;
575 std::ostringstream clientWidthStrStr;
576 std::ostringstream clientNssStrStr;
577 title.append (
"client: width=");
578 clientWidthStrStr << clientSelectedStandard.
m_width;
579 title.append (clientWidthStrStr.str ());
580 title.append (
"MHz");
581 title.append (
" GI=");
582 clientGiStrStr << clientShortGuardInterval;
583 title.append (clientGiStrStr.str ());
585 title.append (
" nss=");
586 clientNssStrStr << clientNss;
587 title.append (clientNssStrStr.str ());
589 gnuplot.
SetTerminal (
"postscript eps color enh \"Times-BoldItalic\"");
590 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.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
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 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)
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 allowed configurations that a Wifi device is configured to use.
WifiPhyBand
Identifies the PHY band.
@ WIFI_PHY_STANDARD_80211b
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
@ WIFI_PHY_STANDARD_80211ac
VHT PHY (clause 22)
@ WIFI_PHY_STANDARD_80211ax
HE PHY (clause 26)
@ WIFI_PHY_STANDARD_80211g
ERP-OFDM PHY (Clause 19, Section 19.5)
@ WIFI_PHY_STANDARD_80211n
HT PHY (clause 20)
@ WIFI_STANDARD_80211n_5GHZ
@ WIFI_STANDARD_80211ax_5GHZ
@ WIFI_STANDARD_80211n_2_4GHZ
@ WIFI_STANDARD_80211ax_2_4GHZ
@ WIFI_STANDARD_80211ax_6GHZ
@ 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(WifiPhyStandard 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, uint16_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
Constructor.
uint16_t m_width
channel width
WifiStandard m_standard
standard
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