wifi: PPDU can be transmitted over multiple center frequencies (one per segment)
This will be a single one except for 80+80MHz when supported
This commit is contained in:
@@ -1386,7 +1386,7 @@ PhyEntity::CanStartRx(Ptr<const WifiPpdu> ppdu) const
|
||||
m_wifiPhy->GetOperatingChannel().GetPrimaryChannelCenterFrequency(primaryWidth);
|
||||
const auto p20MinFreq = p20CenterFreq - (primaryWidth / 2);
|
||||
const auto p20MaxFreq = p20CenterFreq + (primaryWidth / 2);
|
||||
const auto txCenterFreq = ppdu->GetTxCenterFreq();
|
||||
const auto txCenterFreq = ppdu->GetTxCenterFreqs().front();
|
||||
const auto txChannelWidth = ppdu->GetTxChannelWidth();
|
||||
const auto minTxFreq = txCenterFreq - txChannelWidth / 2;
|
||||
const auto maxTxFreq = txCenterFreq + txChannelWidth / 2;
|
||||
|
||||
@@ -89,7 +89,7 @@ WifiBandwidthFilter::DoFilter(Ptr<const SpectrumSignalParameters> params,
|
||||
// The signal power is spread over a frequency interval that includes a guard
|
||||
// band on the left and a guard band on the right of the nominal TX band
|
||||
|
||||
const auto rxCenterFreq = wifiRxParams->ppdu->GetTxCenterFreq();
|
||||
const auto rxCenterFreq = wifiRxParams->ppdu->GetTxCenterFreqs().front();
|
||||
const auto rxWidth = wifiRxParams->ppdu->GetTxVector().GetChannelWidth();
|
||||
const auto guardBandwidth = wifiPhy->GetGuardBandwidth(rxWidth);
|
||||
const auto operatingFrequency = interface->GetCenterFrequency();
|
||||
|
||||
@@ -24,6 +24,49 @@
|
||||
|
||||
#include "ns3/log.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
/**
|
||||
* Get the center frequency (in MHz) of each segment covered by the provided channel width (in
|
||||
* MHz). If the specified channel width is contained in a single frequency segment, a single
|
||||
* center frequency is returned. If the specified channel width is spread over multiple
|
||||
* frequency segments (e.g. 160 MHz if operating channel is 80+80MHz), multiple center
|
||||
* frequencies are returned.
|
||||
*
|
||||
* \param channel the operating channel of the PHY
|
||||
* \param channelWidth the channel width in MHz
|
||||
* \return the center frequency (in MHz) of each segment covered by the given width
|
||||
*/
|
||||
std::vector<uint16_t>
|
||||
GetChannelCenterFrequenciesPerSegment(const ns3::WifiPhyOperatingChannel& channel,
|
||||
ns3::ChannelWidthMhz channelWidth)
|
||||
{
|
||||
if (!channel.IsSet())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
std::vector<uint16_t> freqs{};
|
||||
const auto width = std::min(channelWidth, channel.GetWidth(0));
|
||||
const auto primarySegmentIndex = channel.GetPrimarySegmentIndex(width);
|
||||
const auto secondarySegmentIndex = channel.GetSecondarySegmentIndex(width);
|
||||
const auto primaryIndex = channel.GetPrimaryChannelIndex(channelWidth);
|
||||
const auto segmentIndices =
|
||||
((channel.GetNSegments() < 2) || (channelWidth <= channel.GetWidth(primarySegmentIndex)))
|
||||
? std::vector<uint8_t>{primarySegmentIndex}
|
||||
: std::vector<uint8_t>{primarySegmentIndex, secondarySegmentIndex};
|
||||
for (auto segmentIndex : segmentIndices)
|
||||
{
|
||||
const auto segmentFrequency = channel.GetFrequency(segmentIndex);
|
||||
const auto segmentWidth = channel.GetWidth(segmentIndex);
|
||||
const auto segmentOffset = (primarySegmentIndex * (segmentWidth / channelWidth));
|
||||
const auto freq =
|
||||
segmentFrequency - (segmentWidth / 2.) + (primaryIndex - segmentOffset + 0.5) * width;
|
||||
freqs.push_back(freq);
|
||||
}
|
||||
return freqs;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
@@ -35,9 +78,7 @@ WifiPpdu::WifiPpdu(Ptr<const WifiPsdu> psdu,
|
||||
uint64_t uid /* = UINT64_MAX */)
|
||||
: m_preamble(txVector.GetPreambleType()),
|
||||
m_modulation(txVector.IsValid() ? txVector.GetModulationClass() : WIFI_MOD_CLASS_UNKNOWN),
|
||||
m_txCenterFreq(channel.IsSet()
|
||||
? channel.GetPrimaryChannelCenterFrequency(txVector.GetChannelWidth())
|
||||
: 0),
|
||||
m_txCenterFreqs(GetChannelCenterFrequenciesPerSegment(channel, txVector.GetChannelWidth())),
|
||||
m_uid(uid),
|
||||
m_txVector(txVector),
|
||||
m_operatingChannel(channel),
|
||||
@@ -57,9 +98,7 @@ WifiPpdu::WifiPpdu(const WifiConstPsduMap& psdus,
|
||||
: m_preamble(txVector.GetPreambleType()),
|
||||
m_modulation(txVector.IsValid() ? txVector.GetMode(psdus.begin()->first).GetModulationClass()
|
||||
: WIFI_MOD_CLASS_UNKNOWN),
|
||||
m_txCenterFreq(channel.IsSet()
|
||||
? channel.GetPrimaryChannelCenterFrequency(txVector.GetChannelWidth())
|
||||
: 0),
|
||||
m_txCenterFreqs(GetChannelCenterFrequenciesPerSegment(channel, txVector.GetChannelWidth())),
|
||||
m_uid(uid),
|
||||
m_txVector(txVector),
|
||||
m_operatingChannel(channel),
|
||||
@@ -148,18 +187,18 @@ WifiPpdu::GetTxChannelWidth() const
|
||||
return m_txChannelWidth;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
WifiPpdu::GetTxCenterFreq() const
|
||||
std::vector<uint16_t>
|
||||
WifiPpdu::GetTxCenterFreqs() const
|
||||
{
|
||||
return m_txCenterFreq;
|
||||
return m_txCenterFreqs;
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPpdu::DoesOverlapChannel(uint16_t minFreq, uint16_t maxFreq) const
|
||||
{
|
||||
NS_LOG_FUNCTION(this << m_txCenterFreq << minFreq << maxFreq);
|
||||
uint16_t minTxFreq = m_txCenterFreq - m_txChannelWidth / 2;
|
||||
uint16_t maxTxFreq = m_txCenterFreq + m_txChannelWidth / 2;
|
||||
NS_LOG_FUNCTION(this << m_txCenterFreqs.front() << minFreq << maxFreq);
|
||||
uint16_t minTxFreq = m_txCenterFreqs.front() - m_txChannelWidth / 2;
|
||||
uint16_t maxTxFreq = m_txCenterFreqs.front() + m_txChannelWidth / 2;
|
||||
/**
|
||||
* The PPDU does not overlap the channel in two cases.
|
||||
*
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <list>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* \file
|
||||
@@ -137,9 +138,9 @@ class WifiPpdu : public SimpleRefCount<WifiPpdu>
|
||||
virtual ChannelWidthMhz GetTxChannelWidth() const;
|
||||
|
||||
/**
|
||||
* \return the center frequency (MHz) used for the transmission of this PPDU
|
||||
* \return the center frequency per segment (MHz) used for the transmission of this PPDU
|
||||
*/
|
||||
uint16_t GetTxCenterFreq() const;
|
||||
std::vector<uint16_t> GetTxCenterFreqs() const;
|
||||
|
||||
/**
|
||||
* Check whether the given PPDU overlaps a given channel.
|
||||
@@ -202,8 +203,9 @@ class WifiPpdu : public SimpleRefCount<WifiPpdu>
|
||||
WifiPreamble m_preamble; //!< the PHY preamble
|
||||
WifiModulationClass m_modulation; //!< the modulation used for the transmission of this PPDU
|
||||
WifiConstPsduMap m_psdus; //!< the PSDUs contained in this PPDU
|
||||
uint16_t m_txCenterFreq; //!< the center frequency (MHz) used for the transmission of this PPDU
|
||||
uint64_t m_uid; //!< the unique ID of this PPDU
|
||||
std::vector<uint16_t> m_txCenterFreqs; //!< the center frequency (MHz) per segment used for the
|
||||
//!< transmission of this PPDU
|
||||
uint64_t m_uid; //!< the unique ID of this PPDU
|
||||
mutable std::optional<WifiTxVector>
|
||||
m_txVector; //!< the TXVECTOR at TX PHY or the reconstructed TXVECTOR at RX PHY (or
|
||||
//!< std::nullopt if TXVECTOR has not been reconstructed yet)
|
||||
|
||||
Reference in New Issue
Block a user