wifi: Add functions to update frame retry count and drop MPDUs
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user