wifi: Define ack methods for UL OFDMA transmissions

This commit is contained in:
Stefano Avallone
2021-01-09 16:26:22 +01:00
parent e164766c9b
commit f929fa6b38
4 changed files with 235 additions and 1 deletions

View File

@@ -329,6 +329,75 @@ WifiDlMuAggregateTf::Print (std::ostream &os) const
}
/*
* WifiUlMuMultiStaBa
*/
WifiUlMuMultiStaBa::WifiUlMuMultiStaBa ()
: WifiAcknowledgment (UL_MU_MULTI_STA_BA)
{
}
std::unique_ptr<WifiAcknowledgment>
WifiUlMuMultiStaBa::Copy (void) const
{
return std::unique_ptr<WifiAcknowledgment> (new WifiUlMuMultiStaBa (*this));
}
bool
WifiUlMuMultiStaBa::CheckQosAckPolicy (Mac48Address receiver, uint8_t tid,
WifiMacHeader::QosAckPolicy ackPolicy) const
{
// a Basic Trigger Frame has no QoS ack policy
return true;
}
void
WifiUlMuMultiStaBa::Print (std::ostream &os) const
{
os << "UL_MU_MULTI_STA_BA [";
for (const auto& sta : stationsReceivingMultiStaBa)
{
os << "(" << sta.first.first << "," << +sta.first.second << ") ";
}
os << "]";
}
/*
* WifiAckAfterTbPpdu
*/
WifiAckAfterTbPpdu::WifiAckAfterTbPpdu ()
: WifiAcknowledgment (ACK_AFTER_TB_PPDU)
{
}
std::unique_ptr<WifiAcknowledgment>
WifiAckAfterTbPpdu::Copy (void) const
{
return std::unique_ptr<WifiAcknowledgment> (new WifiAckAfterTbPpdu (*this));
}
bool
WifiAckAfterTbPpdu::CheckQosAckPolicy (Mac48Address receiver, uint8_t tid,
WifiMacHeader::QosAckPolicy ackPolicy) const
{
if (ackPolicy == WifiMacHeader::NORMAL_ACK)
{
return true;
}
return false;
}
void
WifiAckAfterTbPpdu::Print (std::ostream &os) const
{
os << "ACK_AFTER_TB_PPDU";
}
std::ostream & operator << (std::ostream &os, const WifiAcknowledgment* acknowledgment)
{
acknowledgment->Print (os);

View File

@@ -55,7 +55,9 @@ struct WifiAcknowledgment
BAR_BLOCK_ACK,
DL_MU_BAR_BA_SEQUENCE,
DL_MU_TF_MU_BAR,
DL_MU_AGGREGATE_TF
DL_MU_AGGREGATE_TF,
UL_MU_MULTI_STA_BA,
ACK_AFTER_TB_PPDU
};
/**
@@ -301,6 +303,49 @@ struct WifiDlMuAggregateTf : public WifiAcknowledgment
};
/**
* \ingroup wifi
*
* WifiUlMuMultiStaBa specifies that a Basic Trigger Frame is being sent to
* solicit TB PPDUs that will be acknowledged through a multi-STA BlockAck frame.
*/
struct WifiUlMuMultiStaBa : public WifiAcknowledgment
{
WifiUlMuMultiStaBa ();
// Overridden from WifiAcknowledgment
virtual std::unique_ptr<WifiAcknowledgment> Copy (void) const override;
bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override;
void Print (std::ostream &os) const override;
///< Map (originator, tid) pairs to the their index in baType
std::map<std::pair<Mac48Address, uint8_t>, std::size_t> stationsReceivingMultiStaBa;
BlockAckType baType; //!< BlockAck type
WifiTxVector tbPpduTxVector; //!< TXVECTOR for a TB PPDU
WifiTxVector multiStaBaTxVector; //!< TXVECTOR for the Multi-STA BlockAck
};
/**
* \ingroup wifi
*
* WifiAckAfterTbPpdu is used when a station prepares a TB PPDU to send in
* response to a Basic Trigger Frame. The acknowledgment time must be
* zero because the time taken by the actual acknowledgment is not included
* in the duration indicated by the Trigger Frame. The QoS ack policy instead
* must be Normal Ack/Implicit Block Ack Request.
*/
struct WifiAckAfterTbPpdu : public WifiAcknowledgment
{
WifiAckAfterTbPpdu ();
// Overridden from WifiAcknowledgment
virtual std::unique_ptr<WifiAcknowledgment> Copy (void) const override;
bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override;
void Print (std::ostream &os) const override;
};
/**
* \brief Stream insertion operator.
*

View File

@@ -28,6 +28,7 @@
#include "ap-wifi-mac.h"
#include "ctrl-headers.h"
#include "ns3/he-phy.h"
#include "ns3/he-frame-exchange-manager.h"
namespace ns3 {
@@ -188,6 +189,48 @@ WifiDefaultAckManager::TryAddMpdu (Ptr<const WifiMacQueueItem> mpdu,
const WifiMacHeader& hdr = mpdu->GetHeader ();
Mac48Address receiver = hdr.GetAddr1 ();
// Acknowledgment for TB PPDUs
if (txParams.m_txVector.IsUlMu ())
{
if (hdr.IsQosData () && !hdr.HasData ())
{
// QoS Null frame
WifiNoAck* acknowledgment = nullptr;
if (txParams.m_acknowledgment)
{
NS_ASSERT (txParams.m_acknowledgment->method == WifiAcknowledgment::NONE);
acknowledgment = static_cast<WifiNoAck*> (txParams.m_acknowledgment.get ());
acknowledgment = new WifiNoAck (*acknowledgment);
}
else
{
acknowledgment = new WifiNoAck;
}
acknowledgment->SetQosAckPolicy (receiver, hdr.GetQosTid (), WifiMacHeader::NO_ACK);
return std::unique_ptr<WifiAcknowledgment> (acknowledgment);
}
if (txParams.m_acknowledgment)
{
NS_ASSERT (txParams.m_acknowledgment->method == WifiAcknowledgment::ACK_AFTER_TB_PPDU);
return nullptr;
}
WifiAckAfterTbPpdu* acknowledgment = new WifiAckAfterTbPpdu;
if (hdr.IsQosData ())
{
acknowledgment->SetQosAckPolicy (receiver, hdr.GetQosTid (), WifiMacHeader::NORMAL_ACK);
}
return std::unique_ptr<WifiAcknowledgment> (acknowledgment);
}
// if this is a Trigger Frame, call a separate method
if (hdr.IsTrigger ())
{
return TryUlMuTransmission (mpdu, txParams);
}
// if the current protection method (if any) is already BLOCK_ACK or BAR_BLOCK_ACK,
// it will not change by adding an MPDU
if (txParams.m_acknowledgment
@@ -591,4 +634,70 @@ WifiDefaultAckManager::GetAckInfoIfAggregatedMuBar (Ptr<const WifiMacQueueItem>
return nullptr;
}
std::unique_ptr<WifiAcknowledgment>
WifiDefaultAckManager::TryUlMuTransmission (Ptr<const WifiMacQueueItem> mpdu,
const WifiTxParameters& txParams)
{
NS_LOG_FUNCTION (this << *mpdu << &txParams);
NS_ASSERT (mpdu->GetHeader ().IsTrigger ());
Ptr<ApWifiMac> apMac = DynamicCast<ApWifiMac> (m_mac);
NS_ABORT_MSG_IF (apMac == nullptr, "HE APs only can send Trigger Frames");
Ptr<HeFrameExchangeManager> heFem = DynamicCast<HeFrameExchangeManager> (m_mac->GetFrameExchangeManager ());
NS_ABORT_MSG_IF (heFem == nullptr, "HE APs only can send Trigger Frames");
CtrlTriggerHeader trigger;
mpdu->GetPacket ()->PeekHeader (trigger);
if (trigger.IsBasic ())
{
// the only supported ack method for now is through a multi-STA BlockAck frame
WifiUlMuMultiStaBa* acknowledgment = new WifiUlMuMultiStaBa;
acknowledgment->baType.m_variant = BlockAckType::MULTI_STA;
for (const auto& userInfo : trigger)
{
uint16_t aid12 = userInfo.GetAid12 ();
if (aid12 == 2046)
{
NS_LOG_INFO ("Unallocated RU");
continue;
}
NS_ABORT_MSG_IF (aid12 == 0 || aid12 > 2007, "Allocation of RA-RUs is not supported");
NS_ASSERT (apMac->GetStaList ().find (aid12) != apMac->GetStaList ().end ());
Mac48Address staAddress = apMac->GetStaList ().find (aid12)->second;
// find a TID for which a BA agreement exists with the given originator
uint8_t tid = 0;
while (tid < 8 && !heFem->GetBaAgreementEstablished (staAddress, tid))
{
tid++;
}
NS_ASSERT_MSG (tid < 8, "No Block Ack agreement established with originator " << staAddress);
std::size_t index = acknowledgment->baType.m_bitmapLen.size ();
acknowledgment->stationsReceivingMultiStaBa.emplace (std::make_pair (staAddress, tid), index);
// we assume the Block Acknowledgment context is used for the multi-STA BlockAck frame
// (since it requires the longest TX time due to the presence of a bitmap)
acknowledgment->baType.m_bitmapLen.push_back (heFem->GetBlockAckType (staAddress, tid).m_bitmapLen.at (0));
}
uint16_t staId = trigger.begin ()->GetAid12 ();
acknowledgment->tbPpduTxVector = trigger.GetHeTbTxVector (staId);
acknowledgment->multiStaBaTxVector = m_mac->GetWifiRemoteStationManager ()->GetBlockAckTxVector (apMac->GetStaList ().find (staId)->second,
acknowledgment->tbPpduTxVector);
return std::unique_ptr<WifiUlMuMultiStaBa> (acknowledgment);
}
else if (trigger.IsBsrp ())
{
return std::unique_ptr<WifiAcknowledgment> (new WifiNoAck);
}
return nullptr;
}
} //namespace ns3

View File

@@ -128,6 +128,17 @@ private:
virtual std::unique_ptr<WifiAcknowledgment> GetAckInfoIfAggregatedMuBar (Ptr<const WifiMacQueueItem> mpdu,
const WifiTxParameters& txParams);
/**
* Calculate the acknowledgment method for the TB PPDUs solicited by the given
* Trigger Frame.
*
* \param mpdu the given Trigger Frame
* \param txParams the current TX parameters (just the TXVECTOR needs to be set)
* \return the acknowledgment method for the TB PPDUs solicited by the given Trigger Frame
*/
virtual std::unique_ptr<WifiAcknowledgment> TryUlMuTransmission (Ptr<const WifiMacQueueItem> mpdu,
const WifiTxParameters& txParams);
bool m_useExplicitBar; //!< true for sending BARs, false for using Implicit BAR policy
double m_baThreshold; //!< Threshold to determine when a BlockAck must be requested
WifiAcknowledgment::Method m_dlMuAckType; //!< Type of the ack sequence for DL MU PPDUs