wifi: EMLSR client switches to listening mode as soon as it is notified of the MAC header of an MPDU that is not addressed to it

This commit is contained in:
Stefano Avallone
2024-01-17 17:44:38 +01:00
parent 092c56d6b9
commit b14ce3b2c0
6 changed files with 102 additions and 0 deletions

View File

@@ -67,6 +67,32 @@ AdvancedEmlsrManager::~AdvancedEmlsrManager()
NS_LOG_FUNCTION_NOARGS();
}
void
AdvancedEmlsrManager::DoDispose()
{
NS_LOG_FUNCTION(this);
for (auto phy : GetStaMac()->GetDevice()->GetPhys())
{
phy->TraceDisconnectWithoutContext(
"PhyRxMacHeaderEnd",
MakeCallback(&AdvancedEmlsrManager::ReceivedMacHdr, this).Bind(phy));
}
DefaultEmlsrManager::DoDispose();
}
void
AdvancedEmlsrManager::DoSetWifiMac(Ptr<StaWifiMac> mac)
{
NS_LOG_FUNCTION(this << mac);
for (auto phy : GetStaMac()->GetDevice()->GetPhys())
{
phy->TraceConnectWithoutContext(
"PhyRxMacHeaderEnd",
MakeCallback(&AdvancedEmlsrManager::ReceivedMacHdr, this).Bind(phy));
}
}
Time
AdvancedEmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId)
{
@@ -162,4 +188,36 @@ AdvancedEmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId)
return Time{0};
}
void
AdvancedEmlsrManager::ReceivedMacHdr(Ptr<WifiPhy> phy,
const WifiMacHeader& macHdr,
const WifiTxVector& txVector,
Time psduDuration)
{
auto linkId = GetStaMac()->GetLinkForPhy(phy);
if (!linkId.has_value())
{
return;
}
NS_LOG_FUNCTION(this << *linkId << macHdr << txVector << psduDuration.As(Time::MS));
auto& ongoingTxopEnd = GetEhtFem(*linkId)->GetOngoingTxopEndEvent();
if (m_useNotifiedMacHdr && ongoingTxopEnd.IsPending() &&
macHdr.GetAddr1() != GetEhtFem(*linkId)->GetAddress() && !macHdr.GetAddr1().IsBroadcast() &&
!(macHdr.IsCts() && macHdr.GetAddr1() == GetEhtFem(*linkId)->GetBssid() /* CTS-to-self */))
{
// the EMLSR client is no longer involved in the TXOP and switching to listening mode
ongoingTxopEnd.Cancel();
// this method is a callback connected to the PhyRxMacHeaderEnd trace source of WifiPhy
// and is called within a for loop that executes all the callbacks. The call to NotifyTxop
// below leads the main PHY to be connected back to the primary link, thus
// the ResetPhy() method of the FEM on the non-primary link is called, which disconnects
// another callback (FEM::ReceivedMacHdr) from the PhyRxMacHeaderEnd trace source of
// the main PHY, thus invalidating the list of callbacks on which the for loop iterates.
// Hence, schedule the call to NotifyTxopEnd to execute it outside such for loop.
Simulator::ScheduleNow(&AdvancedEmlsrManager::NotifyTxopEnd, this, *linkId, false, false);
}
}
} // namespace ns3

View File

@@ -44,6 +44,24 @@ class AdvancedEmlsrManager : public DefaultEmlsrManager
Time GetDelayUntilAccessRequest(uint8_t linkId) override;
protected:
void DoDispose() override;
void DoSetWifiMac(Ptr<StaWifiMac> mac) override;
/**
* Possibly take actions when notified of the MAC header of the MPDU being received by the
* given PHY.
*
* \param phy the given PHY
* \param macHdr the MAC header of the MPDU being received
* \param txVector the TXVECTOR used to transmit the PSDU
* \param psduDuration the remaining duration of the PSDU
*/
void ReceivedMacHdr(Ptr<WifiPhy> phy,
const WifiMacHeader& macHdr,
const WifiTxVector& txVector,
Time psduDuration);
private:
bool m_useNotifiedMacHdr; //!< whether to use the information about the MAC header of
//!< the MPDU being received (if notified by the PHY)

View File

@@ -1163,6 +1163,12 @@ EhtFrameExchangeManager::CheckEmlsrClientStartingTxop(const WifiMacHeader& hdr,
return true;
}
EventId&
EhtFrameExchangeManager::GetOngoingTxopEndEvent()
{
return m_ongoingTxopEnd;
}
void
EhtFrameExchangeManager::PsduRxError(Ptr<const WifiPsdu> psdu)
{

View File

@@ -126,6 +126,12 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager
*/
void EmlsrSwitchToListening(const Mac48Address& address, const Time& delay);
/**
* \return a reference to the event indicating the possible end of the current TXOP (of
* which this device is not the holder)
*/
EventId& GetOngoingTxopEndEvent();
protected:
void DoDispose() override;
void RxStartIndication(WifiTxVector txVector, Time psduDuration) override;

View File

@@ -177,6 +177,13 @@ EmlsrManager::SetWifiMac(Ptr<StaWifiMac> mac)
m_staMac->TraceConnectWithoutContext("AckedMpdu", MakeCallback(&EmlsrManager::TxOk, this));
m_staMac->TraceConnectWithoutContext("DroppedMpdu",
MakeCallback(&EmlsrManager::TxDropped, this));
DoSetWifiMac(mac);
}
void
EmlsrManager::DoSetWifiMac(Ptr<StaWifiMac> mac)
{
NS_LOG_FUNCTION(this << mac);
}
void

View File

@@ -280,6 +280,13 @@ class EmlsrManager : public Object
protected:
void DoDispose() override;
/**
* Allow subclasses to take actions when the MAC is set.
*
* \param mac the wifi MAC
*/
virtual void DoSetWifiMac(Ptr<StaWifiMac> mac);
/**
* \return the MAC of the non-AP MLD managed by this EMLSR Manager.
*/