wifi: Implement the Reduced Neighbor Report element
This commit is contained in:
@@ -91,6 +91,7 @@ set(source_files
|
||||
model/rate-control/rrpaa-wifi-manager.cc
|
||||
model/rate-control/thompson-sampling-wifi-manager.cc
|
||||
model/recipient-block-ack-agreement.cc
|
||||
model/reduced-neighbor-report.cc
|
||||
model/simple-frame-capture-model.cc
|
||||
model/snr-tag.cc
|
||||
model/spectrum-wifi-phy.cc
|
||||
@@ -229,6 +230,7 @@ set(header_files
|
||||
model/rate-control/rrpaa-wifi-manager.h
|
||||
model/rate-control/thompson-sampling-wifi-manager.h
|
||||
model/recipient-block-ack-agreement.h
|
||||
model/reduced-neighbor-report.h
|
||||
model/reference/error-rate-tables.h
|
||||
model/simple-frame-capture-model.h
|
||||
model/snr-tag.h
|
||||
|
||||
696
src/wifi/model/reduced-neighbor-report.cc
Normal file
696
src/wifi/model/reduced-neighbor-report.cc
Normal file
@@ -0,0 +1,696 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2021 Universita' degli Studi di Napoli Federico II
|
||||
*
|
||||
* 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: Stefano Avallone <stavallo@unina.it>
|
||||
*/
|
||||
|
||||
#include "reduced-neighbor-report.h"
|
||||
#include "wifi-phy-operating-channel.h"
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#include <iterator>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
ReducedNeighborReport::ReducedNeighborReport ()
|
||||
{
|
||||
}
|
||||
|
||||
WifiInformationElementId
|
||||
ReducedNeighborReport::ElementId () const
|
||||
{
|
||||
return IE_REDUCED_NEIGHBOR_REPORT;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
ReducedNeighborReport::GetNNbrApInfoFields (void) const
|
||||
{
|
||||
return m_nbrApInfoFields.size ();
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::AddNbrApInfoField (void)
|
||||
{
|
||||
m_nbrApInfoFields.push_back (NeighborApInformation ());
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::SetOperatingChannel (std::size_t nbrApInfoId,
|
||||
const WifiPhyOperatingChannel& channel)
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
uint8_t operatingClass = 0;
|
||||
uint8_t channelNumber = channel.GetNumber ();
|
||||
|
||||
// Information taken from Table E-4 of 802.11-2020
|
||||
switch (channel.GetPhyBand ())
|
||||
{
|
||||
case WIFI_PHY_BAND_2_4GHZ:
|
||||
if (channel.GetWidth () == 20)
|
||||
{
|
||||
operatingClass = 81;
|
||||
}
|
||||
else if (channel.GetWidth () == 40)
|
||||
{
|
||||
operatingClass = 83;
|
||||
}
|
||||
break;
|
||||
case WIFI_PHY_BAND_5GHZ:
|
||||
if (channel.GetWidth () == 20)
|
||||
{
|
||||
if (channelNumber == 36 || channelNumber == 40
|
||||
|| channelNumber == 44 || channelNumber == 48)
|
||||
{
|
||||
operatingClass = 115;
|
||||
}
|
||||
else if (channelNumber == 52 || channelNumber == 56
|
||||
|| channelNumber == 60 || channelNumber == 64)
|
||||
{
|
||||
operatingClass = 118;
|
||||
}
|
||||
else if (channelNumber == 100 || channelNumber == 104 || channelNumber == 108
|
||||
|| channelNumber == 112 || channelNumber == 116 || channelNumber == 120
|
||||
|| channelNumber == 124 || channelNumber == 128 || channelNumber == 132
|
||||
|| channelNumber == 136 || channelNumber == 140 || channelNumber == 144)
|
||||
{
|
||||
operatingClass = 121;
|
||||
}
|
||||
else if (channelNumber == 149 || channelNumber == 153 || channelNumber == 157
|
||||
|| channelNumber == 161 || channelNumber == 165 || channelNumber == 169
|
||||
|| channelNumber == 173 || channelNumber == 177 || channelNumber == 181)
|
||||
{
|
||||
operatingClass = 125;
|
||||
}
|
||||
}
|
||||
else if (channel.GetWidth () == 40)
|
||||
{
|
||||
if (channelNumber == 38 || channelNumber == 46)
|
||||
{
|
||||
operatingClass = 116;
|
||||
}
|
||||
else if (channelNumber == 54 || channelNumber == 62)
|
||||
{
|
||||
operatingClass = 119;
|
||||
}
|
||||
else if (channelNumber == 102 || channelNumber == 110 || channelNumber == 118
|
||||
|| channelNumber == 126 || channelNumber == 134 || channelNumber == 142)
|
||||
{
|
||||
operatingClass = 122;
|
||||
}
|
||||
else if (channelNumber == 151 || channelNumber == 159
|
||||
|| channelNumber == 167 || channelNumber == 175)
|
||||
{
|
||||
operatingClass = 126;
|
||||
}
|
||||
}
|
||||
else if (channel.GetWidth () == 80)
|
||||
{
|
||||
if (channelNumber == 42 || channelNumber == 58 || channelNumber == 106
|
||||
|| channelNumber == 122 || channelNumber == 138 || channelNumber == 155
|
||||
|| channelNumber == 171)
|
||||
{
|
||||
operatingClass = 128;
|
||||
}
|
||||
}
|
||||
else if (channel.GetWidth () == 160)
|
||||
{
|
||||
if (channelNumber == 50 || channelNumber == 114 || channelNumber == 163)
|
||||
{
|
||||
operatingClass = 129;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WIFI_PHY_BAND_6GHZ:
|
||||
if (channel.GetWidth () == 20)
|
||||
{
|
||||
operatingClass = 131;
|
||||
}
|
||||
else if (channel.GetWidth () == 40)
|
||||
{
|
||||
operatingClass = 132;
|
||||
}
|
||||
else if (channel.GetWidth () == 80)
|
||||
{
|
||||
operatingClass = 133;
|
||||
}
|
||||
else if (channel.GetWidth () == 160)
|
||||
{
|
||||
operatingClass = 134;
|
||||
}
|
||||
break;
|
||||
case WIFI_PHY_BAND_UNSPECIFIED:
|
||||
NS_ABORT_MSG ("The provided channel has an unspecified PHY band");
|
||||
break;
|
||||
}
|
||||
|
||||
NS_ABORT_MSG_IF (operatingClass == 0, "Operating class not found for channel number "
|
||||
<< channelNumber << " width " << channel.GetWidth () << " MHz "
|
||||
<< "band " << channel.GetPhyBand ());
|
||||
|
||||
// find the primary channel number
|
||||
uint16_t startingFreq = 0;
|
||||
|
||||
switch (channel.GetPhyBand ())
|
||||
{
|
||||
case WIFI_PHY_BAND_2_4GHZ:
|
||||
startingFreq = 2407;
|
||||
break;
|
||||
case WIFI_PHY_BAND_5GHZ:
|
||||
startingFreq = 5000;
|
||||
break;
|
||||
case WIFI_PHY_BAND_6GHZ:
|
||||
startingFreq = 5940;
|
||||
break;
|
||||
case WIFI_PHY_BAND_UNSPECIFIED:
|
||||
NS_ABORT_MSG ("The provided channel has an unspecified PHY band");
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t primaryChannelNumber = (channel.GetPrimaryChannelCenterFrequency (20) - startingFreq) / 5;
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).operatingClass = operatingClass;
|
||||
m_nbrApInfoFields.at (nbrApInfoId).channelNumber = primaryChannelNumber;
|
||||
}
|
||||
|
||||
WifiPhyOperatingChannel
|
||||
ReducedNeighborReport::GetOperatingChannel (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
WifiPhyBand band = WIFI_PHY_BAND_UNSPECIFIED;
|
||||
uint16_t width = 0;
|
||||
|
||||
switch (m_nbrApInfoFields.at (nbrApInfoId).operatingClass)
|
||||
{
|
||||
case 81:
|
||||
band = WIFI_PHY_BAND_2_4GHZ;
|
||||
width = 20;
|
||||
break;
|
||||
case 83:
|
||||
band = WIFI_PHY_BAND_2_4GHZ;
|
||||
width = 40;
|
||||
break;
|
||||
case 115:
|
||||
case 118:
|
||||
case 121:
|
||||
case 125:
|
||||
band = WIFI_PHY_BAND_5GHZ;
|
||||
width = 20;
|
||||
break;
|
||||
case 116:
|
||||
case 119:
|
||||
case 122:
|
||||
case 126:
|
||||
band = WIFI_PHY_BAND_5GHZ;
|
||||
width = 40;
|
||||
break;
|
||||
case 128:
|
||||
band = WIFI_PHY_BAND_5GHZ;
|
||||
width = 80;
|
||||
break;
|
||||
case 129:
|
||||
band = WIFI_PHY_BAND_5GHZ;
|
||||
width = 160;
|
||||
break;
|
||||
case 131:
|
||||
band = WIFI_PHY_BAND_6GHZ;
|
||||
width = 20;
|
||||
break;
|
||||
case 132:
|
||||
band = WIFI_PHY_BAND_6GHZ;
|
||||
width = 40;
|
||||
break;
|
||||
case 133:
|
||||
band = WIFI_PHY_BAND_6GHZ;
|
||||
width = 80;
|
||||
break;
|
||||
case 134:
|
||||
band = WIFI_PHY_BAND_6GHZ;
|
||||
width = 160;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NS_ABORT_IF (band == WIFI_PHY_BAND_UNSPECIFIED || width == 0);
|
||||
|
||||
uint16_t startingFreq = 0;
|
||||
|
||||
switch (band)
|
||||
{
|
||||
case WIFI_PHY_BAND_2_4GHZ:
|
||||
startingFreq = 2407;
|
||||
break;
|
||||
case WIFI_PHY_BAND_5GHZ:
|
||||
startingFreq = 5000;
|
||||
break;
|
||||
case WIFI_PHY_BAND_6GHZ:
|
||||
startingFreq = 5940;
|
||||
break;
|
||||
case WIFI_PHY_BAND_UNSPECIFIED:
|
||||
NS_ABORT_MSG ("Unspecified band");
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t primaryChannelNumber = m_nbrApInfoFields.at (nbrApInfoId).channelNumber;
|
||||
uint16_t primaryChannelCenterFrequency = startingFreq + primaryChannelNumber * 5;
|
||||
|
||||
uint8_t channelNumber = 0;
|
||||
uint16_t frequency = 0;
|
||||
|
||||
for (const auto& channel : WifiPhyOperatingChannel::m_frequencyChannels)
|
||||
{
|
||||
if (std::get<2> (channel) == width
|
||||
&& std::get<3> (channel) == WIFI_PHY_OFDM_CHANNEL
|
||||
&& std::get<4> (channel) == band
|
||||
&& primaryChannelCenterFrequency > std::get<1> (channel) - width / 2
|
||||
&& primaryChannelCenterFrequency < std::get<1> (channel) + width / 2)
|
||||
{
|
||||
channelNumber = std::get<0> (channel);
|
||||
frequency = std::get<1> (channel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ABORT_IF (channelNumber == 0 || frequency == 0);
|
||||
|
||||
WifiPhyOperatingChannel channel;
|
||||
channel.Set (channelNumber, frequency, width, WIFI_STANDARD_UNSPECIFIED, band);
|
||||
|
||||
uint16_t channelLowestFreq = frequency - width / 2;
|
||||
uint16_t primaryChannelLowestFreq = primaryChannelCenterFrequency - 10;
|
||||
channel.SetPrimary20Index ((primaryChannelLowestFreq - channelLowestFreq) / 20);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
ReducedNeighborReport::GetNTbttInformationFields (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ();
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::AddTbttInformationField (std::size_t nbrApInfoId)
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.push_back (TbttInformation ());
|
||||
|
||||
// set the TBTT Information Count field
|
||||
m_nbrApInfoFields.at (nbrApInfoId).tbttInfoHdr.tbttInfoCount = m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size () - 1;
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::WriteTbttInformationLength (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
uint8_t length = 0; // reserved value
|
||||
|
||||
auto it = std::next (m_nbrApInfoFields.begin (), nbrApInfoId);
|
||||
|
||||
if (it->hasBssid
|
||||
&& !it->hasShortSsid
|
||||
&& !it->hasBssParams
|
||||
&& !it->has20MHzPsd
|
||||
&& !it->hasMldParams)
|
||||
{
|
||||
length = 7;
|
||||
}
|
||||
else if (it->hasBssid
|
||||
&& it->hasShortSsid
|
||||
&& it->hasBssParams
|
||||
&& it->has20MHzPsd
|
||||
&& it->hasMldParams)
|
||||
{
|
||||
length = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG ("Unsupported TBTT Information field contents");
|
||||
}
|
||||
|
||||
// set the TBTT Information Length field
|
||||
it->tbttInfoHdr.tbttInfoLength = length;
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::ReadTbttInformationLength (std::size_t nbrApInfoId)
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
auto it = std::next (m_nbrApInfoFields.begin (), nbrApInfoId);
|
||||
|
||||
switch (it->tbttInfoHdr.tbttInfoLength)
|
||||
{
|
||||
case 7:
|
||||
it->hasBssid = true;
|
||||
it->hasShortSsid = false;
|
||||
it->hasBssParams = false;
|
||||
it->has20MHzPsd = false;
|
||||
it->hasMldParams = false;
|
||||
break;
|
||||
case 16:
|
||||
it->hasBssid = true;
|
||||
it->hasShortSsid = true;
|
||||
it->hasBssParams = true;
|
||||
it->has20MHzPsd = true;
|
||||
it->hasMldParams = true;
|
||||
break;
|
||||
default:
|
||||
NS_ABORT_MSG ("Unsupported TBTT Information Length value: "
|
||||
<< it->tbttInfoHdr.tbttInfoLength);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::SetBssid (std::size_t nbrApInfoId, std::size_t index, Mac48Address bssid)
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).bssid = bssid;
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).hasBssid = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReducedNeighborReport::HasBssid (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).hasBssid;
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
ReducedNeighborReport::GetBssid (std::size_t nbrApInfoId, std::size_t index) const
|
||||
{
|
||||
NS_ASSERT (HasBssid (nbrApInfoId));
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).bssid;
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::SetShortSsid (std::size_t nbrApInfoId, std::size_t index, uint32_t shortSsid)
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).shortSsid = shortSsid;
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).hasShortSsid = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReducedNeighborReport::HasShortSsid (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).hasShortSsid;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ReducedNeighborReport::GetShortSsid (std::size_t nbrApInfoId, std::size_t index) const
|
||||
{
|
||||
NS_ASSERT (HasShortSsid (nbrApInfoId));
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).shortSsid;
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::SetBssParameters (std::size_t nbrApInfoId, std::size_t index, uint8_t bssParameters)
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).bssParameters = bssParameters;
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).hasBssParams = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReducedNeighborReport::HasBssParameters (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).hasBssParams;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ReducedNeighborReport::GetBssParameters (std::size_t nbrApInfoId, std::size_t index) const
|
||||
{
|
||||
NS_ASSERT (HasBssParameters (nbrApInfoId));
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).bssParameters;
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::SetPsd20MHz (std::size_t nbrApInfoId, std::size_t index, uint8_t psd20MHz)
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).psd20MHz = psd20MHz;
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).has20MHzPsd = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReducedNeighborReport::HasPsd20MHz (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).has20MHzPsd;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ReducedNeighborReport::GetPsd20MHz (std::size_t nbrApInfoId, std::size_t index) const
|
||||
{
|
||||
NS_ASSERT (HasPsd20MHz (nbrApInfoId));
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).psd20MHz;
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::SetMldParameters (std::size_t nbrApInfoId, std::size_t index,
|
||||
uint8_t mldId, uint8_t linkId, uint8_t changeCount)
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
auto it = std::next (m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.begin (), index);
|
||||
it->mldParameters.mldId = mldId;
|
||||
it->mldParameters.linkId = (linkId & 0x0f);
|
||||
it->mldParameters.bssParamsChangeCount = changeCount;
|
||||
|
||||
m_nbrApInfoFields.at (nbrApInfoId).hasMldParams = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReducedNeighborReport::HasMldParameters (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).hasMldParams;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ReducedNeighborReport::GetMldId (std::size_t nbrApInfoId, std::size_t index) const
|
||||
{
|
||||
NS_ASSERT (HasMldParameters (nbrApInfoId));
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).mldParameters.mldId;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ReducedNeighborReport::GetLinkId (std::size_t nbrApInfoId, std::size_t index) const
|
||||
{
|
||||
NS_ASSERT (HasMldParameters (nbrApInfoId));
|
||||
NS_ASSERT (index < m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.size ());
|
||||
|
||||
return m_nbrApInfoFields.at (nbrApInfoId).tbttInformationSet.at (index).mldParameters.linkId & 0x0f;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ReducedNeighborReport::GetTbttInformationCount (std::size_t nbrApInfoId) const
|
||||
{
|
||||
NS_ASSERT (nbrApInfoId < m_nbrApInfoFields.size ());
|
||||
|
||||
return 1 + m_nbrApInfoFields.at (nbrApInfoId).tbttInfoHdr.tbttInfoCount;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ReducedNeighborReport::GetInformationFieldSize () const
|
||||
{
|
||||
uint8_t size = 0;
|
||||
|
||||
for (const auto& neighborApInfo : m_nbrApInfoFields)
|
||||
{
|
||||
size += 4;
|
||||
|
||||
size += 1 * neighborApInfo.tbttInformationSet.size ();
|
||||
|
||||
if (neighborApInfo.hasBssid)
|
||||
{
|
||||
size += 6 * neighborApInfo.tbttInformationSet.size ();
|
||||
}
|
||||
if (neighborApInfo.hasShortSsid)
|
||||
{
|
||||
size += 4 * neighborApInfo.tbttInformationSet.size ();
|
||||
}
|
||||
if (neighborApInfo.hasBssParams)
|
||||
{
|
||||
size += 1 * neighborApInfo.tbttInformationSet.size ();
|
||||
}
|
||||
if (neighborApInfo.has20MHzPsd)
|
||||
{
|
||||
size += 1 * neighborApInfo.tbttInformationSet.size ();
|
||||
}
|
||||
if (neighborApInfo.hasMldParams)
|
||||
{
|
||||
size += 3 * neighborApInfo.tbttInformationSet.size ();
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
ReducedNeighborReport::SerializeInformationField (Buffer::Iterator start) const
|
||||
{
|
||||
for (std::size_t id = 0; id < m_nbrApInfoFields.size (); ++ id)
|
||||
{
|
||||
WriteTbttInformationLength (id);
|
||||
}
|
||||
|
||||
for (auto& neighborApInfo : m_nbrApInfoFields)
|
||||
{
|
||||
// serialize the TBTT Information Header
|
||||
uint16_t tbttInfoHdr = 0;
|
||||
tbttInfoHdr |= neighborApInfo.tbttInfoHdr.type;
|
||||
tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.filtered << 2);
|
||||
tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.tbttInfoCount << 4);
|
||||
tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.tbttInfoLength << 8);
|
||||
start.WriteHtolsbU16 (tbttInfoHdr);
|
||||
|
||||
start.WriteU8 (neighborApInfo.operatingClass);
|
||||
start.WriteU8 (neighborApInfo.channelNumber);
|
||||
|
||||
for (const auto& tbttInformation : neighborApInfo.tbttInformationSet)
|
||||
{
|
||||
start.WriteU8 (tbttInformation.neighborApTbttOffset);
|
||||
|
||||
if (neighborApInfo.hasBssid)
|
||||
{
|
||||
WriteTo (start, tbttInformation.bssid);
|
||||
}
|
||||
if (neighborApInfo.hasShortSsid)
|
||||
{
|
||||
start.WriteHtolsbU32 (tbttInformation.shortSsid);
|
||||
}
|
||||
if (neighborApInfo.hasBssParams)
|
||||
{
|
||||
start.WriteU8 (tbttInformation.bssParameters);
|
||||
}
|
||||
if (neighborApInfo.has20MHzPsd)
|
||||
{
|
||||
start.WriteU8 (tbttInformation.psd20MHz);
|
||||
}
|
||||
if (neighborApInfo.hasMldParams)
|
||||
{
|
||||
start.WriteU8 (tbttInformation.mldParameters.mldId);
|
||||
uint16_t other = 0;
|
||||
other |= (tbttInformation.mldParameters.linkId & 0x0f);
|
||||
other |= (tbttInformation.mldParameters.bssParamsChangeCount << 4);
|
||||
start.WriteHtolsbU16 (other);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ReducedNeighborReport::DeserializeInformationField (Buffer::Iterator start, uint8_t length)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
uint8_t count = 0;
|
||||
|
||||
while (count < length)
|
||||
{
|
||||
AddNbrApInfoField ();
|
||||
|
||||
auto tbttInfoHdr = i.ReadLsbtohU16 ();
|
||||
m_nbrApInfoFields.back ().tbttInfoHdr.type = tbttInfoHdr & 0x0003;
|
||||
m_nbrApInfoFields.back ().tbttInfoHdr.filtered = (tbttInfoHdr >> 2) & 0x0001;
|
||||
m_nbrApInfoFields.back ().tbttInfoHdr.tbttInfoCount = (tbttInfoHdr >> 4) & 0x000f;
|
||||
m_nbrApInfoFields.back ().tbttInfoHdr.tbttInfoLength = (tbttInfoHdr >> 8) & 0x00ff;
|
||||
|
||||
m_nbrApInfoFields.back ().operatingClass = i.ReadU8 ();
|
||||
m_nbrApInfoFields.back ().channelNumber = i.ReadU8 ();
|
||||
count += 4;
|
||||
|
||||
std::size_t neighborId = m_nbrApInfoFields.size () - 1;
|
||||
ReadTbttInformationLength (neighborId);
|
||||
|
||||
for (uint8_t j = 0; j < GetTbttInformationCount (neighborId); j++)
|
||||
{
|
||||
AddTbttInformationField (neighborId);
|
||||
|
||||
m_nbrApInfoFields.back ().tbttInformationSet.back ().neighborApTbttOffset = i.ReadU8 ();
|
||||
count++;
|
||||
|
||||
if (m_nbrApInfoFields.back ().hasBssid)
|
||||
{
|
||||
ReadFrom (i, m_nbrApInfoFields.back ().tbttInformationSet.back ().bssid);
|
||||
count += 6;
|
||||
}
|
||||
if (m_nbrApInfoFields.back ().hasShortSsid)
|
||||
{
|
||||
m_nbrApInfoFields.back ().tbttInformationSet.back ().shortSsid = i.ReadLsbtohU32 ();
|
||||
count += 4;
|
||||
}
|
||||
if (m_nbrApInfoFields.back ().hasBssParams)
|
||||
{
|
||||
m_nbrApInfoFields.back ().tbttInformationSet.back ().bssParameters = i.ReadU8 ();
|
||||
count += 1;
|
||||
}
|
||||
if (m_nbrApInfoFields.back ().has20MHzPsd)
|
||||
{
|
||||
m_nbrApInfoFields.back ().tbttInformationSet.back ().psd20MHz = i.ReadU8 ();
|
||||
count += 1;
|
||||
}
|
||||
if (m_nbrApInfoFields.back ().hasMldParams)
|
||||
{
|
||||
m_nbrApInfoFields.back ().tbttInformationSet.back ().mldParameters.mldId = i.ReadU8 ();
|
||||
uint16_t other = i.ReadLsbtohU16 ();
|
||||
count += 3;
|
||||
m_nbrApInfoFields.back ().tbttInformationSet.back ().mldParameters.linkId = other & 0x000f;
|
||||
m_nbrApInfoFields.back ().tbttInformationSet.back ().mldParameters.bssParamsChangeCount = (other >> 4) & 0x00ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
328
src/wifi/model/reduced-neighbor-report.h
Normal file
328
src/wifi/model/reduced-neighbor-report.h
Normal file
@@ -0,0 +1,328 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2021 Universita' degli Studi di Napoli Federico II
|
||||
*
|
||||
* 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: Stefano Avallone <stavallo@unina.it>
|
||||
*/
|
||||
|
||||
#ifndef REDUCED_NEIGHBOR_REPORT_H
|
||||
#define REDUCED_NEIGHBOR_REPORT_H
|
||||
|
||||
#include "wifi-information-element.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class WifiPhyOperatingChannel;
|
||||
|
||||
|
||||
/**
|
||||
* \brief The Reduced Neighbor Report element
|
||||
* \ingroup wifi
|
||||
*
|
||||
* This class knows how to serialise and deserialise the Reduced Neighbor Report element.
|
||||
*/
|
||||
class ReducedNeighborReport : public WifiInformationElement
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* MLD Parameters subfield
|
||||
*/
|
||||
struct MldParameters
|
||||
{
|
||||
uint8_t mldId; //!< MLD ID
|
||||
uint8_t linkId; //!< Link ID
|
||||
uint8_t bssParamsChangeCount; //!< BSS Parameters Change Count
|
||||
};
|
||||
|
||||
/**
|
||||
* TBTT Information field
|
||||
*/
|
||||
struct TbttInformation
|
||||
{
|
||||
uint8_t neighborApTbttOffset {0}; //!< Neighbor AP TBTT Offset
|
||||
Mac48Address bssid; //!< BSSID (optional)
|
||||
uint32_t shortSsid {0}; //!< Short SSID (optional)
|
||||
uint8_t bssParameters {0}; //!< BSS parameters (optional)
|
||||
uint8_t psd20MHz {0}; //!< 20 MHz PSD (optional)
|
||||
MldParameters mldParameters {0, 0, 0}; //!< MLD Parameters (optional)
|
||||
};
|
||||
|
||||
/**
|
||||
* TBTT Information Header subfield
|
||||
*/
|
||||
struct TbttInformationHeader
|
||||
{
|
||||
uint8_t type : 2; //!< TBTT Information Field Type (2 bits)
|
||||
uint8_t filtered : 1; //!< Filtered Neighbor AP (1 bit)
|
||||
uint8_t reserved : 1; //!< Reserved (1 bit)
|
||||
uint8_t tbttInfoCount : 4; //!< TBTT Information Count (4 bits)
|
||||
uint8_t tbttInfoLength; //!< TBTT Information Length (8 bits)
|
||||
};
|
||||
|
||||
/**
|
||||
* Neighbor AP information field
|
||||
*/
|
||||
struct NeighborApInformation
|
||||
{
|
||||
mutable TbttInformationHeader tbttInfoHdr {0, 0, 0, 0, 0}; //!< TBTT Information header
|
||||
uint8_t operatingClass {0}; //!< Operating class
|
||||
uint8_t channelNumber {0}; //!< Primary channel number
|
||||
std::vector<TbttInformation> tbttInformationSet; //!< One or more TBTT Information fields
|
||||
|
||||
bool hasBssid {false}; //!< whether BSSID is present in all TBTT Information fields
|
||||
bool hasShortSsid {false}; //!< whether Short SSID is present in all TBTT Information fields
|
||||
bool hasBssParams {false}; //!< whether BSS parameters is present in all TBTT Information fields
|
||||
bool has20MHzPsd {false}; //!< whether 20 MHz PSD is present in all TBTT Information fields
|
||||
bool hasMldParams {false}; //!< whether MLD Parameters is present in all TBTT Information fields
|
||||
};
|
||||
|
||||
ReducedNeighborReport ();
|
||||
|
||||
// Implementations of pure virtual methods of WifiInformationElement
|
||||
WifiInformationElementId ElementId () const override;
|
||||
uint8_t GetInformationFieldSize () const override;
|
||||
void SerializeInformationField (Buffer::Iterator start) const override;
|
||||
uint8_t DeserializeInformationField (Buffer::Iterator start, uint8_t length) override;
|
||||
|
||||
/**
|
||||
* Get the number of Neighbor AP Information fields
|
||||
*
|
||||
* \return the number of Neighbor AP Information fields
|
||||
*/
|
||||
std::size_t GetNNbrApInfoFields (void) const;
|
||||
/**
|
||||
* Add a Neighbor AP Information field
|
||||
*/
|
||||
void AddNbrApInfoField (void);
|
||||
|
||||
/**
|
||||
* Set the Operating Class and the Channel Number fields of the given
|
||||
* Neighbor AP Information field based on the given operating channel.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param channel the PHY operating channel
|
||||
*/
|
||||
void SetOperatingChannel (std::size_t nbrApInfoId, const WifiPhyOperatingChannel& channel);
|
||||
/**
|
||||
* Get the operating channel coded into the Operating Class and the Channel Number
|
||||
* fields of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \return the PHY operating channel
|
||||
*/
|
||||
WifiPhyOperatingChannel GetOperatingChannel (std::size_t nbrApInfoId) const;
|
||||
|
||||
/**
|
||||
* Get the number of TBTT Information fields included in the TBTT Information Set
|
||||
* field of the given Neighbor AP Information field
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \return the number of TBTT Information fields
|
||||
*/
|
||||
std::size_t GetNTbttInformationFields (std::size_t nbrApInfoId) const;
|
||||
/**
|
||||
* Add a TBTT Information fields to the TBTT Information Set field
|
||||
* of the given Neighbor AP Information field
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
*/
|
||||
void AddTbttInformationField (std::size_t nbrApInfoId);
|
||||
|
||||
/**
|
||||
* Set the BSSID field of the <i>i</i>-th TBTT Information field of the given
|
||||
* Neighbor AP Information field
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \param bssid the BSSID value
|
||||
*/
|
||||
void SetBssid (std::size_t nbrApInfoId, std::size_t index, Mac48Address bssid);
|
||||
/**
|
||||
* Return true if the BSSID field is present in all the TBTT Information fields
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \return true if the BSSID field is present
|
||||
*/
|
||||
bool HasBssid (std::size_t nbrApInfoId) const;
|
||||
/**
|
||||
* Get the BSSID field (must be present) in the <i>i</i>-th TBTT Information field
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \return the BSSID field
|
||||
*/
|
||||
Mac48Address GetBssid (std::size_t nbrApInfoId, std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Set the Short SSID field of the <i>i</i>-th TBTT Information field of the given
|
||||
* Neighbor AP Information field
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \param shortSsid the short SSID value
|
||||
*/
|
||||
void SetShortSsid (std::size_t nbrApInfoId, std::size_t index, uint32_t shortSsid);
|
||||
/**
|
||||
* Return true if the Short SSID field is present in all the TBTT Information fields
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \return true if the Short SSID field is present
|
||||
*/
|
||||
bool HasShortSsid (std::size_t nbrApInfoId) const;
|
||||
/**
|
||||
* Get the Short SSID field (must be present) in the <i>i</i>-th TBTT Information field
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \return the Short SSID field
|
||||
*/
|
||||
uint32_t GetShortSsid (std::size_t nbrApInfoId, std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Set the BSS Parameters field of the <i>i</i>-th TBTT Information field of the given
|
||||
* Neighbor AP Information field
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \param bssParameters the BSS Parameters value
|
||||
*/
|
||||
void SetBssParameters (std::size_t nbrApInfoId, std::size_t index, uint8_t bssParameters);
|
||||
/**
|
||||
* Return true if the BSS Parameters field is present in all the TBTT Information fields
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \return true if the BSS Parameters field is present
|
||||
*/
|
||||
bool HasBssParameters (std::size_t nbrApInfoId) const;
|
||||
/**
|
||||
* Get the BSS Parameters field (must be present) in the <i>i</i>-th TBTT Information field
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \return the BSS Parameters field
|
||||
*/
|
||||
uint8_t GetBssParameters (std::size_t nbrApInfoId, std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Set the 20 MHz PSD field of the <i>i</i>-th TBTT Information field of the given
|
||||
* Neighbor AP Information field
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \param psd20MHz the 20 MHz PSD value
|
||||
*/
|
||||
void SetPsd20MHz (std::size_t nbrApInfoId, std::size_t index, uint8_t psd20MHz);
|
||||
/**
|
||||
* Return true if the 20 MHz PSD field is present in all the TBTT Information fields
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \return true if the 20 MHz PSD field is present
|
||||
*/
|
||||
bool HasPsd20MHz (std::size_t nbrApInfoId) const;
|
||||
/**
|
||||
* Get the 20 MHz PSD field (must be present) in the <i>i</i>-th TBTT Information field
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \return the 20 MHz PSD field
|
||||
*/
|
||||
uint8_t GetPsd20MHz (std::size_t nbrApInfoId, std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Set the MLD Parameters subfield of the <i>i</i>-th TBTT Information field of the given
|
||||
* Neighbor AP Information field
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \param mldId the MLD ID value
|
||||
* \param linkId the Link ID value
|
||||
* \param changeSequence the Change Sequence value
|
||||
*/
|
||||
void SetMldParameters (std::size_t nbrApInfoId, std::size_t index,
|
||||
uint8_t mldId, uint8_t linkId, uint8_t changeSequence);
|
||||
/**
|
||||
* Return true if the MLD Parameters subfield is present in all the TBTT Information fields
|
||||
* of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \return true if the MLD Parameters subfield is present
|
||||
*/
|
||||
bool HasMldParameters (std::size_t nbrApInfoId) const;
|
||||
/**
|
||||
* Get the MLD ID value in the MLD Parameters subfield (must be present) in the
|
||||
* <i>i</i>-th TBTT Information field of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \return the MLD ID value
|
||||
*/
|
||||
uint8_t GetMldId (std::size_t nbrApInfoId, std::size_t index) const;
|
||||
/**
|
||||
* Get the Link ID value in the MLD Parameters subfield (must be present) in the
|
||||
* <i>i</i>-th TBTT Information field of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \param index the index of the given TBTT Information field
|
||||
* \return the Link ID value
|
||||
*/
|
||||
uint8_t GetLinkId (std::size_t nbrApInfoId, std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Get the TBTT Information Count field of the given Neighbor AP Information field.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
* \return the TBTT Information Count
|
||||
*/
|
||||
uint8_t GetTbttInformationCount (std::size_t nbrApInfoId) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Set the TBTT Information Length field of the given Neighbor AP Information field
|
||||
* based on the xxxPresent flags of the NeighborApInformation struct
|
||||
*
|
||||
* This method is marked as const because it needs to be called within the
|
||||
* SerializeInformationField method. In fact, only when serializing this object
|
||||
* we can set the TBTT Information Length field based on the TBTT Information
|
||||
* field contents.
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
*/
|
||||
void WriteTbttInformationLength (std::size_t nbrApInfoId) const;
|
||||
/**
|
||||
* Use the TBTT Information Length field of the given Neighbor AP Information field
|
||||
* to set the xxxPresent flags of the NeighborApInformation struct
|
||||
*
|
||||
* \param nbrApInfoId identifier of the given Neighbor AP Information field
|
||||
*/
|
||||
void ReadTbttInformationLength (std::size_t nbrApInfoId);
|
||||
|
||||
std::vector<NeighborApInformation> m_nbrApInfoFields; //!< one or more Neighbor AP Information fields
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
#endif /* REDUCED_NEIGHBOR_REPORT_H */
|
||||
@@ -183,7 +183,9 @@ typedef uint8_t WifiInformationElementId;
|
||||
#define IE_AID ((WifiInformationElementId)197)
|
||||
#define IE_QUIET_CHANNEL ((WifiInformationElementId)198)
|
||||
#define IE_OPERATING_MODE_NOTIFICATION ((WifiInformationElementId)199)
|
||||
// 200 to 220 are reserved
|
||||
#define IE_UPSIM ((WifiInformationElementId)200)
|
||||
#define IE_REDUCED_NEIGHBOR_REPORT ((WifiInformationElementId)201)
|
||||
// TODO Add 202 to 220. See Table 9-92 of 802.11-2020
|
||||
#define IE_VENDOR_SPECIFIC ((WifiInformationElementId)221)
|
||||
// 222 to 254 are reserved
|
||||
#define IE_EXTENSION ((WifiInformationElementId)255)
|
||||
|
||||
Reference in New Issue
Block a user