wifi: MU scheduler keeps per-link TX information

This commit is contained in:
Stefano Avallone
2023-01-28 17:27:44 +01:00
parent 3473263bf3
commit 8eb215dc4e
4 changed files with 62 additions and 49 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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();