wifi: Handle CCA for 802.11be PHY
This commit is contained in:
@@ -18,6 +18,7 @@ This file is a best-effort approach to solving this issue; we will do our best b
|
||||
|
||||
* (network) Added a function to detect IPv4 APIPA addresses (169.254.0.0/16).
|
||||
* (wifi) Added a new `AssocType` attribute to `StaWifiMac` to configure the type of association performed by a device, provided that it is supported by the standard configured for the device. By using this attribute, it is possible for an EHT single-link device to perform ML setup with an AP MLD and for an EHT multi-link device to perform legacy association with an AP MLD.
|
||||
* (wifi) Added a new attribute `Per20CcaSensitivityThreshold` to `EhtConfiguration` for tuning the Per 20MHz CCA threshold when 802.11be is used.
|
||||
|
||||
### Changes to existing API
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "ns3/attribute-container.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/double.h"
|
||||
#include "ns3/enum.h"
|
||||
#include "ns3/integer.h"
|
||||
#include "ns3/log.h"
|
||||
@@ -162,7 +163,12 @@ EhtConfiguration::GetTypeId()
|
||||
MakeAttributeContainerChecker<UintegerValue>(
|
||||
MakeUintegerChecker<uint8_t>()),
|
||||
MakeAttributeContainerChecker<UintegerValue>(
|
||||
MakeUintegerChecker<uint8_t>()))));
|
||||
MakeUintegerChecker<uint8_t>()))))
|
||||
.AddAttribute("Per20CcaSensitivityThreshold",
|
||||
"CCA threshold (dBm) for Per 20MHz check.",
|
||||
DoubleValue(-72.0),
|
||||
MakeDoubleAccessor(&EhtConfiguration::m_per20CcaSensitivityThreshold),
|
||||
MakeDoubleChecker<dBm_u>());
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,8 @@ class EhtConfiguration : public Object
|
||||
std::map<std::list<uint64_t>, std::list<uint64_t>>
|
||||
m_linkMappingDl; //!< TIDs-indexed Link Mapping for downlink
|
||||
std::map<std::list<uint64_t>, std::list<uint64_t>>
|
||||
m_linkMappingUl; //!< TIDs-indexed Link Mapping for uplink
|
||||
m_linkMappingUl; //!< TIDs-indexed Link Mapping for uplink
|
||||
dB_u m_per20CcaSensitivityThreshold; //!< CCA threshold for Per 20MHz check
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
|
||||
#include "eht-phy.h"
|
||||
|
||||
#include "eht-configuration.h"
|
||||
#include "eht-ppdu.h"
|
||||
|
||||
#include "ns3/interference-helper.h"
|
||||
#include "ns3/obss-pd-algorithm.h"
|
||||
#include "ns3/wifi-net-device.h"
|
||||
#include "ns3/wifi-phy.h"
|
||||
#include "ns3/wifi-psdu.h"
|
||||
#include "ns3/wifi-utils.h"
|
||||
@@ -43,6 +46,15 @@ const PhyEntity::PpduFormats EhtPhy::m_ehtPpduFormats {
|
||||
WIFI_PPDU_FIELD_DATA } }
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief map a given secondary channel width to its channel list type
|
||||
*/
|
||||
const std::map<MHz_u, WifiChannelListType> ehtSecondaryChannels {
|
||||
{20, WIFI_CHANLIST_SECONDARY},
|
||||
{40, WIFI_CHANLIST_SECONDARY40},
|
||||
{80, WIFI_CHANLIST_SECONDARY80},
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
EhtPhy::EhtPhy(bool buildModeList /* = true */)
|
||||
@@ -405,6 +417,129 @@ EhtPhy::CalculateNonHtReferenceRate(WifiCodeRate codeRate, uint16_t constellatio
|
||||
return dataRate;
|
||||
}
|
||||
|
||||
dBm_u
|
||||
EhtPhy::Per20MHzCcaThreshold(const Ptr<const WifiPpdu> ppdu) const
|
||||
{
|
||||
if (!ppdu)
|
||||
{
|
||||
/**
|
||||
* A signal is present on the 20 MHz subchannel at or above a threshold of –62 dBm at the
|
||||
* receiver's antenna(s). The PHY shall indicate that the 20 MHz subchannel is busy a period
|
||||
* aCCATime after the signal starts and shall continue to indicate the 20 MHz subchannel is
|
||||
* busy while the threshold continues to be exceeded (Sec. 36.3.21.6.4 - Per 20 MHz CCA
|
||||
* sensitivity - of 802.11be D7.0).
|
||||
*/
|
||||
return m_wifiPhy->GetCcaEdThreshold();
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-HT, HT_MF, HT_GF, VHT, HE, or EHT PPDU for which the power measured within
|
||||
* this 20 MHz subchannel is at or above max(–72 dBm, OBSS_PD level) at the
|
||||
* receiver’s antenna(s). The PHY shall indicate that the 20 MHz subchannel is busy
|
||||
* with greater than 90% probability within a period aCCAMidTime (Sec. 36.3.21.6.4 - Per 20 MHz
|
||||
* CCA sensitivity - of 802.11be D7.0).
|
||||
*/
|
||||
auto ehtConfiguration = m_wifiPhy->GetDevice()->GetEhtConfiguration();
|
||||
NS_ASSERT(ehtConfiguration);
|
||||
const auto ccaThresholdNonObss = ehtConfiguration->m_per20CcaSensitivityThreshold;
|
||||
return GetObssPdAlgorithm()
|
||||
? std::max(ccaThresholdNonObss, GetObssPdAlgorithm()->GetObssPdLevel())
|
||||
: ccaThresholdNonObss;
|
||||
}
|
||||
|
||||
dBm_u
|
||||
EhtPhy::GetCcaThreshold(const Ptr<const WifiPpdu> ppdu, WifiChannelListType channelType) const
|
||||
{
|
||||
if (channelType != WIFI_CHANLIST_PRIMARY)
|
||||
{
|
||||
return Per20MHzCcaThreshold(ppdu);
|
||||
}
|
||||
return HePhy::GetCcaThreshold(ppdu, channelType);
|
||||
}
|
||||
|
||||
const std::map<MHz_u, WifiChannelListType>&
|
||||
EhtPhy::GetCcaSecondaryChannels() const
|
||||
{
|
||||
return ehtSecondaryChannels;
|
||||
}
|
||||
|
||||
PhyEntity::CcaIndication
|
||||
EhtPhy::GetCcaIndicationOnSecondary(const Ptr<const WifiPpdu> ppdu)
|
||||
{
|
||||
const auto secondaryWidthsToCheck = GetCcaSecondaryWidths(ppdu);
|
||||
|
||||
for (auto secondaryWidth : secondaryWidthsToCheck)
|
||||
{
|
||||
const auto channelType = ehtSecondaryChannels.at(secondaryWidth);
|
||||
const auto ccaThreshold = GetCcaThreshold(ppdu, channelType);
|
||||
const auto indices =
|
||||
m_wifiPhy->GetOperatingChannel().GetAll20MHzChannelIndicesInSecondary(secondaryWidth);
|
||||
for (auto index : indices)
|
||||
{
|
||||
const auto band = m_wifiPhy->GetBand(20, index);
|
||||
if (const auto delayUntilCcaEnd = GetDelayUntilCcaEnd(ccaThreshold, band);
|
||||
delayUntilCcaEnd.IsStrictlyPositive())
|
||||
{
|
||||
return std::make_pair(delayUntilCcaEnd, channelType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<Time>
|
||||
EhtPhy::GetPer20MHzDurations(const Ptr<const WifiPpdu> ppdu)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
|
||||
/**
|
||||
* 36.3.21.6.4 Per 20 MHz CCA sensitivity:
|
||||
* If the operating channel width is greater than 20 MHz and the PHY issues a PHY-CCA.indication
|
||||
* primitive, the PHY shall set the per20bitmap to indicate the busy/idle status of each 20 MHz
|
||||
* subchannel.
|
||||
*/
|
||||
if (m_wifiPhy->GetChannelWidth() < 40)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<Time> per20MhzDurations{};
|
||||
const auto indices = m_wifiPhy->GetOperatingChannel().GetAll20MHzChannelIndicesInPrimary(
|
||||
m_wifiPhy->GetChannelWidth());
|
||||
for (auto index : indices)
|
||||
{
|
||||
auto band = m_wifiPhy->GetBand(20, index);
|
||||
/**
|
||||
* A signal is present on the 20 MHz subchannel at or above a threshold of –62 dBm at the
|
||||
* receiver's antenna(s). The PHY shall indicate that the 20 MHz subchannel is busy a period
|
||||
* aCCATime after the signal starts and shall continue to indicate the 20 MHz subchannel is
|
||||
* busy while the threshold continues to be exceeded.
|
||||
*/
|
||||
dBm_u ccaThreshold = -62;
|
||||
auto delayUntilCcaEnd = GetDelayUntilCcaEnd(ccaThreshold, band);
|
||||
|
||||
if (ppdu)
|
||||
{
|
||||
const MHz_u subchannelMinFreq =
|
||||
m_wifiPhy->GetFrequency() - (m_wifiPhy->GetChannelWidth() / 2) + (index * 20);
|
||||
const MHz_u subchannelMaxFreq = subchannelMinFreq + 20;
|
||||
const auto ppduBw = ppdu->GetTxVector().GetChannelWidth();
|
||||
|
||||
if ((ppduBw <= m_wifiPhy->GetChannelWidth()) &&
|
||||
ppdu->DoesOverlapChannel(subchannelMinFreq, subchannelMaxFreq))
|
||||
{
|
||||
ccaThreshold = Per20MHzCcaThreshold(ppdu);
|
||||
const auto ppduCcaDuration = GetDelayUntilCcaEnd(ccaThreshold, band);
|
||||
delayUntilCcaEnd = std::max(delayUntilCcaEnd, ppduCcaDuration);
|
||||
}
|
||||
}
|
||||
per20MhzDurations.push_back(delayUntilCcaEnd);
|
||||
}
|
||||
|
||||
return per20MhzDurations;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace
|
||||
|
||||
@@ -252,6 +252,11 @@ class EhtPhy : public HePhy
|
||||
WifiPpduField field) override;
|
||||
WifiPhyRxfailureReason GetFailureReason(WifiPpduField field) const override;
|
||||
uint32_t GetSigBSize(const WifiTxVector& txVector) const override;
|
||||
dBm_u GetCcaThreshold(const Ptr<const WifiPpdu> ppdu,
|
||||
WifiChannelListType channelType) const override;
|
||||
const std::map<MHz_u, WifiChannelListType>& GetCcaSecondaryChannels() const override;
|
||||
PhyEntity::CcaIndication GetCcaIndicationOnSecondary(const Ptr<const WifiPpdu> ppdu) override;
|
||||
std::vector<Time> GetPer20MHzDurations(const Ptr<const WifiPpdu> ppdu) override;
|
||||
|
||||
/**
|
||||
* Create and return the EHT MCS corresponding to
|
||||
@@ -278,6 +283,16 @@ class EhtPhy : public HePhy
|
||||
*/
|
||||
static uint64_t CalculateNonHtReferenceRate(WifiCodeRate codeRate, uint16_t constellationSize);
|
||||
|
||||
/**
|
||||
* Compute the CCA threshold for Per 20MHz check.
|
||||
* This threshold is used for CCA check when signal is not occupying P20 or for Per 20MHz CCA
|
||||
* check.
|
||||
*
|
||||
* @param ppdu the incoming PPDU or nullptr for any signal
|
||||
* @return the CCA threshold for Per 20MHz check
|
||||
*/
|
||||
dBm_u Per20MHzCcaThreshold(const Ptr<const WifiPpdu> ppdu) const;
|
||||
|
||||
static const PpduFormats m_ehtPpduFormats; //!< EHT PPDU formats
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user