wifi: Keep tracked events in interference helper upon channel switching for bands that are still present in the new spectrum model

This commit is contained in:
Sébastien Deronne
2023-02-12 14:35:39 +01:00
committed by Sébastien Deronne
parent 173af90fdd
commit 64236528c8
4 changed files with 117 additions and 7 deletions

View File

@@ -295,6 +295,74 @@ InterferenceHelper::AddBand(WifiSpectrumBand band, const FrequencyRange& range)
m_firstPowers[range].insert({band, 0.0});
}
void
InterferenceHelper::UpdateBands(const std::vector<WifiSpectrumBand>& bands,
const FrequencyRange& range,
int32_t offset)
{
NS_LOG_FUNCTION(this << range << offset);
NS_ABORT_IF(m_niChanges.count(range) == 0);
auto& niChangesPerBand = m_niChanges.at(range);
auto& firstPowerPerBand = m_firstPowers.at(range);
// start index of the lowest band
const auto minStartIndex =
(std::min_element(bands.cbegin(), bands.cend(), [](const auto& lhs, const auto& rhs) {
return lhs.first < rhs.first;
}))->first;
// stop index of the highest band
const auto maxStopIndex =
(std::max_element(bands.cbegin(), bands.cend(), [](const auto& lhs, const auto& rhs) {
return lhs.second < rhs.second;
}))->second;
// index of DC so that it can be skipped
const auto dcIndex =
static_cast<uint32_t>(minStartIndex + ((maxStopIndex - minStartIndex) / 2) + 0.5);
NiChangesPerBand newNiChangesPerBand{};
FirstPowerPerBand newFirstPowerPerBand{};
for (auto it = niChangesPerBand.begin(); it != niChangesPerBand.end();)
{
// apply offset to start index and stop index to get the corresponding ones in the new
// spectrum model
auto newBandStartIndex =
static_cast<uint32_t>(static_cast<int32_t>(it->first.first) + offset);
auto newBandStopIndex =
static_cast<uint32_t>(static_cast<int32_t>(it->first.second) + offset);
const auto erase = std::find_if(bands.cbegin(),
bands.cend(),
[newBandStartIndex, newBandStopIndex](const auto& item) {
return ((newBandStartIndex == item.first) &&
(newBandStopIndex == item.second));
}) == std::end(bands);
if (erase)
{
// band does not belong to the new bands, erase it
it->second.clear();
}
else
{
if (newBandStartIndex >= dcIndex)
{
// skip DC
newBandStartIndex++;
}
const auto band = std::make_pair(newBandStartIndex, newBandStopIndex);
newNiChangesPerBand.insert({band, std::move(it->second)});
newFirstPowerPerBand.insert({band, firstPowerPerBand.at(it->first)});
}
it = niChangesPerBand.erase(it);
}
niChangesPerBand.swap(newNiChangesPerBand);
firstPowerPerBand.swap(newFirstPowerPerBand);
for (const auto& band : bands)
{
if (!HasBand(band, range))
{
// this is a new band, add it
AddBand(band, range);
}
}
}
void
InterferenceHelper::SetNoiseFigure(double value)
{

View File

@@ -168,6 +168,17 @@ class InterferenceHelper : public Object
*/
bool HasBand(WifiSpectrumBand band, const FrequencyRange& range) const;
/**
* Update the frequency bands for a given frequency range when the spectrum model is changed.
*
* \param bands the bands to be added in the new spectrum model
* \param range the frequency range the bands belong to
* \param offset the offset to convert start and stop indices from old to new spectrum model
*/
void UpdateBands(const std::vector<WifiSpectrumBand>& bands,
const FrequencyRange& range,
int32_t offset);
/**
* Set the noise figure.
*

View File

@@ -122,15 +122,16 @@ SpectrumWifiPhy::DoInitialize()
}
void
SpectrumWifiPhy::UpdateInterferenceHelperBands()
SpectrumWifiPhy::UpdateInterferenceHelperBands(std::optional<int32_t> indicesOffset)
{
NS_LOG_FUNCTION(this);
NS_ASSERT(!m_spectrumPhyInterfaces.empty());
uint16_t channelWidth = GetChannelWidth();
std::vector<WifiSpectrumBand> bands;
std::vector<WifiSpectrumBand> ccaBands{};
std::vector<WifiSpectrumBand> ruBands{};
if (channelWidth < 20)
{
bands.push_back(GetBand(channelWidth));
ccaBands.push_back(GetBand(channelWidth));
}
else
{
@@ -138,7 +139,7 @@ SpectrumWifiPhy::UpdateInterferenceHelperBands()
{
for (uint32_t i = 0; i < (channelWidth / bw); ++i)
{
bands.push_back(GetBand(bw, i));
ccaBands.push_back(GetBand(bw, i));
}
}
}
@@ -190,9 +191,11 @@ SpectrumWifiPhy::UpdateInterferenceHelperBands()
}
for (const auto& bandRuPair : m_ruBands[channelWidth])
{
bands.push_back(bandRuPair.first);
ruBands.push_back(bandRuPair.first);
}
}
auto bands{ccaBands};
bands.insert(bands.end(), ruBands.begin(), ruBands.end());
const auto bandsChanged = std::any_of(bands.cbegin(), bands.cend(), [&](const auto& band) {
return !m_interference->HasBand(band, GetCurrentFrequencyRange());
});
@@ -200,6 +203,23 @@ SpectrumWifiPhy::UpdateInterferenceHelperBands()
{
return;
}
if (indicesOffset.has_value())
{
// indicesOffset is computed for multiple of 20 MHz subchannels, and since RU bands are not
// used for CCA, we can here safely erase RU bands (UpdateBands will erase them since they
// are not passed to the call)
m_interference->UpdateBands(ccaBands, GetCurrentFrequencyRange(), *indicesOffset);
// add new RU bands
if (!ruBands.empty())
{
for (const auto& band : ruBands)
{
NS_ASSERT(!m_interference->HasBand(band, GetCurrentFrequencyRange()));
m_interference->AddBand(band, GetCurrentFrequencyRange());
}
}
return;
}
m_interference->RemoveBands(GetCurrentFrequencyRange());
for (const auto& band : bands)
{
@@ -248,6 +268,14 @@ SpectrumWifiPhy::ResetSpectrumModel()
{
NS_LOG_FUNCTION(this);
std::optional<int32_t> indicesOffset{};
if (m_currentSpectrumPhyInterface->GetCenterFrequency() > 0)
{
indicesOffset =
(2e6 * (GetFrequency() - m_currentSpectrumPhyInterface->GetCenterFrequency())) /
GetBandBandwidth();
}
// Replace existing spectrum model with new one
const auto channelWidth = GetChannelWidth();
m_currentSpectrumPhyInterface->SetRxSpectrumModel(GetFrequency(),
@@ -257,7 +285,7 @@ SpectrumWifiPhy::ResetSpectrumModel()
m_currentSpectrumPhyInterface->GetChannel()->AddRx(m_currentSpectrumPhyInterface);
UpdateInterferenceHelperBands();
UpdateInterferenceHelperBands(indicesOffset);
}
void

View File

@@ -201,10 +201,13 @@ class SpectrumWifiPhy : public WifiPhy
* Perform run-time spectrum model change
*/
void ResetSpectrumModel();
/**
* This function is called to update the bands handled by the InterferenceHelper.
* \param indicesOffset the offset to convert start and stop indices from old to new spectrum
* model, if bands are already handled by the InterferenceHelper
*/
void UpdateInterferenceHelperBands();
void UpdateInterferenceHelperBands(std::optional<int32_t> indicesOffset);
/**
* Determine whether the PHY shall issue a PHY-RXSTART.indication primitive in response to a