wifi: Avoid code duplication in WifiPhyStateHelper

This commit is contained in:
Stefano Avallone
2023-09-08 16:36:32 +02:00
committed by Stefano Avallone
parent 7165cf22af
commit 5bd77d712d
2 changed files with 50 additions and 172 deletions

View File

@@ -29,6 +29,7 @@
#include "ns3/simulator.h"
#include <algorithm>
#include <functional>
#include <iterator>
namespace ns3
@@ -66,7 +67,8 @@ WifiPhyStateHelper::GetTypeId()
}
WifiPhyStateHelper::WifiPhyStateHelper()
: m_sleeping(false),
: NS_LOG_TEMPLATE_DEFINE("Queue"),
m_sleeping(false),
m_isOff(false),
m_endTx(Seconds(0)),
m_endRx(Seconds(0)),
@@ -230,108 +232,6 @@ WifiPhyStateHelper::GetState() const
}
}
void
WifiPhyStateHelper::NotifyTxStart(Time duration, double txPowerDbm)
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifyTxStart(duration, txPowerDbm);
}
}
void
WifiPhyStateHelper::NotifyRxStart(Time duration)
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifyRxStart(duration);
}
}
void
WifiPhyStateHelper::NotifyRxEndOk()
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifyRxEndOk();
}
}
void
WifiPhyStateHelper::NotifyRxEndError()
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifyRxEndError();
}
}
void
WifiPhyStateHelper::NotifyCcaBusyStart(Time duration,
WifiChannelListType channelType,
const std::vector<Time>& per20MhzDurations)
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifyCcaBusyStart(duration, channelType, per20MhzDurations);
}
}
void
WifiPhyStateHelper::NotifySwitchingStart(Time duration)
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifySwitchingStart(duration);
}
}
void
WifiPhyStateHelper::NotifySleep()
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifySleep();
}
}
void
WifiPhyStateHelper::NotifyOff()
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifyOff();
}
}
void
WifiPhyStateHelper::NotifyWakeup()
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifyWakeup();
}
}
void
WifiPhyStateHelper::NotifyOn()
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
listener->NotifyOn();
}
}
void
WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates()
{
@@ -404,7 +304,7 @@ WifiPhyStateHelper::SwitchToTx(Time txDuration,
m_previousStateChangeTime = now;
m_endTx = now + txDuration;
m_startTx = now;
NotifyTxStart(txDuration, txPowerDbm);
NotifyListeners(&WifiPhyListener::NotifyTxStart, txDuration, txPowerDbm);
}
void
@@ -427,7 +327,7 @@ WifiPhyStateHelper::SwitchToRx(Time rxDuration)
m_previousStateChangeTime = now;
m_startRx = now;
m_endRx = now + rxDuration;
NotifyRxStart(rxDuration);
NotifyListeners(&WifiPhyListener::NotifyRxStart, rxDuration);
NS_ASSERT(IsStateRx());
}
@@ -460,7 +360,7 @@ WifiPhyStateHelper::SwitchToChannelSwitching(Time switchingDuration)
m_previousStateChangeTime = now;
m_startSwitching = now;
m_endSwitching = now + switchingDuration;
NotifySwitchingStart(switchingDuration);
NotifyListeners(&WifiPhyListener::NotifySwitchingStart, switchingDuration);
NS_ASSERT(switchingDuration.IsZero() || IsStateSwitching());
}
@@ -520,7 +420,7 @@ WifiPhyStateHelper::SwitchFromRxEndOk()
{
NS_LOG_FUNCTION(this);
NS_ASSERT(m_endRx == Simulator::Now());
NotifyRxEndOk();
NotifyListeners(&WifiPhyListener::NotifyRxEndOk);
DoSwitchFromRx();
}
@@ -529,7 +429,7 @@ WifiPhyStateHelper::SwitchFromRxEndError()
{
NS_LOG_FUNCTION(this);
NS_ASSERT(m_endRx == Simulator::Now());
NotifyRxEndError();
NotifyListeners(&WifiPhyListener::NotifyRxEndError);
DoSwitchFromRx();
}
@@ -554,7 +454,7 @@ WifiPhyStateHelper::SwitchMaybeToCcaBusy(Time duration,
{
return;
}
NotifyCcaBusyStart(duration, channelType, per20MhzDurations);
NotifyListeners(&WifiPhyListener::NotifyCcaBusyStart, duration, channelType, per20MhzDurations);
if (channelType != WIFI_CHANLIST_PRIMARY)
{
// WifiPhyStateHelper only updates CCA start and end durations for the primary channel
@@ -591,7 +491,7 @@ WifiPhyStateHelper::SwitchToSleep()
m_previousStateChangeTime = now;
m_sleeping = true;
m_startSleep = now;
NotifySleep();
NotifyListeners(&WifiPhyListener::NotifySleep);
NS_ASSERT(IsStateSleep());
}
@@ -604,7 +504,7 @@ WifiPhyStateHelper::SwitchFromSleep()
m_stateLogger(m_startSleep, now - m_startSleep, WifiPhyState::SLEEP);
m_previousStateChangeTime = now;
m_sleeping = false;
NotifyWakeup();
NotifyListeners(&WifiPhyListener::NotifyWakeup);
}
void
@@ -613,7 +513,7 @@ WifiPhyStateHelper::SwitchFromRxAbort(uint16_t operatingWidth)
NS_LOG_FUNCTION(this << operatingWidth);
NS_ASSERT(IsStateCcaBusy()); // abort is called (with OBSS_PD_CCA_RESET reason) before RX is set
// by payload start
NotifyRxEndOk();
NotifyListeners(&WifiPhyListener::NotifyRxEndOk);
DoSwitchFromRx();
m_endCcaBusy = Simulator::Now();
std::vector<Time> per20MhzDurations;
@@ -621,7 +521,10 @@ WifiPhyStateHelper::SwitchFromRxAbort(uint16_t operatingWidth)
{
std::fill_n(std::back_inserter(per20MhzDurations), (operatingWidth / 20), Seconds(0));
}
NotifyCcaBusyStart(Seconds(0), WIFI_CHANLIST_PRIMARY, per20MhzDurations);
NotifyListeners(&WifiPhyListener::NotifyCcaBusyStart,
Seconds(0),
WIFI_CHANLIST_PRIMARY,
per20MhzDurations);
NS_ASSERT(IsStateIdle());
}
@@ -657,7 +560,7 @@ WifiPhyStateHelper::SwitchToOff()
}
m_previousStateChangeTime = now;
m_isOff = true;
NotifyOff();
NotifyListeners(&WifiPhyListener::NotifyOff);
NS_ASSERT(IsStateOff());
}
@@ -669,7 +572,7 @@ WifiPhyStateHelper::SwitchFromOff()
Time now = Simulator::Now();
m_previousStateChangeTime = now;
m_isOff = false;
NotifyOn();
NotifyListeners(&WifiPhyListener::NotifyOn);
}
} // namespace ns3

View File

@@ -310,6 +310,17 @@ class WifiPhyStateHelper : public Object
WifiPreamble preamble,
uint8_t power);
/**
* Notify all WifiPhyListener objects of the given PHY event.
*
* \tparam FUNC \deduced Member function type
* \tparam Ts \deduced Function argument types
* \param f the member function to invoke
* \param args arguments to pass to the member function
*/
template <typename FUNC, typename... Ts>
void NotifyListeners(FUNC f, Ts&&... args);
private:
/**
* typedef for a list of WifiPhyListeners
@@ -321,73 +332,17 @@ class WifiPhyStateHelper : public Object
*/
void LogPreviousIdleAndCcaBusyStates();
/**
* Notify all WifiPhyListener that the transmission has started for the given duration.
*
* \param duration the duration of the transmission
* \param txPowerDbm the nominal TX power in dBm
*/
void NotifyTxStart(Time duration, double txPowerDbm);
/**
* Notify all WifiPhyListener that the reception has started for the given duration.
*
* \param duration the duration of the reception
*/
void NotifyRxStart(Time duration);
/**
* Notify all WifiPhyListener that the reception was successful.
*/
void NotifyRxEndOk();
/**
* Notify all WifiPhyListener that the reception was not successful.
*/
void NotifyRxEndError();
/**
* Notify all WifiPhyListener that the CCA has started for the given duration.
*
* \param duration the duration of the CCA state
* \param channelType the channel type for which the CCA busy state is reported.
* \param per20MhzDurations vector that indicates for how long each 20 MHz subchannel
* (corresponding to the index of the element in the vector) is busy and where a zero
* duration indicates that the subchannel is idle. The vector is non-empty if the PHY supports
* 802.11ax or later and if the operational channel width is larger than 20 MHz.
*/
void NotifyCcaBusyStart(Time duration,
WifiChannelListType channelType,
const std::vector<Time>& per20MhzDurations);
/**
* Notify all WifiPhyListener that we are switching channel with the given channel
* switching delay.
*
* \param duration the delay to switch the channel
*/
void NotifySwitchingStart(Time duration);
/**
* Notify all WifiPhyListener that we are going to sleep
*/
void NotifySleep();
/**
* Notify all WifiPhyListener that we are going to switch off
*/
void NotifyOff();
/**
* Notify all WifiPhyListener that we woke up
*/
void NotifyWakeup();
/**
* Switch the state from RX.
*/
void DoSwitchFromRx();
/**
* Notify all WifiPhyListener that we are going to switch on
*/
void NotifyOn();
/**
* The trace source fired when state is changed.
*/
TracedCallback<Time, Time, WifiPhyState> m_stateLogger;
NS_LOG_TEMPLATE_DECLARE; //!< the log component
bool m_sleeping; ///< sleeping
bool m_isOff; ///< switched off
Time m_endTx; ///< end transmit
@@ -413,4 +368,24 @@ class WifiPhyStateHelper : public Object
} // namespace ns3
/***************************************************************
* Implementation of the templates declared above.
***************************************************************/
namespace ns3
{
template <typename FUNC, typename... Ts>
void
WifiPhyStateHelper::NotifyListeners(FUNC f, Ts&&... args)
{
NS_LOG_FUNCTION(this);
for (const auto& listener : m_listeners)
{
std::invoke(f, listener, std::forward<Ts>(args)...);
}
}
} // namespace ns3
#endif /* WIFI_PHY_STATE_HELPER_H */