wifi: Start MediumSyncDelay timer if PHY slept for >72us

This commit is contained in:
Stefano Avallone
2024-07-03 17:12:24 +02:00
parent afa46abd12
commit 02340b5087
2 changed files with 38 additions and 6 deletions

View File

@@ -1212,36 +1212,67 @@ EmlsrManager::SetSleepStateForAllAuxPhys(bool sleep)
continue; // do not set sleep mode/resume from sleep the main PHY
}
if (auto linkId = m_staMac->GetLinkForPhy(phy);
linkId.has_value() && !m_staMac->IsEmlsrLink(*linkId))
auto linkId = m_staMac->GetLinkForPhy(phy);
if (linkId.has_value() && !m_staMac->IsEmlsrLink(*linkId))
{
continue; // this PHY is not operating on an EMLSR link
}
if (!sleep)
{
if (!phy->IsStateSleep())
{
continue; // nothing to do
}
NS_LOG_DEBUG("PHY " << +phy->GetPhyId() << ": Resuming from sleep");
phy->ResumeFromSleep();
continue;
// if this aux PHY is operating on a link, check if it lost medium sync
if (linkId.has_value())
{
auto it = m_startSleep.find(phy->GetPhyId());
NS_ASSERT_MSG(it != m_startSleep.cend(),
"No start sleep info for PHY ID " << phy->GetPhyId());
const auto sleepDuration = Simulator::Now() - it->second;
m_startSleep.erase(it);
if (sleepDuration > MicroSeconds(MEDIUM_SYNC_THRESHOLD_USEC))
{
StartMediumSyncDelayTimer(*linkId);
}
}
continue; // resuming the PHY from sleep has been handled
}
if (phy->IsStateSleep())
{
continue; // nothing to do
}
// we force WifiPhy::SetSleepMode() to abort RX and switch immediately to sleep mode in
// case the state is RX. If the state is TX or SWITCHING, WifiPhy::SetSleepMode() postpones
// setting sleep mode to end of TX or SWITCHING. This is fine, but we schedule events here
// to be able to cancel them later if needed
// to correctly record the time an aux PHY was put to sleep and to be able to cancel them
// later if needed
std::stringstream ss;
auto s = std::string("PHY ") + std::to_string(phy->GetPhyId()) + ": Setting sleep mode";
if (phy->IsStateTx() || phy->IsStateSwitching())
{
const auto delay = phy->GetDelayUntilIdle();
NS_LOG_DEBUG(s << " in " << delay.As(Time::US));
m_auxPhyToSleepEvents[phy->GetPhyId()] =
Simulator::Schedule(delay, &WifiPhy::SetSleepMode, phy, true);
m_auxPhyToSleepEvents[phy->GetPhyId()] = Simulator::Schedule(delay, [=, this]() {
phy->SetSleepMode(true);
m_startSleep[phy->GetPhyId()] = Simulator::Now();
});
}
else
{
NS_LOG_DEBUG(s);
phy->SetSleepMode(true);
m_startSleep[phy->GetPhyId()] = Simulator::Now();
}
}
}

View File

@@ -440,6 +440,7 @@ class EmlsrManager : public Object
//!< is carrying out a (DL or UL) TXOP
std::map<uint8_t, EventId> m_auxPhyToSleepEvents; //!< PHY ID-indexed map of events scheduled to
//!< put an Aux PHY to sleep
std::map<uint8_t, Time> m_startSleep; //!< PHY ID-indexed map of last time sleep mode started
std::map<uint8_t, EventId> m_ulMainPhySwitch; //!< link ID-indexed map of timers started when
//!< an aux PHY gains an UL TXOP and schedules
//!< a channel switch for the main PHY