From 921a5eb6c72416c2b8db46fbd6dcdf4ef61733ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Thu, 9 May 2024 08:44:28 +0200 Subject: [PATCH] examples: Add parameter to select 80+80MHz or 160MHz in wifi network examples --- examples/wireless/wifi-eht-network.cc | 24 ++++--- examples/wireless/wifi-he-network.cc | 42 ++++++------ examples/wireless/wifi-vht-network.cc | 97 +++++++++++++++++++++------ 3 files changed, 113 insertions(+), 50 deletions(-) diff --git a/examples/wireless/wifi-eht-network.cc b/examples/wireless/wifi-eht-network.cc index 28307fd3a..2ee3f5c4e 100644 --- a/examples/wireless/wifi-eht-network.cc +++ b/examples/wireless/wifi-eht-network.cc @@ -145,6 +145,7 @@ main(int argc, char* argv[]) bool udp{true}; bool downlink{true}; bool useRts{false}; + bool use80Plus80{false}; uint16_t mpduBufferSize{512}; std::string emlsrLinks; uint16_t paddingDelayUsec{32}; @@ -218,6 +219,7 @@ main(int argc, char* argv[]) "Generate downlink flows if set to 1, uplink flows otherwise", downlink); cmd.AddValue("useRts", "Enable/disable RTS/CTS", useRts); + cmd.AddValue("use80Plus80", "Enable/disable use of 80+80 MHz", use80Plus80); cmd.AddValue("mpduBufferSize", "Size (in number of MPDUs) of the BlockAck buffer", mpduBufferSize); @@ -298,6 +300,9 @@ main(int argc, char* argv[]) int minGi = enableUlOfdma ? 1600 : 800; for (int channelWidth = 20; channelWidth <= maxChannelWidth;) // MHz { + const auto is80Plus80 = (use80Plus80 && (channelWidth == 160)); + const std::string widthStr = is80Plus80 ? "80+80" : std::to_string(channelWidth); + const auto segmentWidthStr = is80Plus80 ? "80" : widthStr; for (int gi = 3200; gi >= minGi;) // Nanoseconds { if (!udp) @@ -335,7 +340,7 @@ main(int argc, char* argv[]) { break; } - channelStr[nLinks] = "{0, " + std::to_string(channelWidth) + ", "; + channelStr[nLinks] = "{0, " + segmentWidthStr + ", "; if (freq == 6) { channelStr[nLinks] += "BAND_6GHZ, 0}"; @@ -379,6 +384,12 @@ main(int argc, char* argv[]) { NS_FATAL_ERROR("Wrong frequency value!"); } + + if (is80Plus80) + { + channelStr[nLinks] += std::string(";") + channelStr[nLinks]; + } + nLinks++; } @@ -389,12 +400,6 @@ main(int argc, char* argv[]) Ssid ssid = Ssid("ns3-80211be"); - /* - * SingleModelSpectrumChannel cannot be used with 802.11be because two - * spectrum models are required: one with 78.125 kHz bands for HE PPDUs - * and one with 312.5 kHz bands for, e.g., non-HT PPDUs (for more details, - * see issue #408 (CLOSED)) - */ SpectrumWifiPhyHelper phy(nLinks); phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO); phy.Set("ChannelSwitchDelay", TimeValue(MicroSeconds(channelSwitchDelayUsec))); @@ -580,8 +585,9 @@ main(int argc, char* argv[]) Simulator::Destroy(); - std::cout << mcs << "\t\t\t" << channelWidth << " MHz\t\t\t" << gi << " ns\t\t\t" - << throughput << " Mbit/s" << std::endl; + std::cout << +mcs << "\t\t\t" << widthStr << " MHz\t\t" + << (widthStr.size() > 3 ? "" : "\t") << gi << " ns\t\t\t" << throughput + << " Mbit/s" << std::endl; // test first element if (mcs == minMcs && channelWidth == 20 && gi == 3200) diff --git a/examples/wireless/wifi-he-network.cc b/examples/wireless/wifi-he-network.cc index bfe1ab673..af4cda941 100644 --- a/examples/wireless/wifi-he-network.cc +++ b/examples/wireless/wifi-he-network.cc @@ -72,6 +72,7 @@ main(int argc, char* argv[]) bool udp{true}; bool downlink{true}; bool useRts{false}; + bool use80Plus80{false}; bool useExtendedBlockAck{false}; Time simulationTime{"10s"}; double distance{1.0}; // meters @@ -101,6 +102,7 @@ main(int argc, char* argv[]) "Generate downlink flows if set to 1, uplink flows otherwise", downlink); cmd.AddValue("useRts", "Enable/disable RTS/CTS", useRts); + cmd.AddValue("use80Plus80", "Enable/disable use of 80+80 MHz", use80Plus80); cmd.AddValue("useExtendedBlockAck", "Enable/disable use of extended BACK", useExtendedBlockAck); cmd.AddValue("nStations", "Number of non-AP HE stations", nStations); cmd.AddValue("dlAckType", @@ -119,7 +121,8 @@ main(int argc, char* argv[]) cmd.AddValue("mcs", "if set, limit testing to a specific MCS (0-11)", mcs); cmd.AddValue("payloadSize", "The application payload size in bytes", payloadSize); cmd.AddValue("phyModel", - "PHY model to use when OFDMA is disabled (Yans or Spectrum). If OFDMA is enabled " + "PHY model to use when OFDMA is disabled (Yans or Spectrum). If 80+80 MHz or " + "OFDMA is enabled " "then Spectrum is automatically selected", phyModel); cmd.AddValue("minExpectedThroughput", @@ -161,9 +164,9 @@ main(int argc, char* argv[]) { NS_ABORT_MSG("Invalid PHY model (must be Yans or Spectrum)"); } - if (dlAckSeqType != "NO-OFDMA") + if (use80Plus80 || (dlAckSeqType != "NO-OFDMA")) { - // SpectrumWifiPhy is required for OFDMA + // SpectrumWifiPhy is required for 80+80 MHz and OFDMA phyModel = "Spectrum"; } @@ -191,6 +194,9 @@ main(int argc, char* argv[]) int minGi = enableUlOfdma ? 1600 : 800; for (int channelWidth = 20; channelWidth <= maxChannelWidth;) // MHz { + const auto is80Plus80 = (use80Plus80 && (channelWidth == 160)); + const std::string widthStr = is80Plus80 ? "80+80" : std::to_string(channelWidth); + const auto segmentWidthStr = is80Plus80 ? "80" : widthStr; for (int gi = 3200; gi >= minGi;) // Nanoseconds { if (!udp) @@ -207,7 +213,7 @@ main(int argc, char* argv[]) NetDeviceContainer staDevices; WifiMacHelper mac; WifiHelper wifi; - std::string channelStr("{0, " + std::to_string(channelWidth) + ", "); + std::string channelStr("{0, " + segmentWidthStr + ", "); StringValue ctrlRate; auto nonHtRefRateMbps = HePhy::GetNonHtReferenceRate(mcs) / 1e6; @@ -216,7 +222,6 @@ main(int argc, char* argv[]) if (frequency == 6) { - wifi.SetStandard(WIFI_STANDARD_80211ax); ctrlRate = StringValue(ossDataMode.str()); channelStr += "BAND_6GHZ, 0}"; Config::SetDefault("ns3::LogDistancePropagationLossModel::ReferenceLoss", @@ -224,7 +229,6 @@ main(int argc, char* argv[]) } else if (frequency == 5) { - wifi.SetStandard(WIFI_STANDARD_80211ax); std::ostringstream ossControlMode; ossControlMode << "OfdmRate" << nonHtRefRateMbps << "Mbps"; ctrlRate = StringValue(ossControlMode.str()); @@ -232,7 +236,6 @@ main(int argc, char* argv[]) } else if (frequency == 2.4) { - wifi.SetStandard(WIFI_STANDARD_80211ax); std::ostringstream ossControlMode; ossControlMode << "ErpOfdmRate" << nonHtRefRateMbps << "Mbps"; ctrlRate = StringValue(ossControlMode.str()); @@ -245,6 +248,12 @@ main(int argc, char* argv[]) NS_FATAL_ERROR("Wrong frequency value!"); } + if (is80Plus80) + { + channelStr += std::string(";") + channelStr; + } + + wifi.SetStandard(WIFI_STANDARD_80211ax); wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue(ossDataMode.str()), @@ -257,17 +266,9 @@ main(int argc, char* argv[]) if (phyModel == "Spectrum") { - /* - * SingleModelSpectrumChannel cannot be used with 802.11ax because two - * spectrum models are required: one with 78.125 kHz bands for HE PPDUs - * and one with 312.5 kHz bands for, e.g., non-HT PPDUs (for more details, - * see issue #408 (CLOSED)) - */ - Ptr spectrumChannel = - CreateObject(); + auto spectrumChannel = CreateObject(); - Ptr lossModel = - CreateObject(); + auto lossModel = CreateObject(); spectrumChannel->AddPropagationLossModel(lossModel); SpectrumWifiPhyHelper phy; @@ -301,7 +302,7 @@ main(int argc, char* argv[]) } else { - YansWifiChannelHelper channel = YansWifiChannelHelper::Default(); + auto channel = YansWifiChannelHelper::Default(); YansWifiPhyHelper phy; phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO); phy.SetChannel(channel.Create()); @@ -454,8 +455,9 @@ main(int argc, char* argv[]) Simulator::Destroy(); - std::cout << mcs << "\t\t\t" << channelWidth << " MHz\t\t\t" << gi << " ns\t\t\t" - << throughput << " Mbit/s" << std::endl; + std::cout << +mcs << "\t\t\t" << widthStr << " MHz\t\t" + << (widthStr.size() > 3 ? "" : "\t") << gi << " ns\t\t\t" << throughput + << " Mbit/s" << std::endl; // test first element if (mcs == minMcs && channelWidth == 20 && gi == 3200) diff --git a/examples/wireless/wifi-vht-network.cc b/examples/wireless/wifi-vht-network.cc index 2c6a642d0..e82c74d2b 100644 --- a/examples/wireless/wifi-vht-network.cc +++ b/examples/wireless/wifi-vht-network.cc @@ -26,9 +26,11 @@ #include "ns3/ipv4-global-routing-helper.h" #include "ns3/log.h" #include "ns3/mobility-helper.h" +#include "ns3/multi-model-spectrum-channel.h" #include "ns3/on-off-helper.h" #include "ns3/packet-sink-helper.h" #include "ns3/packet-sink.h" +#include "ns3/spectrum-wifi-helper.h" #include "ns3/ssid.h" #include "ns3/string.h" #include "ns3/udp-client-server-helper.h" @@ -64,9 +66,11 @@ main(int argc, char* argv[]) { bool udp{true}; bool useRts{false}; + bool use80Plus80{false}; Time simulationTime{"10s"}; double distance{1.0}; // meters int mcs{-1}; // -1 indicates an unset value + std::string phyModel{"Yans"}; double minExpectedThroughput{0.0}; double maxExpectedThroughput{0.0}; @@ -77,7 +81,12 @@ main(int argc, char* argv[]) cmd.AddValue("simulationTime", "Simulation time", simulationTime); cmd.AddValue("udp", "UDP if set to 1, TCP otherwise", udp); cmd.AddValue("useRts", "Enable/disable RTS/CTS", useRts); + cmd.AddValue("use80Plus80", "Enable/disable use of 80+80 MHz", use80Plus80); cmd.AddValue("mcs", "if set, limit testing to a specific MCS (0-9)", mcs); + cmd.AddValue("phyModel", + "PHY model to use (Yans or Spectrum). If 80+80 MHz is enabled, then Spectrum is " + "automatically selected", + phyModel); cmd.AddValue("minExpectedThroughput", "if set, simulation fails if the lowest throughput is below this value", minExpectedThroughput); @@ -86,6 +95,16 @@ main(int argc, char* argv[]) maxExpectedThroughput); cmd.Parse(argc, argv); + if (phyModel != "Yans" && phyModel != "Spectrum") + { + NS_ABORT_MSG("Invalid PHY model (must be Yans or Spectrum)"); + } + if (use80Plus80) + { + // SpectrumWifiPhy is required for 80+80 MHz + phyModel = "Spectrum"; + } + if (useRts) { Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0")); @@ -118,6 +137,9 @@ main(int argc, char* argv[]) channelWidth *= 2; continue; } + const auto is80Plus80 = (use80Plus80 && (channelWidth == 160)); + const std::string widthStr = is80Plus80 ? "80+80" : std::to_string(channelWidth); + const auto segmentWidthStr = is80Plus80 ? "80" : widthStr; for (auto sgi : {false, true}) { uint32_t payloadSize; // 1500 byte IP packet @@ -136,16 +158,11 @@ main(int argc, char* argv[]) NodeContainer wifiApNode; wifiApNode.Create(1); - YansWifiChannelHelper channel = YansWifiChannelHelper::Default(); - YansWifiPhyHelper phy; - phy.SetChannel(channel.Create()); - - phy.Set("ChannelSettings", - StringValue("{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}")); - - WifiHelper wifi; - wifi.SetStandard(WIFI_STANDARD_80211ac); + NetDeviceContainer apDevice; + NetDeviceContainer staDevice; WifiMacHelper mac; + WifiHelper wifi; + std::string channelStr{"{0, " + segmentWidthStr + ", BAND_5GHZ, 0}"}; std::ostringstream ossControlMode; auto nonHtRefRateMbps = VhtPhy::GetNonHtReferenceRate(mcs) / 1e6; @@ -153,6 +170,13 @@ main(int argc, char* argv[]) std::ostringstream ossDataMode; ossDataMode << "VhtMcs" << mcs; + + if (is80Plus80) + { + channelStr += std::string(";") + channelStr; + } + + wifi.SetStandard(WIFI_STANDARD_80211ac); wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue(ossDataMode.str()), @@ -164,19 +188,49 @@ main(int argc, char* argv[]) Ssid ssid = Ssid("ns3-80211ac"); - mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid)); + if (phyModel == "Spectrum") + { + auto spectrumChannel = CreateObject(); + auto lossModel = CreateObject(); + spectrumChannel->AddPropagationLossModel(lossModel); - NetDeviceContainer staDevice; - staDevice = wifi.Install(phy, mac, wifiStaNode); + SpectrumWifiPhyHelper phy; + phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO); + phy.SetChannel(spectrumChannel); - mac.SetType("ns3::ApWifiMac", - "EnableBeaconJitter", - BooleanValue(false), - "Ssid", - SsidValue(ssid)); + phy.Set("ChannelSettings", + StringValue("{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}")); - NetDeviceContainer apDevice; - apDevice = wifi.Install(phy, mac, wifiApNode); + mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid)); + staDevice = wifi.Install(phy, mac, wifiStaNode); + + mac.SetType("ns3::ApWifiMac", + "EnableBeaconJitter", + BooleanValue(false), + "Ssid", + SsidValue(ssid)); + apDevice = wifi.Install(phy, mac, wifiApNode); + } + else + { + auto channel = YansWifiChannelHelper::Default(); + YansWifiPhyHelper phy; + phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO); + phy.SetChannel(channel.Create()); + + phy.Set("ChannelSettings", + StringValue("{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}")); + + mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid)); + staDevice = wifi.Install(phy, mac, wifiStaNode); + + mac.SetType("ns3::ApWifiMac", + "EnableBeaconJitter", + BooleanValue(false), + "Ssid", + SsidValue(ssid)); + apDevice = wifi.Install(phy, mac, wifiApNode); + } int64_t streamNumber = 150; streamNumber += WifiHelper::AssignStreams(apDevice, streamNumber); @@ -283,8 +337,9 @@ main(int argc, char* argv[]) Simulator::Destroy(); - std::cout << mcs << "\t\t\t" << channelWidth << " MHz\t\t\t" << std::boolalpha - << sgi << "\t\t\t" << throughput << " Mbit/s" << std::endl; + std::cout << +mcs << "\t\t\t" << widthStr << " MHz\t\t" + << (widthStr.size() > 3 ? "" : "\t") << (sgi ? "400 ns" : "800 ns") + << "\t\t\t" << throughput << " Mbit/s" << std::endl; // test first element if (mcs == minMcs && channelWidth == 20 && !sgi)