7#include "ns3/boolean.h"
8#include "ns3/constant-position-mobility-model.h"
9#include "ns3/eht-configuration.h"
10#include "ns3/eht-phy.h"
11#include "ns3/interference-helper.h"
13#include "ns3/mobility-helper.h"
14#include "ns3/multi-model-spectrum-channel.h"
15#include "ns3/nist-error-rate-model.h"
16#include "ns3/non-communicating-net-device.h"
17#include "ns3/ofdm-ppdu.h"
18#include "ns3/pointer.h"
19#include "ns3/spectrum-wifi-helper.h"
20#include "ns3/spectrum-wifi-phy.h"
21#include "ns3/string.h"
23#include "ns3/waveform-generator.h"
24#include "ns3/wifi-mac-header.h"
25#include "ns3/wifi-net-device.h"
26#include "ns3/wifi-phy-listener.h"
27#include "ns3/wifi-psdu.h"
28#include "ns3/wifi-spectrum-phy-interface.h"
29#include "ns3/wifi-spectrum-signal-parameters.h"
30#include "ns3/wifi-spectrum-value-helper.h"
31#include "ns3/wifi-utils.h"
81 return std::any_of(
m_rxing.cbegin(),
m_rxing.cend(), [](
const auto& rxing) {
93 bool IsBandTracked(
const std::vector<WifiSpectrumBandFrequencies>& startStopFreqs)
const
97 if (band.frequencies == startStopFreqs)
153 const std::vector<bool>& statusPerMpdu);
162 void DoRun()
override;
200 const auto txDuration =
201 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector,
m_phy->GetPhyBand());
211 txParams->psd = txPowerSpectrum;
212 txParams->txPhy =
nullptr;
213 txParams->duration = txDuration;
214 txParams->ppdu = ppdu;
230 const std::vector<bool>& statusPerMpdu)
257 m_phy->SetInterferenceHelper(interferenceHelper);
259 m_phy->SetErrorRateModel(error);
260 m_phy->SetDevice(dev);
261 m_phy->AddChannel(spectrumChannel);
264 m_phy->SetReceiveOkCallback(
266 m_phy->SetReceiveErrorCallback(
269 node->AddDevice(dev);
344 const std::vector<Time>& )
override
413 void DoRun()
override;
426 m_listener = std::make_shared<TestPhyListener>();
441 "Didn't receive NotifyCcaBusyStart (once preamble is detected + prolonged by L-SIG "
442 "reception, then switched to Rx by at the beginning of data)");
471 void DoRun()
override;
498 :
TestCase(
"SpectrumWifiPhy test RX filters"),
499 m_txChannelWidth(
MHz_u{20}),
500 m_rxChannelWidth(
MHz_u{20})
541 for (
const auto& [band, powerW] : rxPowersW)
544 "band: (" << band <<
") -> powerW=" << powerW
545 << (powerW > 0.0 ?
" (" + std::to_string(
WToDbm(powerW)) +
" dBm)" :
""));
548 size_t numBands = rxPowersW.size();
562 "Total number of bands handled by the receiver is incorrect");
566 auto it = rxPowersW.find(band);
567 NS_LOG_INFO(
"powerW total band: " << it->second <<
" (" <<
WToDbm(it->second) <<
" dBm)");
568 int totalRxPower =
static_cast<int>(
WToDbm(it->second) + 0.5);
569 int expectedTotalRxPower;
574 expectedTotalRxPower = 16;
579 expectedTotalRxPower =
583 expectedTotalRxPower,
584 "Total received power is not correct");
589 it = rxPowersW.find(band);
590 NS_LOG_INFO(
"powerW in primary 20 MHz channel: " << it->second <<
" (" <<
WToDbm(it->second)
592 const auto rxPowerPrimaryChannel20 =
static_cast<int>(
WToDbm(it->second) + 0.5);
593 const auto expectedRxPowerPrimaryChannel20 =
596 expectedRxPowerPrimaryChannel20,
597 "Received power in the primary 20 MHz band is not correct");
609 lossModel->SetFrequency(5.180e9);
610 spectrumChannel->AddPropagationLossModel(lossModel);
612 spectrumChannel->SetPropagationDelayModel(delayModel);
628 txNode->AggregateObject(apMobility);
629 txNode->AddDevice(txDev);
631 txDev->SetEhtConfiguration(txEhtConfiguration);
647 rxNode->AggregateObject(sta1Mobility);
648 rxNode->AddDevice(rxDev);
650 rxDev->SetEhtConfiguration(rxEhtConfiguration);
672 txFrequency =
MHz_u{5955};
675 txFrequency =
MHz_u{5965};
678 txFrequency =
MHz_u{5985};
681 txFrequency =
MHz_u{6025};
684 txFrequency =
MHz_u{6105};
701 rxFrequency =
MHz_u{5955};
704 rxFrequency =
MHz_u{5965};
707 rxFrequency =
MHz_u{5985};
710 rxFrequency =
MHz_u{6025};
713 rxFrequency =
MHz_u{6105};
763 void DoRun()
override;
774 void RunOne(
const std::vector<uint8_t>& channelNumberPerSegment,
777 const std::vector<WifiSpectrumBandIndices>& expectedIndices,
778 const std::vector<WifiSpectrumBandFrequencies>& expectedFrequencies);
784 :
TestCase(
"SpectrumWifiPhy test bands calculations")
796 lossModel->SetFrequency(5.180e9);
797 spectrumChannel->AddPropagationLossModel(lossModel);
799 spectrumChannel->SetPropagationDelayModel(delayModel);
805 m_phy->SetInterferenceHelper(interferenceHelper);
807 m_phy->SetErrorRateModel(errorModel);
808 m_phy->SetDevice(dev);
809 m_phy->AddChannel(spectrumChannel);
812 node->AddDevice(dev);
824 const std::vector<uint8_t>& channelNumberPerSegment,
827 const std::vector<WifiSpectrumBandIndices>& expectedIndices,
828 const std::vector<WifiSpectrumBandFrequencies>& expectedFrequencies)
831 for (
auto channelNumber : channelNumberPerSegment)
838 channelSegments.emplace_back(channelInfo->number, channelInfo->width, channelInfo->band, 0);
840 m_phy->SetOperatingChannel(channelSegments);
842 const auto& bandInfo =
m_phy->GetBand(bandWidth, bandIndex);
843 NS_ASSERT(expectedIndices.size() == expectedFrequencies.size());
844 NS_ASSERT(expectedIndices.size() == bandInfo.indices.size());
845 NS_ASSERT(expectedFrequencies.size() == bandInfo.frequencies.size());
846 for (std::size_t i = 0; i < expectedIndices.size(); ++i)
848 NS_ASSERT(bandInfo.indices.at(i).first == expectedIndices.at(i).first);
850 expectedIndices.at(i).first,
851 "Incorrect start indice for segment " << i);
853 expectedIndices.at(i).second,
854 "Incorrect stop indice for segment " << i);
856 expectedFrequencies.at(i).first,
857 "Incorrect start frequency for segment " << i);
859 expectedFrequencies.at(i).second,
860 "Incorrect stop frequency for segment " << i);
867 const uint32_t indicesPer20MhzBand = 256;
868 const MHz_u channelWidth{160};
869 const uint8_t channelNumberContiguous160Mhz =
871 const std::vector<uint8_t> channelNumberPerSegment = {42,
874 const MHz_u separationWidth{240};
875 for (
bool contiguous160Mhz : {
true ,
false })
877 const auto guardWidth = contiguous160Mhz ? channelWidth : (channelWidth / 2);
879 std::vector<WifiSpectrumBandIndices> previousExpectedIndices{};
880 std::vector<WifiSpectrumBandFrequencies> previousExpectedFrequencies{};
883 const uint32_t expectedStartIndice = guardStopIndice + 1;
886 std::vector<WifiSpectrumBandIndices> expectedIndices{
887 {expectedStartIndice, expectedStopIndice}};
889 const Hz_u expectedStopFrequency =
MHzToHz(5170 + bandWidth);
890 std::vector<WifiSpectrumBandFrequencies> expectedFrequencies{
891 {expectedStartFrequency, expectedStopFrequency}};
892 const std::size_t numBands = (channelWidth / bandWidth);
893 for (std::size_t i = 0; i < numBands; ++i)
895 if ((bandWidth != channelWidth) && (i >= (numBands / 2)))
898 expectedIndices.at(0).first++;
900 if ((bandWidth == channelWidth) && !contiguous160Mhz)
904 expectedIndices = previousExpectedIndices;
905 expectedFrequencies = previousExpectedFrequencies;
907 else if ((i == (numBands / 2)) && !contiguous160Mhz)
909 expectedIndices.at(0).first +=
911 expectedIndices.at(0).second +=
913 expectedFrequencies.at(0).first +=
MHzToHz(separationWidth);
914 expectedFrequencies.at(0).second +=
MHzToHz(separationWidth);
916 RunOne(contiguous160Mhz ? std::vector<uint8_t>{channelNumberContiguous160Mhz}
917 : channelNumberPerSegment,
921 expectedFrequencies);
922 if (!contiguous160Mhz && (bandWidth == (channelWidth / 2)))
924 previousExpectedIndices.emplace_back(expectedIndices.front());
925 previousExpectedFrequencies.emplace_back(expectedFrequencies.front());
927 expectedIndices.at(0).first = expectedIndices.at(0).second + 1;
928 expectedIndices.at(0).second =
929 expectedIndices.at(0).first +
931 expectedFrequencies.at(0).first +=
MHzToHz(bandWidth);
932 expectedFrequencies.at(0).second +=
MHzToHz(bandWidth);
958 void DoRun()
override;
966 void SwitchChannel(
const std::vector<uint8_t>& channelNumberPerSegment);
977 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedTrackedBands,
978 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedUntrackedBands);
988 void RunOne(
const std::vector<uint8_t>& channelNumberPerSegmentBeforeSwitching,
989 const std::vector<uint8_t>& channelNumberPerSegmentAfterSwitching,
990 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedTrackedBands,
991 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedUntrackedBand);
997 :
TestCase(
"SpectrumWifiPhy test channel switching for non-contiguous operating channels")
1009 lossModel->SetFrequency(5.180e9);
1010 spectrumChannel->AddPropagationLossModel(lossModel);
1012 spectrumChannel->SetPropagationDelayModel(delayModel);
1025 node->AddDevice(dev);
1040 for (
auto channelNumber : channelNumberPerSegment)
1047 channelSegments.emplace_back(channelInfo->number, channelInfo->width, channelInfo->band, 0);
1054 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedTrackedBands,
1055 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedUntrackedBands)
1062 auto printBand = [](
const std::vector<WifiSpectrumBandFrequencies>& v) {
1063 std::stringstream ss;
1064 for (
const auto& [start, stop] : v)
1066 ss <<
"[" << start <<
"-" << stop <<
"] ";
1070 for (
const auto& expectedTrackedBand : expectedTrackedBands)
1072 auto bandTracked = interferenceHelper->IsBandTracked(expectedTrackedBand);
1075 "Band " << printBand(expectedTrackedBand) <<
" is not tracked");
1077 for (
const auto& expectedUntrackedBand : expectedUntrackedBands)
1079 auto bandTracked = interferenceHelper->IsBandTracked(expectedUntrackedBand);
1082 "Band " << printBand(expectedUntrackedBand)
1083 <<
" is unexpectedly tracked");
1089 const std::vector<uint8_t>& channelNumberPerSegmentBeforeSwitching,
1090 const std::vector<uint8_t>& channelNumberPerSegmentAfterSwitching,
1091 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedTrackedBands,
1092 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedUntrackedBands)
1099 channelNumberPerSegmentBeforeSwitching);
1104 channelNumberPerSegmentAfterSwitching);
1109 expectedTrackedBands,
1110 expectedUntrackedBands);
1209 void DoRun()
override;
1219 void RunOne(
const std::vector<uint8_t>& channelNumbers,
1220 MHz_u interferenceCenterFrequency,
1221 MHz_u interferenceBandWidth,
1222 bool expectSuccess);
1230 void SwitchChannel(
const std::vector<uint8_t>& channelNumbers);
1259 const std::vector<bool>& statusPerMpdu);
1283 :
TestCase(
"SpectrumWifiPhy test 80+80MHz transmission"),
1284 m_countRxSuccessSta(0),
1285 m_countRxFailureSta(0)
1294 for (
auto channelNumber : channelNumbers)
1301 channelSegments.emplace_back(channelInfo->number, channelInfo->width, channelInfo->band, 0);
1303 m_phyAp->SetOperatingChannel(channelSegments);
1304 m_phySta->SetOperatingChannel(channelSegments);
1329 m_phyAp->Send(psdu, txVector);
1351 const std::vector<bool>& )
1370 "Reception should be "
1371 << (expectSuccess ?
"successful" :
"unsuccessful"));
1382 spectrumChannel->AddPropagationLossModel(lossModel);
1384 spectrumChannel->SetPropagationDelayModel(delayModel);
1390 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
1392 m_phyAp->SetErrorRateModel(apErrorModel);
1394 m_phyAp->AddChannel(spectrumChannel);
1397 m_phyAp->SetMobility(apMobility);
1399 apNode->AggregateObject(apMobility);
1400 apNode->AddDevice(apDev);
1406 m_phySta->SetInterferenceHelper(staInterferenceHelper);
1408 m_phySta->SetErrorRateModel(staErrorModel);
1410 m_phySta->AddChannel(spectrumChannel);
1416 m_phySta->SetMobility(staMobility);
1418 staNode->AggregateObject(staMobility);
1419 staNode->AddDevice(staDev);
1427 interfererNode->AddDevice(interfererDev);
1443 MHz_u interferenceCenterFrequency,
1444 MHz_u interferenceBandWidth,
1457 BandInfo bandInfo{.
fl =
MHzToHz(interferenceCenterFrequency - (interferenceBandWidth / 2)),
1458 .fc =
MHzToHz(interferenceCenterFrequency),
1459 .fh =
MHzToHz(interferenceCenterFrequency + (interferenceBandWidth / 2))};
1462 Watt_u interferencePower{0.1};
1463 *interferencePsd = interferencePower / (interferenceBandWidth * 20e6);
1590 ChannelSwitchScenario chanSwitchScenario);
1595 void DoRun()
override;
1608 uint8_t channelNumber,
1610 std::optional<std::size_t> listenerIndex);
1643 const std::vector<bool>& statusPerMpdu);
1662 bool interferencesExpected);
1672 bool interferencesExpected);
1691 const std::vector<std::size_t>& expectedConnectedPhysPerChannel);
1703 bool expectedCcaBusyIndication,
1704 Time switchingDelay,
1705 Time propagationDelay);
1732 std::vector<uint32_t>
1734 std::vector<uint32_t>
1743 bool trackSignalsInactiveInterfaces,
1745 :
TestCase{
"SpectrumWifiPhy test operation with multiple RF interfaces"},
1746 m_trackSignalsInactiveInterfaces{trackSignalsInactiveInterfaces},
1747 m_chanSwitchScenario{chanSwitchScenario}
1754 uint8_t channelNumber,
1756 std::optional<std::size_t> listenerIndex)
1758 NS_LOG_FUNCTION(
this << phy << band << +channelNumber << channelWidth);
1762 listener->m_notifyMaybeCcaBusyStart = 0;
1763 listener->m_ccaBusyStart =
Seconds(0);
1764 listener->m_ccaBusyEnd =
Seconds(0);
1779 NS_LOG_FUNCTION(
this << phy << txPower << payloadSize << phy->GetCurrentFrequencyRange()
1780 << phy->GetChannelWidth() << phy->GetChannelNumber());
1804 phy->SetTxPowerStart(txPower);
1805 phy->SetTxPowerEnd(txPower);
1815 const auto payloadBytes = packet->GetSize() - 30;
1816 NS_LOG_FUNCTION(
this << index << payloadBytes << phy->GetCurrentFrequencyRange()
1817 << phy->GetChannelWidth() << phy->GetChannelNumber());
1827 const std::vector<bool>& )
1844 bool interferencesExpected)
1857 interferencesExpected);
1863 bool interferencesExpected)
1867 phy->GetAttribute(
"InterferenceHelper", ptr);
1870 const auto energyDuration = interferenceHelper->GetEnergyDuration(
Watt_u{0}, band);
1872 interferencesExpected,
1873 "Incorrect interferences detection");
1883 const std::vector<std::size_t>& expectedConnectedPhysPerChannel)
1885 NS_LOG_FUNCTION(
this << index << expectedNumRx << expectedNumRxSuccess << expectedRxBytes
1886 << expectedFrequencyRangeActiveRfInterface);
1887 const auto phy =
m_rxPhys.at(index);
1888 std::size_t numActiveInterfaces = 0;
1889 for (
const auto& [freqRange, interface] : phy->GetSpectrumPhyInterfaces())
1891 const auto expectedActive = (freqRange == expectedFrequencyRangeActiveRfInterface);
1892 const auto isActive = (
interface == phy->GetCurrentInterface());
1896 numActiveInterfaces++;
1904 expectedConnectedPhysPerChannel.at(i),
1905 "Incorrect number of PHYs attached to the spectrum channel");
1909 expectedNumRxSuccess,
1910 "Unexpected amount of successfully received packets");
1913 "Unexpected amount of unsuccessfully received packets");
1915 expectedNumRxSuccess,
1916 "Unexpected amount of RX payload start indication");
1921 bool expectedCcaBusyIndication,
1922 Time switchingDelay,
1923 Time propagationDelay)
1925 const auto expectedCcaBusyStart =
1927 const auto expectedCcaBusyEnd =
1929 NS_LOG_FUNCTION(
this << index << expectedCcaBusyIndication << expectedCcaBusyStart
1930 << expectedCcaBusyEnd);
1932 const auto ccaBusyIndication = (listener->m_notifyMaybeCcaBusyStart > 0);
1933 const auto ccaBusyStart = listener->m_ccaBusyStart;
1934 const auto ccaBusyEnd = listener->m_ccaBusyEnd;
1936 expectedCcaBusyIndication,
1937 "CCA busy indication check failed");
1947 phy->GetAttribute(
"InterferenceHelper", ptr);
1966 for (std::size_t rxPhyIndex = 0; rxPhyIndex <
m_rxPhys.size(); ++rxPhyIndex)
1968 auto txPhy =
m_txPhys.at(rxPhyIndex);
1970 txPhy->GetPhyBand(),
1971 txPhy->GetChannelNumber(),
1972 txPhy->GetChannelWidth(),
2008 struct SpectrumPhyInterfaceInfo
2013 std::string bandName;
2025 const std::vector<SpectrumPhyInterfaceInfo> interfaces{
2031 for (std::size_t i = 0; i < interfaces.size(); ++i)
2035 spectrumChannel->SetPropagationDelayModel(delayModel);
2036 std::ostringstream oss;
2037 oss <<
"{" << +interfaces.at(i).number <<
", 0, " << interfaces.at(i).bandName <<
", 0}";
2039 phyHelper.
AddChannel(spectrumChannel, interfaces.at(i).range);
2044 mac.SetType(
"ns3::ApWifiMac",
"BeaconGeneration",
BooleanValue(
false));
2045 phyHelper.
Set(
"TrackSignalsFromInactiveInterfaces",
BooleanValue(
false));
2046 auto apDevice = wifi.Install(phyHelper, mac, wifiApNode.Get(0));
2048 mac.SetType(
"ns3::StaWifiMac",
"ActiveProbing",
BooleanValue(
false));
2049 phyHelper.
Set(
"TrackSignalsFromInactiveInterfaces",
2051 auto staDevice = wifi.Install(phyHelper, mac, wifiStaNode.
Get(0));
2056 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2057 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
2058 mobility.SetPositionAllocator(positionAlloc);
2060 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
2061 mobility.Install(wifiApNode);
2062 mobility.Install(wifiStaNode);
2064 for (std::size_t i = 0; i < interfaces.size(); ++i)
2074 const auto index =
m_rxPhys.size();
2081 rxPhy->TraceConnectWithoutContext(
2085 rxPhy->SetReceiveOkCallback(
2087 rxPhy->SetReceiveErrorCallback(
2090 auto listener = std::make_shared<TestPhyListener>();
2091 rxPhy->RegisterListener(listener);
2124 const dBm_u ccaEdThreshold{-62.0};
2125 const auto txAfterChannelSwitchDelay =
2130 const auto checkResultsDelay =
2132 const auto flushResultsDelay =
2134 const auto txOngoingAfterTxStartedDelay =
2142 std::vector<std::size_t> expectedConnectedPhysPerChannel =
2146 std::vector<std::size_t>{2, 2, 2, 2};
2149 for (std::size_t i = 0; i < 4; ++i)
2159 for (std::size_t j = 0; j < 4; ++j)
2163 const auto& expectedFreqRange = txPhy->GetCurrentFrequencyRange();
2168 txPpduPhy->GetCurrentFrequencyRange(),
2169 txPpduPhy->GetBand(txPpduPhy->GetChannelWidth(), 0),
2177 (i == j) ? 1000 : 0,
2179 expectedConnectedPhysPerChannel);
2187 for (std::size_t i = 0; i < 4; ++i)
2197 const auto& expectedFreqRange = txPpduPhy->GetCurrentFrequencyRange();
2198 for (std::size_t j = 0; j < 4; ++j)
2202 for (std::size_t k = 0; k < expectedConnectedPhysPerChannel.size(); ++k)
2204 expectedConnectedPhysPerChannel.at(k) = (k == i) ? 5 : 1;
2212 txPpduPhy->GetPhyBand(),
2213 txPpduPhy->GetChannelNumber(),
2214 txPpduPhy->GetChannelWidth(),
2220 txPpduPhy->GetCurrentFrequencyRange(),
2221 txPpduPhy->GetBand(txPpduPhy->GetChannelWidth(), 0),
2231 expectedConnectedPhysPerChannel);
2240 const auto secondSpectrumChannelIndex = 1;
2241 auto channel36TxPhy =
m_txPhys.at(secondSpectrumChannelIndex);
2242 const auto& expectedFreqRange = channel36TxPhy->GetCurrentFrequencyRange();
2243 for (std::size_t i = 0; i < 4; ++i)
2253 for (std::size_t j = 0; j < 4; ++j)
2257 for (std::size_t k = 0; k < expectedConnectedPhysPerChannel.size(); ++k)
2259 expectedConnectedPhysPerChannel.at(k) =
2260 (k == secondSpectrumChannelIndex) ? 5 : 1;
2275 (i == secondSpectrumChannelIndex) ? 1 : 0,
2276 (i == secondSpectrumChannelIndex) ? 1 : 0,
2277 (i == secondSpectrumChannelIndex) ? 1000 : 0,
2279 expectedConnectedPhysPerChannel);
2287 for (
const auto txPower : {
dBm_u{-60} ,
dBm_u{-70} })
2289 for (std::size_t i = 0; i < 4; ++i)
2291 for (std::size_t j = 0; j < 4; ++j)
2295 txPpduPhy->GetPrimaryChannelNumber(
MHz_u{20}),
2299 txPpduPhy->GetPhyBand());
2300 for (
auto bw = txPpduPhy->GetChannelWidth(); bw >=
MHz_u{20}; bw /= 2)
2302 const auto& channelInfo =
2307 txPpduPhy->GetPhyBand(),
2324 for (std::size_t k = 0; k < 4; ++k)
2326 if ((i != j) && (k == i))
2330 const auto expectCcaBusyIndication =
2331 (k == i) ? (txPower >= ccaEdThreshold)
2333 ? ((txPower >= ccaEdThreshold) ? (j == k) :
false)
2336 delay + checkResultsDelay,
2340 expectCcaBusyIndication,
2341 txOngoingAfterTxStartedDelay,
2378 txPpduPhy->GetPhyBand(),
2379 txPpduPhy->GetChannelNumber(),
2380 txPpduPhy->GetChannelWidth(),
2399 txPpduPhy->GetPhyBand(),
2400 txPpduPhy->GetChannelNumber(),
2401 txPpduPhy->GetChannelWidth(),
2415 delay + checkResultsDelay,
2423 txPpduPhy->GetCurrentFrequencyRange(),
2424 expectedConnectedPhysPerChannel);
2445 txPpduPhy->GetPhyBand(),
2446 txPpduPhy->GetChannelNumber(),
2447 txPpduPhy->GetChannelWidth(),
2467 m_txPhys.at(0)->GetChannelNumber(),
2478 txPpduPhy->GetPhyBand(),
2479 txPpduPhy->GetChannelNumber(),
2480 txPpduPhy->GetChannelWidth(),
2509 m_rxPhys.at(2)->GetChannelNumber(),
2520 txPpduPhy->GetPhyBand(),
2521 txPpduPhy->GetChannelNumber(),
2522 txPpduPhy->GetChannelWidth(),
2542 txPpduPhy->GetCurrentFrequencyRange(),
2543 expectedConnectedPhysPerChannel);
2573 void DoRun()
override;
2577 :
TestCase(
"Check PHY interfaces added to PHY instances using helper")
2588 phyHelper.
Set(0,
"ChannelSettings",
StringValue(
"{2, 0, BAND_2_4GHZ, 0}"));
2589 phyHelper.
Set(1,
"ChannelSettings",
StringValue(
"{36, 0, BAND_5GHZ, 0}"));
2590 phyHelper.
Set(2,
"ChannelSettings",
StringValue(
"{1, 0, BAND_6GHZ, 0}"));
2608 "Incorrect number of PHY interfaces added to PHY link ID 0");
2615 "Incorrect number of PHY interfaces added to PHY link ID 1");
2622 "Incorrect number of PHY interfaces added to PHY link ID 2");
2635 "Incorrect number of PHY interfaces added to PHY link ID 0");
2638 "Incorrect PHY interfaces added to PHY link ID 0");
2644 "Incorrect number of PHY interfaces added to PHY link ID 1");
2647 "Incorrect PHY interfaces added to PHY link ID 1");
2653 "Incorrect number of PHY interfaces added to PHY link ID 2");
2656 "Incorrect PHY interfaces added to PHY link ID 2");
2667 "Incorrect number of PHY interfaces added to PHY link ID 0");
2670 "Incorrect PHY interfaces added to PHY link ID 0");
2673 "Incorrect PHY interfaces added to PHY link ID 0");
2679 "Incorrect number of PHY interfaces added to PHY link ID 1");
2682 "Incorrect PHY interfaces added to PHY link ID 1");
2688 "Incorrect number of PHY interfaces added to PHY link ID 2");
2691 "Incorrect PHY interfaces added to PHY link ID 2");
2702 "Incorrect number of PHY interfaces added to PHY link ID 0");
2705 "Incorrect PHY interfaces added to PHY link ID 0");
2708 "Incorrect PHY interfaces added to PHY link ID 0");
2711 "Incorrect PHY interfaces added to PHY link ID 0");
2717 "Incorrect number of PHY interfaces added to PHY link ID 1");
2720 "Incorrect PHY interfaces added to PHY link ID 0");
2723 "Incorrect PHY interfaces added to PHY link ID 0");
2726 "Incorrect PHY interfaces added to PHY link ID 0");
2732 "Incorrect number of PHY interfaces added to PHY link ID 2");
2735 "Incorrect PHY interfaces added to PHY link ID 0");
2738 "Incorrect PHY interfaces added to PHY link ID 0");
2741 "Incorrect PHY interfaces added to PHY link ID 0");
2770 TestCase::Duration::QUICK);
2774 TestCase::Duration::QUICK);
2778 TestCase::Duration::QUICK);
Extended InterferenceHelper class for the purpose of the tests.
static TypeId GetTypeId()
Get the type ID.
bool IsRxing() const
Indicate whether the interference helper is in receiving state.
bool IsBandTracked(const std::vector< WifiSpectrumBandFrequencies > &startStopFreqs) const
Indicate whether a given band is tracked by the interference helper.
Extended SpectrumWifiPhy class for the purpose of the tests.
virtual WifiSpectrumBandInfo GetBand(MHz_u bandWidth, uint8_t bandIndex=0)=0
Get the info of a given band.
Test 80+80MHz transmission.
SpectrumWifiPhy80Plus80Test()
void StopInterference()
Stop interference function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
void RunOne(const std::vector< uint8_t > &channelNumbers, MHz_u interferenceCenterFrequency, MHz_u interferenceBandWidth, bool expectSuccess)
Run one function.
uint32_t m_countRxSuccessSta
count RX success for STA
void DoRun() override
Implementation to actually run this TestCase.
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
void RxSuccessSta(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function for STA.
void SwitchChannel(const std::vector< uint8_t > &channelNumbers)
Switch channel function.
Ptr< SpectrumWifiPhy > m_phySta
PHY of STA.
void RxFailureSta(Ptr< const WifiPsdu > psdu)
Receive failure function for STA.
uint32_t m_countRxFailureSta
count RX failure for STA
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
void CheckResults(bool expectSuccess)
Verify results.
void Send160MhzPpdu()
Send 160MHz PPDU function.
Spectrum Wifi Phy Basic Test.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
~SpectrumWifiPhyBasicTest() override
void SpectrumWifiPhyRxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Spectrum wifi receive success function.
SpectrumWifiPhyBasicTest()
void SpectrumWifiPhyRxFailure(Ptr< const WifiPsdu > psdu)
Spectrum wifi receive failure function.
Ptr< SpectrumSignalParameters > MakeSignal(Watt_u txPower, const WifiPhyOperatingChannel &channel)
Make signal function.
void SendSignal(Watt_u txPower)
Send signal function.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
uint64_t m_uid
the UID to use for the PPDU
Ptr< SpectrumWifiPhy > m_phy
Phy.
Spectrum Wifi Phy Filter Test.
void RxCallback(Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
Callback triggered when a packet is received by the PHYs.
~SpectrumWifiPhyFilterTest() override
SpectrumWifiPhyFilterTest()
void DoRun() override
Implementation to actually run this TestCase.
void RunOne()
Run one function.
void SendPpdu()
Send PPDU function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Ptr< ExtSpectrumWifiPhy > m_rxPhy
RX PHY.
MHz_u m_rxChannelWidth
RX channel width.
Ptr< ExtSpectrumWifiPhy > m_txPhy
TX PHY.
MHz_u m_txChannelWidth
TX channel width.
Spectrum Wifi Phy Bands Calculations Test.
void RunOne(const std::vector< uint8_t > &channelNumberPerSegment, MHz_u bandWidth, uint8_t bandIndex, const std::vector< WifiSpectrumBandIndices > &expectedIndices, const std::vector< WifiSpectrumBandFrequencies > &expectedFrequencies)
Run one function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_phy
PHY.
SpectrumWifiPhyGetBandTest()
void DoRun() override
Implementation to actually run this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Spectrum Wifi Phy Interfaces Helper Test.
~SpectrumWifiPhyInterfacesHelperTest() override=default
SpectrumWifiPhyInterfacesHelperTest()
void DoRun() override
Implementation to actually run this TestCase.
Spectrum Wifi Phy Listener Test.
void DoRun() override
Implementation to actually run this TestCase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
SpectrumWifiPhyListenerTest()
std::shared_ptr< TestPhyListener > m_listener
listener
Spectrum Wifi Phy Multiple Spectrum Test.
void SendPpdu(Ptr< SpectrumWifiPhy > phy, dBm_u txPower, uint32_t payloadSize)
Send PPDU function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
std::vector< uint32_t > m_rxBytes
count number of received bytes
std::vector< Ptr< SpectrumWifiPhy > > m_rxPhys
RX PHYs.
std::vector< uint32_t > m_countRxSuccess
count number of packets successfully received by PHYs
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
ChannelSwitchScenario m_chanSwitchScenario
the channel switch scenario to consider for the test
void DoRun() override
Implementation to actually run this TestCase.
void DoCheckInterferences(Ptr< SpectrumWifiPhy > phy, const WifiSpectrumBandInfo &band, bool interferencesExpected)
Check the interferences.
void RxSuccess(std::size_t index, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function.
bool m_trackSignalsInactiveInterfaces
flag to indicate whether signals coming from inactive spectrum PHY interfaces are tracked during the ...
void SwitchChannel(Ptr< SpectrumWifiPhy > phy, WifiPhyBand band, uint8_t channelNumber, MHz_u channelWidth, std::optional< std::size_t > listenerIndex)
Switch channel function.
std::vector< std::shared_ptr< TestPhyListener > > m_listeners
listeners
Time m_lastTxEnd
hold the time at which the last transmission ended
void RxFailure(std::size_t index, Ptr< const WifiPsdu > psdu)
Receive failure function.
Time m_lastTxStart
hold the time at which the last transmission started
std::vector< uint32_t > m_counts
count number of packets received by PHYs
void CheckResults(std::size_t index, uint32_t expectedNumRx, uint32_t expectedNumRxSuccess, uint32_t expectedRxBytes, FrequencyRange expectedFrequencyRangeActiveRfInterface, const std::vector< std::size_t > &expectedConnectedPhysPerChannel)
Verify results.
std::vector< Ptr< SpectrumWifiPhy > > m_txPhys
TX PHYs.
std::vector< Ptr< MultiModelSpectrumChannel > > m_spectrumChannels
Spectrum channels.
void CheckInterferences(Ptr< SpectrumWifiPhy > phy, const FrequencyRange &freqRange, const WifiSpectrumBandInfo &band, bool interferencesExpected)
Schedule now to check the interferences.
SpectrumWifiPhyMultipleInterfacesTest(bool trackSignalsInactiveInterfaces, ChannelSwitchScenario chanSwitchScenario)
Constructor.
void CheckCcaIndication(std::size_t index, bool expectedCcaBusyIndication, Time switchingDelay, Time propagationDelay)
Verify CCA indication reported by a given PHY.
void RxCallback(std::size_t index, Ptr< const Packet > packet, RxPowerWattPerChannelBand rxPowersW)
Callback triggered when a packet is received by a PHY.
void Reset()
Reset function.
void CheckRxingState(Ptr< SpectrumWifiPhy > phy, bool rxingExpected)
Verify rxing state of the interference helper.
ChannelSwitchScenario
Enumeration for channel switching scenarios.
@ BETWEEN_TX_RX
perform channel switch during propagation delay (after TX and before RX)
@ BEFORE_TX
start TX after channel switch is completed
std::vector< uint32_t > m_countRxFailure
count number of packets unsuccessfully received by PHYs
Spectrum Wifi Phy Test Suite.
SpectrumWifiPhyTestSuite()
Test tracked bands in interference helper upon channel switching.
void DoRun() override
Implementation to actually run this TestCase.
void RunOne(const std::vector< uint8_t > &channelNumberPerSegmentBeforeSwitching, const std::vector< uint8_t > &channelNumberPerSegmentAfterSwitching, const std::vector< std::vector< WifiSpectrumBandFrequencies > > &expectedTrackedBands, const std::vector< std::vector< WifiSpectrumBandFrequencies > > &expectedUntrackedBand)
Run one function.
void VerifyTrackedBands(const std::vector< std::vector< WifiSpectrumBandFrequencies > > &expectedTrackedBands, const std::vector< std::vector< WifiSpectrumBandFrequencies > > &expectedUntrackedBands)
Verify the bands tracked by the interference helper.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void SwitchChannel(const std::vector< uint8_t > &channelNumberPerSegment)
Switch channel function.
SpectrumWifiPhyTrackedBandsTest()
Ptr< ExtSpectrumWifiPhy > m_phy
PHY.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Time m_ccaBusyEnd
CCA_BUSY end time.
void NotifyTxStart(Time duration, dBm_u txPower) override
void Reset()
Reset function.
void NotifyWakeup() override
Notify listeners that we woke up.
Time m_ccaBusyStart
CCA_BUSY start time.
void NotifyRxEndOk() override
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void NotifyOff() override
Notify listeners that we went to switch off.
void NotifyRxEndError(const WifiTxVector &txVector) override
TestPhyListener()=default
Create a test PhyListener.
void NotifySleep() override
Notify listeners that we went to sleep.
void NotifySwitchingStart(Time duration) override
uint32_t m_notifyMaybeCcaBusyStart
notify maybe CCA busy start
uint32_t m_notifyRxStart
notify receive start
void NotifyCcaBusyStart(Time duration, WifiChannelListType channelType, const std::vector< Time > &) override
void NotifyRxStart(Time duration) override
void NotifyOn() override
Notify listeners that we went to switch on.
uint32_t m_notifyRxEndOk
notify receive end OK
uint32_t m_notifyRxEndError
notify receive end error
~TestPhyListener() override=default
AttributeValue implementation for Boolean.
static WifiMode GetEhtMcs0()
Return MCS 0 from EHT MCS values.
static WifiMode GetHeMcs11()
Return MCS 11 from HE MCS values.
static WifiMode GetHeMcs7()
Return MCS 7 from HE MCS values.
handles interference calculations
std::map< FrequencyRange, bool > m_rxing
flag whether it is in receiving state for a given FrequencyRange
NiChangesPerBand m_niChanges
NI Changes for each band.
Helper class used to assign positions and mobility models to nodes.
keep track of a set of node pointers.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
void GetAttribute(std::string name, AttributeValue &value, bool permissive=false) const
Get the value of an attribute, raising fatal errors if unsuccessful.
void Dispose()
Dispose of this Object.
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
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 ResetPhyToFreqRangeMapping()
Reset mapping of the spectrum PHY interfaces added to the PHY instances.
void AddChannel(const Ptr< SpectrumChannel > channel, const FrequencyRange &freqRange=WHOLE_WIFI_SPECTRUM)
void AddPhyToFreqRangeMapping(uint8_t linkId, const FrequencyRange &freqRange)
Add a given spectrum PHY interface to the PHY instance corresponding of a given link.
void SetDevice(const Ptr< WifiNetDevice > device) override
Sets the device this PHY is associated with.
MHz_u GetGuardBandwidth(MHz_u currentChannelWidth) const override
void AddChannel(const Ptr< SpectrumChannel > channel, const FrequencyRange &freqRange=WHOLE_WIFI_SPECTRUM)
Attach a SpectrumChannel to use for a given frequency range.
Ptr< WifiSpectrumPhyInterface > GetCurrentInterface() const
Get the currently active spectrum PHY interface.
RuBands GetRuBands(Ptr< WifiSpectrumPhyInterface > spectrumPhyInterface, MHz_u guardBandwidth)
This function computes the RU bands that belong to a given spectrum PHY interface.
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.
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
helps to create WifiNetDevice objects
virtual void SetStandard(WifiStandard standard)
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer::Iterator first, NodeContainer::Iterator last) const
create MAC layers for a ns3::WifiNetDevice.
void SetPcapDataLinkType(SupportedPcapDataLinkTypes dlt)
Set the data link type of PCAP traces to be used.
void Set(std::string name, const AttributeValue &v)
void SetInterferenceHelper(std::string type, Args &&... args)
Helper function used to set the interference helper.
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
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.
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
std::vector< ChannelTuple > ChannelSegments
segments identifying an operating channel
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
virtual WifiSpectrumBandInfo GetBand(MHz_u bandWidth, uint8_t bandIndex=0)=0
Get the info of a given band.
receive notifications about PHY events.
Class that keeps track of all information about the current PHY operating channel.
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.
static Ptr< SpectrumValue > CreateOfdmTxPowerSpectralDensity(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})
Create a transmit power spectral density corresponding to OFDM (802.11a/g).
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#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 ",...
#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.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
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.
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.
WifiPhyBand
Identifies the PHY band.
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_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
constexpr FrequencyRange WIFI_SPECTRUM_6_GHZ
Identifier for the frequency range covering the wifi spectrum in the 6 GHz band.
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...
dB_u RatioToDb(double ratio)
Convert from ratio to dB.
std::vector< BandInfo > Bands
Container of BandInfo.
dBm_u WToDbm(Watt_u val)
Convert from Watts to dBm.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
constexpr FrequencyRange WIFI_SPECTRUM_5_GHZ
Identifier for the frequency range covering the wifi spectrum in the 5 GHz band.
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)
constexpr FrequencyRange WIFI_SPECTRUM_2_4_GHZ
Identifier for the frequency range covering the wifi spectrum in the 2.4 GHz band.
static const uint8_t CHANNEL_NUMBER
static SpectrumWifiPhyTestSuite spectrumWifiPhyTestSuite
the test suite
static const MHz_u GUARD_WIDTH
static const MHz_u CHANNEL_WIDTH
The building block of a SpectrumModel.
double fl
lower limit of subband
Struct defining a frequency range between minFrequency and maxFrequency.
MHz_u minFrequency
the minimum frequency
MHz_u maxFrequency
the maximum frequency
RxSignalInfo structure containing info on the received signal.
WifiSpectrumBandInfo structure containing info about a spectrum band.