wifi: Fix allocation of AIDs for AP MLDs

This commit is contained in:
Stefano Avallone
2024-09-25 17:57:06 +02:00
parent 1a1d3cd4cb
commit 50652c429f
7 changed files with 50 additions and 23 deletions

View File

@@ -295,6 +295,8 @@ WifiMloUdpTest::DoSetup()
m_sink = nullptr; // other cases are not supported
}
m_startAid = m_apMac->GetNextAssociationId();
// schedule association/ML setup for one station at a time
m_apMac->TraceConnectWithoutContext("AssociatedSta",
MakeCallback(&WifiMloUdpTest::SetSsid, this));

View File

@@ -209,7 +209,8 @@ ApWifiMac::GetTimeAccessParamsChecker()
}
ApWifiMac::ApWifiMac()
: m_enableBeaconGeneration(false)
: m_enableBeaconGeneration(false),
m_grpAddrBuIndicExp(0)
{
NS_LOG_FUNCTION(this);
m_beaconTxop = CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BEACON"));
@@ -342,6 +343,14 @@ ApWifiMac::DoCompleteConfig()
{
GetLink(linkId).channelAccessManager->Add(m_beaconTxop);
}
// the value 'exp' for the Group Addressed BU Indication Exponent must be such that 2^(exp+1)-1
// is at least equal to N-1, where N is the number of links (Sec. 35.3.15.1 of 802.11be D7.0).
// The max value for Group Addressed BU Indication Exponent is 3 (encoded in a 2-bit subfield)
while ((m_grpAddrBuIndicExp < 3) && ((1 << (m_grpAddrBuIndicExp + 1)) - 1 < GetNLinks() - 1))
{
++m_grpAddrBuIndicExp;
}
}
Ptr<WifiMacQueue>
@@ -1153,6 +1162,7 @@ ApWifiMac::GetEhtOperation(uint8_t linkId) const
}
operation.SetMaxRxNss(maxSpatialStream, 0, WIFI_EHT_MAX_MCS_INDEX);
operation.SetMaxTxNss(maxSpatialStream, 0, WIFI_EHT_MAX_MCS_INDEX);
operation.m_params.grpBuExp = m_grpAddrBuIndicExp;
return operation;
}
@@ -2672,8 +2682,12 @@ ApWifiMac::GetNextAssociationId() const
{
const auto& links = GetLinks();
// if this is an AP MLD, AIDs from 1 to N, where N is 2^(Group_addr_BU_Indic_Exp + 1) - 1
// shall not be allocated (see Section 35.3.15.1 of 802.11be D7.0)
const uint16_t startAid = links.size() == 1 ? 1 : (1 << (m_grpAddrBuIndicExp + 1));
// Return the first AID value between 1 and 2007 that is free for all the links
for (uint16_t nextAid = 1; nextAid <= 2007; ++nextAid)
for (uint16_t nextAid = startAid; nextAid <= 2007; ++nextAid)
{
if (std::none_of(links.cbegin(), links.cend(), [&](auto&& idLinkPair) {
return GetStaList(idLinkPair.first).contains(nextAid);

View File

@@ -123,6 +123,9 @@ class ApWifiMac : public WifiMac
*/
uint16_t GetAssociationId(Mac48Address addr, uint8_t linkId) const;
/// @return the next Association ID to be allocated by the AP
uint16_t GetNextAssociationId() const;
/**
* Get the ID of a link (if any) that has been setup with the station having the given MAC
* address. The address can be either a link address or an MLD address. In the former case,
@@ -623,11 +626,6 @@ class ApWifiMac : public WifiMac
void DoDispose() override;
void DoInitialize() override;
/**
* @return the next Association ID to be allocated by the AP
*/
uint16_t GetNextAssociationId() const;
Ptr<Txop> m_beaconTxop; //!< Dedicated Txop for beacons
bool m_enableBeaconGeneration; //!< Flag whether beacons are being generated
Time m_beaconInterval; //!< Beacon interval
@@ -639,6 +637,7 @@ class ApWifiMac : public WifiMac
Time m_bsrLifetime; //!< Lifetime of Buffer Status Reports
/// transition timeout events running for EMLSR clients
std::map<Mac48Address, EventId> m_transitionTimeoutEvents;
uint8_t m_grpAddrBuIndicExp; //!< Group Addressed BU Indication Exponent of EHT Operation IE
Ptr<ApEmlsrManager> m_apEmlsrManager; ///< AP EMLSR Manager
Ptr<GcrManager> m_gcrManager; //!< GCR Manager

View File

@@ -485,6 +485,8 @@ EmlsrOperationsTestBase::DoSetup()
m_ulSockets.back().SetProtocol(1);
}
m_startAid = m_apMac->GetNextAssociationId();
// schedule ML setup for one station at a time
m_apMac->TraceConnectWithoutContext(
"AssociatedSta",
@@ -538,15 +540,15 @@ EmlsrOperationsTestBase::StaAssociated(uint16_t aid, Mac48Address /* addr */)
// trigger establishment of BA agreement with AP as originator
Simulator::Schedule(delay, [=, this]() {
m_apMac->GetDevice()->GetNode()->AddApplication(
GetApplication(DOWNLINK, aid - 1, 4, 1000, m_establishBaDl.front()));
GetApplication(DOWNLINK, aid - m_startAid, 4, 1000, m_establishBaDl.front()));
});
}
else if (!m_establishBaUl.empty())
{
// trigger establishment of BA agreement with AP as recipient
Simulator::Schedule(delay, [=, this]() {
m_staMacs[aid - 1]->GetDevice()->GetNode()->AddApplication(
GetApplication(UPLINK, aid - 1, 4, 1000, m_establishBaUl.front()));
m_staMacs[aid - m_startAid]->GetDevice()->GetNode()->AddApplication(
GetApplication(UPLINK, aid - m_startAid, 4, 1000, m_establishBaUl.front()));
});
}
else
@@ -573,20 +575,20 @@ EmlsrOperationsTestBase::BaEstablishedDl(Mac48Address recipient,
// trigger establishment of BA agreement with AP as originator
Simulator::Schedule(delay, [=, this]() {
m_apMac->GetDevice()->GetNode()->AddApplication(
GetApplication(DOWNLINK, aid - 1, 4, 1000, *std::next(it)));
GetApplication(DOWNLINK, aid - m_startAid, 4, 1000, *std::next(it)));
});
}
else if (!m_establishBaUl.empty())
{
// trigger establishment of BA agreement with AP as recipient
Simulator::Schedule(delay, [=, this]() {
m_staMacs[aid - 1]->GetDevice()->GetNode()->AddApplication(
GetApplication(UPLINK, aid - 1, 4, 1000, m_establishBaUl.front()));
m_staMacs[aid - m_startAid]->GetDevice()->GetNode()->AddApplication(
GetApplication(UPLINK, aid - m_startAid, 4, 1000, m_establishBaUl.front()));
});
}
else
{
Simulator::Schedule(delay, [=, this]() { SetSsid(aid - 1 + 1); });
Simulator::Schedule(delay, [=, this]() { SetSsid(aid - m_startAid + 1); });
}
}

View File

@@ -232,6 +232,7 @@ class EmlsrOperationsTestBase : public TestCase
std::vector<Ptr<StaWifiMac>> m_staMacs; ///< MACs of the non-AP MLDs
std::vector<PacketSocketAddress> m_dlSockets; ///< packet socket address for DL traffic
std::vector<PacketSocketAddress> m_ulSockets; ///< packet socket address for UL traffic
uint16_t m_startAid{1}; ///< first AID to allocate to stations
uint16_t m_lastAid{0}; ///< AID of last associated station
Time m_duration{0}; ///< simulation duration
std::map<std::size_t, std::shared_ptr<EmlsrMainPhySwitchTrace>>

View File

@@ -270,7 +270,7 @@ AidAssignmentTest::AidAssignmentTest(const std::vector<std::set<uint8_t>>& linkI
m_linkChannels({"{36, 0, BAND_5GHZ, 0}", "{1, 0, BAND_6GHZ, 0}", "{2, 0, BAND_2_4GHZ, 0}"}),
m_linkIds(linkIds),
m_assocType(assocType),
m_expectedAid(1) // AID for first station
m_expectedAid(1) // AID for first station (to be updated in case of AP MLD)
{
}
@@ -363,12 +363,16 @@ AidAssignmentTest::DoSetup()
"Assoc",
MakeCallback(&AidAssignmentTest::SetSsid, this).Bind(DynamicCast<StaWifiMac>(mac)));
}
auto apMac = StaticCast<ApWifiMac>(StaticCast<WifiNetDevice>(apDevice.Get(0))->GetMac());
m_expectedAid = m_startAid = apMac->GetNextAssociationId();
}
void
AidAssignmentTest::SetSsid(Ptr<StaWifiMac> staMac, Mac48Address /* apAddr */)
{
const auto aid = staMac->GetAssociationId();
std::size_t index = aid - m_startAid;
std::stringstream linksStr;
const auto setupLinks = staMac->GetSetupLinkIds();
@@ -382,19 +386,17 @@ AidAssignmentTest::SetSsid(Ptr<StaWifiMac> staMac, Mac48Address /* apAddr */)
// if ML setup is performed, check that the requested links have been setup; otherwise, link 0
// only is setup
const auto expectedLinks =
(m_assocType == WifiAssocType::ML_SETUP ? m_linkIds.at(aid - 1)
(m_assocType == WifiAssocType::ML_SETUP ? m_linkIds.at(index)
: std::set{SINGLE_LINK_OP_ID});
NS_TEST_EXPECT_MSG_EQ((staMac->GetSetupLinkIds() == expectedLinks),
true,
"Unexpected set of setup links " << linksStr.str());
if (m_expectedAid < m_staDevices.GetN())
if (++index < m_staDevices.GetN())
{
// let the next STA associate with the AP
StaticCast<WifiNetDevice>(m_staDevices.Get(m_expectedAid))
->GetMac()
->SetSsid(Ssid("ns-3-ssid"));
StaticCast<WifiNetDevice>(m_staDevices.Get(index))->GetMac()->SetSsid(Ssid("ns-3-ssid"));
++m_expectedAid;
}
else
@@ -409,7 +411,9 @@ AidAssignmentTest::DoRun()
Simulator::Stop(Seconds(5)); // simulation will stop earlier if all STAs complete association
Simulator::Run();
NS_TEST_EXPECT_MSG_EQ(m_expectedAid, m_staDevices.GetN(), "Not all STAs completed association");
NS_TEST_EXPECT_MSG_EQ(m_expectedAid,
m_startAid + m_staDevices.GetN() - 1,
"Not all STAs completed association");
for (uint32_t i = 0; i < m_staDevices.GetN(); ++i)
{
@@ -432,6 +436,7 @@ MultiLinkOperationsTestBase::MultiLinkOperationsTestBase(const std::string& name
m_assocType(baseParams.assocType),
m_staMacs(nStations),
m_nStations(nStations),
m_startAid(1),
m_lastAid(0),
m_rxPkts(nStations + 1)
{
@@ -780,6 +785,8 @@ MultiLinkOperationsTestBase::DoSetup()
m_apMac->TraceConnectWithoutContext("AssociatedSta",
MakeCallback(&MultiLinkOperationsTestBase::SetSsid, this));
m_staMacs[0]->SetSsid(Ssid("ns-3-ssid"));
m_startAid = m_apMac->GetNextAssociationId();
}
Ptr<PacketSocketClient>
@@ -812,9 +819,9 @@ MultiLinkOperationsTestBase::SetSsid(uint16_t aid, Mac48Address /* addr */)
m_lastAid = aid;
// make the next STA to start ML discovery & setup
if (aid < m_nStations)
if (const std::size_t count = aid - m_startAid + 1; count < m_nStations)
{
m_staMacs[aid]->SetSsid(Ssid("ns-3-ssid"));
m_staMacs[count]->SetSsid(Ssid("ns-3-ssid"));
return;
}
// stop generation of beacon frames in order to avoid interference

View File

@@ -169,6 +169,7 @@ class AidAssignmentTest : public TestCase
const std::vector<std::set<uint8_t>> m_linkIds; //!< link IDs for all non-AP STAs/MLDs
WifiAssocType m_assocType; //!< association type
NetDeviceContainer m_staDevices; //!< non-AP STAs/MLDs devices
uint16_t m_startAid; //!< first AID to allocate to stations
uint16_t m_expectedAid; //!< expected AID for current non-AP STA/MLD
};
@@ -302,6 +303,7 @@ class MultiLinkOperationsTestBase : public TestCase
Ptr<ApWifiMac> m_apMac; ///< AP wifi MAC
std::vector<Ptr<StaWifiMac>> m_staMacs; ///< STA wifi MACs
uint8_t m_nStations; ///< number of stations to create
uint16_t m_startAid; ///< first AID to allocate to stations
uint16_t m_lastAid; ///< AID of last associated station
Time m_duration{Seconds(1)}; ///< simulation duration
std::vector<std::size_t> m_rxPkts; ///< number of packets received at application layer