diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index d9a9ed2c9..bae3efac9 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -1269,11 +1269,6 @@ ApWifiMac::SendAssocResp(Mac48Address to, bool isReassoc, uint8_t linkId) auto linkIdStaAddrMap = GetLinkIdStaAddrMap(assoc, to, linkId); SetAid(assoc, linkIdStaAddrMap); - if (GetNLinks() > 1) - { - ConfigQueueScheduler(linkIdStaAddrMap, to, linkId); - } - Ptr packet = Create(); packet->AddHeader(assoc); @@ -1298,39 +1293,6 @@ ApWifiMac::SendAssocResp(Mac48Address to, bool isReassoc, uint8_t linkId) } } -void -ApWifiMac::ConfigQueueScheduler(const LinkIdStaAddrMap& linkIdStaAddrMap, - const Mac48Address& to, - uint8_t linkId) -{ - NS_LOG_FUNCTION(this << to << +linkId); - - // get a list of the IDs of the links to setup - std::list linkIds; - std::transform(linkIdStaAddrMap.cbegin(), - linkIdStaAddrMap.cend(), - std::back_inserter(linkIds), - [](auto&& linkIdStaAddrPair) { return linkIdStaAddrPair.first; }); - - // get the MLD address of the STA, if affiliated with a non-AP MLD, or the STA address - auto staAddr = to; - if (auto mldAddr = GetWifiRemoteStationManager(linkId)->GetMldAddress(to)) - { - staAddr = *mldAddr; - } - - // configure the queue scheduler to only use the links that have been setup for - // transmissions to this station - for (const auto& [acIndex, wifiAc] : wifiAcList) - { - for (auto tid : {wifiAc.GetLowTid(), wifiAc.GetHighTid()}) - { - WifiContainerQueueId queueId(WIFI_QOSDATA_UNICAST_QUEUE, staAddr, tid); - m_scheduler->SetLinkIds(acIndex, queueId, linkIds); - } - } -} - void ApWifiMac::SendOneBeacon(uint8_t linkId) { diff --git a/src/wifi/model/ap-wifi-mac.h b/src/wifi/model/ap-wifi-mac.h index 51b5c503c..9dbf32ef8 100644 --- a/src/wifi/model/ap-wifi-mac.h +++ b/src/wifi/model/ap-wifi-mac.h @@ -328,18 +328,6 @@ class ApWifiMac : public WifiMac LinkIdStaAddrMap GetLinkIdStaAddrMap(MgtAssocResponseHeader& assoc, const Mac48Address& to, uint8_t linkId); - /** - * Configure the queue scheduler so that frames stored in the container queues associated - * with the station which we are sending an Association Response frame to are only transmitted - * on the setup links. - * - * \param linkIdStaAddrMap a map of (link ID, remote STA address) of the links to setup - * \param to the Receiver Address (RA) of the Association Response frame - * \param linkId the ID of the link on which the Association Response frame is being sent - */ - void ConfigQueueScheduler(const LinkIdStaAddrMap& linkIdStaAddrMap, - const Mac48Address& to, - uint8_t linkId); /** * Forward an association or a reassociation response packet to the DCF/EDCA. * diff --git a/src/wifi/model/wifi-mac-queue-scheduler-impl.h b/src/wifi/model/wifi-mac-queue-scheduler-impl.h index 14df9cdd6..0ad3b7256 100644 --- a/src/wifi/model/wifi-mac-queue-scheduler-impl.h +++ b/src/wifi/model/wifi-mac-queue-scheduler-impl.h @@ -74,10 +74,6 @@ class WifiMacQueueSchedulerImpl : public WifiMacQueueScheduler const WifiContainerQueueId& prevQueueId) final; /** \copydoc ns3::WifiMacQueueScheduler::GetLinkIds */ std::list GetLinkIds(AcIndex ac, Ptr mpdu) final; - /** \copydoc ns3::WifiMacQueueScheduler::SetLinkIds */ - void SetLinkIds(AcIndex ac, - const WifiContainerQueueId& queueId, - const std::list& linkIds) final; /** \copydoc ns3::WifiMacQueueScheduler::HasToDropBeforeEnqueue */ Ptr HasToDropBeforeEnqueue(AcIndex ac, Ptr mpdu) final; /** \copydoc ns3::WifiMacQueueScheduler::NotifyEnqueue */ @@ -305,26 +301,38 @@ WifiMacQueueSchedulerImpl::InitQueueInfo(AcIndex ac, Ptr(queueId); - auto address = std::get(queueId); - if (queueType == WIFI_MGT_QUEUE || - (queueType == WIFI_CTL_QUEUE && GetMac() && address != GetMac()->GetAddress()) || - queueType == WIFI_QOSDATA_BROADCAST_QUEUE) + if (GetMac() && GetMac()->GetNLinks() > 1 && + mpdu->GetHeader().GetAddr2() == GetMac()->GetAddress()) { - // these queue types are associated with just one link - NS_ASSERT(GetMac()); - auto linkId = GetMac()->GetLinkIdByAddress(address); - NS_ASSERT(linkId.has_value()); - queueInfoIt->second.linkIds = {*linkId}; + // this is an MLD and the TA field of the frame contains the MLD address, + // which means that the frame can be sent on multiple links + + // this assert checks that association (ML setup) has been established + // between sender and receiver (unless the receiver is the broadcast address) + const auto rxAddr = mpdu->GetHeader().GetAddr1(); + NS_ASSERT_MSG(GetMac()->CanForwardPacketsTo(rxAddr), + "Cannot forward frame to " << rxAddr); + + // we have to include all the links in case of broadcast frame (we are an AP) + // and the links that have been setup with the receiver in case of unicast frame + for (uint8_t linkId = 0; linkId < GetMac()->GetNLinks(); linkId++) + { + if (rxAddr.IsGroup() || + GetMac()->GetWifiRemoteStationManager(linkId)->GetAffiliatedStaAddress(rxAddr)) + { + queueInfoIt->second.linkIds.emplace_back(linkId); + } + } } else { - // all available links can be used. Note that AP's and STA's MACs may update - // the set of links upon association - const uint8_t nLinks = GetMac() ? GetMac()->GetNLinks() : 1; // make unit test happy - queueInfoIt->second.linkIds.resize(nLinks); - std::iota(queueInfoIt->second.linkIds.begin(), queueInfoIt->second.linkIds.end(), 0); + // the TA field of the frame contains a link address, which means that the + // frame can only be sent on the corresponding link + auto linkId = GetMac() ? GetMac()->GetLinkIdByAddress(mpdu->GetHeader().GetAddr2()) + : SINGLE_LINK_OP_ID; // make unit test happy + NS_ASSERT(linkId.has_value()); + queueInfoIt->second.linkIds = {*linkId}; } } return queueInfoIt; @@ -379,17 +387,6 @@ WifiMacQueueSchedulerImpl::GetLinkIds(AcIndex ac, Ptrsecond.linkIds; } -template -void -WifiMacQueueSchedulerImpl::SetLinkIds(AcIndex ac, - const WifiContainerQueueId& queueId, - const std::list& linkIds) -{ - NS_LOG_FUNCTION(this << +ac); - auto [queueInfoIt, ret] = m_perAcInfo[ac].queueInfoMap.insert({queueId, QueueInfo()}); - queueInfoIt->second.linkIds = linkIds; -} - template std::optional WifiMacQueueSchedulerImpl::GetNext(AcIndex ac, uint8_t linkId) diff --git a/src/wifi/model/wifi-mac-queue-scheduler.h b/src/wifi/model/wifi-mac-queue-scheduler.h index 5839e756a..784d298a7 100644 --- a/src/wifi/model/wifi-mac-queue-scheduler.h +++ b/src/wifi/model/wifi-mac-queue-scheduler.h @@ -89,17 +89,6 @@ class WifiMacQueueScheduler : public Object * \return the list of the IDs of the links the given MPDU can be sent over */ virtual std::list GetLinkIds(AcIndex ac, Ptr mpdu) = 0; - /** - * Set the list of the IDs of the links the given container queue (belonging to - * the given Access Category) is associated with. - * - * \param ac the given Access Category - * \param queueId the given container queue - * \param linkIds the list of the IDs of the links the given container queue is associated with - */ - virtual void SetLinkIds(AcIndex ac, - const WifiContainerQueueId& queueId, - const std::list& linkIds) = 0; /** * Check whether an MPDU has to be dropped before enqueuing the given MPDU.