Skip to content

Commit

Permalink
wifi: AP does not use links that have not been setup to transmit to a…
Browse files Browse the repository at this point in the history
… station
  • Loading branch information
stavallo authored and Stefano Avallone committed Dec 31, 2022
1 parent 3c9e2fd commit 6388624
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 18 deletions.
80 changes: 67 additions & 13 deletions src/wifi/model/ap-wifi-mac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "msdu-aggregator.h"
#include "qos-txop.h"
#include "reduced-neighbor-report.h"
#include "wifi-mac-queue-scheduler.h"
#include "wifi-mac-queue.h"
#include "wifi-net-device.h"
#include "wifi-phy.h"
Expand Down Expand Up @@ -1014,23 +1015,20 @@ ApWifiMac::GetAssocResp(Mac48Address to, uint8_t linkId)
return assoc;
}

void
ApWifiMac::SetAid(MgtAssocResponseHeader& assoc, const Mac48Address& to, uint8_t linkId)
ApWifiMac::LinkIdStaAddrMap
ApWifiMac::GetLinkIdStaAddrMap(MgtAssocResponseHeader& assoc,
const Mac48Address& to,
uint8_t linkId)
{
NS_LOG_FUNCTION(this << to << +linkId);

// find all the links to setup (i.e., those for which status code is success)
std::list<std::reference_wrapper<MgtAssocResponseHeader>> assocResponses;
std::map<uint8_t /* link ID */, Mac48Address> linkIdStaAddrMap;

if (assoc.GetStatusCode().IsSuccess())
{
assocResponses.push_back(std::ref(assoc));
linkIdStaAddrMap[linkId] = to;
}

const auto& mle = assoc.GetMultiLinkElement();
if (mle.has_value())
if (const auto& mle = assoc.GetMultiLinkElement())
{
const auto staMldAddress = GetWifiRemoteStationManager(linkId)->GetMldAddress(to);
NS_ABORT_MSG_IF(!staMldAddress.has_value(),
Expand All @@ -1041,7 +1039,6 @@ ApWifiMac::SetAid(MgtAssocResponseHeader& assoc, const Mac48Address& to, uint8_t
if (perStaProfile.HasAssocResponse() &&
perStaProfile.GetAssocResponse().GetStatusCode().IsSuccess())
{
assocResponses.emplace_back(perStaProfile.GetAssocResponse());
uint8_t otherLinkId = perStaProfile.GetLinkId();
auto staAddress = GetWifiRemoteStationManager(otherLinkId)
->GetAffiliatedStaAddress(*staMldAddress);
Expand All @@ -1055,7 +1052,13 @@ ApWifiMac::SetAid(MgtAssocResponseHeader& assoc, const Mac48Address& to, uint8_t
}
}

if (assocResponses.empty())
return linkIdStaAddrMap;
}

void
ApWifiMac::SetAid(MgtAssocResponseHeader& assoc, const LinkIdStaAddrMap& linkIdStaAddrMap)
{
if (linkIdStaAddrMap.empty())
{
// no link to setup, nothing to do
return;
Expand Down Expand Up @@ -1162,9 +1165,21 @@ ApWifiMac::SetAid(MgtAssocResponseHeader& assoc, const Mac48Address& to, uint8_t
// Element must not contain the AID field. We set the AID field in such
// Association Responses anyway, in order to ease future implementation of
// the inheritance mechanism.
for (auto& assocResp : assocResponses)
if (assoc.GetStatusCode().IsSuccess())
{
assocResp.get().SetAssociationId(aid);
assoc.SetAssociationId(aid);
}
if (const auto& mle = assoc.GetMultiLinkElement())
{
for (std::size_t idx = 0; idx < mle->GetNPerStaProfileSubelements(); idx++)
{
if (const auto& perStaProfile = mle->GetPerStaProfile(idx);
perStaProfile.HasAssocResponse() &&
perStaProfile.GetAssocResponse().GetStatusCode().IsSuccess())
{
perStaProfile.GetAssocResponse().SetAssociationId(aid);
}
}
}
}

Expand Down Expand Up @@ -1194,7 +1209,13 @@ ApWifiMac::SendAssocResp(Mac48Address to, bool isReassoc, uint8_t linkId)
assoc.SetMultiLinkElement(GetMultiLinkElement(linkId, hdr.GetType(), to));
}

SetAid(assoc, to, linkId);
auto linkIdStaAddrMap = GetLinkIdStaAddrMap(assoc, to, linkId);
SetAid(assoc, linkIdStaAddrMap);

if (GetNLinks() > 1)
{
ConfigQueueScheduler(linkIdStaAddrMap, to, linkId);
}

Ptr<Packet> packet = Create<Packet>();
packet->AddHeader(assoc);
Expand All @@ -1220,6 +1241,39 @@ 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<uint8_t> 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)
{
Expand Down
35 changes: 30 additions & 5 deletions src/wifi/model/ap-wifi-mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,20 +278,45 @@ class ApWifiMac : public WifiMac
* \return the Association Response frame
*/
MgtAssocResponseHeader GetAssocResp(Mac48Address to, uint8_t linkId);
/// Map of (link ID, remote STA address) of the links to setup
using LinkIdStaAddrMap = std::map<uint8_t, Mac48Address>;
/**
* Set the AID field of the given Association Response frame, which is going
* to be sent to the STA with the given address on the given link. In case of
* Set the AID field of the given Association Response frame. In case of
* multi-link setup, the selected AID value must be assigned to all the STAs
* corresponding to the setup links. The AID value is selected among the AID
* values that are possibly already assigned to the STAs affiliated with the
* non-AP MLD we are associating with. If no STA has an assigned AID value,
* a new AID value is selected.
*
* \param assoc the given Association Response frame
* \param to the address of the STA receiving the Association Response frame
* \param linkId the ID of the given link
* \param linkIdStaAddrMap a map of (link ID, remote STA address) of the links to setup
*/
void SetAid(MgtAssocResponseHeader& assoc, const LinkIdStaAddrMap& linkIdStaAddrMap);
/**
* Get a map of (link ID, remote STA address) of the links to setup. Information
* is taken from the given Association Response that is sent over the given link
* to the given station.
*
* \param assoc the given Association Response frame
* \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 sent
* \return a map of (link ID, remote STA address) of the links to setup
*/
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 SetAid(MgtAssocResponseHeader& assoc, const Mac48Address& to, uint8_t linkId);
void ConfigQueueScheduler(const LinkIdStaAddrMap& linkIdStaAddrMap,
const Mac48Address& to,
uint8_t linkId);
/**
* Forward an association or a reassociation response packet to the DCF/EDCA.
*
Expand Down

0 comments on commit 6388624

Please sign in to comment.