7#include "ns3/boolean.h"
8#include "ns3/constant-position-mobility-model.h"
10#include "ns3/interference-helper.h"
12#include "ns3/mobility-helper.h"
13#include "ns3/multi-model-spectrum-channel.h"
14#include "ns3/nist-error-rate-model.h"
15#include "ns3/non-communicating-net-device.h"
16#include "ns3/ofdm-ppdu.h"
17#include "ns3/pointer.h"
18#include "ns3/spectrum-wifi-helper.h"
19#include "ns3/spectrum-wifi-phy.h"
20#include "ns3/string.h"
22#include "ns3/waveform-generator.h"
23#include "ns3/wifi-mac-header.h"
24#include "ns3/wifi-net-device.h"
25#include "ns3/wifi-phy-listener.h"
26#include "ns3/wifi-psdu.h"
27#include "ns3/wifi-spectrum-phy-interface.h"
28#include "ns3/wifi-spectrum-signal-parameters.h"
29#include "ns3/wifi-spectrum-value-helper.h"
30#include "ns3/wifi-utils.h"
80 return std::any_of(
m_rxing.cbegin(),
m_rxing.cend(), [](
const auto& rxing) {
92 bool IsBandTracked(
const std::vector<WifiSpectrumBandFrequencies>& startStopFreqs)
const
96 if (band.frequencies == startStopFreqs)
152 std::vector<bool> statusPerMpdu);
161 void DoRun()
override;
199 const auto txDuration =
200 m_phy->CalculateTxDuration(psdu->GetSize(), txVector,
m_phy->GetPhyBand());
210 txParams->psd = txPowerSpectrum;
211 txParams->txPhy =
nullptr;
212 txParams->duration = txDuration;
213 txParams->ppdu = ppdu;
229 std::vector<bool> statusPerMpdu)
256 m_phy->SetInterferenceHelper(interferenceHelper);
258 m_phy->SetErrorRateModel(error);
259 m_phy->SetDevice(dev);
260 m_phy->AddChannel(spectrumChannel);
263 m_phy->SetReceiveOkCallback(
265 m_phy->SetReceiveErrorCallback(
268 node->AddDevice(dev);
343 const std::vector<Time>& )
override
412 void DoRun()
override;
425 m_listener = std::make_shared<TestPhyListener>();
440 "Didn't receive NotifyCcaBusyStart (once preamble is detected + prolonged by L-SIG "
441 "reception, then switched to Rx by at the beginning of data)");
470 void DoRun()
override;
497 :
TestCase(
"SpectrumWifiPhy test RX filters"),
498 m_txChannelWidth(20),
540 for (
const auto& [band, powerW] : rxPowersW)
543 "band: (" << band <<
") -> powerW=" << powerW
544 << (powerW > 0.0 ?
" (" + std::to_string(
WToDbm(powerW)) +
" dBm)" :
""));
547 size_t numBands = rxPowersW.size();
560 "Total number of bands handled by the receiver is incorrect");
564 auto it = rxPowersW.find(band);
565 NS_LOG_INFO(
"powerW total band: " << it->second <<
" (" <<
WToDbm(it->second) <<
" dBm)");
566 int totalRxPower =
static_cast<int>(
WToDbm(it->second) + 0.5);
567 int expectedTotalRxPower;
572 expectedTotalRxPower = 16;
577 expectedTotalRxPower =
581 expectedTotalRxPower,
582 "Total received power is not correct");
587 it = rxPowersW.find(band);
588 NS_LOG_INFO(
"powerW in primary 20 MHz channel: " << it->second <<
" (" <<
WToDbm(it->second)
590 const auto rxPowerPrimaryChannel20 =
static_cast<int>(
WToDbm(it->second) + 0.5);
591 const auto expectedRxPowerPrimaryChannel20 =
592 16 -
static_cast<int>(
RatioToDb(channelWidth / 20));
594 expectedRxPowerPrimaryChannel20,
595 "Received power in the primary 20 MHz band is not correct");
607 lossModel->SetFrequency(5.180e9);
608 spectrumChannel->AddPropagationLossModel(lossModel);
610 spectrumChannel->SetPropagationDelayModel(delayModel);
625 txNode->AggregateObject(apMobility);
626 txNode->AddDevice(txDev);
640 rxNode->AggregateObject(sta1Mobility);
641 rxNode->AddDevice(rxDev);
802 void DoRun()
override;
813 void RunOne(
const std::vector<uint8_t>& channelNumberPerSegment,
816 const std::vector<WifiSpectrumBandIndices>& expectedIndices,
817 const std::vector<WifiSpectrumBandFrequencies>& expectedFrequencies);
823 :
TestCase(
"SpectrumWifiPhy test bands calculations")
835 lossModel->SetFrequency(5.180e9);
836 spectrumChannel->AddPropagationLossModel(lossModel);
838 spectrumChannel->SetPropagationDelayModel(delayModel);
844 m_phy->SetInterferenceHelper(interferenceHelper);
846 m_phy->SetErrorRateModel(errorModel);
847 m_phy->SetDevice(dev);
848 m_phy->AddChannel(spectrumChannel);
851 node->AddDevice(dev);
863 const std::vector<uint8_t>& channelNumberPerSegment,
866 const std::vector<WifiSpectrumBandIndices>& expectedIndices,
867 const std::vector<WifiSpectrumBandFrequencies>& expectedFrequencies)
870 for (
auto channelNumber : channelNumberPerSegment)
877 channelSegments.emplace_back(channelInfo->number, channelInfo->width, channelInfo->band, 0);
879 m_phy->SetOperatingChannel(channelSegments);
881 const auto& bandInfo =
m_phy->GetBand(bandWidth, bandIndex);
882 NS_ASSERT(expectedIndices.size() == expectedFrequencies.size());
883 NS_ASSERT(expectedIndices.size() == bandInfo.indices.size());
884 NS_ASSERT(expectedFrequencies.size() == bandInfo.frequencies.size());
885 for (std::size_t i = 0; i < expectedIndices.size(); ++i)
887 NS_ASSERT(bandInfo.indices.at(i).first == expectedIndices.at(i).first);
889 expectedIndices.at(i).first,
890 "Incorrect start indice for segment " << i);
892 expectedIndices.at(i).second,
893 "Incorrect stop indice for segment " << i);
895 expectedFrequencies.at(i).first,
896 "Incorrect start frequency for segment " << i);
898 expectedFrequencies.at(i).second,
899 "Incorrect stop frequency for segment " << i);
906 const uint32_t indicesPer20MhzBand = 256;
907 const MHz_u channelWidth = 160;
908 const uint8_t channelNumberContiguous160Mhz =
910 const std::vector<uint8_t> channelNumberPerSegment = {42,
913 const MHz_u separationWidth = 240;
914 for (
bool contiguous160Mhz : {
true ,
false })
916 MHz_u guardWidth = contiguous160Mhz ? channelWidth : (channelWidth / 2);
917 uint32_t guardStopIndice = (indicesPer20MhzBand * (guardWidth / 20)) - 1;
918 std::vector<WifiSpectrumBandIndices> previousExpectedIndices{};
919 std::vector<WifiSpectrumBandFrequencies> previousExpectedFrequencies{};
920 for (
auto bandWidth : {20, 40, 80, 160})
922 const uint32_t expectedStartIndice = guardStopIndice + 1;
924 expectedStartIndice + (indicesPer20MhzBand * (bandWidth / 20)) - 1;
925 std::vector<WifiSpectrumBandIndices> expectedIndices{
926 {expectedStartIndice, expectedStopIndice}};
927 const Hz_u expectedStartFrequency = 5170 * 1e6;
928 const Hz_u expectedStopFrequency = (5170 + bandWidth) * 1e6;
929 std::vector<WifiSpectrumBandFrequencies> expectedFrequencies{
930 {expectedStartFrequency, expectedStopFrequency}};
931 const std::size_t numBands = (channelWidth / bandWidth);
932 for (std::size_t i = 0; i < numBands; ++i)
934 if ((bandWidth != channelWidth) && (i >= (numBands / 2)))
937 expectedIndices.at(0).first++;
939 if ((bandWidth == channelWidth) && !contiguous160Mhz)
943 expectedIndices = previousExpectedIndices;
944 expectedFrequencies = previousExpectedFrequencies;
946 else if ((i == (numBands / 2)) && !contiguous160Mhz)
948 expectedIndices.at(0).first += (indicesPer20MhzBand * (separationWidth / 20));
949 expectedIndices.at(0).second += (indicesPer20MhzBand * (separationWidth / 20));
950 expectedFrequencies.at(0).first += (separationWidth * 1e6);
951 expectedFrequencies.at(0).second += (separationWidth * 1e6);
953 RunOne(contiguous160Mhz ? std::vector<uint8_t>{channelNumberContiguous160Mhz}
954 : channelNumberPerSegment,
958 expectedFrequencies);
959 if (!contiguous160Mhz && (bandWidth == (channelWidth / 2)))
961 previousExpectedIndices.emplace_back(expectedIndices.front());
962 previousExpectedFrequencies.emplace_back(expectedFrequencies.front());
964 expectedIndices.at(0).first = expectedIndices.at(0).second + 1;
965 expectedIndices.at(0).second =
966 expectedIndices.at(0).first + (indicesPer20MhzBand * (bandWidth / 20)) - 1;
967 expectedFrequencies.at(0).first += (bandWidth * 1e6);
968 expectedFrequencies.at(0).second += (bandWidth * 1e6);
994 void DoRun()
override;
1002 void SwitchChannel(
const std::vector<uint8_t>& channelNumberPerSegment);
1013 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedTrackedBands,
1014 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedUntrackedBands);
1024 void RunOne(
const std::vector<uint8_t>& channelNumberPerSegmentBeforeSwitching,
1025 const std::vector<uint8_t>& channelNumberPerSegmentAfterSwitching,
1026 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedTrackedBands,
1027 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedUntrackedBand);
1033 :
TestCase(
"SpectrumWifiPhy test channel switching for non-contiguous operating channels")
1045 lossModel->SetFrequency(5.180e9);
1046 spectrumChannel->AddPropagationLossModel(lossModel);
1048 spectrumChannel->SetPropagationDelayModel(delayModel);
1061 node->AddDevice(dev);
1076 for (
auto channelNumber : channelNumberPerSegment)
1083 channelSegments.emplace_back(channelInfo->number, channelInfo->width, channelInfo->band, 0);
1090 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedTrackedBands,
1091 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedUntrackedBands)
1098 auto printBand = [](
const std::vector<WifiSpectrumBandFrequencies>& v) {
1099 std::stringstream ss;
1100 for (
const auto& [start, stop] : v)
1102 ss <<
"[" << start <<
"-" << stop <<
"] ";
1106 for (
const auto& expectedTrackedBand : expectedTrackedBands)
1108 auto bandTracked = interferenceHelper->IsBandTracked(expectedTrackedBand);
1111 "Band " << printBand(expectedTrackedBand) <<
" is not tracked");
1113 for (
const auto& expectedUntrackedBand : expectedUntrackedBands)
1115 auto bandTracked = interferenceHelper->IsBandTracked(expectedUntrackedBand);
1118 "Band " << printBand(expectedUntrackedBand)
1119 <<
" is unexpectedly tracked");
1125 const std::vector<uint8_t>& channelNumberPerSegmentBeforeSwitching,
1126 const std::vector<uint8_t>& channelNumberPerSegmentAfterSwitching,
1127 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedTrackedBands,
1128 const std::vector<std::vector<WifiSpectrumBandFrequencies>>& expectedUntrackedBands)
1135 channelNumberPerSegmentBeforeSwitching);
1140 channelNumberPerSegmentAfterSwitching);
1145 expectedTrackedBands,
1146 expectedUntrackedBands);
1157 {{{5170 * 1e6, 5250 * 1e6}} ,
1158 {{5490 * 1e6, 5570 * 1e6}} ,
1159 {{5170 * 1e6, 5250 * 1e6},
1160 {5490 * 1e6, 5570 * 1e6}} },
1161 {{{5170 * 1e6, 5330 * 1e6}} });
1166 {{{5170 * 1e6, 5330 * 1e6}} ,
1167 {{5170 * 1e6, 5250 * 1e6}} },
1168 {{{5490 * 1e6, 5570 * 1e6}} ,
1169 {{5170 * 1e6, 5250 * 1e6},
1170 {5490 * 1e6, 5570 * 1e6}} });
1175 {{{5490 * 1e6, 5570 * 1e6}} ,
1176 {{5490 * 1e6, 5570 * 1e6}} ,
1177 {{5170 * 1e6, 5250 * 1e6},
1178 {5490 * 1e6, 5570 * 1e6}} },
1184 {{{5490 * 1e6, 5570 * 1e6}} ,
1185 {{5650 * 1e6, 5730 * 1e6}} ,
1186 {{5490 * 1e6, 5570 * 1e6},
1187 {5650 * 1e6, 5730 * 1e6}} },
1188 {{{5170 * 1e6, 5250 * 1e6}} ,
1189 {{5170 * 1e6, 5250 * 1e6},
1197 {{{5570 * 1e6, 5650 * 1e6}} ,
1198 {{5735 * 1e6, 5815 * 1e6}} ,
1199 {{5570 * 1e6, 5650 * 1e6},
1200 {5735 * 1e6, 5815 * 1e6}} },
1201 {{{5170 * 1e6, 5250 * 1e6}} ,
1202 {{5490 * 1e6, 5570 * 1e6}} ,
1203 {{5170 * 1e6, 5250 * 1e6},
1237 void DoRun()
override;
1247 void RunOne(
const std::vector<uint8_t>& channelNumbers,
1248 MHz_u interferenceCenterFrequency,
1249 MHz_u interferenceBandWidth,
1250 bool expectSuccess);
1258 void SwitchChannel(
const std::vector<uint8_t>& channelNumbers);
1287 std::vector<bool> statusPerMpdu);
1311 :
TestCase(
"SpectrumWifiPhy test 80+80MHz transmission"),
1312 m_countRxSuccessSta(0),
1313 m_countRxFailureSta(0)
1322 for (
auto channelNumber : channelNumbers)
1329 channelSegments.emplace_back(channelInfo->number, channelInfo->width, channelInfo->band, 0);
1331 m_phyAp->SetOperatingChannel(channelSegments);
1332 m_phySta->SetOperatingChannel(channelSegments);
1357 m_phyAp->Send(psdu, txVector);
1398 "Reception should be "
1399 << (expectSuccess ?
"successful" :
"unsuccessful"));
1410 spectrumChannel->AddPropagationLossModel(lossModel);
1412 spectrumChannel->SetPropagationDelayModel(delayModel);
1418 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
1420 m_phyAp->SetErrorRateModel(apErrorModel);
1422 m_phyAp->AddChannel(spectrumChannel);
1425 m_phyAp->SetMobility(apMobility);
1427 apNode->AggregateObject(apMobility);
1428 apNode->AddDevice(apDev);
1434 m_phySta->SetInterferenceHelper(staInterferenceHelper);
1436 m_phySta->SetErrorRateModel(staErrorModel);
1438 m_phySta->AddChannel(spectrumChannel);
1444 m_phySta->SetMobility(staMobility);
1446 staNode->AggregateObject(staMobility);
1447 staNode->AddDevice(staDev);
1455 interfererNode->AddDevice(interfererDev);
1471 MHz_u interferenceCenterFrequency,
1472 MHz_u interferenceBandWidth,
1485 BandInfo bandInfo{.
fl = (interferenceCenterFrequency - (interferenceBandWidth / 2)) * 1e6,
1486 .fc = interferenceCenterFrequency * 1e6,
1487 .fh = (interferenceCenterFrequency + (interferenceBandWidth / 2)) * 1e6};
1490 Watt_u interferencePower{0.1};
1491 *interferencePsd = interferencePower / (interferenceBandWidth * 20e6);
1526 RunOne({50}, 5290, 80,
false);
1541 RunOne({42, 106}, 5290, 80,
true);
1557 RunOne({42, 106}, 5210, 80,
false);
1573 RunOne({42, 106}, 5530, 80,
false);
1618 ChannelSwitchScenario chanSwitchScenario);
1623 void DoRun()
override;
1636 uint8_t channelNumber,
1638 std::optional<std::size_t> listenerIndex);
1671 std::vector<bool> statusPerMpdu);
1690 bool interferencesExpected);
1700 bool interferencesExpected);
1719 const std::vector<std::size_t>& expectedConnectedPhysPerChannel);
1731 bool expectedCcaBusyIndication,
1732 Time switchingDelay,
1733 Time propagationDelay);
1760 std::vector<uint32_t>
1762 std::vector<uint32_t>
1771 bool trackSignalsInactiveInterfaces,
1773 :
TestCase{
"SpectrumWifiPhy test operation with multiple RF interfaces"},
1774 m_trackSignalsInactiveInterfaces{trackSignalsInactiveInterfaces},
1775 m_chanSwitchScenario{chanSwitchScenario}
1782 uint8_t channelNumber,
1784 std::optional<std::size_t> listenerIndex)
1786 NS_LOG_FUNCTION(
this << phy << band << +channelNumber << channelWidth);
1790 listener->m_notifyMaybeCcaBusyStart = 0;
1791 listener->m_ccaBusyStart =
Seconds(0);
1792 listener->m_ccaBusyEnd =
Seconds(0);
1807 NS_LOG_FUNCTION(
this << phy << txPower << payloadSize << phy->GetCurrentFrequencyRange()
1808 << phy->GetChannelWidth() << phy->GetChannelNumber());
1832 phy->SetTxPowerStart(txPower);
1833 phy->SetTxPowerEnd(txPower);
1843 const auto payloadBytes = packet->GetSize() - 30;
1844 NS_LOG_FUNCTION(
this << index << payloadBytes << phy->GetCurrentFrequencyRange()
1845 << phy->GetChannelWidth() << phy->GetChannelNumber());
1872 bool interferencesExpected)
1885 interferencesExpected);
1891 bool interferencesExpected)
1895 phy->GetAttribute(
"InterferenceHelper", ptr);
1898 const auto energyDuration = interferenceHelper->GetEnergyDuration(0, band);
1900 interferencesExpected,
1901 "Incorrect interferences detection");
1911 const std::vector<std::size_t>& expectedConnectedPhysPerChannel)
1913 NS_LOG_FUNCTION(
this << index << expectedNumRx << expectedNumRxSuccess << expectedRxBytes
1914 << expectedFrequencyRangeActiveRfInterface);
1915 const auto phy =
m_rxPhys.at(index);
1916 std::size_t numActiveInterfaces = 0;
1917 for (
const auto& [freqRange, interface] : phy->GetSpectrumPhyInterfaces())
1919 const auto expectedActive = (freqRange == expectedFrequencyRangeActiveRfInterface);
1920 const auto isActive = (
interface == phy->GetCurrentInterface());
1924 numActiveInterfaces++;
1932 expectedConnectedPhysPerChannel.at(i),
1933 "Incorrect number of PHYs attached to the spectrum channel");
1937 expectedNumRxSuccess,
1938 "Unexpected amount of successfully received packets");
1941 "Unexpected amount of unsuccessfully received packets");
1943 expectedNumRxSuccess,
1944 "Unexpected amount of RX payload start indication");
1949 bool expectedCcaBusyIndication,
1950 Time switchingDelay,
1951 Time propagationDelay)
1953 const auto expectedCcaBusyStart =
1955 const auto expectedCcaBusyEnd =
1957 NS_LOG_FUNCTION(
this << index << expectedCcaBusyIndication << expectedCcaBusyStart
1958 << expectedCcaBusyEnd);
1960 const auto ccaBusyIndication = (listener->m_notifyMaybeCcaBusyStart > 0);
1961 const auto ccaBusyStart = listener->m_ccaBusyStart;
1962 const auto ccaBusyEnd = listener->m_ccaBusyEnd;
1964 expectedCcaBusyIndication,
1965 "CCA busy indication check failed");
1975 phy->GetAttribute(
"InterferenceHelper", ptr);
1994 for (std::size_t rxPhyIndex = 0; rxPhyIndex <
m_rxPhys.size(); ++rxPhyIndex)
1996 auto txPhy =
m_txPhys.at(rxPhyIndex);
1998 txPhy->GetPhyBand(),
1999 txPhy->GetChannelNumber(),
2000 txPhy->GetChannelWidth(),
2036 struct SpectrumPhyInterfaceInfo
2041 std::string bandName;
2053 const std::vector<SpectrumPhyInterfaceInfo> interfaces{
2059 for (std::size_t i = 0; i < interfaces.size(); ++i)
2063 spectrumChannel->SetPropagationDelayModel(delayModel);
2064 std::ostringstream oss;
2065 oss <<
"{" << +interfaces.at(i).number <<
", 0, " << interfaces.at(i).bandName <<
", 0}";
2067 phyHelper.
AddChannel(spectrumChannel, interfaces.at(i).range);
2072 mac.SetType(
"ns3::ApWifiMac",
"BeaconGeneration",
BooleanValue(
false));
2073 phyHelper.
Set(
"TrackSignalsFromInactiveInterfaces",
BooleanValue(
false));
2074 auto apDevice = wifi.Install(phyHelper, mac, wifiApNode.Get(0));
2076 mac.SetType(
"ns3::StaWifiMac",
"ActiveProbing",
BooleanValue(
false));
2077 phyHelper.
Set(
"TrackSignalsFromInactiveInterfaces",
2079 auto staDevice = wifi.Install(phyHelper, mac, wifiStaNode.
Get(0));
2084 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2085 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
2086 mobility.SetPositionAllocator(positionAlloc);
2088 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
2089 mobility.Install(wifiApNode);
2090 mobility.Install(wifiStaNode);
2092 for (std::size_t i = 0; i < interfaces.size(); ++i)
2102 const auto index =
m_rxPhys.size();
2109 rxPhy->TraceConnectWithoutContext(
2113 rxPhy->SetReceiveOkCallback(
2115 rxPhy->SetReceiveErrorCallback(
2118 auto listener = std::make_shared<TestPhyListener>();
2119 rxPhy->RegisterListener(listener);
2152 const dBm_u ccaEdThreshold = -62.0;
2153 const auto txAfterChannelSwitchDelay =
2158 const auto checkResultsDelay =
2160 const auto flushResultsDelay =
2162 const auto txOngoingAfterTxStartedDelay =
2170 std::vector<std::size_t> expectedConnectedPhysPerChannel =
2174 std::vector<std::size_t>{2, 2, 2, 2};
2177 for (std::size_t i = 0; i < 4; ++i)
2187 for (std::size_t j = 0; j < 4; ++j)
2191 const auto& expectedFreqRange = txPhy->GetCurrentFrequencyRange();
2196 txPpduPhy->GetCurrentFrequencyRange(),
2197 txPpduPhy->GetBand(txPpduPhy->GetChannelWidth(), 0),
2205 (i == j) ? 1000 : 0,
2207 expectedConnectedPhysPerChannel);
2215 for (std::size_t i = 0; i < 4; ++i)
2225 const auto& expectedFreqRange = txPpduPhy->GetCurrentFrequencyRange();
2226 for (std::size_t j = 0; j < 4; ++j)
2230 for (std::size_t k = 0; k < expectedConnectedPhysPerChannel.size(); ++k)
2232 expectedConnectedPhysPerChannel.at(k) = (k == i) ? 5 : 1;
2240 txPpduPhy->GetPhyBand(),
2241 txPpduPhy->GetChannelNumber(),
2242 txPpduPhy->GetChannelWidth(),
2248 txPpduPhy->GetCurrentFrequencyRange(),
2249 txPpduPhy->GetBand(txPpduPhy->GetChannelWidth(), 0),
2259 expectedConnectedPhysPerChannel);
2268 const auto secondSpectrumChannelIndex = 1;
2269 auto channel36TxPhy =
m_txPhys.at(secondSpectrumChannelIndex);
2270 const auto& expectedFreqRange = channel36TxPhy->GetCurrentFrequencyRange();
2271 for (std::size_t i = 0; i < 4; ++i)
2281 for (std::size_t j = 0; j < 4; ++j)
2285 for (std::size_t k = 0; k < expectedConnectedPhysPerChannel.size(); ++k)
2287 expectedConnectedPhysPerChannel.at(k) =
2288 (k == secondSpectrumChannelIndex) ? 5 : 1;
2303 (i == secondSpectrumChannelIndex) ? 1 : 0,
2304 (i == secondSpectrumChannelIndex) ? 1 : 0,
2305 (i == secondSpectrumChannelIndex) ? 1000 : 0,
2307 expectedConnectedPhysPerChannel);
2315 for (
const dBm_u txPower : {-60.0 , -70.0 })
2317 for (std::size_t i = 0; i < 4; ++i)
2319 for (std::size_t j = 0; j < 4; ++j)
2322 const auto startChannel =
2327 txPpduPhy->GetPhyBand());
2328 for (
auto bw = txPpduPhy->GetChannelWidth(); bw >= 20; bw /= 2)
2330 const auto& channelInfo =
2335 txPpduPhy->GetPhyBand(),
2352 for (std::size_t k = 0; k < 4; ++k)
2354 if ((i != j) && (k == i))
2358 const auto expectCcaBusyIndication =
2359 (k == i) ? (txPower >= ccaEdThreshold)
2361 ? ((txPower >= ccaEdThreshold) ? (j == k) :
false)
2364 delay + checkResultsDelay,
2368 expectCcaBusyIndication,
2369 txOngoingAfterTxStartedDelay,
2406 txPpduPhy->GetPhyBand(),
2407 txPpduPhy->GetChannelNumber(),
2408 txPpduPhy->GetChannelWidth(),
2427 txPpduPhy->GetPhyBand(),
2428 txPpduPhy->GetChannelNumber(),
2429 txPpduPhy->GetChannelWidth(),
2443 delay + checkResultsDelay,
2451 txPpduPhy->GetCurrentFrequencyRange(),
2452 expectedConnectedPhysPerChannel);
2473 txPpduPhy->GetPhyBand(),
2474 txPpduPhy->GetChannelNumber(),
2475 txPpduPhy->GetChannelWidth(),
2495 m_txPhys.at(0)->GetChannelNumber(),
2506 txPpduPhy->GetPhyBand(),
2507 txPpduPhy->GetChannelNumber(),
2508 txPpduPhy->GetChannelWidth(),
2537 m_rxPhys.at(2)->GetChannelNumber(),
2548 txPpduPhy->GetPhyBand(),
2549 txPpduPhy->GetChannelNumber(),
2550 txPpduPhy->GetChannelWidth(),
2570 txPpduPhy->GetCurrentFrequencyRange(),
2571 expectedConnectedPhysPerChannel);
2601 void DoRun()
override;
2605 :
TestCase(
"Check PHY interfaces added to PHY instances using helper")
2616 phyHelper.
Set(0,
"ChannelSettings",
StringValue(
"{2, 0, BAND_2_4GHZ, 0}"));
2617 phyHelper.
Set(1,
"ChannelSettings",
StringValue(
"{36, 0, BAND_5GHZ, 0}"));
2618 phyHelper.
Set(2,
"ChannelSettings",
StringValue(
"{1, 0, BAND_6GHZ, 0}"));
2636 "Incorrect number of PHY interfaces added to PHY link ID 0");
2643 "Incorrect number of PHY interfaces added to PHY link ID 1");
2650 "Incorrect number of PHY interfaces added to PHY link ID 2");
2663 "Incorrect number of PHY interfaces added to PHY link ID 0");
2666 "Incorrect PHY interfaces added to PHY link ID 0");
2672 "Incorrect number of PHY interfaces added to PHY link ID 1");
2675 "Incorrect PHY interfaces added to PHY link ID 1");
2681 "Incorrect number of PHY interfaces added to PHY link ID 2");
2684 "Incorrect PHY interfaces added to PHY link ID 2");
2695 "Incorrect number of PHY interfaces added to PHY link ID 0");
2698 "Incorrect PHY interfaces added to PHY link ID 0");
2701 "Incorrect PHY interfaces added to PHY link ID 0");
2707 "Incorrect number of PHY interfaces added to PHY link ID 1");
2710 "Incorrect PHY interfaces added to PHY link ID 1");
2716 "Incorrect number of PHY interfaces added to PHY link ID 2");
2719 "Incorrect PHY interfaces added to PHY link ID 2");
2730 "Incorrect number of PHY interfaces added to PHY link ID 0");
2733 "Incorrect PHY interfaces added to PHY link ID 0");
2736 "Incorrect PHY interfaces added to PHY link ID 0");
2739 "Incorrect PHY interfaces added to PHY link ID 0");
2745 "Incorrect number of PHY interfaces added to PHY link ID 1");
2748 "Incorrect PHY interfaces added to PHY link ID 0");
2751 "Incorrect PHY interfaces added to PHY link ID 0");
2754 "Incorrect PHY interfaces added to PHY link ID 0");
2760 "Incorrect number of PHY interfaces added to PHY link ID 2");
2763 "Incorrect PHY interfaces added to PHY link ID 0");
2766 "Incorrect PHY interfaces added to PHY link ID 0");
2769 "Incorrect PHY interfaces added to PHY link ID 0");
2798 TestCase::Duration::QUICK);
2802 TestCase::Duration::QUICK);
2806 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 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 RxSuccessSta(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function for STA.
void CheckResults(bool expectSuccess)
Verify results.
void Send160MhzPpdu()
Send 160MHz PPDU function.
Spectrum Wifi Phy Basic Test.
void SpectrumWifiPhyRxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
~SpectrumWifiPhyBasicTest() override
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.
bool m_trackSignalsInactiveInterfaces
flag to indicate whether signals coming from inactive spectrum PHY interfaces are tracked during the ...
void RxSuccess(std::size_t index, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function.
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.
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
void NotifyRxEndError() override
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
uint32_t m_notifyRxEndError
notify receive end error
~TestPhyListener() override=default
static WifiMode GetHeMcs11()
Return MCS 11 from HE MCS values.
static WifiMode GetHeMcs0()
Return MCS 0 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.
HeRuBands GetHeRuBands(Ptr< WifiSpectrumPhyInterface > spectrumPhyInterface, MHz_u guardBandwidth)
This function computes the RU bands that belong to a given spectrum PHY interface.
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.
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.
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=-20, dBr_u minOuterband=-28, dBr_u lowestPoint=-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.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
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.
constexpr FrequencyRange WIFI_SPECTRUM_5_GHZ
Identifier for the frequency range covering the wifi spectrum in the 5 GHz band.
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.