wifi: Allow MPDU aggregation for groupcast frames
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user