18#include "ns3/ampdu-subframe-header.h" 
   19#include "ns3/application-container.h" 
   20#include "ns3/boolean.h" 
   21#include "ns3/command-line.h" 
   22#include "ns3/config.h" 
   23#include "ns3/double.h" 
   24#include "ns3/gnuplot.h" 
   25#include "ns3/integer.h" 
   27#include "ns3/mobility-helper.h" 
   28#include "ns3/node-list.h" 
   29#include "ns3/packet-socket-client.h" 
   30#include "ns3/packet-socket-helper.h" 
   31#include "ns3/packet-socket-server.h" 
   32#include "ns3/propagation-delay-model.h" 
   33#include "ns3/propagation-loss-model.h" 
   34#include "ns3/queue-size.h" 
   35#include "ns3/rng-seed-manager.h" 
   37#include "ns3/string.h" 
   38#include "ns3/uinteger.h" 
   39#include "ns3/wifi-mac-header.h" 
   40#include "ns3/wifi-mac.h" 
   41#include "ns3/wifi-net-device.h" 
   42#include "ns3/wifi-phy-rx-trace-helper.h" 
   43#include "ns3/wifi-tx-stats-helper.h" 
   44#include "ns3/yans-wifi-helper.h" 
   51#define PI 3.1415926535 
   67std::map<Mac48Address, uint64_t>
 
   69std::map<Mac48Address, uint64_t>
 
   71std::map<Mac48Address, uint64_t>
 
   75std::map<Mac48Address, uint64_t>
 
   80std::map<Mac48Address, uint64_t>
 
   83std::map<Mac48Address, uint64_t>
 
   86std::map<Mac48Address, uint64_t>
 
   89std::map<Mac48Address, uint64_t>
 
   93std::map<Mac48Address, Time>
 
   96std::map<Mac48Address, Time>
 
  114std::map<std::string ,
 
  115         std::map<
unsigned int , 
double >>
 
  302        {
"ErpOfdmRate12Mbps",
 
  315        {
"ErpOfdmRate18Mbps",
 
  328        {
"ErpOfdmRate24Mbps",
 
  341        {
"ErpOfdmRate36Mbps",
 
  354        {
"ErpOfdmRate48Mbps",
 
  367        {
"ErpOfdmRate54Mbps",
 
 
 1008std::map<std::string ,
 
 1009         std::map<
unsigned int , 
double >>
 
 1170        {
"ErpOfdmRate6Mbps",
 
 1183        {
"ErpOfdmRate9Mbps",
 
 1196        {
"ErpOfdmRate12Mbps",
 
 1209        {
"ErpOfdmRate18Mbps",
 
 1222        {
"ErpOfdmRate24Mbps",
 
 1235        {
"ErpOfdmRate36Mbps",
 
 1248        {
"ErpOfdmRate48Mbps",
 
 1261        {
"ErpOfdmRate54Mbps",
 
 
 1910    std::string sub = context.substr(10);
 
 1911    uint32_t pos = sub.find(
"/Device");
 
 1912    return std::stoi(sub.substr(0, pos));
 
 
 1924    std::string sub = context.substr(10);
 
 1925    uint32_t pos = sub.find(
"/Device");
 
 1926    uint32_t nodeId = std::stoi(sub.substr(0, pos));
 
 1929    for (
uint32_t i = 0; i < n->GetNDevices(); i++)
 
 
 1952                 uint64_t increment = 1)
 
 1954    auto it = counter.find(addr);
 
 1955    if (it != counter.end())
 
 1957        it->second += increment;
 
 1961        counter.insert(std::make_pair(addr, increment));
 
 
 1979                     uint16_t channelFreqMhz,
 
 1990        packet->RemoveHeader(subHdr);
 
 1992        packet = packet->CreateFragment(0, 
static_cast<uint32_t>(extractedLength));
 
 1995    packet->PeekHeader(hdr);
 
 2002    if (packet->GetSize() >= 
pktSize) 
 
 
 2051                                << 
" val=" << newVal);
 
 2055                         << newVal << std::endl;
 
 
 2070                                     << 
" size=" << p->GetSize());
 
 
 2085                                             << 
" psduDuration=" << psduDuration);
 
 
 2099                                    << 
" size=" << p->GetSize() << 
" reason=" << reason);
 
 2155        NS_FATAL_ERROR(
"All devices should send with same power, so no packet switch during " 
 2156                       "preamble detection should occur!");
 
 
 2183                                   << 
" size=" << p->GetSize());
 
 
 2202    uint8_t nMpdus = (p->GetSize() / 
pktSize);
 
 2205                                  << 
" nMPDUs=" << +nMpdus << 
" snr=" << snr << 
" mode=" << mode
 
 2206                                  << 
" preamble=" << preamble);
 
 2211            NS_FATAL_ERROR(
"A-MPDU settings not properly applied: maximum configured MPDUs is " 
 2212                           << +
maxMpdus << 
" but received an A-MPDU containing " << +nMpdus
 
 2215        NS_LOG_WARN(
"Warning: less MPDUs aggregated in a received A-MPDU (" 
 2216                    << +nMpdus << 
") than configured (" << +
maxMpdus << 
")");
 
 
 2236                                     << 
" size=" << p->GetSize() << 
" snr=" << snr);
 
 
 2255                                     << 
" size=" << p->GetSize() << 
" " << txPowerW);
 
 2259                       << 
" size=" << p->GetSize() << 
" " << txPowerW << std::endl;
 
 
 2278                                   << 
" " << p->GetSize());
 
 
 2293                       << p->GetSize() << std::endl;
 
 
 2309                       << p->GetSize() << std::endl;
 
 
 2326                            << 
" " << p->GetSize() << 
" " << addr << std::endl;
 
 
 2422            uint16_t guardIntervalNs,
 
 2443                uint16_t guardIntervalNs,
 
 2455        wifiNodes.
Create(networkSize + 1);
 
 2459        wifiNodes.
Create(networkSize);
 
 2463    phy.SetErrorRateModel(
"ns3::NistErrorRateModel");
 
 2464    phy.SetChannel(wifiChannel.
Create());
 
 2468    const auto& wifi = helper;
 
 2474        uint64_t beaconInterval = std::min<uint64_t>(
 
 2475            (ceil((duration.
GetSeconds() * 1000000) / 1024) * 1024),
 
 2477        mac.SetType(
"ns3::ApWifiMac",
 
 2484        devices = wifi.Install(phy, mac, wifiNodes.
Get(0));
 
 2486        mac.SetType(
"ns3::StaWifiMac",
 
 2493        for (
uint32_t i = 1; i < nNodes; ++i)
 
 2495            devices.Add(wifi.Install(phy, mac, wifiNodes.
Get(i)));
 
 2500        mac.SetType(
"ns3::AdhocWifiMac");
 
 2503        devices = wifi.Install(phy, mac, wifiNodes);
 
 2509        "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported",
 
 2511    Config::Set(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HeConfiguration/GuardInterval",
 
 2515    for (
uint32_t i = 0; i < nNodes; ++i)
 
 2519        wifi_dev->GetMac()->SetAttribute(
"BE_MaxAmpduSize",
 
 2521        wifi_dev->GetMac()->SetAttribute(
"BK_MaxAmpduSize",
 
 2523        wifi_dev->GetMac()->SetAttribute(
"VO_MaxAmpduSize",
 
 2525        wifi_dev->GetMac()->SetAttribute(
"VI_MaxAmpduSize",
 
 2531    mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
 
 2533    positionAlloc->Add(Vector(1.0, 1.0, 0.0));
 
 2536    const auto angle = (
static_cast<degree_u>(360) / (nNodes - 1));
 
 2537    for (
uint32_t i = 0; i < (nNodes - 1); ++i)
 
 2539        positionAlloc->Add(Vector(1.0 + (distance * cos((i * angle * 
PI) / 180)),
 
 2540                                  1.0 + (distance * sin((i * angle * 
PI) / 180)),
 
 2544    mobility.SetPositionAllocator(positionAlloc);
 
 2545    mobility.Install(wifiNodes);
 
 2548    packetSocket.
Install(wifiNodes);
 
 2552    startTime->SetAttribute(
"Stream", 
IntegerValue(trialNumber));
 
 2556    for (; i < nNodes; ++i)
 
 2558        uint32_t j = infra ? 0 : (i + 1) % nNodes;
 
 2565        client->SetRemote(socketAddr);
 
 2569        client->SetAttribute(
"Interval", 
TimeValue(pktInterval));
 
 2570        double start = startTime->GetValue();
 
 2571        NS_LOG_DEBUG(
"Client " << i << 
" starting at " << start);
 
 2572        client->SetStartTime(
Seconds(start));
 
 2575        server->SetLocal(socketAddr);
 
 2581        "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx",
 
 2587        Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
 
 2589        Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/DeAssoc",
 
 2598    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/" + txop +
 
 2602    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/" + txop +
 
 2606    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxBegin",
 
 2609    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxEnd",
 
 2612    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin",
 
 2616        "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxPayloadBegin",
 
 2619    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxDrop",
 
 2622    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxEnd",
 
 2625    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxError",
 
 2628    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxOk",
 
 2631    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
 
 2634    Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
 
 2637    Config::Connect(
"/NodeList/*/$ns3::Node/ApplicationList/*/$ns3::PacketSocketClient/Tx",
 
 2644        wifiTxStats.
Enable(devices);
 
 2653        rxTraceHelper.
Enable(devices);
 
 2663        phy.EnablePcap(
"wifi_bianchi_pcap", devices);
 
 2674        const auto numFailureDueToFailedEnqueuePerNodeDevice =
 
 2676        const auto numFailureDueToExpiredLifetimePerNodeDevice =
 
 2678        const auto numFailureDueToRetryLimitReachedPerNodeDevice =
 
 2680        const auto numFailureDueToQosOldPacketPerNodeDevice =
 
 2683        std::cout << 
"WifiTxStatsHelper: node to number of MPDUs acked during (10, " 
 2685        if (numSuccessPerNodeDevice.empty())
 
 2687            std::cout << 
"none\n";
 
 2691            std::cout << std::setw(5) << 
"node" << std::setw(10) << 
"nSuccess" << std::endl;
 
 2692            for (
const auto& [nodeDevTuple, nSuccess] : numSuccessPerNodeDevice)
 
 2694                std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10) << nSuccess
 
 2699            << 
"WifiTxStatsHelper: node to number of MPDUs failed (due to any reason) during (10, " 
 2701        if (numFailurePerNodeDevice.empty())
 
 2703            std::cout << 
"none\n";
 
 2707            std::cout << std::setw(5) << 
"node" << std::setw(10) << 
"nFailed" << std::endl;
 
 2708            for (
const auto& [nodeDevTuple, nFailure] : numFailurePerNodeDevice)
 
 2710                std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10) << nFailure
 
 2713            std::cout << 
"WifiTxStatsHelper: node to number of MPDUs failed (due to " 
 2714                         "WIFI_MAC_DROP_FAILED_ENQUEUE) during (10, " 
 2716            if (numFailureDueToFailedEnqueuePerNodeDevice.empty())
 
 2718                std::cout << 
"none\n";
 
 2722                std::cout << std::setw(5) << 
"node" << std::setw(10) << 
"nFailed" << std::endl;
 
 2723                for (
const auto& [nodeDevTuple, nFailure] :
 
 2724                     numFailureDueToFailedEnqueuePerNodeDevice)
 
 2726                    std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10)
 
 2727                              << nFailure << std::endl;
 
 2730            std::cout << 
"WifiTxStatsHelper: node to number of MPDUs failed (due to " 
 2731                         "WIFI_MAC_DROP_EXPIRED_LIFETIME) during (10, " 
 2733            if (numFailureDueToExpiredLifetimePerNodeDevice.empty())
 
 2735                std::cout << 
"none\n";
 
 2739                std::cout << std::setw(5) << 
"node" << std::setw(10) << 
"nFailed" << std::endl;
 
 2740                for (
const auto& [nodeDevTuple, nFailure] :
 
 2741                     numFailureDueToExpiredLifetimePerNodeDevice)
 
 2743                    std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10)
 
 2744                              << nFailure << std::endl;
 
 2747            std::cout << 
"WifiTxStatsHelper: node to number of MPDUs failed (due to " 
 2748                         "WIFI_MAC_DROP_REACHED_RETRY_LIMIT) during (10, " 
 2750            if (numFailureDueToRetryLimitReachedPerNodeDevice.empty())
 
 2752                std::cout << 
"none\n";
 
 2756                std::cout << std::setw(5) << 
"node" << std::setw(10) << 
"nFailed" << std::endl;
 
 2757                for (
const auto& [nodeDevTuple, nFailure] :
 
 2758                     numFailureDueToRetryLimitReachedPerNodeDevice)
 
 2760                    std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10)
 
 2761                              << nFailure << std::endl;
 
 2764            std::cout << 
"WifiTxStatsHelper: node to number of MPDUs failed (due to " 
 2765                         "WIFI_MAC_DROP_QOS_OLD_PACKET) during (10, " 
 2767            if (numFailureDueToQosOldPacketPerNodeDevice.empty())
 
 2769                std::cout << 
"none\n";
 
 2773                std::cout << std::setw(5) << 
"node" << std::setw(10) << 
"nFailed" << std::endl;
 
 2774                for (
const auto& [nodeDevTuple, nFailure] :
 
 2775                     numFailureDueToQosOldPacketPerNodeDevice)
 
 2777                    std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10)
 
 2778                              << nFailure << std::endl;
 
 2782        std::cout << 
"WifiTxStatsHelper: node to number of retransmissions of MPDUs " 
 2783                     "Acked during (10, " 
 2785        if (numRetransPerNodeDevice.empty())
 
 2787            std::cout << 
"none\n";
 
 2791            std::cout << std::setw(5) << 
"node" << std::setw(10) << 
"nRetrans" << std::endl;
 
 2792            for (
const auto& [nodeDevTuple, nRetrans] : numRetransPerNodeDevice)
 
 2794                std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10) << nRetrans
 
 2803        std::cout << 
"\nWifiPhyRxTraceHelper: overall statistics" << std::endl;
 
 2805        for (
uint32_t nodeIndex = 0; nodeIndex < nNodes; ++nodeIndex)
 
 2807            std::cout << 
"\nWifiPhyRxTraceHelper: per-node statistics for node " << nodeIndex
 
 2811        std::cout << std::endl;
 
 
 2838    auto it = counter.find(addr);
 
 2839    if (it != counter.end())
 
 
 2847main(
int argc, 
char* argv[])
 
 2853    double duration = 100; 
 
 2858    std::string workDir = 
"./"; 
 
 2859    std::string phyMode =
 
 2861    std::string standard(
"11a"); 
 
 2862    bool validate = 
false; 
 
 2864    uint16_t plotBianchiModel =
 
 2866    double maxRelativeError =
 
 2869    double frequency = 5;           
 
 2870    uint16_t channelWidth = 20;     
 
 2871    uint16_t guardIntervalNs = 800; 
 
 2873    uint16_t pktInterval =
 
 2877    dBm_u apTxPower{16};      
 
 2878    dBm_u staTxPower{16};     
 
 2889        "ns3::WifiMacQueue::MaxSize",
 
 2894    cmd.AddValue(
"verbose",
 
 2895                 "Logging level (0: no log - 1: simulation script logs - 2: all logs)",
 
 2897    cmd.AddValue(
"tracing", 
"Generate trace files", 
tracing);
 
 2898    cmd.AddValue(
"useTxHelper", 
"Enable WifiTxStatsHelper on all devices", 
useTxHelper);
 
 2899    cmd.AddValue(
"useRxHelper", 
"Enable WifiPhyRxTraceHelper on all devices", 
useRxHelper);
 
 2900    cmd.AddValue(
"pktSize", 
"The packet size in bytes", 
pktSize);
 
 2901    cmd.AddValue(
"trials", 
"The maximal number of runs per network size", trials);
 
 2902    cmd.AddValue(
"duration", 
"Time duration for each trial in seconds", duration);
 
 2903    cmd.AddValue(
"pcap", 
"Enable/disable PCAP tracing", pcap);
 
 2904    cmd.AddValue(
"infra", 
"True to use infrastructure mode, false to use ring adhoc mode", infra);
 
 2905    cmd.AddValue(
"workDir", 
"The working directory used to store generated files", workDir);
 
 2906    cmd.AddValue(
"phyMode", 
"Set the constant PHY mode string used to transmit frames", phyMode);
 
 2907    cmd.AddValue(
"standard", 
"Set the standard (11a, 11b, 11g, 11n, 11ac, 11ax)", standard);
 
 2908    cmd.AddValue(
"nMinStas", 
"Minimum number of stations to start with", nMinStas);
 
 2909    cmd.AddValue(
"nMaxStas", 
"Maximum number of stations to start with", nMaxStas);
 
 2910    cmd.AddValue(
"nStepSize", 
"Number of stations to add at each step", nStepSize);
 
 2911    cmd.AddValue(
"plotBianchiModel",
 
 2912                 "First bit corresponds to the DIFS model, second bit to the EIFS model",
 
 2914    cmd.AddValue(
"validate",
 
 2915                 "Enable/disable validation of the ns-3 simulations against the Bianchi model",
 
 2917    cmd.AddValue(
"maxRelativeError",
 
 2918                 "The maximum relative error tolerated between ns-3 results and the Bianchi model " 
 2919                 "(used for regression, i.e. when the validate flag is set)",
 
 2921    cmd.AddValue(
"frequency", 
"Set the operating frequency band in GHz: 2.4, 5 or 6", frequency);
 
 2922    cmd.AddValue(
"channelWidth",
 
 2923                 "Set the constant channel width in MHz (only for 11n/ac/ax)",
 
 2925    cmd.AddValue(
"guardIntervalNs",
 
 2926                 "Set the the guard interval in nanoseconds (800 or 400 for 11n/ac, 800 or 1600 or " 
 2929    cmd.AddValue(
"maxMpdus",
 
 2930                 "Set the maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation)",
 
 2932    cmd.AddValue(
"distance", 
"Set the distance in meters between the AP and the STAs", distance);
 
 2933    cmd.AddValue(
"apTxPower",
 
 2934                 "Set the transmit power of the AP in dBm (if infrastructure only)",
 
 2936    cmd.AddValue(
"staTxPower",
 
 2937                 "Set the transmit power of each STA in dBm (or all STAs if adhoc)",
 
 2939    cmd.AddValue(
"pktInterval", 
"Set the socket packet interval in microseconds", pktInterval);
 
 2940    cmd.Parse(argc, argv);
 
 2952            NS_FATAL_ERROR(
"Failed to open file wifi-bianchi-backoff-trace.out");
 
 2957            NS_FATAL_ERROR(
"Failed to open file wifi-bianchi-phy-tx-trace.out");
 
 2962            NS_FATAL_ERROR(
"Failed to open file wifi-bianchi-mac-tx-trace.out");
 
 2967            NS_FATAL_ERROR(
"Failed to open file wifi-bianchi-mac-rx-trace.out");
 
 2972            NS_FATAL_ERROR(
"Failed to open file wifi-bianchi-socket-send-trace.out");
 
 2989    std::stringstream phyModeStr;
 
 2990    phyModeStr << phyMode;
 
 2991    if (phyMode.find(
"Mcs") != std::string::npos)
 
 2993        phyModeStr << 
"_" << channelWidth << 
"MHz";
 
 2996    std::stringstream ss;
 
 2997    ss << 
"wifi-" << standard << 
"-p-" << 
pktSize << (infra ? 
"-infrastructure" : 
"-adhoc") << 
"-r-" 
 2998       << phyModeStr.str() << 
"-min-" << nMinStas << 
"-max-" << nMaxStas << 
"-step-" << nStepSize
 
 2999       << 
"-throughput.plt";
 
 3000    std::ofstream throughputPlot(ss.str());
 
 3002    ss << 
"wifi-" << standard << 
"-p-" << 
pktSize << (infra ? 
"-infrastructure" : 
"-adhoc") << 
"-r-" 
 3003       << phyModeStr.str() << 
"-min-" << nMinStas << 
"-max-" << nMaxStas << 
"-step-" << nStepSize
 
 3004       << 
"-throughput.eps";
 
 3008    if (standard == 
"11a")
 
 3014    else if (standard == 
"11b")
 
 3020    else if (standard == 
"11g")
 
 3026    else if (standard == 
"11n")
 
 3028        if (frequency == 2.4 || frequency == 5)
 
 3034            NS_FATAL_ERROR(
"Unsupported frequency band " << frequency << 
" GHz for standard " 
 3038    else if (standard == 
"11ac")
 
 3043    else if (standard == 
"11ax")
 
 3045        if (frequency == 2.4 || frequency == 5 || frequency == 6)
 
 3051            NS_FATAL_ERROR(
"Unsupported frequency band " << frequency << 
" GHz for standard " 
 3060    std::string channelStr = 
"{0, " + std::to_string(channelWidth) + 
", BAND_" +
 
 3061                             (frequency == 2.4 ? 
"2_4" : (frequency == 5 ? 
"5" : 
"6")) + 
"GHZ, 0}";
 
 3075                                       "ReferenceDistance",
 
 3080    else if (frequency == 5)
 
 3086                                       "ReferenceDistance",
 
 3097                                       "ReferenceDistance",
 
 3104    wifi.SetStandard(wifiStandard);
 
 3105    wifi.SetRemoteStationManager(
"ns3::ConstantRateWifiManager",
 
 3121    double averageThroughput;
 
 3122    std::vector<double> throughputArray(trials);
 
 3123    for (
uint32_t n = nMinStas; n <= nMaxStas; n += nStepSize)
 
 3125        averageThroughput = 0;
 
 3127        for (
uint32_t runIndex = 0; runIndex < trials; runIndex++)
 
 3143            std::cout << 
"Trial " << runIndex + 1 << 
" of " << trials << 
"; " << phyModeStr.str()
 
 3144                      << 
" for " << n << 
" nodes " << std::endl;
 
 3147                cwTraceFile << 
"# Trial " << runIndex + 1 << 
" of " << trials << 
"; " 
 3148                            << phyModeStr.str() << 
" for " << n << 
" nodes" << std::endl;
 
 3150                                 << phyModeStr.str() << 
" for " << n << 
" nodes" << std::endl;
 
 3151                phyTxTraceFile << 
"# Trial " << runIndex + 1 << 
" of " << trials << 
"; " 
 3152                               << phyModeStr.str() << 
" for " << n << 
" nodes" << std::endl;
 
 3153                macTxTraceFile << 
"# Trial " << runIndex + 1 << 
" of " << trials << 
"; " 
 3154                               << phyModeStr.str() << 
" for " << n << 
" nodes" << std::endl;
 
 3155                macRxTraceFile << 
"# Trial " << runIndex + 1 << 
" of " << trials << 
"; " 
 3156                               << phyModeStr.str() << 
" for " << n << 
" nodes" << std::endl;
 
 3158                                    << phyModeStr.str() << 
" for " << n << 
" nodes" << std::endl;
 
 3183                Time dataTransferDuration = last - 
first;
 
 3184                double nodeThroughput =
 
 3185                    (it->second * 8 / 
static_cast<double>(dataTransferDuration.
GetMicroSeconds()));
 
 3192                uint64_t nodeRxEventWhileDecodingPreamble =
 
 3197                uint64_t nodeRxEvents = nodePhyHeaderFailures + nodePsduFailures + nodePsduSuccess +
 
 3198                                        nodeRxEventWhileDecodingPreamble + nodeRxEventWhileRxing +
 
 3199                                        nodeRxEventWhileTxing + nodeRxEventAbortedByTx;
 
 3200                std::cout << 
"Node " << it->first << 
": TX packets " << nodeTxPackets
 
 3201                          << 
"; RX packets " << nodeRxPackets << 
"; PHY header failures " 
 3202                          << nodePhyHeaderFailures << 
"; PSDU failures " << nodePsduFailures
 
 3203                          << 
"; PSDU success " << nodePsduSuccess
 
 3204                          << 
"; RX events while decoding preamble " 
 3205                          << nodeRxEventWhileDecodingPreamble << 
"; RX events while RXing " 
 3206                          << nodeRxEventWhileRxing << 
"; RX events while TXing " 
 3207                          << nodeRxEventWhileTxing << 
"; RX events aborted by TX " 
 3208                          << nodeRxEventAbortedByTx << 
"; total RX events " << nodeRxEvents
 
 3209                          << 
"; total events " << nodeTxPackets + nodeRxEvents << 
"; time first RX " 
 3210                          << 
first << 
"; time last RX " << last << 
"; dataTransferDuration " 
 3211                          << dataTransferDuration << 
"; throughput " << nodeThroughput << 
" Mbps" 
 3214            std::cout << 
"Total throughput: " << 
throughput << 
" Mbps" << std::endl;
 
 3218        averageThroughput = averageThroughput / trials;
 
 3220        bool rateFound = 
false;
 
 3221        double relativeErrorDifs = 0;
 
 3222        double relativeErrorEifs = 0;
 
 3227            auto it = itDifs->second.find(n);
 
 3228            if (it != itDifs->second.end())
 
 3230                relativeErrorDifs = (std::abs(averageThroughput - it->second) / it->second);
 
 3231                std::cout << 
"Relative error (DIFS): " << 100 * relativeErrorDifs << 
"%" 
 3236                NS_FATAL_ERROR(
"No Bianchi results (DIFS) calculated for that number of stations!");
 
 3243            auto it = itEifs->second.find(n);
 
 3244            if (it != itEifs->second.end())
 
 3246                relativeErrorEifs = (std::abs(averageThroughput - it->second) / it->second);
 
 3247                std::cout << 
"Relative error (EIFS): " << 100 * relativeErrorEifs << 
"%" 
 3252                NS_FATAL_ERROR(
"No Bianchi results (EIFS) calculated for that number of stations!");
 
 3255        if (!rateFound && validate)
 
 3259        double relativeError = std::min(relativeErrorDifs, relativeErrorEifs);
 
 3260        if (validate && (relativeError > maxRelativeError))
 
 3266        for (
uint32_t i = 0; i < trials; ++i)
 
 3268            stDev += pow(throughputArray[i] - averageThroughput, 2);
 
 3270        stDev = sqrt(stDev / (trials - 1));
 
 3271        dataset.
Add(n, averageThroughput, stDev);
 
 3278        for (
uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
 
 3281            auto it = itDifs->second.find(i);
 
 3282            if (it != itDifs->second.end())
 
 3286            datasetBianchiDifs.
Add(i, value);
 
 3291        for (
uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
 
 3293            datasetBianchiDifs.
Add(i, 0.0);
 
 3300        for (
uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
 
 3303            auto it = itEifs->second.find(i);
 
 3304            if (it != itEifs->second.end())
 
 3308            datasetBianchiEifs.
Add(i, value);
 
 3313        for (
uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
 
 3315            datasetBianchiEifs.
Add(i, 0.0);
 
 3319    datasetBianchiEifs.
SetTitle(
"Bianchi (EIFS - lower bound)");
 
 3320    datasetBianchiDifs.
SetTitle(
"Bianchi (DIFS - upper bound)");
 
 3322    gnuplot.
SetTerminal(
"postscript eps color enh \"Times-BoldItalic\"");
 
 3323    gnuplot.
SetLegend(
"Number of competing stations", 
"Throughput (Mbps)");
 
 3325    ss << 
"Frame size " << 
pktSize << 
" bytes";
 
 3328    ss << 
"set xrange [" << nMinStas << 
":" << nMaxStas << 
"]\n" 
 3329       << 
"set xtics " << nStepSize << 
"\n" 
 3330       << 
"set grid xtics ytics\n" 
 3332       << 
"set style line 1 linewidth 5\n" 
 3333       << 
"set style line 2 linewidth 5\n" 
 3334       << 
"set style line 3 linewidth 5\n" 
 3335       << 
"set style line 4 linewidth 5\n" 
 3336       << 
"set style line 5 linewidth 5\n" 
 3337       << 
"set style line 6 linewidth 5\n" 
 3338       << 
"set style line 7 linewidth 5\n" 
 3339       << 
"set style line 8 linewidth 5\n" 
 3340       << 
"set style increment user";
 
 3342    if (plotBianchiModel & 0x0001)
 
 3344        datasetBianchiDifs.
SetTitle(
"Bianchi");
 
 3347    if (plotBianchiModel & 0x0002)
 
 3349        datasetBianchiEifs.
SetTitle(
"Bianchi");
 
 3352    if (plotBianchiModel == 0x0003)
 
 3354        datasetBianchiEifs.
SetTitle(
"Bianchi (EIFS - lower bound)");
 
 3355        datasetBianchiDifs.
SetTitle(
"Bianchi (DIFS - upper bound)");
 
 3358    throughputPlot.close();
 
WiFi adhoc experiment class.
Gnuplot2dDataset Run(const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel)
Run an experiment.
a polymophic address class
holds a vector of ns3::Application pointers.
AttributeValue implementation for Boolean.
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 SetErrorBars(ErrorBars errorBars)
void SetStyle(Style style)
void Add(double x, double y)
void SetTitle(const std::string &title)
Change line title.
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 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)
Hold a signed integer type.
static Mac48Address ConvertFrom(const Address &address)
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
static Ptr< Node > GetNode(uint32_t n)
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.
Smart pointer class similar to boost::intrusive_ptr.
Class for representing queue sizes.
AttributeValue implementation for QueueSize.
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.
AttributeValue implementation for Ssid.
Hold variables of type string.
Simulation virtual time values and global simulation resolution.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
int64_t ToInteger(Unit unit) const
Get the Time value expressed in a particular unit.
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
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.
static 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 ...
create MAC layers for a ns3::WifiNetDevice.
represent a single transmission mode
Hold together all Wifi-related objects.
void DisablePreambleDetectionModel()
Disable the preamble detection model on all links.
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
Assists in tracing and analyzing Wi-Fi Physical Layer (PHY) receptions.
void PrintStatistics() const
Print statistics for all nodes, devices, and links during the collection period.
void Stop(Time stopTime)
Stops the collection of statistics at a specified time.
void Enable(NodeContainer nodes)
Enables trace collection for all nodes and WifiNetDevices in the specified NodeContainer.
void Start(Time startTime)
Starts the collection of statistics from a specified start time.
Statistics helper for tracking outcomes of data MPDU transmissions.
void Stop(Time stopTime)
Set the stop time for statistics collection.
CountPerNodeDevice_t GetFailuresByNodeDevice() const
Return the counts of failed MPDU transmissions in a hash map.
CountPerNodeDevice_t GetSuccessesByNodeDevice() const
Return the counts of successful MPDU transmissions in a hash map.
void Enable(const NodeContainer &nodes)
Enables trace collection for all nodes and WifiNetDevices in the specified NodeContainer.
CountPerNodeDevice_t GetRetransmissionsByNodeDevice() const
Return the counts of MPDU retransmissions in a hash map.
void Start(Time startTime)
Set the start time for statistics collection.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
bool IsAggregation() const
Checks whether the PSDU contains A-MPDU.
manage and create wifi channel objects for the YANS model.
void SetPropagationDelay(std::string name, Ts &&... args)
void AddPropagationLoss(std::string name, Ts &&... args)
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
void experiment(std::string queue_disc_type)
void SetDefault(std::string name, const AttributeValue &value)
void Connect(std::string path, const CallbackBase &cb)
void Set(std::string path, const AttributeValue &value)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#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_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#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 MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
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.
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
@ PREAMBLE_DETECT_FAILURE
@ FRAME_CAPTURE_PACKET_SWITCH
@ SIGNAL_DETECTION_ABORTED_BY_TX
@ RECEPTION_ABORTED_BY_TX
@ PREAMBLE_DETECTION_PACKET_SWITCH
@ WIFI_MAC_DROP_QOS_OLD_PACKET
@ WIFI_MAC_DROP_FAILED_ENQUEUE
@ WIFI_MAC_DROP_EXPIRED_LIFETIME
@ WIFI_MAC_DROP_REACHED_RETRY_LIMIT
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.
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
@ LOG_LEVEL_ALL
Print everything.
@ LOG_LEVEL_WARN
LOG_WARN and above.
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
SignalNoiseDbm structure.
std::map< Mac48Address, uint64_t > rxEventAbortedByTx
Map that stores the number of reception events aborted per STA because the PHY has started to transmi...
void BackoffTrace(std::string context, uint32_t newVal, uint8_t)
Backoff trace.
std::map< Mac48Address, uint64_t > rxEventWhileTxing
Map that stores the number of reception events per STA that occurred while PHY was already transmitti...
void PhyRxErrorTrace(std::string context, Ptr< const Packet > p, double snr)
PHY RX error trace.
std::map< Mac48Address, uint64_t > packetsReceived
Map that stores the total packets received per STA (and addressed to that STA)
std::ofstream backoffTraceFile
File that traces backoff over time.
void RestartCalc()
Reset the stats.
std::map< Mac48Address, uint64_t > bytesReceived
Map that stores the total bytes received per STA (and addressed to that STA)
std::map< Mac48Address, uint64_t > rxEventWhileDecodingPreamble
Map that stores the number of reception events per STA that occurred while PHY was already decoding a...
void AssociationLog(std::string context, Mac48Address address)
Association log trace.
void SocketSendTrace(std::string context, Ptr< const Packet > p, const Address &addr)
Socket send trace.
bool tracing
Flag to enable/disable generation of tracing files.
void CwTrace(std::string context, uint32_t cw, uint8_t)
Contention window trace.
uint32_t ContextToNodeId(std::string context)
Parse context strings of the form "/NodeList/x/DeviceList/x/..." to extract the NodeId integer.
std::map< Mac48Address, uint64_t > rxEventWhileRxing
Map that stores the number of reception events per STA that occurred while PHY was already receiving ...
void TracePacketReception(std::string context, Ptr< const Packet > p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
Trace a packet reception.
void PhyRxDropTrace(std::string context, Ptr< const Packet > p, WifiPhyRxfailureReason reason)
PHY Drop trace.
void PhyTxTrace(std::string context, Ptr< const Packet > p, double txPowerW)
PHY TX trace.
std::map< Mac48Address, uint64_t > psduFailed
Map that stores the total number of unsuccessfuly received PSDUS (for which the PHY header was succes...
#define PI
Avoid std::numbers::pi because it's C++20.
std::map< Mac48Address, uint64_t > packetsTransmitted
Map that stores the total packets transmitted per STA.
std::map< std::string, std::map< unsigned int, double > > bianchiResultsDifs
Table of the expected values for DIFS.
bool useRxHelper
Flag to get PPDU statistics with WifiPhyRxTraceHelper.
std::map< Mac48Address, Time > timeLastReceived
Map that stores the time at which the last packet was received per STA (and the packet is addressed t...
std::map< Mac48Address, Time > timeFirstTransmitted
Map that stores the time at which the first packet was transmitted per STA.
uint8_t maxMpdus
The maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation)
void PhyRxDoneTrace(std::string context, Ptr< const Packet > p)
PHY RX end trace.
std::set< uint32_t > associated
Contains the IDs of the STAs that successfully associated to the access point (in infrastructure mode...
std::map< Mac48Address, uint64_t > phyHeaderFailed
Map that stores the total number of unsuccessfuly received PHY headers per STA.
void MacTxTrace(std::string context, Ptr< const Packet > p)
MAC TX trace.
std::ofstream socketSendTraceFile
File that traces packets transmitted by the application over time.
uint64_t GetCount(const std::map< Mac48Address, uint64_t > &counter, Mac48Address addr)
Get the Counter associated with a MAC address.
std::ofstream macTxTraceFile
File that traces MAC transmissions over time.
void PhyRxTrace(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand power)
PHY Rx trace.
std::ofstream phyTxTraceFile
File that traces PHY transmissions over time.
void IncrementCounter(std::map< Mac48Address, uint64_t > &counter, Mac48Address addr, uint64_t increment=1)
Increment the counter for a given address.
std::map< Mac48Address, Time > timeFirstReceived
Map that stores the time at which the first packet was received per STA (and the packet is addressed ...
uint32_t pktSize
packet size used for the simulation (in bytes)
std::map< Mac48Address, uint64_t > psduSucceeded
Map that stores the total number of successfully received PSDUs per STA (including PSDUs not addresse...
std::map< Mac48Address, Time > timeLastTransmitted
Map that stores the time at which the last packet was transmitted per STA.
std::map< std::string, std::map< unsigned int, double > > bianchiResultsEifs
Table of the expected values for EIFS.
void MacRxTrace(std::string context, Ptr< const Packet > p)
MAC RX trace.
void PhyTxDoneTrace(std::string context, Ptr< const Packet > p)
PHY TX end trace.
void PhyRxPayloadTrace(std::string context, WifiTxVector txVector, Time psduDuration)
PHY Rx trace.
Mac48Address ContextToMac(std::string context)
Parse context strings of the form "/NodeList/x/DeviceList/x/..." and fetch the Mac address.
void PhyRxOkTrace(std::string context, Ptr< const Packet > p, double snr, WifiMode mode, WifiPreamble preamble)
PHY successful RX trace.
bool useTxHelper
Flag to get MPDU statistics with WifiTxStatsHelper.
void DisassociationLog(std::string context, Mac48Address address)
Deassociation log trace.
std::ofstream cwTraceFile
File that traces CW over time.
std::ofstream macRxTraceFile
File that traces MAC receptions over time.