wifi: MU scheduler keeps per-link TX information
This commit is contained in:
@@ -143,27 +143,28 @@ HeFrameExchangeManager::StartFrameExchange(Ptr<QosTxop> edca, Time availableTime
|
||||
|
||||
if (txFormat == MultiUserScheduler::DL_MU_TX)
|
||||
{
|
||||
if (m_muScheduler->GetDlMuInfo().psduMap.empty())
|
||||
if (m_muScheduler->GetDlMuInfo(m_linkId).psduMap.empty())
|
||||
{
|
||||
NS_LOG_DEBUG(
|
||||
"The Multi-user Scheduler returned DL_MU_TX with empty psduMap, do not transmit");
|
||||
return false;
|
||||
}
|
||||
|
||||
SendPsduMapWithProtection(m_muScheduler->GetDlMuInfo().psduMap,
|
||||
m_muScheduler->GetDlMuInfo().txParams);
|
||||
SendPsduMapWithProtection(m_muScheduler->GetDlMuInfo(m_linkId).psduMap,
|
||||
m_muScheduler->GetDlMuInfo(m_linkId).txParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (txFormat == MultiUserScheduler::UL_MU_TX)
|
||||
{
|
||||
auto packet = Create<Packet>();
|
||||
packet->AddHeader(m_muScheduler->GetUlMuInfo().trigger);
|
||||
auto trigger = Create<WifiMpdu>(packet, m_muScheduler->GetUlMuInfo().macHdr);
|
||||
packet->AddHeader(m_muScheduler->GetUlMuInfo(m_linkId).trigger);
|
||||
auto trigger = Create<WifiMpdu>(packet, m_muScheduler->GetUlMuInfo(m_linkId).macHdr);
|
||||
SendPsduMapWithProtection(
|
||||
WifiPsduMap{{SU_STA_ID,
|
||||
GetWifiPsdu(trigger, m_muScheduler->GetUlMuInfo().txParams.m_txVector)}},
|
||||
m_muScheduler->GetUlMuInfo().txParams);
|
||||
WifiPsduMap{
|
||||
{SU_STA_ID,
|
||||
GetWifiPsdu(trigger, m_muScheduler->GetUlMuInfo(m_linkId).txParams.m_txVector)}},
|
||||
m_muScheduler->GetUlMuInfo(m_linkId).txParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -494,14 +495,14 @@ HeFrameExchangeManager::SendPsduMap()
|
||||
// Trigger Frame, so that its Duration/ID is correctly computed
|
||||
NS_ASSERT(m_muScheduler);
|
||||
Time tbPpduDuration = HePhy::ConvertLSigLengthToHeTbPpduDuration(
|
||||
m_muScheduler->GetUlMuInfo().trigger.GetUlLength(),
|
||||
m_muScheduler->GetUlMuInfo(m_linkId).trigger.GetUlLength(),
|
||||
acknowledgment->tbPpduTxVector,
|
||||
m_phy->GetPhyBand());
|
||||
acknowledgment->acknowledgmentTime += m_phy->GetSifs() + tbPpduDuration;
|
||||
|
||||
timerType = WifiTxTimer::WAIT_TB_PPDU_AFTER_BASIC_TF;
|
||||
responseTxVector = &acknowledgment->tbPpduTxVector;
|
||||
m_trigVector = GetTrigVector(m_muScheduler->GetUlMuInfo().trigger);
|
||||
m_trigVector = GetTrigVector(m_muScheduler->GetUlMuInfo(m_linkId).trigger);
|
||||
}
|
||||
/*
|
||||
* BSRP Trigger Frame
|
||||
@@ -511,7 +512,7 @@ HeFrameExchangeManager::SendPsduMap()
|
||||
m_psduMap.begin()->first == SU_STA_ID &&
|
||||
(*m_psduMap.begin()->second->begin())->GetHeader().IsTrigger())
|
||||
{
|
||||
CtrlTriggerHeader& trigger = m_muScheduler->GetUlMuInfo().trigger;
|
||||
CtrlTriggerHeader& trigger = m_muScheduler->GetUlMuInfo(m_linkId).trigger;
|
||||
NS_ASSERT(trigger.IsBsrp());
|
||||
NS_ASSERT(m_apMac);
|
||||
|
||||
@@ -536,7 +537,7 @@ HeFrameExchangeManager::SendPsduMap()
|
||||
|
||||
timerType = WifiTxTimer::WAIT_QOS_NULL_AFTER_BSRP_TF;
|
||||
responseTxVector = &txVector;
|
||||
m_trigVector = GetTrigVector(m_muScheduler->GetUlMuInfo().trigger);
|
||||
m_trigVector = GetTrigVector(m_muScheduler->GetUlMuInfo(m_linkId).trigger);
|
||||
}
|
||||
/*
|
||||
* TB PPDU solicited by a Basic Trigger Frame
|
||||
|
||||
@@ -93,9 +93,7 @@ MultiUserScheduler::DoDispose()
|
||||
NS_LOG_FUNCTION(this);
|
||||
m_apMac = nullptr;
|
||||
m_edca = nullptr;
|
||||
m_dlInfo.psduMap.clear();
|
||||
m_dlInfo.txParams.Clear();
|
||||
m_ulInfo.txParams.Clear();
|
||||
m_lastTxInfo.clear();
|
||||
m_accessReqTimer.Cancel();
|
||||
Object::DoDispose();
|
||||
}
|
||||
@@ -228,35 +226,36 @@ MultiUserScheduler::NotifyAccessGranted(Ptr<QosTxop> edca,
|
||||
|
||||
if (txFormat == DL_MU_TX)
|
||||
{
|
||||
m_dlInfo = ComputeDlMuInfo();
|
||||
m_lastTxInfo[linkId].dlInfo = ComputeDlMuInfo();
|
||||
}
|
||||
else if (txFormat == UL_MU_TX)
|
||||
{
|
||||
m_ulInfo = ComputeUlMuInfo();
|
||||
m_lastTxInfo[linkId].ulInfo = ComputeUlMuInfo();
|
||||
CheckTriggerFrame();
|
||||
}
|
||||
|
||||
if (txFormat != NO_TX)
|
||||
{
|
||||
m_lastTxFormat = txFormat;
|
||||
m_lastTxInfo[linkId].lastTxFormat = txFormat;
|
||||
}
|
||||
return txFormat;
|
||||
}
|
||||
|
||||
MultiUserScheduler::TxFormat
|
||||
MultiUserScheduler::GetLastTxFormat() const
|
||||
MultiUserScheduler::GetLastTxFormat(uint8_t linkId)
|
||||
{
|
||||
return m_lastTxFormat;
|
||||
return m_lastTxInfo[linkId].lastTxFormat;
|
||||
}
|
||||
|
||||
MultiUserScheduler::DlMuInfo&
|
||||
MultiUserScheduler::GetDlMuInfo()
|
||||
MultiUserScheduler::GetDlMuInfo(uint8_t linkId)
|
||||
{
|
||||
NS_ABORT_MSG_IF(m_lastTxFormat != DL_MU_TX, "Next transmission is not DL MU");
|
||||
NS_ABORT_MSG_IF(m_lastTxInfo[linkId].lastTxFormat != DL_MU_TX,
|
||||
"Next transmission is not DL MU");
|
||||
|
||||
#ifdef NS3_BUILD_PROFILE_DEBUG
|
||||
// check that all the addressed stations support HE
|
||||
for (auto& psdu : m_dlInfo.psduMap)
|
||||
for (auto& psdu : m_lastTxInfo[linkId].dlInfo.psduMap)
|
||||
{
|
||||
auto receiver = psdu.second->GetAddr1();
|
||||
auto linkId = m_apMac->IsAssociated(receiver);
|
||||
@@ -266,15 +265,16 @@ MultiUserScheduler::GetDlMuInfo()
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_dlInfo;
|
||||
return m_lastTxInfo[linkId].dlInfo;
|
||||
}
|
||||
|
||||
MultiUserScheduler::UlMuInfo&
|
||||
MultiUserScheduler::GetUlMuInfo()
|
||||
MultiUserScheduler::GetUlMuInfo(uint8_t linkId)
|
||||
{
|
||||
NS_ABORT_MSG_IF(m_lastTxFormat != UL_MU_TX, "Next transmission is not UL MU");
|
||||
NS_ABORT_MSG_IF(m_lastTxInfo[linkId].lastTxFormat != UL_MU_TX,
|
||||
"Next transmission is not UL MU");
|
||||
|
||||
return m_ulInfo;
|
||||
return m_lastTxInfo[linkId].ulInfo;
|
||||
}
|
||||
|
||||
Ptr<WifiMpdu>
|
||||
@@ -310,9 +310,10 @@ MultiUserScheduler::CheckTriggerFrame()
|
||||
|
||||
// Set the CS Required subfield to true, unless the UL Length subfield is less
|
||||
// than or equal to 76 (see Section 26.5.2.5 of 802.11ax-2021)
|
||||
m_ulInfo.trigger.SetCsRequired(m_ulInfo.trigger.GetUlLength() > 76);
|
||||
m_lastTxInfo[m_linkId].ulInfo.trigger.SetCsRequired(
|
||||
m_lastTxInfo[m_linkId].ulInfo.trigger.GetUlLength() > 76);
|
||||
|
||||
GetHeFem(m_linkId)->SetTargetRssi(m_ulInfo.trigger);
|
||||
GetHeFem(m_linkId)->SetTargetRssi(m_lastTxInfo[m_linkId].ulInfo.trigger);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
@@ -104,20 +104,22 @@ class MultiUserScheduler : public Object
|
||||
uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Get the information required to perform a DL MU transmission. Note
|
||||
* that this method can only be called if GetTxFormat returns DL_MU_TX.
|
||||
* Get the information required to perform a DL MU transmission on the given link. Note
|
||||
* that this method can only be called if GetTxFormat returns DL_MU_TX on the given link.
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \return the information required to perform a DL MU transmission
|
||||
*/
|
||||
DlMuInfo& GetDlMuInfo();
|
||||
DlMuInfo& GetDlMuInfo(uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Get the information required to solicit an UL MU transmission. Note
|
||||
* that this method can only be called if GetTxFormat returns UL_MU_TX.
|
||||
* Get the information required to solicit an UL MU transmission on the given link. Note
|
||||
* that this method can only be called if GetTxFormat returns UL_MU_TX on the given link.
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \return the information required to solicit an UL MU transmission
|
||||
*/
|
||||
UlMuInfo& GetUlMuInfo();
|
||||
UlMuInfo& GetUlMuInfo(uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Set the duration of the interval between two consecutive requests for channel
|
||||
@@ -155,12 +157,13 @@ class MultiUserScheduler : public Object
|
||||
Ptr<WifiMpdu> GetTriggerFrame(const CtrlTriggerHeader& trigger, uint8_t linkId) const;
|
||||
|
||||
/**
|
||||
* Get the format of the last transmission, as determined by the last call
|
||||
* to NotifyAccessGranted that did not return NO_TX.
|
||||
* Get the format of the last transmission on the given link, as determined by
|
||||
* the last call to NotifyAccessGranted that did not return NO_TX.
|
||||
*
|
||||
* \return the format of the last transmission
|
||||
* \param linkId the ID of the given link
|
||||
* \return the format of the last transmission on the given link
|
||||
*/
|
||||
TxFormat GetLastTxFormat() const;
|
||||
TxFormat GetLastTxFormat(uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Get the maximum size in bytes among the A-MPDUs containing QoS Null frames
|
||||
@@ -229,14 +232,22 @@ class MultiUserScheduler : public Object
|
||||
*/
|
||||
void CheckTriggerFrame();
|
||||
|
||||
TxFormat m_lastTxFormat{NO_TX}; ///< the format of last transmission
|
||||
DlMuInfo m_dlInfo; ///< information required to perform a DL MU transmission
|
||||
UlMuInfo m_ulInfo; ///< information required to solicit an UL MU transmission
|
||||
EventId m_accessReqTimer; ///< the timer controlling additional channel access requests
|
||||
Time m_accessReqInterval; ///< duration of the interval between channel access requests
|
||||
AcIndex m_accessReqAc; ///< AC we request channel access for
|
||||
bool m_restartTimerUponAccess; ///< whether the channel access timer has to be restarted
|
||||
///< upon channel access
|
||||
/**
|
||||
* Type for the information about the last transmission
|
||||
*/
|
||||
struct LastTxInfo
|
||||
{
|
||||
TxFormat lastTxFormat{NO_TX}; ///< the format of last transmission
|
||||
DlMuInfo dlInfo; ///< information required to perform a DL MU transmission
|
||||
UlMuInfo ulInfo; ///< information required to solicit an UL MU transmission
|
||||
};
|
||||
|
||||
std::map<uint8_t, LastTxInfo> m_lastTxInfo; ///< Information about the last transmission
|
||||
EventId m_accessReqTimer; ///< the timer controlling additional channel access requests
|
||||
Time m_accessReqInterval; ///< duration of the interval between channel access requests
|
||||
AcIndex m_accessReqAc; ///< AC we request channel access for
|
||||
bool m_restartTimerUponAccess; ///< whether the channel access timer has to be restarted
|
||||
///< upon channel access
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -155,7 +155,7 @@ RrMultiUserScheduler::SelectTxFormat()
|
||||
return SU_TX;
|
||||
}
|
||||
|
||||
if (m_enableUlOfdma && m_enableBsrp && (GetLastTxFormat() == DL_MU_TX || !mpdu))
|
||||
if (m_enableUlOfdma && m_enableBsrp && (GetLastTxFormat(m_linkId) == DL_MU_TX || !mpdu))
|
||||
{
|
||||
TxFormat txFormat = TrySendingBsrpTf();
|
||||
|
||||
@@ -164,7 +164,7 @@ RrMultiUserScheduler::SelectTxFormat()
|
||||
return txFormat;
|
||||
}
|
||||
}
|
||||
else if (m_enableUlOfdma && ((GetLastTxFormat() == DL_MU_TX) ||
|
||||
else if (m_enableUlOfdma && ((GetLastTxFormat(m_linkId) == DL_MU_TX) ||
|
||||
(m_trigger.GetType() == TriggerFrameType::BSRP_TRIGGER) || !mpdu))
|
||||
{
|
||||
TxFormat txFormat = TrySendingBasicTf();
|
||||
|
||||
Reference in New Issue
Block a user