39 #include "ns3/random-variable-stream.h"
40 #include "ns3/simulator.h"
42 #include "ns3/uinteger.h"
43 #include "ns3/double.h"
44 #include "ns3/wifi-mac.h"
45 #include "ns3/assert.h"
46 #include "ns3/boolean.h"
47 #include "ns3/string.h"
52 #define Min(a,b) ((a < b) ? a : b)
53 #define Max(a,b) ((a > b) ? a : b)
88 std::vector<struct HtRateInfo> ().swap (
m_groupsTable[j].m_ratesTable);
100 static TypeId tid =
TypeId (
"ns3::MinstrelHtWifiManager")
102 .AddConstructor<MinstrelHtWifiManager> ()
103 .SetGroupName (
"Wifi")
104 .AddAttribute (
"UpdateStatistics",
105 "The interval between updating statistics table ",
109 .AddAttribute (
"LookAroundRate",
110 "The percentage to try other rates (for legacy Minstrel)",
113 MakeDoubleChecker<double> (0, 100))
114 .AddAttribute (
"EWMA",
118 MakeDoubleChecker<double> (0, 100))
119 .AddAttribute (
"SampleColumn",
120 "The number of columns used for sampling",
123 MakeUintegerChecker <uint32_t> ())
124 .AddAttribute (
"PacketLength",
125 "The packet length used for calculating mode TxTime",
128 MakeUintegerChecker <uint32_t> ())
129 .AddAttribute (
"UseVhtOnly",
130 "Use only VHT MCSs (and not HT) when VHT is available",
134 .AddAttribute (
"PrintStats",
135 "Control the printing of the statistics table",
139 .AddTraceSource (
"RateChange",
140 "The transmission rate has changed",
142 "ns3::MinstrelHtWifiManager::RateChangeTracedCallback")
177 int64_t numStreamsAssigned = 0;
179 numStreamsAssigned++;
181 return numStreamsAssigned;
230 for (uint32_t chWidth = 20; chWidth <=
MAX_HT_WIDTH; chWidth *= 2)
256 WifiMode mode = htMcsList[deviceIndex];
260 NS_LOG_DEBUG (
"Initialized group " << groupId <<
": (" << (uint32_t)streams <<
"," << (uint32_t)sgi <<
"," << chWidth <<
")");
269 for (uint32_t chWidth = 20; chWidth <=
MAX_VHT_WIDTH; chWidth *= 2)
302 NS_LOG_DEBUG (
"Initialized group " << groupId <<
": (" << (uint32_t)streams <<
"," << (uint32_t)sgi <<
"," << chWidth <<
")");
325 txvector.
SetNss (streams);
334 NS_LOG_FUNCTION (
this << phy << (
int)streams << (
int)sgi << chWidth << mode);
337 txvector.
SetNss (streams);
349 NS_LOG_FUNCTION (
this << phy << (
int)streams << (
int)sgi << chWidth << mode);
352 txvector.
SetNss (streams);
366 for (TxTime::const_iterator i =
m_minstrelGroups[groupId].ratesFirstMpduTxTimeTable.begin (); i !=
m_minstrelGroups[groupId].ratesFirstMpduTxTimeTable.end (); i++)
368 if (mode == i->second)
382 m_minstrelGroups[groupId].ratesFirstMpduTxTimeTable.push_back (std::make_pair (t, mode));
392 if (mode == i->second)
406 m_minstrelGroups[groupId].ratesTxTimeTable.push_back (std::make_pair (t, mode));
500 std::ostringstream tmp;
502 station->
m_statsFile.open (tmp.str ().c_str (), std::ios::out);
582 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt++;
590 double ackSnr,
WifiMode ackMode,
double dataSnr)
622 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess++;
623 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt++;
695 NS_LOG_FUNCTION (
this << st << nSuccessfulMpdus << nFailedMpdus << rxSnr << dataSnr);
706 NS_ASSERT_MSG (
false,
"A-MPDU Tx Status called but no HT or VHT supported.");
710 nSuccessfulMpdus <<
" FailedMpdus= " << nFailedMpdus);
713 station->
m_ampduLen += nSuccessfulMpdus + nFailedMpdus;
719 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess += nSuccessfulMpdus;
720 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt += nSuccessfulMpdus + nFailedMpdus;
801 station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount))
809 station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount +
810 station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount))
817 NS_ASSERT_MSG (
false,
"Max retries reached and m_longRetry not cleared properly. longRetry= " << station->
m_longRetry);
834 station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount)
841 NS_ASSERT_MSG (
false,
"Max retries reached and m_longRetry not cleared properly. longRetry= " << station->
m_longRetry);
917 uint32_t mcsIndex = station->
m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex;
926 NS_ASSERT_MSG (
false,
"Inconsistent group selected. Group: (" << (uint32_t)group.
streams <<
"," << (uint32_t)group.
sgi <<
"," << group.
chWidth <<
")" <<
976 uint32_t mcsIndex = station->
m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex;
983 bool rateFound =
false;
985 for (uint32_t i = 0; i < nBasicRates; i++)
988 if (rate <= lastDataRate)
998 uint32_t nSupportRates = phy->
GetNModes ();
999 for (uint32_t i = 0; i < nSupportRates; i++)
1002 if (rate <= lastDataRate)
1030 uint32_t maxRetries;
1043 NS_LOG_DEBUG (
"No re-transmission allowed. Retries: " << station->
m_longRetry <<
" Max retries: " << maxRetries);
1065 return station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].retryCount +
1066 station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount +
1067 station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount;
1071 return 1 + station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTp2RateId].retryCount +
1072 station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount;
1090 uint32_t index = station->
m_groupsTable[sampleGroup].m_index;
1095 uint32_t rateIndex =
GetIndex (sampleGroup, sampleIndex);
1155 uint32_t sampleGroupId =
GetGroupId (sampleIdx);
1156 uint32_t sampleRateId =
GetRateId (sampleIdx);
1159 if (station->
m_groupsTable[sampleGroupId].m_supported && station->
m_groupsTable[sampleGroupId].m_ratesTable[sampleRateId].supported)
1171 " SampleRate= " << sampleIdx <<
" SampleProb= " << sampleRateInfo.
ewmaProb);
1192 Time maxTp2Duration = station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].perfectTxTime;
1193 Time maxProbDuration = station->
m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].perfectTxTime;
1195 NS_LOG_DEBUG (
"Use sample rate? SampleDuration= " << sampleDuration <<
" maxTp2Duration= " << maxTp2Duration <<
1196 " maxProbDuration= " << maxProbDuration <<
" sampleStreams= " << (uint32_t)sampleStreams <<
1197 " maxTpStreams= " << (uint32_t)maxTpStreams);
1198 if (sampleDuration < maxTp2Duration || (sampleStreams <= maxTpStreams - 1 && sampleDuration < maxProbDuration))
1206 NS_LOG_DEBUG (
"FindRate " <<
"sampleRate=" << sampleIdx);
1221 NS_LOG_DEBUG (
"FindRate " <<
"sampleRate=" << sampleIdx);
1282 station->
m_groupsTable[j].m_ratesTable[i].retryUpdated =
false;
1285 "\t attempt=" << station->
m_groupsTable[j].m_ratesTable[i].numRateAttempt <<
1286 "\t success=" << station->
m_groupsTable[j].m_ratesTable[i].numRateSuccess);
1289 if (station->
m_groupsTable[j].m_ratesTable[i].numRateAttempt > 0)
1291 station->
m_groupsTable[j].m_ratesTable[i].numSamplesSkipped = 0;
1296 tempProb = (100 * station->
m_groupsTable[j].m_ratesTable[i].numRateSuccess) / station->
m_groupsTable[j].m_ratesTable[i].numRateAttempt;
1301 if (station->
m_groupsTable[j].m_ratesTable[i].successHist == 0)
1303 station->
m_groupsTable[j].m_ratesTable[i].ewmaProb = tempProb;
1308 tempProb, station->
m_groupsTable[j].m_ratesTable[i].ewmaProb,
1312 station->
m_groupsTable[j].m_ratesTable[i].ewmaProb = tempProb;
1322 station->
m_groupsTable[j].m_ratesTable[i].numSamplesSkipped++;
1328 station->
m_groupsTable[j].m_ratesTable[i].numRateSuccess = 0;
1329 station->
m_groupsTable[j].m_ratesTable[i].numRateAttempt = 0;
1331 if (station->
m_groupsTable[j].m_ratesTable[i].throughput != 0)
1375 Time txTime = station->
m_groupsTable[groupId].m_ratesTable[rateId].perfectTxTime;
1392 uint32_t tmpGroupId, tmpRateId;
1393 double tmpTh, tmpProb;
1394 uint32_t groupId, rateId;
1397 uint32_t maxGPGroupId, maxGPRateId;
1407 tmpProb = station->
m_groupsTable[tmpGroupId].m_ratesTable[tmpRateId].ewmaProb;
1408 tmpTh = station->
m_groupsTable[tmpGroupId].m_ratesTable[tmpRateId].throughput;
1412 currentTh = station->
m_groupsTable[groupId].m_ratesTable[rateId].throughput;
1413 if (currentTh > tmpTh)
1420 maxGPTh = station->
m_groupsTable[maxGPGroupId].m_ratesTable[maxGPRateId].throughput;
1422 if (currentTh > maxGPTh)
1450 uint32_t groupId, rateId;
1452 uint32_t maxTpGroupId, maxTpRateId;
1453 uint32_t maxTp2GroupId, maxTp2RateId;
1454 double maxTpTh, maxTpProb;
1455 double maxTp2Th, maxTp2Prob;
1459 prob = station->
m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb;
1460 th = station->
m_groupsTable[groupId].m_ratesTable[rateId].throughput;
1464 maxTpProb = station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].ewmaProb;
1465 maxTpTh = station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].throughput;
1469 maxTp2Prob = station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].ewmaProb;
1470 maxTp2Th = station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].throughput;
1472 if (th > maxTpTh || (th == maxTpTh && prob > maxTpProb))
1477 else if (th > maxTp2Th || (th == maxTp2Th && prob > maxTp2Prob))
1488 maxTpTh = station->
m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].throughput;
1492 maxTp2Prob = group->
m_ratesTable[maxTp2RateId].ewmaProb;
1493 maxTp2Th = station->
m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].throughput;
1495 if (th > maxTpTh || (th == maxTpTh && prob > maxTpProb))
1500 else if (th > maxTp2Th || (th == maxTp2Th && prob > maxTp2Prob))
1518 for (uint32_t groupId = 0; groupId <
m_numGroups; groupId++)
1539 station->
m_groupsTable[groupId].m_ratesTable[i].supported =
false;
1543 for (uint32_t i = 0; i < station->
m_nModes; i++)
1563 station->
m_groupsTable[groupId].m_ratesTable[rateId].supported =
true;
1564 station->
m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex = i;
1565 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt = 0;
1566 station->
m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess = 0;
1567 station->
m_groupsTable[groupId].m_ratesTable[rateId].prob = 0;
1568 station->
m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb = 0;
1569 station->
m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateAttempt = 0;
1570 station->
m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateSuccess = 0;
1571 station->
m_groupsTable[groupId].m_ratesTable[rateId].numSamplesSkipped = 0;
1572 station->
m_groupsTable[groupId].m_ratesTable[rateId].successHist = 0;
1573 station->
m_groupsTable[groupId].m_ratesTable[rateId].attemptHist = 0;
1574 station->
m_groupsTable[groupId].m_ratesTable[rateId].throughput = 0;
1576 station->
m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 0;
1577 station->
m_groupsTable[groupId].m_ratesTable[rateId].adjustedRetryCount = 0;
1595 if (!station->
m_groupsTable[groupId].m_ratesTable[rateId].retryUpdated)
1608 uint32_t cwMax = 1023;
1609 Time cwTime, txTime, dataTxTime;
1611 Time ackTime =
GetMac ()->GetBasicBlockAckTimeout ();
1613 if (station->
m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb < 1)
1615 station->
m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 1;
1619 station->
m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 2;
1620 station->
m_groupsTable[groupId].m_ratesTable[rateId].retryUpdated =
true;
1626 cwTime = (cw / 2) * slotTime;
1627 cw =
Min ((cw + 1) * 2, cwMax);
1628 cwTime += (cw / 2) * slotTime;
1629 cw =
Min ((cw + 1) * 2, cwMax);
1632 txTime = cwTime + 2 * (dataTxTime + ackTime);
1638 cwTime = (cw / 2) * slotTime;
1639 cw =
Min ((cw + 1) * 2, cwMax);
1642 txTime += cwTime + ackTime + dataTxTime;
1645 && (++station->
m_groupsTable[groupId].m_ratesTable[rateId].retryCount < 7));
1652 double diff, incr, tmp;
1655 diff = currentProb - ewmaProb;
1656 incr = (100 - weight) * diff / 100;
1657 tmp = oldEwmsd * oldEwmsd;
1658 tmp = weight * (tmp + diff * incr) / 100;
1677 for (uint32_t i = 0; i < numSampleRates; i++ )
1684 newIndex = (i + uv) % numSampleRates;
1702 station->
m_statsFile <<
" best ____________rate__________ ________statistics________ ________last_______ ______sum-of________\n" <<
1703 " mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n";
1731 for (uint32_t i = 0; i < numRates; i++)
1737 of <<
"HT" << group.
chWidth <<
" " << giMode <<
"GI " << (int)group.
streams <<
" ";
1741 of <<
"VHT" << group.
chWidth <<
" " << giMode <<
"GI " << (int)group.
streams <<
" ";
1748 uint32_t idx =
GetIndex (groupId, i);
1749 if (idx == maxTpRate)
1757 if (idx == maxTpRate2)
1765 if (idx == maxProbRate)
1776 of << std::setw (4) <<
" MCS" << (group.
streams - 1) * 8 + i;
1780 of << std::setw (7) <<
" MCS" << i <<
"/" << (int) group.
streams;
1783 of <<
" " << std::setw (3) << idx <<
" ";
1790 std::setw (7) << station->
m_groupsTable[groupId].m_ratesTable[i].throughput / 100 <<
" " <<
1791 std::setw (7) << station->
m_groupsTable[groupId].m_ratesTable[i].ewmaProb <<
" " <<
1792 std::setw (7) << station->
m_groupsTable[groupId].m_ratesTable[i].ewmsdProb <<
" " <<
1793 std::setw (7) << station->
m_groupsTable[groupId].m_ratesTable[i].prob <<
" " <<
1794 std::setw (2) << station->
m_groupsTable[groupId].m_ratesTable[i].retryCount <<
" " <<
1795 std::setw (3) << station->
m_groupsTable[groupId].m_ratesTable[i].prevNumRateSuccess <<
" " <<
1796 std::setw (3) << station->
m_groupsTable[groupId].m_ratesTable[i].prevNumRateAttempt <<
" " <<
1797 std::setw (9) << station->
m_groupsTable[groupId].m_ratesTable[i].successHist <<
" " <<
1798 std::setw (9) << station->
m_groupsTable[groupId].m_ratesTable[i].attemptHist <<
"\n";
1850 uint32_t groupId = 0;
1851 uint32_t rateId = 0;
1852 while (groupId < m_numGroups && !station->m_groupsTable[groupId].m_supported)
1856 while (rateId < m_numRates && !station->m_groupsTable[groupId].m_ratesTable[rateId].supported)
1869 uint32_t rateId = 0;
1870 while (rateId < m_numRates && !station->m_groupsTable[groupId].m_ratesTable[rateId].supported)
1884 for (uint32_t i = 0; i < phy->
GetNMcs (); i++)
1889 vhtMcsList.push_back (mode);
1900 for (uint32_t i = 0; i < phy->
GetNMcs (); i++)
1905 htMcsList.push_back (mode);
virtual void DoReportRtsOk(WifiRemoteStation *station, double ctsSnr, WifiMode ctsMode, double rtsSnr)
This method is a pure virtual method that must be implemented by the sub-class.
virtual uint32_t GetFrequency(void) const =0
Simulation virtual time values and global simulation resolution.
void SetShortGuardInterval(bool guardinterval)
Sets if short gurad interval is being used.
A struct to contain information of a group.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
AttributeValue implementation for Boolean.
double CalculateThroughput(MinstrelHtWifiRemoteStation *station, uint32_t groupId, uint32_t rateId, double ewmaProb)
Return the average throughput of the MCS defined by groupId and rateId.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
static const uint8_t MAX_SUPPORTED_STREAMS
Constants for maximum values.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
WifiModeList GetHtDeviceMcsList(void) const
Returns a list of only the HT MCS supported by the device.
void PrintTable(MinstrelHtWifiRemoteStation *station)
Printing Minstrel Table.
uint32_t GetHtGroupId(uint8_t txstreams, uint8_t sgi, uint32_t chWidth)
Returns the groupId of a HT MCS with the given number of streams, if using sgi and the channel width ...
virtual uint32_t GetNModes(void) const =0
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
uint32_t GetLowestIndex(MinstrelHtWifiRemoteStation *station)
Returns the lowest global index of the rates supported by the station.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
uint32_t m_maxProbRate
The highest success probability rate of this group.
double CalculateEwmsd(double oldEwmsd, double currentProb, double ewmaProb, uint32_t weight)
Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation.
virtual WifiTxVector DoGetDataTxVector(WifiRemoteStation *station)
enum WifiModulationClass GetModulationClass() const
virtual uint8_t GetNMcs(void) const =0
The WifiPhy::GetNMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of t...
hold per-remote-station state for Minstrel Wifi manager.
uint32_t m_ampduPacketCount
Number of A-MPDUs transmitted.
uint32_t GetIndex(uint32_t groupId, uint32_t rateId)
Returns the global index corresponding to the groupId and rateId.
static const uint8_t MAX_VHT_STREAM_GROUPS
Maximal number of groups per stream in VHT (4 possible channel widths and 2 possible SGI configuratio...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
uint32_t m_sampleRate
current sample rate
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
uint32_t m_maxTpRate
The max throughput rate of this group.
void SetStbc(bool stbc)
Sets if STBC is being used.
bool IsShortGuardInterval(void) const
std::vector< struct McsGroup > MinstrelMcsGroups
Data structure for a table of group definitions.
virtual void DoReportFinalRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
Mac48Address m_address
Mac48Address of the remote station.
void StatsDump(MinstrelHtWifiRemoteStation *station, uint32_t index, std::ofstream &of)
Print group statistics.
HtMinstrelRate m_ratesTable
Information about rates of this group.
uint32_t m_txrate
current transmit rate
virtual void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode)
This method is a pure virtual method that must be implemented by the sub-class.
WifiMode GetMcsSupported(const WifiRemoteStation *station, uint32_t i) const
Return the WifiMode supported by the specified station at the specified index.
virtual bool DoNeedDataRetransmission(WifiRemoteStation *st, Ptr< const Packet > packet, bool normally)
MinstrelRate m_minstrelTable
minstrel table
uint32_t m_frameLength
Frame length used for calculate modes TxTime.
MinstrelMcsGroups m_minstrelGroups
Global array for groups information.
bool m_isHt
If the station is HT capable.
bool m_sampleDeferred
a flag to indicate sample rate is on the second stage
uint32_t m_maxTpRate2
The second max throughput rate of this group.
void UpdatePacketCounters(MinstrelHtWifiRemoteStation *station, uint32_t nSuccessfulMpdus, uint32_t nFailedMpdus)
Update the number of sample count variables.
virtual void SetupPhy(Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
virtual WifiMode GetMcs(uint8_t mcs) const =0
The WifiPhy::GetMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of tr...
WifiRemoteStationState * m_state
Remote station state.
bool m_printStats
If statistics table should be printed.
void SetChannelWidth(uint32_t channelWidth)
Sets the selected channelWidth (in MHz)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Ptr< WifiPhy > GetPhy(void) const
Return the WifiPhy.
bool GetStbc(const WifiRemoteStation *station) const
Return whether the given station supports space-time block coding (STBC).
uint32_t m_col
To keep track of the current position in the our random sample table going row by row from 1st column...
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
virtual bool GetStbc(void) const =0
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
Time CalculateFirstMpduTxDuration(Ptr< WifiPhy > phy, uint8_t streams, uint8_t sgi, uint32_t chWidth, WifiMode mode)
Estimates the TxTime of a frame with a given mode and group (stream, guard interval and channel width...
void AddFirstMpduTxTime(uint32_t groupId, WifiMode mode, Time t)
Save a TxTime to the vector of groups.
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
bool m_isSampling
a flag to indicate we are currently sampling
virtual WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station)
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
double m_ewmaLevel
Exponential weighted moving average level (or coefficient).
void CalculateRetransmits(MinstrelHtWifiRemoteStation *station, uint32_t index)
Calculate the number of retransmissions to set for the index rate.
SampleRate m_sampleTable
sample table
Hold an unsigned integer type.
static const uint8_t MAX_VHT_GROUP_RATES
Number of rates (or MCS) per VHT group.
Time GetMpduTxTime(uint32_t groupId, WifiMode mode) const
Obtain the TXtime saved in the group information.
static const uint8_t MAX_HT_WIDTH
Maximal channel width.
virtual ~MinstrelHtWifiManager()
WifiMode GetBasicMode(uint32_t i) const
Return a basic mode from the set of basic modes.
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
static const uint8_t MAX_HT_STREAM_GROUPS
Maximal number of groups per stream in HT (2 possible channel widths and 2 possible SGI configuration...
uint32_t GetChannelWidth(void) const
virtual void DoDisposeStation(WifiRemoteStation *station)
uint8_t GetMcsValue(void) const
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, enum WifiPreamble preamble, double frequency)
uint32_t GetRateId(uint32_t index)
For managing rates from different groups, a global index for all rates in all groups is used...
uint32_t m_sampleWait
How many transmission attempts to wait until a new sample.
virtual void SetupPhy(Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
hold a list of per-remote-station state.
bool m_useVhtOnly
If only VHT MCS should be used, instead of HT and VHT.
std::vector< struct GroupInfo > McsGroupData
Data structure for a table of groups.
uint32_t m_longRetry
long retries such as data packets
static TypeId GetTypeId(void)
static const uint8_t MAX_VHT_WIDTH
Maximal channel width.
The MPDU is part of an A-MPDU, but is not the last aggregate.
uint32_t GetNess(const WifiRemoteStation *station) const
void SetNss(uint8_t nss)
Sets the number of Nss refer to IEEE 802.11n Table 20-28 for explanation and range.
bool m_initialized
for initializing tables
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
virtual WifiRemoteStation * DoCreateStation(void) const
uint32_t GetVhtGroupId(uint8_t txstreams, uint8_t sgi, uint32_t chWidth)
Returns the groupId of a VHT MCS with the given number of streams, if using sgi and the channel width...
double ewmaProb
Exponential weighted moving average of probability.
Time perfectTxTime
Perfect transmission time calculation, or frame calculation.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t m_numRates
Number of rates per group Minstrel should consider.
uint32_t m_maxTpRate2
second highest throughput rate
void SetBestStationThRates(MinstrelHtWifiRemoteStation *station, uint32_t index)
Set index rate as maxTpRate or maxTp2Rate if is better than current values.
void InitSampleTable(MinstrelHtWifiRemoteStation *station)
Initialize Sample Table.
static bool IsValidTxVector(WifiTxVector txVector)
The standard disallows certain combinations of WifiMode, number of spatial streams, and channel widths.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
virtual void DoReportRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
void UpdateRetry(MinstrelHtWifiRemoteStation *station)
Update the number of retries and reset accordingly.
uint32_t m_nSampleCol
Number of sample columns.
uint32_t m_sampleCount
Max number of samples per update interval.
virtual void DoReportFinalDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
uint8_t m_numGroups
Number of groups Minstrel should consider.
virtual void SetupMac(Ptr< WifiMac > mac)
Set up MAC associated with this device since it is the object that knows the full set of timing param...
Time m_updateStats
How frequent do we calculate the stats (1/10 seconds).
bool HasVhtSupported(void) const
Return whether the device has VHT capability support enabled.
uint64_t GetDataRate(uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
static const uint8_t MAX_HT_GROUP_RATES
Number of rates (or MCS) per HT group.
virtual void DoReportDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
virtual WifiMode GetMode(uint32_t mode) const =0
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
void UpdateStats(MinstrelHtWifiRemoteStation *station)
Updating the Minstrel Table every 1/10 seconds.
McsGroupData m_groupsTable
Table of groups with stats.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
std::vector< WifiMode > WifiModeList
In various parts of the code, folk are interested in maintaining a list of transmission modes...
bool GetShortGuardInterval(const WifiRemoteStation *station) const
Return whether the given station supports short guard interval.
WifiModeList GetVhtDeviceMcsList(void) const
Returns a list of only the VHT MCS supported by the device.
static Time Now(void)
Return the current simulation virtual time.
double m_ampduLen
Number of MPDUs in an A-MPDU.
std::ofstream m_statsFile
File where statistics table is written.
void RateInit(MinstrelHtWifiRemoteStation *station)
Initialize Minstrel Table.
int m_totalPacketsCount
total number of packets as of now
uint64_t GetNonHtReferenceRate(void) const
virtual void SetupMac(Ptr< WifiMac > mac)
Set up MAC associated with this device since it is the object that knows the full set of timing param...
Implementation of Minstrel HT Rate Control AlgorithmMinstrel-HT is a rate adaptation mechanism for th...
uint32_t FindRate(MinstrelHtWifiRemoteStation *station)
Find a rate to use from Minstrel Table.
uint8_t GetNumberOfSupportedRxAntennas(const WifiRemoteStation *station) const
Return the number of receive antennas the station has.
bool HasHtSupported(void) const
Return whether the device has HT capability support enabled.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
Data structure to contain the information that defines a group.
#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 AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
virtual void DoInitialize(void)
Initialize() implementation.
int m_samplePacketsCount
how many packets we have sample so far
uint8_t GetDefaultTxPowerLevel(void) const
double m_lookAroundRate
The % to try other rates than our current rate.
uint32_t m_maxProbRate
rate with highest prob of success
uint8_t GetNss(void) const
uint32_t GetNBasicModes(void) const
Return the number of basic modes we support.
uint32_t GetLongRetryCount(const WifiRemoteStation *station) const
Return the long retry limit of the given station.
uint32_t GetNMcsSupported(const WifiRemoteStation *station) const
Return the number of MCS supported by the given station.
uint32_t m_nModes
number of modes supported
void AddMpduTxTime(uint32_t groupId, WifiMode mode, Time t)
Save a TxTime to the vector of groups.
A struct to contain all statistics information related to a data rate.
bool GetVhtSupported(const WifiRemoteStation *station) const
Return whether the given station is VHT capable.
void SetNextSample(MinstrelHtWifiRemoteStation *station)
Set the next sample from Sample Table.
uint32_t m_maxTpRate
the current throughput rate
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
uint32_t m_numSamplesSlow
Number of times a slow rate was sampled.
Time Seconds(double value)
Construct a Time in the indicated unit.
Ptr< MinstrelWifiManager > m_legacyManager
Pointer to an instance of MinstrelWifiManager.
uint32_t numSamplesSkipped
Number of times this rate statistics were not updated because no attempts have been made...
uint32_t GetGroupId(uint32_t index)
Return the groupId from the global index.
void SetBestProbabilityRate(MinstrelHtWifiRemoteStation *station, uint32_t index)
Set index rate as maxProbRate if it is better than current value.
uint32_t m_sampleTries
Number of sample tries after waiting sampleWait.
void SetNess(uint8_t ness)
Sets the Ness number refer to IEEE 802.11n Table 20-6 for explanation.
std::vector< struct HtRateInfo > HtMinstrelRate
Data structure for a Minstrel Rate table.
uint32_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
virtual bool IsLowLatency(void) const
Time GetFirstMpduTxTime(uint32_t groupId, WifiMode mode) const
Obtain the TXtime saved in the group information.
uint32_t GetShortRetryCount(const WifiRemoteStation *station) const
Return the short retry limit of the given station.
uint32_t GetNumberOfTransmitAntennas(void)
Time CalculateMpduTxDuration(Ptr< WifiPhy > phy, uint8_t streams, uint8_t sgi, uint32_t chWidth, WifiMode mode)
Estimates the TxTime of a frame with a given mode and group (stream, guard interval and channel width...
uint32_t CountRetries(MinstrelHtWifiRemoteStation *station)
TracedCallback< uint64_t, Mac48Address > m_rateChange
The trace source fired when the transmission rate change.
WifiMode GetMode(void) const
void UpdateRate(MinstrelHtWifiRemoteStation *station)
uint32_t GetNextSample(MinstrelHtWifiRemoteStation *station)
Getting the next sample from Sample Table.
double m_avgAmpduLen
Average number of MPDUs in an A-MPDU.
uint32_t m_shortRetry
short retries such as control packts
virtual void DoReportDataOk(WifiRemoteStation *station, double ackSnr, WifiMode ackMode, double dataSnr)
This method is a pure virtual method that must be implemented by the sub-class.
This class can be used to hold variables of floating point type such as 'double' or 'float'...
virtual void DoReportAmpduTxStatus(WifiRemoteStation *station, uint32_t nSuccessfulMpdus, uint32_t nFailedMpdus, double rxSnr, double dataSnr)
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
a unique identifier for an interface.
bool IsValidMcs(Ptr< WifiPhy > phy, uint8_t streams, uint32_t chWidth, WifiMode mode)
Check the validity of a combination of number of streams, chWidth and mode.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
std::vector< std::vector< uint32_t > > SampleRate
Data structure for a Sample Rate table A vector of a vector uint32_t.
void CheckInit(MinstrelHtWifiRemoteStation *station)
Check for initializations.
uint32_t m_sampleGroup
The group that the sample rate belongs to.
hold per-remote-station state.
bool GetHtSupported(const WifiRemoteStation *station) const
Return whether the given station is HT capable.
Ptr< WifiMac > GetMac(void) const
Return the WifiMac.
Time m_nextStatsUpdate
10 times every second