wifi: add HE support to MinstrelHt (initial patch from Alexander Krotov)
This commit is contained in:
@@ -114,6 +114,11 @@ MinstrelHtWifiManager::GetTypeId (void)
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&MinstrelHtWifiManager::m_useVhtOnly),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("UseHeOnly",
|
||||
"Use only HE MCSs (and not HT nor VHT) when HE is available",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&MinstrelHtWifiManager::m_useHeOnly),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("PrintStats",
|
||||
"Control the printing of the statistics table",
|
||||
BooleanValue (false),
|
||||
@@ -183,31 +188,30 @@ void
|
||||
MinstrelHtWifiManager::DoInitialize ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (GetHeSupported ())
|
||||
{
|
||||
NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
|
||||
}
|
||||
/**
|
||||
* Here we initialize m_minstrelGroups with all the possible groups.
|
||||
* If a group is not supported by the device, then it is marked as not supported.
|
||||
* Then, after all initializations are finished, we check actual support for each receiving station.
|
||||
*/
|
||||
|
||||
// Check if the device supports HT
|
||||
if (GetHtSupported ())
|
||||
{
|
||||
m_numGroups = MAX_SUPPORTED_STREAMS * MAX_HT_STREAM_GROUPS;
|
||||
m_numGroups = MAX_HT_SUPPORTED_STREAMS * MAX_HT_STREAM_GROUPS;
|
||||
m_numRates = MAX_HT_GROUP_RATES;
|
||||
|
||||
if (GetVhtSupported ())
|
||||
{
|
||||
m_numGroups += MAX_SUPPORTED_STREAMS * MAX_VHT_STREAM_GROUPS;
|
||||
m_numGroups += MAX_VHT_SUPPORTED_STREAMS * MAX_VHT_STREAM_GROUPS;
|
||||
m_numRates = MAX_VHT_GROUP_RATES;
|
||||
}
|
||||
if (GetHeSupported ())
|
||||
{
|
||||
m_numGroups += MAX_HE_SUPPORTED_STREAMS * MAX_HE_STREAM_GROUPS;
|
||||
m_numRates = MAX_HE_GROUP_RATES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the groups array.
|
||||
* The HT groups come first, then the VHT ones.
|
||||
* The HT groups come first, then the VHT ones, and finally the HE ones.
|
||||
* Minstrel maintains different types of indexes:
|
||||
* - A global continuous index, which identifies all rates within all groups, in [0, m_numGroups * m_numRates]
|
||||
* - A groupId, which indexes a group in the array, in [0, m_numGroups]
|
||||
@@ -221,22 +225,22 @@ MinstrelHtWifiManager::DoInitialize ()
|
||||
// Initialize all HT groups
|
||||
for (uint16_t chWidth = 20; chWidth <= MAX_HT_WIDTH; chWidth *= 2)
|
||||
{
|
||||
for (uint8_t sgi = 0; sgi <= 1; sgi++)
|
||||
for (int gi = 800; gi >= 400; )
|
||||
{
|
||||
for (uint8_t streams = 1; streams <= MAX_SUPPORTED_STREAMS; streams++)
|
||||
for (uint8_t streams = 1; streams <= MAX_HT_SUPPORTED_STREAMS; streams++)
|
||||
{
|
||||
uint8_t groupId = GetHtGroupId (streams, sgi, chWidth);
|
||||
uint8_t groupId = GetHtGroupId (streams, gi, chWidth);
|
||||
|
||||
m_minstrelGroups[groupId].streams = streams;
|
||||
m_minstrelGroups[groupId].sgi = sgi;
|
||||
m_minstrelGroups[groupId].gi = gi;
|
||||
m_minstrelGroups[groupId].chWidth = chWidth;
|
||||
m_minstrelGroups[groupId].isVht = false;
|
||||
m_minstrelGroups[groupId].type = GROUP_HT;
|
||||
m_minstrelGroups[groupId].isSupported = false;
|
||||
|
||||
// Check capabilities of the device
|
||||
if (!(!GetShortGuardIntervalSupported () && m_minstrelGroups[groupId].sgi) ///Is SGI supported by the transmitter?
|
||||
&& (GetPhy ()->GetChannelWidth () >= m_minstrelGroups[groupId].chWidth) ///Is channel width supported by the transmitter?
|
||||
&& (GetPhy ()->GetMaxSupportedTxSpatialStreams () >= m_minstrelGroups[groupId].streams)) ///Are streams supported by the transmitter?
|
||||
if (!(!GetShortGuardIntervalSupported () && (gi == 400)) ///Is SGI supported by the transmitter?
|
||||
&& (GetPhy ()->GetChannelWidth () >= chWidth) ///Is channel width supported by the transmitter?
|
||||
&& (GetPhy ()->GetMaxSupportedTxSpatialStreams () >= streams)) ///Are streams supported by the transmitter?
|
||||
{
|
||||
m_minstrelGroups[groupId].isSupported = true;
|
||||
|
||||
@@ -246,12 +250,13 @@ MinstrelHtWifiManager::DoInitialize ()
|
||||
{
|
||||
uint16_t deviceIndex = i + (m_minstrelGroups[groupId].streams - 1) * 8;
|
||||
WifiMode mode = htMcsList[deviceIndex];
|
||||
AddFirstMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, sgi, chWidth, mode, FIRST_MPDU_IN_AGGREGATE));
|
||||
AddMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, sgi, chWidth, mode, MIDDLE_MPDU_IN_AGGREGATE));
|
||||
AddFirstMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, gi, chWidth, mode, FIRST_MPDU_IN_AGGREGATE));
|
||||
AddMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, gi, chWidth, mode, MIDDLE_MPDU_IN_AGGREGATE));
|
||||
}
|
||||
NS_LOG_DEBUG ("Initialized group " << +groupId << ": (" << +streams << "," << +sgi << "," << chWidth << ")");
|
||||
NS_LOG_DEBUG ("Initialized group " << +groupId << ": (" << +streams << "," << gi << "," << chWidth << ")");
|
||||
}
|
||||
}
|
||||
gi /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,22 +265,22 @@ MinstrelHtWifiManager::DoInitialize ()
|
||||
// Initialize all VHT groups
|
||||
for (uint16_t chWidth = 20; chWidth <= MAX_VHT_WIDTH; chWidth *= 2)
|
||||
{
|
||||
for (uint8_t sgi = 0; sgi <= 1; sgi++)
|
||||
for (int gi = 800; gi >= 400; )
|
||||
{
|
||||
for (uint8_t streams = 1; streams <= MAX_SUPPORTED_STREAMS; streams++)
|
||||
for (uint8_t streams = 1; streams <= MAX_VHT_SUPPORTED_STREAMS; streams++)
|
||||
{
|
||||
uint8_t groupId = GetVhtGroupId (streams, sgi, chWidth);
|
||||
uint8_t groupId = GetVhtGroupId (streams, gi, chWidth);
|
||||
|
||||
m_minstrelGroups[groupId].streams = streams;
|
||||
m_minstrelGroups[groupId].sgi = sgi;
|
||||
m_minstrelGroups[groupId].gi = gi;
|
||||
m_minstrelGroups[groupId].chWidth = chWidth;
|
||||
m_minstrelGroups[groupId].isVht = true;
|
||||
m_minstrelGroups[groupId].type = GROUP_VHT;
|
||||
m_minstrelGroups[groupId].isSupported = false;
|
||||
|
||||
// Check capabilities of the device
|
||||
if (!(!GetShortGuardIntervalSupported () && m_minstrelGroups[groupId].sgi) ///Is SGI supported by the transmitter?
|
||||
&& (GetPhy ()->GetChannelWidth () >= m_minstrelGroups[groupId].chWidth) ///Is channel width supported by the transmitter?
|
||||
&& (GetPhy ()->GetMaxSupportedTxSpatialStreams () >= m_minstrelGroups[groupId].streams)) ///Are streams supported by the transmitter?
|
||||
if (!(!GetShortGuardIntervalSupported () && (gi == 400)) ///Is SGI supported by the transmitter?
|
||||
&& (GetPhy ()->GetChannelWidth () >= chWidth) ///Is channel width supported by the transmitter?
|
||||
&& (GetPhy ()->GetMaxSupportedTxSpatialStreams () >= streams)) ///Are streams supported by the transmitter?
|
||||
{
|
||||
m_minstrelGroups[groupId].isSupported = true;
|
||||
|
||||
@@ -287,13 +292,58 @@ MinstrelHtWifiManager::DoInitialize ()
|
||||
// Check for invalid VHT MCSs and do not add time to array.
|
||||
if (IsValidMcs (GetPhy (), streams, chWidth, mode))
|
||||
{
|
||||
AddFirstMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, sgi, chWidth, mode, FIRST_MPDU_IN_AGGREGATE));
|
||||
AddMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, sgi, chWidth, mode, MIDDLE_MPDU_IN_AGGREGATE));
|
||||
AddFirstMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, gi, chWidth, mode, FIRST_MPDU_IN_AGGREGATE));
|
||||
AddMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, gi, chWidth, mode, MIDDLE_MPDU_IN_AGGREGATE));
|
||||
}
|
||||
}
|
||||
NS_LOG_DEBUG ("Initialized group " << +groupId << ": (" << +streams << "," << +sgi << "," << chWidth << ")");
|
||||
NS_LOG_DEBUG ("Initialized group " << +groupId << ": (" << +streams << "," << gi << "," << chWidth << ")");
|
||||
}
|
||||
}
|
||||
gi /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetHeSupported ())
|
||||
{
|
||||
// Initialize all HE groups
|
||||
for (uint16_t chWidth = 20; chWidth <= MAX_HE_WIDTH; chWidth *= 2)
|
||||
{
|
||||
for (int gi = 3200; gi >= 800; )
|
||||
{
|
||||
for (uint8_t streams = 1; streams <= MAX_HE_SUPPORTED_STREAMS; streams++)
|
||||
{
|
||||
uint8_t groupId = GetHeGroupId (streams, gi, chWidth);
|
||||
|
||||
m_minstrelGroups[groupId].streams = streams;
|
||||
m_minstrelGroups[groupId].gi = gi;
|
||||
m_minstrelGroups[groupId].chWidth = chWidth;
|
||||
m_minstrelGroups[groupId].type = GROUP_HE;
|
||||
m_minstrelGroups[groupId].isSupported = false;
|
||||
|
||||
// Check capabilities of the device
|
||||
if ((GetGuardInterval () <= gi) ///Is GI supported by the transmitter?
|
||||
&& (GetPhy ()->GetChannelWidth () >= chWidth) ///Is channel width supported by the transmitter?
|
||||
&& (GetPhy ()->GetMaxSupportedTxSpatialStreams () >= streams)) ///Are streams supported by the transmitter?
|
||||
{
|
||||
m_minstrelGroups[groupId].isSupported = true;
|
||||
|
||||
// Calculate tx time for all rates of the group
|
||||
WifiModeList heMcsList = GetHeDeviceMcsList ();
|
||||
for (uint8_t i = 0; i < MAX_HE_GROUP_RATES; i++)
|
||||
{
|
||||
WifiMode mode = heMcsList.at (i);
|
||||
// Check for invalid HE MCSs and do not add time to array.
|
||||
if (IsValidMcs (GetPhy (), streams, chWidth, mode))
|
||||
{
|
||||
AddFirstMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, gi, chWidth, mode, FIRST_MPDU_IN_AGGREGATE));
|
||||
AddMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, gi, chWidth, mode, MIDDLE_MPDU_IN_AGGREGATE));
|
||||
}
|
||||
}
|
||||
NS_LOG_DEBUG ("Initialized group " << +groupId << ": (" << +streams << "," << gi << "," << chWidth << ")");
|
||||
}
|
||||
}
|
||||
gi /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,13 +362,13 @@ MinstrelHtWifiManager::IsValidMcs (Ptr<WifiPhy> phy, uint8_t streams, uint16_t c
|
||||
}
|
||||
|
||||
Time
|
||||
MinstrelHtWifiManager::CalculateMpduTxDuration (Ptr<WifiPhy> phy, uint8_t streams, uint8_t sgi,
|
||||
MinstrelHtWifiManager::CalculateMpduTxDuration (Ptr<WifiPhy> phy, uint8_t streams, uint16_t gi,
|
||||
uint16_t chWidth, WifiMode mode, MpduType mpduType)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << phy << +streams << +sgi << chWidth << mode << mpduType);
|
||||
NS_LOG_FUNCTION (this << phy << +streams << gi << chWidth << mode << mpduType);
|
||||
WifiTxVector txvector;
|
||||
txvector.SetNss (streams);
|
||||
txvector.SetGuardInterval (sgi ? 400 : 800);
|
||||
txvector.SetGuardInterval (gi);
|
||||
txvector.SetChannelWidth (chWidth);
|
||||
txvector.SetNess (0);
|
||||
txvector.SetStbc (0);
|
||||
@@ -644,7 +694,7 @@ MinstrelHtWifiManager::DoReportAmpduTxStatus (WifiRemoteStation *st, uint16_t nS
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERT_MSG (station->m_isHt, "A-MPDU Tx Status called but no HT or VHT supported.");
|
||||
NS_ASSERT_MSG (station->m_isHt, "A-MPDU Tx Status called but this is a non-HT STA.");
|
||||
|
||||
NS_LOG_DEBUG ("DoReportAmpduTxStatus. TxRate=" << station->m_txrate << " SuccMpdus=" <<
|
||||
nSuccessfulMpdus << " FailedMpdus=" << nFailedMpdus);
|
||||
@@ -851,21 +901,25 @@ MinstrelHtWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
McsGroup group = m_minstrelGroups[groupId];
|
||||
|
||||
// Check consistency of rate selected.
|
||||
if ((group.sgi && !GetShortGuardIntervalSupported (station)) || group.chWidth > GetChannelWidth (station) || group.streams > GetNumberOfSupportedStreams (station))
|
||||
if (((group.type == GROUP_HE) && (group.gi < GetGuardInterval (station))) ||
|
||||
(((group.type == GROUP_HT) || (group.type == GROUP_VHT)) && (group.gi == 400) && !GetShortGuardIntervalSupported (station)) ||
|
||||
(group.chWidth > GetChannelWidth (station)) ||
|
||||
(group.streams > GetNumberOfSupportedStreams (station)))
|
||||
{
|
||||
NS_FATAL_ERROR ("Inconsistent group selected. Group: (" << +group.streams <<
|
||||
"," << +group.sgi << "," << group.chWidth << ")" <<
|
||||
"," << group.gi << "," << group.chWidth << ")" <<
|
||||
" Station capabilities: (" << GetNumberOfSupportedStreams (station) <<
|
||||
"," << GetShortGuardIntervalSupported (station) << "," << GetChannelWidth (station) << ")");
|
||||
"," << ((group.type == GROUP_HE) ? GetGuardInterval (station) : (GetShortGuardIntervalSupported (station) ? 400 : 800)) <<
|
||||
"," << GetChannelWidth (station) << ")");
|
||||
}
|
||||
WifiMode mode = GetMcsSupported (station, mcsIndex);
|
||||
uint64_t dataRate = mode.GetDataRate (group.chWidth, group.sgi ? 400 : 800, group.streams);
|
||||
uint64_t dataRate = mode.GetDataRate (group.chWidth, group.gi, group.streams);
|
||||
if (m_currentRate != dataRate && !station->m_isSampling)
|
||||
{
|
||||
NS_LOG_DEBUG ("New datarate: " << dataRate);
|
||||
m_currentRate = dataRate;
|
||||
}
|
||||
return WifiTxVector (mode, GetDefaultTxPowerLevel (), GetPreambleForTransmission (mode.GetModulationClass (), GetShortPreambleEnabled ()), group.sgi ? 400 : 800, GetNumberOfAntennas (), group.streams, GetNess (station), GetChannelWidthForTransmission (mode, group.chWidth), GetAggregation (station) && !station->m_isSampling);
|
||||
return WifiTxVector (mode, GetDefaultTxPowerLevel (), GetPreambleForTransmission (mode.GetModulationClass (), GetShortPreambleEnabled ()), group.gi, GetNumberOfAntennas (), group.streams, GetNess (station), GetChannelWidthForTransmission (mode, group.chWidth), GetAggregation (station) && !station->m_isSampling);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1082,7 +1136,7 @@ MinstrelHtWifiManager::FindRate (MinstrelHtWifiRemoteStation *station)
|
||||
* Also do not sample if the probability is already higher than 95%
|
||||
* to avoid wasting airtime.
|
||||
*/
|
||||
HtRateInfo sampleRateInfo = station->m_groupsTable[sampleGroupId].m_ratesTable[sampleRateId];
|
||||
MinstrelHtRateInfo sampleRateInfo = station->m_groupsTable[sampleGroupId].m_ratesTable[sampleRateId];
|
||||
|
||||
NS_LOG_DEBUG ("Use sample rate? MaxTpRate= " << station->m_maxTpRate << " CurrentRate= " << station->m_txrate <<
|
||||
" SampleRate= " << sampleIdx << " SampleProb= " << sampleRateInfo.ewmaProb);
|
||||
@@ -1303,7 +1357,7 @@ void
|
||||
MinstrelHtWifiManager::SetBestProbabilityRate (MinstrelHtWifiRemoteStation *station, uint16_t index)
|
||||
{
|
||||
GroupInfo *group;
|
||||
HtRateInfo rate;
|
||||
MinstrelHtRateInfo rate;
|
||||
uint8_t tmpGroupId, tmpRateId;
|
||||
double tmpTh, tmpProb;
|
||||
uint8_t groupId, rateId;
|
||||
@@ -1430,72 +1484,123 @@ MinstrelHtWifiManager::RateInit (MinstrelHtWifiRemoteStation *station)
|
||||
* Initialize groups supported by the receiver.
|
||||
*/
|
||||
NS_LOG_DEBUG ("Supported groups by station:");
|
||||
bool noSupportedGroupFound = true;
|
||||
for (uint8_t groupId = 0; groupId < m_numGroups; groupId++)
|
||||
{
|
||||
if (m_minstrelGroups[groupId].isSupported)
|
||||
{
|
||||
station->m_groupsTable[groupId].m_supported = false;
|
||||
if (!(!GetVhtSupported (station) && m_minstrelGroups[groupId].isVht) ///Is VHT supported by the receiver?
|
||||
&& (m_minstrelGroups[groupId].isVht || !GetVhtSupported (station) || !m_useVhtOnly) ///If it is an HT MCS, check if VHT only is disabled
|
||||
&& !(!GetShortGuardIntervalSupported (station) && m_minstrelGroups[groupId].sgi) ///Is SGI supported by the receiver?
|
||||
&& (GetChannelWidth (station) >= m_minstrelGroups[groupId].chWidth) ///Is channel width supported by the receiver?
|
||||
&& (GetNumberOfSupportedStreams (station) >= m_minstrelGroups[groupId].streams)) ///Are streams supported by the receiver?
|
||||
|
||||
if ((m_minstrelGroups[groupId].type == GROUP_HE) && !GetHeSupported (station))
|
||||
{
|
||||
NS_LOG_DEBUG ("Group " << +groupId << ": (" << +m_minstrelGroups[groupId].streams <<
|
||||
"," << +m_minstrelGroups[groupId].sgi << "," << m_minstrelGroups[groupId].chWidth << ")");
|
||||
//It is a HE group but the receiver does not support HE: skip
|
||||
continue;
|
||||
}
|
||||
if ((m_minstrelGroups[groupId].type == GROUP_VHT) && !GetVhtSupported (station))
|
||||
{
|
||||
//It is a VHT group but the receiver does not support VHT: skip
|
||||
continue;
|
||||
}
|
||||
if ((m_minstrelGroups[groupId].type != GROUP_HE) && GetHeSupported (station) && m_useHeOnly)
|
||||
{
|
||||
//It is not a HE group and the receiver supports HE: skip since UseHeOnly attribute is enabled
|
||||
continue;
|
||||
}
|
||||
if (!GetHeSupported (station) && (m_minstrelGroups[groupId].type != GROUP_VHT) && GetVhtSupported (station) && m_useVhtOnly)
|
||||
{
|
||||
//It is not a VHT group and the receiver supports VHT (but not HE): skip since UseVhtOnly attribute is enabled
|
||||
continue;
|
||||
}
|
||||
if (((m_minstrelGroups[groupId].type == GROUP_HT) || (m_minstrelGroups[groupId].type == GROUP_VHT))
|
||||
&& (m_minstrelGroups[groupId].gi == 400) && !GetShortGuardIntervalSupported (station))
|
||||
{
|
||||
//It is a SGI group but the receiver does not support SGI: skip
|
||||
continue;
|
||||
}
|
||||
if ((m_minstrelGroups[groupId].type == GROUP_HE) && (m_minstrelGroups[groupId].gi < GetGuardInterval (station)))
|
||||
{
|
||||
//The receiver does not support the GI: skip
|
||||
continue;
|
||||
}
|
||||
if (GetChannelWidth (station) < m_minstrelGroups[groupId].chWidth)
|
||||
{
|
||||
//The receiver does not support the channel width: skip
|
||||
continue;
|
||||
}
|
||||
if (GetNumberOfSupportedStreams (station) < m_minstrelGroups[groupId].streams)
|
||||
{
|
||||
//The receiver does not support the number of spatial streams: skip
|
||||
continue;
|
||||
}
|
||||
|
||||
station->m_groupsTable[groupId].m_supported = true; ///Group supported.
|
||||
station->m_groupsTable[groupId].m_col = 0;
|
||||
station->m_groupsTable[groupId].m_index = 0;
|
||||
NS_LOG_DEBUG ("Group: " << +groupId
|
||||
<< " type: " << m_minstrelGroups[groupId].type
|
||||
<< " streams: " << +m_minstrelGroups[groupId].streams
|
||||
<< " GI: " << m_minstrelGroups[groupId].gi
|
||||
<< " width: " << m_minstrelGroups[groupId].chWidth);
|
||||
|
||||
station->m_groupsTable[groupId].m_ratesTable = HtMinstrelRate (m_numRates); ///Create the rate list for the group.
|
||||
for (uint8_t i = 0; i < m_numRates; i++)
|
||||
noSupportedGroupFound = false;
|
||||
station->m_groupsTable[groupId].m_supported = true;
|
||||
station->m_groupsTable[groupId].m_col = 0;
|
||||
station->m_groupsTable[groupId].m_index = 0;
|
||||
|
||||
station->m_groupsTable[groupId].m_ratesTable = MinstrelHtRate (m_numRates); ///Create the rate list for the group.
|
||||
for (uint8_t i = 0; i < m_numRates; i++)
|
||||
{
|
||||
station->m_groupsTable[groupId].m_ratesTable[i].supported = false;
|
||||
}
|
||||
|
||||
// Initialize all modes supported by the remote station that belong to the current group.
|
||||
for (uint8_t i = 0; i < station->m_nModes; i++)
|
||||
{
|
||||
WifiMode mode = GetMcsSupported (station, i);
|
||||
|
||||
///Use the McsValue as the index in the rate table.
|
||||
///This way, MCSs not supported are not initialized.
|
||||
uint8_t rateId = mode.GetMcsValue ();
|
||||
if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
|
||||
{
|
||||
station->m_groupsTable[groupId].m_ratesTable[i].supported = false;
|
||||
rateId %= MAX_HT_GROUP_RATES;
|
||||
}
|
||||
|
||||
// Initialize all modes supported by the remote station that belong to the current group.
|
||||
for (uint8_t i = 0; i < station->m_nModes; i++)
|
||||
if (((m_minstrelGroups[groupId].type == GROUP_HE)
|
||||
&& (mode.GetModulationClass () == WIFI_MOD_CLASS_HE) ///If it is a HE MCS only add to a HE group.
|
||||
&& IsValidMcs (GetPhy (), m_minstrelGroups[groupId].streams, m_minstrelGroups[groupId].chWidth, mode)) ///Check validity of the HE MCS
|
||||
|| ((m_minstrelGroups[groupId].type == GROUP_VHT)
|
||||
&& (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT) ///If it is a VHT MCS only add to a VHT group.
|
||||
&& IsValidMcs (GetPhy (), m_minstrelGroups[groupId].streams, m_minstrelGroups[groupId].chWidth, mode)) ///Check validity of the VHT MCS
|
||||
|| ((m_minstrelGroups[groupId].type == GROUP_HT)
|
||||
&& (mode.GetModulationClass () == WIFI_MOD_CLASS_HT) ///If it is a HT MCS only add to a HT group.
|
||||
&& (mode.GetMcsValue () < (m_minstrelGroups[groupId].streams * 8)) ///Check if the HT MCS corresponds to groups number of streams.
|
||||
&& (mode.GetMcsValue () >= ((m_minstrelGroups[groupId].streams - 1) * 8))))
|
||||
{
|
||||
WifiMode mode = GetMcsSupported (station, i);
|
||||
NS_LOG_DEBUG ("Mode " << +i << ": " << mode);
|
||||
|
||||
///Use the McsValue as the index in the rate table.
|
||||
///This way, MCSs not supported are not initialized.
|
||||
uint8_t rateId = mode.GetMcsValue ();
|
||||
if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
|
||||
{
|
||||
rateId %= MAX_HT_GROUP_RATES;
|
||||
}
|
||||
|
||||
if ((m_minstrelGroups[groupId].isVht && mode.GetModulationClass () == WIFI_MOD_CLASS_VHT ///If it is a VHT MCS only add to a VHT group.
|
||||
&& IsValidMcs (GetPhy (), m_minstrelGroups[groupId].streams, m_minstrelGroups[groupId].chWidth, mode)) ///Check validity of the VHT MCS
|
||||
|| (!m_minstrelGroups[groupId].isVht && mode.GetModulationClass () == WIFI_MOD_CLASS_HT ///If it is a HT MCS only add to a HT group.
|
||||
&& mode.GetMcsValue () < (m_minstrelGroups[groupId].streams * 8) ///Check if the HT MCS corresponds to groups number of streams.
|
||||
&& mode.GetMcsValue () >= ((m_minstrelGroups[groupId].streams - 1) * 8)))
|
||||
{
|
||||
NS_LOG_DEBUG ("Mode " << +i << ": " << mode << " isVht: " << m_minstrelGroups[groupId].isVht);
|
||||
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].supported = true;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex = i; ///Mapping between rateId and operationalMcsSet
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].prob = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateAttempt = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateSuccess = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].numSamplesSkipped = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].successHist = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].attemptHist = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].throughput = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].perfectTxTime = GetFirstMpduTxTime (groupId, GetMcsSupported (station, i));
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].adjustedRetryCount = 0;
|
||||
CalculateRetransmits (station, groupId, rateId);
|
||||
}
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].supported = true;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex = i; ///Mapping between rateId and operationalMcsSet
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].prob = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateAttempt = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateSuccess = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].numSamplesSkipped = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].successHist = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].attemptHist = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].throughput = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].perfectTxTime = GetFirstMpduTxTime (groupId, GetMcsSupported (station, i));
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 0;
|
||||
station->m_groupsTable[groupId].m_ratesTable[rateId].adjustedRetryCount = 0;
|
||||
CalculateRetransmits (station, groupId, rateId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
///make sure at least one group is supported, otherwise we end up with an infinite loop in SetNextSample
|
||||
if (noSupportedGroupFound)
|
||||
{
|
||||
NS_FATAL_ERROR ("No supported group has been found");
|
||||
}
|
||||
SetNextSample (station); /// Select the initial sample index.
|
||||
UpdateStats (station); /// Calculate the initial high throughput rates.
|
||||
station->m_txrate = FindRate (station); /// Select the rate to use.
|
||||
@@ -1636,27 +1741,11 @@ MinstrelHtWifiManager::StatsDump (MinstrelHtWifiRemoteStation *station, uint8_t
|
||||
uint8_t numRates = m_numRates;
|
||||
McsGroup group = m_minstrelGroups[groupId];
|
||||
Time txTime;
|
||||
char giMode;
|
||||
if (group.sgi)
|
||||
{
|
||||
giMode = 'S';
|
||||
}
|
||||
else
|
||||
{
|
||||
giMode = 'L';
|
||||
}
|
||||
for (uint8_t i = 0; i < numRates; i++)
|
||||
{
|
||||
if (station->m_groupsTable[groupId].m_supported && station->m_groupsTable[groupId].m_ratesTable[i].supported)
|
||||
{
|
||||
if (!group.isVht)
|
||||
{
|
||||
of << "HT" << group.chWidth << " " << giMode << "GI " << (int)group.streams << " ";
|
||||
}
|
||||
else
|
||||
{
|
||||
of << "VHT" << group.chWidth << " " << giMode << "GI " << (int)group.streams << " ";
|
||||
}
|
||||
of << group.type << " " << group.chWidth << " " << group.gi << " " << +group.streams << " ";
|
||||
|
||||
uint16_t maxTpRate = station->m_maxTpRate;
|
||||
uint16_t maxTpRate2 = station->m_maxTpRate2;
|
||||
@@ -1688,13 +1777,13 @@ MinstrelHtWifiManager::StatsDump (MinstrelHtWifiRemoteStation *station, uint8_t
|
||||
of << ' ';
|
||||
}
|
||||
|
||||
if (!group.isVht)
|
||||
if (group.type == GROUP_HT)
|
||||
{
|
||||
of << std::setw (4) << " MCS" << (group.streams - 1) * 8 + i;
|
||||
}
|
||||
else
|
||||
{
|
||||
of << std::setw (7) << " MCS" << +i << "/" << (int) group.streams;
|
||||
of << std::setw (7) << " MCS" << +i << "/" << static_cast<int>(group.streams);
|
||||
}
|
||||
|
||||
of << " " << std::setw (3) << +idx << " ";
|
||||
@@ -1742,17 +1831,82 @@ MinstrelHtWifiManager::GetGroupId (uint16_t index)
|
||||
}
|
||||
|
||||
uint8_t
|
||||
MinstrelHtWifiManager::GetHtGroupId (uint8_t txstreams, uint8_t sgi, uint16_t chWidth)
|
||||
MinstrelHtWifiManager::GetHtGroupId (uint8_t txstreams, uint16_t gi, uint16_t chWidth)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << +txstreams << +sgi << chWidth);
|
||||
return MAX_SUPPORTED_STREAMS * 2 * (chWidth == 40 ? 1 : 0) + MAX_SUPPORTED_STREAMS * sgi + txstreams - 1;
|
||||
NS_LOG_FUNCTION (this << +txstreams << gi << chWidth);
|
||||
uint8_t giIndex = (gi == 400) ? 1 : 0;
|
||||
uint8_t widthIndex = (chWidth == 40) ? 1 : 0;
|
||||
return (MAX_HT_SUPPORTED_STREAMS * 2 * widthIndex) + (MAX_HT_SUPPORTED_STREAMS * giIndex) + txstreams - 1;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
MinstrelHtWifiManager::GetVhtGroupId (uint8_t txstreams, uint8_t sgi, uint16_t chWidth)
|
||||
MinstrelHtWifiManager::GetVhtGroupId (uint8_t txstreams, uint16_t gi, uint16_t chWidth)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << +txstreams << +sgi << chWidth);
|
||||
return MAX_HT_STREAM_GROUPS * MAX_SUPPORTED_STREAMS + MAX_SUPPORTED_STREAMS * 2 * (chWidth == 160 ? 3 : chWidth == 80 ? 2 : chWidth == 40 ? 1 : 0) + MAX_SUPPORTED_STREAMS * sgi + txstreams - 1;
|
||||
NS_LOG_FUNCTION (this << +txstreams << gi << chWidth);
|
||||
uint8_t giIndex = (gi == 400) ? 1 : 0;
|
||||
uint8_t widthIndex;
|
||||
if (chWidth == 160)
|
||||
{
|
||||
widthIndex = 3;
|
||||
}
|
||||
else if (chWidth == 80)
|
||||
{
|
||||
widthIndex = 2;
|
||||
}
|
||||
else if (chWidth == 40)
|
||||
{
|
||||
widthIndex = 1;
|
||||
}
|
||||
else //20 MHz
|
||||
{
|
||||
widthIndex = 0;
|
||||
}
|
||||
uint8_t groupId = (MAX_HT_STREAM_GROUPS * MAX_HT_SUPPORTED_STREAMS); ///add all HT groups
|
||||
groupId += (MAX_VHT_SUPPORTED_STREAMS * 2 * widthIndex) + (MAX_VHT_SUPPORTED_STREAMS * giIndex) + txstreams - 1;
|
||||
return groupId;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
MinstrelHtWifiManager::GetHeGroupId (uint8_t txstreams, uint16_t gi, uint16_t chWidth)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << +txstreams << gi << chWidth);
|
||||
uint8_t giIndex;
|
||||
if (gi == 800)
|
||||
{
|
||||
giIndex = 2;
|
||||
}
|
||||
else if (gi == 1600)
|
||||
{
|
||||
giIndex = 1;
|
||||
}
|
||||
else //3200 ns
|
||||
{
|
||||
giIndex = 0;
|
||||
}
|
||||
uint8_t widthIndex;
|
||||
if (chWidth == 160)
|
||||
{
|
||||
widthIndex = 3;
|
||||
}
|
||||
else if (chWidth == 80)
|
||||
{
|
||||
widthIndex = 2;
|
||||
}
|
||||
else if (chWidth == 40)
|
||||
{
|
||||
widthIndex = 1;
|
||||
}
|
||||
else //20 MHz
|
||||
{
|
||||
widthIndex = 0;
|
||||
}
|
||||
uint8_t groupId = (MAX_HT_STREAM_GROUPS * MAX_HT_SUPPORTED_STREAMS); ///add all HT groups
|
||||
if (GetVhtSupported ()) ///This check is needed since we do not support VHT in 2.4 GHz band
|
||||
{
|
||||
groupId += MAX_VHT_STREAM_GROUPS * MAX_VHT_SUPPORTED_STREAMS; ///add all VHT groups
|
||||
}
|
||||
groupId += (MAX_HE_SUPPORTED_STREAMS * 3 * widthIndex) + (MAX_HE_SUPPORTED_STREAMS * giIndex) + txstreams - 1;
|
||||
return groupId;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
@@ -1788,6 +1942,17 @@ MinstrelHtWifiManager::GetLowestIndex (MinstrelHtWifiRemoteStation *station, uin
|
||||
return GetIndex (groupId, rateId);
|
||||
}
|
||||
|
||||
WifiModeList
|
||||
MinstrelHtWifiManager::GetHeDeviceMcsList () const
|
||||
{
|
||||
WifiModeList heMcsList;
|
||||
for (const auto & mode : GetPhy ()->GetMcsList (WIFI_MOD_CLASS_HE))
|
||||
{
|
||||
heMcsList.push_back (mode);
|
||||
}
|
||||
return heMcsList;
|
||||
}
|
||||
|
||||
WifiModeList
|
||||
MinstrelHtWifiManager::GetVhtDeviceMcsList (void) const
|
||||
{
|
||||
|
||||
@@ -37,6 +37,39 @@ namespace ns3 {
|
||||
*/
|
||||
typedef std::map<WifiMode, Time> TxTime;
|
||||
|
||||
/**
|
||||
* \enum McsGroupType
|
||||
* \brief Available MCS group types
|
||||
*/
|
||||
enum McsGroupType
|
||||
{
|
||||
GROUP_HT = 0,
|
||||
GROUP_VHT,
|
||||
GROUP_HE
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Stream insertion operator.
|
||||
*
|
||||
* \param os the stream
|
||||
* \param type the MCS group type
|
||||
* \returns a reference to the stream
|
||||
*/
|
||||
inline std::ostream& operator<< (std::ostream& os, McsGroupType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GROUP_HT:
|
||||
return (os << "HT");
|
||||
case GROUP_VHT:
|
||||
return (os << "VHT");
|
||||
case GROUP_HE:
|
||||
return (os << "HE");
|
||||
default:
|
||||
return (os << "INVALID");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data structure to contain the information that defines a group.
|
||||
* It also contains the transmission times for all the MCS in the group.
|
||||
@@ -45,11 +78,11 @@ typedef std::map<WifiMode, Time> TxTime;
|
||||
*/
|
||||
struct McsGroup
|
||||
{
|
||||
uint8_t streams; ///< streams
|
||||
uint8_t sgi; ///< short guard interval (0 or 1)
|
||||
uint16_t chWidth; ///< channel width (MHz)
|
||||
bool isVht; ///< is VHT?
|
||||
bool isSupported; ///< is supported?
|
||||
uint8_t streams; ///< number of spatial streams
|
||||
uint16_t gi; ///< guard interval duration (nanoseconds)
|
||||
uint16_t chWidth; ///< channel width (MHz)
|
||||
McsGroupType type; ///< identifies the group, \see McsGroupType
|
||||
bool isSupported; ///< flag whether group is supported
|
||||
// To accurately account for TX times, we separate the TX time of the first
|
||||
// MPDU in an A-MPDU from the rest of the MPDUs.
|
||||
TxTime ratesTxTimeTable; ///< rates transmit time table
|
||||
@@ -66,7 +99,7 @@ struct MinstrelHtWifiRemoteStation;
|
||||
/**
|
||||
* A struct to contain all statistics information related to a data rate.
|
||||
*/
|
||||
struct HtRateInfo
|
||||
struct MinstrelHtRateInfo
|
||||
{
|
||||
/**
|
||||
* Perfect transmission time calculation, or frame calculation.
|
||||
@@ -98,9 +131,9 @@ struct HtRateInfo
|
||||
|
||||
/**
|
||||
* Data structure for a Minstrel Rate table.
|
||||
* A vector of a struct HtRateInfo.
|
||||
* A vector of a struct MinstrelHtRateInfo.
|
||||
*/
|
||||
typedef std::vector<HtRateInfo> HtMinstrelRate;
|
||||
typedef std::vector<MinstrelHtRateInfo> MinstrelHtRate;
|
||||
|
||||
/**
|
||||
* A struct to contain information of a group.
|
||||
@@ -116,7 +149,7 @@ struct GroupInfo
|
||||
uint16_t m_maxTpRate; //!< The max throughput rate of this group in bps.
|
||||
uint16_t m_maxTpRate2; //!< The second max throughput rate of this group in bps.
|
||||
uint16_t m_maxProbRate; //!< The highest success probability rate of this group in bps.
|
||||
HtMinstrelRate m_ratesTable; //!< Information about rates of this group.
|
||||
MinstrelHtRate m_ratesTable; //!< Information about rates of this group.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -129,19 +162,24 @@ typedef std::vector<struct GroupInfo> McsGroupData;
|
||||
* Constants for maximum values.
|
||||
*/
|
||||
|
||||
static const uint8_t MAX_SUPPORTED_STREAMS = 4; //!< Maximal number of streams supported by the PHY layer.
|
||||
static const uint8_t MAX_HT_STREAM_GROUPS = 4; //!< Maximal number of groups per stream in HT (2 possible channel widths and 2 possible SGI configurations).
|
||||
static const uint8_t MAX_VHT_STREAM_GROUPS = 8; //!< Maximal number of groups per stream in VHT (4 possible channel widths and 2 possible SGI configurations).
|
||||
static const uint8_t MAX_HT_GROUP_RATES = 8; //!< Number of rates (or MCS) per HT group.
|
||||
static const uint8_t MAX_VHT_GROUP_RATES = 10; //!< Number of rates (or MCS) per VHT group.
|
||||
static const uint8_t MAX_HT_WIDTH = 40; //!< Maximal channel width in MHz.
|
||||
static const uint8_t MAX_VHT_WIDTH = 160; //!< Maximal channel width in MHz.
|
||||
static const uint8_t MAX_HT_SUPPORTED_STREAMS = 4; //!< Maximal number of streams supported by the HT PHY layer.
|
||||
static const uint8_t MAX_VHT_SUPPORTED_STREAMS = 8; //!< Maximal number of streams supported by the VHT PHY layer.
|
||||
static const uint8_t MAX_HE_SUPPORTED_STREAMS = 8; //!< Maximal number of streams supported by the HE PHY layer.
|
||||
static const uint8_t MAX_HT_STREAM_GROUPS = 4; //!< Maximal number of groups per stream in HT (2 possible channel widths and 2 possible GI configurations).
|
||||
static const uint8_t MAX_VHT_STREAM_GROUPS = 8; //!< Maximal number of groups per stream in VHT (4 possible channel widths and 2 possible GI configurations).
|
||||
static const uint8_t MAX_HE_STREAM_GROUPS = 12; //!< Maximal number of groups per stream in HE (4 possible channel widths and 3 possible GI configurations).
|
||||
static const uint8_t MAX_HT_GROUP_RATES = 8; //!< Number of rates (or MCS) per HT group.
|
||||
static const uint8_t MAX_VHT_GROUP_RATES = 10; //!< Number of rates (or MCS) per VHT group.
|
||||
static const uint8_t MAX_HE_GROUP_RATES = 12; //!< Number of rates (or MCS) per HE group.
|
||||
static const uint8_t MAX_HT_WIDTH = 40; //!< Maximal channel width in MHz.
|
||||
static const uint8_t MAX_VHT_WIDTH = 160; //!< Maximal channel width in MHz.
|
||||
static const uint8_t MAX_HE_WIDTH = 160; //!< Maximal channel width in MHz.
|
||||
|
||||
/**
|
||||
* \brief Implementation of Minstrel HT Rate Control Algorithm
|
||||
* \brief Implementation of Minstrel-HT Rate Control Algorithm
|
||||
* \ingroup wifi
|
||||
*
|
||||
* Minstrel-HT is a rate adaptation mechanism for the 802.11n/ac standard
|
||||
* Minstrel-HT is a rate adaptation mechanism for the 802.11n/ac/ax standards
|
||||
* based on Minstrel, and is based on the approach of probing the channel
|
||||
* to dynamically learn about working rates that can be supported.
|
||||
* Minstrel-HT is designed for high-latency devices that implement a
|
||||
@@ -155,7 +193,7 @@ static const uint8_t MAX_VHT_WIDTH = 160; //!< Maximal channel width in M
|
||||
* Minstrel-HT adapts the MCS, channel width, number of streams, and
|
||||
* short guard interval (enabled or disabled). For keeping statistics,
|
||||
* it arranges MCS in groups, where each group is defined by the
|
||||
* tuple (streams, SGI, channel width). There is a vector of all groups
|
||||
* tuple (streams, GI, channel width). There is a vector of all groups
|
||||
* supported by the PHY layer of the transmitter; for each group, the
|
||||
* capabilities and the estimated duration of its rates are maintained.
|
||||
*
|
||||
@@ -180,10 +218,6 @@ static const uint8_t MAX_VHT_WIDTH = 160; //!< Maximal channel width in M
|
||||
*
|
||||
* When this rate control is configured but non-legacy modes are not supported,
|
||||
* Minstrel-HT uses legacy Minstrel (minstrel-wifi-manager) for rate control.
|
||||
*
|
||||
* This RAA does not support HE modes yet and will error
|
||||
* exit if the user tries to configure this RAA with a Wi-Fi MAC
|
||||
* that supports 802.11ax or higher.
|
||||
*/
|
||||
class MinstrelHtWifiManager : public WifiRemoteStationManager
|
||||
{
|
||||
@@ -244,13 +278,13 @@ private:
|
||||
*
|
||||
* \param phy pointer to the wifi PHY
|
||||
* \param streams the number of streams
|
||||
* \param sgi short guard interval enabled (0 or 1)
|
||||
* \param gi guard interval duration (nanoseconds)
|
||||
* \param chWidth the channel width (MHz)
|
||||
* \param mode the wifi mode
|
||||
* \param mpduType the type of the MPDU
|
||||
* \returns the transmit time
|
||||
*/
|
||||
Time CalculateMpduTxDuration (Ptr<WifiPhy> phy, uint8_t streams, uint8_t sgi,
|
||||
Time CalculateMpduTxDuration (Ptr<WifiPhy> phy, uint8_t streams, uint16_t gi,
|
||||
uint16_t chWidth, WifiMode mode, MpduType mpduType);
|
||||
|
||||
/**
|
||||
@@ -322,7 +356,7 @@ private:
|
||||
/**
|
||||
* Find a rate to use from Minstrel Table.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \returns the rate in bps
|
||||
*/
|
||||
uint16_t FindRate (MinstrelHtWifiRemoteStation *station);
|
||||
@@ -330,21 +364,21 @@ private:
|
||||
/**
|
||||
* Update the Minstrel Table.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
*/
|
||||
void UpdateStats (MinstrelHtWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Initialize Minstrel Table.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
*/
|
||||
void RateInit (MinstrelHtWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Return the average throughput of the MCS defined by groupId and rateId.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \param groupId the group ID
|
||||
* \param rateId the rate ID
|
||||
* \param ewmaProb the EWMA probability
|
||||
@@ -355,7 +389,7 @@ private:
|
||||
/**
|
||||
* Set index rate as maxTpRate or maxTp2Rate if is better than current values.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \param index the index
|
||||
*/
|
||||
void SetBestStationThRates (MinstrelHtWifiRemoteStation *station, uint16_t index);
|
||||
@@ -363,7 +397,7 @@ private:
|
||||
/**
|
||||
* Set index rate as maxProbRate if it is better than current value.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \param index the index
|
||||
*/
|
||||
void SetBestProbabilityRate (MinstrelHtWifiRemoteStation *station, uint16_t index);
|
||||
@@ -371,7 +405,7 @@ private:
|
||||
/**
|
||||
* Calculate the number of retransmissions to set for the index rate.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \param index the index
|
||||
*/
|
||||
void CalculateRetransmits (MinstrelHtWifiRemoteStation *station, uint16_t index);
|
||||
@@ -379,7 +413,7 @@ private:
|
||||
/**
|
||||
* Calculate the number of retransmissions to set for the (groupId, rateId) rate.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \param groupId the group ID
|
||||
* \param rateId the rate ID
|
||||
*/
|
||||
@@ -422,28 +456,28 @@ private:
|
||||
/**
|
||||
* Initialize Sample Table.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
*/
|
||||
void InitSampleTable (MinstrelHtWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Printing Sample Table.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
*/
|
||||
void PrintSampleTable (MinstrelHtWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Printing Minstrel Table.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
*/
|
||||
void PrintTable (MinstrelHtWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Print group statistics.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \param groupId the group ID
|
||||
* \param of the output file stream
|
||||
*/
|
||||
@@ -452,14 +486,14 @@ private:
|
||||
/**
|
||||
* Check for initializations.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
*/
|
||||
void CheckInit (MinstrelHtWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Count retries.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \returns the count of retries
|
||||
*/
|
||||
uint32_t CountRetries (MinstrelHtWifiRemoteStation * station);
|
||||
@@ -467,7 +501,7 @@ private:
|
||||
/**
|
||||
* Update rate.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
*/
|
||||
void UpdateRate (MinstrelHtWifiRemoteStation *station);
|
||||
|
||||
@@ -501,29 +535,39 @@ private:
|
||||
uint16_t GetIndex (uint8_t groupId, uint8_t rateId);
|
||||
|
||||
/**
|
||||
* Returns the groupId of a HT MCS with the given number of streams, if using SGI and the channel width used.
|
||||
* Returns the groupId of an HT MCS with the given number of streams, GI and channel width used.
|
||||
*
|
||||
* \param txstreams the number of streams
|
||||
* \param sgi short guard interval enabled (0 or 1)
|
||||
* \param gi guard interval duration (nanoseconds)
|
||||
* \param chWidth the channel width (MHz)
|
||||
* \returns the HT group ID
|
||||
*/
|
||||
uint8_t GetHtGroupId (uint8_t txstreams, uint8_t sgi, uint16_t chWidth);
|
||||
uint8_t GetHtGroupId (uint8_t txstreams, uint16_t gi, uint16_t chWidth);
|
||||
|
||||
/**
|
||||
* Returns the groupId of a VHT MCS with the given number of streams, if using SGI and the channel width used.
|
||||
* Returns the groupId of a VHT MCS with the given number of streams, GI and channel width used.
|
||||
*
|
||||
* \param txstreams the number of streams
|
||||
* \param sgi short guard interval enabled (0 or 1)
|
||||
* \param gi guard interval duration (nanoseconds)
|
||||
* \param chWidth the channel width (MHz)
|
||||
* \returns the VHT group ID
|
||||
*/
|
||||
uint8_t GetVhtGroupId (uint8_t txstreams, uint8_t sgi, uint16_t chWidth);
|
||||
uint8_t GetVhtGroupId (uint8_t txstreams, uint16_t gi, uint16_t chWidth);
|
||||
|
||||
/**
|
||||
* Returns the groupId of an HE MCS with the given number of streams, GI and channel width used.
|
||||
*
|
||||
* \param txstreams the number of streams
|
||||
* \param gi guard interval duration (nanoseconds)
|
||||
* \param chWidth the channel width (MHz)
|
||||
* \returns the HE group ID
|
||||
*/
|
||||
uint8_t GetHeGroupId (uint8_t txstreams, uint16_t gi, uint16_t chWidth);
|
||||
|
||||
/**
|
||||
* Returns the lowest global index of the rates supported by the station.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \returns the lowest global index
|
||||
*/
|
||||
uint16_t GetLowestIndex (MinstrelHtWifiRemoteStation *station);
|
||||
@@ -531,12 +575,18 @@ private:
|
||||
/**
|
||||
* Returns the lowest global index of the rates supported by in the group.
|
||||
*
|
||||
* \param station the minstrel HT wifi remote station
|
||||
* \param station the Minstrel-HT wifi remote station
|
||||
* \param groupId the group ID
|
||||
* \returns the lowest global index
|
||||
*/
|
||||
uint16_t GetLowestIndex (MinstrelHtWifiRemoteStation *station, uint8_t groupId);
|
||||
|
||||
/**
|
||||
* Returns a list of only the HE MCS supported by the device.
|
||||
* \returns the list of the HE MCS supported
|
||||
*/
|
||||
WifiModeList GetHeDeviceMcsList () const;
|
||||
|
||||
/**
|
||||
* Returns a list of only the VHT MCS supported by the device.
|
||||
* \returns the list of the VHT MCS supported
|
||||
@@ -558,11 +608,12 @@ private:
|
||||
uint8_t m_numGroups; //!< Number of groups Minstrel should consider.
|
||||
uint8_t m_numRates; //!< Number of rates per group Minstrel should consider.
|
||||
bool m_useVhtOnly; //!< If only VHT MCS should be used, instead of HT and VHT.
|
||||
bool m_useHeOnly; //!< If only HE MCS should be used, instead of HT, VHT and HE.
|
||||
bool m_printStats; //!< If statistics table should be printed.
|
||||
|
||||
MinstrelMcsGroups m_minstrelGroups; //!< Global array for groups information.
|
||||
|
||||
Ptr<MinstrelWifiManager> m_legacyManager; //!< Pointer to an instance of MinstrelWifiManager. Used when 802.11n/ac not supported.
|
||||
Ptr<MinstrelWifiManager> m_legacyManager; //!< Pointer to an instance of MinstrelWifiManager. Used when 802.11n/ac/ax not supported.
|
||||
|
||||
Ptr<UniformRandomVariable> m_uniformRandomVariable; //!< Provides uniform random variables.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user