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:
committed by
Sébastien Deronne
parent
173af90fdd
commit
64236528c8
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user