wifi: Add a trace source to WifiPhy to notify of MAC header reception

This commit is contained in:
Stefano Avallone
2024-01-08 22:59:09 +01:00
parent f78be0a507
commit 34956c3ceb
5 changed files with 82 additions and 1 deletions

View File

@@ -20,6 +20,7 @@ Changes from ns-3.42 to ns-3-dev
* (tcp) A new trace source `TcpSocketBase::LastRtt` has been added for tracing the last RTT sample observed. The existing trace source `TcpSocketBase::Rtt` is still providing the smoothed RTT, although it had been incorrectly documented as providing the last RTT.
* (core) Added `LaplacianRandomVariable` class implementing the Laplacian random variable, and `LargestExtremeValueRandomVariable` class implementing the Largest Extreme Value random variable.
* (wifi) Added a new trace source to `WifiPhy`: **PhyRxMacHeaderEnd**, which is fired when the reception of the MAC header of an MPDU is completed and provides the MAC header and the remaining PSDU duration. The trace source is actually fired when the new **NotifyMacHdrRxEnd** attribute of `WifiPhy` is set to true (it is set to false by default).
### Changes to existing API

View File

@@ -31,6 +31,7 @@
#include "wifi-utils.h"
#include "ns3/assert.h"
#include "ns3/data-rate.h"
#include "ns3/log.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"
@@ -611,6 +612,34 @@ PhyEntity::ScheduleEndOfMpdus(Ptr<Event> event)
auto mpdu = psdu->begin();
for (size_t i = 0; i < nMpdus && mpdu != psdu->end(); ++mpdu)
{
if (m_wifiPhy->m_notifyRxMacHeaderEnd)
{
// calculate MAC header size (including A-MPDU subframe header, if present)
auto macHdrSize =
(*mpdu)->GetHeader().GetSerializedSize() + (mpduType == NORMAL_MPDU ? 0 : 4);
// calculate the (approximate) duration of the MAC header TX
auto macHdrDuration = DataRate(txVector.GetMode(staId).GetDataRate(txVector, staId))
.CalculateBytesTxTime(macHdrSize);
const auto widthBand = GetChannelWidthAndBand(txVector, staId);
const auto snrPer = m_wifiPhy->m_interference->CalculatePayloadSnrPer(
event,
widthBand.first,
widthBand.second,
staId,
{relativeStart, relativeStart + macHdrDuration});
if (GetRandomValue() > snrPer.per)
{
// interference level should permit to correctly decode the MAC header
m_endOfMacHdrEvents.push_back(
Simulator::Schedule(endOfMpduDuration + macHdrDuration, [=, this]() {
m_wifiPhy->m_phyRxMacHeaderEndTrace((*mpdu)->GetHeader(),
txVector,
remainingAmpduDuration -
macHdrDuration);
}));
}
}
uint32_t size = (mpduType == NORMAL_MPDU) ? psdu->GetSize() : psdu->GetAmpduSubframeSize(i);
Time mpduDuration = m_wifiPhy->GetPayloadDuration(size,
txVector,
@@ -925,6 +954,11 @@ PhyEntity::NotifyInterferenceRxEndAndClear(bool reset)
NS_ASSERT(endOfMpduEvent.IsExpired());
}
m_endOfMpduEvents.clear();
for (const auto& endOfMacHdrEvent : m_endOfMacHdrEvents)
{
NS_ASSERT(endOfMacHdrEvent.IsExpired());
}
m_endOfMacHdrEvents.clear();
if (reset)
{
m_wifiPhy->Reset();
@@ -1122,6 +1156,11 @@ PhyEntity::CancelAllEvents()
endMpduEvent.Cancel();
}
m_endOfMpduEvents.clear();
for (auto& endMacHdrEvent : m_endOfMacHdrEvents)
{
endMacHdrEvent.Cancel();
}
m_endOfMacHdrEvents.clear();
}
bool
@@ -1160,6 +1199,11 @@ PhyEntity::DoAbortCurrentReception(WifiPhyRxfailureReason reason)
endMpduEvent.Cancel();
}
m_endOfMpduEvents.clear();
for (auto& endMacHdrEvent : m_endOfMacHdrEvents)
{
endMacHdrEvent.Cancel();
}
m_endOfMacHdrEvents.clear();
}
}

View File

@@ -954,7 +954,8 @@ class PhyEntity : public SimpleRefCount<PhyEntity>
std::list<WifiMode> m_modeList; //!< the list of supported modes
std::vector<EventId> m_endPreambleDetectionEvents; //!< the end of preamble detection events
std::vector<EventId> m_endOfMpduEvents; //!< the end of MPDU events (only used for A-MPDUs)
std::vector<EventId> m_endOfMpduEvents; //!< the end of MPDU events (only used for A-MPDUs)
std::vector<EventId> m_endOfMacHdrEvents; //!< the end of MAC header events
std::vector<EventId>
m_endRxPayloadEvents; //!< the end of receive events (only one unless UL MU reception)

View File

@@ -304,6 +304,12 @@ WifiPhy::GetTypeId()
DoubleValue(100.0), // set to a high value so as to have no effect
MakeDoubleAccessor(&WifiPhy::m_powerDensityLimit),
MakeDoubleChecker<double>())
.AddAttribute("NotifyMacHdrRxEnd",
"Whether the PHY is capable of notifying the MAC about the end of "
"the reception of the MAC header of every MPDU.",
BooleanValue(false),
MakeBooleanAccessor(&WifiPhy::m_notifyRxMacHeaderEnd),
MakeBooleanChecker())
.AddTraceSource("PhyTxBegin",
"Trace source indicating a packet "
"has begun transmitting over the channel medium",
@@ -335,6 +341,11 @@ WifiPhy::GetTypeId()
"payload of a PPDU has begun",
MakeTraceSourceAccessor(&WifiPhy::m_phyRxPayloadBeginTrace),
"ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
.AddTraceSource("PhyRxMacHeaderEnd",
"Trace source indicating the MAC header of an MPDU has been "
"completely received.",
MakeTraceSourceAccessor(&WifiPhy::m_phyRxMacHeaderEndTrace),
"ns3::WifiPhy::PhyRxMacHeaderEndTracedCallback")
.AddTraceSource("PhyRxEnd",
"Trace source indicating a packet "
"has been completely received from the channel medium "

View File

@@ -55,6 +55,7 @@ class WifiRadioEnergyModel;
class UniformRandomVariable;
class InterferenceHelper;
class ErrorRateModel;
class WifiMacHeader;
/**
* \brief 802.11 PHY layer model
@@ -766,6 +767,17 @@ class WifiPhy : public Object
typedef void (*PhyRxPpduDropTracedCallback)(Ptr<const WifiPpdu> ppdu,
WifiPhyRxfailureReason reason);
/**
* TracedCallback signature for end of MAC header reception events.
*
* \param macHdr the MAC header of the MPDU being received
* \param txVector the TXVECTOR used to transmit the PSDU
* \param psduDuration the remaining duration of the PSDU
*/
typedef void (*PhyRxMacHeaderEndTracedCallback)(const WifiMacHeader& macHdr,
const WifiTxVector& txVector,
Time psduDuration);
/**
* Assign a fixed random variable stream number to the random variables
* used by this model. Return the number of streams (possibly zero) that
@@ -1505,6 +1517,17 @@ class WifiPhy : public Object
*/
TracedCallback<WifiTxVector, Time> m_phyRxPayloadBeginTrace;
/**
* The trace source fired when the reception of a MAC header ends.
*
* This traced callback models the behavior of real PHYs that are able to decode the MAC
* header of an MPDU being received and make the information therein available to the MAC
* as soon as the reception of the MAC header ends.
*
* \see class CallBackTraceSource
*/
TracedCallback<const WifiMacHeader&, const WifiTxVector&, Time> m_phyRxMacHeaderEndTrace;
/**
* The trace source fired when a packet ends the reception process from
* the medium.
@@ -1624,6 +1647,7 @@ class WifiPhy : public Object
Ptr<WifiRadioEnergyModel> m_wifiRadioEnergyModel; //!< Wifi radio energy model
Ptr<ErrorModel> m_postReceptionErrorModel; //!< Error model for receive packet events
Time m_timeLastPreambleDetected; //!< Record the time the last preamble was detected
bool m_notifyRxMacHeaderEnd; //!< whether the PHY is capable of notifying MAC header RX end
Callback<void> m_capabilitiesChangedCallback; //!< Callback when PHY capabilities changed
};