wifi: Add support for IE_EXTENSION and fix 802.11ax information elements
This commit is contained in:
@@ -93,7 +93,13 @@ HeCapabilities::HeCapabilities ()
|
||||
WifiInformationElementId
|
||||
HeCapabilities::ElementId () const
|
||||
{
|
||||
return IE_HE_CAPABILITIES;
|
||||
return IE_EXTENSION;
|
||||
}
|
||||
|
||||
WifiInformationElementId
|
||||
HeCapabilities::ElementIdExt () const
|
||||
{
|
||||
return IE_EXT_HE_CAPABILITIES;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -107,7 +113,7 @@ HeCapabilities::GetInformationFieldSize () const
|
||||
{
|
||||
//we should not be here if ht is not supported
|
||||
NS_ASSERT (m_heSupported > 0);
|
||||
return 16; //todo: variable length!
|
||||
return 19; //todo: variable length!
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
@@ -140,8 +146,9 @@ HeCapabilities::SerializeInformationField (Buffer::Iterator start) const
|
||||
start.WriteU8 (GetHeMacCapabilitiesInfo2 ());
|
||||
start.WriteHtolsbU64 (GetHePhyCapabilitiesInfo1 ());
|
||||
start.WriteU8 (GetHePhyCapabilitiesInfo2 ());
|
||||
start.WriteU16 (GetSupportedMcsAndNss ()); //todo: variable length
|
||||
//todo: optional PPE Threshold field
|
||||
start.WriteHtolsbU32 (GetSupportedMcsAndNss ());
|
||||
//todo: add another 32-bits field if 160 MHz channel is supported (variable length)
|
||||
//todo: optional PPE Threshold field (variable length)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,11 +160,12 @@ HeCapabilities::DeserializeInformationField (Buffer::Iterator start, uint8_t len
|
||||
uint8_t macCapabilities2 = i.ReadU8 ();
|
||||
uint64_t phyCapabilities1 = i.ReadLsbtohU64 ();
|
||||
uint8_t phyCapabilities2 = i.ReadU8 ();
|
||||
uint16_t mcsset = i.ReadU16 (); //todo: variable length
|
||||
uint32_t mcsset = i.ReadU32 ();
|
||||
SetHeMacCapabilitiesInfo (macCapabilities1, macCapabilities2);
|
||||
SetHePhyCapabilitiesInfo (phyCapabilities1, phyCapabilities2);
|
||||
SetSupportedMcsAndNss (mcsset);
|
||||
//todo: optional PPE Threshold field
|
||||
//todo: add another 32-bits field if 160 MHz channel is supported (variable length)
|
||||
//todo: optional PPE Threshold field (variable length)
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,11 @@ public:
|
||||
* \returns the wifi information element ID
|
||||
*/
|
||||
WifiInformationElementId ElementId () const;
|
||||
/**
|
||||
* Get the wifi information element ID extension
|
||||
* \returns the wifi information element ID extension
|
||||
*/
|
||||
WifiInformationElementId ElementIdExt () const;
|
||||
/**
|
||||
* Get information field size
|
||||
* \returns the information field size
|
||||
@@ -175,14 +180,14 @@ public:
|
||||
void SetHighestNssSupported (uint8_t nss);
|
||||
|
||||
/**
|
||||
* Is transmit MCS supported.
|
||||
* Is RX MCS supported.
|
||||
*
|
||||
* \param mcs the MCS
|
||||
* \returns true if MCS transmit supported
|
||||
*/
|
||||
bool IsSupportedTxMcs (uint8_t mcs) const;
|
||||
/**
|
||||
* Is reeive MCS supported.
|
||||
* Is RX MCS supported.
|
||||
*
|
||||
* \param mcs the MCS
|
||||
* \returns true if MCS receive supported
|
||||
|
||||
@@ -40,7 +40,13 @@ HeOperation::HeOperation ()
|
||||
WifiInformationElementId
|
||||
HeOperation::ElementId () const
|
||||
{
|
||||
return IE_HE_OPERATION;
|
||||
return IE_EXTENSION;
|
||||
}
|
||||
|
||||
WifiInformationElementId
|
||||
HeOperation::ElementIdExt () const
|
||||
{
|
||||
return IE_EXT_HE_OPERATION;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -54,7 +60,7 @@ HeOperation::GetInformationFieldSize () const
|
||||
{
|
||||
//we should not be here if he is not supported
|
||||
NS_ASSERT (m_heSupported > 0);
|
||||
return 10;
|
||||
return 7;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -91,10 +97,23 @@ void
|
||||
HeOperation::SetMaxHeMcsPerNss (uint8_t nss, uint8_t maxHeMcs)
|
||||
{
|
||||
NS_ASSERT ((maxHeMcs >= 7 && maxHeMcs <= 11) && (nss >= 1 && nss <= 8));
|
||||
m_basicHeMcsAndNssSet |= (((maxHeMcs - 7) & 0x07) << ((nss - 1) * 3));
|
||||
uint8_t val = 3; //3 means not supported
|
||||
if (maxHeMcs > 9) //MCS 0 - 11
|
||||
{
|
||||
val = 2;
|
||||
}
|
||||
else if (maxHeMcs > 7) //MCS 0 - 9
|
||||
{
|
||||
val = 1;
|
||||
}
|
||||
else if (maxHeMcs == 7) //MCS 0 - 7
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
m_basicHeMcsAndNssSet |= ((val & 0x03) << ((nss - 1) * 2));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
uint16_t
|
||||
HeOperation::GetBasicHeMcsAndNssSet (void) const
|
||||
{
|
||||
return m_basicHeMcsAndNssSet;
|
||||
@@ -127,11 +146,8 @@ HeOperation::SerializeInformationField (Buffer::Iterator start) const
|
||||
{
|
||||
//write the corresponding value for each bit
|
||||
start.WriteHtolsbU32 (GetHeOperationParameters ());
|
||||
uint32_t mcsset = GetBasicHeMcsAndNssSet ();
|
||||
start.WriteU16 (mcsset & 0xffff);
|
||||
start.WriteU8 ((mcsset >> 16) & 0xff);
|
||||
start.WriteU16 (0); //todo: VHT Operation Information
|
||||
start.WriteU8 (0); //todo: VHT Operation Information
|
||||
start.WriteU16 (GetBasicHeMcsAndNssSet ());
|
||||
//todo: VHT Operation Information (variable)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,13 +156,9 @@ HeOperation::DeserializeInformationField (Buffer::Iterator start, uint8_t length
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
uint32_t heOperationParameters = i.ReadLsbtohU32 ();
|
||||
uint16_t mcsset_1 = i.ReadU16 ();
|
||||
uint8_t mcsset_2 = i.ReadU8 ();
|
||||
i.ReadU16 (); //todo: VHT Operation Information
|
||||
i.ReadU8 (); //todo: VHT Operation Information
|
||||
m_basicHeMcsAndNssSet = i.ReadU16 ();
|
||||
SetHeOperationParameters (heOperationParameters);
|
||||
m_basicHeMcsAndNssSet |= mcsset_1 & 0xffff;
|
||||
m_basicHeMcsAndNssSet |= (mcsset_2 & 0xff) << 16;
|
||||
//todo: VHT Operation Information (variable)
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
*
|
||||
* \return the Basic HE-MCS And Nss field in the HE Operation information element
|
||||
*/
|
||||
uint32_t GetBasicHeMcsAndNssSet (void) const;
|
||||
uint16_t GetBasicHeMcsAndNssSet (void) const;
|
||||
|
||||
/**
|
||||
* Return the element ID.
|
||||
@@ -79,6 +79,11 @@ public:
|
||||
* \returns the element ID
|
||||
*/
|
||||
WifiInformationElementId ElementId () const;
|
||||
/**
|
||||
* Get the wifi information element ID extension
|
||||
* \returns the wifi information element ID extension
|
||||
*/
|
||||
WifiInformationElementId ElementIdExt () const;
|
||||
/**
|
||||
* Return the information field size.
|
||||
*
|
||||
@@ -131,7 +136,7 @@ private:
|
||||
uint8_t m_dualBeacon; //!< Dual Beacon
|
||||
|
||||
//Basic HE-MCS and NSS Set
|
||||
uint32_t m_basicHeMcsAndNssSet; ///< basic HE MCS NSS set
|
||||
uint16_t m_basicHeMcsAndNssSet; ///< basic HE MCS NSS set
|
||||
|
||||
//TODO: VHT Operation Information subfields not defined in the standard yet.
|
||||
|
||||
|
||||
@@ -37,13 +37,28 @@ WifiInformationElement::GetSerializedSize () const
|
||||
return (2 + GetInformationFieldSize ());
|
||||
}
|
||||
|
||||
WifiInformationElementId
|
||||
WifiInformationElement::ElementIdExt () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
WifiInformationElement::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (ElementId ());
|
||||
i.WriteU8 (GetInformationFieldSize ());
|
||||
SerializeInformationField (i);
|
||||
i.Next (GetInformationFieldSize ());
|
||||
if (ElementId () == IE_EXTENSION)
|
||||
{
|
||||
i.WriteU8 (ElementIdExt ());
|
||||
SerializeInformationField (i);
|
||||
i.Next (GetInformationFieldSize () - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SerializeInformationField (i);
|
||||
i.Next (GetInformationFieldSize ());
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -77,10 +92,24 @@ WifiInformationElement::DeserializeIfPresent (Buffer::Iterator i)
|
||||
}
|
||||
|
||||
uint8_t length = i.ReadU8 ();
|
||||
|
||||
DeserializeInformationField (i, length);
|
||||
i.Next (length);
|
||||
|
||||
if (ElementId () == IE_EXTENSION)
|
||||
{
|
||||
uint8_t elementIdExt = i.ReadU8 ();
|
||||
//If the element here isn't the one we're after then we immediately
|
||||
//return the iterator we were passed indicating that we haven't
|
||||
//taken anything from the buffer.
|
||||
if (elementIdExt != ElementIdExt ())
|
||||
{
|
||||
return start;
|
||||
}
|
||||
DeserializeInformationField (i, length - 1);
|
||||
i.Next (length - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeserializeInformationField (i, length);
|
||||
i.Next (length);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -97,6 +126,11 @@ WifiInformationElement::operator== (WifiInformationElement const & a) const
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ElementIdExt () != a.ElementIdExt ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t ieSize = GetInformationFieldSize ();
|
||||
|
||||
Buffer myIe, hisIe;
|
||||
|
||||
@@ -185,10 +185,11 @@ typedef uint8_t WifiInformationElementId;
|
||||
#define IE_OPERATING_MODE_NOTIFICATION ((WifiInformationElementId)199)
|
||||
// 200 to 220 are reserved
|
||||
#define IE_VENDOR_SPECIFIC ((WifiInformationElementId)221)
|
||||
// 222 to 255 are reserved
|
||||
#define IE_HE_CAPABILITIES ((WifiInformationElementId)255) //todo: not defined yet in the standard!
|
||||
#define IE_HE_OPERATION ((WifiInformationElementId)255) //todo: not defined yet in the standard!
|
||||
// 222 to 254 are reserved
|
||||
#define IE_EXTENSION ((WifiInformationElementId)255)
|
||||
|
||||
#define IE_EXT_HE_CAPABILITIES ((WifiInformationElementId)35)
|
||||
#define IE_EXT_HE_OPERATION ((WifiInformationElementId)36)
|
||||
|
||||
/**
|
||||
* \brief Information element, as defined in 802.11-2007 standard
|
||||
@@ -303,6 +304,11 @@ public:
|
||||
virtual uint8_t DeserializeInformationField (Buffer::Iterator start,
|
||||
uint8_t length) = 0;
|
||||
|
||||
/**
|
||||
* \returns Own unique Element ID Extension
|
||||
*/
|
||||
virtual WifiInformationElementId ElementIdExt () const;
|
||||
|
||||
// In addition, a subclass may optionally override the following...
|
||||
/**
|
||||
* Generate human-readable form of IE
|
||||
|
||||
Reference in New Issue
Block a user