diff --git a/CHANGES.md b/CHANGES.md index 284cda094..efd727ee2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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 diff --git a/src/wifi/model/eht/eht-configuration.cc b/src/wifi/model/eht/eht-configuration.cc index da05c3d25..4ddec44f1 100644 --- a/src/wifi/model/eht/eht-configuration.cc +++ b/src/wifi/model/eht/eht-configuration.cc @@ -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( MakeUintegerChecker()), MakeAttributeContainerChecker( - MakeUintegerChecker())))); + MakeUintegerChecker())))) + .AddAttribute("Per20CcaSensitivityThreshold", + "CCA threshold (dBm) for Per 20MHz check.", + DoubleValue(-72.0), + MakeDoubleAccessor(&EhtConfiguration::m_per20CcaSensitivityThreshold), + MakeDoubleChecker()); return tid; } diff --git a/src/wifi/model/eht/eht-configuration.h b/src/wifi/model/eht/eht-configuration.h index cb1c9d953..328246432 100644 --- a/src/wifi/model/eht/eht-configuration.h +++ b/src/wifi/model/eht/eht-configuration.h @@ -110,7 +110,8 @@ class EhtConfiguration : public Object std::map, std::list> m_linkMappingDl; //!< TIDs-indexed Link Mapping for downlink std::map, std::list> - 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 diff --git a/src/wifi/model/eht/eht-phy.cc b/src/wifi/model/eht/eht-phy.cc index fa01822da..ff10b59af 100644 --- a/src/wifi/model/eht/eht-phy.cc +++ b/src/wifi/model/eht/eht-phy.cc @@ -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 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 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 ppdu, WifiChannelListType channelType) const +{ + if (channelType != WIFI_CHANLIST_PRIMARY) + { + return Per20MHzCcaThreshold(ppdu); + } + return HePhy::GetCcaThreshold(ppdu, channelType); +} + +const std::map& +EhtPhy::GetCcaSecondaryChannels() const +{ + return ehtSecondaryChannels; +} + +PhyEntity::CcaIndication +EhtPhy::GetCcaIndicationOnSecondary(const Ptr 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