wifi: Handle 80+80MHz as a single 160 MHz band to handle reception of 80+80MHz PPDUs
This commit is contained in:
@@ -997,15 +997,21 @@ HePhy::GetRuBandForTx(const WifiTxVector& txVector, uint16_t staId) const
|
||||
ru.GetPhyIndex(channelWidth, m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(20)));
|
||||
// for a TX spectrum, the guard bandwidth is a function of the transmission channel width
|
||||
// and the spectrum width equals the transmission channel width (hence bandIndex equals 0)
|
||||
auto indices = ConvertHeRuSubcarriers(channelWidth,
|
||||
GetGuardBandwidth(channelWidth),
|
||||
m_wifiPhy->GetOperatingChannel().GetFrequencies(),
|
||||
m_wifiPhy->GetChannelWidth(),
|
||||
m_wifiPhy->GetSubcarrierSpacing(),
|
||||
{group.front().first, group.back().second},
|
||||
0);
|
||||
auto frequencies = m_wifiPhy->ConvertIndicesToFrequencies(indices);
|
||||
return {indices, frequencies};
|
||||
const auto indices = ConvertHeRuSubcarriers(channelWidth,
|
||||
GetGuardBandwidth(channelWidth),
|
||||
m_wifiPhy->GetOperatingChannel().GetFrequencies(),
|
||||
m_wifiPhy->GetChannelWidth(),
|
||||
m_wifiPhy->GetSubcarrierSpacing(),
|
||||
{group.front().first, group.back().second},
|
||||
0);
|
||||
WifiSpectrumBandInfo ruBandForTx{};
|
||||
for (const auto& indicesPerSegment : indices)
|
||||
{
|
||||
ruBandForTx.indices.emplace_back(indicesPerSegment);
|
||||
ruBandForTx.frequencies.emplace_back(
|
||||
m_wifiPhy->ConvertIndicesToFrequencies(indicesPerSegment));
|
||||
}
|
||||
return ruBandForTx;
|
||||
}
|
||||
|
||||
WifiSpectrumBandInfo
|
||||
@@ -1021,7 +1027,7 @@ HePhy::GetRuBandForRx(const WifiTxVector& txVector, uint16_t staId) const
|
||||
ru.GetPhyIndex(channelWidth, m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(20)));
|
||||
// for an RX spectrum, the guard bandwidth is a function of the operating channel width
|
||||
// and the spectrum width equals the operating channel width
|
||||
auto indices = ConvertHeRuSubcarriers(
|
||||
const auto indices = ConvertHeRuSubcarriers(
|
||||
channelWidth,
|
||||
GetGuardBandwidth(m_wifiPhy->GetChannelWidth()),
|
||||
m_wifiPhy->GetOperatingChannel().GetFrequencies(),
|
||||
@@ -1029,8 +1035,14 @@ HePhy::GetRuBandForRx(const WifiTxVector& txVector, uint16_t staId) const
|
||||
m_wifiPhy->GetSubcarrierSpacing(),
|
||||
{group.front().first, group.back().second},
|
||||
m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(channelWidth));
|
||||
auto frequencies = m_wifiPhy->ConvertIndicesToFrequencies(indices);
|
||||
return {indices, frequencies};
|
||||
WifiSpectrumBandInfo ruBandForRx{};
|
||||
for (const auto& indicesPerSegment : indices)
|
||||
{
|
||||
ruBandForRx.indices.emplace_back(indicesPerSegment);
|
||||
ruBandForRx.frequencies.emplace_back(
|
||||
m_wifiPhy->ConvertIndicesToFrequencies(indicesPerSegment));
|
||||
}
|
||||
return ruBandForRx;
|
||||
}
|
||||
|
||||
WifiSpectrumBandInfo
|
||||
@@ -1052,7 +1064,7 @@ HePhy::GetNonOfdmaBand(const WifiTxVector& txVector, uint16_t staId) const
|
||||
nonOfdmaRu.GetRuType(),
|
||||
nonOfdmaRu.GetPhyIndex(channelWidth,
|
||||
m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(20)));
|
||||
auto indices = ConvertHeRuSubcarriers(
|
||||
const auto indices = ConvertHeRuSubcarriers(
|
||||
channelWidth,
|
||||
GetGuardBandwidth(m_wifiPhy->GetChannelWidth()),
|
||||
m_wifiPhy->GetOperatingChannel().GetFrequencies(),
|
||||
@@ -1060,8 +1072,14 @@ HePhy::GetNonOfdmaBand(const WifiTxVector& txVector, uint16_t staId) const
|
||||
m_wifiPhy->GetSubcarrierSpacing(),
|
||||
{groupPreamble.front().first, groupPreamble.back().second},
|
||||
m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(channelWidth));
|
||||
auto frequencies = m_wifiPhy->ConvertIndicesToFrequencies(indices);
|
||||
return {indices, frequencies};
|
||||
WifiSpectrumBandInfo nonOfdmaBand{};
|
||||
for (const auto& indicesPerSegment : indices)
|
||||
{
|
||||
nonOfdmaBand.indices.emplace_back(indicesPerSegment);
|
||||
nonOfdmaBand.frequencies.emplace_back(
|
||||
m_wifiPhy->ConvertIndicesToFrequencies(indicesPerSegment));
|
||||
}
|
||||
return nonOfdmaBand;
|
||||
}
|
||||
|
||||
ChannelWidthMhz
|
||||
@@ -1837,7 +1855,7 @@ HePhy::GetRxPpduFromTxPpdu(Ptr<const WifiPpdu> ppdu)
|
||||
return VhtPhy::GetRxPpduFromTxPpdu(ppdu);
|
||||
}
|
||||
|
||||
WifiSpectrumBandIndices
|
||||
std::vector<WifiSpectrumBandIndices>
|
||||
HePhy::ConvertHeRuSubcarriers(ChannelWidthMhz bandWidth,
|
||||
ChannelWidthMhz guardBandwidth,
|
||||
const std::vector<uint16_t>& centerFrequencies,
|
||||
@@ -1846,14 +1864,18 @@ HePhy::ConvertHeRuSubcarriers(ChannelWidthMhz bandWidth,
|
||||
HeRu::SubcarrierRange subcarrierRange,
|
||||
uint8_t bandIndex)
|
||||
{
|
||||
const auto segmentWidth = (totalWidth / centerFrequencies.size());
|
||||
NS_ASSERT_MSG(bandWidth <= segmentWidth,
|
||||
"Bandwidth (" << bandWidth << ") cannot exceed contiguous segment width ("
|
||||
<< segmentWidth << ")");
|
||||
WifiSpectrumBandIndices convertedSubcarriers;
|
||||
NS_ASSERT_MSG(bandWidth <= totalWidth,
|
||||
"Bandwidth (" << bandWidth << ") cannot exceed total operating channel width ("
|
||||
<< totalWidth << ")");
|
||||
std::vector<WifiSpectrumBandIndices> convertedSubcarriers{};
|
||||
guardBandwidth /= centerFrequencies.size();
|
||||
const auto nGuardBands =
|
||||
static_cast<uint32_t>(((2 * guardBandwidth * 1e6) / subcarrierSpacing) + 0.5);
|
||||
const auto numBands = totalWidth / bandWidth;
|
||||
if (bandWidth > (totalWidth / centerFrequencies.size()))
|
||||
{
|
||||
NS_ASSERT(bandIndex == 0);
|
||||
bandWidth /= centerFrequencies.size();
|
||||
}
|
||||
uint32_t centerFrequencyIndex = 0;
|
||||
switch (bandWidth)
|
||||
{
|
||||
@@ -1876,18 +1898,28 @@ HePhy::ConvertHeRuSubcarriers(ChannelWidthMhz bandWidth,
|
||||
|
||||
const auto numBandsInBand = static_cast<size_t>(bandWidth * 1e6 / subcarrierSpacing);
|
||||
centerFrequencyIndex += numBandsInBand * bandIndex;
|
||||
|
||||
if ((centerFrequencies.size() > 1) && (bandIndex >= (numBands / 2)))
|
||||
// start and stop subcarriers might be in different frequency segments, hence define a low and a
|
||||
// high center frequency
|
||||
auto centerFrequencyIndexLow = centerFrequencyIndex;
|
||||
auto centerFrequencyIndexHigh = centerFrequencyIndex;
|
||||
if (centerFrequencies.size() > 1)
|
||||
{
|
||||
const auto numBandsBetweenSegments =
|
||||
SpectrumWifiPhy::GetNumBandsBetweenSegments(centerFrequencies,
|
||||
totalWidth,
|
||||
subcarrierSpacing);
|
||||
centerFrequencyIndex += numBandsBetweenSegments;
|
||||
if (subcarrierRange.first > 0)
|
||||
{
|
||||
centerFrequencyIndexLow += numBandsBetweenSegments;
|
||||
}
|
||||
if (subcarrierRange.second > 0)
|
||||
{
|
||||
centerFrequencyIndexHigh += numBandsBetweenSegments;
|
||||
}
|
||||
}
|
||||
|
||||
convertedSubcarriers.first = centerFrequencyIndex + subcarrierRange.first;
|
||||
convertedSubcarriers.second = centerFrequencyIndex + subcarrierRange.second;
|
||||
convertedSubcarriers.emplace_back(centerFrequencyIndexLow + subcarrierRange.first,
|
||||
centerFrequencyIndexHigh + subcarrierRange.second);
|
||||
++bandIndex;
|
||||
return convertedSubcarriers;
|
||||
}
|
||||
|
||||
|
||||
@@ -453,9 +453,10 @@ class HePhy : public VhtPhy
|
||||
* \return the converted subcarriers
|
||||
*
|
||||
* This is a helper function to convert HE RU subcarriers, which are relative to the center
|
||||
* frequency subcarrier, to the indexes used by the Spectrum model.
|
||||
* frequency subcarrier, to the indexes used by the Spectrum model. The size of the returned
|
||||
* vector corresponds to the number of segments covered by the HE RU.
|
||||
*/
|
||||
static WifiSpectrumBandIndices ConvertHeRuSubcarriers(
|
||||
static std::vector<WifiSpectrumBandIndices> ConvertHeRuSubcarriers(
|
||||
ChannelWidthMhz bandWidth,
|
||||
ChannelWidthMhz guardBandwidth,
|
||||
const std::vector<uint16_t>& centerFrequencies,
|
||||
|
||||
@@ -848,8 +848,12 @@ bool
|
||||
InterferenceHelper::IsBandInFrequencyRange(const WifiSpectrumBandInfo& band,
|
||||
const FrequencyRange& freqRange) const
|
||||
{
|
||||
return ((band.frequencies.second > (freqRange.minFrequency * 1e6)) &&
|
||||
(band.frequencies.first < (freqRange.maxFrequency * 1e6)));
|
||||
return std::all_of(band.frequencies.cbegin(),
|
||||
band.frequencies.cend(),
|
||||
[&freqRange](const auto& freqs) {
|
||||
return ((freqs.second > (freqRange.minFrequency * 1e6)) &&
|
||||
(freqs.first < (freqRange.maxFrequency * 1e6)));
|
||||
});
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "ns3/spectrum-channel.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#undef NS_LOG_APPEND_CONTEXT
|
||||
#define NS_LOG_APPEND_CONTEXT WIFI_PHY_NS_LOG_APPEND_CONTEXT(Ptr(this))
|
||||
@@ -178,9 +179,15 @@ SpectrumWifiPhy::GetHeRuBands(Ptr<WifiSpectrumPhyInterface> spectrumPhyInterface
|
||||
GetSubcarrierSpacing(),
|
||||
subcarrierRange,
|
||||
i);
|
||||
const auto bandFrequencies =
|
||||
ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, bandIndices);
|
||||
WifiSpectrumBandInfo band = {bandIndices, bandFrequencies};
|
||||
|
||||
WifiSpectrumBandInfo band{};
|
||||
for (const auto& indicesPerSegment : bandIndices)
|
||||
{
|
||||
band.indices.emplace_back(indicesPerSegment);
|
||||
band.frequencies.emplace_back(
|
||||
ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface,
|
||||
indicesPerSegment));
|
||||
}
|
||||
std::size_t index =
|
||||
(bw == 160 && phyIndex > nRus / 2 ? phyIndex - nRus / 2 : phyIndex);
|
||||
const auto p20Index = GetOperatingChannel().GetPrimaryChannelIndex(20);
|
||||
@@ -502,7 +509,13 @@ SpectrumWifiPhy::StartRx(Ptr<SpectrumSignalParameters> rxParams,
|
||||
ChannelWidthMhz prevBw = 0;
|
||||
for (const auto& band : bands)
|
||||
{
|
||||
ChannelWidthMhz bw = (band.frequencies.second - band.frequencies.first) / 1e6;
|
||||
const auto bw =
|
||||
std::accumulate(band.frequencies.cbegin(),
|
||||
band.frequencies.cend(),
|
||||
0,
|
||||
[](ChannelWidthMhz sum, const auto& startStopFreqs) {
|
||||
return sum + ((startStopFreqs.second - startStopFreqs.first) / 1e6);
|
||||
});
|
||||
NS_ASSERT(bw <= channelWidth);
|
||||
index = ((bw != prevBw) ? 0 : (index + 1));
|
||||
double rxPowerPerBandW =
|
||||
@@ -695,9 +708,19 @@ SpectrumWifiPhy::GetBandForInterface(Ptr<WifiSpectrumPhyInterface> spectrumPhyIn
|
||||
uint8_t bandIndex /* = 0 */)
|
||||
{
|
||||
const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
|
||||
NS_ASSERT_MSG(bandWidth <= (channelWidth / spectrumPhyInterface->GetCenterFrequencies().size()),
|
||||
"Bandwidth cannot exceed segment width");
|
||||
NS_ASSERT_MSG(bandWidth <= channelWidth,
|
||||
"Bandwidth cannot exceed total operating channel width");
|
||||
const auto subcarrierSpacing = GetSubcarrierSpacing();
|
||||
WifiSpectrumBandInfo bandInfo;
|
||||
std::size_t numSegments = 1;
|
||||
if (const auto segmentWidth =
|
||||
(channelWidth / spectrumPhyInterface->GetCenterFrequencies().size());
|
||||
bandWidth > segmentWidth)
|
||||
{
|
||||
NS_ASSERT(bandIndex == 0);
|
||||
numSegments = spectrumPhyInterface->GetCenterFrequencies().size();
|
||||
bandWidth /= spectrumPhyInterface->GetCenterFrequencies().size();
|
||||
}
|
||||
const auto numBandsInBand = static_cast<size_t>(bandWidth * 1e6 / subcarrierSpacing);
|
||||
auto numBandsInChannel = static_cast<size_t>(channelWidth * 1e6 / subcarrierSpacing);
|
||||
const auto numBands = channelWidth / bandWidth;
|
||||
@@ -709,31 +732,37 @@ SpectrumWifiPhy::GetBandForInterface(Ptr<WifiSpectrumPhyInterface> spectrumPhyIn
|
||||
size_t totalNumBands = rxSpectrumModel->GetNumBands();
|
||||
NS_ASSERT_MSG((numBandsInChannel % 2 == 1) && (totalNumBands % 2 == 1),
|
||||
"Should have odd number of bands");
|
||||
NS_ASSERT_MSG(bandIndex < numBands, "Band index is out of bound");
|
||||
NS_ASSERT(totalNumBands >= numBandsInChannel);
|
||||
const auto numBandsBetweenSegments =
|
||||
GetNumBandsBetweenSegments(spectrumPhyInterface->GetCenterFrequencies(),
|
||||
channelWidth,
|
||||
GetSubcarrierSpacing());
|
||||
auto startIndex = ((totalNumBands - numBandsInChannel - numBandsBetweenSegments) / 2) +
|
||||
(bandIndex * numBandsInBand);
|
||||
if (bandIndex >= (numBands / 2))
|
||||
for (std::size_t segmentIndex = 0; segmentIndex < numSegments; ++segmentIndex)
|
||||
{
|
||||
startIndex += numBandsBetweenSegments;
|
||||
NS_ASSERT_MSG(bandIndex < numBands, "Band index is out of bound");
|
||||
NS_ASSERT(totalNumBands >= numBandsInChannel);
|
||||
const auto numBandsBetweenSegments =
|
||||
GetNumBandsBetweenSegments(spectrumPhyInterface->GetCenterFrequencies(),
|
||||
channelWidth,
|
||||
GetSubcarrierSpacing());
|
||||
auto startIndex = ((totalNumBands - numBandsInChannel - numBandsBetweenSegments) / 2) +
|
||||
(bandIndex * numBandsInBand);
|
||||
if (bandIndex >= (numBands / 2))
|
||||
{
|
||||
startIndex += numBandsBetweenSegments;
|
||||
}
|
||||
auto stopIndex = startIndex + numBandsInBand - 1;
|
||||
auto frequencies =
|
||||
ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, {startIndex, stopIndex});
|
||||
auto freqRange = spectrumPhyInterface->GetFrequencyRange();
|
||||
NS_ASSERT(frequencies.first >= (freqRange.minFrequency * 1e6));
|
||||
NS_ASSERT(frequencies.second <= (freqRange.maxFrequency * 1e6));
|
||||
NS_ASSERT((frequencies.second - frequencies.first) == (bandWidth * 1e6));
|
||||
if (startIndex >= totalNumBands / 2)
|
||||
{
|
||||
// step past DC
|
||||
startIndex += 1;
|
||||
}
|
||||
bandInfo.indices.emplace_back(startIndex, stopIndex);
|
||||
bandInfo.frequencies.emplace_back(frequencies);
|
||||
++bandIndex;
|
||||
}
|
||||
auto stopIndex = startIndex + numBandsInBand - 1;
|
||||
auto frequencies =
|
||||
ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, {startIndex, stopIndex});
|
||||
auto freqRange = spectrumPhyInterface->GetFrequencyRange();
|
||||
NS_ASSERT(frequencies.first >= (freqRange.minFrequency * 1e6));
|
||||
NS_ASSERT(frequencies.second <= (freqRange.maxFrequency * 1e6));
|
||||
NS_ASSERT((frequencies.second - frequencies.first) == (bandWidth * 1e6));
|
||||
if (startIndex >= totalNumBands / 2)
|
||||
{
|
||||
// step past DC
|
||||
startIndex += 1;
|
||||
}
|
||||
return {{startIndex, stopIndex}, frequencies};
|
||||
return bandInfo;
|
||||
}
|
||||
|
||||
WifiSpectrumBandInfo
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "ns3/ptr.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* \file
|
||||
@@ -60,8 +61,10 @@ using WifiSpectrumBandFrequencies = std::pair<uint64_t, uint64_t>;
|
||||
/// WifiSpectrumBandInfo structure containing info about a spectrum band
|
||||
struct WifiSpectrumBandInfo
|
||||
{
|
||||
WifiSpectrumBandIndices indices; //!< the start and stop indices of the band
|
||||
WifiSpectrumBandFrequencies frequencies; //!< the start and stop frequencies of the band
|
||||
std::vector<WifiSpectrumBandIndices>
|
||||
indices; //!< the start and stop indices for each segment of the band
|
||||
std::vector<WifiSpectrumBandFrequencies>
|
||||
frequencies; //!< the start and stop frequencies for each segment of the band
|
||||
};
|
||||
|
||||
/// vector of spectrum bands
|
||||
@@ -73,13 +76,20 @@ using WifiSpectrumBands = std::vector<WifiSpectrumBandInfo>;
|
||||
*
|
||||
* \param lhs the band on the left of operator<
|
||||
* \param rhs the band on the right of operator<
|
||||
* \return true if the start/stop frequencies of left are lower than the start/stop frequencies of
|
||||
* right, false otherwise
|
||||
* \return true if the start/stop frequencies of the first segment of left are lower than the
|
||||
* start/stop frequencies of the first segment of right. If the first segment is the same for left
|
||||
* and right, it return true if the start/stop frequencies of the second segment of left are lower
|
||||
* than the start/stop frequencies of the second segment of right. Otherwise, the function return
|
||||
* false.
|
||||
*/
|
||||
inline bool
|
||||
operator<(const WifiSpectrumBandInfo& lhs, const WifiSpectrumBandInfo& rhs)
|
||||
{
|
||||
return lhs.frequencies < rhs.frequencies;
|
||||
if (lhs.frequencies.front() == rhs.frequencies.front())
|
||||
{
|
||||
return lhs.frequencies.back() < rhs.frequencies.back();
|
||||
}
|
||||
return lhs.frequencies.front() < rhs.frequencies.front();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,8 +102,14 @@ operator<(const WifiSpectrumBandInfo& lhs, const WifiSpectrumBandInfo& rhs)
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, const WifiSpectrumBandInfo& band)
|
||||
{
|
||||
os << "indices: [" << band.indices.first << "-" << band.indices.second << "], frequencies: ["
|
||||
<< band.frequencies.first << "Hz-" << band.frequencies.second << "Hz]";
|
||||
NS_ASSERT(band.indices.size() == band.frequencies.size());
|
||||
for (std::size_t segmentIndex = 0; segmentIndex < band.indices.size(); ++segmentIndex)
|
||||
{
|
||||
os << "indices segment" << segmentIndex << ": [" << band.indices.at(segmentIndex).first
|
||||
<< "-" << band.indices.at(segmentIndex).second << "], frequencies segment"
|
||||
<< segmentIndex << ": [" << band.frequencies.at(segmentIndex).first << "Hz-"
|
||||
<< band.frequencies.at(segmentIndex).second << "Hz] ";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@@ -653,10 +653,18 @@ WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity(
|
||||
ChannelWidthMhz channelWidth,
|
||||
double txPowerW,
|
||||
ChannelWidthMhz guardBandwidth,
|
||||
const WifiSpectrumBandIndices& ru)
|
||||
const std::vector<WifiSpectrumBandIndices>& ru)
|
||||
{
|
||||
auto printRuIndices = [](const std::vector<WifiSpectrumBandIndices>& v) {
|
||||
std::stringstream ss;
|
||||
for (const auto& [start, stop] : v)
|
||||
{
|
||||
ss << start << "-" << stop << " ";
|
||||
}
|
||||
return ss.str();
|
||||
};
|
||||
NS_LOG_FUNCTION(printFrequencies(centerFrequencies)
|
||||
<< channelWidth << txPowerW << guardBandwidth << ru.first << ru.second);
|
||||
<< channelWidth << txPowerW << guardBandwidth << printRuIndices(ru));
|
||||
uint32_t carrierSpacing = 78125;
|
||||
Ptr<SpectrumValue> c = Create<SpectrumValue>(
|
||||
GetSpectrumModel(centerFrequencies, channelWidth, carrierSpacing, guardBandwidth));
|
||||
@@ -664,18 +672,18 @@ WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity(
|
||||
// Build spectrum mask
|
||||
auto vit = c->ValuesBegin();
|
||||
auto bit = c->ConstBandsBegin();
|
||||
double txPowerPerBandW = (txPowerW / (ru.second - ru.first + 1)); // FIXME: null subcarriers
|
||||
const auto numSubcarriers =
|
||||
std::accumulate(ru.cbegin(), ru.cend(), 0, [](uint32_t sum, const auto& p) {
|
||||
return sum + (p.second - p.first) + 1;
|
||||
});
|
||||
double txPowerPerBandW = (txPowerW / numSubcarriers); // FIXME: null subcarriers
|
||||
uint32_t numBands = c->GetSpectrumModel()->GetNumBands();
|
||||
for (size_t i = 0; i < numBands; i++, vit++, bit++)
|
||||
{
|
||||
if (i < ru.first || i > ru.second) // outside the spectrum mask
|
||||
{
|
||||
*vit = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*vit = (txPowerPerBandW / (bit->fh - bit->fl));
|
||||
}
|
||||
const auto allocated = std::any_of(ru.cbegin(), ru.cend(), [i](const auto& p) {
|
||||
return (i >= p.first && i <= p.second);
|
||||
});
|
||||
*vit = allocated ? (txPowerPerBandW / (bit->fh - bit->fl)) : 0.0;
|
||||
}
|
||||
|
||||
return c;
|
||||
@@ -1131,28 +1139,30 @@ WifiSpectrumValueHelper::DbmToW(double dBm)
|
||||
}
|
||||
|
||||
double
|
||||
WifiSpectrumValueHelper::GetBandPowerW(Ptr<SpectrumValue> psd, const WifiSpectrumBandIndices& band)
|
||||
WifiSpectrumValueHelper::GetBandPowerW(Ptr<SpectrumValue> psd,
|
||||
const std::vector<WifiSpectrumBandIndices>& segments)
|
||||
{
|
||||
auto valueIt = psd->ConstValuesBegin() + band.first;
|
||||
auto end = psd->ConstValuesBegin() + band.second;
|
||||
auto bandIt = psd->ConstBandsBegin() + band.first; // all bands have same width
|
||||
auto powerWattPerHertz{0.0};
|
||||
auto bandIt = psd->ConstBandsBegin() + segments.front().first; // all bands have same width
|
||||
const auto bandWidth = (bandIt->fh - bandIt->fl);
|
||||
NS_ASSERT_MSG(bandWidth >= 0.0,
|
||||
"Invalid width for subband [" << bandIt->fl << ";" << bandIt->fh << "]");
|
||||
uint32_t index [[maybe_unused]] = 0;
|
||||
auto powerWattPerHertz{0.0};
|
||||
while (valueIt <= end)
|
||||
for (const auto& [start, stop] : segments)
|
||||
{
|
||||
NS_ASSERT_MSG(*valueIt >= 0.0,
|
||||
"Invalid power value " << *valueIt << " in subband " << index);
|
||||
powerWattPerHertz += *valueIt;
|
||||
++valueIt;
|
||||
++index;
|
||||
auto valueIt = psd->ConstValuesBegin() + start;
|
||||
auto end = psd->ConstValuesBegin() + stop;
|
||||
uint32_t index [[maybe_unused]] = 0;
|
||||
while (valueIt <= end)
|
||||
{
|
||||
NS_ASSERT_MSG(*valueIt >= 0.0,
|
||||
"Invalid power value " << *valueIt << " in subband " << index);
|
||||
powerWattPerHertz += *valueIt;
|
||||
++valueIt;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
const auto power = powerWattPerHertz * bandWidth;
|
||||
NS_ASSERT_MSG(power >= 0.0,
|
||||
"Invalid calculated power " << power << " for band [" << band.first << ";"
|
||||
<< band.second << "]");
|
||||
NS_ASSERT_MSG(power >= 0.0, "Invalid calculated power " << power);
|
||||
return power;
|
||||
}
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ class WifiSpectrumValueHelper
|
||||
ChannelWidthMhz channelWidth,
|
||||
double txPowerW,
|
||||
ChannelWidthMhz guardBandwidth,
|
||||
const WifiSpectrumBandIndices& ru);
|
||||
const std::vector<WifiSpectrumBandIndices>& ru);
|
||||
|
||||
/**
|
||||
* Create a power spectral density corresponding to the noise
|
||||
@@ -348,11 +348,13 @@ class WifiSpectrumValueHelper
|
||||
* Calculate the power of the specified band composed of uniformly-sized sub-bands.
|
||||
*
|
||||
* \param psd received Power Spectral Density in W/Hz
|
||||
* \param band a pair of start and stop indexes that defines the band
|
||||
* \param segments a vector of pair of start and stop indexes that defines each segment of the
|
||||
* band
|
||||
*
|
||||
* \return band power in W
|
||||
*/
|
||||
static double GetBandPowerW(Ptr<SpectrumValue> psd, const WifiSpectrumBandIndices& band);
|
||||
static double GetBandPowerW(Ptr<SpectrumValue> psd,
|
||||
const std::vector<WifiSpectrumBandIndices>& segments);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -146,7 +146,7 @@ YansWifiChannel::Receive(Ptr<YansWifiPhy> phy, Ptr<const WifiPpdu> ppdu, double
|
||||
return;
|
||||
}
|
||||
RxPowerWattPerChannelBand rxPowerW;
|
||||
rxPowerW.insert({{{0, 0}, {0, 0}}, DbmToW(totalRxPowerDbm)}); // dummy band for YANS
|
||||
rxPowerW.insert({{{{0, 0}}, {{0, 0}}}, (DbmToW(totalRxPowerDbm))}); // dummy band for YANS
|
||||
phy->StartReceivePreamble(ppdu, rxPowerW, ppdu->GetTxDuration());
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ YansWifiPhy::SetInterferenceHelper(const Ptr<InterferenceHelper> helper)
|
||||
{
|
||||
WifiPhy::SetInterferenceHelper(helper);
|
||||
// add dummy band for Yans
|
||||
m_interference->AddBand({{0, 0}, {0, 0}});
|
||||
m_interference->AddBand({{{0, 0}}, {{0, 0}}});
|
||||
}
|
||||
|
||||
YansWifiPhy::~YansWifiPhy()
|
||||
@@ -122,7 +122,7 @@ YansWifiPhy::GetTxMaskRejectionParams() const
|
||||
WifiSpectrumBandInfo
|
||||
YansWifiPhy::GetBand(ChannelWidthMhz /*bandWidth*/, uint8_t /*bandIndex*/)
|
||||
{
|
||||
return {{0, 0}, {0, 0}};
|
||||
return {{{0, 0}}, {{0, 0}}};
|
||||
}
|
||||
|
||||
FrequencyRange
|
||||
|
||||
@@ -715,13 +715,14 @@ SpectrumWifiPhyFilterTest::RunOne()
|
||||
std::make_pair(subcarrierGroup.front().first,
|
||||
subcarrierGroup.back().second);
|
||||
const auto band = HePhy::ConvertHeRuSubcarriers(
|
||||
bw,
|
||||
m_rxPhy->GetGuardBandwidth(m_rxChannelWidth),
|
||||
m_rxPhy->GetOperatingChannel().GetFrequencies(),
|
||||
m_rxPhy->GetChannelWidth(),
|
||||
m_rxPhy->GetSubcarrierSpacing(),
|
||||
subcarrierRange,
|
||||
i);
|
||||
bw,
|
||||
m_rxPhy->GetGuardBandwidth(m_rxChannelWidth),
|
||||
m_rxPhy->GetOperatingChannel().GetFrequencies(),
|
||||
m_rxPhy->GetChannelWidth(),
|
||||
m_rxPhy->GetSubcarrierSpacing(),
|
||||
subcarrierRange,
|
||||
i)
|
||||
.front();
|
||||
m_ruBands.insert(band);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user