38 #include "ns3/packet.h"
39 #include "ns3/simulator.h"
41 #include "ns3/random-variable-stream.h"
43 #include "ns3/wifi-mac.h"
44 #include "ns3/wifi-phy.h"
46 #define Min(a,b) ((a < b) ? a : b)
47 #define Max(a,b) ((a > b) ? a : b)
78 static TypeId tid =
TypeId (
"ns3::MinstrelHtWifiManager")
80 .AddConstructor<MinstrelHtWifiManager> ()
81 .SetGroupName (
"Wifi")
82 .AddAttribute (
"UpdateStatistics",
83 "The interval between updating statistics table ",
87 .AddAttribute (
"LegacyUpdateStatistics",
88 "The interval between updating statistics table (for legacy Minstrel) ",
92 .AddAttribute (
"LookAroundRate",
93 "The percentage to try other rates (for legacy Minstrel)",
96 MakeUintegerChecker<uint8_t>(0, 100))
97 .AddAttribute (
"EWMA",
101 MakeUintegerChecker<uint8_t>(0, 100))
102 .AddAttribute (
"SampleColumn",
103 "The number of columns used for sampling",
106 MakeUintegerChecker <uint8_t> ())
107 .AddAttribute (
"PacketLength",
108 "The packet length used for calculating mode TxTime (bytes)",
111 MakeUintegerChecker <uint32_t> ())
112 .AddAttribute (
"UseLatestAmendmentOnly",
113 "Use only the latest amendment when it is supported by both peers",
117 .AddAttribute (
"PrintStats",
118 "Control the printing of the statistics table",
122 .AddTraceSource (
"Rate",
123 "Traced value for rate changes (b/s)",
125 "ns3::TracedValueCallback::Uint64")
158 int64_t numStreamsAssigned = 0;
160 numStreamsAssigned++;
162 return numStreamsAssigned;
221 for (uint16_t chWidth = 20; chWidth <=
MAX_HT_WIDTH; chWidth *= 2)
223 for (
int gi = 800; gi >= 400; )
238 && (
GetPhy ()->GetMaxSupportedTxSpatialStreams () >= streams))
247 WifiMode mode = htMcsList[deviceIndex];
251 NS_LOG_DEBUG (
"Initialized group " << +groupId <<
": (" << +streams <<
"," << gi <<
"," << chWidth <<
")");
261 for (uint16_t chWidth = 20; chWidth <=
MAX_VHT_WIDTH; chWidth *= 2)
263 for (
int gi = 800; gi >= 400; )
278 && (
GetPhy ()->GetMaxSupportedTxSpatialStreams () >= streams))
294 NS_LOG_DEBUG (
"Initialized group " << +groupId <<
": (" << +streams <<
"," << gi <<
"," << chWidth <<
")");
305 for (uint16_t chWidth = 20; chWidth <=
MAX_HE_WIDTH; chWidth *= 2)
307 for (
int gi = 3200; gi >= 800; )
322 && (
GetPhy ()->GetMaxSupportedTxSpatialStreams () >= streams))
338 NS_LOG_DEBUG (
"Initialized group " << +groupId <<
": (" << +streams <<
"," << gi <<
"," << chWidth <<
")");
353 txvector.
SetNss (streams);
365 txvector.
SetNss (streams);
389 m_minstrelGroups[groupId].ratesFirstMpduTxTimeTable.insert (std::make_pair (mode, t));
405 m_minstrelGroups[groupId].ratesTxTimeTable.insert (std::make_pair (mode, t));
566 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt++;
573 double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss)
575 NS_LOG_FUNCTION (
this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
607 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess++;
608 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt++;
681 double rxSnr,
double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss)
683 NS_LOG_FUNCTION (
this << st << nSuccessfulMpdus << nFailedMpdus << rxSnr << dataSnr << dataChannelWidth << +dataNss);
695 nSuccessfulMpdus <<
" FailedMpdus=" << nFailedMpdus);
698 station->
m_ampduLen += nSuccessfulMpdus + nFailedMpdus;
704 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess += nSuccessfulMpdus;
705 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt += nSuccessfulMpdus + nFailedMpdus;
786 station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount))
794 station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount +
795 station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount))
819 station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount)
892 uint8_t mcsIndex = station->
m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex;
894 NS_LOG_DEBUG (
"DoGetDataMode rateId= " << +rateId <<
" groupId= " << +groupId <<
" mode= " <<
GetMcsSupported (station, mcsIndex));
905 "," << group.
gi <<
"," << group.
chWidth <<
")" <<
911 WifiTxVector txVector {mode,
GetDefaultTxPowerLevel (),
GetPreambleForTransmission (mode.
GetModulationClass (),
GetShortPreambleEnabled ()), group.
gi,
GetNumberOfAntennas (), group.
streams,
GetNess (station),
GetChannelWidthForTransmission (mode, group.
chWidth),
GetAggregation (station) && !station->
m_isSampling};
957 uint8_t mcsIndex = station->
m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex;
964 bool rateFound =
false;
966 for (uint8_t i = 0; i < nBasicRates; i++)
969 if (rate <= lastDataRate)
979 for (
const auto & mode :
phy->GetModeList ())
981 uint64_t rate = mode.GetDataRate (20);
982 if (rate <= lastDataRate)
1010 uint32_t maxRetries;
1023 NS_LOG_DEBUG (
"No re-transmission allowed. Retries: " << station->
m_longRetry <<
" Max retries: " << maxRetries);
1045 return station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].retryCount +
1046 station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount +
1047 station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount;
1051 return 1 + station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTp2RateId].retryCount +
1052 station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount;
1061 uint8_t index = station->
m_groupsTable[sampleGroup].m_index;
1064 uint16_t rateIndex =
GetIndex (sampleGroup, sampleIndex);
1122 uint8_t sampleGroupId =
GetGroupId (sampleIdx);
1123 uint8_t sampleRateId =
GetRateId (sampleIdx);
1126 if (station->
m_groupsTable[sampleGroupId].m_supported && station->
m_groupsTable[sampleGroupId].m_ratesTable[sampleRateId].supported)
1138 " SampleRate= " << sampleIdx <<
" SampleProb= " << sampleRateInfo.
ewmaProb);
1159 Time maxTp2Duration = station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].perfectTxTime;
1160 Time maxProbDuration = station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].perfectTxTime;
1162 NS_LOG_DEBUG (
"Use sample rate? SampleDuration= " << sampleDuration <<
" maxTp2Duration= " << maxTp2Duration <<
1163 " maxProbDuration= " << maxProbDuration <<
" sampleStreams= " << +sampleStreams <<
1164 " maxTpStreams= " << +maxTpStreams);
1165 if (sampleDuration < maxTp2Duration || (sampleStreams < maxTpStreams && sampleDuration < maxProbDuration))
1173 NS_LOG_DEBUG (
"FindRate " <<
"sampleRate=" << sampleIdx);
1188 NS_LOG_DEBUG (
"FindRate " <<
"sampleRate=" << sampleIdx);
1247 station->
m_groupsTable[j].m_ratesTable[i].retryUpdated =
false;
1250 "\t attempt=" << station->
m_groupsTable[j].m_ratesTable[i].numRateAttempt <<
1251 "\t success=" << station->
m_groupsTable[j].m_ratesTable[i].numRateSuccess);
1254 if (station->
m_groupsTable[j].m_ratesTable[i].numRateAttempt > 0)
1256 station->
m_groupsTable[j].m_ratesTable[i].numSamplesSkipped = 0;
1261 tempProb = (100 * station->
m_groupsTable[j].m_ratesTable[i].numRateSuccess) / station->
m_groupsTable[j].m_ratesTable[i].numRateAttempt;
1266 if (station->
m_groupsTable[j].m_ratesTable[i].successHist == 0)
1268 station->
m_groupsTable[j].m_ratesTable[i].ewmaProb = tempProb;
1273 tempProb, station->
m_groupsTable[j].m_ratesTable[i].ewmaProb,
1277 station->
m_groupsTable[j].m_ratesTable[i].ewmaProb = tempProb;
1287 station->
m_groupsTable[j].m_ratesTable[i].numSamplesSkipped++;
1293 station->
m_groupsTable[j].m_ratesTable[i].numRateSuccess = 0;
1294 station->
m_groupsTable[j].m_ratesTable[i].numRateAttempt = 0;
1296 if (station->
m_groupsTable[j].m_ratesTable[i].throughput != 0)
1340 Time txTime = station->
m_groupsTable[groupId].m_ratesTable[rateId].perfectTxTime;
1357 uint8_t tmpGroupId, tmpRateId;
1358 double tmpTh, tmpProb;
1359 uint8_t groupId, rateId;
1362 uint8_t maxGPGroupId, maxGPRateId;
1372 tmpProb = station->
m_groupsTable[tmpGroupId].m_ratesTable[tmpRateId].ewmaProb;
1373 tmpTh = station->
m_groupsTable[tmpGroupId].m_ratesTable[tmpRateId].throughput;
1377 currentTh = station->
m_groupsTable[groupId].m_ratesTable[rateId].throughput;
1378 if (currentTh > tmpTh)
1385 maxGPTh = station->
m_groupsTable[maxGPGroupId].m_ratesTable[maxGPRateId].throughput;
1387 if (currentTh > maxGPTh)
1416 uint8_t groupId, rateId;
1418 uint8_t maxTpGroupId, maxTpRateId;
1419 uint8_t maxTp2GroupId, maxTp2RateId;
1420 double maxTpTh, maxTpProb;
1421 double maxTp2Th, maxTp2Prob;
1425 prob = station->
m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb;
1426 th = station->
m_groupsTable[groupId].m_ratesTable[rateId].throughput;
1430 maxTpProb = station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].ewmaProb;
1431 maxTpTh = station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].throughput;
1435 maxTp2Prob = station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].ewmaProb;
1436 maxTp2Th = station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].throughput;
1438 if (th > maxTpTh || (th == maxTpTh && prob > maxTpProb))
1443 else if (th > maxTp2Th || (th == maxTp2Th && prob > maxTp2Prob))
1454 maxTpTh = station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].throughput;
1458 maxTp2Prob = group->
m_ratesTable[maxTp2RateId].ewmaProb;
1459 maxTp2Th = station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].throughput;
1461 if (th > maxTpTh || (th == maxTpTh && prob > maxTpProb))
1466 else if (th > maxTp2Th || (th == maxTp2Th && prob > maxTp2Prob))
1483 bool noSupportedGroupFound =
true;
1484 for (uint8_t groupId = 0; groupId <
m_numGroups; groupId++)
1538 noSupportedGroupFound =
false;
1546 station->
m_groupsTable[groupId].m_ratesTable[i].supported =
false;
1550 for (uint8_t i = 0; i < station->
m_nModes; i++)
1575 station->
m_groupsTable[groupId].m_ratesTable[rateId].supported =
true;
1576 station->
m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex = i;
1577 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt = 0;
1578 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess = 0;
1579 station->
m_groupsTable[groupId].m_ratesTable[rateId].prob = 0;
1580 station->
m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb = 0;
1581 station->
m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateAttempt = 0;
1582 station->
m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateSuccess = 0;
1583 station->
m_groupsTable[groupId].m_ratesTable[rateId].numSamplesSkipped = 0;
1584 station->
m_groupsTable[groupId].m_ratesTable[rateId].successHist = 0;
1585 station->
m_groupsTable[groupId].m_ratesTable[rateId].attemptHist = 0;
1586 station->
m_groupsTable[groupId].m_ratesTable[rateId].throughput = 0;
1588 station->
m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 0;
1589 station->
m_groupsTable[groupId].m_ratesTable[rateId].adjustedRetryCount = 0;
1596 if (noSupportedGroupFound)
1611 if (!station->
m_groupsTable[groupId].m_ratesTable[rateId].retryUpdated)
1623 uint32_t cwMax = 1023;
1624 Time cwTime, txTime, dataTxTime;
1628 if (station->
m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb < 1)
1630 station->
m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 1;
1634 station->
m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 2;
1635 station->
m_groupsTable[groupId].m_ratesTable[rateId].retryUpdated =
true;
1641 cwTime = (cw / 2) * slotTime;
1642 cw =
Min ((cw + 1) * 2, cwMax);
1643 cwTime += (cw / 2) * slotTime;
1644 cw =
Min ((cw + 1) * 2, cwMax);
1647 txTime = cwTime + 2 * (dataTxTime + ackTime);
1653 cwTime = (cw / 2) * slotTime;
1654 cw =
Min ((cw + 1) * 2, cwMax);
1657 txTime += cwTime + ackTime + dataTxTime;
1660 && (++station->
m_groupsTable[groupId].m_ratesTable[rateId].retryCount < 7));
1667 double diff, incr, tmp;
1670 diff = currentProb - ewmaProb;
1671 incr = (100 - weight) * diff / 100;
1672 tmp = oldEwmsd * oldEwmsd;
1673 tmp = weight * (tmp + diff * incr) / 100;
1691 for (uint8_t i = 0; i < numSampleRates; i++ )
1698 newIndex = (i + uv) % numSampleRates;
1715 std::ostringstream tmp;
1717 station->
m_statsFile.open (tmp.str ().c_str (), std::ios::out);
1720 station->
m_statsFile <<
" best ____________rate__________ ________statistics________ ________last_______ ______sum-of________\n" <<
1721 " mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n";
1740 for (uint8_t i = 0; i < numRates; i++)
1750 uint16_t idx =
GetIndex (groupId, i);
1751 if (idx == maxTpRate)
1759 if (idx == maxTpRate2)
1767 if (idx == maxProbRate)
1778 of << std::setw (4) <<
" MCS" << (group.
streams - 1) * 8 + i;
1782 of << std::setw (7) <<
" MCS" << +i <<
"/" <<
static_cast<int>(group.
streams);
1785 of <<
" " << std::setw (3) << +idx <<
" ";
1792 std::setw (7) << station->
m_groupsTable[groupId].m_ratesTable[i].throughput / 100 <<
" " <<
1793 std::setw (7) << station->
m_groupsTable[groupId].m_ratesTable[i].ewmaProb <<
" " <<
1794 std::setw (7) << station->
m_groupsTable[groupId].m_ratesTable[i].ewmsdProb <<
" " <<
1795 std::setw (7) << station->
m_groupsTable[groupId].m_ratesTable[i].prob <<
" " <<
1796 std::setw (2) << station->
m_groupsTable[groupId].m_ratesTable[i].retryCount <<
" " <<
1797 std::setw (3) << station->
m_groupsTable[groupId].m_ratesTable[i].prevNumRateSuccess <<
" " <<
1798 std::setw (3) << station->
m_groupsTable[groupId].m_ratesTable[i].prevNumRateAttempt <<
" " <<
1799 std::setw (9) << station->
m_groupsTable[groupId].m_ratesTable[i].successHist <<
" " <<
1800 std::setw (9) << station->
m_groupsTable[groupId].m_ratesTable[i].attemptHist <<
"\n";
1833 uint8_t giIndex = (gi == 400) ? 1 : 0;
1834 uint8_t widthIndex = (chWidth == 40) ? 1 : 0;
1842 uint8_t giIndex = (gi == 400) ? 1 : 0;
1848 else if (chWidth == 80)
1852 else if (chWidth == 40)
1874 else if (gi == 1600)
1887 else if (chWidth == 80)
1891 else if (chWidth == 40)
1913 uint8_t groupId = 0;
1915 while (groupId < m_numGroups && !station->m_groupsTable[groupId].m_supported)
1919 while (rateId < m_numRates && !station->m_groupsTable[groupId].m_ratesTable[rateId].supported)
1933 while (rateId < m_numRates && !station->m_groupsTable[groupId].m_ratesTable[rateId].supported)
1947 heMcsList.push_back (mode);
1958 vhtMcsList.push_back (mode);
1969 htMcsList.push_back (mode);
AttributeValue implementation for Boolean.
Implementation of Minstrel-HT Rate Control Algorithm.
uint32_t CountRetries(MinstrelHtWifiRemoteStation *station)
Count retries.
uint32_t m_frameLength
Frame length used for calculate modes TxTime in bytes.
void InitSampleTable(MinstrelHtWifiRemoteStation *station)
Initialize Sample Table.
bool m_printStats
If statistics table should be printed.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode) override
This method is a pure virtual method that must be implemented by the sub-class.
bool DoNeedRetransmission(WifiRemoteStation *st, Ptr< const Packet > packet, bool normally) override
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station) override
MinstrelMcsGroups m_minstrelGroups
Global array for groups information.
void AddMpduTxTime(uint8_t groupId, WifiMode mode, Time t)
Save a TxTime to the vector of groups.
void SetNextSample(MinstrelHtWifiRemoteStation *station)
Set the next sample from Sample Table.
uint8_t m_numRates
Number of rates per group Minstrel should consider.
uint8_t m_nSampleCol
Number of sample columns.
void DoInitialize(void) override
Initialize() implementation.
void RateInit(MinstrelHtWifiRemoteStation *station)
Initialize Minstrel Table.
void SetBestStationThRates(MinstrelHtWifiRemoteStation *station, uint16_t index)
Set index rate as maxTpRate or maxTp2Rate if is better than current values.
WifiModeList GetHtDeviceMcsList(void) const
Returns a list of only the HT MCS supported by the device.
void PrintTable(MinstrelHtWifiRemoteStation *station)
Printing Minstrel Table.
void StatsDump(MinstrelHtWifiRemoteStation *station, uint8_t groupId, std::ofstream &of)
Print group statistics.
void DoReportAmpduTxStatus(WifiRemoteStation *station, uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus, double rxSnr, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss) override
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
double CalculateThroughput(MinstrelHtWifiRemoteStation *station, uint8_t groupId, uint8_t rateId, double ewmaProb)
Return the average throughput of the MCS defined by groupId and rateId.
WifiModeList GetVhtDeviceMcsList(void) const
Returns a list of only the VHT MCS supported by the device.
void AddFirstMpduTxTime(uint8_t groupId, WifiMode mode, Time t)
Save a TxTime to the vector of groups.
double CalculateEwmsd(double oldEwmsd, double currentProb, double ewmaProb, double weight)
Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation.
void DoReportDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
void SetBestProbabilityRate(MinstrelHtWifiRemoteStation *station, uint16_t index)
Set index rate as maxProbRate if it is better than current value.
WifiModeList GetHeDeviceMcsList() const
Returns a list of only the HE MCS supported by the device.
Time m_updateStats
How frequent do we calculate the stats.
TracedValue< uint64_t > m_currentRate
Trace rate changes.
uint16_t GetLowestIndex(MinstrelHtWifiRemoteStation *station)
Returns the lowest global index of the rates supported by the station.
Time CalculateMpduTxDuration(Ptr< WifiPhy > phy, uint8_t streams, uint16_t gi, uint16_t chWidth, WifiMode mode, MpduType mpduType)
Estimates the TxTime of a frame with a given mode and group (stream, guard interval and channel width...
void CheckInit(MinstrelHtWifiRemoteStation *station)
Check for initializations.
void UpdateRetry(MinstrelHtWifiRemoteStation *station)
Update the number of retries and reset accordingly.
Time GetFirstMpduTxTime(uint8_t groupId, WifiMode mode) const
Obtain the TxTime saved in the group information.
Time GetMpduTxTime(uint8_t groupId, WifiMode mode) const
Obtain the TxTime saved in the group information.
uint8_t m_numGroups
Number of groups Minstrel should consider.
void CalculateRetransmits(MinstrelHtWifiRemoteStation *station, uint16_t index)
Calculate the number of retransmissions to set for the index rate.
void SetupPhy(const Ptr< WifiPhy > phy) override
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
void DoReportDataOk(WifiRemoteStation *station, double ackSnr, WifiMode ackMode, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss) override
This method is a pure virtual method that must be implemented by the sub-class.
uint8_t m_ewmaLevel
Exponential weighted moving average level (or coefficient).
uint16_t FindRate(MinstrelHtWifiRemoteStation *station)
Find a rate to use from Minstrel Table.
uint8_t m_lookAroundRate
The % to try other rates than our current rate.
void UpdateRate(MinstrelHtWifiRemoteStation *station)
Update rate.
uint8_t GetRateId(uint16_t index)
Return the rateId inside a group, from the global index.
Time m_legacyUpdateStats
How frequent do we calculate the stats for legacy MinstrelWifiManager.
uint8_t GetGroupId(uint16_t index)
Return the groupId from the global index.
uint8_t GetVhtGroupId(uint8_t txstreams, uint16_t gi, uint16_t chWidth)
Returns the groupId of a VHT MCS with the given number of streams, GI and channel width used.
uint8_t GetHtGroupId(uint8_t txstreams, uint16_t gi, uint16_t chWidth)
Returns the groupId of an HT MCS with the given number of streams, GI and channel width used.
WifiRemoteStation * DoCreateStation(void) const override
void DoReportRtsOk(WifiRemoteStation *station, double ctsSnr, WifiMode ctsMode, double rtsSnr) override
This method is a pure virtual method that must be implemented by the sub-class.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
uint16_t GetNextSample(MinstrelHtWifiRemoteStation *station)
Getting the next sample from Sample Table.
void UpdateStats(MinstrelHtWifiRemoteStation *station)
Update the Minstrel Table.
uint16_t GetIndex(uint8_t groupId, uint8_t rateId)
Returns the global index corresponding to the groupId and rateId.
virtual ~MinstrelHtWifiManager()
Ptr< MinstrelWifiManager > m_legacyManager
Pointer to an instance of MinstrelWifiManager.
uint8_t GetHeGroupId(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.
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station) override
bool IsValidMcs(Ptr< WifiPhy > phy, uint8_t streams, uint16_t chWidth, WifiMode mode)
Check the validity of a combination of number of streams, chWidth and mode.
void SetupMac(const Ptr< WifiMac > mac) override
Set up MAC associated with this device since it is the object that knows the full set of timing param...
void DoReportFinalDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
static TypeId GetTypeId(void)
Get the type ID.
void UpdatePacketCounters(MinstrelHtWifiRemoteStation *station, uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus)
Update the number of sample count variables.
void DoReportFinalRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
bool m_useLatestAmendmentOnly
Flag if only the latest supported amendment by both peers should be used.
void DoReportRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static Time Now(void)
Return the current simulation virtual time.
Simulation virtual time values and global simulation resolution.
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
represent a single transmission mode
uint64_t GetNonHtReferenceRate(void) const
uint8_t GetMcsValue(void) const
WifiModulationClass GetModulationClass() const
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
static Time GetPayloadDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, MpduType mpdutype=NORMAL_MPDU, uint16_t staId=SU_STA_ID)
Time GetSlot(void) const
Return the slot duration for this PHY.
Time GetBlockAckTxTime(void) const
Return the estimated BlockAck TX time for this PHY.
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
hold a list of per-remote-station state.
uint8_t GetNumberOfSupportedStreams(Mac48Address address) const
Return the number of spatial streams supported by the station.
uint8_t GetNess(const WifiRemoteStation *station) const
uint16_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
bool GetVhtSupported(void) const
Return whether the device has VHT capability support enabled.
Ptr< WifiPhy > GetPhy(void) const
Return the WifiPhy.
uint8_t GetNBasicModes(void) const
Return the number of basic modes we support.
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
bool GetShortPreambleEnabled(void) const
Return whether the device uses short PHY preambles.
uint8_t GetDefaultTxPowerLevel(void) const
uint8_t GetNMcsSupported(Mac48Address address) const
Return the number of MCS supported by the station.
WifiMode GetBasicMode(uint8_t i) const
Return a basic mode from the set of basic modes.
virtual void SetupPhy(const Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
bool GetHeSupported(void) const
Return whether the device has HE capability support enabled.
WifiMode GetMcsSupported(const WifiRemoteStation *station, uint8_t i) const
Return the WifiMode supported by the specified station at the specified index.
bool GetShortGuardIntervalSupported(void) const
Return whether the device has SGI support enabled.
bool GetHtSupported(void) const
Return whether the device has HT capability support enabled.
virtual void SetupMac(const Ptr< WifiMac > mac)
Set up MAC associated with this device since it is the object that knows the full set of timing param...
uint16_t GetGuardInterval(void) const
Return the supported HE guard interval duration (in nanoseconds).
uint8_t GetNumberOfAntennas(void) const
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetStbc(bool stbc)
Sets if STBC is being used.
void SetNess(uint8_t ness)
Sets the Ness number.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
bool IsValid(void) const
The standard disallows certain combinations of WifiMode, number of spatial streams,...
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
MpduType
The type of an MPDU.
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ FIRST_MPDU_IN_AGGREGATE
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate.
@ MIDDLE_MPDU_IN_AGGREGATE
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const uint8_t MAX_HT_GROUP_RATES
Number of rates (or MCS) per HT group.
static const uint8_t MAX_VHT_STREAM_GROUPS
Maximal number of groups per stream in VHT (4 possible channel widths and 2 possible GI configuration...
std::vector< RateInfo > MinstrelRate
Data structure for a Minstrel Rate table A vector of a struct RateInfo.
std::vector< McsGroup > MinstrelMcsGroups
Data structure for a table of group definitions.
static const uint8_t MAX_VHT_GROUP_RATES
Number of rates (or MCS) per VHT group.
static const uint8_t MAX_VHT_SUPPORTED_STREAMS
Maximal number of streams supported by the VHT PHY layer.
static const uint8_t MAX_HT_SUPPORTED_STREAMS
Constants for maximum values.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
uint16_t GetChannelWidthForTransmission(WifiMode mode, uint16_t maxAllowedChannelWidth)
Return the channel width that is allowed based on the selected mode and the given maximum channel wid...
static const uint8_t MAX_HE_GROUP_RATES
Number of rates (or MCS) per HE group.
static const uint8_t MAX_HT_WIDTH
Maximal channel width in MHz.
static const uint8_t MAX_HT_STREAM_GROUPS
Maximal number of groups per stream in HT (2 possible channel widths and 2 possible GI configurations...
static const uint8_t MAX_HE_STREAM_GROUPS
Maximal number of groups per stream in HE (4 possible channel widths and 3 possible GI configurations...
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble)
Return the preamble to be used for the transmission.
std::vector< MinstrelHtRateInfo > MinstrelHtRate
Data structure for a Minstrel Rate table.
std::vector< WifiMode > WifiModeList
In various parts of the code, folk are interested in maintaining a list of transmission modes.
std::vector< std::vector< uint8_t > > SampleRate
Data structure for a Sample Rate table A vector of a vector uint8_t.
static const uint8_t MAX_HE_WIDTH
Maximal channel width in MHz.
std::vector< struct GroupInfo > McsGroupData
Data structure for a table of groups.
static const uint8_t MAX_VHT_WIDTH
Maximal channel width in MHz.
static const uint8_t MAX_HE_SUPPORTED_STREAMS
Maximal number of streams supported by the HE PHY layer.
A struct to contain information of a group.
MinstrelHtRate m_ratesTable
Information about rates of this group.
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.
uint16_t m_maxTpRate
The max throughput rate of this group in bps.
Data structure to contain the information that defines a group.
uint16_t chWidth
channel width (MHz)
uint16_t gi
guard interval duration (nanoseconds)
McsGroupType type
identifies the group,
uint8_t streams
number of spatial streams
A struct to contain all statistics information related to a data rate.
Time perfectTxTime
Perfect transmission time calculation, or frame calculation.
double ewmaProb
Exponential weighted moving average of probability.
uint32_t numSamplesSkipped
Number of times this rate statistics were not updated because no attempts have been made.
MinstrelHtWifiRemoteStation structure.
McsGroupData m_groupsTable
Table of groups with stats.
uint32_t m_sampleCount
Max number of samples per update interval.
uint8_t m_sampleGroup
The group that the sample rate belongs to.
uint32_t m_ampduPacketCount
Number of A-MPDUs transmitted.
uint32_t m_numSamplesSlow
Number of times a slow rate was sampled.
uint32_t m_sampleTries
Number of sample tries after waiting sampleWait.
std::ofstream m_statsFile
File where statistics table is written.
uint32_t m_sampleWait
How many transmission attempts to wait until a new sample.
bool m_isHt
If the station is HT capable.
uint32_t m_avgAmpduLen
Average number of MPDUs in an A-MPDU.
uint32_t m_ampduLen
Number of MPDUs in an A-MPDU.
hold per-remote-station state for Minstrel Wifi manager.
uint16_t m_maxTpRate2
second highest throughput rate in bps
Time m_nextStatsUpdate
10 times every second
bool m_initialized
for initializing tables
uint16_t m_sampleRate
current sample rate in bps
uint8_t m_index
vector index
uint16_t m_txrate
current transmit rate in bps
int m_totalPacketsCount
total number of packets as of now
bool m_isSampling
a flag to indicate we are currently sampling
MinstrelRate m_minstrelTable
minstrel table
uint32_t m_shortRetry
short retries such as control packets
uint16_t m_maxTpRate
the current throughput rate in bps
bool m_sampleDeferred
a flag to indicate sample rate is on the second stage
uint8_t m_nModes
number of modes supported
SampleRate m_sampleTable
sample table
int m_samplePacketsCount
how many packets we have sample so far
uint8_t m_col
To keep track of the current position in the our random sample table going row by row from 1st column...
uint32_t m_longRetry
long retries such as data packets
uint16_t m_maxProbRate
rate with highest probability of success in bps
hold per-remote-station state.
WifiRemoteStationState * m_state
Remote station state.
Mac48Address m_address
Mac48Address of the remote station.