9#include "ns3/ap-wifi-mac.h" 
   10#include "ns3/boolean.h" 
   11#include "ns3/constant-position-mobility-model.h" 
   12#include "ns3/ctrl-headers.h" 
   13#include "ns3/demangle.h" 
   14#include "ns3/double.h" 
   15#include "ns3/eht-configuration.h" 
   16#include "ns3/eht-phy.h" 
   17#include "ns3/he-configuration.h" 
   18#include "ns3/he-ppdu.h" 
   19#include "ns3/interference-helper.h" 
   21#include "ns3/mobility-helper.h" 
   22#include "ns3/multi-model-spectrum-channel.h" 
   23#include "ns3/nist-error-rate-model.h" 
   25#include "ns3/non-communicating-net-device.h" 
   26#include "ns3/pointer.h" 
   27#include "ns3/rng-seed-manager.h" 
   28#include "ns3/simulator.h" 
   29#include "ns3/spectrum-wifi-helper.h" 
   30#include "ns3/spectrum-wifi-phy.h" 
   31#include "ns3/sta-wifi-mac.h" 
   32#include "ns3/string.h" 
   34#include "ns3/threshold-preamble-detection-model.h" 
   36#include "ns3/waveform-generator.h" 
   37#include "ns3/wifi-mac-header.h" 
   38#include "ns3/wifi-net-device.h" 
   39#include "ns3/wifi-phy-listener.h" 
   40#include "ns3/wifi-psdu.h" 
   41#include "ns3/wifi-spectrum-phy-interface.h" 
   42#include "ns3/wifi-spectrum-signal-parameters.h" 
   43#include "ns3/wifi-spectrum-value-helper.h" 
   44#include "ns3/wifi-utils.h" 
   65template <
typename PhyEntityType>
 
  108template <
typename PhyEntityType>
 
  115template <
typename PhyEntityType>
 
  124    return PhyEntityType::GetStaId(ppdu);
 
 
  127template <
typename PhyEntityType>
 
  131    PhyEntityType::m_globalPpduUid = uid;
 
 
  134template <
typename PhyEntityType>
 
  141    NS_ASSERT(channelWidth <= PhyEntityType::m_wifiPhy->GetChannelWidth());
 
  143    auto ru = txVector.
GetRu(staId);
 
  144    const auto nonOfdmaWidth = PhyEntityType::GetNonOfdmaWidth(ru);
 
  155            PhyEntityType::m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(
MHz_u{20})),
 
  157    const auto indices = PhyEntityType::ConvertRuSubcarriers(
 
  159         PhyEntityType::GetGuardBandwidth(PhyEntityType::m_wifiPhy->GetChannelWidth()),
 
  160         PhyEntityType::m_wifiPhy->GetOperatingChannel().GetFrequencies(),
 
  161         PhyEntityType::m_wifiPhy->GetChannelWidth(),
 
  162         PhyEntityType::m_wifiPhy->GetSubcarrierSpacing(),
 
  164         {groupPreamble.front().first, groupPreamble.back().second},
 
  165         PhyEntityType::m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(channelWidth)});
 
  167    for (
const auto& indicesPerSegment : indices)
 
  169        nonOfdmaBand.
indices.emplace_back(indicesPerSegment);
 
  170        nonOfdmaBand.frequencies.emplace_back(
 
  171            PhyEntityType::m_wifiPhy->ConvertIndicesToFrequencies(indicesPerSegment));
 
 
 
  179template <
typename LatestPhyEntityType>
 
  258template <
typename LatestPhyEntityType>
 
  263        TypeId(std::string(
"ns3::OfdmaSpectrumWifiPhy") +
 
  264               Demangle(
typeid(LatestPhyEntityType).name()))
 
  266            .SetGroupName(
"Wifi")
 
  267            .AddTraceSource(
"TxPpduUid",
 
  268                            "UID of the PPDU to be transmitted",
 
  271                            "ns3::OfdmaSpectrumWifiPhy<LatestPhyEntityType>::TxPpduUidCallback");
 
 
  275template <
typename LatestPhyEntityType>
 
  283template <
typename LatestPhyEntityType>
 
  289    m_phyEntities[modClass] = m_ofdmaTestPhy;
 
 
  293template <
typename LatestPhyEntityType>
 
  297    m_ofdmaTestPhy = 
nullptr;
 
 
  301template <
typename LatestPhyEntityType>
 
  305    m_ofdmaTestPhy->SetGlobalPpduUid(uid);
 
  306    m_previouslyRxPpduUid = uid;
 
 
  309template <
typename LatestPhyEntityType>
 
  313    m_previouslyRxPpduUid = uid;
 
 
  316template <
typename LatestPhyEntityType>
 
  320    m_phyTxPpduUidTrace(ppdu->GetUid());
 
 
  324template <
typename LatestPhyEntityType>
 
  325std::map<std::pair<uint64_t, WifiPreamble>, 
Ptr<Event>>&
 
  328    return m_currentPreambleEvents;
 
 
  331template <
typename LatestPhyEntityType>
 
  335    return m_currentEvent;
 
 
  338template <
typename LatestPhyEntityType>
 
  343    return m_interference->GetEnergyDuration(energy, band);
 
 
  346template <
typename LatestPhyEntityType>
 
 
  359template <
typename LatestPhyEntityType>
 
  371    void DoRun() 
override;
 
  383                       const std::vector<bool>& statusPerMpdu);
 
  394                       const std::vector<bool>& statusPerMpdu);
 
  405                       const std::vector<bool>& statusPerMpdu);
 
  461    void SendMuPpdu(uint16_t rxStaId1, uint16_t rxStaId2);
 
 
  517template <
typename LatestPhyEntityType>
 
  520               ((
Demangle(typeid(LatestPhyEntityType).name()).find(
"He") != 
std::string::npos)
 
  523      m_modClass{(
Demangle(typeid(LatestPhyEntityType).name()).find(
"He") != 
std::string::npos)
 
 
  530template <
typename LatestPhyEntityType>
 
  534    m_countRxSuccessSta1 = 0;
 
  535    m_countRxSuccessSta2 = 0;
 
  536    m_countRxSuccessSta3 = 0;
 
  537    m_countRxFailureSta1 = 0;
 
  538    m_countRxFailureSta2 = 0;
 
  539    m_countRxFailureSta3 = 0;
 
  540    m_countRxBytesSta1 = 0;
 
  541    m_countRxBytesSta2 = 0;
 
  542    m_countRxBytesSta3 = 0;
 
 
  545template <
typename LatestPhyEntityType>
 
  564        txVector.SetEhtPpduType(0);
 
  566    auto ruType{RuType::RU_TYPE_MAX};
 
  567    if (m_channelWidth == 
MHz_u{20})
 
  569        ruType = RuType::RU_106_TONE;
 
  571        txVector.SetRuAllocation({ruAllocPer20}, 0);
 
  573    else if (m_channelWidth == 
MHz_u{40})
 
  575        ruType = RuType::RU_242_TONE;
 
  577        txVector.SetRuAllocation({ruAllocPer20, ruAllocPer20}, 0);
 
  579    else if (m_channelWidth == 
MHz_u{80})
 
  581        ruType = RuType::RU_484_TONE;
 
  584        txVector.SetRuAllocation({ruAllocUser, ruAllocNoUser, ruAllocNoUser, ruAllocUser}, 0);
 
  586    else if (m_channelWidth == 
MHz_u{160})
 
  588        ruType = RuType::RU_996_TONE;
 
  591        txVector.SetRuAllocation({ruAllocUser,
 
  601    else if (m_channelWidth == 
MHz_u{320})
 
  604        ruType = RuType::RU_2x996_TONE;
 
  605        txVector.SetRuAllocation({88, 30, 88, 30, 88, 30, 88, 30, 30, 88, 30, 88, 30, 88, 30, 88},
 
  610        NS_ASSERT_MSG(
false, 
"Unsupported channel width: " << m_channelWidth);
 
  618    txVector.SetRu(ru1, rxStaId1);
 
  621    txVector.SetNss(1, rxStaId1);
 
  623    std::size_t ru2Index = (m_channelWidth > 
MHz_u{80}) ? 1 : 2;
 
  628    txVector.SetRu(ru2, rxStaId2);
 
  631    txVector.SetNss(1, rxStaId2);
 
  640    psdus.insert(std::make_pair(rxStaId1, psdu1));
 
  649    psdus.insert(std::make_pair(rxStaId2, psdu2));
 
  651    m_phyAp->Send(psdus, txVector);
 
 
  654template <
typename LatestPhyEntityType>
 
  660    m_phyInterferer->SetTxPowerSpectralDensity(interferencePsd);
 
  661    m_phyInterferer->SetPeriod(duration);
 
  662    m_phyInterferer->Start();
 
 
  668template <
typename LatestPhyEntityType>
 
  672    m_phyInterferer->Stop();
 
 
  675template <
typename LatestPhyEntityType>
 
  681    const std::vector<bool>& )
 
  684    m_countRxSuccessSta1++;
 
  685    m_countRxBytesSta1 += (psdu->GetSize() - 30);
 
 
  688template <
typename LatestPhyEntityType>
 
  694    const std::vector<bool>& )
 
  697    m_countRxSuccessSta2++;
 
  698    m_countRxBytesSta2 += (psdu->GetSize() - 30);
 
 
  701template <
typename LatestPhyEntityType>
 
  707    const std::vector<bool>& )
 
  710    m_countRxSuccessSta3++;
 
  711    m_countRxBytesSta3 += (psdu->GetSize() - 30);
 
 
  714template <
typename LatestPhyEntityType>
 
  719    m_countRxFailureSta1++;
 
 
  722template <
typename LatestPhyEntityType>
 
  727    m_countRxFailureSta2++;
 
 
  730template <
typename LatestPhyEntityType>
 
  735    m_countRxFailureSta3++;
 
 
  738template <
typename LatestPhyEntityType>
 
  746                          "The number of successfully received packets by STA 1 is not correct!");
 
  749                          "The number of unsuccessfully received packets by STA 1 is not correct!");
 
  752                          "The number of bytes received by STA 1 is not correct!");
 
 
  755template <
typename LatestPhyEntityType>
 
  763                          "The number of successfully received packets by STA 2 is not correct!");
 
  766                          "The number of unsuccessfully received packets by STA 2 is not correct!");
 
  769                          "The number of bytes received by STA 2 is not correct!");
 
 
  772template <
typename LatestPhyEntityType>
 
  780                          "The number of successfully received packets by STA 3 is not correct!");
 
  783                          "The number of unsuccessfully received packets by STA 3 is not correct!");
 
  786                          "The number of bytes received by STA 3 is not correct!");
 
 
  789template <
typename LatestPhyEntityType>
 
  803template <
typename LatestPhyEntityType>
 
  811    phy->GetAttribute(
"State", ptr);
 
  813    currentState = state->GetState();
 
  817                          "PHY State " << currentState << 
" does not match expected state " 
 
  821template <
typename LatestPhyEntityType>
 
  825    const auto standard =
 
  830    lossModel->SetFrequency(
MHzToHz(m_frequency));
 
  831    spectrumChannel->AddPropagationLossModel(lossModel);
 
  834    spectrumChannel->SetPropagationDelayModel(delayModel);
 
  840    m_phyAp->SetInterferenceHelper(apInterferenceHelper);
 
  842    m_phyAp->SetErrorRateModel(apErrorModel);
 
  843    m_phyAp->SetDevice(apDev);
 
  844    m_phyAp->AddChannel(spectrumChannel);
 
  845    m_phyAp->ConfigureStandard(standard);
 
  847    m_phyAp->SetMobility(apMobility);
 
  848    apDev->SetPhy(m_phyAp);
 
  849    apNode->AggregateObject(apMobility);
 
  850    apNode->AddDevice(apDev);
 
  851    apDev->SetStandard(standard);
 
  861    m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
 
  863    m_phySta1->SetErrorRateModel(sta1ErrorModel);
 
  864    m_phySta1->SetDevice(sta1Dev);
 
  865    m_phySta1->AddChannel(spectrumChannel);
 
  866    m_phySta1->ConfigureStandard(standard);
 
  867    m_phySta1->SetReceiveOkCallback(
 
  869    m_phySta1->SetReceiveErrorCallback(
 
  872    m_phySta1->SetMobility(sta1Mobility);
 
  873    sta1Dev->SetPhy(m_phySta1);
 
  874    sta1Node->AggregateObject(sta1Mobility);
 
  875    sta1Node->AddDevice(sta1Dev);
 
  876    sta1Dev->SetStandard(standard);
 
  886    m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
 
  888    m_phySta2->SetErrorRateModel(sta2ErrorModel);
 
  889    m_phySta2->SetDevice(sta2Dev);
 
  890    m_phySta2->AddChannel(spectrumChannel);
 
  891    m_phySta2->ConfigureStandard(standard);
 
  892    m_phySta2->SetReceiveOkCallback(
 
  894    m_phySta2->SetReceiveErrorCallback(
 
  897    m_phySta2->SetMobility(sta2Mobility);
 
  898    sta2Dev->SetPhy(m_phySta2);
 
  899    sta2Node->AggregateObject(sta2Mobility);
 
  900    sta2Node->AddDevice(sta2Dev);
 
  901    sta2Dev->SetStandard(standard);
 
  911    m_phySta3->SetInterferenceHelper(sta3InterferenceHelper);
 
  913    m_phySta3->SetErrorRateModel(sta3ErrorModel);
 
  914    m_phySta3->SetDevice(sta3Dev);
 
  915    m_phySta3->AddChannel(spectrumChannel);
 
  916    m_phySta3->ConfigureStandard(standard);
 
  918    m_phySta3->SetReceiveOkCallback(
 
  920    m_phySta3->SetReceiveErrorCallback(
 
  923    m_phySta3->SetMobility(sta3Mobility);
 
  924    sta3Dev->SetPhy(m_phySta3);
 
  925    sta3Node->AggregateObject(sta3Mobility);
 
  926    sta3Node->AddDevice(sta3Dev);
 
  927    sta3Dev->SetStandard(standard);
 
  936    m_phyInterferer->SetDevice(interfererDev);
 
  937    m_phyInterferer->SetChannel(spectrumChannel);
 
  938    m_phyInterferer->SetDutyCycle(1);
 
  939    interfererNode->AddDevice(interfererDev);
 
 
  942template <
typename LatestPhyEntityType>
 
  948    m_phySta1->Dispose();
 
  950    m_phySta2->Dispose();
 
  952    m_phySta3->Dispose();
 
  954    m_phyInterferer->Dispose();
 
  955    m_phyInterferer = 
nullptr;
 
 
  958template <
typename LatestPhyEntityType>
 
  964    int64_t streamNumber = 0;
 
  965    m_phyAp->AssignStreams(streamNumber);
 
  966    m_phySta1->AssignStreams(streamNumber);
 
  967    m_phySta2->AssignStreams(streamNumber);
 
  968    m_phySta3->AssignStreams(streamNumber);
 
  977    const auto operatingChannel{
 
  979    m_phyAp->SetOperatingChannel(operatingChannel);
 
  980    m_phySta1->SetOperatingChannel(operatingChannel);
 
  981    m_phySta2->SetOperatingChannel(operatingChannel);
 
  982    m_phySta3->SetOperatingChannel(operatingChannel);
 
 1014                        WifiPhyState::CCA_BUSY);
 
 1019                        WifiPhyState::IDLE);
 
 1024                        WifiPhyState::IDLE);
 
 1029                        WifiPhyState::IDLE);
 
 1078                        WifiPhyState::CCA_BUSY);
 
 1088                        WifiPhyState::IDLE);
 
 1093                        WifiPhyState::IDLE);
 
 1098                        WifiPhyState::IDLE);
 
 1135    bandInfo.
fc = 
MHzToHz(m_frequency - (m_channelWidth / 4));
 
 1136    bandInfo.
fl = bandInfo.
fc - 
MHzToHz(m_channelWidth / 4);
 
 1137    bandInfo.
fh = bandInfo.
fc + 
MHzToHz(m_channelWidth / 4);
 
 1139    bands.push_back(bandInfo);
 
 1143    Watt_u interferencePower{0.1};
 
 1144    *interferencePsdRu1 = interferencePower / (
MHzToHz(m_channelWidth / 2) * 20);
 
 1169                        WifiPhyState::CCA_BUSY);
 
 1174                        WifiPhyState::CCA_BUSY);
 
 1179                        WifiPhyState::CCA_BUSY);
 
 1184                        WifiPhyState::CCA_BUSY);
 
 1221    bandInfo.
fc = 
MHzToHz(m_frequency + (m_channelWidth / 4));
 
 1222    bandInfo.
fl = bandInfo.
fc - 
MHzToHz(m_channelWidth / 4);
 
 1223    bandInfo.
fh = bandInfo.
fc + 
MHzToHz(m_channelWidth / 4);
 
 1225    bands.push_back(bandInfo);
 
 1229    *interferencePsdRu2 = interferencePower / (
MHzToHz(m_channelWidth / 2) * 20);
 
 1254                        WifiPhyState::CCA_BUSY);
 
 1259                        (m_channelWidth >= 
MHz_u{40}) ? WifiPhyState::IDLE
 
 1260                                                      : WifiPhyState::CCA_BUSY);
 
 1265                        (m_channelWidth >= 
MHz_u{40}) ? WifiPhyState::IDLE
 
 1266                                                      : WifiPhyState::CCA_BUSY);
 
 1271                        (m_channelWidth >= 
MHz_u{40}) ? WifiPhyState::IDLE
 
 1272                                                      : WifiPhyState::CCA_BUSY);
 
 1310    bandInfo.
fl = bandInfo.
fc - 
MHzToHz(m_channelWidth / 2);
 
 1311    bandInfo.
fh = bandInfo.
fc + 
MHzToHz(m_channelWidth / 2);
 
 1313    bands.push_back(bandInfo);
 
 1317    *interferencePsdAll = interferencePower / (
MHzToHz(m_channelWidth) * 20);
 
 1342                        WifiPhyState::CCA_BUSY);
 
 1347                        WifiPhyState::CCA_BUSY);
 
 1352                        WifiPhyState::CCA_BUSY);
 
 1357                        WifiPhyState::CCA_BUSY);
 
 
 1390template <
typename LatestPhyEntityType>
 
 1394    m_frequency = 
MHz_u{5955};
 
 1395    m_channelWidth = 
MHz_u{20};
 
 1399    m_frequency = 
MHz_u{5965};
 
 1400    m_channelWidth = 
MHz_u{40};
 
 1404    m_frequency = 
MHz_u{5985};
 
 1405    m_channelWidth = 
MHz_u{80};
 
 1409    m_frequency = 
MHz_u{6025};
 
 1410    m_channelWidth = 
MHz_u{160};
 
 1416        m_frequency = 
MHz_u{6105};
 
 1417        m_channelWidth = 
MHz_u{320};
 
 
 1439    void DoRun() 
override;
 
 1451                       const std::vector<bool>& statusPerMpdu);
 
 1463                       const std::vector<bool>& statusPerMpdu);
 
 1511                    const std::vector<bool>& puncturedSubchannels);
 
 
 1567    : 
TestCase(
"DL-OFDMA PHY puncturing test"),
 
 1568      m_countRxSuccessSta1(0),
 
 1569      m_countRxSuccessSta2(0),
 
 1570      m_countRxFailureSta1(0),
 
 1571      m_countRxFailureSta2(0),
 
 1572      m_countRxBytesSta1(0),
 
 1573      m_countRxBytesSta2(0),
 
 1574      m_frequency(
MHz_u{5210}),
 
 1575      m_channelWidth(
MHz_u{80}),
 
 1576      m_indexSubchannel(0),
 
 
 1596                                     const std::vector<bool>& puncturedSubchannels)
 
 1611    RuType ruType = puncturedSubchannels.empty()
 
 1612                        ? RuType::RU_484_TONE
 
 1613                        : (puncturedSubchannels.at(1) ? RuType::RU_242_TONE : RuType::RU_484_TONE);
 
 1615    txVector.SetRu(ru1, rxStaId1);
 
 1617    txVector.SetNss(1, rxStaId1);
 
 1619    ruType = puncturedSubchannels.empty()
 
 1620                 ? RuType::RU_484_TONE
 
 1621                 : (puncturedSubchannels.at(1) ? RuType::RU_484_TONE : RuType::RU_242_TONE);
 
 1623                     ruType == RuType::RU_484_TONE ? 2 : (puncturedSubchannels.at(3) ? 3 : 4),
 
 1625    txVector.SetRu(ru2, rxStaId2);
 
 1627    txVector.SetNss(1, rxStaId2);
 
 1630    if (puncturedSubchannels.empty())
 
 1632        ruAlloc.push_back(200);
 
 1633        ruAlloc.push_back(114);
 
 1634        ruAlloc.push_back(114);
 
 1635        ruAlloc.push_back(200);
 
 1639        ruAlloc.push_back(puncturedSubchannels.at(1) ? 192 : 200);
 
 1640        ruAlloc.push_back(puncturedSubchannels.at(1) ? 113 : 114);
 
 1641        ruAlloc.push_back(puncturedSubchannels.at(2) ? 113
 
 1642                                                     : (puncturedSubchannels.at(3) ? 192 : 114));
 
 1643        ruAlloc.push_back(puncturedSubchannels.at(2) ? 192
 
 1644                                                     : (puncturedSubchannels.at(3) ? 113 : 200));
 
 1647    txVector.SetRuAllocation(ruAlloc, 0);
 
 1657    psdus.insert(std::make_pair(rxStaId1, psdu1));
 
 1666    psdus.insert(std::make_pair(rxStaId2, psdu2));
 
 1668    if (!puncturedSubchannels.empty())
 
 1670        txVector.SetInactiveSubchannels(puncturedSubchannels);
 
 1673    m_phyAp->Send(psdus, txVector);
 
 
 1697                                        const std::vector<bool>& )
 
 
 1708                                        const std::vector<bool>& )
 
 
 1736                          "The number of successfully received packets by STA 1 is not correct!");
 
 1739                          "The number of unsuccessfully received packets by STA 1 is not correct!");
 
 1742                          "The number of bytes received by STA 1 is not correct!");
 
 
 1752                          "The number of successfully received packets by STA 2 is not correct!");
 
 1755                          "The number of unsuccessfully received packets by STA 2 is not correct!");
 
 1758                          "The number of bytes received by STA 2 is not correct!");
 
 
 1776    phy->GetAttribute(
"State", ptr);
 
 1778    currentState = state->GetState();
 
 1782                          "PHY State " << currentState << 
" does not match expected state " 
 
 1792    spectrumChannel->AddPropagationLossModel(lossModel);
 
 1795    spectrumChannel->SetPropagationDelayModel(delayModel);
 
 1801    m_phyAp->SetInterferenceHelper(apInterferenceHelper);
 
 1803    m_phyAp->SetErrorRateModel(apErrorModel);
 
 1805    m_phyAp->AddChannel(spectrumChannel);
 
 1808    m_phyAp->SetMobility(apMobility);
 
 1810    apNode->AggregateObject(apMobility);
 
 1811    apNode->AddDevice(apDev);
 
 1818    m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
 
 1820    m_phySta1->SetErrorRateModel(sta1ErrorModel);
 
 1830    sta1Node->AggregateObject(sta1Mobility);
 
 1831    sta1Node->AddDevice(sta1Dev);
 
 1838    m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
 
 1840    m_phySta2->SetErrorRateModel(sta2ErrorModel);
 
 1850    sta2Node->AggregateObject(sta2Mobility);
 
 1851    sta2Node->AddDevice(sta2Dev);
 
 1860    interfererNode->AddDevice(interfererDev);
 
 
 1881    int64_t streamNumber = 0;
 
 1882    m_phyAp->AssignStreams(streamNumber);
 
 1909    bands.push_back(bandInfo);
 
 1913    Watt_u interferencePower{0.1};
 
 1914    *interferencePsd = interferencePower / 10e6;
 
 1929                        std::vector<bool>{});
 
 1947                        WifiPhyState::IDLE);
 
 1952                        WifiPhyState::IDLE);
 
 1994    std::vector<bool> puncturedSubchannels;
 
 1996    for (std::size_t i = 0; i < num20MhzSubchannels; ++i)
 
 2000            puncturedSubchannels.push_back(
true);
 
 2004            puncturedSubchannels.push_back(
false);
 
 2012                        puncturedSubchannels);
 
 2030                        WifiPhyState::IDLE);
 
 2035                        WifiPhyState::IDLE);
 
 
 2062    for (
auto index : {1, 2, 3})
 
 
 2085    void DoRun() 
override;
 
 2126    void CheckUid(uint16_t staId, uint64_t expectedUid);
 
 
 2138    : 
TestCase(
"UL-OFDMA PPDU UID attribution test"),
 
 2139      m_ppduUidAp(UINT64_MAX),
 
 2140      m_ppduUidSta1(UINT64_MAX),
 
 2141      m_ppduUidSta2(UINT64_MAX)
 
 
 2155    spectrumChannel->AddPropagationLossModel(lossModel);
 
 2158    spectrumChannel->SetPropagationDelayModel(delayModel);
 
 2164    m_phyAp->SetInterferenceHelper(apInterferenceHelper);
 
 2166    m_phyAp->SetErrorRateModel(apErrorModel);
 
 2167    m_phyAp->AddChannel(spectrumChannel);
 
 2178    m_phyAp->TraceConnectWithoutContext(
"TxPpduUid",
 
 2181    m_phyAp->SetMobility(apMobility);
 
 2183    apNode->AggregateObject(apMobility);
 
 2184    apNode->AddDevice(apDev);
 
 2192    m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
 
 2194    m_phySta1->SetErrorRateModel(sta1ErrorModel);
 
 2200    m_phySta1->TraceConnectWithoutContext(
"TxPpduUid",
 
 2205    sta1Node->AggregateObject(sta1Mobility);
 
 2206    sta1Node->AddDevice(sta1Dev);
 
 2212    m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
 
 2214    m_phySta2->SetErrorRateModel(sta2ErrorModel);
 
 2220    m_phySta2->TraceConnectWithoutContext(
"TxPpduUid",
 
 2225    sta2Node->AggregateObject(sta2Mobility);
 
 2226    sta2Node->AddDevice(sta2Dev);
 
 
 2264                          "UID " << uid << 
" does not match expected one " << expectedUid << 
" for " 
 
 2311    uint16_t rxStaId1 = 1;
 
 2313    txVector.SetRu(ru1, rxStaId1);
 
 2315    txVector.SetNss(1, rxStaId1);
 
 2317    uint16_t rxStaId2 = 2;
 
 2319    txVector.SetRu(ru2, rxStaId2);
 
 2321    txVector.SetNss(1, rxStaId2);
 
 2323    txVector.SetRuAllocation({96}, 0);
 
 2332    psdus.insert(std::make_pair(rxStaId1, psdu1));
 
 2341    psdus.insert(std::make_pair(rxStaId2, psdu2));
 
 2343    m_phyAp->Send(psdus, txVector);
 
 
 2365    uint16_t rxStaId1 = 1;
 
 2367    txVector1.SetRu(ru1, rxStaId1);
 
 2369    txVector1.SetNss(1, rxStaId1);
 
 2370    trigVector.SetRu(ru1, rxStaId1);
 
 2372    trigVector.SetNss(1, rxStaId1);
 
 2381    psdus1.insert(std::make_pair(rxStaId1, psdu1));
 
 2383    uint16_t rxStaId2 = 2;
 
 2385    txVector2.SetRu(ru2, rxStaId2);
 
 2387    txVector2.SetNss(1, rxStaId2);
 
 2388    trigVector.SetRu(ru2, rxStaId2);
 
 2390    trigVector.SetNss(1, rxStaId2);
 
 2399    psdus2.insert(std::make_pair(rxStaId2, psdu2));
 
 2401    const auto txDuration1 =
 
 2406    const auto txDuration2 =
 
 2411    const auto txDuration = std::max(txDuration1, txDuration2);
 
 2413    txVector1.SetLength(
 
 2416    txVector2.SetLength(
 
 2420    auto phyAp = 
m_phyAp->GetPhyEntity();
 
 2421    phyAp->SetTrigVector(trigVector, txDuration);
 
 
 2449    psdus.insert(std::make_pair(
SU_STA_ID, psdu));
 
 2454        m_phyAp->Send(psdus, txVector);
 
 
 2472    int64_t streamNumber = 0;
 
 2473    m_phyAp->AssignStreams(streamNumber);
 
 
 2522    void DoRun() 
override;
 
 2533    void RxHeTbPpdu(uint64_t uid, uint16_t staId, 
Watt_u txPower, 
size_t payloadSize);
 
 
 2582    : 
TestCase(
"UL-OFDMA multiple RX events test"),
 
 2583      m_totalBytesDropped(0),
 
 2584      m_trigVector(
HePhy::GetHeMcs7(),
 
 
 2621    auto events = 
m_phy->GetCurrentPreambleEvents();
 
 2623    for (
const auto& uid : uids)
 
 2626        auto it = events.find(pair);
 
 2627        bool found = (it != events.end());
 
 2630                              "HE TB PPDU with UID " << uid << 
" has not been received!");
 
 
 2638                          expectedBytesDropped,
 
 2639                          "The number of dropped bytes is not correct!");
 
 
 2661    txVector.SetRu(ru, staId);
 
 2663    txVector.SetNss(1, staId);
 
 2674    psdus.insert(std::make_pair(staId, psdu));
 
 2678                                                                         m_phy->GetPhyBand(),
 
 2682                               m_phy->GetOperatingChannel(),
 
 2688    const auto nonOfdmaDuration = 
m_phy->GetPhyEntity()->CalculateNonHeDurationForHeTb(txVector);
 
 2689    const auto centerFrequency =
 
 2690        m_phy->GetPhyEntity()->GetCenterFrequenciesForNonHePart(ppdu, staId).front();
 
 2692    auto channelWidth = ruWidth < 
MHz_u{20} ? 
MHz_u{20} : ruWidth;
 
 2697        m_phy->GetGuardBandwidth(channelWidth));
 
 2699    rxParams->psd = rxPsd;
 
 2700    rxParams->txPhy = 
nullptr;
 
 2701    rxParams->duration = nonOfdmaDuration;
 
 2702    rxParams->ppdu = ppdu;
 
 2705    std::tie(length, ppduDuration) =
 
 2707    txVector.SetLength(length);
 
 2711    ppdu->ResetTxVector();
 
 2712    m_phy->StartRx(rxParams, 
nullptr);
 
 2717    const auto band = 
m_phy->GetPhyEntity()->GetRuBandForRx(txVector, staId);
 
 2725    rxParamsOfdma->psd = rxPsd;
 
 2726    rxParamsOfdma->txPhy = 
nullptr;
 
 2727    rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration;
 
 2728    rxParamsOfdma->ppdu = ppduOfdma;
 
 
 2747    m_phy->StartRx(rxParamsOfdma, 
nullptr);
 
 
 2763    mac->SetAttribute(
"BeaconGeneration", 
BooleanValue(
false));
 
 2765    m_phy->SetInterferenceHelper(interferenceHelper);
 
 2766    m_phy->SetErrorRateModel(error);
 
 2767    m_phy->AddChannel(spectrumChannel);
 
 2773    m_phy->TraceConnectWithoutContext(
"PhyRxDrop",
 
 2775    m_phy->SetDevice(dev);
 
 2778    preambleDetectionModel->SetAttribute(
"Threshold", 
DoubleValue(4));
 
 2779    preambleDetectionModel->SetAttribute(
"MinimumRssi", 
DoubleValue(-82));
 
 2780    m_phy->SetPreambleDetectionModel(preambleDetectionModel);
 
 2782    heConfiguration->m_maxTbPpduDelay = 
NanoSeconds(400);
 
 2783    dev->SetHeConfiguration(heConfiguration);
 
 2785    node->AddDevice(dev);
 
 
 2800    int64_t streamNumber = 0;
 
 2801    m_phy->AssignStreams(streamNumber);
 
 2807        std::vector<uint64_t> uids{0};
 
 2835        std::vector<uint64_t> uids{1, 2};
 
 2879        std::vector<uint64_t> uids{3, 4};
 
 2923        std::vector<uint64_t> uids{5, 6};
 
 2958                            std::vector<uint64_t>{uids[0]});
 
 2971        std::vector<uint64_t> uids{7, 8};
 
 3006                            std::vector<uint64_t>{uids[0]});
 
 3019        std::vector<uint64_t> uids{9};
 
 
 3097                            const std::vector<Time>& )
 override 
 
 
 3193template <
typename LatestPhyEntityType>
 
 3213    void DoRun() 
override;
 
 3241                    std::size_t payloadSize,
 
 3253    void SendSuPpdu(uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
 
 3355                      Time expectedLastNotification,
 
 3356                      bool expectedSuccess);
 
 3373                   const std::vector<bool>& statusPerMpdu);
 
 3410                      bool scheduleTxSta1 = 
true,
 
 3412                      WifiPhyState expectedStateBeforeEnd = WifiPhyState::RX,
 
 3425                                        Watt_u rxPowerNonOfdmaRu1,
 
 3426                                        Watt_u rxPowerNonOfdmaRu2,
 
 3443    std::shared_ptr<OfdmaTestPhyListener>
 
 
 3460template <
typename LatestPhyEntityType>
 
 3462    : 
TestCase{
std::string(
"UL-OFDMA PHY test for ") +
 
 3463               ((
Demangle(typeid(LatestPhyEntityType).name()).find(
"He") != 
std::string::npos)
 
 3466      m_modClass{(
Demangle(typeid(LatestPhyEntityType).name()).find(
"He") != 
std::string::npos)
 
 
 3473template <
typename LatestPhyEntityType>
 
 3476                                                            std::size_t payloadSize,
 
 3502    std::ostringstream addr;
 
 3503    addr << 
"00:00:00:00:00:0" << txStaId;
 
 3507    psdus.insert(std::make_pair(
SU_STA_ID, psdu));
 
 3514    else if (txStaId == 2)
 
 3518    else if (txStaId == 3)
 
 3522    else if (txStaId == 0)
 
 3526    phy->SetPpduUid(uid);
 
 3527    phy->Send(psdus, txVector);
 
 
 3530template <
typename LatestPhyEntityType>
 
 3534                                                                      uint8_t bssColor)
 const 
 3551        txVector.SetEhtPpduType(0);
 
 3553    auto ruType{RuType::RU_TYPE_MAX};
 
 3554    if (m_channelWidth == 
MHz_u{20})
 
 3556        ruType = RuType::RU_106_TONE;
 
 3558    else if (m_channelWidth == 
MHz_u{40})
 
 3560        ruType = RuType::RU_242_TONE;
 
 3562    else if (m_channelWidth == 
MHz_u{80})
 
 3564        ruType = RuType::RU_484_TONE;
 
 3566    else if (m_channelWidth == 
MHz_u{160})
 
 3568        ruType = RuType::RU_996_TONE;
 
 3570    else if (m_channelWidth == 
MHz_u{320})
 
 3572        ruType = RuType::RU_2x996_TONE;
 
 3576        NS_ASSERT_MSG(
false, 
"Unsupported channel width: " << m_channelWidth);
 
 3579    auto primary80MHzOrLow80MHz{
true};
 
 3580    auto primary160MHz{
true};
 
 3581    if (m_channelWidth > 
MHz_u{80})
 
 3590            const auto& [p160, p80OrLow80] =
 
 3592            primary160MHz = p160;
 
 3593            primary80MHzOrLow80MHz = p80OrLow80;
 
 3601    txVector.SetRu(ru, txStaId);
 
 3604    txVector.SetNss(1, txStaId);
 
 
 3608template <
typename LatestPhyEntityType>
 
 3613    auto channelWidth = m_channelWidth;
 
 3634    RuType ruType = RuType::RU_106_TONE;
 
 3635    if (channelWidth == 
MHz_u{20})
 
 3637        ruType = RuType::RU_106_TONE;
 
 3639    else if (channelWidth == 
MHz_u{40})
 
 3641        ruType = RuType::RU_242_TONE;
 
 3643    else if (channelWidth == 
MHz_u{80})
 
 3645        ruType = RuType::RU_484_TONE;
 
 3647    else if (channelWidth == 
MHz_u{160})
 
 3649        ruType = RuType::RU_996_TONE;
 
 3651    else if (channelWidth == 
MHz_u{320})
 
 3653        ruType = RuType::RU_2x996_TONE;
 
 3657        NS_ASSERT_MSG(
false, 
"Unsupported channel width: " << channelWidth);
 
 3660    uint16_t aid1 = (error == AID ? 3 : 1);
 
 3661    uint16_t aid2 = (error == AID ? 4 : 2);
 
 3666    txVector.
SetRu(ru1, aid1);
 
 3669    txVector.
SetNss(1, aid1);
 
 3673                                                       (channelWidth == 
MHz_u{160} ? 1ULL : 2ULL),
 
 3674                                                       (channelWidth != 
MHz_u{160})})
 
 3676                                                        (channelWidth == 
MHz_u{320} ? 1ULL : 2ULL),
 
 3677                                                        (channelWidth != 
MHz_u{320}),
 
 3679    txVector.
SetRu(ru2, aid2);
 
 3682    txVector.
SetNss(1, aid2);
 
 3685    std::tie(length, m_expectedPpduDuration) =
 
 3688                                                   m_phyAp->GetPhyBand());
 
 3689    if (error == UL_LENGTH)
 
 3694    auto phyAp = m_phyAp->GetPhyEntity();
 
 3695    phyAp->SetTrigVector(txVector, m_expectedPpduDuration);
 
 
 3698template <
typename LatestPhyEntityType>
 
 3702                                                            std::size_t payloadSize,
 
 3707    NS_LOG_FUNCTION(
this << txStaId << index << payloadSize << uid << +bssColor << (incrementUid));
 
 3715    auto txVector = GetTxVectorForTbPpdu(txStaId, index, bssColor);
 
 3721    std::ostringstream addr;
 
 3722    addr << 
"00:00:00:00:00:0" << txStaId;
 
 3726    psdus.insert(std::make_pair(txStaId, psdu));
 
 3733    else if (txStaId == 2)
 
 3737    else if (txStaId == 3)
 
 3750    phy->SetPpduUid(uid);
 
 3751    phy->Send(psdus, txVector);
 
 
 3754template <
typename LatestPhyEntityType>
 
 3761    m_phyInterferer->SetTxPowerSpectralDensity(interferencePsd);
 
 3762    m_phyInterferer->SetPeriod(duration);
 
 3763    m_phyInterferer->Start();
 
 
 3769template <
typename LatestPhyEntityType>
 
 3773    m_phyInterferer->Stop();
 
 
 3776template <
typename LatestPhyEntityType>
 
 3782    const std::vector<bool>& )
 
 3784    NS_LOG_FUNCTION(
this << *psdu << psdu->GetAddr2() << rxSignalInfo << txVector);
 
 3785    if (psdu->GetAddr2() == 
Mac48Address(
"00:00:00:00:00:01"))
 
 3787        m_countRxSuccessFromSta1++;
 
 3788        m_countRxBytesFromSta1 += (psdu->GetSize() - 30);
 
 3790    else if (psdu->GetAddr2() == 
Mac48Address(
"00:00:00:00:00:02"))
 
 3792        m_countRxSuccessFromSta2++;
 
 3793        m_countRxBytesFromSta2 += (psdu->GetSize() - 30);
 
 
 3797template <
typename LatestPhyEntityType>
 
 3802    if (psdu->GetAddr2() == 
Mac48Address(
"00:00:00:00:00:01"))
 
 3804        m_countRxFailureFromSta1++;
 
 3806    else if (psdu->GetAddr2() == 
Mac48Address(
"00:00:00:00:00:02"))
 
 3808        m_countRxFailureFromSta2++;
 
 
 3812template <
typename LatestPhyEntityType>
 
 3820                          "The number of successfully received packets from STA 1 is not correct!");
 
 3822        m_countRxFailureFromSta1,
 
 3824        "The number of unsuccessfully received packets from STA 1 is not correct!");
 
 3827                          "The number of bytes received from STA 1 is not correct!");
 
 
 3830template <
typename LatestPhyEntityType>
 
 3838                          "The number of successfully received packets from STA 2 is not correct!");
 
 3840        m_countRxFailureFromSta2,
 
 3842        "The number of unsuccessfully received packets from STA 2 is not correct!");
 
 3845                          "The number of bytes received from STA 2 is not correct!");
 
 
 3848template <
typename LatestPhyEntityType>
 
 3855    auto event = phy->GetCurrentEvent();
 
 3857    auto rxPower = 
event->GetRxPower(band);
 
 3863                              "RX power " << rxPower << 
" over (" << band
 
 3864                                          << 
") does not match expected power " << expectedRxPower
 
 
 3868template <
typename LatestPhyEntityType>
 
 3882    if (expectedRxPower > 
Watt_u{0.0})
 
 3885            phy->GetEnergyDuration(expectedRxPower - step, band).IsStrictlyPositive(),
 
 3887            "At least " << expectedRxPower << 
" W expected for OFDMA part over (" << band << 
") at " 
 3890            phy->GetEnergyDuration(expectedRxPower + step, band).IsStrictlyPositive(),
 
 3892            "At most " << expectedRxPower << 
" W expected for OFDMA part over (" << band << 
") at " 
 3898            phy->GetEnergyDuration(expectedRxPower + step, band).IsStrictlyPositive(),
 
 3900            "At most " << expectedRxPower << 
" W expected for OFDMA part over (" << band << 
") at " 
 
 3905template <
typename LatestPhyEntityType>
 
 3911                          "m_currentEvent for AP was not cleared");
 
 3914                          "m_currentEvent for STA 1 was not cleared");
 
 3917                          "m_currentEvent for STA 2 was not cleared");
 
 
 3920template <
typename LatestPhyEntityType>
 
 3934template <
typename LatestPhyEntityType>
 
 3942    phy->GetAttribute(
"State", ptr);
 
 3944    currentState = state->GetState();
 
 3948                          "PHY State " << currentState << 
" does not match expected state " 
 
 3952template <
typename LatestPhyEntityType>
 
 3955                                                                Time expectedLastNotification)
 
 3958                          expectedNotifications,
 
 3959                          "Number of RX start notifications " 
 3960                              << m_apPhyStateListener->GetNumRxStartNotifications()
 
 3961                              << 
" does not match expected count " << expectedNotifications
 
 3964                          expectedLastNotification,
 
 3965                          "Last time RX start notification has been received " 
 3966                              << m_apPhyStateListener->GetLastRxStartNotification()
 
 3967                              << 
" does not match expected time " << expectedLastNotification
 
 
 3971template <
typename LatestPhyEntityType>
 
 3974                                                              Time expectedLastNotification,
 
 3975                                                              bool expectedSuccess)
 
 3978                          expectedNotifications,
 
 3979                          "Number of RX end notifications " 
 3980                              << m_apPhyStateListener->GetNumRxEndNotifications()
 
 3981                              << 
" does not match expected count " << expectedNotifications
 
 3984                          expectedLastNotification,
 
 3985                          "Last time RX end notification has been received " 
 3986                              << m_apPhyStateListener->GetLastRxEndNotification()
 
 3987                              << 
" does not match expected time " << expectedLastNotification
 
 3991                          "Last time RX end notification indicated a " 
 3992                              << (m_apPhyStateListener->IsLastRxSuccess() ? 
"success" : 
"failure")
 
 3993                              << 
" but expected a " << (expectedSuccess ? 
"success" : 
"failure")
 
 
 3997template <
typename LatestPhyEntityType>
 
 4001    m_countRxSuccessFromSta1 = 0;
 
 4002    m_countRxSuccessFromSta2 = 0;
 
 4003    m_countRxFailureFromSta1 = 0;
 
 4004    m_countRxFailureFromSta2 = 0;
 
 4005    m_countRxBytesFromSta1 = 0;
 
 4006    m_countRxBytesFromSta2 = 0;
 
 4007    m_phySta1->SetPpduUid(0);
 
 4008    m_phySta1->SetTriggerFrameUid(0);
 
 4009    m_phySta2->SetTriggerFrameUid(0);
 
 4010    SetBssColor(m_phyAp, 0);
 
 4011    m_apPhyStateListener->Reset();
 
 
 4014template <
typename LatestPhyEntityType>
 
 4020    heConfiguration->m_bssColor = bssColor;
 
 
 4023template <
typename LatestPhyEntityType>
 
 4029    phy->SetAttribute(
"PowerDensityLimit", 
DoubleValue(psdLimit));
 
 
 4032template <
typename LatestPhyEntityType>
 
 4036    const auto standard =
 
 4041    lossModel->SetFrequency(m_frequency);
 
 4042    spectrumChannel->AddPropagationLossModel(lossModel);
 
 4045    spectrumChannel->SetPropagationDelayModel(delayModel);
 
 4049    preambleDetectionModel->SetAttribute(
 
 4053    preambleDetectionModel->SetAttribute(
"Threshold", 
DoubleValue(-100)); 
 
 4057    apDev->SetStandard(standard);
 
 4061    apMac->SetAttribute(
"BeaconGeneration", 
BooleanValue(
false));
 
 4062    apDev->SetMac(apMac);
 
 4065    apDev->SetHeConfiguration(heConfiguration);
 
 4071    m_phyAp->SetInterferenceHelper(apInterferenceHelper);
 
 4073    m_phyAp->SetErrorRateModel(apErrorModel);
 
 4074    m_phyAp->SetDevice(apDev);
 
 4075    m_phyAp->AddChannel(spectrumChannel);
 
 4076    m_phyAp->ConfigureStandard(standard);
 
 4077    m_phyAp->SetReceiveOkCallback(
 
 4079    m_phyAp->SetReceiveErrorCallback(
 
 4081    m_phyAp->SetPreambleDetectionModel(preambleDetectionModel);
 
 4083    m_phyAp->SetMobility(apMobility);
 
 4084    m_apPhyStateListener = std::make_unique<OfdmaTestPhyListener>();
 
 4085    m_phyAp->RegisterListener(m_apPhyStateListener);
 
 4086    apDev->SetPhy(m_phyAp);
 
 4087    apMac->SetWifiPhys({m_phyAp});
 
 4088    apNode->AggregateObject(apMobility);
 
 4089    apNode->AddDevice(apDev);
 
 4093    sta1Dev->SetStandard(standard);
 
 4101    m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
 
 4103    m_phySta1->SetErrorRateModel(sta1ErrorModel);
 
 4104    m_phySta1->SetDevice(sta1Dev);
 
 4105    m_phySta1->AddChannel(spectrumChannel);
 
 4106    m_phySta1->ConfigureStandard(standard);
 
 4107    m_phySta1->SetPreambleDetectionModel(preambleDetectionModel);
 
 4109    m_phySta1->SetMobility(sta1Mobility);
 
 4110    sta1Dev->SetPhy(m_phySta1);
 
 4111    sta1Node->AggregateObject(sta1Mobility);
 
 4112    sta1Node->AddDevice(sta1Dev);
 
 4116    sta2Dev->SetStandard(standard);
 
 4124    m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
 
 4126    m_phySta2->SetErrorRateModel(sta2ErrorModel);
 
 4127    m_phySta2->SetDevice(sta2Dev);
 
 4128    m_phySta2->AddChannel(spectrumChannel);
 
 4129    m_phySta2->ConfigureStandard(standard);
 
 4130    m_phySta2->SetPreambleDetectionModel(preambleDetectionModel);
 
 4132    m_phySta2->SetMobility(sta2Mobility);
 
 4133    sta2Dev->SetPhy(m_phySta2);
 
 4134    sta2Node->AggregateObject(sta2Mobility);
 
 4135    sta2Node->AddDevice(sta2Dev);
 
 4139    sta3Dev->SetStandard(standard);
 
 4147    m_phySta3->SetInterferenceHelper(sta3InterferenceHelper);
 
 4149    m_phySta3->SetErrorRateModel(sta3ErrorModel);
 
 4150    m_phySta3->SetDevice(sta3Dev);
 
 4151    m_phySta3->AddChannel(spectrumChannel);
 
 4152    m_phySta3->ConfigureStandard(standard);
 
 4153    m_phySta3->SetPreambleDetectionModel(preambleDetectionModel);
 
 4155    m_phySta3->SetMobility(sta3Mobility);
 
 4156    sta3Dev->SetPhy(m_phySta3);
 
 4157    sta3Node->AggregateObject(sta3Mobility);
 
 4158    sta3Node->AddDevice(sta3Dev);
 
 4163    m_phyInterferer->SetDevice(interfererDev);
 
 4164    m_phyInterferer->SetChannel(spectrumChannel);
 
 4165    m_phyInterferer->SetDutyCycle(1);
 
 4166    interfererNode->AddDevice(interfererDev);
 
 4169    std::list<Ptr<WifiPhy>> phys{m_phyAp, m_phySta1, m_phySta2, m_phySta3};
 
 4170    for (
auto& phy : phys)
 
 4173        phy->SetAttribute(
"TxPowerStart", 
DoubleValue(16.0));
 
 4174        phy->SetAttribute(
"TxPowerEnd", 
DoubleValue(16.0));
 
 4175        phy->SetAttribute(
"PowerDensityLimit", 
DoubleValue(100.0)); 
 
 4178        phy->SetAttribute(
"TxMaskInnerBandMinimumRejection", 
DoubleValue(-100.0));
 
 4179        phy->SetAttribute(
"TxMaskOuterBandMinimumRejection", 
DoubleValue(-100.0));
 
 4180        phy->SetAttribute(
"TxMaskOuterBandMaximumRejection", 
DoubleValue(-100.0));
 
 
 4184template <
typename LatestPhyEntityType>
 
 4190    m_phySta1->Dispose();
 
 4191    m_phySta1 = 
nullptr;
 
 4192    m_phySta2->Dispose();
 
 4193    m_phySta2 = 
nullptr;
 
 4194    m_phySta3->Dispose();
 
 4195    m_phySta3 = 
nullptr;
 
 4196    m_phyInterferer->Dispose();
 
 4197    m_phyInterferer = 
nullptr;
 
 
 4200template <
typename LatestPhyEntityType>
 
 4207template <
typename LatestPhyEntityType>
 
 4218                                                              bool scheduleTxSta1,
 
 4219                                                              Time ulTimeDifference,
 
 4223    static uint64_t uid = 0;
 
 4249                        m_apPhyStateListener.get());
 
 4277                        expectedStateBeforeEnd);
 
 4282                        expectedStateAtEnd);
 
 4285    if (expectedSuccessFromSta1 + expectedFailuresFromSta1 + expectedSuccessFromSta2 +
 
 4286            expectedFailuresFromSta2 >
 
 4290        const bool isSuccess = (expectedSuccessFromSta1 > 0) || (expectedSuccessFromSta2 > 0);
 
 4297        const Time expectedPayloadEnd = delay + m_expectedPpduDuration + ulTimeDifference;
 
 4320                        expectedSuccessFromSta1,
 
 4321                        expectedFailuresFromSta1,
 
 4322                        expectedBytesFromSta1);
 
 4327                        expectedSuccessFromSta2,
 
 4328                        expectedFailuresFromSta2,
 
 4329                        expectedBytesFromSta2);
 
 
 4339template <
typename LatestPhyEntityType>
 
 4343    Watt_u rxPowerNonOfdmaRu1,
 
 4344    Watt_u rxPowerNonOfdmaRu2,
 
 4349    const auto txVectorSta1 = GetTxVectorForTbPpdu(1, 1, 0);
 
 4350    const auto txVectorSta2 = GetTxVectorForTbPpdu(2, 2, 0);
 
 4352    const auto nonOfdmaDuration = phyEntity->CalculateNonHeDurationForHeTb(txVectorSta2);
 
 4353    NS_ASSERT(nonOfdmaDuration == phyEntity->CalculateNonHeDurationForHeTb(txVectorSta1));
 
 4355    std::vector<Watt_u> rxPowerNonOfdma{rxPowerNonOfdmaRu1, rxPowerNonOfdmaRu2};
 
 4356    std::vector<WifiSpectrumBandInfo> nonOfdmaBand{phyEntity->GetNonOfdmaBand(txVectorSta1, 1),
 
 4357                                                   phyEntity->GetNonOfdmaBand(txVectorSta2, 2)};
 
 4358    std::vector<Watt_u> rxPowerOfdma{rxPowerOfdmaRu1, rxPowerOfdmaRu2};
 
 4359    std::vector<WifiSpectrumBandInfo> ofdmaBand{phyEntity->GetRuBandForRx(txVectorSta1, 1),
 
 4360                                                phyEntity->GetRuBandForRx(txVectorSta2, 2)};
 
 4362    for (uint8_t i = 0; i < 2; ++i)
 
 4369            delay + detectionDuration +
 
 4375            rxPowerNonOfdma[i]);
 
 4381                            rxPowerNonOfdma[i]);
 
 4405            delay + detectionDuration +
 
 4411            rxPowerNonOfdma[i]);
 
 4417                            rxPowerNonOfdma[i]);
 
 4435    if (rxPowerOfdmaRu1 != 
Watt_u{0.0})
 
 4442        const auto rxPowerNonOfdmaSta1Only =
 
 4443            (m_channelWidth >= 
MHz_u{40})
 
 4444                ? rxPowerNonOfdma[0]
 
 4445                : rxPowerNonOfdma[0] / 2; 
 
 4448            delay + detectionDuration +
 
 4454            rxPowerNonOfdmaSta1Only);
 
 4460                            rxPowerNonOfdmaSta1Only);
 
 
 4479template <
typename LatestPhyEntityType>
 
 4483    NS_LOG_DEBUG(
"Run UL OFDMA PHY transmission test for " << m_channelWidth << 
" MHz");
 
 4487    int64_t streamNumber = 0;
 
 4488    m_phyAp->AssignStreams(streamNumber);
 
 4489    m_phySta1->AssignStreams(streamNumber);
 
 4490    m_phySta2->AssignStreams(streamNumber);
 
 4491    m_phySta3->AssignStreams(streamNumber);
 
 4493    const auto standard =
 
 4502    const auto operatingChannel{
 
 4504    m_phyAp->SetOperatingChannel(operatingChannel);
 
 4505    m_phySta1->SetOperatingChannel(operatingChannel);
 
 4506    m_phySta2->SetOperatingChannel(operatingChannel);
 
 4507    m_phySta3->SetOperatingChannel(operatingChannel);
 
 4526                        "Reception of solicited HE TB PPDUs");
 
 4545        "Reception of solicited HE TB PPDUs with delay (< 400ns) between the two signals");
 
 4564                        "Dropping of unsolicited HE TB PPDUs");
 
 4576                 WifiPhyState::CCA_BUSY);
 
 4584                        "Dropping of HE TB PPDUs with channel width differing from TRIGVECTOR");
 
 4596                 WifiPhyState::CCA_BUSY,
 
 4605                        "Dropping of HE TB PPDUs with UL Length differing from TRIGVECTOR");
 
 4617                 WifiPhyState::CCA_BUSY,
 
 4626                        "Dropping of HE TB PPDUs with AIDs differing from TRIGVECTOR");
 
 4638                 WifiPhyState::CCA_BUSY,
 
 4649        "Reception of solicited HE TB PPDUs with interference on RU 1 during PSDU reception");
 
 4652    bandInfo.
fc = 
MHzToHz(m_frequency - (m_channelWidth / 4));
 
 4653    bandInfo.
fl = bandInfo.
fc - 
MHzToHz(m_channelWidth / 4);
 
 4654    bandInfo.
fh = bandInfo.
fc + 
MHzToHz(m_channelWidth / 4);
 
 4656    bands.push_back(bandInfo);
 
 4660    Watt_u interferencePower{0.1};
 
 4661    *interferencePsdRu1 = interferencePower / (
MHzToHz(m_channelWidth / 2) * 20);
 
 4671        WifiPhyState::CCA_BUSY, 
 
 4688        "Reception of solicited HE TB PPDUs with interference on RU 2 during PSDU reception");
 
 4690    bandInfo.
fc = 
MHzToHz(m_frequency + (m_channelWidth / 4));
 
 4691    bandInfo.
fl = bandInfo.
fc - 
MHzToHz(m_channelWidth / 4);
 
 4692    bandInfo.
fh = bandInfo.
fc + 
MHzToHz(m_channelWidth / 4);
 
 4694    bands.push_back(bandInfo);
 
 4698    *interferencePsdRu2 = interferencePower / (
MHzToHz(m_channelWidth / 2) * 20);
 
 4707                 (m_channelWidth >= 
MHz_u{40})
 
 4708                     ? WifiPhyState::IDLE
 
 4709                     : WifiPhyState::CCA_BUSY, 
 
 4726                        "Reception of solicited HE TB PPDUs with interference on the full band " 
 4727                        "during PSDU reception");
 
 4730    bandInfo.
fl = bandInfo.
fc - 
MHzToHz(m_channelWidth / 2);
 
 4731    bandInfo.
fh = bandInfo.
fc + 
MHzToHz(m_channelWidth / 2);
 
 4733    bands.push_back(bandInfo);
 
 4737    *interferencePsdAll = interferencePower / (
MHzToHz(m_channelWidth) * 20);
 
 4747        WifiPhyState::CCA_BUSY, 
 
 4765                        "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU " 
 4766                        "1 during PSDU reception");
 
 4781    if (m_channelWidth > 
MHz_u{20})
 
 4799                 WifiPhyState::CCA_BUSY, 
 
 4817                        "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU " 
 4818                        "2 during PSDU reception");
 
 4830    if (m_channelWidth > 
MHz_u{20})
 
 4848                 (m_channelWidth >= 
MHz_u{40})
 
 4849                     ? WifiPhyState::IDLE
 
 4850                     : WifiPhyState::CCA_BUSY, 
 
 4868        "Reception of solicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
 
 4895                        "Reception of solicited HE TB PPDU only on RU 2");
 
 4902                        (m_channelWidth >= 
MHz_u{40})
 
 4903                            ? WifiPhyState::IDLE
 
 4904                            : WifiPhyState::CCA_BUSY); 
 
 4925                        "Measure power for reception of HE TB PPDU only on RU 2");
 
 4928    SchedulePowerMeasurementChecks(delay,
 
 4929                                   (m_channelWidth >= 
MHz_u{40}) ? 
Watt_u{0.0} : rxPower,
 
 4954        "Measure power for reception of HE TB PPDU only on RU 2 with PSD limitation");
 
 4963    rxPower = (m_channelWidth > 
MHz_u{40})
 
 4967    auto rxPowerOfdma = rxPower;
 
 4968    if (m_channelWidth <= 
MHz_u{40})
 
 4971            (m_channelWidth == 
MHz_u{20})
 
 4975    SchedulePowerMeasurementChecks(delay,
 
 4976                                   (m_channelWidth >= 
MHz_u{40}) ? 
Watt_u{0.0} : rxPower,
 
 5006                        "Measure power for reception of HE TB PPDU on both RUs");
 
 5009    const auto rxPowerNonOfdma =
 
 5010        (m_channelWidth >= 
MHz_u{40})
 
 5013    SchedulePowerMeasurementChecks(delay, rxPowerNonOfdma, rxPowerNonOfdma, rxPower, rxPower);
 
 5031                        "Reception of an HE TB PPDU from another BSS");
 
 5065        "Reception of solicited HE TB PPDUs with delay (< 400ns) between the two signals and " 
 5066        "reception of an HE TB PPDU from another BSS between the ends of the two HE TB PPDUs");
 
 5083                 WifiPhyState::CCA_BUSY,
 
 
 5097template <
typename LatestPhyEntityType>
 
 5101    m_frequency = 
MHz_u{5955};
 
 5102    m_channelWidth = 
MHz_u{20};
 
 5106    m_frequency = 
MHz_u{5965};
 
 5107    m_channelWidth = 
MHz_u{40};
 
 5111    m_frequency = 
MHz_u{5985};
 
 5112    m_channelWidth = 
MHz_u{80};
 
 5116    m_frequency = 
MHz_u{6025};
 
 5117    m_channelWidth = 
MHz_u{160};
 
 5123        m_frequency = 
MHz_u{6105};
 
 5124        m_channelWidth = 
MHz_u{320};
 
 
 5147    void DoRun() 
override;
 
 5156    void SendTbPpdu(uint16_t txStaId, std::size_t index, std::size_t payloadSize, 
Time txDuration);
 
 5229                   const std::vector<bool>& statusPerMpdu);
 
 
 5252    : 
TestCase(
"PHY padding exclusion test"),
 
 5253      m_countRxSuccessFromSta1(0),
 
 5254      m_countRxSuccessFromSta2(0),
 
 5255      m_countRxFailureFromSta1(0),
 
 5256      m_countRxFailureFromSta2(0),
 
 5257      m_countRxBytesFromSta1(0),
 
 5258      m_countRxBytesFromSta2(0)
 
 
 5265                                    std::size_t payloadSize,
 
 5283    txVector.SetRu(ru, txStaId);
 
 5285    txVector.SetNss(1, txStaId);
 
 5292    std::ostringstream addr;
 
 5293    addr << 
"00:00:00:00:00:0" << txStaId;
 
 5297    psdus.insert(std::make_pair(txStaId, psdu));
 
 5304    else if (txStaId == 2)
 
 5313    phy->Send(psdus, txVector);
 
 
 5339                                   const std::vector<bool>& )
 
 5341    NS_LOG_FUNCTION(
this << *psdu << psdu->GetAddr2() << rxSignalInfo << txVector);
 
 5342    if (psdu->GetAddr2() == 
Mac48Address(
"00:00:00:00:00:01"))
 
 5347    else if (psdu->GetAddr2() == 
Mac48Address(
"00:00:00:00:00:02"))
 
 
 5358    if (psdu->GetAddr2() == 
Mac48Address(
"00:00:00:00:00:01"))
 
 5362    else if (psdu->GetAddr2() == 
Mac48Address(
"00:00:00:00:00:02"))
 
 
 5375                          "The number of successfully received packets from STA 1 is not correct!");
 
 5379        "The number of unsuccessfully received packets from STA 1 is not correct!");
 
 5382                          "The number of bytes received from STA 1 is not correct!");
 
 
 5392                          "The number of successfully received packets from STA 2 is not correct!");
 
 5396        "The number of unsuccessfully received packets from STA 2 is not correct!");
 
 5399                          "The number of bytes received from STA 2 is not correct!");
 
 
 5407                          "m_currentEvent for AP was not cleared");
 
 5410                          "m_currentEvent for STA 1 was not cleared");
 
 5413                          "m_currentEvent for STA 2 was not cleared");
 
 
 5429    WifiPhyState currentState = phy->GetState()->GetState();
 
 5433                          "PHY State " << currentState << 
" does not match expected state " 
 
 5456    int64_t streamNumber = 0;
 
 5461    spectrumChannel->AddPropagationLossModel(lossModel);
 
 5464    spectrumChannel->SetPropagationDelayModel(delayModel);
 
 5471    apMac->SetAttribute(
"BeaconGeneration", 
BooleanValue(
false));
 
 5472    apDev->SetMac(apMac);
 
 5475    apDev->SetHeConfiguration(heConfiguration);
 
 5477    m_phyAp->SetInterferenceHelper(apInterferenceHelper);
 
 5479    m_phyAp->SetErrorRateModel(apErrorModel);
 
 5481    m_phyAp->AddChannel(spectrumChannel);
 
 5483    m_phyAp->AssignStreams(streamNumber);
 
 5496    m_phyAp->SetMobility(apMobility);
 
 5500    apMac->SetWifiPhys({
m_phyAp});
 
 5501    apNode->AggregateObject(apMobility);
 
 5502    apNode->AddDevice(apDev);
 
 5508    m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
 
 5510    m_phySta1->SetErrorRateModel(sta1ErrorModel);
 
 5522    sta1Node->AggregateObject(sta1Mobility);
 
 5523    sta1Node->AddDevice(sta1Dev);
 
 5529    m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
 
 5531    m_phySta2->SetErrorRateModel(sta2ErrorModel);
 
 5543    sta2Node->AggregateObject(sta2Mobility);
 
 5544    sta2Node->AddDevice(sta2Dev);
 
 5552    interfererNode->AddDevice(interfererDev);
 
 
 5582    trigVector.SetRu(
HeRu::RuSpec(RuType::RU_106_TONE, 1, 
false), 1);
 
 5584    trigVector.SetNss(1, 1);
 
 5585    trigVector.SetRu(
HeRu::RuSpec(RuType::RU_106_TONE, 2, 
false), 2);
 
 5587    trigVector.SetNss(1, 2);
 
 5589    std::tie(length, ppduDuration) =
 
 5591    trigVector.SetLength(length);
 
 5593    hePhyAp->SetTrigVector(trigVector, ppduDuration);
 
 
 5600    Time ppduWithPaddingDuration =
 
 5601        expectedPpduDuration + 10 * 
NanoSeconds(12800 + 1600 ); 
 
 5612                        ppduWithPaddingDuration);
 
 5619                        ppduWithPaddingDuration);
 
 5625                        ppduWithPaddingDuration);
 
 5637                        WifiPhyState::IDLE);
 
 5655                        ppduWithPaddingDuration);
 
 5662                        ppduWithPaddingDuration);
 
 5668                        ppduWithPaddingDuration);
 
 5676    bands.push_back(bandInfo);
 
 5680    Watt_u interferencePower{0.1};
 
 5700                        WifiPhyState::CCA_BUSY);
 
 
 5732    void DoRun() 
override;
 
 5739    void SendMuBar(std::vector<uint16_t> staIds);
 
 5755    void RunOne(
bool setupBa);
 
 5775                               const std::vector<bool>& statusPerMpdu);
 
 
 5800    : 
TestCase(
"UL-OFDMA power control test"),
 
 5802      m_txPowerAp(
dBm_u{0}),
 
 5803      m_txPowerStart(
dBm_u{0}),
 
 5804      m_txPowerEnd(
dBm_u{0}),
 
 5806      m_requestedRssiSta1(
dBm_u{0}),
 
 5807      m_requestedRssiSta2(
dBm_u{0}),
 
 5808      m_rssiSta1(
dBm_u{0}),
 
 5809      m_rssiSta2(
dBm_u{0}),
 
 
 5827    m_apDev->Send(pkt, destination, 0);
 
 
 5833    NS_ASSERT(!staIds.empty() && staIds.size() <= 2);
 
 5837    muBar.
SetType(TriggerFrameType::MU_BAR_TRIGGER);
 
 5845    RuType ru = (staIds.size() == 1) ? RuType::RU_242_TONE : RuType::RU_106_TONE;
 
 5846    std::size_t index = 1;
 
 5847    int8_t ulTargetRssi = -40; 
 
 5848    for (
const auto& staId : staIds)
 
 5861        else if (staId == 2)
 
 5901    bar->AddHeader(muBar);
 
 5904    if (staIds.size() == 1)
 
 5907        if (staIds.front() == aidSta1)
 
 5930    auto nav = 
m_apDev->GetPhy()->GetSifs();
 
 5931    const auto staId = staIds.front(); 
 
 5936    psdu->SetDuration(nav);
 
 5937    psdus.insert(std::make_pair(
SU_STA_ID, psdu));
 
 5939    m_phyAp->Send(psdus, txVector);
 
 
 5946                                               const std::vector<bool>& )
 
 5949    const auto rssi = rxSignalInfo.
rssi;
 
 5951    const auto& hdr = psdu->GetHeader(0);
 
 5953    if (hdr.GetAddr2() == 
m_sta1Dev->GetAddress())
 
 5959            "The obtained RSSI from STA 1 at AP is different from the expected one (" 
 5960                << rssi << 
" vs " << 
m_rssiSta1 << 
", with tolerance of " << 
m_tol << 
")");
 
 5962    else if (psdu->GetAddr2() == 
m_sta2Dev->GetAddress())
 
 5968            "The obtained RSSI from STA 2 at AP is different from the expected one (" 
 5969                << rssi << 
" vs " << 
m_rssiSta2 << 
", with tolerance of " << 
m_tol << 
")");
 
 
 5981    m_phyAp->SetReceiveOkCallback(
 
 
 5994    spectrumChannel->AddPropagationLossModel(lossModel);
 
 5996    spectrumChannel->SetPropagationDelayModel(delayModel);
 
 6001    spectrumPhy.
Set(
"ChannelSettings", 
StringValue(
"{0, 0, BAND_5GHZ, 0}"));
 
 6005    wifi.SetRemoteStationManager(
"ns3::ConstantRateWifiManager",
 
 6012    mac.SetType(
"ns3::StaWifiMac");
 
 6013    auto staDevs = wifi.Install(spectrumPhy, mac, staNodes);
 
 6023    mac.SetType(
"ns3::ApWifiMac",
 
 6037    mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
 
 6039    positionAlloc->Add(Vector(0.0, 0.0, 0.0));
 
 6040    positionAlloc->Add(Vector(1.0, 0.0, 0.0)); 
 
 6042        Vector(2.0, 0.0, 0.0)); 
 
 6043    mobility.SetPositionAllocator(positionAlloc);
 
 6045    mobility.Install(apNode);
 
 6046    mobility.Install(staNodes);
 
 6048    lossModel->SetDefaultLoss(50.0);
 
 
 6073    int64_t streamNumber = 0;
 
 6078    m_phyAp->AssignStreams(streamNumber);
 
 6079    phySta1->AssignStreams(streamNumber);
 
 6080    phySta2->AssignStreams(streamNumber);
 
 6094    Time relativeStart{};
 
 6113        apMac->SetAttribute(
"BeaconGeneration", 
BooleanValue(
false));
 
 6122        std::vector<uint16_t> staIds{1};
 
 6128        std::vector<uint16_t> staIds{2};
 
 6137        std::vector<uint16_t> staIds{1, 2};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
SpectrumWifiPhy used for testing OFDMA.
Ptr< Event > GetCurrentEvent()
void SetTriggerFrameUid(uint64_t uid)
Since we assume trigger frame was previously received from AP, this is used to set its UID.
TracedCallback< uint64_t > m_phyTxPpduUidTrace
Callback providing UID of the PPDU that is about to be transmitted.
Ptr< LatestPhyEntityType > GetPhyEntity() const
static TypeId GetTypeId()
Get the type ID.
Ptr< OfdmaTestPhy< LatestPhyEntityType > > m_ofdmaTestPhy
Pointer to latest PHY entity instance used for OFDMA test.
std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > & GetCurrentPreambleEvents()
void DoDispose() override
Destructor implementation.
Time GetEnergyDuration(Watt_u energy, WifiSpectrumBandInfo band)
Wrapper to InterferenceHelper method.
void SetPpduUid(uint64_t uid)
Set the global PPDU UID counter.
void(* TxPpduUidCallback)(uint64_t uid)
TracedCallback signature for UID of transmitted PPDU.
void DoInitialize() override
Initialize() implementation.
OfdmaSpectrumWifiPhy(uint16_t staId)
Constructor.
void StartTx(Ptr< const WifiPpdu > ppdu) override
PHY entity slightly modified so as to return a given STA-ID in case of DL MU for OfdmaSpectrumWifiPhy...
void SetGlobalPpduUid(uint64_t uid)
Set the global PPDU UID counter.
uint16_t m_staId
ID of the STA to which this PHY belongs to.
uint16_t GetStaId(const Ptr< const WifiPpdu > ppdu) const override
Return the STA ID that has been assigned to the station this PHY belongs to.
WifiSpectrumBandInfo GetNonOfdmaBand(const WifiTxVector &txVector, uint16_t staId) const
Get the band used to transmit the non-OFDMA part of an HE TB PPDU.
OfdmaTestPhy(uint16_t staId)
Constructor.
PHY listener for OFDMA tests.
OfdmaTestPhyListener()=default
bool m_lastRxSuccess
flag whether last RX has been successful
void NotifyRxStart(Time duration) override
Time GetLastRxStartNotification() const
Return the time at which the last RX start notification has been received.
void NotifySwitchingStart(Time duration) override
void NotifyWakeup() override
Notify listeners that we woke up.
uint32_t m_notifyRxStart
count number of RX start notifications
void Reset()
Reset function.
Time m_lastRxEnd
last time a RX end notification has been received
Time m_lastRxStart
last time a RX start notification has been received
Time GetLastRxEndNotification() const
Return the time at which the last RX end notification has been received.
void NotifyCcaBusyStart(Time duration, WifiChannelListType channelType, const std::vector< Time > &) override
uint32_t m_notifyRxEnd
count number of RX end notifications
bool IsLastRxSuccess() const
Return whether last RX has been successful.
void NotifySleep() override
Notify listeners that we went to sleep.
uint32_t GetNumRxEndNotifications() const
Return the number of RX end notifications that has been received since the last reset.
void NotifyRxEndOk() override
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void NotifyTxStart(Time duration, dBm_u txPower) override
uint32_t GetNumRxStartNotifications() const
Return the number of RX start notifications that has been received since the last reset.
void NotifyRxEndError(const WifiTxVector &txVector) override
void NotifyOff() override
Notify listeners that we went to switch off.
void NotifyOn() override
Notify listeners that we went to switch on.
DL-OFDMA PHY puncturing test.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
uint32_t m_countRxBytesSta1
count RX bytes for STA 1
uint32_t m_countRxBytesSta2
count RX bytes for STA 2
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
void DoRun() override
Implementation to actually run this TestCase.
TestDlOfdmaPhyPuncturing()
Time m_expectedPpduDuration20Mhz
expected duration to send MU PPDU on 20 MHz RU
void CheckResultsSta1(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 1.
void ResetResults()
Reset the results.
uint32_t m_countRxSuccessSta2
count RX success for STA 2
void RunOne()
Run one function.
void DoCheckPhyState(Ptr< OfdmaSpectrumWifiPhy< HePhy > > phy, WifiPhyState expectedState)
Check the PHY state now.
void RxFailureSta1(Ptr< const WifiPsdu > psdu)
Receive failure function for STA 1.
uint32_t m_countRxFailureSta2
count RX failure for STA 2
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void SendMuPpdu(uint16_t rxStaId1, uint16_t rxStaId2, const std::vector< bool > &puncturedSubchannels)
Send MU-PPDU function.
uint32_t m_countRxFailureSta1
count RX failure for STA 1
void RxSuccessSta2(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function for STA 2.
Time m_expectedPpduDuration40Mhz
expected duration to send MU PPDU on 40 MHz RU
void CheckResultsSta2(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 2.
MHz_u m_frequency
frequency
MHz_u m_channelWidth
channel width
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phySta2
PHY of STA 2.
void RxFailureSta2(Ptr< const WifiPsdu > psdu)
Receive failure function for STA 2.
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phySta1
PHY of STA 1.
void StopInterference()
Stop interference function.
void RxSuccessSta1(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function for STA 1.
uint8_t m_indexSubchannel
Index of the subchannel (starting from 0) that should contain an interference and be punctured during...
uint32_t m_countRxSuccessSta1
count RX success for STA 1
void CheckPhyState(Ptr< OfdmaSpectrumWifiPhy< HePhy > > phy, WifiPhyState expectedState)
Schedule now to check the PHY state.
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > m_phySta1
PHY of STA 1.
uint32_t m_countRxSuccessSta3
count RX success for STA 3
uint32_t m_countRxBytesSta3
count RX bytes for STA 3
void DoRun() override
Implementation to actually run this TestCase.
Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > m_phySta3
PHY of STA 3.
void StopInterference()
Stop interference function.
void CheckResultsSta1(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 1.
void RxFailureSta3(Ptr< const WifiPsdu > psdu)
Receive failure function for STA 3.
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
void RxFailureSta2(Ptr< const WifiPsdu > psdu)
Receive failure function for STA 2.
void RunOne()
Run one function.
uint32_t m_countRxFailureSta3
count RX failure for STA 3
uint32_t m_countRxBytesSta2
count RX bytes for STA 2
TestDlOfdmaPhyTransmission()
Constructor.
void ResetResults()
Reset the results.
Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > m_phySta2
PHY of STA 2.
void RxSuccessSta3(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function for STA 3.
void CheckPhyState(Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > phy, WifiPhyState expectedState)
Schedule now to check the PHY state.
MHz_u m_frequency
frequency
uint32_t m_countRxBytesSta1
count RX bytes for STA 1
void CheckResultsSta2(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 2.
void RxSuccessSta1(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function for STA 1.
Time m_expectedPpduDuration
expected duration to send MU PPDU
void RxFailureSta1(Ptr< const WifiPsdu > psdu)
Receive failure function for STA 1.
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
MHz_u m_channelWidth
channel width
void CheckResultsSta3(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 3.
uint32_t m_countRxFailureSta1
count RX failure for STA 1
void DoCheckPhyState(Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > phy, WifiPhyState expectedState)
Check the PHY state now.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
uint32_t m_countRxSuccessSta2
count RX success for STA 2
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
WifiModulationClass m_modClass
the modulation class to consider for the test
uint32_t m_countRxFailureSta2
count RX failure for STA 2
void RxSuccessSta2(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function for STA 2.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void SendMuPpdu(uint16_t rxStaId1, uint16_t rxStaId2)
Send MU-PPDU function.
uint32_t m_countRxSuccessSta1
count RX success for STA 1
UL-OFDMA multiple RX events test.
WifiTxVector m_trigVector
TRIGVECTOR.
void RxHeTbPpdu(uint64_t uid, uint16_t staId, Watt_u txPower, size_t payloadSize)
Receive HE TB PPDU function.
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phy
Phy.
void Reset()
Reset function.
~TestMultipleHeTbPreambles() override
void RxHeTbPpduOfdmaPart(Ptr< WifiSpectrumSignalParameters > rxParamsOfdma)
Receive OFDMA part of HE TB PPDU function.
void CheckHeTbPreambles(size_t nEvents, std::vector< uint64_t > uids)
Check the received HE TB preambles.
TestMultipleHeTbPreambles()
uint64_t m_totalBytesDropped
total number of dropped bytes
void CheckBytesDropped(size_t expectedBytesDropped)
Check the number of bytes dropped.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void DoRxHeTbPpduOfdmaPart(Ptr< WifiSpectrumSignalParameters > rxParamsOfdma)
Receive OFDMA part of HE TB PPDU function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
PHY padding exclusion test.
void DoCheckPhyState(Ptr< OfdmaSpectrumWifiPhy< HePhy > > phy, WifiPhyState expectedState)
Check the PHY state.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void CheckRxFromSta1(uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
Check the received PSDUs from STA1.
void VerifyEventsCleared()
Verify all events are cleared at end of TX or RX.
TestPhyPaddingExclusion()
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
~TestPhyPaddingExclusion() override
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
uint32_t m_countRxSuccessFromSta2
count RX success from STA 2
void DoRun() override
Implementation to actually run this TestCase.
void SendTbPpdu(uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration)
Send HE TB PPDU function.
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phySta1
PHY of STA 1.
void RxFailure(Ptr< const WifiPsdu > psdu)
Receive failure function.
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phySta2
PHY of STA 2.
uint32_t m_countRxBytesFromSta1
count RX bytes from STA 1
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function.
void SetTrigVector(Time ppduDuration)
Set TRIGVECTOR for HE TB PPDU.
void Reset()
Reset function.
uint32_t m_countRxFailureFromSta1
count RX failure from STA 1
uint32_t m_countRxSuccessFromSta1
count RX success from STA 1
void StopInterference()
Stop interference function.
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phyAp
PHY of AP.
void RunOne()
Run one function.
void CheckRxFromSta2(uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
Check the received PSDUs from STA2.
uint32_t m_countRxFailureFromSta2
count RX failure from STA 2
uint32_t m_countRxBytesFromSta2
count RX bytes from STA 2
void CheckPhyState(Ptr< OfdmaSpectrumWifiPhy< HePhy > > phy, WifiPhyState expectedState)
Check the PHY state.
void SetPsdLimit(Ptr< WifiPhy > phy, dBm_per_MHz_u psdLimit)
Set the PSD limit.
void StopInterference()
Stop interference function.
Time m_expectedPpduDuration
expected duration to send MU PPDU
Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > m_phySta2
PHY of STA 2.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function.
void RunOne()
Run one function.
void DoCheckPhyState(Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > phy, WifiPhyState expectedState)
Check the PHY state.
void CheckApRxEnd(uint32_t expectedNotifications, Time expectedLastNotification, bool expectedSuccess)
Check the the number of RX end notifications at the AP as well as the last time a RX end has been not...
uint32_t m_countRxSuccessFromSta1
count RX success from STA 1
uint32_t m_countRxFailureFromSta2
count RX failure from STA 2
uint32_t m_countRxSuccessFromSta2
count RX success from STA 2
uint32_t m_countRxBytesFromSta1
count RX bytes from STA 1
WifiTxVector GetTxVectorForTbPpdu(uint16_t txStaId, std::size_t index, uint8_t bssColor) const
Get TXVECTOR for HE PPDU.
Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > m_phySta3
PHY of STA 3.
Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > m_phySta1
PHY of STA 1.
void SchedulePowerMeasurementChecks(Time delay, Watt_u rxPowerNonOfdmaRu1, Watt_u rxPowerNonOfdmaRu2, Watt_u rxPowerOfdmaRu1, Watt_u rxPowerOfdmaRu2)
Schedule power measurement related checks.
void SendTbPpdu(uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor, bool incrementUid)
Send HE TB PPDU function.
void CheckPhyState(Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > phy, WifiPhyState expectedState)
Check the PHY state.
TrigVectorInfo
Erroneous info included in a TRIGVECTOR.
void CheckNonOfdmaRxPower(Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > phy, WifiSpectrumBandInfo band, Watt_u expectedRxPower)
Check the received power for the non-OFDMA of the HE TB PPDUs over the given band.
void Reset()
Reset function.
void CheckOfdmaRxPower(Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > phy, WifiSpectrumBandInfo band, Watt_u expectedRxPower)
Check the received power for the OFDMA part of the HE TB PPDUs over the given band.
WifiModulationClass m_modClass
the modulation class to consider for the test
void CheckRxFromSta1(uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
Check the received PSDUs from STA1.
uint32_t m_countRxFailureFromSta1
count RX failure from STA 1
TestUlOfdmaPhyTransmission()
void RxFailure(Ptr< const WifiPsdu > psdu)
Receive failure function.
void CheckApRxStart(uint32_t expectedNotifications, Time expectedLastNotification)
Check the the number of RX start notifications at the AP as well as the last time a RX start has been...
void DoRun() override
Implementation to actually run this TestCase.
void LogScenario(std::string log) const
Log scenario description.
void ScheduleTest(Time delay, bool solicited, WifiPhyState expectedStateAtEnd, uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1, uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2, bool scheduleTxSta1=true, Time ulTimeDifference=Seconds(0), WifiPhyState expectedStateBeforeEnd=WifiPhyState::RX, TrigVectorInfo error=NONE)
Schedule test to perform.
void CheckRxFromSta2(uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
Check the received PSDUs from STA2.
MHz_u m_frequency
frequency
Ptr< OfdmaSpectrumWifiPhy< LatestPhyEntityType > > m_phyAp
PHY of AP.
MHz_u m_channelWidth
channel width
void VerifyEventsCleared()
Verify all events are cleared at end of TX or RX.
void SendSuPpdu(uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
Send HE SU PPDU function.
std::shared_ptr< OfdmaTestPhyListener > m_apPhyStateListener
listener for AP PHY state transitions
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
uint32_t m_countRxBytesFromSta2
count RX bytes from STA 2
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void SetBssColor(Ptr< WifiPhy > phy, uint8_t bssColor)
Set the BSS color.
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
void SetTrigVector(uint8_t bssColor, TrigVectorInfo error)
Set TRIGVECTOR for HE TB PPDU.
UL-OFDMA power control test.
dBm_u m_requestedRssiSta2
requested RSSI from STA 2 at AP for HE TB PPDUs
void DoRun() override
Implementation to actually run this TestCase.
Ptr< WifiNetDevice > m_sta2Dev
network device of STA 2
dBm_u m_rssiSta2
expected RSSI from STA 2 at AP for HE TB PPDUs
dBm_u m_txPowerEnd
maximum transmission power for STAs
dBm_u m_txPowerStart
minimum transmission power for STAs
void SetupBa(Address destination)
Send a QoS Data packet to the destination station in order to set up a block Ack session (so that the...
Ptr< WifiNetDevice > m_sta1Dev
network device of STA 1
dBm_u m_rssiSta1
expected RSSI from STA 1 at AP for HE TB PPDUs
Ptr< WifiNetDevice > m_apDev
network device of AP
dBm_u m_requestedRssiSta1
requested RSSI from STA 1 at AP for HE TB PPDUs
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
uint8_t m_bssColor
BSS color.
void ReplaceReceiveOkCallbackOfAp()
Replace the AP's callback on its PHY's ReceiveOkCallback by the ReceiveOkCallbackAtAp method.
dBm_u m_txPowerAp
transmit power of AP
uint8_t m_txPowerLevels
number of transmission power levels for STAs
dB_u m_tol
tolerance between received and expected RSSIs
TestUlOfdmaPowerControl()
void RunOne(bool setupBa)
Run one simulation with an optional BA session set up phase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
void ReceiveOkCallbackAtAp(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive OK callback function at AP.
~TestUlOfdmaPowerControl() override
void SendMuBar(std::vector< uint16_t > staIds)
Send a MU BAR through the AP to the STAs listed in the provided vector.
UL-OFDMA PPDU UID attribution test.
~TestUlOfdmaPpduUid() override
void TxPpduSta1(uint64_t uid)
Transmitted PPDU information function for STA 1.
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phyAp
PHY of AP.
void ResetPpduUid()
Reset the global PPDU UID counter in WifiPhy.
void CheckUid(uint16_t staId, uint64_t expectedUid)
Check the UID of the transmitted PPDU.
void TxPpduAp(uint64_t uid)
Transmitted PPDU information function for AP.
void TxPpduSta2(uint64_t uid)
Transmitted PPDU information function for STA 2.
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phySta1
PHY of STA 1.
uint64_t m_ppduUidAp
UID of PPDU transmitted by AP.
uint64_t m_ppduUidSta1
UID of PPDU transmitted by STA1.
uint64_t m_ppduUidSta2
UID of PPDU transmitted by STA2.
void DoRun() override
Implementation to actually run this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Ptr< OfdmaSpectrumWifiPhy< HePhy > > m_phySta2
PHY of STA 2.
void SendMuPpdu()
Send MU-PPDU toward both STAs.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void SendTbPpdu()
Send TB-PPDU from both STAs.
void SendSuPpdu(uint16_t txStaId)
Send SU-PPDU function.
wifi PHY OFDMA Test Suite
a polymophic address class
AttributeValue implementation for Boolean.
User Info field of Trigger frames.
void SetAid12(uint16_t aid)
Set the AID12 subfield, which carries the 12 LSBs of the AID of the station for which this User Info ...
void SetUlFecCodingType(bool ldpc)
Set the UL FEC Coding Type subfield, which indicates whether BCC or LDPC is used.
void SetUlMcs(uint8_t mcs)
Set the UL MCS subfield, which indicates the MCS of the solicited HE TB PPDU.
void SetMuBarTriggerDepUserInfo(const CtrlBAckRequestHeader &bar)
Set the Trigger Dependent User Info subfield for the MU-BAR variant of Trigger frames,...
void SetUlDcm(bool dcm)
Set the UL DCM subfield, which indicates whether or not DCM is used.
void SetSsAllocation(uint8_t startingSs, uint8_t nSs)
Set the SS Allocation subfield, which is present when the AID12 subfield is neither 0 nor 2045.
void SetUlTargetRssi(int8_t dBm)
Set the UL Target RSSI subfield to indicate the expected receive signal power in dBm.
void SetRuAllocation(WifiRu::RuSpec ru)
Set the RU Allocation subfield according to the specified RU.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
static WifiMode GetEhtMcs7()
Return MCS 7 from EHT MCS values.
static WifiMode GetEhtMcs9()
Return MCS 9 from EHT MCS values.
static std::pair< bool, bool > GetPrimaryFlags(MHz_u bw, RuType ruType, std::size_t phyIndex, uint8_t p20Index)
Get the primary flags of a given RU transmitted in a PPDU.
static std::size_t GetIndexIn80MHzSegment(MHz_u bw, RuType ruType, std::size_t phyIndex)
Get the index of a given RU transmitted in a PPDU within its 80 MHz segment.
static WifiMode GetHeMcs9()
Return MCS 9 from HE MCS values.
static WifiMode GetHeMcs7()
Return MCS 7 from HE MCS values.
static std::pair< uint16_t, Time > ConvertHeTbPpduDurationToLSigLength(Time ppduDuration, const WifiTxVector &txVector, WifiPhyBand band)
Compute the L-SIG length value corresponding to the given HE TB PPDU duration.
@ PSD_HE_PORTION
HE portion of an HE PPDU.
@ PSD_NON_HE_PORTION
Non-HE portion of an HE PPDU.
static std::size_t GetIndexIn80MHzSegment(MHz_u bw, RuType ruType, std::size_t phyIndex)
Get the index of a given RU transmitted in a PPDU within its 80 MHz segment.
static bool GetPrimary80MHzFlag(MHz_u bw, RuType ruType, std::size_t phyIndex, uint8_t p20Index)
Get the primary 80 MHz flag of a given RU transmitted in a PPDU.
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
keep track of a set of node pointers.
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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
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 Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(const Ptr< SpectrumChannel > channel)
void DoInitialize() override
Initialize() implementation.
void DoDispose() override
Destructor implementation.
void StartTx(Ptr< const WifiPpdu > ppdu) override
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.
AttributeValue implementation for Time.
Forward calls to a chain of Callback.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
helps to create WifiNetDevice objects
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.
void Set(std::string name, const AttributeValue &v)
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
static Time GetPreambleDetectionDuration()
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
void Reset()
Reset data upon end of TX or RX.
receive notifications about PHY events.
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 objects implements the PHY state machine of the Wifi device.
std::variant< HeRu::RuSpec, EhtRu::RuSpec > RuSpec
variant of the RU specification
static RuSpec FindOverlappingRu(MHz_u bw, RuSpec referenceRu, RuType searchedRuType)
Find the RU allocation of the given RU type overlapping the given reference RU allocation.
static MHz_u GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
static RuType GetRuType(RuSpec ru)
Get the type of a given RU.
static SubcarrierGroup GetSubcarrierGroup(MHz_u bw, RuType ruType, std::size_t phyIndex, WifiModulationClass mc)
Get the subcarrier group of the RU having the given PHY index among all the RUs of the given type (nu...
static std::size_t GetPhyIndex(RuSpec ru, MHz_u bw, uint8_t p20Index)
Get the RU PHY index.
static Ptr< SpectrumValue > CreateHeMuOfdmTxPowerSpectralDensity(const std::vector< MHz_u > ¢erFrequencies, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, const std::vector< WifiSpectrumBandIndices > &ru)
Create a transmit power spectral density corresponding to the OFDMA part of HE TB PPDUs for a given R...
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(MHz_u centerFrequency, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=dBr_u{-20}, dBr_u minOuterband=dBr_u{-28}, dBr_u lowestPoint=dBr_u{-40}, const std::vector< bool > &puncturedSubchannels={})
Create a transmit power spectral density corresponding to OFDM High Efficiency (HE/EHT) (802....
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
void SetRu(WifiRu::RuSpec ru, uint16_t staId)
Set the RU specification for the STA-ID.
WifiPreamble GetPreambleType() const
const HeMuUserInfoMap & GetHeMuUserInfoMap() const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
void SetLength(uint16_t length)
Set the LENGTH field of the L-SIG.
MHz_u GetChannelWidth() const
WifiRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#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_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#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.
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_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
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.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPhyBand
Identifies the PHY band.
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyState
The state of the PHY layer.
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::string Demangle(const std::string &mangled)
std::vector< BandInfo > Bands
Container of BandInfo.
RuType
The different Resource Unit (RU) types.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
MHz_u GetMaximumChannelWidth(WifiModulationClass modulation)
Get the maximum channel width allowed for the given modulation class.
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
uint32_t GetBlockAckSize(BlockAckType type)
Return the total BlockAck size (including FCS trailer).
WifiModulationClass GetModulationClassForStandard(WifiStandard standard)
Return the modulation class corresponding to a given standard.
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)
std::vector< uint16_t > RuAllocation
9 bits RU_ALLOCATION per 20 MHz
static const MHz_u CHANNEL_WIDTH
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.
WifiSpectrumBandInfo structure containing info about a spectrum band.
std::vector< WifiSpectrumBandIndices > indices
the start and stop indices for each segment of the band
static const MHz_u DEFAULT_FREQUENCY
static WifiPhyOfdmaTestSuite wifiPhyOfdmaTestSuite
the test suite
static const uint8_t DEFAULT_CHANNEL_NUMBER
static const WifiPhyBand DEFAULT_WIFI_BAND
static const MHz_u DEFAULT_CHANNEL_WIDTH
static const MHz_u DEFAULT_GUARD_WIDTH