9#include "ns3/ap-wifi-mac.h" 
   10#include "ns3/boolean.h" 
   11#include "ns3/constant-position-mobility-model.h" 
   12#include "ns3/he-configuration.h" 
   13#include "ns3/he-phy.h" 
   14#include "ns3/interference-helper.h" 
   16#include "ns3/mobility-helper.h" 
   17#include "ns3/multi-model-spectrum-channel.h" 
   18#include "ns3/nist-error-rate-model.h" 
   20#include "ns3/non-communicating-net-device.h" 
   21#include "ns3/pointer.h" 
   22#include "ns3/rng-seed-manager.h" 
   23#include "ns3/simulator.h" 
   24#include "ns3/spectrum-wifi-helper.h" 
   25#include "ns3/spectrum-wifi-phy.h" 
   26#include "ns3/sta-wifi-mac.h" 
   27#include "ns3/string.h" 
   30#include "ns3/waveform-generator.h" 
   31#include "ns3/wifi-mac-header.h" 
   32#include "ns3/wifi-net-device.h" 
   33#include "ns3/wifi-psdu.h" 
   34#include "ns3/wifi-spectrum-signal-parameters.h" 
   35#include "ns3/wifi-spectrum-value-helper.h" 
   36#include "ns3/wifi-utils.h" 
  201    using StasParams = std::vector<std::tuple<WifiStandard, MHz_u, uint8_t>>;
 
  217                                   std::vector<bool> per20MhzInterference = {});
 
  222    void DoRun() 
override;
 
  236                   const std::vector<bool>& statusPerMpdu);
 
  293    std::vector<Ptr<WaveformGenerator>>
 
 
  302    std::vector<bool> per20MhzInterference)
 
  303    : 
TestCase{
"non-HT duplicate PHY reception test"},
 
  304      m_apStandard{apStandard},
 
  305      m_apFrequency{apFrequency},
 
  306      m_apP20Index{apP20Index},
 
  307      m_stasParams{stasParams},
 
  308      m_per20MhzInterference{per20MhzInterference},
 
  309      m_countRxSuccessStas{},
 
  310      m_countRxFailureStas{},
 
 
  354    interferer->SetTxPowerSpectralDensity(interferencePsd);
 
  355    interferer->SetPeriod(duration);
 
 
  375                                          const std::vector<bool>& )
 
  378    const auto expectedWidth =
 
  379        std::min(
m_phyAp->GetChannelWidth(), 
m_phyStas.at(index)->GetChannelWidth());
 
  382                          "Incorrect channel width in TXVECTOR");
 
 
  398    NS_LOG_FUNCTION(
this << index << expectedRxSuccess << expectedRxFailure);
 
  401                          "The number of successfully received packets by STA " 
  402                              << index << 
" is not correct!");
 
  405                          "The number of unsuccessfully received packets by STA " 
  406                              << index << 
" is not correct!");
 
 
  415    spectrumChannel->AddPropagationLossModel(lossModel);
 
  417    spectrumChannel->SetPropagationDelayModel(delayModel);
 
  423    m_phyAp->SetInterferenceHelper(apInterferenceHelper);
 
  425    m_phyAp->SetErrorRateModel(apErrorModel);
 
  427    m_phyAp->AddChannel(spectrumChannel);
 
  430    m_phyAp->SetMobility(apMobility);
 
  432    apNode->AggregateObject(apMobility);
 
  433    apNode->AddDevice(apDev);
 
  441        staPhy->SetInterferenceHelper(sta1InterferenceHelper);
 
  443        staPhy->SetErrorRateModel(sta1ErrorModel);
 
  444        staPhy->SetDevice(staDev);
 
  445        staPhy->AddChannel(spectrumChannel);
 
  446        staPhy->ConfigureStandard(std::get<0>(staParams));
 
  447        staPhy->SetReceiveOkCallback(
 
  449        staPhy->SetReceiveErrorCallback(
 
  452        staPhy->SetMobility(staMobility);
 
  453        staDev->SetPhy(staPhy);
 
  454        staNode->AggregateObject(staMobility);
 
  455        staNode->AddDevice(staDev);
 
  474            phyInterferer->SetDevice(interfererDev);
 
  475            phyInterferer->SetChannel(spectrumChannel);
 
  476            phyInterferer->SetDutyCycle(1);
 
  477            interfererNode->AddDevice(interfererDev);
 
 
  495        phyInterferer->Dispose();
 
  496        phyInterferer = 
nullptr;
 
 
  505    int64_t streamNumber = 0;
 
  506    m_phyAp->AssignStreams(streamNumber);
 
  509        phySta->AssignStreams(streamNumber);
 
  523    for (
const auto& [staStandard, staFrequency, staP20Index] : 
m_stasParams)
 
  531                                                                         stachannelInfo.width,
 
  537    const auto minApCenterFrequency =
 
  539    for (
MHz_u channelWidth{20}; channelWidth <= apchannelInfo.width; channelWidth *= 2, ++index)
 
  554                bands.push_back(bandInfo);
 
  557                Watt_u interferencePower{0.005}; 
 
  559                *interferencePsd = interferencePower / 10e6;
 
  568        const auto apCenterFreq =
 
  569            m_phyAp->GetOperatingChannel().GetPrimaryChannelCenterFrequency(channelWidth);
 
  570        const auto apMinFreq = apCenterFreq - (channelWidth / 2);
 
  571        const auto apMaxFreq = apCenterFreq + (channelWidth / 2);
 
  578            const MHz_u p20Width{20};
 
  579            const auto staP20Freq =
 
  580                m_phyStas.at(i)->GetOperatingChannel().GetPrimaryChannelCenterFrequency(p20Width);
 
  581            const auto staP20MinFreq = staP20Freq - (p20Width / 2);
 
  582            const auto staP20MaxFreq = staP20Freq + (p20Width / 2);
 
  583            bool expectRx = (staP20MinFreq >= apMinFreq && staP20MaxFreq <= apMaxFreq);
 
  584            bool expectSuccess = 
true;
 
  587                const auto index20MhzSubBand =
 
  595                                expectRx ? expectSuccess : 0,
 
  596                                expectRx ? !expectSuccess : 0);
 
 
  639    void DoRun() 
override;
 
  665                      const std::vector<bool>& statusPerMpdu);
 
 
  697    const std::vector<CtsTxInfos>& ctsTxInfosPerSta)
 
  698    : 
TestCase{
"test PHY reception of multiple CTS frames following a MU-RTS frame"},
 
  699      m_ctsTxInfosPerSta{ctsTxInfosPerSta},
 
  700      m_countApRxCtsSuccess{0},
 
  701      m_countApRxCtsFailure{0},
 
  702      m_countStaRxCtsSuccess{0},
 
  703      m_countStaRxCtsFailure{0},
 
  704      m_stasTxPower(
dBm_u{10})
 
 
  716                         [](
const auto& lhs, 
const auto& rhs) { return lhs.bw < rhs.bw; })
 
  728        phySta->SetPpduUid(0);
 
 
  768    m_phyStas.at(phyIndex)->Send(psdu, txVector);
 
 
  776                                                const std::vector<bool>& )
 
  778    NS_LOG_FUNCTION(
this << phyIndex << *psdu << rxSignalInfo << txVector);
 
  779    std::vector<CtsTxInfos> successfulCtsInfos{};
 
  782                 std::back_inserter(successfulCtsInfos),
 
  783                 [](
const auto& info) { return !info.discard; });
 
  784    const auto isAp = (phyIndex == 0);
 
  790                                  "RX power is not correct!");
 
  793        std::max_element(successfulCtsInfos.cbegin(),
 
  794                         successfulCtsInfos.cend(),
 
  795                         [](
const auto& lhs, 
const auto& rhs) { return lhs.bw < rhs.bw; })
 
  803                          "Incorrect channel width in TXVECTOR");
 
 
  818    const auto isAp = (phyIndex == 0);
 
 
  834                          "The number of successfully received CTS frames by AP is not correct!");
 
  838        "The number of successfully received CTS frames by non-participating STAs is not correct!");
 
  841                          "The number of unsuccessfully received CTS frames by AP is not correct!");
 
  844                          "The number of unsuccessfully received CTS frames by non-participating " 
  845                          "STAs is not correct!");
 
 
  853    int64_t streamNumber = 0;
 
  858    spectrumChannel->AddPropagationLossModel(lossModel);
 
  860    spectrumChannel->SetPropagationDelayModel(delayModel);
 
  867    apMac->SetAttribute(
"BeaconGeneration", 
BooleanValue(
false));
 
  868    apDev->SetMac(apMac);
 
  888                         [](
const auto& lhs, 
const auto& rhs) { return lhs.bw < rhs.bw; })
 
  905    apNode->AggregateObject(apMobility);
 
  906    apNode->AddDevice(apDev);
 
  914        phySta->SetInterferenceHelper(staInterferenceHelper);
 
  916        phySta->SetErrorRateModel(staErrorModel);
 
  917        phySta->SetDevice(staDev);
 
  918        phySta->AddChannel(spectrumChannel);
 
  920        phySta->AssignStreams(streamNumber);
 
  931        phySta->SetOperatingChannel(
 
  935        phySta->SetMobility(staMobility);
 
  936        staDev->SetPhy(phySta);
 
  939        staNode->AggregateObject(staMobility);
 
  940        staNode->AddDevice(staDev);
 
  948        nonParticipatingHePhySta->SetInterferenceHelper(nonParticipatingHeStaInterferenceHelper);
 
  950        nonParticipatingHePhySta->SetErrorRateModel(nonParticipatingHeStaErrorModel);
 
  951        nonParticipatingHePhySta->SetDevice(nonParticipatingHeStaDev);
 
  952        nonParticipatingHePhySta->AddChannel(spectrumChannel);
 
  955        nonParticipatingHePhySta->SetOperatingChannel(
 
  959        nonParticipatingHePhySta->SetMobility(nonParticipatingHeStaMobility);
 
  960        nonParticipatingHeStaDev->SetPhy(nonParticipatingHePhySta);
 
  963        nonParticipatingHePhySta->AssignStreams(streamNumber);
 
  964        nonParticipatingHeStaNode->AggregateObject(nonParticipatingHeStaMobility);
 
  965        nonParticipatingHeStaNode->AddDevice(nonParticipatingHeStaDev);
 
  967        nonParticipatingHePhySta->SetReceiveOkCallback(
 
  969        nonParticipatingHePhySta->SetReceiveErrorCallback(
 
  978    nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper);
 
  980    nonHePhySta->SetErrorRateModel(nonHeStaErrorModel);
 
  981    nonHePhySta->SetDevice(nonHeStaDev);
 
  982    nonHePhySta->AddChannel(spectrumChannel);
 
  984    nonHePhySta->SetOperatingChannel(
 
  987    nonHePhySta->SetMobility(nonHeStaMobility);
 
  988    nonHeStaDev->SetPhy(nonHePhySta);
 
  990    nonHePhySta->AssignStreams(streamNumber);
 
  991    nonHeStaNode->AggregateObject(nonHeStaMobility);
 
  992    nonHeStaNode->AddDevice(nonHeStaDev);
 
 
 1014    for (std::size_t index = 0; index < 
m_phyStas.size(); ++index)
 
 
 1088                TestCase::Duration::QUICK);
 
 1096                                                   {
false, 
true, 
false, 
false}),
 
 1097                TestCase::Duration::QUICK);
 
 1102        TestCase::Duration::QUICK);
 
 1106        TestCase::Duration::QUICK);
 
 1110        TestCase::Duration::QUICK);
 
 1114                TestCase::Duration::QUICK);
 
 1119                TestCase::Duration::QUICK);
 
 1124                TestCase::Duration::QUICK);
 
 1128                TestCase::Duration::QUICK);
 
 1132                TestCase::Duration::QUICK);
 
 1136                TestCase::Duration::QUICK);
 
 1140                TestCase::Duration::QUICK);
 
 
HE PHY used for testing MU-RTS/CTS.
void SetPreviousTxPpduUid(uint64_t uid)
Set the previous TX PPDU UID counter.
void SetMuRtsTxVector(const WifiTxVector &muRtsTxVector)
Set the TXVECTOR of the previously transmitted MU-RTS.
~MuRtsCtsHePhy() override
Spectrum PHY used for testing MU-RTS/CTS.
void DoDispose() override
Destructor implementation.
MuRtsCtsSpectrumWifiPhy()
~MuRtsCtsSpectrumWifiPhy() override
Ptr< MuRtsCtsHePhy > m_muRtsCtsHePhy
Pointer to HE PHY instance used for MU-RTS/CTS PHY test.
void SetPpduUid(uint64_t uid)
Set the global PPDU UID counter.
void SetMuRtsTxVector(const WifiTxVector &muRtsTxVector)
Set the TXVECTOR of the previously transmitted MU-RTS.
void DoInitialize() override
Initialize() implementation.
static TypeId GetTypeId()
Get the type ID.
test PHY reception of multiple CTS frames as a response to a MU-RTS frame.
TestMultipleCtsResponsesFromMuRts(const std::vector< CtsTxInfos > &ctsTxInfosPerSta)
Constructor.
std::size_t m_countApRxCtsFailure
count the number of unsuccessfully received CTS frames by the AP
void RxCtsSuccess(std::size_t phyIndex, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
CTS RX success function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
std::size_t m_countStaRxCtsFailure
count the number of unsuccessfully received CTS frames by the non-participating STA
dBm_u m_stasTxPower
TX power configured for the STAs.
void FakePreviousMuRts()
Function called to fake the transmission of a MU-RTS.
std::vector< CtsTxInfos > m_ctsTxInfosPerSta
information about CTS responses
std::vector< Ptr< MuRtsCtsSpectrumWifiPhy > > m_phyStas
STAs PHYs.
void TxNonHtDuplicateCts(std::size_t phyIndex)
Function called to trigger a CTS frame sent by a STA using non-HT duplicate.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
std::size_t m_countApRxCtsSuccess
count the number of successfully received CTS frames by the AP
Ptr< MuRtsCtsSpectrumWifiPhy > m_phyAp
AP PHY.
void RxCtsFailure(std::size_t phyIndex, Ptr< const WifiPsdu > psdu)
CTS RX failure function.
std::size_t m_countStaRxCtsSuccess
count the number of successfully received CTS frames by the non-participating STA
void CheckResults()
Check the results.
non-HT duplicate PHY reception test The test consists in an AP sending a single non-HT duplicate PPDU...
MHz_u m_apFrequency
the center frequency of the AP
void GenerateInterference(Ptr< WaveformGenerator > interferer, Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
std::vector< bool > m_per20MhzInterference
flags per 20 MHz subchannel whether an interference should be generated on that subchannel
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
TestNonHtDuplicatePhyReception(WifiStandard apStandard, MHz_u apFrequency, uint8_t apP20Index, StasParams stasParams, std::vector< bool > per20MhzInterference={})
Constructor.
void ResetResults()
Reset the results.
std::vector< Ptr< SpectrumWifiPhy > > m_phyStas
PHYs of STAs.
void RxFailure(std::size_t index, Ptr< const WifiPsdu > psdu)
Receive failure function.
std::vector< std::tuple< WifiStandard, MHz_u, uint8_t > > StasParams
A vector containing parameters per STA: the standard, the center frequency and the P20 index.
std::vector< uint32_t > m_countRxFailureStas
count RX failure for STAs
StasParams m_stasParams
the parameters of the STAs
void SendNonHtDuplicatePpdu(MHz_u channelWidth)
Send non-HT duplicate PPDU function.
void CheckResults(std::size_t index, uint32_t expectedRxSuccess, uint32_t expectedRxFailure)
Check the results.
void StopInterference(Ptr< WaveformGenerator > interferer)
Stop interference function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
WifiStandard m_apStandard
the standard to use for the AP
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
uint8_t m_apP20Index
the index of the primary 20 MHz channel of the AP
void DoRun() override
Implementation to actually run this TestCase.
void RxSuccess(std::size_t index, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function.
std::vector< uint32_t > m_countRxSuccessStas
count RX success for STAs
std::vector< Ptr< WaveformGenerator > > m_phyInterferers
PHYs of interferers (1 interferer per 20 MHz subchannel)
wifi non-HT duplicate Test Suite
WifiNonHtDuplicateTestSuite()
AttributeValue implementation for Boolean.
std::optional< WifiTxVector > m_currentTxVector
If the STA is an AP STA, this holds the TXVECTOR of the PPDU that has been sent.
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
void Dispose()
Dispose of this Object.
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54 Mbps.
static WifiMode GetOfdmRate24Mbps()
Return a WifiMode for OFDM at 24 Mbps.
void SetOwner(Ptr< WifiPhy > wifiPhy)
Set the WifiPhy owning this PHY entity.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
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 void Run()
Run the simulation.
void SetDevice(const Ptr< WifiNetDevice > device) override
Sets the device this PHY is associated with.
void DoInitialize() override
Initialize() implementation.
void AddChannel(const Ptr< SpectrumChannel > channel, const FrequencyRange &freqRange=WHOLE_WIFI_SPECTRUM)
Attach a SpectrumChannel to use for a given frequency range.
void DoDispose() override
Destructor implementation.
Hold variables of type string.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Simulation virtual time values and global simulation resolution.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
void SetReceiveErrorCallback(RxErrorCallback callback)
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
void SetOperatingChannel(const WifiPhyOperatingChannel &channel)
If the standard for this object has not been set yet, store the channel settings corresponding to the...
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
void SetReceiveOkCallback(RxOkCallback callback)
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first frequency segment matching the specified parameters.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetTriggerResponding(bool triggerResponding)
Set the Trigger Responding parameter to the given value.
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
MHz_u GetChannelWidth() const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
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.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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...
std::vector< BandInfo > Bands
Container of BandInfo.
dBm_u WToDbm(Watt_u val)
Convert from Watts to dBm.
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Hz_u MHzToHz(MHz_u val)
Convert from MHz to Hz.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Information about CTS responses to expect in the test.
MHz_u bw
the width of the CTS response
bool discard
flag whether the CTS response shall be discarded
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
RxSignalInfo structure containing info on the received signal.
constexpr MHz_u DEFAULT_FREQUENCY
static WifiNonHtDuplicateTestSuite wifiNonHtDuplicateTestSuite
the test suite