wifi: Add EML Operating Mode Notification frame

This commit is contained in:
Stefano Avallone
2023-01-31 18:25:40 +01:00
committed by Stefano Avallone
parent e3e46e6691
commit 85cb36e6bf
2 changed files with 288 additions and 1 deletions

View File

@@ -643,6 +643,10 @@ WifiActionHeader::SetAction(WifiActionHeader::CategoryValue type,
m_actionValue = static_cast<uint8_t>(action.unprotectedDmgAction);
break;
}
case PROTECTED_EHT: {
m_actionValue = static_cast<uint8_t>(action.protectedEhtAction);
break;
}
case VENDOR_SPECIFIC_ACTION: {
break;
}
@@ -674,6 +678,8 @@ WifiActionHeader::GetCategory() const
return FST;
case UNPROTECTED_DMG:
return UNPROTECTED_DMG;
case PROTECTED_EHT:
return PROTECTED_EHT;
case VENDOR_SPECIFIC_ACTION:
return VENDOR_SPECIFIC_ACTION;
default:
@@ -984,6 +990,46 @@ WifiActionHeader::GetAction() const
}
break;
case PROTECTED_EHT:
switch (m_actionValue)
{
case PROTECTED_EHT_TID_TO_LINK_MAPPING_REQUEST:
retval.protectedEhtAction = PROTECTED_EHT_TID_TO_LINK_MAPPING_REQUEST;
break;
case PROTECTED_EHT_TID_TO_LINK_MAPPING_RESPONSE:
retval.protectedEhtAction = PROTECTED_EHT_TID_TO_LINK_MAPPING_RESPONSE;
break;
case PROTECTED_EHT_TID_TO_LINK_MAPPING_TEARDOWN:
retval.protectedEhtAction = PROTECTED_EHT_TID_TO_LINK_MAPPING_TEARDOWN;
break;
case PROTECTED_EHT_EPCS_PRIORITY_ACCESS_ENABLE_REQUEST:
retval.protectedEhtAction = PROTECTED_EHT_EPCS_PRIORITY_ACCESS_ENABLE_REQUEST;
break;
case PROTECTED_EHT_EPCS_PRIORITY_ACCESS_ENABLE_RESPONSE:
retval.protectedEhtAction = PROTECTED_EHT_EPCS_PRIORITY_ACCESS_ENABLE_RESPONSE;
break;
case PROTECTED_EHT_EPCS_PRIORITY_ACCESS_TEARDOWN:
retval.protectedEhtAction = PROTECTED_EHT_EPCS_PRIORITY_ACCESS_TEARDOWN;
break;
case PROTECTED_EHT_EML_OPERATING_MODE_NOTIFICATION:
retval.protectedEhtAction = PROTECTED_EHT_EML_OPERATING_MODE_NOTIFICATION;
break;
case PROTECTED_EHT_LINK_RECOMMENDATION:
retval.protectedEhtAction = PROTECTED_EHT_LINK_RECOMMENDATION;
break;
case PROTECTED_EHT_MULTI_LINK_OPERATION_UPDATE_REQUEST:
retval.protectedEhtAction = PROTECTED_EHT_MULTI_LINK_OPERATION_UPDATE_REQUEST;
break;
case PROTECTED_EHT_MULTI_LINK_OPERATION_UPDATE_RESPONSE:
retval.protectedEhtAction = PROTECTED_EHT_MULTI_LINK_OPERATION_UPDATE_RESPONSE;
break;
default:
NS_FATAL_ERROR("Unknown Protected EHT action code");
retval.protectedEhtAction =
PROTECTED_EHT_TID_TO_LINK_MAPPING_REQUEST; /* quiet compiler */
}
break;
default:
NS_FATAL_ERROR("Unsupported action");
retval.selfProtectedAction = PEER_LINK_OPEN; /* quiet compiler */
@@ -1032,6 +1078,8 @@ WifiActionHeader::CategoryValueToString(CategoryValue value) const
return "Fst";
case UNPROTECTED_DMG:
return "UnprotectedDmg";
case PROTECTED_EHT:
return "ProtectedEht";
case VENDOR_SPECIFIC_ACTION:
return "VendorSpecificAction";
default:
@@ -1551,4 +1599,162 @@ MgtDelBaHeader::SetParameterSet(uint16_t params)
m_tid = (params >> 12) & 0x0f;
}
/***************************************************
* EMLSR Operating Mode Notification
****************************************************/
NS_OBJECT_ENSURE_REGISTERED(MgtEmlOperatingModeNotification);
TypeId
MgtEmlOperatingModeNotification::GetTypeId()
{
static TypeId tid = TypeId("ns3::MgtEmlOperatingModeNotification")
.SetParent<Header>()
.SetGroupName("Wifi")
.AddConstructor<MgtEmlOperatingModeNotification>();
return tid;
}
TypeId
MgtEmlOperatingModeNotification::GetInstanceTypeId() const
{
return GetTypeId();
}
void
MgtEmlOperatingModeNotification::Print(std::ostream& os) const
{
os << "EMLSR Mode=" << +m_emlControl.emlsrMode << " EMLMR Mode=" << +m_emlControl.emlmrMode
<< " EMLSR Parameter Update Control=" << +m_emlControl.emlsrParamUpdateCtrl;
if (m_emlControl.linkBitmap)
{
os << " Link bitmap=" << std::hex << *m_emlControl.linkBitmap << std::dec;
}
if (m_emlsrParamUpdate)
{
os << " EMLSR Padding Delay="
<< CommonInfoBasicMle::DecodeEmlsrPaddingDelay(m_emlsrParamUpdate->paddingDelay)
.As(Time::US)
<< " EMLSR Transition Delay="
<< CommonInfoBasicMle::DecodeEmlsrTransitionDelay(m_emlsrParamUpdate->transitionDelay)
.As(Time::US);
}
}
uint32_t
MgtEmlOperatingModeNotification::GetSerializedSize() const
{
uint32_t size = 2; // Dialog Token (1) + first byte of EML Control
if (m_emlControl.linkBitmap)
{
size += 2;
}
if (m_emlControl.mcsMapCountCtrl)
{
size += 1;
}
// TODO add size of EMLMR Supported MCS And NSS Set subfield when implemented
if (m_emlsrParamUpdate)
{
size += 1; // EMLSR Parameter Update field
}
return size;
}
void
MgtEmlOperatingModeNotification::Serialize(Buffer::Iterator start) const
{
start.WriteU8(m_dialogToken);
NS_ABORT_MSG_IF(m_emlControl.emlsrMode == 1 && m_emlControl.emlmrMode == 1,
"EMLSR Mode and EMLMR Mode cannot be both set to 1");
uint8_t val = m_emlControl.emlsrMode | (m_emlControl.emlmrMode << 1) |
(m_emlControl.emlsrParamUpdateCtrl << 2);
start.WriteU8(val);
NS_ABORT_MSG_IF(m_emlControl.linkBitmap.has_value() !=
(m_emlControl.emlsrMode == 1 || m_emlControl.emlmrMode == 1),
"The EMLSR/EMLMR Link Bitmap is present if and only if either of the EMLSR "
"Mode and EMLMR Mode subfields are set to 1");
if (m_emlControl.linkBitmap)
{
start.WriteHtolsbU16(*m_emlControl.linkBitmap);
}
// TODO serialize MCS Map Count Control and EMLMR Supported MCS And NSS Set subfields
// when implemented
NS_ABORT_MSG_IF(m_emlsrParamUpdate.has_value() != (m_emlControl.emlsrParamUpdateCtrl == 1),
"The EMLSR Parameter Update field is present "
<< std::boolalpha << m_emlsrParamUpdate.has_value()
<< " if and only if the EMLSR "
"Parameter Update Control subfield is set to 1 "
<< +m_emlControl.emlsrParamUpdateCtrl);
if (m_emlsrParamUpdate)
{
val = m_emlsrParamUpdate->paddingDelay | (m_emlsrParamUpdate->transitionDelay << 3);
start.WriteU8(val);
}
}
uint32_t
MgtEmlOperatingModeNotification::Deserialize(Buffer::Iterator start)
{
Buffer::Iterator i = start;
m_dialogToken = i.ReadU8();
uint8_t val = i.ReadU8();
m_emlControl.emlsrMode = val & 0x01;
m_emlControl.emlmrMode = (val >> 1) & 0x01;
m_emlControl.emlsrParamUpdateCtrl = (val >> 2) & 0x01;
NS_ABORT_MSG_IF(m_emlControl.emlsrMode == 1 && m_emlControl.emlmrMode == 1,
"EMLSR Mode and EMLMR Mode cannot be both set to 1");
if (m_emlControl.emlsrMode == 1 || m_emlControl.emlmrMode == 1)
{
m_emlControl.linkBitmap = i.ReadLsbtohU16();
}
// TODO deserialize MCS Map Count Control and EMLMR Supported MCS And NSS Set subfields
// when implemented
if (m_emlControl.emlsrParamUpdateCtrl == 1)
{
val = i.ReadU8();
m_emlsrParamUpdate = EmlsrParamUpdate{};
m_emlsrParamUpdate->paddingDelay = val & 0x07;
m_emlsrParamUpdate->transitionDelay = (val >> 3) & 0x07;
}
return i.GetDistanceFrom(start);
}
void
MgtEmlOperatingModeNotification::SetLinkIdInBitmap(uint8_t linkId)
{
NS_ABORT_MSG_IF(linkId > 15, "Link ID must not exceed 15");
if (!m_emlControl.linkBitmap)
{
m_emlControl.linkBitmap = 0;
}
m_emlControl.linkBitmap = *m_emlControl.linkBitmap | (1 << linkId);
}
std::list<uint8_t>
MgtEmlOperatingModeNotification::GetLinkBitmap() const
{
std::list<uint8_t> list;
NS_ASSERT_MSG(m_emlControl.linkBitmap.has_value(), "No link bitmap");
uint16_t bitmap = *m_emlControl.linkBitmap;
for (uint8_t linkId = 0; linkId < 16; linkId++)
{
if ((bitmap & 0x0001) == 1)
{
list.push_back(linkId);
}
bitmap >>= 1;
}
return list;
}
} // namespace ns3

View File

@@ -46,6 +46,8 @@
#include "ns3/vht-capabilities.h"
#include "ns3/vht-operation.h"
#include <list>
namespace ns3
{
@@ -543,7 +545,7 @@ class WifiActionHeader : public Header
*/
/// CategoryValue enumeration
enum CategoryValue // table 8-38 staring from IEEE 802.11, Part11, (Year 2012)
enum CategoryValue // table 9-51 of IEEE 802.11-2020
{
QOS = 1,
BLOCK_ACK = 3,
@@ -555,6 +557,7 @@ class WifiActionHeader : public Header
DMG = 16, // Category: DMG
FST = 18, // Category: Fast Session Transfer
UNPROTECTED_DMG = 20, // Category: Unprotected DMG
PROTECTED_EHT = 37, // Category: Protected EHT
// Since vendor specific action has no stationary Action value,the parse process is not
// here. Refer to vendor-specific-action in wave module.
VENDOR_SPECIFIC_ACTION = 127,
@@ -694,6 +697,24 @@ class WifiActionHeader : public Header
UNPROTECTED_MIMO_BF_SELECTION = 5,
};
/**
* Protected EHT action field values
* See 802.11be D3.0 Table 9-623c
*/
enum ProtectedEhtActionValue
{
PROTECTED_EHT_TID_TO_LINK_MAPPING_REQUEST = 0,
PROTECTED_EHT_TID_TO_LINK_MAPPING_RESPONSE = 1,
PROTECTED_EHT_TID_TO_LINK_MAPPING_TEARDOWN = 2,
PROTECTED_EHT_EPCS_PRIORITY_ACCESS_ENABLE_REQUEST = 3,
PROTECTED_EHT_EPCS_PRIORITY_ACCESS_ENABLE_RESPONSE = 4,
PROTECTED_EHT_EPCS_PRIORITY_ACCESS_TEARDOWN = 5,
PROTECTED_EHT_EML_OPERATING_MODE_NOTIFICATION = 6,
PROTECTED_EHT_LINK_RECOMMENDATION = 7,
PROTECTED_EHT_MULTI_LINK_OPERATION_UPDATE_REQUEST = 8,
PROTECTED_EHT_MULTI_LINK_OPERATION_UPDATE_RESPONSE = 9,
};
/**
* typedef for union of different ActionValues
*/
@@ -708,6 +729,7 @@ class WifiActionHeader : public Header
DmgActionValue dmgAction; ///< dmg
FstActionValue fstAction; ///< fst
UnprotectedDmgActionValue unprotectedDmgAction; ///< unprotected dmg
ProtectedEhtActionValue protectedEhtAction; ///< protected eht
} ActionValue; ///< the action value
/**
@@ -1077,6 +1099,65 @@ class MgtDelBaHeader : public Header
uint16_t m_reasonCode; //!< Not used for now. Always set to 1: "Unspecified reason"
};
/**
* \ingroup wifi
* Implement the header for Action frames of type EML Operating Mode Notification.
*/
class MgtEmlOperatingModeNotification : public Header
{
public:
MgtEmlOperatingModeNotification() = default;
/**
* Register this type.
* \return The TypeId.
*/
static TypeId GetTypeId();
TypeId GetInstanceTypeId() const override;
void Print(std::ostream& os) const override;
uint32_t GetSerializedSize() const override;
void Serialize(Buffer::Iterator start) const override;
uint32_t Deserialize(Buffer::Iterator start) override;
/**
* EML Control field.
*/
struct EmlControl
{
uint8_t emlsrMode : 1; //!< EMLSR Mode
uint8_t emlmrMode : 1; //!< EMLMR Mode
uint8_t emlsrParamUpdateCtrl : 1; //!< EMLSR Parameter Update Control
uint8_t : 5; //!< reserved
std::optional<uint16_t> linkBitmap; //!< EMLSR/EMLMR Link Bitmap
std::optional<uint8_t> mcsMapCountCtrl; //!< MCS Map Count Control
// TODO Add EMLMR Supported MCS And NSS Set subfield when EMLMR is supported
};
/**
* EMLSR Parameter Update field.
*/
struct EmlsrParamUpdate
{
uint8_t paddingDelay : 3; //!< EMLSR Padding Delay
uint8_t transitionDelay : 3; //!< EMLSR Transition Delay
};
/**
* Set the bit position in the link bitmap corresponding to the given link.
*
* \param linkId the ID of the given link
*/
void SetLinkIdInBitmap(uint8_t linkId);
/**
* \return the ID of the links whose bit position in the link bitmap is set to 1
*/
std::list<uint8_t> GetLinkBitmap() const;
uint8_t m_dialogToken{0}; //!< Dialog Token
EmlControl m_emlControl{}; //!< EML Control field
std::optional<EmlsrParamUpdate> m_emlsrParamUpdate{}; //!< EMLSR Parameter Update field
};
} // namespace ns3
#endif /* MGT_HEADERS_H */