24#include "ns3/assert.h"
25#include "ns3/data-rate.h"
27#include "ns3/mobility-model.h"
28#include "ns3/packet.h"
29#include "ns3/simulator.h"
33#undef NS_LOG_APPEND_CONTEXT
34#define NS_LOG_APPEND_CONTEXT WIFI_PHY_NS_LOG_APPEND_CONTEXT(m_wifiPhy)
47 return (os <<
"DROP");
49 return (os <<
"ABORT");
51 return (os <<
"IGNORE");
54 return (os <<
"unknown");
63 return os <<
"success";
115 "This method should be used only for HtPhy and child classes. Use GetMode instead.");
122 NS_ABORT_MSG(
"This method should be used only for HtPhy and child classes. Use IsModeSupported "
133std::list<WifiMode>::const_iterator
139std::list<WifiMode>::const_iterator
148 NS_FATAL_ERROR(
"PPDU field is not a SIG field (no sense in retrieving the signaled mode) or is "
158 const auto itPpdu = ppduFormats.find(preamble);
159 if (itPpdu != ppduFormats.end())
161 const auto itField = std::find(itPpdu->second.begin(), itPpdu->second.end(), currentField);
162 if (itField != itPpdu->second.end())
164 const auto itNextField = std::next(itField, 1);
165 if (itNextField != itPpdu->second.end())
167 return *(itNextField);
169 NS_FATAL_ERROR(
"No field after " << currentField <<
" for " << preamble
170 <<
" for the provided PPDU formats");
174 NS_FATAL_ERROR(
"Unsupported PPDU field " << currentField <<
" for " << preamble
175 <<
" for the provided PPDU formats");
180 NS_FATAL_ERROR(
"Unsupported preamble " << preamble <<
" for the provided PPDU formats");
215 return ppdu->GetPsdu();
223 Time start = ppduStart;
228 map[field] = {{start, start + duration},
GetSigMode(field, txVector)};
240 NS_FATAL_ERROR(
"This method is unsupported for the base PhyEntity class. Use the overloaded "
241 "version in the amendment-specific subclasses instead!");
256 auto it = sections.find(field);
258 const auto& startStopTimes = it->second.first;
259 return startStopTimes
267 return m_wifiPhy->m_interference->CalculatePhyHeaderSnrPer(
269 measurementChannelWidth,
281 "Use the StartReceivePreamble method for preamble reception");
292 << field <<
" for this PHY entity");
308 const auto& txVector =
event->GetPpdu()->GetTxVector();
356 const auto& txVector = ppdu->GetTxVector();
357 return ppdu->GetTxDuration() -
368 auto itFormat = ppduFormats.find(event->GetPpdu()->GetPreamble());
369 if (itFormat != ppduFormats.end())
371 auto itField = std::find(itFormat->second.begin(), itFormat->second.end(), field);
372 if (itField != itFormat->second.end())
399 std::max_element(rxPowersW.begin(), rxPowersW.end(), [](
const auto& p1,
const auto& p2) {
400 return p1.second < p2.second;
413 if (ppdu->IsTruncatedTx())
415 NS_LOG_DEBUG(
"Packet reception stopped because transmitter has been switched off");
427 NS_LOG_DEBUG(
"Drop packet because of channel switching");
440 m_wifiPhy->m_frameCaptureModel->IsInCaptureWindow(
441 m_wifiPhy->m_timeLastPreambleDetected) &&
461 m_wifiPhy->m_currentPreambleEvents.clear();
473 m_wifiPhy->m_frameCaptureModel->IsInCaptureWindow(
474 m_wifiPhy->m_timeLastPreambleDetected) &&
483 NS_LOG_DEBUG(
"Drop packet because already decoding preamble");
514 m_wifiPhy->NotifyRxPpduDrop(ppdu, reason);
515 auto it =
m_wifiPhy->m_currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
516 if (it !=
m_wifiPhy->m_currentPreambleEvents.end())
518 m_wifiPhy->m_currentPreambleEvents.erase(it);
532 auto it =
m_wifiPhy->m_currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
533 if (it !=
m_wifiPhy->m_currentPreambleEvents.end())
535 m_wifiPhy->m_currentPreambleEvents.erase(it);
537 if (
m_wifiPhy->m_currentPreambleEvents.empty())
542 if (rxDuration >
m_state->GetDelayUntilIdle())
562 m_state->SwitchToRx(payloadDuration);
575 const auto& txVector =
event->GetPpdu()->GetTxVector();
584 return payloadDuration;
593 const auto& txVector =
event->GetPpdu()->GetTxVector();
595 Time endOfMpduDuration;
598 Time remainingAmpduDuration = psduDuration;
599 size_t nMpdus = psdu->GetNMpdus();
603 double totalAmpduNumSymbols = 0.0;
604 auto mpdu = psdu->begin();
605 for (
size_t i = 0; i < nMpdus && mpdu != psdu->end(); ++mpdu)
611 (*mpdu)->GetHeader().GetSerializedSize() + (mpduType ==
NORMAL_MPDU ? 0 : 4);
613 auto macHdrDuration =
DataRate(txVector.GetMode(staId).GetDataRate(txVector, staId))
616 const auto snrPer =
m_wifiPhy->m_interference->CalculatePayloadSnrPer(
621 {relativeStart, relativeStart + macHdrDuration});
627 m_wifiPhy->m_phyRxMacHeaderEndTrace((*mpdu)->GetHeader(),
629 remainingAmpduDuration -
635 uint32_t size = (mpduType ==
NORMAL_MPDU) ? psdu->GetSize() : psdu->GetAmpduSubframeSize(i);
642 totalAmpduNumSymbols,
645 remainingAmpduDuration -= mpduDuration;
646 if (i == (nMpdus - 1) && !remainingAmpduDuration.
IsZero())
648 if (remainingAmpduDuration < txVector.GetGuardInterval())
650 mpduDuration += remainingAmpduDuration;
655 endOfMpduDuration += mpduDuration;
657 << i <<
" in " << endOfMpduDuration.
As(
Time::NS) <<
" (relativeStart="
659 <<
", remainingAmdpuDuration=" << remainingAmpduDuration.
As(
Time::NS) <<
")");
671 relativeStart += mpduDuration;
683 NS_LOG_FUNCTION(
this << *event << mpduIndex << relativeStart << mpduDuration);
684 const auto ppdu =
event->GetPpdu();
685 const auto& txVector = ppdu->GetTxVector();
688 std::pair<bool, SignalNoiseDbm> rxInfo =
691 <<
", correct reception: " << rxInfo.first <<
", Signal/Noise: "
692 << rxInfo.second.signal <<
"/" << rxInfo.second.noise <<
"dBm");
696 signalNoiseIt->second = rxInfo.second;
699 rxSignalInfo.
snr =
DbToRatio(
dB_u{rxInfo.second.signal - rxInfo.second.noise});
700 rxSignalInfo.
rssi = rxInfo.second.signal;
704 statusPerMpduIt->second.push_back(rxInfo.first);
716 const auto ppdu =
event->GetPpdu();
717 const auto& txVector = ppdu->GetTxVector();
723 const auto snr =
m_wifiPhy->m_interference->CalculateSnr(event,
724 channelWidthAndBand.first,
725 txVector.GetNss(staId),
726 channelWidthAndBand.second);
736 auto statusPerMpdu = statusPerMpduIt->second;
741 if (std::count(statusPerMpdu.cbegin(), statusPerMpdu.cend(),
true))
747 signalNoiseIt->second,
750 rxSignalInfo.
snr = snr;
751 rxSignalInfo.
rssi = signalNoiseIt->second.signal;
764 m_state->NotifyRxPpduOutcome(ppdu, rxSignalInfo, txVector, staId, statusPerMpduIt->second);
772 success ?
m_state->NotifyRxPsduSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu)
773 :
m_state->NotifyRxPsduFailed(psdu, snr);
781 const std::vector<bool>& statusPerMpdu)
791 m_state->SwitchFromRxEndError(txVector);
802 m_wifiPhy->m_currentPreambleEvents.clear();
806std::pair<bool, SignalNoiseDbm>
810 Time relativeMpduStart,
813 NS_LOG_FUNCTION(
this << *mpdu << *event << staId << relativeMpduStart << mpduDuration);
817 channelWidthAndBand.first,
818 channelWidthAndBand.second,
820 {relativeMpduStart, relativeMpduStart + mpduDuration});
822 WifiMode mode =
event->GetPpdu()->GetTxVector().GetMode(staId);
825 <<
", size=" << mpdu->GetSize()
826 <<
", relativeStart = " << relativeMpduStart.
As(
Time::NS)
827 <<
", duration = " << mpduDuration.
As(
Time::NS));
834 signalNoise.
signal =
WToDbm(event->GetRxPower(channelWidthAndBand.second));
835 signalNoise.
noise =
WToDbm(event->GetRxPower(channelWidthAndBand.second) / snrPer.
snr);
837 !(
m_wifiPhy->m_postReceptionErrorModel &&
838 m_wifiPhy->m_postReceptionErrorModel->IsCorrupt(mpdu->GetPacket()->Copy())))
841 return {
true, signalNoise};
846 return {
false, signalNoise};
858 std::optional<Time> delayUntilPreambleDetectionEnd;
861 if (endPreambleDetectionEvent.IsPending())
863 delayUntilPreambleDetectionEnd =
864 std::max(delayUntilPreambleDetectionEnd.value_or(
Time{0}),
868 return delayUntilPreambleDetectionEnd;
881 for (
const auto& endOfMacHdrEvent : it->second)
883 if (endOfMacHdrEvent.IsPending())
892std::pair<MHz_u, WifiSpectrumBandInfo>
899const std::map<std::pair<uint64_t, WifiPreamble>,
Ptr<Event>>&
902 return m_wifiPhy->m_currentPreambleEvents;
910 m_wifiPhy->m_currentPreambleEvents.insert({{ppdu->GetUid(), ppdu->GetPreamble()},
event});
919 const auto it = currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
920 if (it != currentPreambleEvents.cend())
923 NS_LOG_DEBUG(
"Received another PPDU for UID " << ppdu->GetUid());
924 const auto foundEvent = it->second;
938 bool isStartHePortionRxing )
940 return m_wifiPhy->m_interference->Add(ppdu,
944 isStartHePortionRxing);
952 if (
const auto maxDelay =
953 m_wifiPhy->GetPhyEntityForPpdu(ppdu)->GetMaxDelayPpduSameUid(ppdu->GetTxVector());
967 m_wifiPhy->m_interference->UpdateEvent(event, rxPower);
968 const auto& txVector = ppdu->GetTxVector();
969 const auto& eventTxVector =
event->GetPpdu()->GetTxVector();
970 auto updatedTxVector{eventTxVector};
971 updatedTxVector.SetChannelWidth(
972 std::max(eventTxVector.GetChannelWidth(), txVector.GetChannelWidth()));
973 if (updatedTxVector.GetChannelWidth() != eventTxVector.GetChannelWidth())
975 event->UpdatePpdu(ppdu);
992 for (
const auto& endOfMacHdrEvent : endOfMacHdrEvents)
1020 ? std::to_string(
WToDbm(rxPower)) +
"dBm)"
1021 : std::to_string(rxPower) +
"W)"));
1022 m_wifiPhy->m_interference->NotifyRxStart(
1043 std::optional<Watt_u>
1047 for (
auto preambleEvent :
m_wifiPhy->m_currentPreambleEvents)
1049 const auto rxPower = preambleEvent.second->GetRxPower(measurementBand);
1050 if (!maxRxPower || (rxPower > *maxRxPower))
1052 maxRxPower = rxPower;
1053 maxEvent = preambleEvent.second;
1058 if (maxEvent != event)
1060 NS_LOG_DEBUG(
"Receiver got a stronger packet with UID "
1061 << maxEvent->GetPpdu()->GetUid()
1062 <<
" during preamble detection: drop packet with UID "
1063 << event->GetPpdu()->GetUid());
1066 auto it =
m_wifiPhy->m_currentPreambleEvents.find(
1067 {
event->GetPpdu()->GetUid(),
event->GetPpdu()->GetPreamble()});
1068 m_wifiPhy->m_currentPreambleEvents.erase(it);
1071 m_wifiPhy->m_interference->NotifyRxEnd(maxEvent->GetStartTime(),
1081 measurementChannelWidth,
1086 if (
const auto power =
m_wifiPhy->m_currentEvent->GetRxPower(measurementBand);
1087 (!
m_wifiPhy->m_preambleDetectionModel && maxRxPower && (*maxRxPower >
Watt_u{0.0})) ||
1089 m_wifiPhy->m_preambleDetectionModel->IsPreambleDetected(
WToDbm(power),
1091 measurementChannelWidth)))
1094 for (
auto& it :
m_wifiPhy->m_phyEntities)
1096 it.second->CancelRunningEndPreambleDetectionEvents();
1099 for (
auto it =
m_wifiPhy->m_currentPreambleEvents.begin();
1100 it !=
m_wifiPhy->m_currentPreambleEvents.end();)
1102 if (it->second !=
m_wifiPhy->m_currentEvent)
1104 NS_LOG_DEBUG(
"Drop packet with UID " << it->first.first <<
" and preamble "
1105 << it->first.second <<
" arrived at time "
1106 << it->second->GetStartTime());
1108 if (
m_wifiPhy->m_currentEvent->GetPpdu()->GetUid() > it->first.first)
1114 m_wifiPhy->m_currentEvent->GetStartTime(),
1121 m_wifiPhy->NotifyRxPpduDrop(it->second->GetPpdu(), reason);
1123 it =
m_wifiPhy->m_currentPreambleEvents.erase(it);
1135 m_wifiPhy->m_currentEvent->GetRxPowerPerBand());
1139 const auto durationTillEnd =
1142 m_wifiPhy->NotifyCcaBusy(event->GetPpdu(),
1152 NS_LOG_DEBUG(
"Drop packet because PHY preamble detection failed");
1157 m_wifiPhy->m_currentEvent->GetEndTime());
1158 if (
m_wifiPhy->m_currentPreambleEvents.empty())
1173 WifiMode txMode = ppdu->GetTxVector().GetMode();
1176 NS_LOG_DEBUG(
"Drop packet because it was sent using an unsupported mode (" << txMode
1190 endRxPayloadEvent.Cancel();
1195 endMpduEvent.Cancel();
1200 for (
auto& endMacHdrEvent : endOfMacHdrEvents)
1202 endMacHdrEvent.Cancel();
1214 endPreambleDetectionEvent.Cancel();
1224 m_wifiPhy->AbortCurrentReception(reason);
1235 endMpduEvent.Cancel();
1240 for (
auto& endMacHdrEvent : endOfMacHdrEvents)
1242 endMacHdrEvent.Cancel();
1259 m_wifiPhy->m_currentPreambleEvents.clear();
1260 m_wifiPhy->SwitchMaybeToCcaBusy(event->GetPpdu());
1291 if (
static_cast<uint16_t
>(
m_wifiPhy->GetChannelWidth()) % 20 != 0)
1296 m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(bandWidth));
1304 m_wifiPhy->GetOperatingChannel().GetSecondaryChannelIndex(bandWidth));
1317 return (!ppdu) ?
m_wifiPhy->GetCcaEdThreshold() :
m_wifiPhy->GetCcaSensitivityThreshold();
1323 return m_wifiPhy->m_interference->GetEnergyDuration(
DbmToW(threshold), band);
1334 if (ccaIndication.has_value())
1336 NS_LOG_DEBUG(
"CCA busy for " << ccaIndication.value().second <<
" during "
1337 << ccaIndication.value().first.As(
Time::S));
1338 m_state->SwitchMaybeToCcaBusy(ccaIndication.value().first,
1339 ccaIndication.value().second,
1360 return std::nullopt;
1370 m_state->SwitchMaybeToCcaBusy(duration, channelType, {});
1389 m_wifiPhy->m_phyRxPayloadBeginTrace(txVector, payloadDuration);
1397 auto txVector = ppdu->GetTxVector();
1399 Transmit(ppdu->GetTxDuration(), ppdu, txPower, txPowerSpectrum,
"transmission");
1407 const std::string& type)
1410 NS_LOG_DEBUG(
"Start " << type <<
": signal power before antenna gain=" << txPower <<
"dBm");
1412 txParams->duration = txDuration;
1413 txParams->psd = txPowerSpectrum;
1414 txParams->ppdu = ppdu;
1415 NS_LOG_DEBUG(
"Starting " << type <<
" with power " << txPower <<
" dBm on channel "
1416 << +
m_wifiPhy->GetChannelNumber() <<
" for "
1417 << txParams->duration.As(
Time::MS));
1418 NS_LOG_DEBUG(
"Starting " << type <<
" with integrated spectrum power "
1419 <<
WToDbm(
Integral(*txPowerSpectrum)) <<
" dBm; spectrum model Uid: "
1420 << txPowerSpectrum->GetSpectrumModel()->GetUid());
1423 spectrumWifiPhy->Transmit(txParams);
1429 return m_wifiPhy->GetGuardBandwidth(currentChannelWidth);
1432std::tuple<dBr_u, dBr_u, dBr_u>
1435 return m_wifiPhy->GetTxMaskRejectionParams();
1444 const auto& it = psduMap.begin();
1453 const auto channelWidth =
m_wifiPhy->GetChannelWidth();
1454 const auto primaryWidth = ((
static_cast<uint16_t
>(channelWidth) % 20 == 0)
1458 const auto p20CenterFreq =
1459 m_wifiPhy->GetOperatingChannel().GetPrimaryChannelCenterFrequency(primaryWidth);
1460 const auto p20MinFreq = p20CenterFreq - (primaryWidth / 2);
1461 const auto p20MaxFreq = p20CenterFreq + (primaryWidth / 2);
1462 const auto txChannelWidth = (ppdu->GetTxChannelWidth() / ppdu->GetTxCenterFreqs().size());
1463 for (
auto txCenterFreq : ppdu->GetTxCenterFreqs())
1465 const auto minTxFreq = txCenterFreq - txChannelWidth / 2;
1466 const auto maxTxFreq = txCenterFreq + txChannelWidth / 2;
1467 if ((p20MinFreq >= minTxFreq) && (p20MaxFreq <= maxTxFreq))
Class for representing data rates.
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
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.
void DropPreambleEvent(Ptr< const WifiPpdu > ppdu, WifiPhyRxfailureReason reason, Time endRx)
Drop the PPDU and the corresponding preamble detection event, but keep CCA busy state after the compl...
std::list< WifiMode >::const_iterator end() const
Return a const iterator to past-the-last WifiMode.
void EndOfMpdu(Ptr< Event > event, Ptr< WifiMpdu > mpdu, size_t mpduIndex, Time relativeStart, Time mpduDuration)
The last symbol of an MPDU in an A-MPDU has arrived.
MHz_u GetGuardBandwidth(MHz_u currentChannelWidth) const
virtual void RxPayloadSucceeded(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, uint16_t staId, const std::vector< bool > &statusPerMpdu)
Perform amendment-specific actions when the payload is successfully received.
virtual PhyFieldRxStatus DoEndReceivePreamble(Ptr< Event > event)
End receiving the preamble, perform amendment-specific actions, and provide the status of the recepti...
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper of the WifiPhy (to make it reachable for child classes)
virtual void RxPayloadFailed(Ptr< const WifiPsdu > psdu, double snr, const WifiTxVector &txVector)
Perform amendment-specific actions when the payload is unsuccessfuly received.
void EndPreambleDetectionPeriod(Ptr< Event > event)
End the preamble detection period.
virtual void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration, WifiChannelListType channelType)
Notify PHY state helper to switch to CCA busy state,.
virtual Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration)
Build amendment-specific PPDU.
virtual Time GetDuration(WifiPpduField field, const WifiTxVector &txVector) const
Get the duration of the PPDU field (or group of fields) used by this entity for the given transmissio...
virtual uint64_t ObtainNextUid(const WifiTxVector &txVector)
Obtain the next UID for the PPDU to transmit.
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.
virtual std::optional< Time > GetTimeToPreambleDetectionEnd() const
Get the remaining time to preamble detection period to elapse, if preamble detection is ongoing.
virtual bool HandlesMcsModes() const
Check if the WifiModes handled by this PHY are MCSs.
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::pair< bool, SignalNoiseDbm > GetReceptionStatus(Ptr< WifiMpdu > mpdu, Ptr< Event > event, uint16_t staId, Time relativeMpduStart, Time mpduDuration)
Get the reception status for the provided MPDU and notify.
std::optional< std::pair< Time, WifiChannelListType > > CcaIndication
CCA end time and its corresponding channel list type (can be std::nullopt if IDLE)
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
virtual MHz_u GetRxChannelWidth(const WifiTxVector &txVector) const
Return the channel width used in the reception spectrum model.
virtual ~PhyEntity()
Destructor for PHY entity.
virtual const PpduFormats & GetPpduFormats() const =0
Return the PPDU formats of the PHY.
virtual uint8_t GetNumModes() const
virtual bool DoStartReceiveField(WifiPpduField field, Ptr< Event > event)
Start receiving a given field, perform amendment-specific actions, and signify if it is supported.
void SetOwner(Ptr< WifiPhy > wifiPhy)
Set the WifiPhy owning this PHY entity.
std::list< WifiMode >::const_iterator begin() const
Return a const iterator to the first WifiMode.
virtual void CancelAllEvents()
Cancel and clear all running events.
virtual Time CalculateTxDuration(const WifiConstPsduMap &psduMap, const WifiTxVector &txVector, WifiPhyBand band) const
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Abort the current reception.
void EndReceivePayload(Ptr< Event > event)
The last symbol of the PPDU has arrived.
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.
virtual Ptr< SpectrumValue > GetTxPowerSpectralDensity(Watt_u txPower, Ptr< const WifiPpdu > ppdu) const =0
virtual bool IsMcsSupported(uint8_t index) const
Check if the WifiMode corresponding to the given MCS index is supported.
void StartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
virtual void DoResetReceive(Ptr< Event > event)
Perform amendment-specific actions before resetting PHY at the end of the PPDU under reception after ...
void EndReceiveField(WifiPpduField field, Ptr< Event > event)
End receiving a given field.
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW)
Get the event corresponding to the incoming PPDU.
virtual WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const
Get the WifiMode for the SIG field specified by the PPDU field.
WifiSpectrumBandInfo GetPrimaryBand(MHz_u bandWidth) const
If the operating channel width is a multiple of 20 MHz, return the info corresponding to the primary ...
WifiPpduField GetNextField(WifiPpduField currentField, WifiPreamble preamble) const
Return the field following the provided one.
void CancelRunningEndPreambleDetectionEvents()
Cancel all end preamble detection events.
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.
virtual void SwitchMaybeToCcaBusy(const Ptr< const WifiPpdu > ppdu)
Check if PHY state should move to CCA busy state based on current state of interference tracker.
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,...
void StartPreambleDetectionPeriod(Ptr< Event > event)
Start the preamble detection period.
Time GetDurationUpToField(WifiPpduField field, const WifiTxVector &txVector) const
Get the duration of the PPDU up to (but excluding) the given field.
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...
SnrPer GetPhyHeaderSnrPer(WifiPpduField field, Ptr< Event > event) const
Obtain the SNR and PER of the PPDU field from the WifiPhy's InterferenceHelper class.
virtual dBm_u GetCcaThreshold(const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType) const
Return the CCA threshold for a given channel type.
Time GetRemainingDurationAfterField(Ptr< const WifiPpdu > ppdu, WifiPpduField field) const
Get the remaining duration of the PPDU after the end of the given field.
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.
void StartReceiveField(WifiPpduField field, Ptr< Event > event)
Start receiving a given field.
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.
PhyHeaderSections GetPhyHeaderSections(const WifiTxVector &txVector, Time ppduStart) const
Return a map of PHY header chunk information per PPDU field.
virtual CcaIndication GetCcaIndication(const Ptr< const WifiPpdu > ppdu)
Get CCA end time and its corresponding channel list type when a new signal has been received by the P...
std::list< WifiMode > m_modeList
the list of supported modes
virtual Time GetMaxDelayPpduSameUid(const WifiTxVector &txVector)
Obtain the maximum time between two PPDUs with the same UID to consider they are identical and their ...
Ptr< const Event > GetCurrentEvent() const
Get the pointer to the current event (stored in WifiPhy).
double GetRandomValue() const
Obtain a random value from the WifiPhy's generator.
std::vector< EventId > m_endPreambleDetectionEvents
the end of preamble detection events
virtual std::optional< Time > GetTimeToMacHdrEnd(uint16_t staId) const
Get the remaining time to the end of the MAC header reception of the next MPDU being received from th...
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 ...
virtual Ptr< const WifiPpdu > GetRxPpduFromTxPpdu(Ptr< const WifiPpdu > ppdu)
The WifiPpdu from the TX PHY is received by each RX PHY attached to the same channel.
virtual WifiMode GetMcs(uint8_t index) const
Get the WifiMode corresponding to the given MCS index.
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
virtual MHz_u GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const =0
Return the channel width used to measure the RSSI.
virtual WifiConstPsduMap GetWifiConstPsduMap(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector) const
Get a WifiConstPsduMap from a PSDU and the TXVECTOR to use to send the PSDU.
virtual bool IsConfigSupported(Ptr< const WifiPpdu > ppdu) const
Checks if the signaled configuration (excluding bandwidth) is supported by the PHY.
Ptr< Event > CreateInterferenceEvent(Ptr< const WifiPpdu > ppdu, Time duration, RxPowerWattPerChannelBand &rxPower, bool isStartHePortionRxing=false)
Create an event using WifiPhy's InterferenceHelper class.
PhyRxFailureAction
Action to perform in case of RX failure.
@ DROP
drop PPDU and set CCA_BUSY
@ IGNORE
ignore the reception
@ ABORT
abort reception of PPDU
WifiSpectrumBandInfo GetSecondaryBand(MHz_u bandWidth) const
If the channel bonding is used, return the info corresponding to the secondary channel of the given b...
virtual PhyFieldRxStatus DoEndReceiveField(WifiPpduField field, Ptr< Event > event)
End receiving a given field, perform amendment-specific actions, and provide the status of the recept...
std::map< uint16_t, std::vector< EventId > > m_endOfMacHdrEvents
STA_ID-indexed map of the RX end of MAC header events.
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.
Simulation virtual time values and global simulation resolution.
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.
bool IsZero() const
Exactly equivalent to t == 0.
represent a single transmission mode
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
static Time GetPayloadDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, MpduType mpdutype=NORMAL_MPDU, uint16_t staId=SU_STA_ID)
static Time GetPreambleDetectionDuration()
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiPreamble GetPreambleType() const
MHz_u GetChannelWidth() const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#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_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_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.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double 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)
MpduType
The type of an MPDU.
@ PREAMBLE_DETECT_FAILURE
@ FRAME_CAPTURE_PACKET_SWITCH
@ PREAMBLE_DETECTION_PACKET_SWITCH
@ WIFI_PPDU_FIELD_EHT_SIG
EHT-SIG field.
@ 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
@ LAST_MPDU_IN_AGGREGATE
The MPDU is the last aggregate in an A-MPDU with multiple MPDUs.
@ NORMAL_MPDU
The MPDU is not part of an A-MPDU.
@ FIRST_MPDU_IN_AGGREGATE
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate.
@ SINGLE_MPDU
The MPDU is a single MPDU.
@ MIDDLE_MPDU_IN_AGGREGATE
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
@ SWITCHING
The PHY layer is switching to other channel.
@ TX
The PHY layer is sending a packet.
@ OFF
The PHY layer is switched off.
@ IDLE
The PHY layer is IDLE.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ SLEEP
The PHY layer is sleeping.
@ RX
The PHY layer is receiving a packet.
dB_u RatioToDb(double ratio)
Convert from ratio to dB.
std::ostream & operator<<(std::ostream &os, const Angles &a)
double Integral(const SpectrumValue &arg)
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
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.
double dBm_u
dBm weak type
double DbToRatio(dB_u val)
Convert from dB to ratio.
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
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)
double Watt_u
Watt weak type.
Status of the reception of the PPDU field.
WifiPhyRxfailureReason reason
failure reason
PhyRxFailureAction actionIfFailure
action to perform in case of failure
bool isSuccess
outcome (true if success) of the reception
RxSignalInfo structure containing info on the received signal.
double snr
SNR in linear scale.
SignalNoiseDbm structure.
dBm_u signal
signal strength
A struct for both SNR and PER.
double snr
SNR in linear scale.
WifiSpectrumBandInfo structure containing info about a spectrum band.