From a9f4de2979a64c8f3b1172b42957cc164b7cbaf9 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 14 Sep 2022 14:07:04 +0200 Subject: [PATCH] wifi: FEMs create and handle MPDU aliases --- src/wifi/model/ap-wifi-mac.cc | 3 ++- src/wifi/model/frame-exchange-manager.cc | 4 ++++ src/wifi/model/he/he-frame-exchange-manager.cc | 3 ++- src/wifi/model/ht/ht-frame-exchange-manager.cc | 2 +- src/wifi/model/mac-rx-middle.cc | 3 ++- src/wifi/model/qos-frame-exchange-manager.cc | 7 +++++++ src/wifi/model/qos-frame-exchange-manager.h | 10 ++++++++++ src/wifi/model/qos-txop.cc | 10 +++++++++- src/wifi/model/sta-wifi-mac.cc | 3 ++- 9 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index 03c360fc4..a17e9498d 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -1406,7 +1406,8 @@ void ApWifiMac::Receive(Ptr mpdu, uint8_t linkId) { NS_LOG_FUNCTION(this << *mpdu << +linkId); - const WifiMacHeader* hdr = &mpdu->GetHeader(); + // consider the MAC header of the original MPDU (makes a difference for data frames only) + const WifiMacHeader* hdr = &mpdu->GetOriginal()->GetHeader(); Ptr packet = mpdu->GetPacket(); Mac48Address from = hdr->GetAddr2(); if (hdr->IsData()) diff --git a/src/wifi/model/frame-exchange-manager.cc b/src/wifi/model/frame-exchange-manager.cc index 6ec02e54b..42a9c540e 100644 --- a/src/wifi/model/frame-exchange-manager.cc +++ b/src/wifi/model/frame-exchange-manager.cc @@ -877,6 +877,10 @@ FrameExchangeManager::NormalAckTimeout(Ptr mpdu, const WifiTxVector& t else { NS_LOG_DEBUG("Missed Ack, retransmit MPDU"); + if (mpdu->IsQueued()) // the MPDU may have been removed due to lifetime expiration + { + mpdu = m_mac->GetTxopQueue(mpdu->GetQueueAc())->GetOriginal(mpdu); + } mpdu->GetHeader().SetRetry(); RetransmitMpduAfterMissedAck(mpdu); m_dcf->UpdateFailedCw(m_linkId); diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index b0cdcc215..8220985ec 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -29,6 +29,7 @@ #include "ns3/recipient-block-ack-agreement.h" #include "ns3/snr-tag.h" #include "ns3/sta-wifi-mac.h" +#include "ns3/wifi-mac-queue.h" #include #include @@ -1102,7 +1103,7 @@ HeFrameExchangeManager::NormalAckTimeout(Ptr mpdu, const WifiTxVector& { if (mpdu->IsQueued()) { - mpdu->GetHeader().SetRetry(); + m_mac->GetTxopQueue(mpdu->GetQueueAc())->GetOriginal(mpdu)->GetHeader().SetRetry(); } } } diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index 952cb749d..3fcdfffa6 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -421,7 +421,7 @@ HtFrameExchangeManager::StartFrameExchange(Ptr edca, Time availableTime // Use SendDataFrame if we can try aggregation if (hdr.IsQosData() && !hdr.GetAddr1().IsGroup() && !peekedItem->IsFragment() && - !GetWifiRemoteStationManager()->NeedFragmentation(peekedItem)) + !GetWifiRemoteStationManager()->NeedFragmentation(peekedItem = CreateAlias(peekedItem))) { return SendDataFrame(peekedItem, availableTime, initialFrame); } diff --git a/src/wifi/model/mac-rx-middle.cc b/src/wifi/model/mac-rx-middle.cc index 18f065907..6766c54bf 100644 --- a/src/wifi/model/mac-rx-middle.cc +++ b/src/wifi/model/mac-rx-middle.cc @@ -301,7 +301,8 @@ void MacRxMiddle::Receive(Ptr mpdu, uint8_t linkId) { NS_LOG_FUNCTION(*mpdu << +linkId); - const WifiMacHeader* hdr = &mpdu->GetHeader(); + // consider the MAC header of the original MPDU (makes a difference for data frames only) + const WifiMacHeader* hdr = &mpdu->GetOriginal()->GetHeader(); NS_ASSERT(hdr->IsData() || hdr->IsMgt()); OriginatorRxStatus* originator = Lookup(hdr); diff --git a/src/wifi/model/qos-frame-exchange-manager.cc b/src/wifi/model/qos-frame-exchange-manager.cc index f11619985..e80287dc8 100644 --- a/src/wifi/model/qos-frame-exchange-manager.cc +++ b/src/wifi/model/qos-frame-exchange-manager.cc @@ -280,6 +280,7 @@ QosFrameExchangeManager::StartFrameExchange(Ptr edca, return false; } + mpdu = CreateAlias(mpdu); WifiTxParameters txParams; txParams.m_txVector = GetWifiRemoteStationManager()->GetDataTxVector(mpdu->GetHeader(), m_allowedWidth); @@ -312,6 +313,12 @@ QosFrameExchangeManager::StartFrameExchange(Ptr edca, return true; } +Ptr +QosFrameExchangeManager::CreateAlias(Ptr mpdu) const +{ + return mpdu; +} + bool QosFrameExchangeManager::TryAddMpdu(Ptr mpdu, WifiTxParameters& txParams, diff --git a/src/wifi/model/qos-frame-exchange-manager.h b/src/wifi/model/qos-frame-exchange-manager.h index d3ab0cc85..c6056d1e6 100644 --- a/src/wifi/model/qos-frame-exchange-manager.h +++ b/src/wifi/model/qos-frame-exchange-manager.h @@ -92,6 +92,16 @@ class QosFrameExchangeManager : public FrameExchangeManager const WifiTxParameters& txParams, Time ppduDurationLimit) const; + /** + * Create an alias of the given MPDU for transmission by this Frame Exchange Manager. + * This is required by 11be MLDs to support translation of MAC addresses. For single + * link devices, the given MPDU is simply returned. + * + * \param mpdu the given MPDU + * \return the alias of the given MPDU for transmission on this link + */ + virtual Ptr CreateAlias(Ptr mpdu) const; + protected: void DoDispose() override; diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index ce387d563..996d07592 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -526,8 +526,16 @@ QosTxop::AssignSequenceNumber(Ptr mpdu) const if (!mpdu->IsFragment() && !mpdu->GetHeader().IsRetry() && !mpdu->IsInFlight()) { - uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor(&mpdu->GetHeader()); + // in case of 11be MLDs, sequence numbers refer to the MLD address + auto origMpdu = m_queue->GetOriginal(mpdu); + uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor(&origMpdu->GetHeader()); mpdu->GetHeader().SetSequenceNumber(sequence); + // if this is not the original copy of the MPDU, assign the sequence number to + // the original copy as well + if (!mpdu->IsOriginal()) + { + origMpdu->GetHeader().SetSequenceNumber(sequence); + } } } diff --git a/src/wifi/model/sta-wifi-mac.cc b/src/wifi/model/sta-wifi-mac.cc index 526a6b07c..3c6452340 100644 --- a/src/wifi/model/sta-wifi-mac.cc +++ b/src/wifi/model/sta-wifi-mac.cc @@ -795,7 +795,8 @@ void StaWifiMac::Receive(Ptr mpdu, uint8_t linkId) { NS_LOG_FUNCTION(this << *mpdu << +linkId); - const WifiMacHeader* hdr = &mpdu->GetHeader(); + // consider the MAC header of the original MPDU (makes a difference for data frames only) + const WifiMacHeader* hdr = &mpdu->GetOriginal()->GetHeader(); Ptr packet = mpdu->GetPacket(); NS_ASSERT(!hdr->IsCtl()); Mac48Address myAddr =