wifi: Add Advanced EMLSR Manager

This commit is contained in:
Stefano Avallone
2024-01-19 22:12:04 +01:00
parent 936d9c94d8
commit c0a8b460e4
4 changed files with 224 additions and 0 deletions

View File

@@ -27,6 +27,7 @@ set(source_files
model/channel-access-manager.cc
model/ctrl-headers.cc
model/edca-parameter-set.cc
model/eht/advanced-emlsr-manager.cc
model/eht/default-emlsr-manager.cc
model/eht/eht-capabilities.cc
model/eht/eht-configuration.cc
@@ -186,6 +187,7 @@ set(header_files
model/channel-access-manager.h
model/ctrl-headers.h
model/edca-parameter-set.h
model/eht/advanced-emlsr-manager.h
model/eht/default-emlsr-manager.h
model/eht/eht-capabilities.h
model/eht/eht-configuration.h

View File

@@ -885,6 +885,7 @@ WifiHelper::EnableLogComponents(LogLevel logLevel)
LogComponentEnable("AarfWifiManager", logLevel);
LogComponentEnable("AarfcdWifiManager", logLevel);
LogComponentEnable("AdhocWifiMac", logLevel);
LogComponentEnable("AdvancedEmlsrManager", logLevel);
LogComponentEnable("AmrrWifiManager", logLevel);
LogComponentEnable("ApWifiMac", logLevel);
LogComponentEnable("AparfWifiManager", logLevel);

View File

@@ -0,0 +1,165 @@
/*
* Copyright (c) 2024 Universita' di Napoli Federico II
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Stefano Avallone <stavallo@unina.it>
*/
#include "advanced-emlsr-manager.h"
#include "eht-frame-exchange-manager.h"
#include "ns3/boolean.h"
#include "ns3/log.h"
#include "ns3/wifi-net-device.h"
#include "ns3/wifi-phy.h"
namespace ns3
{
NS_LOG_COMPONENT_DEFINE("AdvancedEmlsrManager");
NS_OBJECT_ENSURE_REGISTERED(AdvancedEmlsrManager);
TypeId
AdvancedEmlsrManager::GetTypeId()
{
static TypeId tid =
TypeId("ns3::AdvancedEmlsrManager")
.SetParent<DefaultEmlsrManager>()
.SetGroupName("Wifi")
.AddConstructor<AdvancedEmlsrManager>()
.AddAttribute("UseNotifiedMacHdr",
"Whether to use the information about the MAC header of the MPDU "
"being received, if notified by the PHY.",
BooleanValue(true),
MakeBooleanAccessor(&AdvancedEmlsrManager::m_useNotifiedMacHdr),
MakeBooleanChecker())
.AddAttribute("AllowUlTxopInRx",
"Whether a (main or aux) PHY is allowed to start an UL TXOP if "
"another PHY is receiving a PPDU (possibly starting a DL TXOP). "
"If this attribute is true, the PPDU may be dropped.",
BooleanValue(false),
MakeBooleanAccessor(&AdvancedEmlsrManager::m_allowUlTxopInRx),
MakeBooleanChecker());
return tid;
}
AdvancedEmlsrManager::AdvancedEmlsrManager()
{
NS_LOG_FUNCTION(this);
}
AdvancedEmlsrManager::~AdvancedEmlsrManager()
{
NS_LOG_FUNCTION_NOARGS();
}
Time
AdvancedEmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
// prevent or allow an UL TXOP depending on whether another PHY is receiving a PPDU
for (const auto id : GetStaMac()->GetLinkIds())
{
if (id != linkId && GetStaMac()->IsEmlsrLink(id))
{
auto phy = GetStaMac()->GetWifiPhy(id);
if (auto macHdr = GetEhtFem(id)->GetReceivedMacHdr(); macHdr && m_useNotifiedMacHdr)
{
NS_ASSERT(phy &&
phy->GetState()->GetLastTime({WifiPhyState::RX}) == Simulator::Now());
// we are receiving the MAC payload of a PSDU; if the PSDU being received on
// another link is an ICF, give up the TXOP and restart channel access at the
// end of PSDU reception. Note that we cannot be sure that the PSDU being received
// is an ICF addressed to us until we receive the entire PSDU
if (const auto& hdr = macHdr->get();
hdr.IsTrigger() &&
(hdr.GetAddr1().IsBroadcast() || hdr.GetAddr1() == GetEhtFem(id)->GetAddress()))
{
return phy->GetDelayUntilIdle();
}
continue;
}
if (phy && phy->IsReceivingPhyHeader())
{
// we don't know yet the type of the frame being received; prevent or allow
// the UL TXOP based on user configuration
if (!m_allowUlTxopInRx)
{
// retry channel access after the end of the current PHY header field
return phy->GetDelayUntilIdle();
}
continue;
}
if (phy && phy->IsStateRx())
{
// we don't know yet the type of the frame being received; prevent or allow
// the UL TXOP based on user configuration
if (!m_allowUlTxopInRx)
{
if (!m_useNotifiedMacHdr)
{
// restart channel access at the end of PSDU reception
return phy->GetDelayUntilIdle();
}
// retry channel access after the expected end of the MAC header reception
auto macHdrSize = WifiMacHeader(WIFI_MAC_QOSDATA).GetSerializedSize() +
4 /* A-MPDU subframe header length */;
auto ongoingRxInfo = GetEhtFem(id)->GetOngoingRxInfo();
// if a PHY is in RX state, it should have info about received MAC header.
// The exception is represented by this situation:
// - an aux PHY is disconnected from the MAC stack because the main PHY is
// operating on its link
// - the main PHY notifies the MAC header info to the FEM and then leaves the
// link (e.g., because it recognizes that the MPDU is not addressed to the
// EMLSR client). Disconnecting the main PHY from the MAC stack causes the
// MAC header info to be discarded by the FEM
// - the aux PHY is re-connected to the MAC stack and is still in RX state
// when the main PHY gets channel access on another link (and we get here)
if (!ongoingRxInfo.has_value())
{
NS_ASSERT_MSG(phy != GetStaMac()->GetDevice()->GetPhy(GetMainPhyId()),
"Main PHY should have MAC header info when in RX state");
// we are in the situation described above; if the MPDU being received
// by the aux PHY is not addressed to the EMLSR client, we can ignore it
continue;
}
const auto& txVector = ongoingRxInfo->get().txVector;
if (txVector.IsMu())
{
// this is not an ICF, ignore it
continue;
}
auto macHdrDuration = DataRate(txVector.GetMode().GetDataRate(txVector))
.CalculateBytesTxTime(macHdrSize);
const auto timeSinceRxStart =
Simulator::Now() - phy->GetState()->GetLastTime({WifiPhyState::CCA_BUSY});
return Max(macHdrDuration - timeSinceRxStart, Time{0});
}
continue;
}
}
}
return Time{0};
}
} // namespace ns3

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Universita' di Napoli Federico II
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Stefano Avallone <stavallo@unina.it>
*/
#ifndef ADVANCED_EMLSR_MANAGER_H
#define ADVANCED_EMLSR_MANAGER_H
#include "default-emlsr-manager.h"
namespace ns3
{
/**
* \ingroup wifi
*
* AdvancedEmlsrManager is an advanced EMLSR manager.
*/
class AdvancedEmlsrManager : public DefaultEmlsrManager
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
AdvancedEmlsrManager();
~AdvancedEmlsrManager() override;
Time GetDelayUntilAccessRequest(uint8_t linkId) override;
private:
bool m_useNotifiedMacHdr; //!< whether to use the information about the MAC header of
//!< the MPDU being received (if notified by the PHY)
bool m_allowUlTxopInRx; //!< whether a (main or aux) PHY is allowed to start an UL
//!< TXOP if another PHY is receiving a PPDU
};
} // namespace ns3
#endif /* ADVANCED_EMLSR_MANAGER_H */