Skip to content

Commit

Permalink
wifi: Let EmlsrManager explicitly indicate whether UL TXOP can be sta…
Browse files Browse the repository at this point in the history
…rted

...instead of relying on whether the delay to request channel access is
zero
  • Loading branch information
Stefano Avallone committed Sep 23, 2024
1 parent bf1524f commit a46abc4
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 50 deletions.
18 changes: 9 additions & 9 deletions src/wifi/model/eht/advanced-emlsr-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ AdvancedEmlsrManager::DoSetWifiMac(Ptr<StaWifiMac> mac)
}
}

Time
std::pair<bool, Time>
AdvancedEmlsrManager::DoGetDelayUntilAccessRequest(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
Expand All @@ -131,7 +131,7 @@ AdvancedEmlsrManager::DoGetDelayUntilAccessRequest(uint8_t linkId)
hdr.IsTrigger() &&
(hdr.GetAddr1().IsBroadcast() || hdr.GetAddr1() == GetEhtFem(id)->GetAddress()))
{
return phy->GetDelayUntilIdle();
return {false, phy->GetDelayUntilIdle()};
}
continue;
}
Expand All @@ -143,7 +143,7 @@ AdvancedEmlsrManager::DoGetDelayUntilAccessRequest(uint8_t linkId)
if (!m_allowUlTxopInRx)
{
// retry channel access after the end of the current PHY header field
return phy->GetDelayUntilIdle();
return {false, phy->GetDelayUntilIdle()};
}
continue;
}
Expand All @@ -157,7 +157,7 @@ AdvancedEmlsrManager::DoGetDelayUntilAccessRequest(uint8_t linkId)
if (!m_useNotifiedMacHdr)
{
// restart channel access at the end of PSDU reception
return phy->GetDelayUntilIdle();
return {false, phy->GetDelayUntilIdle()};
}

// retry channel access after the expected end of the MAC header reception
Expand Down Expand Up @@ -192,14 +192,14 @@ AdvancedEmlsrManager::DoGetDelayUntilAccessRequest(uint8_t linkId)
.CalculateBytesTxTime(macHdrSize);
const auto timeSinceRxStart =
Simulator::Now() - phy->GetState()->GetLastTime({WifiPhyState::CCA_BUSY});
return Max(macHdrDuration - timeSinceRxStart, Time{0});
return {false, Max(macHdrDuration - timeSinceRxStart, Time{0})};
}
continue;
}
}
}

return Time{0};
return {true, Time{0}};
}

void
Expand Down Expand Up @@ -290,7 +290,7 @@ AdvancedEmlsrManager::DoNotifyTxopEnd(uint8_t linkId)
}
}

Time
std::pair<bool, Time>
AdvancedEmlsrManager::GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
Expand All @@ -316,7 +316,7 @@ AdvancedEmlsrManager::GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId)
NS_LOG_DEBUG("Not enough time for main PHY to switch link (main PHY state: "
<< mainPhy->GetState()->GetState() << ")");
// retry channel access when the CTS was expected to be received
return timeToCtsEnd;
return {false, timeToCtsEnd};
}

// TXOP can be started, schedule main PHY switch. Main PHY shall terminate the channel switch
Expand All @@ -333,7 +333,7 @@ AdvancedEmlsrManager::GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId)
RESET_BACKOFF,
DONT_REQUEST_ACCESS);

return Time{0};
return {true, Time{0}};
}

void
Expand Down
4 changes: 2 additions & 2 deletions src/wifi/model/eht/advanced-emlsr-manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class AdvancedEmlsrManager : public DefaultEmlsrManager
protected:
void DoDispose() override;
void DoSetWifiMac(Ptr<StaWifiMac> mac) override;
Time DoGetDelayUntilAccessRequest(uint8_t linkId) override;
Time GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) override;
std::pair<bool, Time> DoGetDelayUntilAccessRequest(uint8_t linkId) override;
std::pair<bool, Time> GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) override;
void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId, AcIndex aci) override;

/**
Expand Down
10 changes: 5 additions & 5 deletions src/wifi/model/eht/default-emlsr-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,11 @@ DefaultEmlsrManager::NotifyMainPhySwitch(std::optional<uint8_t> currLinkId,
}
}

Time
std::pair<bool, Time>
DefaultEmlsrManager::DoGetDelayUntilAccessRequest(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
return Time{0}; // start the TXOP
return {true, Time{0}}; // start the TXOP
}

void
Expand Down Expand Up @@ -271,7 +271,7 @@ DefaultEmlsrManager::GetTimeToCtsEnd(uint8_t linkId) const
return rtsTxTime + phy->GetSifs() + ctsTxTime + MicroSeconds(2 * MAX_PROPAGATION_DELAY_USEC);
}

Time
std::pair<bool, Time>
DefaultEmlsrManager::GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
Expand All @@ -296,7 +296,7 @@ DefaultEmlsrManager::GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId)
NS_LOG_DEBUG("Not enough time for main PHY to switch link (main PHY state: "
<< mainPhy->GetState()->GetState() << ")");
// retry channel access when the CTS was expected to be received
return timeToCtsEnd;
return {false, timeToCtsEnd};
}
break;
default:
Expand All @@ -317,7 +317,7 @@ DefaultEmlsrManager::GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId)
RESET_BACKOFF,
DONT_REQUEST_ACCESS);

return Time{0};
return {true, Time{0}};
}

} // namespace ns3
4 changes: 2 additions & 2 deletions src/wifi/model/eht/default-emlsr-manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ class DefaultEmlsrManager : public EmlsrManager
protected:
uint8_t GetLinkToSendEmlOmn() override;
std::optional<uint8_t> ResendNotification(Ptr<const WifiMpdu> mpdu) override;
Time DoGetDelayUntilAccessRequest(uint8_t linkId) override;
std::pair<bool, Time> DoGetDelayUntilAccessRequest(uint8_t linkId) override;
void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId, AcIndex aci) override;
Time GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) override;
std::pair<bool, Time> GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) override;

/**
* This function is intended to be called when an aux PHY is about to transmit an RTS on
Expand Down
32 changes: 14 additions & 18 deletions src/wifi/model/eht/eht-frame-exchange-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -276,28 +276,24 @@ EhtFrameExchangeManager::StartTransmission(Ptr<Txop> edca, MHz_u allowedWidth)
}

// let EMLSR manager decide whether to prevent or allow this UL TXOP
if (auto delay = emlsrManager->GetDelayUntilAccessRequest(
if (const auto [startTxop, delay] = emlsrManager->GetDelayUntilAccessRequest(
m_linkId,
DynamicCast<QosTxop>(edca)->GetAccessCategory());
delay.IsStrictlyPositive())
{
NotifyChannelReleased(edca);
Simulator::Schedule(delay,
&Txop::StartAccessAfterEvent,
edca,
m_linkId,
Txop::DIDNT_HAVE_FRAMES_TO_TRANSMIT, // queued frames cannot be
// transmitted until RX ends
Txop::CHECK_MEDIUM_BUSY); // generate backoff if medium busy
return false;
}
!startTxop)

// in case of aux PHY that is not TX capable, the main PHY can transmit if the medium is
// sensed idle for a PIFS after the end of channel switch (assuming main PHY is switching)
if (auto mainPhy = m_staMac->GetDevice()->GetPhy(emlsrManager->GetMainPhyId());
m_phy != mainPhy && !emlsrManager->GetAuxPhyTxCapable())
{
NS_LOG_DEBUG("Aux PHY is not capable of transmitting a PPDU");
if (delay.IsStrictlyPositive())
{
NotifyChannelReleased(edca);
Simulator::Schedule(
delay,
&Txop::StartAccessAfterEvent,
edca,
m_linkId,
Txop::DIDNT_HAVE_FRAMES_TO_TRANSMIT, // queued frames cannot be
// transmitted until RX ends
Txop::CHECK_MEDIUM_BUSY); // generate backoff if medium busy
}
return false;
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/wifi/model/eht/emlsr-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ EmlsrManager::NotifyIcfReceived(uint8_t linkId)
DoNotifyIcfReceived(linkId);
}

Time
std::pair<bool, Time>
EmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci)
{
auto phy = m_staMac->GetWifiPhy(linkId);
Expand All @@ -413,15 +413,15 @@ EmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci)
auto mainPhy = m_staMac->GetDevice()->GetPhy(m_mainPhyId);

// check possible reasons to give up the TXOP that apply to both main PHY and aux PHYs
if (auto delay = DoGetDelayUntilAccessRequest(linkId); delay.IsStrictlyPositive())
if (const auto [startTxop, delay] = DoGetDelayUntilAccessRequest(linkId); !startTxop)
{
return delay;
return {false, delay};
}

if (phy == mainPhy)
{
// no more constraints to check if medium was gained by main PHY
return Time{0};
return {true, Time{0}};
}

// an aux PHY is operating on the given link; call the appropriate method depending on
Expand All @@ -433,7 +433,8 @@ EmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci)
// PHY switches link, the UL TXOP will be started; if the main PHY does not switch, it is
// because it is going to start an UL TXOP on another link and this link will be restarted
// at the end of that UL TXOP when this link will be unblocked
return Time{0};
NS_LOG_DEBUG("Aux PHY is not capable of transmitting a PPDU");
return {false, Time{0}};
}

return GetDelayUnlessMainPhyTakesOverUlTxop(linkId);
Expand Down
22 changes: 13 additions & 9 deletions src/wifi/model/eht/emlsr-manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <map>
#include <optional>
#include <set>
#include <utility>

class EmlsrCcaBusyTest;

Expand Down Expand Up @@ -147,10 +148,11 @@ class EmlsrManager : public Object
*
* \param linkId the ID of the given link
* \param aci the index of the given AC
* \return zero, if the UL TXOP can be started, or the delay after which the EMLSR client
* restarts channel access, otherwise
* \return a pair consisting of a boolean value indicating whether the UL TXOP can be started
* and a Time value indicating the delay after which the EMLSR client must restart
* channel access (if needed) in case the UL TXOP is not started
*/
Time GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci);
std::pair<bool, Time> GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci);

/**
* Set the member variable indicating whether Aux PHYs are capable of transmitting PPDUs.
Expand Down Expand Up @@ -357,10 +359,11 @@ class EmlsrManager : public Object
* check possible reasons to give up the TXOP that apply to both main PHY and aux PHYs.
*
* \param linkId the ID of the given link
* \return zero, if the UL TXOP can be started, or the delay after which the EMLSR client
* restarts channel access, otherwise
* \return a pair consisting of a boolean value indicating whether the UL TXOP can be started
* and a Time value indicating the delay after which the EMLSR client must restart
* channel access (if needed) in case the UL TXOP is not started
*/
virtual Time DoGetDelayUntilAccessRequest(uint8_t linkId) = 0;
virtual std::pair<bool, Time> DoGetDelayUntilAccessRequest(uint8_t linkId) = 0;

/**
* Subclasses have to provide an implementation for this method, that is called by the base
Expand All @@ -381,10 +384,11 @@ class EmlsrManager : public Object
* EMLSR client restarts channel access on the given link, otherwise.
*
* \param linkId the ID of the given link
* \return zero, if the UL TXOP can be started, or the delay after which the EMLSR client
* restarts channel access, otherwise
* \return a pair consisting of a boolean value indicating whether the UL TXOP can be started
* and a Time value indicating the delay after which the EMLSR client must restart
* channel access (if needed) in case the UL TXOP is not started
*/
virtual Time GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) = 0;
virtual std::pair<bool, Time> GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) = 0;

Time m_emlsrPaddingDelay; //!< EMLSR Padding delay
Time m_emlsrTransitionDelay; //!< EMLSR Transition delay
Expand Down

0 comments on commit a46abc4

Please sign in to comment.