From 4f43ba2a7a15006cb40a26701f2173f82a34f0ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Sun, 28 May 2023 19:03:22 +0200 Subject: [PATCH] wifi: Support retrieval of default 80+80MHz channel numbers --- src/wifi/model/wifi-phy-operating-channel.cc | 36 +++++++++++++++++--- src/wifi/model/wifi-phy-operating-channel.h | 16 ++++++--- src/wifi/model/wifi-phy.cc | 5 ++- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/wifi/model/wifi-phy-operating-channel.cc b/src/wifi/model/wifi-phy-operating-channel.cc index d39acbd18..c6ba69112 100644 --- a/src/wifi/model/wifi-phy-operating-channel.cc +++ b/src/wifi/model/wifi-phy-operating-channel.cc @@ -399,12 +399,38 @@ WifiPhyOperatingChannel::SetDefault(ChannelWidthMhz width, WifiStandard standard } uint8_t -WifiPhyOperatingChannel::GetDefaultChannelNumber(ChannelWidthMhz width, - WifiStandard standard, - WifiPhyBand band) +WifiPhyOperatingChannel::GetDefaultChannelNumber( + ChannelWidthMhz width, + WifiStandard standard, + WifiPhyBand band, + std::optional previousChannelNumber /* = std::nullopt */) { - auto channelIt = FindFirst(0, 0, width, standard, band); - + auto start = m_frequencyChannels.begin(); + auto prevSegmentChannelIt = m_frequencyChannels.end(); + if (previousChannelNumber) + { + prevSegmentChannelIt = FindFirst(*previousChannelNumber, 0, width, standard, band, start); + if (prevSegmentChannelIt != m_frequencyChannels.end()) + { + start = std::next(prevSegmentChannelIt); + } + } + auto channelIt = FindFirst(0, 0, width, standard, band, start); + if (prevSegmentChannelIt != m_frequencyChannels.end() && channelIt != m_frequencyChannels.end()) + { + const auto prevFreq = prevSegmentChannelIt->frequency; + const auto prevWidth = prevSegmentChannelIt->width; + const auto prevMaxFreq = prevFreq + (prevWidth / 2); + const auto nextFreq = channelIt->frequency; + const auto nextWidth = channelIt->width; + const auto nextMinFreq = nextFreq - (nextWidth / 2); + if (prevMaxFreq <= nextMinFreq) + { + // segments are contiguous to each others, find next segment to make sure they are + // not contiguous + channelIt = FindFirst(0, 0, width, standard, band, std::next(channelIt)); + } + } if (channelIt != m_frequencyChannels.end()) { // a channel matches the specified criteria diff --git a/src/wifi/model/wifi-phy-operating-channel.h b/src/wifi/model/wifi-phy-operating-channel.h index ca9dd02fb..58843807d 100644 --- a/src/wifi/model/wifi-phy-operating-channel.h +++ b/src/wifi/model/wifi-phy-operating-channel.h @@ -26,6 +26,7 @@ #include "ns3/he-ru.h" +#include #include #include #include @@ -167,17 +168,22 @@ class WifiPhyOperatingChannel void SetDefault(ChannelWidthMhz width, WifiStandard standard, WifiPhyBand band); /** - * Get the default channel number of the given width and for the given standard - * and band. + * Get the default channel number for a given segment of the given width and for the given + * standard and band. * * \param width the channel width in MHz * \param standard the standard * \param band the PHY band + * \param previousChannelNumber the channel number of the previous (in frequency) segment (if + * non-contiguous operating channel is used). If there is no place for another segment that is + * not contiguous to that previous one (at a higher frequency), an error is thrown * \return the default channel number */ - static uint8_t GetDefaultChannelNumber(ChannelWidthMhz width, - WifiStandard standard, - WifiPhyBand band); + static uint8_t GetDefaultChannelNumber( + ChannelWidthMhz width, + WifiStandard standard, + WifiPhyBand band, + std::optional previousChannelNumber = std::nullopt); /** * Return the channel number for a given frequency segment. diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index d67f7bea1..cf2977db8 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -1228,6 +1228,7 @@ WifiPhy::DoChannelSwitch() m_channelAccessRequested = false; // Update unspecified parameters with default values + std::optional prevChannelNumber{}; for (auto& [number, width, band, primary20] : m_channelSettings) { if (band == WIFI_PHY_BAND_UNSPECIFIED) @@ -1243,8 +1244,10 @@ WifiPhy::DoChannelSwitch() number = WifiPhyOperatingChannel::GetDefaultChannelNumber(width, m_standard, - static_cast(band)); + static_cast(band), + prevChannelNumber); } + prevChannelNumber = number; } // We need to call SetStandard if this is the first time we set a channel or we