diff --git a/src/wifi/model/wifi-phy-operating-channel.cc b/src/wifi/model/wifi-phy-operating-channel.cc index 7412b75cd..f564b590a 100644 --- a/src/wifi/model/wifi-phy-operating-channel.cc +++ b/src/wifi/model/wifi-phy-operating-channel.cc @@ -277,15 +277,23 @@ operator<<(std::ostream& os, const FrequencyChannelInfo& info) } WifiPhyOperatingChannel::WifiPhyOperatingChannel() - : WifiPhyOperatingChannel(m_frequencyChannels.end()) + : WifiPhyOperatingChannel(std::vector{}) { } WifiPhyOperatingChannel::WifiPhyOperatingChannel(ConstIterator it) - : m_channelIt(it), + : WifiPhyOperatingChannel(std::vector{it}) +{ +} + +WifiPhyOperatingChannel::WifiPhyOperatingChannel(const std::vector& channelIts) + : m_channelIts(channelIts), m_primary20Index(0) { NS_LOG_FUNCTION(this); + NS_ASSERT_MSG(channelIts.size() <= 2, + "Operating channel does not support more than 2 segments"); + SortSegments(); } WifiPhyOperatingChannel::~WifiPhyOperatingChannel() @@ -296,7 +304,7 @@ WifiPhyOperatingChannel::~WifiPhyOperatingChannel() bool WifiPhyOperatingChannel::IsSet() const { - return m_channelIt != m_frequencyChannels.end(); + return !m_channelIts.empty(); } void @@ -308,14 +316,14 @@ WifiPhyOperatingChannel::Set(uint8_t number, { NS_LOG_FUNCTION(this << +number << frequency << width << standard << band); - auto channelIt = FindFirst(number, frequency, width, standard, band); - - if (channelIt != m_frequencyChannels.end() && + if (const auto channelIt = FindFirst(number, frequency, width, standard, band); + channelIt != m_frequencyChannels.cend() && FindFirst(number, frequency, width, standard, band, std::next(channelIt)) == - m_frequencyChannels.end()) + m_frequencyChannels.cend()) { // a unique channel matches the specified criteria - m_channelIt = channelIt; + m_channelIts.resize(1); + m_channelIts.front() = channelIt; m_primary20Index = 0; return; } @@ -404,49 +412,49 @@ uint8_t WifiPhyOperatingChannel::GetNumber() const { NS_ASSERT(IsSet()); - return m_channelIt->number; + return m_channelIts.front()->number; } uint16_t WifiPhyOperatingChannel::GetFrequency() const { NS_ASSERT(IsSet()); - return m_channelIt->frequency; + return m_channelIts.front()->frequency; } ChannelWidthMhz WifiPhyOperatingChannel::GetWidth() const { NS_ASSERT(IsSet()); - return m_channelIt->width; + return m_channelIts.front()->width; } WifiPhyBand WifiPhyOperatingChannel::GetPhyBand() const { NS_ASSERT(IsSet()); - return m_channelIt->band; + return m_channelIts.front()->band; } bool WifiPhyOperatingChannel::IsOfdm() const { NS_ASSERT(IsSet()); - return (m_channelIt->type == FrequencyChannelType::OFDM); + return (m_channelIts.front()->type == FrequencyChannelType::OFDM); } bool WifiPhyOperatingChannel::IsDsss() const { NS_ASSERT(IsSet()); - return (m_channelIt->type == FrequencyChannelType::DSSS); + return (m_channelIts.front()->type == FrequencyChannelType::DSSS); } bool WifiPhyOperatingChannel::Is80211p() const { NS_ASSERT(IsSet()); - return (m_channelIt->type == FrequencyChannelType::CH_80211P); + return (m_channelIts.front()->type == FrequencyChannelType::CH_80211P); } WifiChannelWidthType @@ -477,6 +485,15 @@ WifiPhyOperatingChannel::GetWidthType() const } } +void +WifiPhyOperatingChannel::SortSegments() +{ + std::sort(m_channelIts.begin(), m_channelIts.end(), [](const auto& lhs, const auto& rhs) { + return lhs->frequency < rhs->frequency; + }); + m_channelIts.erase(std::unique(m_channelIts.begin(), m_channelIts.end()), m_channelIts.end()); +} + uint8_t WifiPhyOperatingChannel::GetPrimaryChannelIndex(ChannelWidthMhz primaryChannelWidth) const { @@ -729,7 +746,7 @@ WifiPhyOperatingChannel::Get20MHzIndicesCoveringRu(HeRu::RuSpec ru, ChannelWidth bool WifiPhyOperatingChannel::operator==(const WifiPhyOperatingChannel& other) const { - return m_channelIt == other.m_channelIt; + return m_channelIts == other.m_channelIts; } bool diff --git a/src/wifi/model/wifi-phy-operating-channel.h b/src/wifi/model/wifi-phy-operating-channel.h index 7a6cb43f9..173d81132 100644 --- a/src/wifi/model/wifi-phy-operating-channel.h +++ b/src/wifi/model/wifi-phy-operating-channel.h @@ -28,6 +28,7 @@ #include #include +#include namespace ns3 { @@ -86,6 +87,14 @@ class WifiPhyOperatingChannel */ WifiPhyOperatingChannel(ConstIterator it); + /** + * Create a PHY operating channel from iterators pointing to multiple frequency segments in the + * set of available channels. + * + * \param its the iterators pointing to frequency segments in the set of available channels + */ + WifiPhyOperatingChannel(const std::vector& its); + virtual ~WifiPhyOperatingChannel(); /** @@ -231,7 +240,7 @@ class WifiPhyOperatingChannel /** * Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel - * with the lowest center frequency). + * with the lowest center frequency among all segments). * * \param index the index of the primary 20 MHz channel */ @@ -290,7 +299,7 @@ class WifiPhyOperatingChannel const std::set& primaryIndices) const; /** - * Find the first channel matching the specified parameters. + * Find the first frequency segment matching the specified parameters. * * \param number the channel number (use 0 to leave it unspecified) * \param frequency the channel center frequency in MHz (use 0 to leave it unspecified) @@ -330,9 +339,15 @@ class WifiPhyOperatingChannel std::set Get20MHzIndicesCoveringRu(HeRu::RuSpec ru, ChannelWidthMhz width) const; private: - ConstIterator m_channelIt; //!< const iterator pointing to the configured frequency channel - uint8_t m_primary20Index; /**< index of the primary20 channel (0 indicates the 20 MHz - subchannel with the lowest center frequency) */ + /** + * Sort the segments by increasing frequencies. + */ + void SortSegments(); + + std::vector + m_channelIts; //!< const iterators pointing to the configured frequency channel + uint8_t m_primary20Index; /**< index of the primary20 channel (0 indicates the 20 MHz + subchannel with the lowest center frequency) */ }; /**