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" 79 NS_LOG_DEBUG (
"Change from " << oldVal <<
" to " << newVal);
111 m_standard (standard),
138 actualDataset.
Add (snr, currentRate);
145 int main (
int argc,
char *argv[])
147 std::vector <StandardInfo> serverStandards;
148 std::vector <StandardInfo> clientStandards;
150 uint32_t rtsThreshold = 999999;
151 uint32_t maxAmpduSize = 65535;
160 uint16_t serverNss = 1;
161 uint16_t clientNss = 1;
162 uint16_t serverShortGuardInterval = 800;
163 uint16_t clientShortGuardInterval = 800;
164 uint16_t serverChannelWidth = 20;
165 uint16_t clientChannelWidth = 20;
166 std::string wifiManager (
"Ideal");
167 std::string standard (
"802.11a");
170 bool infrastructure =
false;
171 uint32_t maxSlrc = 7;
172 uint32_t maxSsrc = 7;
175 cmd.AddValue (
"maxSsrc",
"The maximum number of retransmission attempts for a RTS packet", maxSsrc);
176 cmd.AddValue (
"maxSlrc",
"The maximum number of retransmission attempts for a DATA packet", maxSlrc);
177 cmd.AddValue (
"rtsThreshold",
"RTS threshold", rtsThreshold);
178 cmd.AddValue (
"maxAmpduSize",
"Max A-MPDU size", maxAmpduSize);
179 cmd.AddValue (
"stepSize",
"Power between steps (dBm)", stepSize);
180 cmd.AddValue (
"stepTime",
"Time on each step (seconds)", stepTime);
181 cmd.AddValue (
"broadcast",
"Send broadcast instead of unicast", broadcast);
182 cmd.AddValue (
"serverChannelWidth",
"Set channel width of the server (valid only for 802.11n or ac)", serverChannelWidth);
183 cmd.AddValue (
"clientChannelWidth",
"Set channel width of the client (valid only for 802.11n or ac)", clientChannelWidth);
184 cmd.AddValue (
"serverNss",
"Set nss of the server (valid only for 802.11n or ac)", serverNss);
185 cmd.AddValue (
"clientNss",
"Set nss of the client (valid only for 802.11n or ac)", clientNss);
186 cmd.AddValue (
"serverShortGuardInterval",
"Set short guard interval of the server (802.11n/ac/ax) in nanoseconds", serverShortGuardInterval);
187 cmd.AddValue (
"clientShortGuardInterval",
"Set short guard interval of the client (802.11n/ac/ax) in nanoseconds", clientShortGuardInterval);
188 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);
189 cmd.AddValue (
"wifiManager",
"Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, MinstrelHt, Onoe, Rraa)", wifiManager);
190 cmd.AddValue (
"infrastructure",
"Use infrastructure instead of adhoc", infrastructure);
191 cmd.Parse (argc,argv);
194 std::cout << std::endl <<
"This program demonstrates and plots the operation of different " << std::endl;
195 std::cout <<
"Wi-Fi rate controls on different station configurations," << std::endl;
196 std::cout <<
"by stepping down the received signal strength across a wide range" << std::endl;
197 std::cout <<
"and observing the adjustment of the rate." << std::endl;
198 std::cout <<
"Run 'wifi-manager-example --PrintHelp' to show program options." << std::endl << std::endl;
200 if (infrastructure ==
false)
202 NS_ABORT_MSG_IF (serverNss != clientNss,
"In ad hoc mode, we assume sender and receiver are similarly configured");
205 if (standard ==
"802.11b")
207 NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22,
"Invalid channel width for standard " << standard);
208 NS_ABORT_MSG_IF (serverNss != 1,
"Invalid nss for standard " << standard);
209 NS_ABORT_MSG_IF (clientChannelWidth != 22 && clientChannelWidth != 22,
"Invalid channel width for standard " << standard);
210 NS_ABORT_MSG_IF (clientNss != 1,
"Invalid nss for standard " << standard);
212 else if (standard ==
"802.11a" || standard ==
"802.11g")
214 NS_ABORT_MSG_IF (serverChannelWidth != 20,
"Invalid channel width for standard " << standard);
215 NS_ABORT_MSG_IF (serverNss != 1,
"Invalid nss for standard " << standard);
216 NS_ABORT_MSG_IF (clientChannelWidth != 20,
"Invalid channel width for standard " << standard);
217 NS_ABORT_MSG_IF (clientNss != 1,
"Invalid nss for standard " << standard);
219 else if (standard ==
"802.11n-5GHz" || standard ==
"802.11n-2.4GHz")
221 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40,
"Invalid channel width for standard " << standard);
222 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
223 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40,
"Invalid channel width for standard " << standard);
224 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
226 else if (standard ==
"802.11ac")
228 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160,
"Invalid channel width for standard " << standard);
229 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
230 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160,
"Invalid channel width for standard " << standard);
231 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
233 else if (standard ==
"802.11ax-5GHz" || standard ==
"802.11ax-2.4GHz")
235 NS_ABORT_MSG_IF (serverChannelWidth != 20 && serverChannelWidth != 40 && serverChannelWidth != 80 && serverChannelWidth != 160,
"Invalid channel width for standard " << standard);
236 NS_ABORT_MSG_IF (serverNss == 0 || serverNss > 4,
"Invalid nss " << serverNss <<
" for standard " << standard);
237 NS_ABORT_MSG_IF (clientChannelWidth != 20 && clientChannelWidth != 40 && clientChannelWidth != 80 && clientChannelWidth != 160,
"Invalid channel width for standard " << standard);
238 NS_ABORT_MSG_IF (clientNss == 0 || clientNss > 4,
"Invalid nss " << clientNss <<
" for standard " << standard);
241 std::string plotName =
"wifi-manager-example-";
242 std::string dataName =
"wifi-manager-example-";
243 plotName += wifiManager;
244 dataName += wifiManager;
247 plotName += standard;
248 dataName += standard;
249 if (standard ==
"802.11n-5GHz" 250 || standard ==
"802.11n-2.4GHz" 251 || standard ==
"802.11ac" 252 || standard ==
"802.11ax-5GHz" 253 || standard ==
"802.11ax-2.4GHz")
255 plotName +=
"-server=";
256 dataName +=
"-server=";
257 std::ostringstream oss;
258 oss << serverChannelWidth <<
"MHz_" << serverShortGuardInterval <<
"ns_" << serverNss <<
"SS";
259 plotName += oss.str ();
260 dataName += oss.str ();
261 plotName +=
"-client=";
262 dataName +=
"-client=";
264 oss << clientChannelWidth <<
"MHz_" << clientShortGuardInterval <<
"ns_" << clientNss <<
"SS";
265 plotName += oss.str ();
266 dataName += oss.str ();
270 std::ofstream outfile (dataName.c_str ());
274 uint32_t channelRateFactor =
std::max (clientChannelWidth, serverChannelWidth) / 20;
275 channelRateFactor = channelRateFactor *
std::max (clientNss, serverNss);
304 for (std::vector<StandardInfo>::size_type i = 0; i != serverStandards.size (); i++)
306 if (standard == serverStandards[i].m_name)
308 serverSelectedStandard = serverStandards[i];
311 for (std::vector<StandardInfo>::size_type i = 0; i != clientStandards.size (); i++)
313 if (standard == clientStandards[i].m_name)
315 clientSelectedStandard = clientStandards[i];
321 std::cout <<
"Testing " << serverSelectedStandard.
m_name <<
" with " << wifiManager <<
" ..." << std::endl;
323 steps =
static_cast<uint32_t
> (std::abs (static_cast<double> (clientSelectedStandard.
m_snrHigh - clientSelectedStandard.
m_snrLow ) / stepSize) + 1);
325 Ptr<Node> clientNode = CreateObject<Node> ();
326 Ptr<Node> serverNode = CreateObject<Node> ();
348 wifi.SetRemoteStationManager (
"ns3::" + wifiManager +
"WifiManager",
"RtsCtsThreshold",
UintegerValue (rtsThreshold));
357 wifiMac.
SetType (
"ns3::StaWifiMac",
360 serverDevice =
wifi.Install (wifiPhy, wifiMac, serverNode);
361 wifiMac.
SetType (
"ns3::ApWifiMac",
364 clientDevice =
wifi.Install (wifiPhy, wifiMac, clientNode);
368 wifiMac.
SetType (
"ns3::AdhocWifiMac",
370 serverDevice =
wifi.Install (wifiPhy, wifiMac, serverNode);
371 clientDevice =
wifi.Install (wifiPhy, wifiMac, clientNode);
376 wifi.AssignStreams (serverDevice, 100);
377 wifi.AssignStreams (clientDevice, 100);
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));
389 mobility.SetPositionAllocator (positionAlloc);
390 mobility.SetMobilityModel (
"ns3::ConstantPositionMobilityModel");
409 uint8_t t_clientNss =
static_cast<uint8_t
> (clientNss);
410 uint8_t t_serverNss =
static_cast<uint8_t
> (serverNss);
412 wifiPhyPtrClient->SetMaxSupportedTxSpatialStreams (t_clientNss);
413 wifiPhyPtrClient->SetMaxSupportedRxSpatialStreams (t_clientNss);
418 if (serverSelectedStandard.
m_name ==
"802.11n-5GHz" 419 || serverSelectedStandard.
m_name ==
"802.11n-2.4GHz" 420 || serverSelectedStandard.
m_name ==
"802.11ac")
424 wifiPhyPtrClient->SetChannelWidth (clientSelectedStandard.
m_width);
425 wifiPhyPtrClient->SetShortGuardInterval (clientShortGuardInterval == 400);
427 else if (serverSelectedStandard.
m_name ==
"802.11ax-5GHz" 428 || serverSelectedStandard.
m_name ==
"802.11ax-2.4GHz")
432 wifiPhyPtrClient->SetChannelWidth (clientSelectedStandard.
m_width);
433 wifiPhyPtrClient->SetGuardInterval (
NanoSeconds (clientShortGuardInterval));
435 NS_LOG_DEBUG (
"Channel width " << wifiPhyPtrClient->GetChannelWidth () <<
" noiseDbm " <<
noiseDbm);
436 NS_LOG_DEBUG (
"NSS " << wifiPhyPtrClient->GetMaxSupportedTxSpatialStreams ());
441 rssLossModel->
SetRss (rssCurrent);
442 NS_LOG_INFO (
"Setting initial Rss to " << rssCurrent);
447 packetSocketHelper.
Install (serverNode);
448 packetSocketHelper.
Install (clientNode);
472 double rate = clientSelectedStandard.
m_yMax * 1e6 * 1.10;
473 double clientInterval =
static_cast<double> (
packetSize) * 8 / rate;
474 NS_LOG_DEBUG (
"Setting interval to " << clientInterval <<
" sec for rate of " << rate <<
" bits/sec");
482 serverNode->AddApplication (server);
488 gnuplot.AddDataset (rateDataset);
489 gnuplot.AddDataset (actualDataset);
491 std::ostringstream xMinStr, xMaxStr, yMaxStr;
492 std::string xRangeStr (
"set xrange [");
493 xMinStr << clientSelectedStandard.
m_xMin;
494 xRangeStr.append (xMinStr.str ());
495 xRangeStr.append (
":");
496 xMaxStr << clientSelectedStandard.
m_xMax;
497 xRangeStr.append (xMaxStr.str ());
498 xRangeStr.append (
"]");
499 std::string yRangeStr (
"set yrange [0:");
500 yMaxStr << clientSelectedStandard.
m_yMax;
501 yRangeStr.append (yMaxStr.str ());
502 yRangeStr.append (
"]");
504 std::string title (
"Results for ");
505 title.append (standard);
506 title.append (
" with ");
507 title.append (wifiManager);
508 title.append (
"\\n");
509 if (standard ==
"802.11n-5GHz" 510 || standard ==
"802.11n-2.4GHz" 511 || standard ==
"802.11ac" 512 || standard ==
"802.11n-5GHz" 513 || standard ==
"802.11ax-2.4GHz")
515 std::ostringstream serverGiStrStr;
516 std::ostringstream serverWidthStrStr;
517 std::ostringstream serverNssStrStr;
518 title.append (
"server: width=");
519 serverWidthStrStr << serverSelectedStandard.
m_width;
520 title.append (serverWidthStrStr.str ());
521 title.append (
"MHz");
522 title.append (
" GI=");
523 serverGiStrStr << serverShortGuardInterval;
524 title.append (serverGiStrStr.str ());
526 title.append (
" nss=");
527 serverNssStrStr << serverNss;
528 title.append (serverNssStrStr.str ());
529 title.append (
"\\n");
530 std::ostringstream clientGiStrStr;
531 std::ostringstream clientWidthStrStr;
532 std::ostringstream clientNssStrStr;
533 title.append (
"client: width=");
534 clientWidthStrStr << clientSelectedStandard.
m_width;
535 title.append (clientWidthStrStr.str ());
536 title.append (
"MHz");
537 title.append (
" GI=");
538 clientGiStrStr << clientShortGuardInterval;
539 title.append (clientGiStrStr.str ());
541 title.append (
" nss=");
542 clientNssStrStr << clientNss;
543 title.append (clientNssStrStr.str ());
545 gnuplot.SetTerminal (
"postscript eps color enh \"Times-BoldItalic\"");
546 gnuplot.SetLegend (
"SNR (dB)",
"Rate (Mb/s)");
547 gnuplot.SetTitle (title);
548 gnuplot.SetExtra (xRangeStr);
549 gnuplot.AppendExtra (yRangeStr);
550 gnuplot.AppendExtra (
"set key top left");
551 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.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
#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.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
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)
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
void SetChannel(Ptr< YansWifiChannel > channel)
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
void SetPropagationDelayModel(const Ptr< PropagationDelayModel > delay)
HE PHY for the 5 GHz band (clause 26)
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
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
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Ptr< WifiPhy > GetPhy(void) const
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(uint16_t channelwidth)
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
void SetShortGuardInterval(bool shortGuardInterval)
Enable or disable support for HT/VHT short guard interval.
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
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.
StandardInfo(std::string name, WifiPhyStandard standard, uint16_t width, double snrLow, double snrHigh, double xMin, double xMax, double yMax)
Constructor.
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.
uint16_t m_width
channel width
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
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 Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
void SetNumberOfAntennas(uint8_t antennas)
static const uint32_t packetSize
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.
void SetStartTime(Time start)
Specify application start time.