diff --git a/src/wifi/model/sta-wifi-mac.cc b/src/wifi/model/sta-wifi-mac.cc index de8f97399..5ba9c94c5 100644 --- a/src/wifi/model/sta-wifi-mac.cc +++ b/src/wifi/model/sta-wifi-mac.cc @@ -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& 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 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 diff --git a/src/wifi/model/sta-wifi-mac.h b/src/wifi/model/sta-wifi-mac.h index 2d45d66d2..7cd93e098 100644 --- a/src/wifi/model/sta-wifi-mac.h +++ b/src/wifi/model/sta-wifi-mac.h @@ -237,6 +237,8 @@ protected: std::optional 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 m_probeDelay; ///< RandomVariable used to randomize the time