9#include "ns3/boolean.h"
10#include "ns3/command-line.h"
11#include "ns3/config.h"
12#include "ns3/data-rate.h"
13#include "ns3/double.h"
15#include "ns3/error-model.h"
16#include "ns3/inet-socket-address.h"
17#include "ns3/internet-stack-helper.h"
18#include "ns3/ipv4-address-helper.h"
19#include "ns3/ipv4-l3-protocol.h"
20#include "ns3/ipv4-list-routing-helper.h"
21#include "ns3/ipv4-static-routing-helper.h"
22#include "ns3/ipv4-static-routing.h"
24#include "ns3/mobility-helper.h"
25#include "ns3/mobility-model.h"
28#include "ns3/on-off-helper.h"
29#include "ns3/packet-sink-helper.h"
30#include "ns3/packet-sink.h"
31#include "ns3/simulator.h"
32#include "ns3/socket.h"
34#include "ns3/string.h"
36#include "ns3/trace-helper.h"
37#include "ns3/udp-socket-factory.h"
38#include "ns3/udp-socket.h"
39#include "ns3/uinteger.h"
40#include "ns3/wifi-mac.h"
41#include "ns3/wifi-net-device.h"
42#include "ns3/wifi-psdu.h"
43#include "ns3/yans-wifi-channel.h"
44#include "ns3/yans-wifi-helper.h"
115 std::string sub = context.substr(10);
117 return std::stoi(sub.substr(0, pos));
168 auto psdu = psduMap.begin()->second;
169 if (psdu->GetHeader(0).GetAddr1().IsGroup() && !psdu->GetHeader(0).GetAddr1().IsBroadcast() &&
170 psdu->GetHeader(0).IsQosData())
172 NS_LOG_INFO(
"AP tx multicast: PSDU=" << *psdu <<
" TXVECTOR=" << txVector);
173 if (ranVar->GetValue() < errorRate)
175 auto uid = psdu->GetPayload(0)->GetUid();
176 NS_LOG_INFO(
"Corrupt multicast frame with UID=" << uid);
177 rxErrorModel->SetList({uid});
181 rxErrorModel->SetList({});
204 packet->RemoveHeader(hdr);
207 std::stringstream ss;
214main(
int argc,
char* argv[])
219 std::size_t nStations{1};
220 Time simulationTime{
"10s"};
224 uint32_t rtsThreshold{std::numeric_limits<uint16_t>::max()};
225 std::string targetAddr{
"239.192.100.1"};
226 std::string accessCategory{
"AC_BE"};
227 std::string gcrRetransmissionPolicy{
"NoAckNoRetry"};
228 std::string rateManager{
"Constant"};
229 uint16_t constantRateMcs{11};
230 uint16_t nRetriesGcrUr{7};
231 std::string gcrProtection{
"Rts-Cts"};
232 double multicastFrameErrorRate{0.0};
233 uint16_t maxAmpduLength{0};
234 double minExpectedPackets{0};
235 double maxExpectedPackets{0};
236 double minExpectedThroughput{0};
237 double maxExpectedThroughput{0};
238 double tolerance{0.01};
241 cmd.AddValue(
"logging",
"turn on example log components", logging);
242 cmd.AddValue(
"verbose",
"turn on all wifi log components",
verbose);
243 cmd.AddValue(
"pcap",
"turn on pcap file output", pcap);
244 cmd.AddValue(
"nStations",
"number of non-AP stations", nStations);
245 cmd.AddValue(
"simulationTime",
"Simulation time", simulationTime);
246 cmd.AddValue(
"payloadSize",
"The application payload size in bytes", payloadSize);
249 "The maximum number of packets to be generated by the application (0 for no limit)",
251 cmd.AddValue(
"dataRate",
"The application data rate", dataRate);
252 cmd.AddValue(
"rtsThreshold",
"RTS threshold", rtsThreshold);
253 cmd.AddValue(
"rateManager",
254 "The rate adaptation manager to use (Constant, Ideal, MinstrelHt)",
257 "The MCS to use if Constant rate adaptation manager is used",
259 cmd.AddValue(
"targetAddress",
"multicast target address", targetAddr);
260 cmd.AddValue(
"accessCategory",
261 "select the multicast traffic access category (AC_BE, AC_BK, AC_VI, AC_VO)",
264 "gcrRetransmissionPolicy",
265 "GCR retransmission policy for groupcast frames (NoAckNoRetry, GcrUr, GcrBlockAck)",
266 gcrRetransmissionPolicy);
267 cmd.AddValue(
"nRetriesGcrUr",
268 "number of retries per groupcast frame when GCR-UR retransmission policy is used",
270 cmd.AddValue(
"gcrProtection",
271 "protection to use for GCR (Rts-Cts or Cts-To-Self)",
273 cmd.AddValue(
"multicastFrameErrorRate",
274 "artificial error rate for multicast frame",
275 multicastFrameErrorRate);
276 cmd.AddValue(
"maxAmpduLength",
"maximum length in bytes of an A-MPDU", maxAmpduLength);
277 cmd.AddValue(
"minExpectedPackets",
278 "if set, simulation fails if the lowest amount of received packets is below this "
281 cmd.AddValue(
"maxExpectedPackets",
282 "if set, simulation fails if the highest amount of received packets is above this "
285 cmd.AddValue(
"minExpectedThroughput",
286 "if set, simulation fails if the throughput is below this value",
287 minExpectedThroughput);
288 cmd.AddValue(
"maxExpectedThroughput",
289 "if set, simulation fails if the throughput is above this value",
290 maxExpectedThroughput);
291 cmd.Parse(argc, argv);
317 wifiChannel.SetPropagationDelay(
"ns3::ConstantSpeedPropagationDelayModel");
321 if (rateManager ==
"Constant")
323 wifi.SetRemoteStationManager(
"ns3::ConstantRateWifiManager",
325 StringValue(
"HeMcs" + std::to_string(constantRateMcs)),
331 wifi.SetRemoteStationManager(
"ns3::" + rateManager +
"RateWifiManager",
336 if (gcrRetransmissionPolicy !=
"NoAckNoRetry")
338 std::string retransmissionPolicyStr;
339 if (gcrRetransmissionPolicy ==
"GcrUr")
341 retransmissionPolicyStr =
"GCR_UR";
343 else if (gcrRetransmissionPolicy ==
"GcrBlockAck")
345 retransmissionPolicyStr =
"GCR_BA";
349 std::cout <<
"Wrong retransmission policy!" << std::endl;
353 "RetransmissionPolicy",
355 "UnsolicitedRetryLimit",
365 auto apDevice =
wifi.Install(wifiPhy, wifiMac, wifiApNode);
373 ranVar->SetStream(1);
374 Config::Connect(
"/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phys/0/PhyTxPsduBegin",
376 for (std::size_t i = 0; i < nStations; ++i)
379 wifiMac->GetWifiPhy(0)->SetPostReceptionErrorModel(rxErrorModel);
381 Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxOk",
387 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
388 for (std::size_t i = 0; i < nStations; ++i)
390 positionAlloc->Add(Vector(i, 0.0, 0.0));
392 mobility.SetPositionAllocator(positionAlloc);
393 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
400 listRouting.
Add(staticRouting, 0);
404 internet.SetIpv6StackInstall(
false);
406 internet.SetRoutingHelper(listRouting);
411 ipv4address.
SetBase(
"10.0.0.0",
"255.255.255.0");
412 auto apNodeInterface = ipv4address.
Assign(apDevice);
413 auto staNodeInterfaces = ipv4address.
Assign(staDevices);
418 routing->AddHostRouteTo(targetAddr.c_str(),
423 std::string maxAmpduSizeAttribute;
424 if (accessCategory ==
"AC_BE")
427 maxAmpduSizeAttribute =
"BE_MaxAmpduSize";
429 else if (accessCategory ==
"AC_BK")
432 maxAmpduSizeAttribute =
"BK_MaxAmpduSize";
434 else if (accessCategory ==
"AC_VI")
437 maxAmpduSizeAttribute =
"VI_MaxAmpduSize";
439 else if (accessCategory ==
"AC_VO")
442 maxAmpduSizeAttribute =
"VO_MaxAmpduSize";
449 apWifiMac->SetAttribute(maxAmpduSizeAttribute,
UintegerValue(maxAmpduLength));
454 auto sinks = sinkHelper.Install(wifiStaNodes);
456 sinks.Stop(simulationTime +
Seconds(2.0));
460 OnOffHelper onoffHelper(
"ns3::UdpSocketFactory", sourceSocket);
461 onoffHelper.SetAttribute(
"DataRate",
DataRateValue(dataRate));
462 onoffHelper.SetAttribute(
"PacketSize",
UintegerValue(payloadSize));
463 onoffHelper.SetAttribute(
"MaxBytes",
UintegerValue(maxPackets * payloadSize));
465 onoffHelper.SetAttribute(
"OnTime",
StringValue(
"ns3::ConstantRandomVariable[Constant=1]"));
466 onoffHelper.SetAttribute(
"OffTime",
StringValue(
"ns3::ConstantRandomVariable[Constant=0]"));
467 auto source = onoffHelper.Install(wifiApNode);
469 source.Stop(simulationTime +
Seconds(1.0));
474 wifiPhy.
EnablePcap(
"wifi-multicast-AP", apDevice.Get(0));
475 for (std::size_t i = 0; i < nStations; ++i)
483 Config::Connect(
"/NodeList/*/$ns3::Node/ApplicationList/*/$ns3::OnOffApplication/Tx",
494 std::cout <<
"Node\t\t\tTX packets\t\tTX bytes\t\tRX packets\t\tRX bytes\t\tThroughput (Mbit/s)"
500 const auto txPackets =
g_txBytes / payloadSize;
502 <<
"\t\t\t" << txPackets <<
"\t\t\t" <<
g_txBytes <<
"\t\t\t0\t\t\t0\t\t\t" << txRate
504 for (std::size_t i = 0; i < nStations; ++i)
506 const auto rxBytes = sinks.Get(0)->GetObject<
PacketSink>()->GetTotalRx();
507 const auto rxPackets = rxBytes / payloadSize;
512 std::cout <<
"STA" << i + 1 <<
"\t\t\t0\t\t\t0\t\t\t" << rxPackets <<
"\t\t\t" << rxBytes
514 if (rxPackets < minExpectedPackets)
516 NS_LOG_ERROR(
"Obtained RX packets " << rxPackets <<
" is not expected!");
519 if (maxExpectedPackets > 0 && rxPackets > maxExpectedPackets)
521 NS_LOG_ERROR(
"Obtained RX packets " << rxPackets <<
" is not expected!");
524 if ((
throughput * (1 + tolerance)) < minExpectedThroughput)
529 if (maxExpectedThroughput > 0 && (
throughput > (maxExpectedThroughput * (1 + tolerance))))
a polymophic address class
Parse command-line arguments.
Class for representing data rates.
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
static Ipv4Address GetAny()
Access to the IPv4 forwarding table, interfaces, and configuration.
Helper class that adds ns3::Ipv4ListRouting objects.
void Add(const Ipv4RoutingHelper &routing, int16_t priority)
Helper class that adds ns3::Ipv4StaticRouting objects.
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Try and find the static routing protocol as either the main routing protocol or in the list of routin...
Helper class used to assign positions and mobility models to nodes.
keep track of a set of node pointers.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Receive and consume traffic generated to an IP address and port.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
Smart pointer class similar to boost::intrusive_ptr.
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 variables of type string.
Simulation virtual time values and global simulation resolution.
Hold an unsigned integer type.
helps to create WifiNetDevice objects
static void EnableLogComponents(LogLevel logLevel=LOG_LEVEL_ALL)
Helper to enable all WifiNetDevice log components with one statement.
create MAC layers for a ns3::WifiNetDevice.
void SetGcrManager(std::string type, Args &&... args)
Helper function used to set the GCR Manager that can be installed on a QoS AP.
void SetType(std::string type, Args &&... args)
represent a single transmission mode
void SetPcapDataLinkType(SupportedPcapDataLinkTypes dlt)
Set the data link type of PCAP traces to be used.
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
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 Connect(std::string path, const CallbackBase &cb)
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Time Seconds(double value)
Construct a Time in the indicated unit.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
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...
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
@ LOG_LEVEL_ALL
Print everything.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Time g_lastTx
Time at which last TX packet is generated.
void TxCallback(Ptr< ListErrorModel > rxErrorModel, Ptr< RandomVariableStream > ranVar, double errorRate, std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback when a frame is transmitted.
Time g_lastRx
Time at which last RX packet is received.
uint32_t ContextToNodeId(const std::string &context)
Parse context strings of the form "/NodeList/x/DeviceList/x/..." to extract the NodeId integer.
void RxCallback(std::string context, Ptr< const Packet > p, double snr, WifiMode mode, WifiPreamble preamble)
Callback when a frame is successfully received.
uint64_t g_txBytes
Number of generated bytes.
Time g_firstTx
Time at which first TX packet is generated.
void SocketRxPacket(std::string context, Ptr< const Packet > p, const Address &from)
void SocketTxPacket(std::string context, Ptr< const Packet > p)
Socket sent packet.