wifi: Add StaWifiMac Multi-link Probe Request generation

This commit is contained in:
Sharan Naribole
2024-05-06 17:04:49 +02:00
committed by Stefano Avallone
parent 9c49377716
commit ea474ecbbc
3 changed files with 116 additions and 22 deletions

View File

@@ -349,18 +349,9 @@ StaWifiMac::IsEmlsrLink(uint8_t linkId) const
return GetLink(linkId).emlsrEnabled;
}
void
StaWifiMac::SendProbeRequest(uint8_t linkId)
MgtProbeRequestHeader
StaWifiMac::GetProbeRequest(uint8_t linkId) const
{
NS_LOG_FUNCTION(this << linkId);
WifiMacHeader hdr;
hdr.SetType(WIFI_MAC_MGT_PROBE_REQUEST);
hdr.SetAddr1(Mac48Address::GetBroadcast());
hdr.SetAddr2(GetFrameExchangeManager(linkId)->GetAddress());
hdr.SetAddr3(Mac48Address::GetBroadcast());
hdr.SetDsNotFrom();
hdr.SetDsNotTo();
Ptr<Packet> packet = Create<Packet>();
MgtProbeRequestHeader probe;
probe.Get<Ssid>() = GetSsid();
auto supportedRates = GetSupportedRates(linkId);
@@ -387,7 +378,45 @@ StaWifiMac::SendProbeRequest(uint8_t linkId)
{
probe.Get<EhtCapabilities>() = GetEhtCapabilities(linkId);
}
packet->AddHeader(probe);
return probe;
}
MgtProbeRequestHeader
StaWifiMac::GetMultiLinkProbeRequest(uint8_t linkId,
const std::vector<uint8_t>& apLinkIds,
std::optional<uint8_t> apMldId) const
{
NS_LOG_FUNCTION(this << linkId << apMldId.has_value());
auto req = GetProbeRequest(linkId);
if (GetNLinks() == 1)
{
// Single link (non-EHT) device
NS_LOG_DEBUG("Single link device does not support Multi-link operation, not including "
"Multi-link Element");
return req;
}
req.Get<MultiLinkElement>() = GetProbeReqMultiLinkElement(apLinkIds, apMldId);
return req;
}
void
StaWifiMac::EnqueueProbeRequest(const MgtProbeRequestHeader& probeReq,
uint8_t linkId,
const Mac48Address& addr1,
const Mac48Address& addr3)
{
NS_LOG_FUNCTION(this << linkId << addr1 << addr3);
WifiMacHeader hdr(WIFI_MAC_MGT_PROBE_REQUEST);
hdr.SetAddr1(addr1);
hdr.SetAddr2(GetFrameExchangeManager(linkId)->GetAddress());
hdr.SetAddr3(addr3);
hdr.SetDsNotFrom();
hdr.SetDsNotTo();
auto packet = Create<Packet>();
packet->AddHeader(probeReq);
if (!GetQosSupported())
{
@@ -460,7 +489,7 @@ StaWifiMac::GetAssociationRequest(bool isReassoc, uint8_t linkId) const
}
MultiLinkElement
StaWifiMac::GetMultiLinkElement(bool isReassoc, uint8_t linkId) const
StaWifiMac::GetBasicMultiLinkElement(bool isReassoc, uint8_t linkId) const
{
NS_LOG_FUNCTION(this << isReassoc << +linkId);
@@ -538,6 +567,30 @@ StaWifiMac::GetMultiLinkElement(bool isReassoc, uint8_t linkId) const
return multiLinkElement;
}
MultiLinkElement
StaWifiMac::GetProbeReqMultiLinkElement(const std::vector<uint8_t>& apLinkIds,
std::optional<uint8_t> apMldId) const
{
// IEEE 802.11be D6.0 9.4.2.321.3
MultiLinkElement mle(MultiLinkElement::PROBE_REQUEST_VARIANT);
if (apMldId.has_value())
{
mle.SetApMldId(*apMldId);
}
for (const auto apLinkId : apLinkIds)
{
mle.AddPerStaProfileSubelement();
auto& perStaProfile = mle.GetPerStaProfile(mle.GetNPerStaProfileSubelements() - 1);
perStaProfile.SetLinkId(apLinkId);
// Current support limited to Complete Profile request per link ID
// TODO: Add support for Partial Per-STA Profile request
perStaProfile.SetCompleteProfile();
};
return mle;
}
std::vector<TidToLinkMapping>
StaWifiMac::GetTidToLinkMappingElements(WifiTidToLinkMappingNegSupport apNegSupport)
{
@@ -647,7 +700,7 @@ StaWifiMac::SendAssociationRequest(bool isReassoc)
GetWifiRemoteStationManager(linkId)->GetMldAddress(*link.bssid).has_value())
{
auto addMle = [&](auto&& frame) {
frame.template Get<MultiLinkElement>() = GetMultiLinkElement(isReassoc, linkId);
frame.template Get<MultiLinkElement>() = GetBasicMultiLinkElement(isReassoc, linkId);
};
std::visit(addMle, frame);

View File

@@ -204,11 +204,38 @@ class StaWifiMac : public WifiMac
Ptr<EmlsrManager> GetEmlsrManager() const;
/**
* Enqueue a probe request packet for transmission on the given link.
* Get the frame body of the Probe Request to transmit on the given link.
*
* @param linkId the ID of the given link
* @return the Probe Request frame body
*/
void SendProbeRequest(uint8_t linkId);
MgtProbeRequestHeader GetProbeRequest(uint8_t linkId) const;
/**
* Get the frame body of the Multi-Link Probe Request to transmit on the given link.
*
* @param linkId the ID of the given link
* @param apLinkIds ID of the links on which the requested APs, affiliated with the
* AP MLD, operate
* @param apMldId the AP MLD ID to include in the Common Info field
* @return the Multi-Link Probe Request frame body
*/
MgtProbeRequestHeader GetMultiLinkProbeRequest(uint8_t linkId,
const std::vector<uint8_t>& apLinkIds,
std::optional<uint8_t> apMldId) const;
/**
* Enqueue the given probe request packet for transmission on the given link.
*
* @param probeReq the given Probe Request frame body
* @param linkId the ID of the given link
* @param addr1 the MAC address for the Address1 field
* @param addr3 the MAC address for the Address3 field
*/
void EnqueueProbeRequest(const MgtProbeRequestHeader& probeReq,
uint8_t linkId,
const Mac48Address& addr1 = Mac48Address::GetBroadcast(),
const Mac48Address& addr3 = Mac48Address::GetBroadcast());
/**
* This method is called after wait beacon timeout or wait probe request timeout has
@@ -474,6 +501,7 @@ class StaWifiMac : public WifiMac
* @return true if we are waiting for an association response from an AP, false otherwise
*/
bool IsWaitAssocResp() const;
/**
* This method is called after we have not received a beacon from the AP on any link.
*/
@@ -497,14 +525,24 @@ class StaWifiMac : public WifiMac
*/
AllSupportedRates GetSupportedRates(uint8_t linkId) const;
/**
* Return the Multi-Link Element to include in the management frames transmitted
* Return the Basic Multi-Link Element to include in the management frames transmitted
* on the given link
*
* @param isReassoc whether the Multi-Link Element is included in a Reassociation Request
* @param isReassoc whether the Basic Multi-Link Element is included in a Reassociation Request
* @param linkId the ID of the given link
* @return the Multi-Link Element
* @return the Basic Multi-Link Element
*/
MultiLinkElement GetMultiLinkElement(bool isReassoc, uint8_t linkId) const;
MultiLinkElement GetBasicMultiLinkElement(bool isReassoc, uint8_t linkId) const;
/**
* Return the Probe Request Multi-Link Element to include in the management frames to transmit.
*
* @param apLinkIds ID of the links on which the requested APs operate
* @param apMldId the AP MLD ID to include in the Common Info field
* @return the Probe Request Multi-Link Element
*/
MultiLinkElement GetProbeReqMultiLinkElement(const std::vector<uint8_t>& apLinkIds,
std::optional<uint8_t> apMldId) const;
/**
* @param apNegSupport the negotiation type supported by the AP MLD

View File

@@ -90,9 +90,12 @@ WifiDefaultAssocManager::DoStartScanning()
for (uint8_t linkId = 0; linkId < m_mac->GetNLinks(); linkId++)
{
Simulator::Schedule(GetScanParams().probeDelay,
&StaWifiMac::SendProbeRequest,
&StaWifiMac::EnqueueProbeRequest,
m_mac,
linkId);
m_mac->GetProbeRequest(linkId),
linkId,
Mac48Address::GetBroadcast(),
Mac48Address::GetBroadcast());
}
m_probeRequestEvent =
Simulator::Schedule(GetScanParams().probeDelay + GetScanParams().maxChannelTime,