wifi: Introduce HeOperation in 802.11ax management frames

This commit is contained in:
Sébastien Deronne
2017-11-25 16:19:45 +01:00
parent c8c85d8b76
commit e4b7d7c4cc
9 changed files with 427 additions and 4 deletions

View File

@@ -641,7 +641,22 @@ ApWifiMac::GetVhtOperation (void) const
}
operation.SetMaxVhtMcsPerNss (nss, maxMcs);
}
}
return operation;
}
HeOperation
ApWifiMac::GetHeOperation (void) const
{
NS_LOG_FUNCTION (this);
HeOperation operation;
if (m_heSupported)
{
operation.SetHeSupported (1);
for (uint8_t nss = 1; nss <= m_phy->GetMaxSupportedRxSpatialStreams (); nss++)
{
operation.SetMaxHeMcsPerNss (nss, 11); //TBD: hardcode to 11 for now since we assume all MCS values are supported
}
}
return operation;
}
@@ -691,6 +706,7 @@ ApWifiMac::SendProbeResp (Mac48Address to)
if (m_heSupported)
{
probe.SetHeCapabilities (GetHeCapabilities ());
probe.SetHeOperation (GetHeOperation ());
}
packet->AddHeader (probe);
@@ -749,6 +765,7 @@ ApWifiMac::SendAssocResp (Mac48Address to, bool success)
if (m_heSupported)
{
assoc.SetHeCapabilities (GetHeCapabilities ());
assoc.SetHeOperation (GetHeOperation ());
}
packet->AddHeader (assoc);
@@ -804,6 +821,7 @@ ApWifiMac::SendOneBeacon (void)
if (m_heSupported)
{
beacon.SetHeCapabilities (GetHeCapabilities ());
beacon.SetHeOperation (GetHeOperation ());
}
packet->AddHeader (beacon);

View File

@@ -25,7 +25,6 @@
#include "regular-wifi-mac.h"
#include "capability-information.h"
#include "ht-operation.h"
#include "supported-rates.h"
#include "dsss-parameter-set.h"
#include "erp-information.h"
@@ -241,6 +240,12 @@ private:
* \return the VHT operation that we support
*/
VhtOperation GetVhtOperation (void) const;
/**
* Return the HE operation of the current AP.
*
* \return the HE operation that we support
*/
HeOperation GetHeOperation (void) const;
/**
* Return an instance of SupportedRates that contains all rates that we support
* including HT rates.

View File

@@ -0,0 +1,187 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2017 Sébastien Deronne
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#include "he-operation.h"
namespace ns3 {
HeOperation::HeOperation ()
: m_bsssColor (0),
m_defaultPEDuration (0),
m_twtRequired (0),
m_heDurationBasedRtsThreshold (0),
m_partialBsssColor (0),
m_maxBssidIndicator (0),
m_txBssidIndicator (0),
m_bsssColorDisabled (0),
m_dualBeacon (0),
m_basicHeMcsAndNssSet (0),
m_heSupported (0)
{
}
WifiInformationElementId
HeOperation::ElementId () const
{
return IE_HE_OPERATION;
}
void
HeOperation::SetHeSupported (uint8_t hesupported)
{
m_heSupported = hesupported;
}
uint8_t
HeOperation::GetInformationFieldSize () const
{
//we should not be here if he is not supported
NS_ASSERT (m_heSupported > 0);
return 10;
}
void
HeOperation::SetHeOperationParameters (uint32_t ctrl)
{
m_bsssColor = ctrl & 0x3f;
m_defaultPEDuration = (ctrl >> 6) & 0x07;
m_twtRequired = (ctrl >> 9) & 0x01;
m_heDurationBasedRtsThreshold = (ctrl >> 10) & 0x03ff;
m_partialBsssColor = (ctrl >> 20) & 0x01;
m_maxBssidIndicator = (ctrl >> 21) & 0xff;
m_txBssidIndicator = (ctrl >> 29) & 0x01;
m_bsssColorDisabled = (ctrl >> 30) & 0x01;
m_dualBeacon = (ctrl >> 31) & 0x01;
}
uint32_t
HeOperation::GetHeOperationParameters () const
{
uint32_t val = 0;
val |= m_bsssColor & 0x3f;
val |= (m_defaultPEDuration & 0x07) << 6;
val |= (m_twtRequired & 0x01) << 9;
val |= (m_heDurationBasedRtsThreshold & 0x03ff) << 10;
val |= (m_partialBsssColor & 0x01) << 20;
val |= (m_maxBssidIndicator & 0xff) << 21;
val |= (m_txBssidIndicator & 0x01) << 29;
val |= (m_bsssColorDisabled & 0x01) << 30;
val |= (m_dualBeacon & 0x01) << 31;
return val;
}
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));
}
uint32_t
HeOperation::GetBasicHeMcsAndNssSet (void) const
{
return m_basicHeMcsAndNssSet;
}
Buffer::Iterator
HeOperation::Serialize (Buffer::Iterator i) const
{
if (m_heSupported < 1)
{
return i;
}
return WifiInformationElement::Serialize (i);
}
uint16_t
HeOperation::GetSerializedSize () const
{
if (m_heSupported < 1)
{
return 0;
}
return WifiInformationElement::GetSerializedSize ();
}
void
HeOperation::SerializeInformationField (Buffer::Iterator start) const
{
if (m_heSupported == 1)
{
//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
}
}
uint8_t
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
SetHeOperationParameters (heOperationParameters);
m_basicHeMcsAndNssSet |= mcsset_1 & 0xffff;
m_basicHeMcsAndNssSet |= (mcsset_2 & 0xff) << 16;
return length;
}
ATTRIBUTE_HELPER_CPP (HeOperation);
/**
* output stream output operator
*
* \param os output stream
* \param HeOperation the HE operation
*
* \returns output stream
*/
std::ostream &
operator << (std::ostream &os, const HeOperation &HeOperation)
{
os << HeOperation.GetHeOperationParameters () << "|"
<< HeOperation.GetBasicHeMcsAndNssSet ();
return os;
}
/**
* input stream input operator
*
* \param is input stream
* \param HeOperation the HE operation
*
* \returns input stream
*/
std::istream &operator >> (std::istream &is, HeOperation &HeOperation)
{
uint32_t c1;
is >> c1;
HeOperation.SetHeOperationParameters (c1);
return is;
}
} //namespace ns3

View File

@@ -0,0 +1,149 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2017 Sébastien Deronne
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#ifndef HE_OPERATION_H
#define HE_OPERATION_H
#include "wifi-information-element.h"
namespace ns3 {
/**
* \brief The HE Operation Information Element
* \ingroup wifi
*
* This class knows how to serialise and deserialise
* the HE Operation Information Element
*
* \see attribute_HeOperation
*/
class HeOperation : public WifiInformationElement
{
public:
HeOperation ();
/**
* Set the HE supported information element.
*
* \param hesupported the HE supported information element
*/
void SetHeSupported (uint8_t hesupported);
/**
* Set the HE Operation Parameters field in the HE Operation information element.
*
* \param ctrl the HE Operation Parameters field in the HE Operation information element
*/
void SetHeOperationParameters (uint32_t ctrl);
/**
* Set the Basic HE-MCS and NSS field in the HE Operation information element
* by specifying the tuple (nss, maxMcs).
*
* \param nss the NSS
* \param maxHeMcs the maximum supported HE-MCS value corresponding to that NSS
*/
void SetMaxHeMcsPerNss (uint8_t nss, uint8_t maxHeMcs);
/**
* Return the HE Operation Parameters field in the HE Operation information element.
*
* \return the HE Operation Parameters field in the HE Operation information element
*/
uint32_t GetHeOperationParameters (void) const;
/**
* Return the Basic HE-MCS And Nss field in the HE Operation information element.
*
* \return the Basic HE-MCS And Nss field in the HE Operation information element
*/
uint32_t GetBasicHeMcsAndNssSet (void) const;
/**
* Return the element ID.
*
* \returns the element ID
*/
WifiInformationElementId ElementId () const;
/**
* Return the information field size.
*
* \returns the information field size
*/
uint8_t GetInformationFieldSize () const;
/**
* Serialize the information field.
*
* \param start the information field iterator
*/
void SerializeInformationField (Buffer::Iterator start) const;
/**
* Deserialize the information field.
*
* \param start the iterator
* \param length the length
* \returns the information field size
*/
uint8_t DeserializeInformationField (Buffer::Iterator start, uint8_t length);
/**
* This information element is a bit special in that it is only
* included if the STA is a HE STA. To support this we
* override the Serialize and GetSerializedSize methods of
* WifiInformationElement.
*
* \param start
*
* \return an iterator
*/
Buffer::Iterator Serialize (Buffer::Iterator start) const;
/**
* Return the serialized size of this HE Operations IE.
*
* \return the serialized size of this HE Operations IE
*/
uint16_t GetSerializedSize () const;
private:
//HE Operation Parameters fields
uint8_t m_bsssColor; //!< BSS color
uint8_t m_defaultPEDuration; //!< default PE duration
uint8_t m_twtRequired; //!< TWT required
uint16_t m_heDurationBasedRtsThreshold; //!< HE duration based RTS threshold
uint8_t m_partialBsssColor; //!< partial BSS color
uint8_t m_maxBssidIndicator; //!< max BSSID indicator
uint8_t m_txBssidIndicator; //!< TX BSSID indicator
uint8_t m_bsssColorDisabled; //!< BSS color disabled
uint8_t m_dualBeacon; //!< BSS color disabled
//Basic HE-MCS and NSS Set
uint32_t m_basicHeMcsAndNssSet; ///< basic HE MCS NSS set
//TODO: VHT Operation Information subfields not defined in the standard yet.
/// This is used to decide whether this element should be added to the frame or not
uint8_t m_heSupported;
};
std::ostream &operator << (std::ostream &os, const HeOperation &HeOperation);
std::istream &operator >> (std::istream &is, HeOperation &HeOperation);
ATTRIBUTE_HELPER_HEADER (HeOperation);
} //namespace ns3
#endif /* HE_OPERATION_H */

View File

@@ -271,6 +271,18 @@ MgtProbeResponseHeader::GetHeCapabilities (void) const
return m_heCapability;
}
void
MgtProbeResponseHeader::SetHeOperation (HeOperation heoperation)
{
m_heOperation = heoperation;
}
HeOperation
MgtProbeResponseHeader::GetHeOperation (void) const
{
return m_heOperation;
}
void
MgtProbeResponseHeader::SetSsid (Ssid ssid)
{
@@ -360,6 +372,7 @@ MgtProbeResponseHeader::GetSerializedSize (void) const
size += m_vhtCapability.GetSerializedSize ();
size += m_vhtOperation.GetSerializedSize ();
size += m_heCapability.GetSerializedSize ();
size += m_heOperation.GetSerializedSize ();
return size;
}
@@ -373,7 +386,8 @@ MgtProbeResponseHeader::Print (std::ostream &os) const
<< "HT Operation=" << m_htOperation << " , "
<< "VHT Capabilities=" << m_vhtCapability << " , "
<< "VHT Operation=" << m_vhtOperation << " , "
<< "HE Capabilities=" << m_heCapability;
<< "HE Capabilities=" << m_heCapability << " , "
<< "HE Operation=" << m_heOperation;
}
void
@@ -403,6 +417,7 @@ MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const
i = m_vhtCapability.Serialize (i);
i = m_vhtOperation.Serialize (i);
i = m_heCapability.Serialize (i);
i = m_heOperation.Serialize (i);
}
uint32_t
@@ -424,6 +439,7 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
i = m_vhtCapability.DeserializeIfPresent (i);
i = m_vhtOperation.DeserializeIfPresent (i);
i = m_heCapability.DeserializeIfPresent (i);
i = m_heOperation.DeserializeIfPresent (i);
return i.GetDistanceFrom (start);
}
@@ -729,6 +745,18 @@ MgtAssocResponseHeader::GetHeCapabilities (void) const
return m_heCapability;
}
void
MgtAssocResponseHeader::SetHeOperation (HeOperation heoperation)
{
m_heOperation = heoperation;
}
HeOperation
MgtAssocResponseHeader::GetHeOperation (void) const
{
return m_heOperation;
}
void
MgtAssocResponseHeader::SetErpInformation (ErpInformation erpInformation)
{
@@ -786,6 +814,7 @@ MgtAssocResponseHeader::GetSerializedSize (void) const
size += m_vhtCapability.GetSerializedSize ();
size += m_vhtOperation.GetSerializedSize ();
size += m_heCapability.GetSerializedSize ();
size += m_heOperation.GetSerializedSize ();
return size;
}
@@ -799,7 +828,8 @@ MgtAssocResponseHeader::Print (std::ostream &os) const
<< "HT Operation=" << m_htOperation << " , "
<< "VHT Capabilities=" << m_vhtCapability << " , "
<< "VHT Operation=" << m_vhtOperation << " , "
<< "HE Capabilities=" << m_heCapability;
<< "HE Capabilities=" << m_heCapability << " , "
<< "HE Operation=" << m_heOperation;
}
void
@@ -818,6 +848,7 @@ MgtAssocResponseHeader::Serialize (Buffer::Iterator start) const
i = m_vhtCapability.Serialize (i);
i = m_vhtOperation.Serialize (i);
i = m_heCapability.Serialize (i);
i = m_heOperation.Serialize (i);
}
uint32_t
@@ -836,6 +867,7 @@ MgtAssocResponseHeader::Deserialize (Buffer::Iterator start)
i = m_vhtCapability.DeserializeIfPresent (i);
i = m_vhtOperation.DeserializeIfPresent (i);
i = m_heCapability.DeserializeIfPresent (i);
i = m_heOperation.DeserializeIfPresent (i);
return i.GetDistanceFrom (start);
}

View File

@@ -35,6 +35,7 @@
#include "erp-information.h"
#include "edca-parameter-set.h"
#include "he-capabilities.h"
#include "he-operation.h"
namespace ns3 {
@@ -214,6 +215,12 @@ public:
* \return HE capabilities
*/
HeCapabilities GetHeCapabilities (void) const;
/**
* Return the HE operation.
*
* \return HE operation
*/
HeOperation GetHeOperation (void) const;
/**
* Return the ERP information.
*
@@ -286,6 +293,12 @@ public:
* \param hecapabilities HE capabilities
*/
void SetHeCapabilities (HeCapabilities hecapabilities);
/**
* Set the HE operation.
*
* \param heoperation HE operation
*/
void SetHeOperation (HeOperation heoperation);
/**
* Register this type.
@@ -311,6 +324,7 @@ private:
ErpInformation m_erpInformation; //!< ERP information
EdcaParameterSet m_edcaParameterSet; //!< EDCA Parameter Set
HeCapabilities m_heCapability; //!< HE capabilities
HeOperation m_heOperation; //!< HE operation
};
@@ -475,6 +489,12 @@ public:
* \return HE capabilities
*/
HeCapabilities GetHeCapabilities (void) const;
/**
* Return the HE operation.
*
* \return HE operation
*/
HeOperation GetHeOperation (void) const;
/**
* Return the ERP information.
*
@@ -523,6 +543,12 @@ public:
* \param hecapabilities HE capabilities
*/
void SetHeCapabilities (HeCapabilities hecapabilities);
/**
* Set the HE operation.
*
* \param heoperation HE operation
*/
void SetHeOperation (HeOperation heoperation);
/**
* Set the Service Set Identifier (SSID).
*
@@ -589,7 +615,8 @@ private:
HtOperation m_htOperation; //!< HT operation
VhtCapabilities m_vhtCapability; //!< VHT capabilities
VhtOperation m_vhtOperation; //!< VHT operation
HeCapabilities m_heCapability; //!< HE capabilities
HeCapabilities m_heCapability; //!< HE capabilities
HeOperation m_heOperation; //!< HE operation
ErpInformation m_erpInformation; //!< ERP information
EdcaParameterSet m_edcaParameterSet; //!< EDCA Parameter Set
};

View File

@@ -590,6 +590,7 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
HeCapabilities heCapabilities = beacon.GetHeCapabilities ();
//todo: once we support non constant rate managers, we should add checks here whether HE is supported by the peer
m_stationManager->AddStationHeCapabilities (hdr->GetAddr2 (), heCapabilities);
HeOperation heOperation = beacon.GetHeOperation ();
for (uint32_t i = 0; i < m_phy->GetNMcs (); i++)
{
WifiMode mcs = m_phy->GetMcs (i);
@@ -806,6 +807,7 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
HeCapabilities hecapabilities = assocResp.GetHeCapabilities ();
//todo: once we support non constant rate managers, we should add checks here whether HE is supported by the peer
m_stationManager->AddStationHeCapabilities (hdr->GetAddr2 (), hecapabilities);
HeOperation heOperation = assocResp.GetHeOperation ();
}
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{

View File

@@ -187,6 +187,7 @@ typedef uint8_t WifiInformationElementId;
#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!
/**

View File

@@ -85,6 +85,7 @@ def build(bld):
'model/he-capabilities.cc',
'model/frame-capture-model.cc',
'model/simple-frame-capture-model.cc',
'model/he-operation.cc',
'helper/wifi-radio-energy-model-helper.cc',
'helper/vht-wifi-mac-helper.cc',
'helper/ht-wifi-mac-helper.cc',
@@ -196,6 +197,7 @@ def build(bld):
'model/frame-capture-model.h',
'model/simple-frame-capture-model.h',
'model/qos-blocked-destinations.h',
'model/he-operation.h',
'helper/wifi-radio-energy-model-helper.h',
'helper/vht-wifi-mac-helper.h',
'helper/ht-wifi-mac-helper.h',