diff --git a/src/wifi/model/he-capabilities.cc b/src/wifi/model/he-capabilities.cc index be8ddeb84..ae65a059b 100644 --- a/src/wifi/model/he-capabilities.cc +++ b/src/wifi/model/he-capabilities.cc @@ -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; } diff --git a/src/wifi/model/he-capabilities.h b/src/wifi/model/he-capabilities.h index 2e43ccd14..776ceb579 100644 --- a/src/wifi/model/he-capabilities.h +++ b/src/wifi/model/he-capabilities.h @@ -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 diff --git a/src/wifi/model/he-operation.cc b/src/wifi/model/he-operation.cc index 1291cf46c..6247f80bf 100644 --- a/src/wifi/model/he-operation.cc +++ b/src/wifi/model/he-operation.cc @@ -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; } diff --git a/src/wifi/model/he-operation.h b/src/wifi/model/he-operation.h index 17150279a..2caf16b8d 100644 --- a/src/wifi/model/he-operation.h +++ b/src/wifi/model/he-operation.h @@ -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. diff --git a/src/wifi/model/wifi-information-element.cc b/src/wifi/model/wifi-information-element.cc index bea446576..5a7dff5ad 100644 --- a/src/wifi/model/wifi-information-element.cc +++ b/src/wifi/model/wifi-information-element.cc @@ -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; diff --git a/src/wifi/model/wifi-information-element.h b/src/wifi/model/wifi-information-element.h index c9c57b574..59e822a5b 100644 --- a/src/wifi/model/wifi-information-element.h +++ b/src/wifi/model/wifi-information-element.h @@ -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