wifi: APs reply to received EML Operating Mode Notification frame

This commit is contained in:
Stefano Avallone
2023-02-06 14:05:46 +01:00
committed by Stefano Avallone
parent 917022c28c
commit 233cb96506
2 changed files with 77 additions and 5 deletions

View File

@@ -23,7 +23,6 @@
#include "amsdu-subframe-header.h"
#include "channel-access-manager.h"
#include "frame-exchange-manager.h"
#include "mac-rx-middle.h"
#include "mac-tx-middle.h"
#include "mgt-headers.h"
@@ -36,6 +35,7 @@
#include "wifi-phy.h"
#include "ns3/eht-configuration.h"
#include "ns3/eht-frame-exchange-manager.h"
#include "ns3/he-configuration.h"
#include "ns3/ht-configuration.h"
#include "ns3/log.h"
@@ -1636,8 +1636,10 @@ ApWifiMac::Receive(Ptr<const WifiMpdu> mpdu, uint8_t linkId)
}
else if (hdr->GetAddr1() == GetFrameExchangeManager(linkId)->GetAddress())
{
if (hdr->IsAssocReq() || hdr->IsReassocReq())
switch (hdr->GetType())
{
case WIFI_MAC_MGT_ASSOCIATION_REQUEST:
case WIFI_MAC_MGT_REASSOCIATION_REQUEST: {
NS_LOG_DEBUG(((hdr->IsAssocReq()) ? "Association" : "Reassociation")
<< " request received from " << from
<< ((GetNLinks() > 1) ? " on link ID " + std::to_string(linkId) : ""));
@@ -1662,8 +1664,7 @@ ApWifiMac::Receive(Ptr<const WifiMpdu> mpdu, uint8_t linkId)
SendAssocResp(hdr->GetAddr2(), hdr->IsReassocReq(), linkId);
return;
}
else if (hdr->IsDisassociation())
{
case WIFI_MAC_MGT_DISASSOCIATION: {
NS_LOG_DEBUG("Disassociation received from " << from);
GetWifiRemoteStationManager(linkId)->RecordDisassociated(from);
auto& staList = GetLink(linkId).staList;
@@ -1689,6 +1690,25 @@ ApWifiMac::Receive(Ptr<const WifiMpdu> mpdu, uint8_t linkId)
}
return;
}
case WIFI_MAC_MGT_ACTION: {
auto pkt = mpdu->GetPacket()->Copy();
auto [category, action] = WifiActionHeader::Remove(pkt);
if (category == WifiActionHeader::PROTECTED_EHT &&
action.protectedEhtAction ==
WifiActionHeader::PROTECTED_EHT_EML_OPERATING_MODE_NOTIFICATION &&
IsAssociated(hdr->GetAddr2()))
{
// received an EML Operating Mode Notification frame from an associated station
MgtEmlOperatingModeNotification frame;
pkt->RemoveHeader(frame);
ReceiveEmlNotification(frame, hdr->GetAddr2(), linkId);
return;
}
break;
}
default:;
// do nothing
}
}
}
@@ -1808,7 +1828,7 @@ ApWifiMac::ReceiveAssocRequest(const AssocReqRefVariant& assoc,
{
remoteStationManager->AddStationHtCapabilities(from, *htCapabilities);
}
// const ExtendedCapabilities& extendedCapabilities = frame.GetExtendedCapabilities ();
// const ExtendedCapabilities& extendedCapabilities = frame.GetExtendedCapabilities();
// TODO: to be completed
}
if (GetVhtSupported(linkId))
@@ -1917,6 +1937,45 @@ ApWifiMac::ParseReportedStaInfo(const AssocReqRefVariant& assoc, Mac48Address fr
std::visit(recvMle, assoc);
}
void
ApWifiMac::ReceiveEmlNotification(MgtEmlOperatingModeNotification& frame,
const Mac48Address& sender,
uint8_t linkId)
{
NS_LOG_FUNCTION(this << frame << sender << linkId);
auto ehtConfiguration = GetEhtConfiguration();
if (BooleanValue emlsrActivated;
!ehtConfiguration ||
!ehtConfiguration->GetAttributeFailSafe("EmlsrActivated", emlsrActivated) ||
!emlsrActivated.Get())
{
NS_LOG_DEBUG(
"Received an EML Operating Mode Notification frame but EMLSR is not activated");
return;
}
// An AP MLD with dot11EHTEMLSROptionActivated equal to true sets the EMLSR Mode subfield
// to the value obtained from the EMLSR Mode subfield of the received EML Operating Mode
// Notification frame. (Sec. 9.6.35.8 of 802.11be D3.0)
// When included in a frame sent by an AP affiliated with an AP MLD, the EMLSR Parameter
// Update Control subfield is set to 0. (Sec. 9.6.35.8 of 802.11be D3.0)
frame.m_emlControl.emlsrParamUpdateCtrl = 0;
// An AP MLD with dot11EHTEMLSROptionImplemented equal to true sets the EMLSR Link Bitmap
// subfield to the value obtained from the EMLSR Link Bitmap subfield of the received
// EML Operating Mode Notification frame. (Sec. 9.6.35.8 of 802.11be D3.0)
// The EMLSR Parameter Update field [..] is present if [..] the Action frame is sent by
// a non-AP STA affiliated with a non-AP MLD (Sec. 9.6.35.8 of 802.11be D3.0)
frame.m_emlsrParamUpdate.reset();
auto ehtFem = StaticCast<EhtFrameExchangeManager>(GetFrameExchangeManager(linkId));
ehtFem->SendEmlOperatingModeNotification(sender, frame);
}
void
ApWifiMac::DeaggregateAmsduAndForward(Ptr<const WifiMpdu> mpdu)
{

View File

@@ -48,6 +48,7 @@ class UniformRandomVariable;
class MgtAssocRequestHeader;
class MgtReassocRequestHeader;
class MgtAssocResponseHeader;
class MgtEmlOperatingModeNotification;
/// variant holding a reference to a (Re)Association Request
using AssocReqRefVariant = std::variant<std::reference_wrapper<MgtAssocRequestHeader>,
@@ -237,6 +238,18 @@ class ApWifiMac : public WifiMac
*/
void ParseReportedStaInfo(const AssocReqRefVariant& assoc, Mac48Address from, uint8_t linkId);
/**
* Take necessary actions upon receiving the given EML Operating Mode Notification frame
* from the given station on the given link.
*
* \param frame the received EML Operating Mode Notification frame
* \param sender the MAC address of the sender of the frame
* \param linkId the ID of the link over which the frame was received
*/
void ReceiveEmlNotification(MgtEmlOperatingModeNotification& frame,
const Mac48Address& sender,
uint8_t linkId);
/**
* The packet we sent was successfully received by the receiver
* (i.e. we received an Ack from the receiver). If the packet