wifi: Add functions to update frame retry count and drop MPDUs

This commit is contained in:
Stefano Avallone
2024-07-24 17:32:11 +02:00
parent 194b48ecfa
commit 7307d68c41
4 changed files with 132 additions and 1 deletions

View File

@@ -994,6 +994,25 @@ FrameExchangeManager::NotifyChannelReleased(Ptr<Txop> txop)
m_protectedStas.clear();
}
Ptr<WifiMpdu>
FrameExchangeManager::DropMpduIfRetryLimitReached(Ptr<WifiPsdu> psdu)
{
NS_LOG_FUNCTION(this << *psdu);
const auto mpdusToDrop = GetWifiRemoteStationManager()->GetMpdusToDropOnTxFailure(psdu);
Ptr<WifiMpdu> droppedMpdu{nullptr};
for (const auto& mpdu : mpdusToDrop)
{
// this MPDU needs to be dropped
droppedMpdu = mpdu;
NotifyPacketDiscarded(mpdu);
DequeueMpdu(mpdu);
}
return droppedMpdu;
}
void
FrameExchangeManager::NormalAckTimeout(Ptr<WifiMpdu> mpdu, const WifiTxVector& txVector)
{

View File

@@ -652,6 +652,17 @@ class FrameExchangeManager : public Object
*/
virtual void TransmissionFailed();
/**
* Wrapper for the GetMpdusToDropOnTxFailure function of the remote station manager that
* additionally drops the MPDUs in the given PSDU that the remote station manager requested
* to drop.
*
* @param psdu the given PSDU
* @return an MPDU that has been dropped, if any, to be notified to the remote station manager
* through the appropriate function
*/
Ptr<WifiMpdu> DropMpduIfRetryLimitReached(Ptr<WifiPsdu> psdu);
/**
* Called when the Ack timeout expires.
*

View File

@@ -15,6 +15,7 @@
#include "wifi-mpdu.h"
#include "wifi-net-device.h"
#include "wifi-phy.h"
#include "wifi-psdu.h"
#include "wifi-tx-parameters.h"
#include "ns3/boolean.h"
@@ -57,6 +58,17 @@ WifiRemoteStationManager::GetTypeId()
UintegerValue(4),
MakeUintegerAccessor(&WifiRemoteStationManager::SetMaxSlrc),
MakeUintegerChecker<uint32_t>())
.AddAttribute(
"IncrementRetryCountUnderBa",
"The 802.11-2020 standard states that the retry count for frames that are part of "
"a Block Ack agreement shall not be incremented when a transmission fails. As a "
"consequence, frames that are part of a Block Ack agreement are not dropped based "
"on the number of retries. Set this attribute to true to override the standard "
"behavior and increment the retry count (and eventually drop) frames that are "
"part of a Block Ack agreement.",
BooleanValue(false),
MakeBooleanAccessor(&WifiRemoteStationManager::m_incrRetryCountUnderBa),
MakeBooleanChecker())
.AddAttribute("RtsCtsThreshold",
"If the size of the PSDU is bigger than this value, we use an RTS/CTS "
"handshake before sending the data frame."
@@ -1110,6 +1122,63 @@ WifiRemoteStationManager::ReportAmpduTxStatus(Mac48Address address,
dataTxVector.GetNss(GetStaId(address, dataTxVector)));
}
std::list<Ptr<WifiMpdu>>
WifiRemoteStationManager::GetMpdusToDropOnTxFailure(Ptr<WifiPsdu> psdu)
{
NS_LOG_FUNCTION(this << *psdu);
auto* station = Lookup(psdu->GetHeader(0).GetAddr1());
DoIncrementRetryCountOnTxFailure(station, psdu);
return DoGetMpdusToDropOnTxFailure(station, psdu);
}
void
WifiRemoteStationManager::DoIncrementRetryCountOnTxFailure(WifiRemoteStation* station,
Ptr<WifiPsdu> psdu)
{
NS_LOG_FUNCTION(this << *psdu);
// The frame retry count for an MSDU or A-MSDU that is not part of a block ack agreement or
// for an MMPDU shall be incremented every time transmission fails for that MSDU, A-MSDU, or
// MMPDU, including of an associated RTS (Sec. 10.23.2.12.1 of 802.11-2020).
// Frames for which the retry count needs to be incremented:
// - management frames
// - non-QoS Data frames
// - QoS Data frames that are not part of a Block Ack agreement
// - QoS Data frames that are part of a Block Ack agreement if the IncrementRetryCountUnderBa
// attribute is set to true
const auto& hdr = psdu->GetHeader(0);
if (hdr.IsMgt() || (hdr.IsData() && !hdr.IsQosData()) ||
(hdr.IsQosData() && (!m_wifiMac->GetBaAgreementEstablishedAsOriginator(
hdr.GetAddr1(),
hdr.GetQosTid() || m_incrRetryCountUnderBa))))
{
psdu->IncrementRetryCount();
}
}
std::list<Ptr<WifiMpdu>>
WifiRemoteStationManager::DoGetMpdusToDropOnTxFailure(WifiRemoteStation* station,
Ptr<WifiPsdu> psdu)
{
NS_LOG_FUNCTION(this << *psdu);
std::list<Ptr<WifiMpdu>> mpdusToDrop;
for (const auto& mpdu : *PeekPointer(psdu))
{
if (mpdu->GetRetryCount() == m_wifiMac->GetFrameRetryLimit())
{
// this MPDU needs to be dropped
mpdusToDrop.push_back(mpdu);
}
}
return mpdusToDrop;
}
bool
WifiRemoteStationManager::NeedRts(const WifiMacHeader& header, const WifiTxParameters& txParams)
{

View File

@@ -26,6 +26,7 @@
#include "ns3/vht-capabilities.h"
#include <array>
#include <list>
#include <memory>
#include <optional>
#include <unordered_map>
@@ -38,6 +39,7 @@ class WifiMac;
class WifiMacHeader;
class Packet;
class WifiMpdu;
class WifiPsdu;
class WifiTxVector;
class WifiTxParameters;
@@ -975,6 +977,15 @@ class WifiRemoteStationManager : public Object
*/
void ReportRxOk(Mac48Address address, RxSignalInfo rxSignalInfo, const WifiTxVector& txVector);
/**
* Increment the retry count for all the MPDUs (if needed) in the given PSDU and find the
* MPDUs to drop based on the frame retry count.
*
* @param psdu the given PSDU, whose transmission failed
* @return the list of MPDUs that have to be dropped
*/
std::list<Ptr<WifiMpdu>> GetMpdusToDropOnTxFailure(Ptr<WifiPsdu> psdu);
/**
* @param header MAC header of the data frame to send
* @param txParams the TX parameters for the data frame to send
@@ -1277,7 +1288,9 @@ class WifiRemoteStationManager : public Object
*/
uint8_t GetNess(const WifiRemoteStation* station) const;
uint8_t m_linkId; //!< the ID of the link this object is associated with
uint8_t m_linkId; //!< the ID of the link this object is associated with
bool m_incrRetryCountUnderBa; //!< whether to increment the retry count of frames that are
//!< part of a Block Ack agreement
private:
/**
@@ -1291,6 +1304,25 @@ class WifiRemoteStationManager : public Object
*/
uint16_t GetStaId(Mac48Address address, const WifiTxVector& txVector) const;
/**
* Increment the retry count (if needed) for the given PSDU, whose transmission failed.
*
* @param station the station the PSDU is addressed to
* @param psdu the given PSDU
*/
virtual void DoIncrementRetryCountOnTxFailure(WifiRemoteStation* station, Ptr<WifiPsdu> psdu);
/**
* Find the MPDUs to drop (possibly based on their frame retry count) in the given PSDU,
* whose transmission failed.
*
* @param station the station the PSDU is addressed to
* @param psdu the given PSDU
* @return the MPDUs in the PSDU to drop
*/
virtual std::list<Ptr<WifiMpdu>> DoGetMpdusToDropOnTxFailure(WifiRemoteStation* station,
Ptr<WifiPsdu> psdu);
/**
* @param station the station that we need to communicate
* @param size the size of the frame to send in bytes