40 #include "ns3/core-module.h"
41 #include "ns3/network-module.h"
42 #include "ns3/wifi-module.h"
43 #include "ns3/stats-module.h"
44 #include "ns3/mobility-module.h"
45 #include "ns3/propagation-module.h"
46 #include "ns3/rng-seed-manager.h"
69 NS_LOG_DEBUG (
"Change from " << oldVal <<
" to " << newVal);
108 m_standard (standard),
135 actualDataset.
Add (snr, currentRate);
142 int main (
int argc,
char *argv[])
144 std::vector <StandardInfo> serverStandards;
145 std::vector <StandardInfo> clientStandards;
147 uint32_t rtsThreshold = 999999;
148 uint32_t maxAmpduSize = 65535;
157 uint16_t serverNss = 1;
158 uint16_t clientNss = 1;
159 uint16_t serverShortGuardInterval = 800;
160 uint16_t clientShortGuardInterval = 800;
161 uint16_t serverChannelWidth = 20;
162 uint16_t clientChannelWidth = 20;
163 std::string wifiManager (
"Ideal");
164 std::string standard (
"802.11a");
167 bool infrastructure =
false;
168 uint32_t maxSlrc = 7;
169 uint32_t maxSsrc = 7;
172 cmd.
AddValue (
"maxSsrc",
"The maximum number of retransmission attempts for a RTS packet", maxSsrc);
173 cmd.
AddValue (
"maxSlrc",
"The maximum number of retransmission attempts for a DATA packet", maxSlrc);
174 cmd.
AddValue (
"rtsThreshold",
"RTS threshold", rtsThreshold);
175 cmd.
AddValue (
"maxAmpduSize",
"Max A-MPDU size", maxAmpduSize);
176 cmd.
AddValue (
"stepSize",
"Power between steps (dBm)", stepSize);
177 cmd.
AddValue (
"stepTime",
"Time on each step (seconds)", stepTime);
178 cmd.
AddValue (
"broadcast",
"Send broadcast instead of unicast", broadcast);
179 cmd.
AddValue (
"serverChannelWidth",
"Set channel width of the server (valid only for 802.11n or ac)", serverChannelWidth);
180 cmd.
AddValue (
"clientChannelWidth",
"Set channel width of the client (valid only for 802.11n or ac)", clientChannelWidth);
181 cmd.
AddValue (
"serverNss",
"Set nss of the server (valid only for 802.11n or ac)", serverNss);
182 cmd.
AddValue (
"clientNss",
"Set nss of the client (valid only for 802.11n or ac)", clientNss);
183 cmd.
AddValue (
"serverShortGuardInterval",
"Set short guard interval of the server (802.11n/ac/ax) in nanoseconds", serverShortGuardInterval);
184 cmd.
AddValue (
"clientShortGuardInterval",
"Set short guard interval of the client (802.11n/ac/ax) in nanoseconds", clientShortGuardInterval);
185 cmd.
AddValue (
"standard",
"Set standard (802.11a, 802.11b, 802.11g, 802.11n-5GHz, 802.11n-2.4GHz, 802.11ac, 802.11-holland, 802.11-10MHz, 802.11-5MHz, 802.11ax-5GHz, 802.11ax-2.4GHz)", standard);
186 cmd.
AddValue (
"wifiManager",
"Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa)", wifiManager);
187 cmd.
AddValue (
"infrastructure",
"Use infrastructure instead of adhoc", infrastructure);
188 cmd.
Parse (argc,argv);
191 std::cout << std::endl <<
"This program demonstrates and plots the operation of different " << std::endl;
192 std::cout <<
"Wi-Fi rate controls on different station configurations," << std::endl;
193 std::cout <<
"by stepping down the received signal strength across a wide range" << std::endl;
194 std::cout <<
"and observing the adjustment of the rate." << std::endl;
195 std::cout <<
"Run 'wifi-manager-example --PrintHelp' to show program options."<< std::endl << std::endl;
197 if (infrastructure ==
false)
199 NS_ABORT_MSG_IF (serverNss != clientNss,
"In ad hoc mode, we assume sender and receiver are similarly configured");
202 if (standard ==
"802.11b")
204 NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22,
"Invalid channel width for standard " << standard);
205 NS_ABORT_MSG_IF (serverNss != 1,
"Invalid nss for standard " << standard);
206 NS_ABORT_MSG_IF (clientChannelWidth != 22 && clientChannelWidth != 22,
"Invalid channel width for standard " << standard);
207 NS_ABORT_MSG_IF (clientNss != 1,
"Invalid nss for standard " << standard);
209 else if (standard ==
"802.11a" || standard ==
"802.11g")
211 NS_ABORT_MSG_IF (serverChannelWidth != 20,
"Invalid channel width for standard " << standard);
212 NS_ABORT_MSG_IF (serverNss != 1,
"Invalid nss for standard " << standard);
213 NS_ABORT_MSG_IF (clientChannelWidth != 20,
"Invalid channel width for standard " << standard);
214 NS_ABORT_MSG_IF (clientNss != 1,
"Invalid nss for standard " << standard);
216 else if (standard ==
"802.11n-5GHz" || standard ==
"802.11n-2.4GHz")
218 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40,
"Invalid channel width for standard " << standard);
219 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
220 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40,
"Invalid channel width for standard " << standard);
221 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
223 else if (standard ==
"802.11ac")
225 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160,
"Invalid channel width for standard " << standard);
226 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
227 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160,
"Invalid channel width for standard " << standard);
228 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
230 else if (standard ==
"802.11ax-5GHz" || standard ==
"802.11ax-2.4GHz")
232 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160,
"Invalid channel width for standard " << standard);
233 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
234 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160,
"Invalid channel width for standard " << standard);
235 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
238 std::string plotName =
"wifi-manager-example-";
239 std::string dataName =
"wifi-manager-example-";
240 plotName += wifiManager;
241 dataName += wifiManager;
244 plotName += standard;
245 dataName += standard;
246 if (standard ==
"802.11n-5GHz" ||
247 standard ==
"802.11n-2.4GHz" ||
248 standard ==
"802.11ac" ||
249 standard ==
"802.11ax-5GHz" ||
250 standard ==
"802.11ax-2.4GHz")
252 plotName +=
"-server=";
253 dataName +=
"-server=";
254 std::ostringstream oss;
255 oss << serverChannelWidth <<
"MHz_" << serverShortGuardInterval <<
"ns_" << serverNss <<
"SS";
256 plotName += oss.str ();
257 dataName += oss.str ();
258 plotName +=
"-client=";
259 dataName +=
"-client=";
261 oss << clientChannelWidth <<
"MHz_" << clientShortGuardInterval <<
"ns_" << clientNss <<
"SS";
262 plotName += oss.str ();
263 dataName += oss.str ();
267 std::ofstream outfile (dataName.c_str ());
271 uint32_t channelRateFactor =
std::max (clientChannelWidth, serverChannelWidth) / 20;
272 channelRateFactor = channelRateFactor *
std::max (clientNss, serverNss);
301 for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size (); i++)
303 if (standard == serverStandards[i].m_name)
305 serverSelectedStandard = serverStandards[i];
308 for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size (); i++)
310 if (standard == clientStandards[i].m_name)
312 clientSelectedStandard = clientStandards[i];
318 std::cout <<
"Testing " << serverSelectedStandard.
m_name <<
" with " << wifiManager <<
" ..." << std::endl;
320 steps =
static_cast<uint32_t
>(std::abs<double> ((clientSelectedStandard.
m_snrHigh - clientSelectedStandard.
m_snrLow ) / stepSize) + 1);
322 Ptr<Node> clientNode = CreateObject<Node> ();
323 Ptr<Node> serverNode = CreateObject<Node> ();
351 wifiMac.
SetType (
"ns3::StaWifiMac",
354 serverDevice = wifi.
Install (wifiPhy, wifiMac, serverNode);
355 wifiMac.
SetType (
"ns3::ApWifiMac",
358 clientDevice = wifi.
Install (wifiPhy, wifiMac, clientNode);
362 wifiMac.
SetType (
"ns3::AdhocWifiMac",
364 serverDevice = wifi.
Install (wifiPhy, wifiMac, serverNode);
365 clientDevice = wifi.
Install (wifiPhy, wifiMac, clientNode);
373 if (wifiManager ==
"MinstrelHt")
385 positionAlloc->
Add (Vector (ap1_x, ap1_y, 0.0));
386 NS_LOG_INFO (
"Setting initial AP position to " << Vector (ap1_x, ap1_y, 0.0));
387 positionAlloc->
Add (Vector (sta1_x, sta1_y, 0.0));
388 NS_LOG_INFO (
"Setting initial STA position to " << Vector (sta1_x, sta1_y, 0.0));
410 wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams (clientNss);
411 wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams (clientNss);
416 if (serverSelectedStandard.
m_name ==
"802.11n-5GHz"
417 || serverSelectedStandard.
m_name ==
"802.11n-2.4GHz"
418 || serverSelectedStandard.
m_name ==
"802.11ac")
422 wifiPhyPtrClient->SetChannelWidth (clientSelectedStandard.
m_width);
423 wifiPhyPtrClient->SetShortGuardInterval (clientShortGuardInterval == 400);
425 else if (serverSelectedStandard.
m_name ==
"802.11ax-5GHz"
426 || serverSelectedStandard.
m_name ==
"802.11ax-2.4GHz")
430 wifiPhyPtrClient->SetChannelWidth (clientSelectedStandard.
m_width);
431 wifiPhyPtrClient->SetGuardInterval (
NanoSeconds (clientShortGuardInterval));
433 NS_LOG_DEBUG (
"Channel width " << wifiPhyPtrClient->GetChannelWidth () <<
" noiseDbm " <<
noiseDbm);
434 NS_LOG_DEBUG (
"NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams ());
439 rssLossModel->
SetRss (rssCurrent);
440 NS_LOG_INFO (
"Setting initial Rss to " << rssCurrent);
445 packetSocketHelper.
Install (serverNode);
446 packetSocketHelper.
Install (clientNode);
470 double rate = clientSelectedStandard.
m_yMax * 1e6 * 1.10;
471 double clientInterval =
static_cast<double> (
packetSize) * 8 / rate;
472 NS_LOG_DEBUG (
"Setting interval to " << clientInterval <<
" sec for rate of " << rate <<
" bits/sec");
480 serverNode->AddApplication (server);
486 gnuplot.AddDataset (rateDataset);
487 gnuplot.AddDataset (actualDataset);
489 std::ostringstream xMinStr, xMaxStr, yMaxStr;
490 std::string xRangeStr (
"set xrange [");
491 xMinStr << clientSelectedStandard.
m_xMin;
492 xRangeStr.append (xMinStr.str ());
493 xRangeStr.append (
":");
494 xMaxStr << clientSelectedStandard.
m_xMax;
495 xRangeStr.append (xMaxStr.str ());
496 xRangeStr.append (
"]");
497 std::string yRangeStr (
"set yrange [0:");
498 yMaxStr << clientSelectedStandard.
m_yMax;
499 yRangeStr.append (yMaxStr.str ());
500 yRangeStr.append (
"]");
502 std::string title (
"Results for ");
503 title.append (standard);
504 title.append (
" with ");
505 title.append (wifiManager);
506 title.append (
"\\n");
507 if (standard ==
"802.11n-5GHz"
508 || standard ==
"802.11n-2.4GHz"
509 || standard ==
"802.11ac"
510 || standard ==
"802.11n-5GHz"
511 || standard ==
"802.11ax-2.4GHz")
513 std::ostringstream serverGiStrStr;
514 std::ostringstream serverWidthStrStr;
515 std::ostringstream serverNssStrStr;
516 title.append (
"server: width=");
517 serverWidthStrStr << serverSelectedStandard.
m_width;
518 title.append (serverWidthStrStr.str ());
519 title.append (
"MHz");
520 title.append (
" GI=");
521 serverGiStrStr << serverShortGuardInterval;
522 title.append (serverGiStrStr.str ());
524 title.append (
" nss=");
525 serverNssStrStr << serverNss;
526 title.append (serverNssStrStr.str ());
527 title.append (
"\\n");
528 std::ostringstream clientGiStrStr;
529 std::ostringstream clientWidthStrStr;
530 std::ostringstream clientNssStrStr;
531 title.append (
"client: width=");
532 clientWidthStrStr << clientSelectedStandard.
m_width;
533 title.append (clientWidthStrStr.str ());
534 title.append (
"MHz");
535 title.append (
" GI=");
536 clientGiStrStr << clientShortGuardInterval;
537 title.append (clientGiStrStr.str ());
539 title.append (
" nss=");
540 clientNssStrStr << clientNss;
541 title.append (clientNssStrStr.str ());
543 gnuplot.SetTerminal (
"postscript eps color enh \"Times-BoldItalic\"");
544 gnuplot.SetLegend (
"SNR (dB)",
"Rate (Mb/s)");
545 gnuplot.SetTitle (title);
546 gnuplot.SetExtra (xRangeStr);
547 gnuplot.AppendExtra (yRangeStr);
548 gnuplot.AppendExtra (
"set key top left");
549 gnuplot.GenerateOutput (outfile);
ERP-OFDM PHY (Clause 19, Section 19.5)
void Set(std::string name, const AttributeValue &v)
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
OFDM PHY for the 5 GHz band (Clause 17 with 5 MHz channel bandwidth)
AttributeValue implementation for Boolean.
void SetLocal(PacketSocketAddress addr)
set the local address and protocol to be used
void SetPropagationLossModel(const Ptr< PropagationLossModel > loss)
HT PHY for the 5 GHz band (clause 20)
Class to represent a 2D points plot.
void SetRemoteStationManager(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
Make it easy to create and manage PHY objects for the yans model.
an address for a packet socket
static void Run(void)
Run the simulation.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
HE PHY for the 2.4 GHz band (clause 26)
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
OFDM PHY for the 5 GHz band (Clause 17 with 10 MHz channel bandwidth)
double m_snrLow
lowest SNR
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
const double NOISE_DBM_Hz
HT PHY for the 2.4 GHz band (clause 20)
static YansWifiPhyHelper Default(void)
Create a phy helper in a default working state.
double stepSize
step size in dBm
helps to create WifiNetDevice objects
void ChangeSignalAndReportRate(Ptr< FixedRssLossModel > rssModel, struct Step step, double rss, Gnuplot2dDataset &rateDataset, Gnuplot2dDataset &actualDataset)
Give ns3::PacketSocket powers to ns3::Node.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
static void SetRun(uint64_t run)
Set the run number of simulation.
a polymophic address class
virtual void SetStandard(WifiPhyStandard standard)
void SetChannel(Ptr< YansWifiChannel > channel)
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
Ptr< WifiPhy > GetPhy(void) const
void SetPropagationDelayModel(const Ptr< PropagationDelayModel > delay)
HE PHY for the 5 GHz band (clause 26)
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
AttributeValue implementation for Time.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Hold an unsigned integer type.
holds a vector of ns3::NetDevice pointers
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer::Iterator first, NodeContainer::Iterator last) const
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the Phy and Mac aspects ...
Hold together all Wifi-related objects.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
void Add(double x, double y)
void PacketRx(Ptr< const Packet > pkt, const Address &addr)
Parse command-line arguments.
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
This is intended to be the configuration used in this paper: Gavin Holland, Nitin Vaidya and Paramvir...
double m_snrHigh
highest SNR
void RateChangeMinstrelHt(uint64_t newVal, Mac48Address dest)
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
OFDM PHY for the 5 GHz band (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPhysicalAddress(const Address address)
Set the destination address.
virtual void SetChannelWidth(uint8_t channelwidth)
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
void SetMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
void SetShortGuardInterval(bool shortGuardInterval)
Enable or disable support for HT/VHT short guard interval.
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
create MAC layers for a ns3::WifiNetDevice.
static Time Now(void)
Return the current simulation virtual time.
void SetGuardInterval(Time guardInterval)
The IEEE 802.11 SSID Information Element.
virtual void SetType(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue(), std::string n10="", const AttributeValue &v10=EmptyAttributeValue())
static void SetSeed(uint32_t seed)
Set the seed.
Helper class used to assign positions and mobility models to nodes.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
void SetRemote(PacketSocketAddress addr)
set the remote address and protocol to be used
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
WifiPhyStandard m_standard
standard
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Time Seconds(double value)
Construct a Time in the indicated unit.
AttributeValue implementation for Ssid.
void SetDefault(std::string name, const AttributeValue &value)
double stepTime
step size in seconds
void SetProtocol(uint16_t protocol)
Set the protocol.
void Add(Vector v)
Add a position to the list of positions.
void Parse(int argc, char *argv[])
Parse the program arguments.
void SetNumberOfAntennas(uint8_t antennas)
static const uint32_t packetSize
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
StandardInfo(std::string name, WifiPhyStandard standard, uint8_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
Constructor.
void RateChange(uint64_t oldVal, uint64_t newVal)
This class can be used to hold variables of floating point type such as 'double' or 'float'...
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
uint8_t m_width
channel width
void SetStartTime(Time start)
Specify application start time.