wifi: StaWifiMac keeps per-link beacon watchdogs

This commit is contained in:
Stefano Avallone
2022-07-19 18:39:58 +02:00
committed by Stefano Avallone
parent 124bb89881
commit 23d508d193
2 changed files with 36 additions and 24 deletions

View File

@@ -103,8 +103,7 @@ StaWifiMac::GetTypeId (void)
StaWifiMac::StaWifiMac ()
: m_state (UNASSOCIATED),
m_aid (0),
m_assocRequestEvent (),
m_beaconWatchdogEnd (Seconds (0))
m_assocRequestEvent ()
{
NS_LOG_FUNCTION (this);
@@ -553,7 +552,14 @@ StaWifiMac::ScanningTimeout (const std::optional<ApInfo>& bestAp)
};
Time beaconInterval = std::visit (getBeaconInterval, bestAp->m_frame);
Time delay = beaconInterval * m_maxMissedBeacons;
RestartBeaconWatchdog (delay);
// restart beacon watchdog for all links to setup
for (uint8_t linkId = 0; linkId < GetNLinks (); linkId++)
{
if (GetLink (linkId).apLinkId.has_value () || GetNLinks () == 1)
{
RestartBeaconWatchdog (delay, linkId);
}
}
SetState (WAIT_ASSOC_RESP);
SendAssociationRequest (false);
}
@@ -567,17 +573,18 @@ StaWifiMac::AssocRequestTimeout (void)
}
void
StaWifiMac::MissedBeacons (void)
StaWifiMac::MissedBeacons (uint8_t linkId)
{
NS_LOG_FUNCTION (this);
if (m_beaconWatchdogEnd > Simulator::Now ())
NS_LOG_FUNCTION (this << +linkId);
auto& link = GetLink (linkId);
if (link.beaconWatchdogEnd > Simulator::Now ())
{
if (m_beaconWatchdog.IsRunning ())
if (link.beaconWatchdog.IsRunning ())
{
m_beaconWatchdog.Cancel ();
link.beaconWatchdog.Cancel ();
}
m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::Now (),
&StaWifiMac::MissedBeacons, this);
link.beaconWatchdog = Simulator::Schedule (link.beaconWatchdogEnd - Simulator::Now (),
&StaWifiMac::MissedBeacons, this, linkId);
return;
}
NS_LOG_DEBUG ("beacon missed");
@@ -585,9 +592,9 @@ StaWifiMac::MissedBeacons (void)
// a frame, wait until the RX is completed (otherwise, crashes may occur if
// we are receiving a MU frame because its reception requires the STA-ID)
Time delay = Seconds (0);
if (GetWifiPhy ()->IsStateRx ())
if (GetWifiPhy (linkId)->IsStateRx ())
{
delay = GetWifiPhy ()->GetDelayUntilIdle ();
delay = GetWifiPhy (linkId)->GetDelayUntilIdle ();
}
Simulator::Schedule (delay, &StaWifiMac::Disassociated, this);
}
@@ -603,15 +610,16 @@ StaWifiMac::Disassociated (void)
}
void
StaWifiMac::RestartBeaconWatchdog (Time delay)
StaWifiMac::RestartBeaconWatchdog (Time delay, uint8_t linkId)
{
NS_LOG_FUNCTION (this << delay);
m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd);
if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay
&& m_beaconWatchdog.IsExpired ())
NS_LOG_FUNCTION (this << delay << +linkId);
auto& link = GetLink (linkId);
link.beaconWatchdogEnd = std::max (Simulator::Now () + delay, link.beaconWatchdogEnd);
if (Simulator::GetDelayLeft (link.beaconWatchdog) < delay
&& link.beaconWatchdog.IsExpired ())
{
NS_LOG_DEBUG ("really restart watchdog.");
m_beaconWatchdog = Simulator::Schedule (delay, &StaWifiMac::MissedBeacons, this);
link.beaconWatchdog = Simulator::Schedule (delay, &StaWifiMac::MissedBeacons, this, linkId);
}
}
@@ -827,7 +835,7 @@ StaWifiMac::ReceiveBeacon (Ptr<WifiMpdu> mpdu, uint8_t linkId)
{
m_beaconArrival (Simulator::Now ());
Time delay = MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissedBeacons);
RestartBeaconWatchdog (delay);
RestartBeaconWatchdog (delay, linkId);
UpdateApInfo (beacon, hdr.GetAddr2 (), hdr.GetAddr3 (), linkId);
}
else

View File

@@ -237,6 +237,8 @@ protected:
std::optional<uint8_t> apLinkId; //!< ID (as set by the AP) of the link we have
//!< setup or are setting up
bool sendAssocReq; //!< whether this link is used to send the Association Request
EventId beaconWatchdog; //!< beacon watchdog
Time beaconWatchdogEnd {0}; //!< beacon watchdog end
};
/**
@@ -367,14 +369,18 @@ private:
bool IsWaitAssocResp (void) const;
/**
* This method is called after we have not received a beacon from the AP
* on the given link.
*
* \param linkId the ID of the given link
*/
void MissedBeacons (void);
void MissedBeacons (uint8_t linkId);
/**
* Restarts the beacon timer.
* Restarts the beacon timer for the given link.
*
* \param delay the delay before the watchdog fires
* \param linkId the ID of the given link
*/
void RestartBeaconWatchdog (Time delay);
void RestartBeaconWatchdog (Time delay, uint8_t linkId);
/**
* Take actions after disassociation.
*/
@@ -454,8 +460,6 @@ private:
Time m_probeRequestTimeout; ///< probe request timeout
Time m_assocRequestTimeout; ///< association request timeout
EventId m_assocRequestEvent; ///< association request event
EventId m_beaconWatchdog; ///< beacon watchdog
Time m_beaconWatchdogEnd; ///< beacon watchdog end
uint32_t m_maxMissedBeacons; ///< maximum missed beacons
bool m_activeProbing; ///< active probing
Ptr<RandomVariableStream> m_probeDelay; ///< RandomVariable used to randomize the time