wifi: Allow MPDU aggregation for groupcast frames

This commit is contained in:
Sébastien Deronne
2023-07-25 22:41:08 +02:00
parent 0547e943ac
commit 0e70a85da6
3 changed files with 62 additions and 22 deletions

View File

@@ -229,8 +229,16 @@ MpduAggregator::GetNextAmpdu(Ptr<WifiMpdu> mpdu,
auto qosTxop = m_mac->GetQosTxop(tid);
NS_ASSERT(qosTxop);
const auto isGcr = IsGcr(m_mac, header);
const auto bufferSize = qosTxop->GetBaBufferSize(origRecipient, tid, isGcr);
const auto startSeq = qosTxop->GetBaStartingSequence(origRecipient, tid, isGcr);
// Have to make sure that the block ack agreement is established and A-MPDU is enabled
if (m_mac->GetBaAgreementEstablishedAsOriginator(recipient, tid) &&
auto apMac = DynamicCast<ApWifiMac>(m_mac);
const auto agreementEstablished =
isGcr ? apMac->IsGcrBaAgreementEstablishedWithAllMembers(header.GetAddr1(), tid)
: m_mac->GetBaAgreementEstablishedAsOriginator(recipient, tid).has_value();
if (agreementEstablished &&
GetMaxAmpduSize(recipient, tid, txParams.m_txVector.GetModulationClass()) > 0)
{
/* here is performed MPDU aggregation */
@@ -238,6 +246,23 @@ MpduAggregator::GetNextAmpdu(Ptr<WifiMpdu> mpdu,
while (nextMpdu)
{
const auto isGcrUr = isGcr && (apMac->GetGcrManager()->GetRetransmissionPolicy() ==
GroupAddressRetransmissionPolicy::GCR_UNSOLICITED_RETRY);
if (isGcrUr && header.IsRetry() && !nextMpdu->GetHeader().IsRetry())
{
// if this is a retransmitted A-MPDU transmitted via GCR-UR, do not add new MPDU
break;
}
if (isGcr &&
apMac->GetGcrManager()->GetRetransmissionPolicyFor(header) !=
apMac->GetGcrManager()->GetRetransmissionPolicyFor(nextMpdu->GetHeader()))
{
// if an MPDU has been previously transmitted using No-Ack/No-Retry,
// do not add a new MPDU that still needs to be transmitted using No-Ack/No-Retry,
// unless No-Ack/No-Retry is the only selected retransmission policy
break;
}
// if we are here, nextMpdu can be aggregated to the A-MPDU.
NS_LOG_DEBUG("Adding packet with sequence number "
<< nextMpdu->GetHeader().GetSequenceNumber()
@@ -254,9 +279,8 @@ MpduAggregator::GetNextAmpdu(Ptr<WifiMpdu> mpdu,
if (peekedMpdu)
{
// PeekNextMpdu() does not return an MPDU that is beyond the transmit window
NS_ASSERT(IsInWindow(peekedMpdu->GetHeader().GetSequenceNumber(),
qosTxop->GetBaStartingSequence(origRecipient, tid),
qosTxop->GetBaBufferSize(origRecipient, tid)));
NS_ASSERT(
IsInWindow(peekedMpdu->GetHeader().GetSequenceNumber(), startSeq, bufferSize));
peekedMpdu = m_htFem->CreateAliasIfNeeded(peekedMpdu);
// get the next MPDU to aggregate, provided that the constraints on size

View File

@@ -11,6 +11,7 @@
#include "qos-txop.h"
#include "ap-wifi-mac.h"
#include "channel-access-manager.h"
#include "ctrl-headers.h"
#include "mac-tx-middle.h"
@@ -436,13 +437,25 @@ QosTxop::PeekNextMpdu(uint8_t linkId, uint8_t tid, Mac48Address recipient, Ptr<c
break;
}
// if no BA agreement, we cannot have multiple MPDUs in-flight
if (item->GetHeader().IsQosData() &&
!m_mac->GetBaAgreementEstablishedAsOriginator(item->GetHeader().GetAddr1(),
item->GetHeader().GetQosTid()))
if (item->GetHeader().IsQosData())
{
NS_LOG_DEBUG("No BA agreement and an MPDU is already in-flight");
return nullptr;
auto apMac = DynamicCast<ApWifiMac>(m_mac);
const auto isGcr = IsGcr(m_mac, item->GetHeader());
const auto agreementEstablished =
isGcr
? apMac->IsGcrBaAgreementEstablishedWithAllMembers(
item->GetHeader().GetAddr1(),
item->GetHeader().GetQosTid())
: m_mac
->GetBaAgreementEstablishedAsOriginator(item->GetHeader().GetAddr1(),
item->GetHeader().GetQosTid())
.has_value();
// if no BA agreement, we cannot have multiple MPDUs in-flight
if (!agreementEstablished)
{
NS_LOG_DEBUG("No BA agreement and an MPDU is already in-flight");
return nullptr;
}
}
NS_LOG_DEBUG("Skipping in flight MPDU: " << *item);
@@ -467,21 +480,24 @@ QosTxop::PeekNextMpdu(uint8_t linkId, uint8_t tid, Mac48Address recipient, Ptr<c
return nullptr;
}
WifiMacHeader& hdr = item->GetHeader();
auto& hdr = item->GetHeader();
// peek the next sequence number and check if it is within the transmit window
// in case of QoS data frame
uint16_t sequence = item->HasSeqNoAssigned() ? hdr.GetSequenceNumber()
: m_txMiddle->PeekNextSequenceNumberFor(&hdr);
const auto sequence = item->HasSeqNoAssigned() ? hdr.GetSequenceNumber()
: m_txMiddle->PeekNextSequenceNumberFor(&hdr);
if (hdr.IsQosData())
{
Mac48Address recipient = hdr.GetAddr1();
uint8_t tid = hdr.GetQosTid();
if (m_mac->GetBaAgreementEstablishedAsOriginator(recipient, tid) &&
!IsInWindow(sequence,
GetBaStartingSequence(recipient, tid),
GetBaBufferSize(recipient, tid)))
const auto recipient = hdr.GetAddr1();
const auto tid = hdr.GetQosTid();
const auto isGcr = IsGcr(m_mac, hdr);
const auto bufferSize = GetBaBufferSize(recipient, tid, isGcr);
const auto startSeq = GetBaStartingSequence(recipient, tid, isGcr);
auto apMac = DynamicCast<ApWifiMac>(m_mac);
const auto agreementEstablished =
isGcr ? apMac->IsGcrBaAgreementEstablishedWithAllMembers(recipient, tid)
: m_mac->GetBaAgreementEstablishedAsOriginator(recipient, tid).has_value();
if (agreementEstablished && !IsInWindow(sequence, startSeq, bufferSize))
{
NS_LOG_DEBUG("Packet beyond the end of the current transmit window");
return nullptr;

View File

@@ -292,8 +292,8 @@ WifiDefaultAckManager::TryAddMpdu(Ptr<const WifiMpdu> mpdu, const WifiTxParamete
if (receiver.IsGroup())
{
NS_ABORT_MSG_IF(!txParams.LastAddedIsFirstMpdu(receiver),
"Unicast frames only can be aggregated");
NS_ABORT_MSG_IF(!IsGcr(m_mac, hdr) && !txParams.LastAddedIsFirstMpdu(receiver),
"Unicast frames only can be aggregated if GCR is not used");
auto acknowledgment = std::make_unique<WifiNoAck>();
if (hdr.IsQosData())
{