wifi: Add Advanced EMLSR Manager
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
165
src/wifi/model/eht/advanced-emlsr-manager.cc
Normal file
165
src/wifi/model/eht/advanced-emlsr-manager.cc
Normal 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
|
||||
56
src/wifi/model/eht/advanced-emlsr-manager.h
Normal file
56
src/wifi/model/eht/advanced-emlsr-manager.h
Normal 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 */
|
||||
Reference in New Issue
Block a user