16#include "ns3/ap-wifi-mac.h"
17#include "ns3/assert.h"
18#include "ns3/interference-helper.h"
20#include "ns3/simulator.h"
21#include "ns3/spectrum-wifi-phy.h"
22#include "ns3/sta-wifi-mac.h"
23#include "ns3/vht-configuration.h"
24#include "ns3/wifi-net-device.h"
25#include "ns3/wifi-psdu.h"
26#include "ns3/wifi-utils.h"
30#undef NS_LOG_APPEND_CONTEXT
31#define NS_LOG_APPEND_CONTEXT WIFI_PHY_NS_LOG_APPEND_CONTEXT(m_wifiPhy)
72 m_trigVector(
std::nullopt),
73 m_trigVectorExpirationTime(
std::nullopt),
74 m_currentTxVector(
std::nullopt),
76 m_lastPer20MHzDurations()
147 uint8_t smallestMcs = 5;
150 smallestMcs = std::min(smallestMcs, info.second.mcs);
185 uint8_t nExtensionLtf )
const
198 NS_ABORT_MSG_IF(nDataLtf > 8,
"Unsupported number of LTFs " << +nDataLtf <<
" for HE");
199 NS_ABORT_MSG_IF(nExtensionLtf > 0,
"No extension LTFs expected for HE");
200 return stfDuration + ltfDuration * nDataLtf;
232 if (
const auto sigBSize =
GetSigBSize(txVector); sigBSize > 0)
238 const auto numSymbols = ceil((sigBSize) / ndbps);
240 return FemtoSeconds(
static_cast<uint64_t
>(numSymbols * symbolDuration.GetFemtoSeconds()));
256 floor(
static_cast<double>((ppduDuration - preambleDuration).GetNanoSeconds() -
257 (sigExtension * 1000)) /
258 tSymbol.GetNanoSeconds());
259 return preambleDuration + (nSymbols * tSymbol) +
MicroSeconds(sigExtension);
262std::pair<uint16_t, Time>
272 uint16_t length = ((ceil((
static_cast<double>(ppduDuration.
GetNanoSeconds() - (20 * 1000) -
273 (sigExtension * 1000)) /
278 return {length, ppduDuration};
290 Time calculatedDuration =
291 MicroSeconds(((ceil(
static_cast<double>(length + 3 + m) / 3)) * 4) + 20 + sigExtension);
325 NS_ASSERT(gi == 800 || gi == 1600 || gi == 3200);
362 const auto& txVector = ppdu->GetTxVector();
365 const auto psdFlag = hePpdu->GetTxPsdFlag();
374 NS_LOG_INFO(
"Switch to HE portion (already started? "
375 << (hePortionStarted ?
"Y" :
"N") <<
") "
376 <<
"and schedule payload reception in "
390 NS_LOG_INFO(
"Consider HE portion of the PPDU as interference since device dropped the "
402 ppdu->GetTxDuration());
412 beginMuPayloadRxEvent.second.Cancel();
426 endMpduEvent.Cancel();
446 beginMuPayloadRxEvent.second.Cancel();
460 const auto it = currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
464 const auto& txVector = ppdu->GetTxVector();
465 const auto rxDuration =
469 : ppdu->GetTxDuration();
470 if (it != currentPreambleEvents.cend())
475 << ppdu->GetUid() <<
" from STA-ID " << ppdu->GetStaId()
476 <<
" and BSS color " << +txVector.GetBssColor());
480 NS_LOG_DEBUG(
"Received another response to a trigger frame " << ppdu->GetUid());
491 << ppdu->GetUid() <<
" from STA-ID " << ppdu->GetStaId()
492 <<
" and BSS color " << +txVector.GetBssColor());
496 NS_LOG_DEBUG(
"Received response to a trigger frame for UID " << ppdu->GetUid());
504 const auto& txVector = ppdu->GetTxVector();
527 NS_LOG_DEBUG(
"Drop packet because already receiving another HE TB PPDU");
534 NS_LOG_DEBUG(
"Drop packet because already receiving another response to a trigger frame");
554 uint8_t bssColor = 0;
560 bssColor = heConfiguration->m_bssColor;
571 return ppdu->GetStaId();
576 if (mac && mac->IsAssociated())
578 return mac->GetAssociationId();
606 const auto& txVector =
event->GetPpdu()->GetTxVector();
609 .bssColor = txVector.GetBssColor(),
618 uint8_t rxBssColor = txVector.GetBssColor();
619 if (myBssColor != 0 && rxBssColor != 0 && myBssColor != rxBssColor)
622 << +rxBssColor <<
") does not match the device's (" << +myBssColor
623 <<
"). The PPDU is filtered.");
634 NS_LOG_DEBUG(
"Expected an HE TB PPDU, receiving a " << txVector.GetPreambleType());
645 NS_LOG_DEBUG(
"No valid TRIGVECTOR, the PHY was not expecting a TB PPDU");
654 if (
m_trigVector->GetChannelWidth() != txVector.GetChannelWidth())
656 NS_LOG_DEBUG(
"Received channel width different than in TRIGVECTOR");
661 NS_LOG_DEBUG(
"Received UL Length (" << txVector.GetLength()
662 <<
") different than in TRIGVECTOR ("
666 uint16_t staId = ppdu->GetStaId();
667 if (!
m_trigVector->GetHeMuUserInfoMap().contains(staId))
669 NS_LOG_DEBUG(
"TB PPDU received from un unexpected STA ID");
688 "No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
734 "No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
739 event->GetPpdu()->GetUid();
752 const auto& txVector = ppdu->GetTxVector();
754 const auto txMode = txVector.GetMode(staId);
755 auto nss = txVector.GetNssMax();
756 if (txVector.IsDlMu())
759 for (
auto info : txVector.GetHeMuUserInfoMap())
761 if (info.first == staId)
763 nss = info.second.nss;
771 NS_LOG_DEBUG(
"Packet reception could not be started because not enough RX antennas");
776 NS_LOG_DEBUG(
"Drop packet because it was sent using an unsupported mode ("
777 << txVector.GetMode() <<
")");
787 const auto ppdu =
event->GetPpdu();
788 const auto& txVector = ppdu->GetTxVector();
790 if (!txVector.IsMu())
797 if (txVector.IsDlMu())
799 Time payloadDuration =
802 return payloadDuration;
818 Time timeToEndRx = payloadDuration + maxOffset;
822 NS_LOG_DEBUG(
"Ignore HE TB PPDU payload received by STA but keep state in Rx");
831 beginMuPayloadRxEvent.second.Cancel();
846 NS_ASSERT(beginMuPayloadRxEvent.second.IsPending());
858 const std::vector<bool>& statusPerMpdu)
877 m_state->SwitchFromRxEndError(txVector);
910 m_state->SwitchFromRxEndError(ppdu->GetTxVector());
933 auto it = rxPowersW.end();
936 it = std::max_element(rxPowersW.cbegin(),
938 [](
const auto& p1,
const auto& p2) { return p1.second < p2.second; });
953 auto payloadDuration =
966std::pair<MHz_u, WifiSpectrumBandInfo>
984 auto ru = txVector.
GetRu(staId);
986 NS_ASSERT(channelWidth <= m_wifiPhy->GetChannelWidth());
1003 {group.front().first, group.back().second},
1006 for (
const auto& indicesPerSegment : indices)
1008 ruBandForTx.
indices.emplace_back(indicesPerSegment);
1009 ruBandForTx.frequencies.emplace_back(
1019 auto ru = txVector.
GetRu(staId);
1021 NS_ASSERT(channelWidth <= m_wifiPhy->GetChannelWidth());
1039 {group.front().first, group.back().second},
1042 for (
const auto& indicesPerSegment : indices)
1044 ruBandForRx.
indices.emplace_back(indicesPerSegment);
1045 ruBandForRx.frequencies.emplace_back(
1083 channelWidth =
MHz_u{20};
1085 return channelWidth;
1106 const auto ppduBw = ppdu->GetTxVector().GetChannelWidth();
1109 while (bw >
MHz_u{20})
1111 obssPdLevel +=
dB_u{3};
1124 if (ccaIndication.has_value())
1126 NS_LOG_DEBUG(
"CCA busy for " << ccaIndication.value().second <<
" during "
1127 << ccaIndication.value().first.As(
Time::S));
1128 NotifyCcaBusy(ccaIndication.value().first, ccaIndication.value().second, per20MHzDurations);
1159 const std::vector<Time>& per20MHzDurations)
1162 m_state->SwitchMaybeToCcaBusy(duration, channelType, per20MHzDurations);
1182 std::vector<Time> per20MhzDurations{};
1185 for (
auto index : indices)
1201 const auto subchannelMaxFreq = subchannelMinFreq +
MHz_u{20};
1202 const auto ppduBw = ppdu->GetTxVector().GetChannelWidth();
1204 if (ppduBw <= m_wifiPhy->GetChannelWidth() &&
1205 ppdu->DoesOverlapChannel(subchannelMinFreq, subchannelMaxFreq))
1207 std::optional<dBm_u> obssPdLevel{std::nullopt};
1212 switch (
static_cast<uint16_t
>(ppduBw))
1222 ccaThreshold = obssPdLevel.has_value()
1223 ? std::max(
dBm_u{-72.0}, obssPdLevel.value())
1234 ccaThreshold = obssPdLevel.has_value()
1235 ? std::max(
dBm_u{-72.0}, obssPdLevel.value() +
dB_u{3})
1246 ccaThreshold = obssPdLevel.has_value()
1247 ? std::max(
dBm_u{-69.0}, obssPdLevel.value() +
dB_u{6})
1259 delayUntilCcaEnd = std::max(delayUntilCcaEnd, ppduCcaDuration);
1261 per20MhzDurations.push_back(delayUntilCcaEnd);
1264 return per20MhzDurations;
1299 if (heConfiguration->m_maxTbPpduDelay.IsStrictlyPositive())
1301 maxDelay =
Min(maxDelay, heConfiguration->m_maxTbPpduDelay);
1320 const auto& txVector = ppdu->GetTxVector();
1321 const auto& centerFrequencies = ppdu->GetTxCenterFreqs();
1322 auto channelWidth = txVector.GetChannelWidth();
1323 auto printFrequencies = [](
const std::vector<MHz_u>& v) {
1324 std::stringstream ss;
1325 for (
const auto& centerFrequency : v)
1327 ss << centerFrequency <<
" ";
1331 NS_LOG_FUNCTION(
this << printFrequencies(centerFrequencies) << channelWidth << txPower
1333 const auto& puncturedSubchannels = txVector.GetInactiveSubchannels();
1334 if (!puncturedSubchannels.empty())
1337 const auto& indices =
1339 const auto p20IndexInBitmap = p20Index - *(indices.cbegin());
1341 !puncturedSubchannels.at(p20IndexInBitmap));
1344 switch (ppdu->GetType())
1352 channelWidth = (ruWidth <
MHz_u{20}) ?
MHz_u{20} : ruWidth;
1358 std::get<0>(txMaskRejectionParams),
1359 std::get<1>(txMaskRejectionParams),
1360 std::get<2>(txMaskRejectionParams),
1361 puncturedSubchannels);
1382 std::get<0>(txMaskRejectionParams),
1383 std::get<1>(txMaskRejectionParams),
1384 std::get<2>(txMaskRejectionParams),
1385 puncturedSubchannels);
1394 std::get<0>(txMaskRejectionParams),
1395 std::get<1>(txMaskRejectionParams),
1396 std::get<2>(txMaskRejectionParams),
1397 puncturedSubchannels);
1402 NS_ASSERT(puncturedSubchannels.empty());
1408 std::get<0>(txMaskRejectionParams),
1409 std::get<1>(txMaskRejectionParams),
1410 std::get<2>(txMaskRejectionParams));
1419 const auto& txVector = ppdu->GetTxVector();
1421 auto centerFrequencies = ppdu->GetTxCenterFreqs();
1422 const auto currentWidth = txVector.GetChannelWidth();
1424 auto ru = txVector.GetRu(staId);
1426 if (nonOfdmaWidth != currentWidth)
1429 const auto nonOfdmaRu =
1432 const MHz_u startingFrequency = centerFrequencies.front() - (currentWidth / 2);
1433 centerFrequencies.front() =
1443 return centerFrequencies;
1450 const auto& txVector = ppdu->GetTxVector();
1457 const auto nonHeTxPower =
1472 auto nonHeTxPowerSpectrum =
1477 nonHeTxPowerSpectrum,
1478 "non-HE portion transmission");
1481 auto hePortionDuration = ppdu->GetTxDuration() - nonHePortionDuration;
1482 auto heTxPowerSpectrum =
1502 Time hePortionDuration)
1508 Transmit(hePortionDuration, ppdu, txPower, txPowerSpectrum,
"HE portion transmission");
1523 for (
auto& staIdPsdu : psduMap)
1529 "STA-ID in psduMap (" << staIdPsdu.first
1530 <<
") should be referenced in txVector");
1536 if (current > maxDuration)
1538 maxDuration = current;
1548 for (uint8_t i = 0; i < 12; ++i)
1559 return GetHeMcs##x();
1576 NS_ABORT_MSG(
"Inexistent index (" << +index <<
") requested for HE");
1582#define GET_HE_MCS(x) \
1583 WifiMode HePhy::GetHeMcs##x() \
1585 static WifiMode mcs = CreateHeMcs(x); \
1650 const auto dataRate =
GetDataRate(mcsValue, channelWidth, guardInterval, nss);
1658 if (txVector.
IsMu())
1672 if (txVector.
IsMu())
1686 NS_ASSERT((gi == 800) || (gi == 1600) || (gi == 3200));
1698 switch (
static_cast<uint16_t
>(channelWidth))
1715 NS_ASSERT_MSG(
false,
"Invalid channel width: " << channelWidth);
1738 switch (constellationSize)
1743 dataRate = 54000000;
1747 NS_FATAL_ERROR(
"Trying to get reference rate for a MCS with wrong combination of "
1748 "coding rate and modulation");
1795 if (ppdu->GetTxVector().IsUlMu() && mac && mac->GetTypeOfStation() ==
AP)
1814 rxPpdu = ppdu->Copy();
1828std::vector<WifiSpectrumBandIndices>
1833 <<
") cannot exceed total operating channel width ("
1835 std::vector<WifiSpectrumBandIndices> convertedSubcarriers{};
1837 const auto nGuardBands =
1847 const uint32_t guardSubcarriers = (bw <
MHz_u{40}) ? 6 : 12;
1850 uint32_t centerFrequencyIndex = (nGuardBands / 2) + guardSubcarriers + offset;
1852 centerFrequencyIndex += numBandsInBand * info.
bandIndex;
1855 auto centerFrequencyIndexLow = centerFrequencyIndex;
1856 auto centerFrequencyIndexHigh = centerFrequencyIndex;
1859 const auto numBandsBetweenSegments =
1865 centerFrequencyIndexLow += numBandsBetweenSegments;
1869 centerFrequencyIndexHigh += numBandsBetweenSegments;
1872 convertedSubcarriers.emplace_back(centerFrequencyIndexLow + info.
subcarrierRange.first,
1874 return convertedSubcarriers;
Constructor class for HE modes.
bool IsNull() const
Check for null implementation.
std::optional< WifiTxVector > m_trigVector
the TRIGVECTOR
Time GetLSigDuration(WifiPreamble preamble) const override
virtual Time CalculateNonHeDurationForHeTb(const WifiTxVector &txVector) const
static uint64_t GetDataRate(uint8_t mcsValue, MHz_u channelWidth, Time guardInterval, uint8_t nss)
Return the data rate corresponding to the supplied HE MCS index, channel width, guard interval,...
static Time ConvertLSigLengthToHeTbPpduDuration(uint16_t length, const WifiTxVector &txVector, WifiPhyBand band)
static uint64_t GetPhyRate(uint8_t mcsValue, MHz_u channelWidth, Time guardInterval, uint8_t nss)
Return the PHY rate corresponding to the supplied HE MCS index, channel width, guard interval,...
uint64_t GetCurrentHeTbPpduUid() const
Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW) override
Get the event corresponding to the incoming PPDU.
void CancelAllEvents() override
Cancel and clear all running events.
void SetObssPdAlgorithm(const Ptr< ObssPdAlgorithm > algorithm)
Sets the OBSS-PD algorithm.
static void InitializeModes()
Initialize all HE modes.
void DoAbortCurrentReception(WifiPhyRxfailureReason reason) override
Perform amendment-specific actions before aborting the current reception.
WifiSpectrumBandInfo GetRuBandForRx(const WifiTxVector &txVector, uint16_t staId) const
Get the band in the RX spectrum associated with the RU used by the PSDU transmitted to/by a given STA...
void StartReceiveMuPayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
virtual PhyFieldRxStatus ProcessSigB(Ptr< Event > event, PhyFieldRxStatus status)
Process SIG-B, perform amendment-specific actions, and provide an updated status of the reception.
virtual Time CalculateNonHeDurationForHeMu(const WifiTxVector &txVector) const
std::optional< WifiTxVector > m_currentTxVector
If the STA is an AP STA, this holds the TXVECTOR of the PPDU that has been sent.
Time GetSigBDuration(const WifiTxVector &txVector) const override
static WifiMode CreateHeMcs(uint8_t index)
Create and return the HE MCS corresponding to the provided index.
virtual uint32_t GetSigBSize(const WifiTxVector &txVector) const
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
void BuildModeList() override
Build mode list.
WifiConstPsduMap GetWifiConstPsduMap(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector) const override
Get a WifiConstPsduMap from a PSDU and the TXVECTOR to use to send the PSDU.
static uint64_t CalculateNonHtReferenceRate(WifiCodeRate codeRate, uint16_t constellationSize)
Return the rate (in bps) of the non-HT Reference Rate which corresponds to the supplied code rate and...
void StartTxHePortion(Ptr< const WifiPpdu > ppdu, dBm_u txPower, Ptr< SpectrumValue > txPowerSpectrum, Time hePortionDuration)
Start the transmission of the HE portion of the MU PPDU.
MHz_u GetNonOfdmaWidth(WifiRu::RuSpec ru) const
Get the width of the non-OFDMA portion of an HE TB PPDU.
bool CanStartRx(Ptr< const WifiPpdu > ppdu) const override
Determine whether the PHY shall issue a PHY-RXSTART.indication primitive in response to a given PPDU.
void SetEndOfHeSigACallback(EndOfHeSigACallback callback)
Set a callback for a end of HE-SIG-A.
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied HE MCS index.
void StartTx(Ptr< const WifiPpdu > ppdu) override
This function is called by SpectrumWifiPhy to send the PPDU while performing amendment-specific actio...
PhyFieldRxStatus ProcessSig(Ptr< Event > event, PhyFieldRxStatus status, WifiPpduField field) override
Process SIG-A or SIG-B, perform amendment-specific actions, and provide an updated status of the rece...
EndOfHeSigACallback m_endOfHeSigACallback
end of HE-SIG-A callback
Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const override
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const override
Get the WifiMode for the SIG field specified by the PPDU field.
const PpduFormats & GetPpduFormats() const override
Return the PPDU formats of the PHY.
uint64_t ObtainNextUid(const WifiTxVector &txVector) override
Obtain the next UID for the PPDU to transmit.
Time CalculateTxDuration(const WifiConstPsduMap &psduMap, const WifiTxVector &txVector, WifiPhyBand band) const override
static uint64_t GetPhyRateFromTxVector(const WifiTxVector &txVector, uint16_t staId=SU_STA_ID)
Return the PHY rate corresponding to the supplied TXVECTOR for the STA-ID.
Ptr< ObssPdAlgorithm > m_obssPdAlgorithm
OBSS-PD algorithm.
dBm_u GetCcaThreshold(const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType) const override
Return the CCA threshold for a given channel type.
std::pair< MHz_u, WifiSpectrumBandInfo > GetChannelWidthAndBand(const WifiTxVector &txVector, uint16_t staId) const override
Get the channel width and band to use (will be overloaded by child classes).
MHz_u GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const override
Return the channel width used to measure the RSSI.
Ptr< ObssPdAlgorithm > GetObssPdAlgorithm() const
Gets the OBSS-PD algorithm.
uint8_t GetBssColor() const
static Time GetValidPpduDuration(Time ppduDuration, const WifiTxVector &txVector, WifiPhyBand band)
Given a PPDU duration value, the TXVECTOR used to transmit the PPDU and the PHY band,...
uint8_t GetNumberBccEncoders(const WifiTxVector &txVector) const override
Time GetMaxDelayPpduSameUid(const WifiTxVector &txVector) override
Obtain the maximum time between two PPDUs with the same UID to consider they are identical and their ...
void HandleRxPpduWithSameContent(Ptr< Event > event, Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPower) override
Handle reception of a PPDU that carries the same content of another PPDU.
static bool IsAllowed(const WifiTxVector &txVector)
Check whether the combination in TXVECTOR is allowed.
std::size_t m_rxHeTbPpdus
Number of successfully received HE TB PPDUS.
~HePhy() override
Destructor for HE PHY.
Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration) override
Build amendment-specific PPDU.
void NotifyEndOfHeSigA(HeSigAParameters params)
Fire a EndOfHeSigA callback (if connected) once HE-SIG-A field has been received.
Ptr< SpectrumValue > GetTxPowerSpectralDensity(Watt_u txPower, Ptr< const WifiPpdu > ppdu) const override
void RxPayloadSucceeded(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, uint16_t staId, const std::vector< bool > &statusPerMpdu) override
Perform amendment-specific actions when the payload is successfully received.
uint64_t m_currentMuPpduUid
UID of the HE MU or HE TB PPDU being received.
uint32_t GetMaxPsduSize() const override
Get the maximum PSDU size in bytes.
static const PpduFormats m_hePpduFormats
HE PPDU formats.
static uint64_t GetDataRateFromTxVector(const WifiTxVector &txVector, uint16_t staId=SU_STA_ID)
Return the data rate corresponding to the supplied TXVECTOR for the STA-ID.
std::map< uint16_t, EventId > m_beginMuPayloadRxEvents
the beginning of the MU payload reception events (indexed by STA-ID)
virtual std::vector< Time > GetPer20MHzDurations(const Ptr< const WifiPpdu > ppdu)
Compute the per-20 MHz CCA durations vector that indicates for how long each 20 MHz subchannel (corre...
void RxPayloadFailed(Ptr< const WifiPsdu > psdu, double snr, const WifiTxVector &txVector) override
Perform amendment-specific actions when the payload is unsuccessfuly received.
Ptr< const WifiPpdu > GetRxPpduFromTxPpdu(Ptr< const WifiPpdu > ppdu) override
The WifiPpdu from the TX PHY is received by each RX PHY attached to the same channel.
HePhy(bool buildModeList=true)
Constructor for HE PHY.
bool IsConfigSupported(Ptr< const WifiPpdu > ppdu) const override
Checks if the signaled configuration (excluding bandwidth) is supported by the PHY.
uint16_t GetStaId(const Ptr< const WifiPpdu > ppdu) const override
Return the STA ID that has been assigned to the station this PHY belongs to.
static Time GetSymbolDuration(Time guardInterval)
void SetTrigVector(const WifiTxVector &trigVector, Time validity)
Set the TRIGVECTOR and the associated expiration time.
static std::pair< uint16_t, Time > ConvertHeTbPpduDurationToLSigLength(Time ppduDuration, const WifiTxVector &txVector, WifiPhyBand band)
Compute the L-SIG length value corresponding to the given HE TB PPDU duration.
static uint64_t GetNonHtReferenceRate(uint8_t mcsValue)
Calculate the rate in bps of the non-HT Reference Rate corresponding to the supplied HE MCS index.
WifiMode GetSigBMode(const WifiTxVector &txVector) const override
void SwitchMaybeToCcaBusy(const Ptr< const WifiPpdu > ppdu) override
Check if PHY state should move to CCA busy state based on current state of interference tracker.
Time DoStartReceivePayload(Ptr< Event > event) override
Start receiving the PSDU (i.e.
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration) override
Start receiving the PHY preamble of a PPDU (i.e.
virtual PhyFieldRxStatus ProcessSigA(Ptr< Event > event, PhyFieldRxStatus status)
Process SIG-A, perform amendment-specific actions, and provide an updated status of the reception.
std::optional< Time > m_trigVectorExpirationTime
expiration time of the TRIGVECTOR
void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu) override
Perform amendment-specific actions at the end of the reception of the payload.
void DoResetReceive(Ptr< Event > event) override
Perform amendment-specific actions before resetting PHY at the end of the PPDU under reception after ...
WifiMode GetSigAMode() const override
std::vector< MHz_u > GetCenterFrequenciesForNonHePart(const Ptr< const WifiPpdu > ppdu, uint16_t staId) const
Get the center frequency per segment of the non-HE portion of the current PPDU for the given STA-ID.
Time GetSigADuration(WifiPreamble preamble) const override
Time GetTrainingDuration(const WifiTxVector &txVector, uint8_t nDataLtf, uint8_t nExtensionLtf=0) const override
static std::vector< WifiSpectrumBandIndices > ConvertRuSubcarriers(const RuSubcarriersInfo &info)
This is a helper function to convert RU subcarriers, which are relative to the center frequency subca...
std::vector< Time > m_lastPer20MHzDurations
Hold the last per-20 MHz CCA durations vector.
void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration, WifiChannelListType channelType) override
Notify PHY state helper to switch to CCA busy state,.
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied HE MCS index.
WifiSpectrumBandInfo GetRuBandForTx(const WifiTxVector &txVector, uint16_t staId) const
Get the band in the TX spectrum associated with the RU used by the PSDU transmitted to/by a given STA...
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSDs for pre-HE and HE porti...
@ PSD_HE_PORTION
HE portion of an HE PPDU.
@ PSD_NON_HE_PORTION
Non-HE portion of an HE PPDU.
static uint32_t GetSigBFieldSize(MHz_u channelWidth, WifiModulationClass mc, const RuAllocation &ruAllocation, std::optional< Center26ToneRuIndication > center26ToneRuIndication, bool sigBCompression, std::size_t numMuMimoUsers)
Get variable length HE SIG-B field size.
static uint64_t CalculatePhyRate(WifiCodeRate codeRate, uint64_t dataRate)
Return the PHY rate corresponding to the supplied code rate and data rate.
CcaIndication GetCcaIndication(const Ptr< const WifiPpdu > ppdu) override
Get CCA end time and its corresponding channel list type when a new signal has been received by the P...
uint8_t m_bssMembershipSelector
the BSS membership selector
uint8_t m_maxMcsIndexPerSs
the maximum MCS index per spatial stream as defined by the standard
static uint64_t CalculateDataRate(Time symbolDuration, uint16_t usableSubCarriers, uint16_t numberOfBitsPerSubcarrier, double codingRate, uint8_t nss)
Calculates data rate from the supplied parameters.
static double GetCodeRatio(WifiCodeRate codeRate)
Convert WifiCodeRate to a ratio, e.g., code ratio of WIFI_CODE_RATE_1_2 is 0.5.
uint8_t m_maxSupportedMcsIndexPerSs
the maximum supported MCS index per spatial stream
static uint16_t GetUsableSubcarriers()
Ptr< const WifiPpdu > GetRxPpduFromTxPpdu(Ptr< const WifiPpdu > ppdu) override
The WifiPpdu from the TX PHY is received by each RX PHY attached to the same channel.
MHz_u GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const override
Return the channel width used to measure the RSSI.
void NotifyPayloadBegin(const WifiTxVector &txVector, const Time &payloadDuration)
Fire the trace indicating that the PHY is starting to receive the payload of a PPDU.
virtual void HandleRxPpduWithSameContent(Ptr< Event > event, Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPower)
Handle reception of a PPDU that carries the same content of another PPDU.
MHz_u GetGuardBandwidth(MHz_u currentChannelWidth) const
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper of the WifiPhy (to make it reachable for child classes)
virtual Time DoStartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
virtual void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
void Transmit(Time txDuration, Ptr< const WifiPpdu > ppdu, dBm_u txPower, Ptr< SpectrumValue > txPowerSpectrum, const std::string &type)
This function prepares most of the WifiSpectrumSignalParameters parameters and invokes SpectrumWifiPh...
const std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > & GetCurrentPreambleEvents() const
Get the map of current preamble events (stored in WifiPhy).
std::map< UidStaIdPair, SignalNoiseDbm > m_signalNoiseMap
Map of the latest signal power and noise power in dBm (noise power includes the noise figure)
Watt_u GetRxPowerForPpdu(Ptr< Event > event) const
Obtain the received power for a given band.
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
virtual void CancelAllEvents()
Cancel and clear all running events.
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
void EndReceivePayload(Ptr< Event > event)
The last symbol of the PPDU has arrived.
std::map< WifiPreamble, std::vector< WifiPpduField > > PpduFormats
A map of PPDU field elements per preamble type.
virtual std::pair< MHz_u, WifiSpectrumBandInfo > GetChannelWidthAndBand(const WifiTxVector &txVector, uint16_t staId) const
Get the channel width and band to use (will be overloaded by child classes).
static uint64_t m_globalPpduUid
Global counter of the PPDU UID.
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW)
Get the event corresponding to the incoming PPDU.
Time GetDelayUntilCcaEnd(dBm_u threshold, const WifiSpectrumBandInfo &band)
Return the delay until CCA busy is ended for a given sensitivity threshold and a given band.
Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector) const
void NotifyInterferenceRxEndAndClear(bool reset)
Notify WifiPhy's InterferenceHelper of the end of the reception, clear maps and end of MPDU event,...
std::map< UidStaIdPair, std::vector< bool > > m_statusPerMpduMap
Map of the current reception status per MPDU that is filled in as long as MPDUs are being processed b...
virtual bool CanStartRx(Ptr< const WifiPpdu > ppdu) const
Determine whether the PHY shall issue a PHY-RXSTART.indication primitive in response to a given PPDU.
virtual void StartTx(Ptr< const WifiPpdu > ppdu)
This function is called by SpectrumWifiPhy to send the PPDU while performing amendment-specific actio...
virtual uint16_t GetStaId(const Ptr< const WifiPpdu > ppdu) const
Return the STA ID that has been assigned to the station this PHY belongs to.
virtual bool IsModeSupported(WifiMode mode) const
Check if the WifiMode is supported.
void ResetReceive(Ptr< Event > event)
Reset PHY at the end of the PPDU under reception after it has failed the PHY header.
std::list< WifiMode > m_modeList
the list of supported modes
Ptr< const Event > GetCurrentEvent() const
Get the pointer to the current event (stored in WifiPhy).
virtual Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
void ErasePreambleEvent(Ptr< const WifiPpdu > ppdu, Time rxDuration)
Erase the event corresponding to the PPDU from the list of preamble events, but consider it as noise ...
void AddPreambleEvent(Ptr< Event > event)
Add an entry to the map of current preamble events (stored in WifiPhy).
virtual void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu)
Perform amendment-specific actions at the end of the reception of the payload.
std::tuple< dBr_u, dBr_u, dBr_u > GetTxMaskRejectionParams() const
Ptr< Event > CreateInterferenceEvent(Ptr< const WifiPpdu > ppdu, Time duration, RxPowerWattPerChannelBand &rxPower, bool isStartHePortionRxing=false)
Create an event using WifiPhy's InterferenceHelper class.
@ DROP
drop PPDU and set CCA_BUSY
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
static uint32_t GetNumBandsBetweenSegments(const std::vector< MHz_u > ¢erFrequencies, MHz_u totalWidth, Hz_u subcarrierSpacing)
Determine the number of bands between the two segments if the operating channel is made of non-contig...
Simulation virtual time values and global simulation resolution.
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
PHY entity for VHT (11ac)
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied VHT MCS index.
Time GetDuration(WifiPpduField field, const WifiTxVector &txVector) const override
Get the duration of the PPDU field (or group of fields) used by this entity for the given transmissio...
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
static uint64_t CalculateNonHtReferenceRate(WifiCodeRate codeRate, uint16_t constellationSize)
Return the rate (in bps) of the non-HT Reference Rate which corresponds to the supplied code rate and...
static WifiMode GetVhtMcs3()
Return MCS 3 from VHT MCS values.
dBm_u GetCcaThreshold(const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType) const override
Return the CCA threshold for a given channel type.
static WifiMode GetVhtMcs1()
Return MCS 1 from VHT MCS values.
static WifiMode GetVhtMcs4()
Return MCS 4 from VHT MCS values.
static WifiMode GetVhtMcs2()
Return MCS 2 from VHT MCS values.
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied VHT MCS index.
WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const override
Get the WifiMode for the SIG field specified by the PPDU field.
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, NonHtReferenceRateCallback nonHtReferenceRateCallback, AllowedCallback isAllowedCallback)
represent a single transmission mode
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
uint8_t GetMcsValue() const
dB_u GetTxGain() const
Return the transmission gain.
Hz_u GetSubcarrierSpacing() const
MHz_u GetFrequency() const
uint8_t GetMaxSupportedRxSpatialStreams() const
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
dBm_u GetCcaEdThreshold() const
Return the CCA energy detection threshold.
virtual WifiSpectrumBandFrequencies ConvertIndicesToFrequencies(const WifiSpectrumBandIndices &indices) const =0
This is a helper function to convert start and stop indices to start and stop frequencies.
void NotifyRxPpduDrop(Ptr< const WifiPpdu > ppdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxPpduDrop trace.
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
static void AddStaticPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of implemented PHY entities for the given modulation class.
MHz_u GetChannelWidth() const
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
dBm_u GetTxPowerForTransmission(Ptr< const WifiPpdu > ppdu) const
Compute the transmit power for the next transmission.
uint64_t GetPreviouslyRxPpduUid() const
Time GetLastRxEndTime() const
Return the end time of the last received packet.
virtual WifiSpectrumBandInfo GetBand(MHz_u bandWidth, uint8_t bandIndex=0)=0
Get the info of a given band.
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
std::set< uint8_t > GetAll20MHzChannelIndicesInPrimary(MHz_u width) const
Get the channel indices of all the 20 MHz channels included in the primary channel of the given width...
uint8_t GetPrimaryChannelIndex(MHz_u primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
std::vector< MHz_u > GetFrequencies() const
Return the center frequency per segment.
std::variant< HeRu::RuSpec, EhtRu::RuSpec > RuSpec
variant of the RU specification
static RuSpec FindOverlappingRu(MHz_u bw, RuSpec referenceRu, RuType searchedRuType)
Find the RU allocation of the given RU type overlapping the given reference RU allocation.
static MHz_u GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
static RuType GetRuType(RuSpec ru)
Get the type of a given RU.
static SubcarrierGroup GetSubcarrierGroup(MHz_u bw, RuType ruType, std::size_t phyIndex, WifiModulationClass mc)
Get the subcarrier group of the RU having the given PHY index among all the RUs of the given type (nu...
static std::size_t GetPhyIndex(RuSpec ru, MHz_u bw, uint8_t p20Index)
Get the RU PHY index.
static std::size_t GetIndex(RuSpec ru)
Get the index of a given RU.
static Ptr< SpectrumValue > CreateDuplicated20MhzTxPowerSpectralDensity(const std::vector< MHz_u > ¢erFrequencies, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=dBr_u{-20}, dBr_u minOuterband=dBr_u{-28}, dBr_u lowestPoint=dBr_u{-40}, const std::vector< bool > &puncturedSubchannels={})
Create a transmit power spectral density corresponding to OFDM duplicated over multiple 20 MHz subcha...
static Ptr< SpectrumValue > CreateHeMuOfdmTxPowerSpectralDensity(const std::vector< MHz_u > ¢erFrequencies, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, const std::vector< WifiSpectrumBandIndices > &ru)
Create a transmit power spectral density corresponding to the OFDMA part of HE TB PPDUs for a given R...
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(MHz_u centerFrequency, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=dBr_u{-20}, dBr_u minOuterband=dBr_u{-28}, dBr_u lowestPoint=dBr_u{-40}, const std::vector< bool > &puncturedSubchannels={})
Create a transmit power spectral density corresponding to OFDM High Efficiency (HE/EHT) (802....
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
bool IsTriggerResponding() const
Return true if the Trigger Responding parameter is set to true, false otherwise.
bool IsSigBCompression() const
Indicate whether the Common field is present in the HE-SIG-B field.
const RuAllocation & GetRuAllocation(uint8_t p20Index) const
Get RU_ALLOCATION field.
std::optional< Center26ToneRuIndication > GetCenter26ToneRuIndication() const
Get CENTER_26_TONE_RU field This field is present if format is HE_MU and when channel width is set to...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
WifiPreamble GetPreambleType() const
uint16_t GetLength() const
Get the LENGTH field of the L-SIG.
const HeMuUserInfoMap & GetHeMuUserInfoMap() const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
MHz_u GetChannelWidth() const
Time GetGuardInterval() const
WifiRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
WifiPpduField
The type of PPDU field (grouped for convenience)
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_PPDU_FIELD_SIG_B
SIG-B field.
@ WIFI_PPDU_FIELD_TRAINING
STF + LTF fields (excluding those in preamble for HT-GF)
@ WIFI_PPDU_FIELD_NON_HT_HEADER
PHY header field for DSSS or ERP, short PHY header field for HR/DSSS or ERP, field not present for HT...
@ WIFI_PPDU_FIELD_PREAMBLE
SYNC + SFD fields for DSSS or ERP, shortSYNC + shortSFD fields for HR/DSSS or ERP,...
@ WIFI_PPDU_FIELD_DATA
data field
@ WIFI_PPDU_FIELD_SIG_A
SIG-A field.
Declaration of ns3::HePhy class and ns3::HeSigAParameters struct.
#define HE_PHY
This defines the BSS membership value for HE PHY.
class anonymous_namespace{he-phy.cc}::ConstructorHe g_constructor_he
the constructor for HE modes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
dBm_u WToDbm(Watt_u val)
Convert from Watts to dBm.
double MHz_u
MHz weak type.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
double dBm_u
dBm weak type
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
@ LOG_FUNCTION
Function tracing for non-trivial function calls.
bool IsDlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a downlink multi-user transmission.
Hz_u MHzToHz(MHz_u val)
Convert from MHz to Hz.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
bool IsUlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a uplink multi-user transmission.
WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
@ WIFI_CODE_RATE_3_4
3/4 coding rate
@ WIFI_CODE_RATE_5_6
5/6 coding rate
structure containing the information about the RU subcarriers to be able to converted to the indices ...
MHz_u bandWidth
width of the band used for the OFDMA transmission.
Hz_u subcarrierSpacing
subcarrier spacing
MHz_u totalWidth
width of the operating channel
const std::vector< MHz_u > & centerFrequencies
center frequency of each segment
uint8_t bandIndex
index (starting at 0) of the band within the operating channel
MHz_u guardBandwidth
width of the guard band
WifiModulationClass mc
modulation class used for the transmission
SubcarrierRange subcarrierRange
subcarrier range of the RU
Parameters for received HE-SIG-A for OBSS_PD based SR.
Status of the reception of the PPDU field.
bool isSuccess
outcome (true if success) of the reception
RxSignalInfo structure containing info on the received signal.
SignalNoiseDbm structure.
WifiSpectrumBandInfo structure containing info about a spectrum band.
std::vector< WifiSpectrumBandIndices > indices
the start and stop indices for each segment of the band