wifi: WifiPhyOperatingChannel stores multiple contiguous segments

This commit is contained in:
Sébastien Deronne
2023-06-03 11:47:38 +02:00
parent d1f44345e5
commit 5f8abd65b2
2 changed files with 53 additions and 21 deletions

View File

@@ -277,15 +277,23 @@ operator<<(std::ostream& os, const FrequencyChannelInfo& info)
}
WifiPhyOperatingChannel::WifiPhyOperatingChannel()
: WifiPhyOperatingChannel(m_frequencyChannels.end())
: WifiPhyOperatingChannel(std::vector<ConstIterator>{})
{
}
WifiPhyOperatingChannel::WifiPhyOperatingChannel(ConstIterator it)
: m_channelIt(it),
: WifiPhyOperatingChannel(std::vector<ConstIterator>{it})
{
}
WifiPhyOperatingChannel::WifiPhyOperatingChannel(const std::vector<ConstIterator>& 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

View File

@@ -28,6 +28,7 @@
#include <set>
#include <tuple>
#include <vector>
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<ConstIterator>& 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<uint8_t>& 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<uint8_t> 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<ConstIterator>
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) */
};
/**