From 9f5db9c27d925e24b23dc1bc3fdf05b741d679d6 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 13 Jul 2022 12:28:46 +0200 Subject: [PATCH] wifi: Make Reduced Neighbor Report IE optional in mgt frames --- src/wifi/model/ap-wifi-mac.cc | 34 ++++++++++++-------- src/wifi/model/ap-wifi-mac.h | 4 +-- src/wifi/model/mgt-headers.cc | 17 ++++++---- src/wifi/model/mgt-headers.h | 14 +++++--- src/wifi/model/wifi-assoc-manager.cc | 4 +-- src/wifi/model/wifi-assoc-manager.h | 10 +++--- src/wifi/model/wifi-default-assoc-manager.cc | 8 ++--- 7 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index 626bec06b..8511c9048 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -591,32 +591,32 @@ ApWifiMac::GetMuEdcaParameterSet (void) const return std::nullopt; } -Ptr +std::optional ApWifiMac::GetReducedNeighborReport (uint8_t linkId) const { NS_LOG_FUNCTION (this << +linkId); if (GetNLinks () <= 1) { - return nullptr; + return std::nullopt; } NS_ABORT_IF (!GetEhtSupported ()); - auto rnr = Create (); + ReducedNeighborReport rnr; for (uint8_t index = 0; index < GetNLinks (); ++index) { if (index != linkId) // all links but the one used to send this Beacon frame { - rnr->AddNbrApInfoField (); - std::size_t nbrId = rnr->GetNNbrApInfoFields () - 1; - rnr->SetOperatingChannel (nbrId, GetLink (index).phy->GetOperatingChannel ()); - rnr->AddTbttInformationField (nbrId); - rnr->SetBssid (nbrId, 0, GetLink (index).feManager->GetAddress ()); - rnr->SetShortSsid (nbrId, 0, 0); - rnr->SetBssParameters (nbrId, 0, 0); - rnr->SetPsd20MHz (nbrId, 0, 0); - rnr->SetMldParameters (nbrId, 0, 0, index, 0); + rnr.AddNbrApInfoField (); + std::size_t nbrId = rnr.GetNNbrApInfoFields () - 1; + rnr.SetOperatingChannel (nbrId, GetLink (index).phy->GetOperatingChannel ()); + rnr.AddTbttInformationField (nbrId); + rnr.SetBssid (nbrId, 0, GetLink (index).feManager->GetAddress ()); + rnr.SetShortSsid (nbrId, 0, 0); + rnr.SetBssParameters (nbrId, 0, 0); + rnr.SetPsd20MHz (nbrId, 0, 0); + rnr.SetMldParameters (nbrId, 0, 0, index, 0); } } return rnr; @@ -896,7 +896,10 @@ ApWifiMac::SendProbeResp (Mac48Address to, uint8_t linkId) * TBTT Information Length field set to 16 or higher, for each of the other APs * (if any) affiliated with the same AP MLD. (Sec. 35.3.4.1 of 802.11be D2.1.1) */ - probe.SetReducedNeighborReport (GetReducedNeighborReport (linkId)); + if (auto rnr = GetReducedNeighborReport (linkId); rnr.has_value ()) + { + probe.SetReducedNeighborReport (std::move (*rnr)); + } /* * If an AP affiliated with an AP MLD is not in a multiple BSSID set [..], the AP * shall include, in a Beacon frame or a Probe Response frame, which is not a @@ -1132,7 +1135,10 @@ ApWifiMac::SendOneBeacon (uint8_t linkId) * TBTT Information Length field set to 16 or higher, for each of the other APs * (if any) affiliated with the same AP MLD. (Sec. 35.3.4.1 of 802.11be D2.1.1) */ - beacon.SetReducedNeighborReport (GetReducedNeighborReport (linkId)); + if (auto rnr = GetReducedNeighborReport (linkId); rnr.has_value ()) + { + beacon.SetReducedNeighborReport (std::move (*rnr)); + } /* * If an AP affiliated with an AP MLD is not in a multiple BSSID set [..], the AP * shall include, in a Beacon frame or a Probe Response frame, which is not a diff --git a/src/wifi/model/ap-wifi-mac.h b/src/wifi/model/ap-wifi-mac.h index ac1b52d23..8110a11aa 100644 --- a/src/wifi/model/ap-wifi-mac.h +++ b/src/wifi/model/ap-wifi-mac.h @@ -315,12 +315,12 @@ private: std::optional GetMuEdcaParameterSet (void) const; /** * Return the Reduced Neighbor Report (RNR) element that the current AP sends - * on the given link + * on the given link, if one needs to be advertised. * * \param linkId the ID of the link to send the RNR element onto * \return the Reduced Neighbor Report element */ - Ptr GetReducedNeighborReport (uint8_t linkId) const; + std::optional GetReducedNeighborReport (uint8_t linkId) const; /** * Return the Multi-Link Element that the current AP includes in the management * frames of the given type it transmits on the given link. diff --git a/src/wifi/model/mgt-headers.cc b/src/wifi/model/mgt-headers.cc index 1adadcaac..945fd9b6b 100644 --- a/src/wifi/model/mgt-headers.cc +++ b/src/wifi/model/mgt-headers.cc @@ -527,11 +527,17 @@ MgtProbeResponseHeader::SetMuEdcaParameterSet (MuEdcaParameterSet&& muEdcaParame } void -MgtProbeResponseHeader::SetReducedNeighborReport (Ptr reducedNeighborReport) +MgtProbeResponseHeader::SetReducedNeighborReport (const ReducedNeighborReport& reducedNeighborReport) { m_reducedNeighborReport = reducedNeighborReport; } +void +MgtProbeResponseHeader::SetReducedNeighborReport (ReducedNeighborReport&& reducedNeighborReport) +{ + m_reducedNeighborReport = std::move (reducedNeighborReport); +} + void MgtProbeResponseHeader::SetMultiLinkElement (Ptr multiLinkElement) { @@ -550,7 +556,7 @@ MgtProbeResponseHeader::GetMuEdcaParameterSet (void) const return m_muEdcaParameterSet; } -Ptr +const std::optional& MgtProbeResponseHeader::GetReducedNeighborReport (void) const { return m_reducedNeighborReport; @@ -597,11 +603,11 @@ MgtProbeResponseHeader::GetSerializedSize (void) const if (m_htOperation.has_value ()) size += m_htOperation->GetSerializedSize (); if (m_vhtCapability.has_value ()) size += m_vhtCapability->GetSerializedSize (); if (m_vhtOperation.has_value ()) size += m_vhtOperation->GetSerializedSize (); + if (m_reducedNeighborReport.has_value ()) size += m_reducedNeighborReport->GetSerializedSize (); if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize (); if (m_heOperation.has_value ()) size += m_heOperation->GetSerializedSize (); if (m_muEdcaParameterSet.has_value ()) size += m_muEdcaParameterSet->GetSerializedSize (); if (m_ehtCapability.has_value ()) size += m_ehtCapability->GetSerializedSize (); - if (m_reducedNeighborReport != nullptr) size += m_reducedNeighborReport->GetSerializedSize (); if (m_multiLinkElement != nullptr) size += m_multiLinkElement->GetSerializedSize (); return size; } @@ -640,11 +646,11 @@ MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const if (m_htOperation.has_value ()) i = m_htOperation->Serialize (i); if (m_vhtCapability.has_value ()) i = m_vhtCapability->Serialize (i); if (m_vhtOperation.has_value ()) i = m_vhtOperation->Serialize (i); + if (m_reducedNeighborReport.has_value ()) i = m_reducedNeighborReport->Serialize (i); if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i); if (m_heOperation.has_value ()) i = m_heOperation->Serialize (i); if (m_muEdcaParameterSet.has_value ()) i = m_muEdcaParameterSet->Serialize (i); if (m_ehtCapability.has_value ()) i = m_ehtCapability->Serialize (i); - if (m_reducedNeighborReport != nullptr) i = m_reducedNeighborReport->Serialize (i); if (m_multiLinkElement != nullptr) i = m_multiLinkElement->Serialize (i); } @@ -667,12 +673,11 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start) i = WifiInformationElement::DeserializeIfPresent (m_htOperation, i); i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i); i = WifiInformationElement::DeserializeIfPresent (m_vhtOperation, i); + i = WifiInformationElement::DeserializeIfPresent (m_reducedNeighborReport, i); i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i); i = WifiInformationElement::DeserializeIfPresent (m_heOperation, i); i = WifiInformationElement::DeserializeIfPresent (m_muEdcaParameterSet, i); i = WifiInformationElement::DeserializeIfPresent (m_ehtCapability, i); - i = (m_reducedNeighborReport = Create ())->DeserializeIfPresent (tmp = i); - if (i.GetDistanceFrom (tmp) == 0) m_reducedNeighborReport = nullptr; i = (m_multiLinkElement = Create (WIFI_MAC_MGT_BEACON))->DeserializeIfPresent (tmp = i); if (i.GetDistanceFrom (tmp) == 0) m_multiLinkElement = nullptr; diff --git a/src/wifi/model/mgt-headers.h b/src/wifi/model/mgt-headers.h index 1d4a06e1d..f65f6fcf9 100644 --- a/src/wifi/model/mgt-headers.h +++ b/src/wifi/model/mgt-headers.h @@ -987,11 +987,11 @@ public: const std::optional& GetMuEdcaParameterSet (void) const; /** - * Return the Reduced Neighbor Report information element. + * Return the Reduced Neighbor Report information element, if present. * - * \return the Reduced Neighbor Report information element + * \return the Reduced Neighbor Report information element, if present */ - Ptr GetReducedNeighborReport (void) const; + const std::optional& GetReducedNeighborReport (void) const; /** * Return the Multi-Link Element information element, if present, or a null * pointer, otherwise. @@ -1162,7 +1162,11 @@ public: * * \param reducedNeighborReport the Reduced Neighbor Report information element */ - void SetReducedNeighborReport (Ptr reducedNeighborReport); + void SetReducedNeighborReport (const ReducedNeighborReport& reducedNeighborReport); + + /** \copydoc SetReducedNeighborReport */ + void SetReducedNeighborReport (ReducedNeighborReport&& reducedNeighborReport); + /** * Set the Multi-Link Element information element * @@ -1206,7 +1210,7 @@ private: std::optional m_edcaParameterSet; //!< EDCA Parameter Set std::optional m_muEdcaParameterSet; //!< MU EDCA Parameter Set std::optional m_ehtCapability; //!< EHT capabilities - Ptr m_reducedNeighborReport; //!< Reduced Neighbor Report information + std::optional m_reducedNeighborReport; //!< Reduced Neighbor Report information Ptr m_multiLinkElement; //!< Multi-Link Element }; diff --git a/src/wifi/model/wifi-assoc-manager.cc b/src/wifi/model/wifi-assoc-manager.cc index 2e3feb45d..e2d10e7f8 100644 --- a/src/wifi/model/wifi-assoc-manager.cc +++ b/src/wifi/model/wifi-assoc-manager.cc @@ -244,7 +244,7 @@ WifiAssocManager::GetSetupLinks (const StaWifiMac::ApInfo& apInfo) } bool -WifiAssocManager::CanSetupMultiLink (Ptr& mle, Ptr& rnr) +WifiAssocManager::CanSetupMultiLink (Ptr& mle, OptRnrConstRef& rnr) { NS_LOG_FUNCTION (this); @@ -274,7 +274,7 @@ WifiAssocManager::CanSetupMultiLink (Ptr& mle, PtrGetNNbrApInfoFields () == 0) + if (!rnr.has_value () || rnr->get ().GetNNbrApInfoFields () == 0) { NS_LOG_DEBUG ("No Reduced Neighbor Report Element in Beacon/Probe Response"); return false; diff --git a/src/wifi/model/wifi-assoc-manager.h b/src/wifi/model/wifi-assoc-manager.h index 763a7dc1b..e55448fa7 100644 --- a/src/wifi/model/wifi-assoc-manager.h +++ b/src/wifi/model/wifi-assoc-manager.h @@ -206,18 +206,20 @@ protected: */ void ScanningTimeout (void); + /// typedef for an optional const reference to a ReducedNeighborReport object + using OptRnrConstRef = std::optional>; + /** * Check whether 11be Multi-Link setup can be established with the current best AP. * * \param[out] mle pointer to the Multi-Link Element present in the * Beacon/Probe Response received from the best AP, if any. * Otherwise, the pointer is not modified. - * \param[out] rnr pointer to the Reduced Neighbor Report Element present in the - * Beacon/Probe Response received from the best AP, if any - * Otherwise, the pointer is not modified. + * \param[out] rnr const reference to the Reduced Neighbor Report Element present + * in the Beacon/Probe Response received from the best AP, if any. * \return whether 11be Multi-Link setup can be established with the current best AP */ - bool CanSetupMultiLink (Ptr& mle, Ptr& rnr); + bool CanSetupMultiLink (Ptr& mle, OptRnrConstRef& rnr); Ptr m_mac; ///< pointer to the STA wifi MAC diff --git a/src/wifi/model/wifi-default-assoc-manager.cc b/src/wifi/model/wifi-default-assoc-manager.cc index 772a4827d..47fbb7d0d 100644 --- a/src/wifi/model/wifi-default-assoc-manager.cc +++ b/src/wifi/model/wifi-default-assoc-manager.cc @@ -106,7 +106,7 @@ WifiDefaultAssocManager::EndScanning (void) NS_LOG_FUNCTION (this); Ptr mle; - Ptr rnr; + OptRnrConstRef rnr; std::list apList; // If multi-link setup is not possible, just call ScanningTimeout() and return @@ -157,7 +157,7 @@ WifiDefaultAssocManager::EndScanning (void) while (apIt != apList.end ()) { - auto apChannel = rnr->GetOperatingChannel (apIt->m_nbrApInfoId); + auto apChannel = rnr->get ().GetOperatingChannel (apIt->m_nbrApInfoId); // we cannot setup a link with this affiliated AP if this PHY object is // constrained to operate in the current PHY band and this affiliated AP @@ -171,13 +171,13 @@ WifiDefaultAssocManager::EndScanning (void) // if we get here, it means we can setup a link with this affiliated AP // set the BSSID for this link - Mac48Address bssid = rnr->GetBssid (apIt->m_nbrApInfoId, apIt->m_tbttInfoFieldId); + Mac48Address bssid = rnr->get ().GetBssid (apIt->m_nbrApInfoId, apIt->m_tbttInfoFieldId); NS_LOG_DEBUG ("Setting BSSID=" << bssid << " for link " << +linkId); m_mac->SetBssid (bssid, linkId); // store AP MLD MAC address in the WifiRemoteStationManager associated with // the link requested to setup m_mac->GetWifiRemoteStationManager (linkId)->SetMldAddress (bssid, mle->GetMldMacAddress ()); - setupLinks.push_back ({linkId, rnr->GetLinkId (apIt->m_nbrApInfoId, apIt->m_tbttInfoFieldId)}); + setupLinks.push_back ({linkId, rnr->get ().GetLinkId (apIt->m_nbrApInfoId, apIt->m_tbttInfoFieldId)}); // switch this link to using the channel used by a reported AP // TODO check if the STA only supports a narrower channel width