A Discrete-Event Network Simulator
API
minstrel-wifi-manager.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 Duy Nguyen
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Duy Nguyen <duy@soe.ucsc.edu>
19  * Matías Richart <mrichart@fing.edu.uy>
20  *
21  * Some Comments:
22  *
23  * 1) Segment Size is declared for completeness but not used because it has
24  * to do more with the requirement of the specific hardware.
25  *
26  * 2) By default, Minstrel applies the multi-rate retry (the core of Minstrel
27  * algorithm). Otherwise, please use ConstantRateWifiManager instead.
28  *
29  * http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/minstrel
30  */
31 
32 #include "minstrel-wifi-manager.h"
33 #include "ns3/simulator.h"
34 #include "ns3/log.h"
35 #include "ns3/double.h"
36 #include "ns3/boolean.h"
37 #include "wifi-mac.h"
38 #include "wifi-phy.h"
39 #include <iomanip>
40 
41 #define Min(a,b) ((a < b) ? a : b)
42 
43 namespace ns3 {
44 
45 NS_LOG_COMPONENT_DEFINE ("MinstrelWifiManager");
46 
47 NS_OBJECT_ENSURE_REGISTERED (MinstrelWifiManager);
48 
49 TypeId
51 {
52  static TypeId tid = TypeId ("ns3::MinstrelWifiManager")
54  .SetGroupName ("Wifi")
55  .AddConstructor<MinstrelWifiManager> ()
56  .AddAttribute ("UpdateStatistics",
57  "The interval between updating statistics table ",
58  TimeValue (Seconds (0.1)),
60  MakeTimeChecker ())
61  .AddAttribute ("LookAroundRate",
62  "the percentage to try other rates",
63  DoubleValue (10),
65  MakeDoubleChecker<double> ())
66  .AddAttribute ("EWMA",
67  "EWMA level",
68  DoubleValue (75),
70  MakeDoubleChecker<double> ())
71  .AddAttribute ("SampleColumn",
72  "The number of columns used for sampling",
73  UintegerValue (10),
75  MakeUintegerChecker <uint32_t> ())
76  .AddAttribute ("PacketLength",
77  "The packet length used for calculating mode TxTime",
78  UintegerValue (1200),
80  MakeUintegerChecker <uint32_t> ())
81  .AddAttribute ("PrintStats",
82  "Print statistics table",
83  BooleanValue (false),
86  .AddTraceSource ("Rate",
87  "Traced value for rate changes (b/s)",
89  "ns3::TracedValueCallback::Uint64")
90  ;
91  return tid;
92 }
93 
96  m_currentRate (0)
97 {
98  NS_LOG_FUNCTION (this);
99  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
100 }
101 
103 {
104  NS_LOG_FUNCTION (this);
105 }
106 
107 void
109 {
110  NS_LOG_FUNCTION (this << phy);
111  uint32_t nModes = phy->GetNModes ();
112  for (uint32_t i = 0; i < nModes; i++)
113  {
114  WifiMode mode = phy->GetMode (i);
115  WifiTxVector txVector;
116  txVector.SetMode (mode);
118  AddCalcTxTime (mode, phy->CalculateTxDuration (m_pktLen, txVector, phy->GetFrequency ()));
119  }
121 }
122 
123 void
125 {
126  NS_LOG_FUNCTION (this << mac);
128 }
129 
130 int64_t
132 {
133  NS_LOG_FUNCTION (this << stream);
135  return 1;
136 }
137 
138 Time
140 {
141  NS_LOG_FUNCTION (this << mode);
142  for (TxTime::const_iterator i = m_calcTxTime.begin (); i != m_calcTxTime.end (); i++)
143  {
144  if (mode == i->second)
145  {
146  return i->first;
147  }
148  }
149  NS_ASSERT (false);
150  return Seconds (0);
151 }
152 
153 void
155 {
156  NS_LOG_FUNCTION (this << mode << t);
157  m_calcTxTime.push_back (std::make_pair (t, mode));
158 }
159 
162 {
163  NS_LOG_FUNCTION (this);
165 
167  station->m_col = 0;
168  station->m_index = 0;
169  station->m_maxTpRate = 0;
170  station->m_maxTpRate2 = 0;
171  station->m_maxProbRate = 0;
172  station->m_nModes = 0;
173  station->m_totalPacketsCount = 0;
174  station->m_samplePacketsCount = 0;
175  station->m_isSampling = false;
176  station->m_sampleRate = 0;
177  station->m_sampleDeferred = false;
178  station->m_shortRetry = 0;
179  station->m_longRetry = 0;
180  station->m_retry = 0;
181  station->m_txrate = 0;
182  station->m_initialized = false;
183 
184  return station;
185 }
186 
187 void
189 {
190  NS_LOG_FUNCTION (this << station);
191  if (!station->m_initialized && GetNSupported (station) > 1)
192  {
193  //Note: we appear to be doing late initialization of the table
194  //to make sure that the set of supported rates has been initialized
195  //before we perform our own initialization.
196  station->m_nModes = GetNSupported (station);
197  station->m_minstrelTable = MinstrelRate (station->m_nModes);
198  station->m_sampleTable = SampleRate (station->m_nModes, std::vector<uint32_t> (m_sampleCol));
199  InitSampleTable (station);
200  RateInit (station);
201  station->m_initialized = true;
202  std::ostringstream tmp;
203  tmp << "minstrel-stats-" << station->m_state->m_address << ".txt";
204  station->m_statsFile.open (tmp.str ().c_str (), std::ios::out);
205  }
206 }
207 
223 void
225 {
226  NS_LOG_FUNCTION (this << station);
227  station->m_longRetry++;
228  station->m_minstrelTable[station->m_txrate].numRateAttempt++;
229 
230  NS_LOG_DEBUG ("DoReportDataFailed " << station << " rate " << station->m_txrate << " longRetry " << station->m_longRetry);
231 
232  //for normal rate, we're not currently sampling random rates
233  if (!station->m_isSampling)
234  {
235  NS_LOG_DEBUG ("Failed with normal rate: current=" << station->m_txrate << ", sample=" << station->m_sampleRate << ", maxTp=" << station->m_maxTpRate << ", maxTp2=" << station->m_maxTpRate2 << ", maxProb=" << station->m_maxProbRate);
236  //use best throughput rate
237  if (station->m_longRetry < station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)
238  {
239  NS_LOG_DEBUG (" More retries left for the maximum throughput rate.");
240  station->m_txrate = station->m_maxTpRate;
241  }
242 
243  //use second best throughput rate
244  else if (station->m_longRetry <= (station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
245  station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount))
246  {
247  NS_LOG_DEBUG (" More retries left for the second maximum throughput rate.");
248  station->m_txrate = station->m_maxTpRate2;
249  }
250 
251  //use best probability rate
252  else if (station->m_longRetry <= (station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
253  station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount +
254  station->m_minstrelTable[station->m_maxProbRate].adjustedRetryCount))
255  {
256  NS_LOG_DEBUG (" More retries left for the maximum probability rate.");
257  station->m_txrate = station->m_maxProbRate;
258  }
259 
260  //use lowest base rate
261  else if (station->m_longRetry > (station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
262  station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount +
263  station->m_minstrelTable[station->m_maxProbRate].adjustedRetryCount))
264  {
265  NS_LOG_DEBUG (" More retries left for the base rate.");
266  station->m_txrate = 0;
267  }
268  }
269 
270  //for look-around rate, we're currently sampling random rates
271  else
272  {
273  NS_LOG_DEBUG ("Failed with look around rate: current=" << station->m_txrate << ", sample=" << station->m_sampleRate << ", maxTp=" << station->m_maxTpRate << ", maxTp2=" << station->m_maxTpRate2 << ", maxProb=" << station->m_maxProbRate);
274  //current sampling rate is slower than the current best rate
275  if (station->m_sampleDeferred)
276  {
277  NS_LOG_DEBUG ("Look around rate is slower than the maximum throughput rate.");
278  //use best throughput rate
279  if (station->m_longRetry < station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)
280  {
281  NS_LOG_DEBUG (" More retries left for the maximum throughput rate.");
282  station->m_txrate = station->m_maxTpRate;
283  }
284 
285  //use random rate
286  else if (station->m_longRetry <= (station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
287  station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
288  {
289  NS_LOG_DEBUG (" More retries left for the sampling rate.");
290  station->m_txrate = station->m_sampleRate;
291  }
292 
293  //use max probability rate
294  else if (station->m_longRetry <= (station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
295  station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
296  station->m_minstrelTable[station->m_maxProbRate].adjustedRetryCount ))
297  {
298  NS_LOG_DEBUG (" More retries left for the maximum probability rate.");
299  station->m_txrate = station->m_maxProbRate;
300  }
301 
302  //use lowest base rate
303  else if (station->m_longRetry > (station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
304  station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
305  station->m_minstrelTable[station->m_maxProbRate].adjustedRetryCount))
306  {
307  NS_LOG_DEBUG (" More retries left for the base rate.");
308  station->m_txrate = 0;
309  }
310  }
311  //current sampling rate is better than current best rate
312  else
313  {
314  NS_LOG_DEBUG ("Look around rate is faster than the maximum throughput rate.");
315  //use random rate
316  if (station->m_longRetry < station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount)
317  {
318  NS_LOG_DEBUG (" More retries left for the sampling rate.");
319  station->m_txrate = station->m_sampleRate;
320  }
321 
322  //use the best throughput rate
323  else if (station->m_longRetry <= (station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
324  station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
325  {
326  NS_LOG_DEBUG (" More retries left for the maximum throughput rate.");
327  station->m_txrate = station->m_maxTpRate;
328  }
329 
330  //use the best probability rate
331  else if (station->m_longRetry <= (station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
332  station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
333  station->m_minstrelTable[station->m_maxProbRate].adjustedRetryCount))
334  {
335  NS_LOG_DEBUG (" More retries left for the maximum probability rate.");
336  station->m_txrate = station->m_maxProbRate;
337  }
338 
339  //use the lowest base rate
340  else if (station->m_longRetry > (station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
341  station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
342  station->m_minstrelTable[station->m_maxProbRate].adjustedRetryCount))
343  {
344  NS_LOG_DEBUG (" More retries left for the base rate.");
345  station->m_txrate = 0;
346  }
347  }
348  }
349 }
350 
353 {
354  NS_LOG_FUNCTION (this << station);
355  uint32_t channelWidth = GetChannelWidth (station);
356  if (channelWidth > 20 && channelWidth != 22)
357  {
358  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
359  channelWidth = 20;
360  }
361  if (!station->m_initialized)
362  {
363  CheckInit (station);
364 
365  //start the rate at half way
366  station->m_txrate = station->m_nModes / 2;
367  }
368  WifiMode mode = GetSupported (station, station->m_txrate);
369  if (m_currentRate != mode.GetDataRate (channelWidth))
370  {
371  NS_LOG_DEBUG ("New datarate: " << mode.GetDataRate (channelWidth));
372  m_currentRate = mode.GetDataRate (channelWidth);
373  }
374  return WifiTxVector (mode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
375 }
376 
379 {
380  NS_LOG_FUNCTION (this << station);
381  NS_LOG_DEBUG ("DoGetRtsMode m_txrate=" << station->m_txrate);
382  uint32_t channelWidth = GetChannelWidth (station);
383  if (channelWidth > 20 && channelWidth != 22)
384  {
385  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
386  channelWidth = 20;
387  }
388  WifiTxVector rtsTxVector;
389  WifiMode mode;
390  if (GetUseNonErpProtection () == false)
391  {
392  mode = GetSupported (station, 0);
393  }
394  else
395  {
396  mode = GetNonErpSupported (station, 0);
397  }
398  rtsTxVector = WifiTxVector (mode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
399  return rtsTxVector;
400 }
401 
402 uint32_t
404 {
405  if (!station->m_isSampling)
406  {
407  return station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
408  station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount +
409  station->m_minstrelTable[station->m_maxProbRate].adjustedRetryCount +
410  station->m_minstrelTable[0].adjustedRetryCount;
411  }
412  else
413  {
414  return station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
415  station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
416  station->m_minstrelTable[station->m_maxProbRate].adjustedRetryCount +
417  station->m_minstrelTable[0].adjustedRetryCount;
418  }
419 }
420 
421 uint32_t
423 {
424  NS_LOG_FUNCTION (this << station);
425 
426  if (station->m_totalPacketsCount == 0)
427  {
428  return 0;
429  }
430 
431 
432  uint32_t idx;
433 
434  int delta = (station->m_totalPacketsCount * m_lookAroundRate / 100) - (station->m_samplePacketsCount + station->m_numSamplesDeferred / 2);
435 
436  NS_LOG_DEBUG ("Decide sampling. Delta: " << delta << " lookAroundRatio: " << m_lookAroundRate);
437 
438  /* delta < 0: no sampling required */
439  if (delta >= 0)
440  {
441  NS_LOG_DEBUG ("Search next sampling rate");
442  int ratesSupported = station->m_nModes;
443  if (delta > ratesSupported * 2)
444  {
445  /* From Linux implementation:
446  * With multi-rate retry, not every planned sample
447  * attempt actually gets used, due to the way the retry
448  * chain is set up - [max_tp,sample,prob,lowest] for
449  * sample_rate < max_tp.
450  *
451  * If there's too much sampling backlog and the link
452  * starts getting worse, minstrel would start bursting
453  * out lots of sampling frames, which would result
454  * in a large throughput loss. */
455  station->m_samplePacketsCount += (delta - ratesSupported * 2);
456  }
457 
458  //now go through the table and find an index rate
459  idx = GetNextSample (station);
460 
461  //error check
462  if (idx >= station->m_nModes)
463  {
464  NS_LOG_DEBUG ("ALERT!!! ERROR");
465  }
466 
467  //set the rate that we're currently sampling
468  station->m_sampleRate = idx;
469 
470  /* From Linux implementation:
471  * Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage)
472  * rate sampling method should be used.
473  * Respect such rates that are not sampled for 20 iterations.
474  */
475  if ((station->m_minstrelTable[idx].perfectTxTime > station->m_minstrelTable[station->m_maxTpRate].perfectTxTime)
476  && (station->m_minstrelTable[idx].numSamplesSkipped < 20))
477  {
478  // If the rate is slower and we have sample it enough, defer to second stage
479  station->m_sampleDeferred = true;
480  station->m_numSamplesDeferred++;
481 
482  //set flag that we are currently sampling
483  station->m_isSampling = true;
484  }
485  else
486  {
487  // if samplieLimit is zero, then don't sample this rate
488  if (!station->m_minstrelTable[idx].sampleLimit)
489  {
490  idx = station->m_maxTpRate;
491  station->m_isSampling = false;
492  }
493  else
494  {
495  //set flag that we are currently sampling
496  station->m_isSampling = true;
497  if (station->m_minstrelTable[idx].sampleLimit > 0)
498  {
499  station->m_minstrelTable[idx].sampleLimit--;
500  }
501  }
502  }
503 
504  //using the best rate instead
505  if (station->m_sampleDeferred)
506  {
507  NS_LOG_DEBUG ("The next look around rate is slower than the maximum throughput rate, continue with the maximum throughput rate: " << station->m_maxTpRate << "(" << GetSupported (station, station->m_maxTpRate) << ")");
508  idx = station->m_maxTpRate;
509  }
510  }
511  //continue using the best rate
512  else
513  {
514  NS_LOG_DEBUG ("Continue using the maximum throughput rate: " << station->m_maxTpRate << "(" << GetSupported (station, station->m_maxTpRate) << ")");
515  idx = station->m_maxTpRate;
516  }
517 
518  NS_LOG_DEBUG ("Rate = " << idx << "(" << GetSupported (station, idx) << ")");
519 
520  return idx;
521 }
522 
523 void
525 {
526  NS_LOG_FUNCTION (this << station);
527  if (Simulator::Now () < station->m_nextStatsUpdate)
528  {
529  return;
530  }
531 
532  if (!station->m_initialized)
533  {
534  return;
535  }
536  NS_LOG_FUNCTION (this);
538  NS_LOG_DEBUG ("Next update at " << station->m_nextStatsUpdate);
539  NS_LOG_DEBUG ("Currently using rate: " << station->m_txrate << " (" << GetSupported (station, station->m_txrate) << ")");
540 
541  Time txTime;
542  uint32_t tempProb;
543 
544  NS_LOG_DEBUG ("Index-Rate\t\tAttempt\tSuccess");
545  for (uint32_t i = 0; i < station->m_nModes; i++)
546  {
547 
548  //calculate the perfect tx time for this rate
549  txTime = station->m_minstrelTable[i].perfectTxTime;
550 
551  //just for initialization
552  if (txTime.GetMicroSeconds () == 0)
553  {
554  txTime = Seconds (1);
555  }
556 
557  NS_LOG_DEBUG (i << " " << GetSupported (station, i) <<
558  "\t" << station->m_minstrelTable[i].numRateAttempt <<
559  "\t" << station->m_minstrelTable[i].numRateSuccess);
560 
561  //if we've attempted something
562  if (station->m_minstrelTable[i].numRateAttempt)
563  {
564  station->m_minstrelTable[i].numSamplesSkipped = 0;
569  tempProb = (station->m_minstrelTable[i].numRateSuccess * 18000) / station->m_minstrelTable[i].numRateAttempt;
570 
571  //bookeeping
572  station->m_minstrelTable[i].prob = tempProb;
573 
574  if (station->m_minstrelTable[i].successHist == 0)
575  {
576  station->m_minstrelTable[i].ewmaProb = tempProb;
577  }
578  else
579  {
580  //ewma probability (cast for gcc 3.4 compatibility)
581  tempProb = static_cast<uint32_t> (((tempProb * (100 - m_ewmaLevel)) + (station->m_minstrelTable[i].ewmaProb * m_ewmaLevel) ) / 100);
582 
583  station->m_minstrelTable[i].ewmaProb = tempProb;
584  }
585 
586  //calculating throughput
587  station->m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds ());
588 
589  }
590  else
591  {
592  station->m_minstrelTable[i].numSamplesSkipped++;
593  }
594 
595  //bookeeping
596  station->m_minstrelTable[i].successHist += station->m_minstrelTable[i].numRateSuccess;
597  station->m_minstrelTable[i].attemptHist += station->m_minstrelTable[i].numRateAttempt;
598  station->m_minstrelTable[i].prevNumRateSuccess = station->m_minstrelTable[i].numRateSuccess;
599  station->m_minstrelTable[i].prevNumRateAttempt = station->m_minstrelTable[i].numRateAttempt;
600  station->m_minstrelTable[i].numRateSuccess = 0;
601  station->m_minstrelTable[i].numRateAttempt = 0;
602 
603  //Sample less often below 10% and above 95% of success
604  if ((station->m_minstrelTable[i].ewmaProb > 17100) || (station->m_minstrelTable[i].ewmaProb < 1800))
605  {
613  if (station->m_minstrelTable[i].retryCount > 2)
614  {
615  station->m_minstrelTable[i].adjustedRetryCount = 2;
616  }
617  station->m_minstrelTable[i].sampleLimit = 4;
618  }
619  else
620  {
621  // no sampling limit.
622  station->m_minstrelTable[i].sampleLimit = -1;
623  station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount;
624  }
625 
626  //if it's 0 allow two retries.
627  if (station->m_minstrelTable[i].adjustedRetryCount == 0)
628  {
629  station->m_minstrelTable[i].adjustedRetryCount = 2;
630  }
631  }
632 
633  NS_LOG_DEBUG ("Attempt/success resetted to 0");
634 
635  uint32_t max_tp = 0, index_max_tp = 0, index_max_tp2 = 0;
636 
637  //go find max throughput, second maximum throughput, high probability succ
638  NS_LOG_DEBUG ("Finding the maximum throughput, second maximum throughput, and highest probability");
639  NS_LOG_DEBUG ("Index-Rate\t\tT-put\tEWMA");
640  for (uint32_t i = 0; i < station->m_nModes; i++)
641  {
642  NS_LOG_DEBUG (i << " " << GetSupported (station, i) <<
643  "\t" << station->m_minstrelTable[i].throughput <<
644  "\t" << station->m_minstrelTable[i].ewmaProb);
645 
646  if (max_tp < station->m_minstrelTable[i].throughput)
647  {
648  index_max_tp = i;
649  max_tp = station->m_minstrelTable[i].throughput;
650  }
651  }
652 
653  max_tp = 0;
654  //find the second highest max
655  for (uint32_t i = 0; i < station->m_nModes; i++)
656  {
657  if ((i != index_max_tp) && (max_tp < station->m_minstrelTable[i].throughput))
658  {
659  index_max_tp2 = i;
660  max_tp = station->m_minstrelTable[i].throughput;
661  }
662  }
663 
664  uint32_t max_prob = 0, index_max_prob = 0;
665  for (uint32_t i = 0; i < station->m_nModes; i++)
666  {
667  if ((station->m_minstrelTable[i].ewmaProb >= 95 * 180) && (station->m_minstrelTable[i].throughput >= station->m_minstrelTable[index_max_prob].throughput))
668  {
669  index_max_prob = i;
670  max_prob = station->m_minstrelTable[i].ewmaProb;
671  }
672  else if (station->m_minstrelTable[i].ewmaProb >= max_prob)
673  {
674  index_max_prob = i;
675  max_prob = station->m_minstrelTable[i].ewmaProb;
676  }
677  }
678 
679  station->m_maxTpRate = index_max_tp;
680  station->m_maxTpRate2 = index_max_tp2;
681  station->m_maxProbRate = index_max_prob;
682 
683  if (index_max_tp > station->m_txrate)
684  {
685  station->m_txrate = index_max_tp;
686  }
687 
688  NS_LOG_DEBUG ("max throughput=" << index_max_tp << "(" << GetSupported (station, index_max_tp) <<
689  ")\tsecond max throughput=" << index_max_tp2 << "(" << GetSupported (station, index_max_tp2) <<
690  ")\tmax prob=" << index_max_prob << "(" << GetSupported (station, index_max_prob) << ")");
691  if (m_printStats)
692  {
693  PrintTable (station);
694  }
695 }
696 
697 void
699  double rxSnr, WifiMode txMode)
700 {
701  NS_LOG_FUNCTION (this << st << rxSnr << txMode);
702 }
703 
704 void
706 {
707  NS_LOG_FUNCTION (this << st);
709  NS_LOG_DEBUG ("DoReportRtsFailed m_txrate=" << station->m_txrate);
710 
711  station->m_shortRetry++;
712 }
713 
714 void
715 MinstrelWifiManager::DoReportRtsOk (WifiRemoteStation *st, double ctsSnr, WifiMode ctsMode, double rtsSnr)
716 {
717  NS_LOG_FUNCTION (this << st);
718  NS_LOG_DEBUG ("self=" << st << " rts ok");
719 }
720 
721 void
723 {
724  NS_LOG_FUNCTION (this << st);
726  UpdateRetry (station);
727 }
728 
729 void
731 {
732  NS_LOG_FUNCTION (this << st);
734  CheckInit (station);
735  if (!station->m_initialized)
736  {
737  return;
738  }
739 
740  UpdateRate (station);
741 }
742 
743 void
745  double ackSnr, WifiMode ackMode, double dataSnr)
746 {
747  NS_LOG_FUNCTION (st << ackSnr << ackMode << dataSnr);
749 
750  CheckInit (station);
751  if (!station->m_initialized)
752  {
753  return;
754  }
755 
756  NS_LOG_DEBUG ("DoReportDataOk m_txrate = " << station->m_txrate << ", attempt = " << station->m_minstrelTable[station->m_txrate].numRateAttempt << ", success = " << station->m_minstrelTable[station->m_txrate].numRateSuccess << " (before update).");
757 
758  station->m_minstrelTable[station->m_txrate].numRateSuccess++;
759  station->m_minstrelTable[station->m_txrate].numRateAttempt++;
760 
761  UpdatePacketCounters (station);
762 
763  NS_LOG_DEBUG ("DoReportDataOk m_txrate = " << station->m_txrate << ", attempt = " << station->m_minstrelTable[station->m_txrate].numRateAttempt << ", success = " << station->m_minstrelTable[station->m_txrate].numRateSuccess << " (after update).");
764 
765  UpdateRetry (station);
766  UpdateStats (station);
767 
768  if (station->m_nModes >= 1)
769  {
770  station->m_txrate = FindRate (station);
771  }
772 }
773 
774 void
776 {
777  NS_LOG_FUNCTION (this << st);
779 
780  CheckInit (station);
781  if (!station->m_initialized)
782  {
783  return;
784  }
785 
786  NS_LOG_DEBUG ("DoReportFinalDataFailed m_txrate = " << station->m_txrate << ", attempt = " << station->m_minstrelTable[station->m_txrate].numRateAttempt << ", success = " << station->m_minstrelTable[station->m_txrate].numRateSuccess << " (before update).");
787 
788  UpdatePacketCounters (station);
789 
790  UpdateRetry (station);
791  UpdateStats (station);
792 
793  NS_LOG_DEBUG ("DoReportFinalDataFailed m_txrate = " << station->m_txrate << ", attempt = " << station->m_minstrelTable[station->m_txrate].numRateAttempt << ", success = " << station->m_minstrelTable[station->m_txrate].numRateSuccess << " (after update).");
794 
795  if (station->m_nModes >= 1)
796  {
797  station->m_txrate = FindRate (station);
798  }
799 }
800 
801 void
803 {
804  NS_LOG_FUNCTION (this << station);
805 
806  station->m_totalPacketsCount++;
807  // If it is a sampling frame and the sampleRate was used, increase counter
808  if (station->m_isSampling && (!station->m_sampleDeferred || station->m_longRetry >= station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
809  {
810  station->m_samplePacketsCount++;
811  }
812 
813  if (station->m_numSamplesDeferred > 0)
814  {
815  station->m_numSamplesDeferred--;
816  }
817 
818  if (station->m_totalPacketsCount == ~0)
819  {
820  station->m_numSamplesDeferred = 0;
821  station->m_samplePacketsCount = 0;
822  station->m_totalPacketsCount = 0;
823  }
824  station->m_isSampling = false;
825  station->m_sampleDeferred = false;
826 }
827 
828 void
830 {
831  NS_LOG_FUNCTION (this << station);
832  station->m_retry = station->m_shortRetry + station->m_longRetry;
833  station->m_shortRetry = 0;
834  station->m_longRetry = 0;
835 }
836 
839 {
840  NS_LOG_FUNCTION (this << st);
842  return GetDataTxVector (station);
843 }
844 
847 {
848  NS_LOG_FUNCTION (this << st);
850  return GetRtsTxVector (station);
851 }
852 
853 bool
855 {
856  NS_LOG_FUNCTION (this << st << packet << normally);
858 
859  CheckInit (station);
860  if (!station->m_initialized)
861  {
862  return normally;
863  }
864  if (station->m_longRetry > CountRetries (station))
865  {
866  return false;
867  }
868  else
869  {
870  return true;
871  }
872 }
873 
874 bool
876 {
877  NS_LOG_FUNCTION (this);
878  return true;
879 }
880 
881 uint32_t
883 {
884  NS_LOG_FUNCTION (this << station);
885  uint32_t bitrate;
886  bitrate = station->m_sampleTable[station->m_index][station->m_col];
887  station->m_index++;
888 
889  //bookeeping for m_index and m_col variables
890  if (station->m_index > (station->m_nModes - 2))
891  {
892  station->m_index = 0;
893  station->m_col++;
894  if (station->m_col >= m_sampleCol)
895  {
896  station->m_col = 0;
897  }
898  }
899  return bitrate;
900 }
901 
902 void
904 {
905  NS_LOG_FUNCTION (station);
906 
907  for (uint32_t i = 0; i < station->m_nModes; i++)
908  {
909  NS_LOG_DEBUG ("Initializing rate index " << i << " " << GetSupported (station, i));
910  station->m_minstrelTable[i].numRateAttempt = 0;
911  station->m_minstrelTable[i].numRateSuccess = 0;
912  station->m_minstrelTable[i].prevNumRateSuccess = 0;
913  station->m_minstrelTable[i].prevNumRateAttempt = 0;
914  station->m_minstrelTable[i].successHist = 0;
915  station->m_minstrelTable[i].attemptHist = 0;
916  station->m_minstrelTable[i].numSamplesSkipped = 0;
917  station->m_minstrelTable[i].prob = 0;
918  station->m_minstrelTable[i].ewmaProb = 0;
919  station->m_minstrelTable[i].throughput = 0;
920  station->m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i));
921  NS_LOG_DEBUG (" perfectTxTime = " << station->m_minstrelTable[i].perfectTxTime);
922  station->m_minstrelTable[i].retryCount = 1;
923  station->m_minstrelTable[i].adjustedRetryCount = 1;
924  //Emulating minstrel.c::ath_rate_ctl_reset
925  //We only check from 2 to 10 retries. This guarantee that
926  //at least one retry is permitter.
927  Time totalTxTimeWithGivenRetries = Seconds (0.0); //tx_time in minstrel.c
928  NS_LOG_DEBUG (" Calculating the number of retries");
929  for (uint32_t retries = 2; retries < 11; retries++)
930  {
931  NS_LOG_DEBUG (" Checking " << retries << " retries");
932  totalTxTimeWithGivenRetries = CalculateTimeUnicastPacket (station->m_minstrelTable[i].perfectTxTime, 0, retries);
933  NS_LOG_DEBUG (" totalTxTimeWithGivenRetries = " << totalTxTimeWithGivenRetries);
934  if (totalTxTimeWithGivenRetries > MilliSeconds (6))
935  {
936  break;
937  }
938  station->m_minstrelTable[i].sampleLimit = -1;
939  station->m_minstrelTable[i].retryCount = retries;
940  station->m_minstrelTable[i].adjustedRetryCount = retries;
941  }
942  }
943  UpdateStats (station);
944 }
945 
946 Time
947 MinstrelWifiManager::CalculateTimeUnicastPacket (Time dataTransmissionTime, uint32_t shortRetries, uint32_t longRetries)
948 {
949  NS_LOG_FUNCTION (this << dataTransmissionTime << shortRetries << longRetries);
950  //See rc80211_minstrel.c
951 
952  //First transmission (DATA + ACK timeout)
953  Time tt = dataTransmissionTime + GetMac ()->GetAckTimeout ();
954 
955  uint32_t cwMax = 1023;
956  uint32_t cw = 31;
957  for (uint32_t retry = 0; retry < longRetries; retry++)
958  {
959  //Add one re-transmission (DATA + ACK timeout)
960  tt += dataTransmissionTime + GetMac ()->GetAckTimeout ();
961 
962  //Add average back off (half the current contention window)
963  tt += NanoSeconds ((cw / 2) * GetMac ()->GetSlot ());
964 
965  //Update contention window
966  cw = std::min (cwMax, (cw + 1) * 2);
967  }
968 
969  return tt;
970 }
971 
972 void
974 {
975  NS_LOG_DEBUG ("InitSampleTable=" << this);
976 
977  station->m_col = station->m_index = 0;
978 
979  //for off-setting to make rates fall between 0 and nModes
980  uint32_t numSampleRates = station->m_nModes;
981 
982  uint32_t newIndex;
983  for (uint32_t col = 0; col < m_sampleCol; col++)
984  {
985  for (uint32_t i = 0; i < numSampleRates; i++ )
986  {
991  int uv = m_uniformRandomVariable->GetInteger (0, numSampleRates);
992  newIndex = (i + uv) % numSampleRates;
993 
994  //this loop is used for filling in other uninitialized places
995  while (station->m_sampleTable[newIndex][col] != 0)
996  {
997  newIndex = (newIndex + 1) % station->m_nModes;
998  }
999  station->m_sampleTable[newIndex][col] = i;
1000  }
1001  }
1002 }
1003 
1004 void
1006 {
1007  NS_LOG_DEBUG ("PrintSampleTable=" << station);
1008 
1009  uint32_t numSampleRates = station->m_nModes;
1010  std::stringstream table;
1011  for (uint32_t i = 0; i < numSampleRates; i++)
1012  {
1013  for (uint32_t j = 0; j < m_sampleCol; j++)
1014  {
1015  table << station->m_sampleTable[i][j] << "\t";
1016  }
1017  table << std::endl;
1018  }
1019  NS_LOG_DEBUG (table.str ());
1020 }
1021 
1022 void
1024 {
1025  NS_LOG_FUNCTION (this << station);
1026  NS_LOG_DEBUG ("PrintTable=" << station);
1027 
1028  station->m_statsFile << "best _______________rate________________ ________statistics________ ________last_______ ______sum-of________\n" <<
1029  "rate [ name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n";
1030 
1031  uint32_t maxTpRate = station->m_maxTpRate;
1032  uint32_t maxTpRate2 = station->m_maxTpRate2;
1033  uint32_t maxProbRate = station->m_maxProbRate;
1034 
1035  for (uint32_t i = 0; i < station->m_nModes; i++)
1036  {
1037  RateInfo rate = station->m_minstrelTable[i];
1038 
1039  if (i == maxTpRate)
1040  {
1041  station->m_statsFile << 'A';
1042  }
1043  else
1044  {
1045  station->m_statsFile << ' ';
1046  }
1047  if (i == maxTpRate2)
1048  {
1049  station->m_statsFile << 'B';
1050  }
1051  else
1052  {
1053  station->m_statsFile << ' ';
1054  }
1055  if (i == maxProbRate)
1056  {
1057  station->m_statsFile << 'P';
1058  }
1059  else
1060  {
1061  station->m_statsFile << ' ';
1062  }
1063 
1064  float tmpTh = rate.throughput / 100000.0;
1065  station->m_statsFile << " " <<
1066  std::setw (17) << GetSupported (station, i) << " " <<
1067  std::setw (2) << i << " " <<
1068  std::setw (4) << rate.perfectTxTime.GetMicroSeconds () <<
1069  std::setw (8) << " ----- " <<
1070  std::setw (8) << tmpTh << " " <<
1071  std::setw (3) << rate.ewmaProb / 180 <<
1072  std::setw (3) << " --- " <<
1073  std::setw (3) << rate.prob / 180 << " " <<
1074  std::setw (1) << rate.adjustedRetryCount << " " <<
1075  std::setw (3) << rate.prevNumRateSuccess << " " <<
1076  std::setw (3) << rate.prevNumRateAttempt << " " <<
1077  std::setw (9) << rate.successHist << " " <<
1078  std::setw (9) << rate.attemptHist << "\n";
1079  }
1080  station->m_statsFile << "\nTotal packet count: ideal " << station->m_totalPacketsCount - station->m_samplePacketsCount
1081  << " lookaround " << station->m_samplePacketsCount << "\n\n";
1082 
1083  station->m_statsFile.flush ();
1084 }
1085 
1086 void
1088 {
1089  //HT is not supported by this algorithm.
1090  if (enable)
1091  {
1092  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HT rates");
1093  }
1094 }
1095 
1096 void
1098 {
1099  //VHT is not supported by this algorithm.
1100  if (enable)
1101  {
1102  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support VHT rates");
1103  }
1104 }
1105 
1106 void
1108 {
1109  //HE is not supported by this algorithm.
1110  if (enable)
1111  {
1112  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
1113  }
1114 }
1115 
1116 } //namespace ns3
void CheckInit(MinstrelWifiRemoteStation *station)
check for initializations
void PrintTable(MinstrelWifiRemoteStation *station)
printing Minstrel Table
uint32_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station)
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...
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
#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 the RngStream.
bool m_printStats
If statistics table should be printed.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time perfectTxTime
Perfect transmission time calculation, or frame calculation Given a bit rate and a packet length n by...
#define min(a, b)
Definition: 80211b.c:44
Implementation of Minstrel Rate Control AlgorithmMinstrel is a rate control algorithm implemented in ...
bool GetUseNonErpProtection(void) const
Return whether the device supports protection of non-ERP stations.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:84
void DoReportFinalDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
hold per-remote-station state for Minstrel Wifi manager.
Time m_updateStats
how frequent do we calculate the stats (1/10 seconds)
void UpdateStats(MinstrelWifiRemoteStation *station)
updating the Minstrel Table every 1/10 seconds
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint32_t m_sampleRate
current sample rate
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1001
uint32_t GetNextSample(MinstrelWifiRemoteStation *station)
getting the next sample from Sample Table
Mac48Address m_address
Mac48Address of the remote station.
bool DoNeedDataRetransmission(WifiRemoteStation *st, Ptr< const Packet > packet, bool normally)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
uint32_t m_txrate
current transmit rate
MinstrelRate m_minstrelTable
minstrel table
std::ofstream m_statsFile
stats file
bool m_sampleDeferred
a flag to indicate sample rate is on the second stage
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1270
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
std::vector< RateInfo > MinstrelRate
Data structure for a Minstrel Rate table A vector of a struct RateInfo.
TracedValue< uint64_t > m_currentRate
Trace rate changes.
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
WifiMode GetSupported(const WifiRemoteStation *station, uint32_t i) const
Return whether mode associated with the specified station at the specified index. ...
uint32_t FindRate(MinstrelWifiRemoteStation *station)
find a rate to use from Minstrel Table
uint32_t m_pktLen
packet length used for calculate mode TxTime
WifiRemoteStationState * m_state
Remote station state.
void SetHeSupported(bool enable)
Enable or disable HE capability support.
uint32_t adjustedRetryCount
adjust the retry limit for this rate
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.
Definition: time.cc:446
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.
void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode)
This method is a pure virtual method that must be implemented by the sub-class.
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2262
uint32_t m_col
To keep track of the current position in the our random sample table going row by row from 1st column...
A struct to contain all information related to a data rate.
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
tuple phy
Definition: third.py:86
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 m_isSampling
a flag to indicate we are currently sampling
int m_numSamplesDeferred
number samles deferred
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:349
void SetHtSupported(bool enable)
Enable or disable HT capability support.
AttributeValue implementation for Time.
Definition: nstime.h:1055
SampleRate m_sampleTable
sample table
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1017
uint32_t prevNumRateSuccess
Number of successful frames transmitted with previous rate.
Hold an unsigned integer type.
Definition: uinteger.h:44
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint32_t i) const
Return whether non-ERP mode associated with the specified station at the specified index...
WifiPreamble GetPreambleForTransmission(WifiMode mode, Mac48Address dest)
Return the preamble to be used for the transmission.
uint64_t GetDataRate(uint8_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:143
void PrintSampleTable(MinstrelWifiRemoteStation *station)
printing Sample Table
uint8_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
uint32_t prevNumRateAttempt
Number of transmission attempts with previous rate.
uint64_t attemptHist
Aggregate of all transmission attempts.
double m_ewmaLevel
exponential weighted moving average
uint64_t successHist
Aggregate of all transmission successes.
WifiRemoteStation * DoCreateStation(void) const
Mac48Address GetAddress(const WifiRemoteStation *station) const
Return the address of the station.
void AddCalcTxTime(WifiMode mode, Time t)
Add transmission time for the given mode to an internal list.
uint32_t GetNModes(void) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:3541
tuple mac
Definition: third.py:92
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...
void DoReportFinalRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
hold a list of per-remote-station state.
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station)
uint32_t m_longRetry
long retries such as data packets
bool m_initialized
for initializing tables
uint32_t ewmaProb
EWMA calculation ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100.
TxTime m_calcTxTime
to hold all the calculated TxTime for all modes
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void UpdateRate(MinstrelWifiRemoteStation *station)
updating the rate
uint32_t m_maxTpRate2
second highest throughput rate
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
WifiTxVector GetDataTxVector(MinstrelWifiRemoteStation *station)
Get data transmit vector.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1056
uint32_t throughput
throughput of a rate
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
uint32_t m_retry
total retries short + long
int m_totalPacketsCount
total number of packets as of now
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void UpdateRetry(MinstrelWifiRemoteStation *station)
update the number of retries and reset accordingly
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: double.h:42
double m_lookAroundRate
the % to try other rates than our current rate
int m_samplePacketsCount
how many packets we have sample so far
static TypeId GetTypeId(void)
Get the type ID.
void InitSampleTable(MinstrelWifiRemoteStation *station)
initialize Sample Table
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...
uint32_t m_maxProbRate
rate with highest prob of success
if(desigRtr==addrLocal)
uint32_t GetLongRetryCount(const WifiRemoteStation *station) const
Return the long retry limit of the given station.
void DoReportRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
uint32_t m_nModes
number of modes supported
WifiTxVector GetRtsTxVector(MinstrelWifiRemoteStation *station)
Get RTS transmit vector.
void SetVhtSupported(bool enable)
Enable or disable VHT capability support.
uint32_t m_maxTpRate
the current throughput rate
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
uint32_t CountRetries(MinstrelWifiRemoteStation *station)
Count retries.
Time GetCalcTxTime(WifiMode mode) const
for estimating the TxTime of a packet with a given mode
void DoReportDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
uint32_t GetShortRetryCount(const WifiRemoteStation *station) const
Return the short retry limit of the given station.
uint32_t m_sampleCol
number of sample columns
uint32_t m_shortRetry
short retries such as control packts
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
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.
a unique identifier for an interface.
Definition: type-id.h:58
Time CalculateTimeUnicastPacket(Time dataTransmissionTime, uint32_t shortRetries, uint32_t longRetries)
Estimate the time to transmit the given packet with the given number of retries.
void RateInit(MinstrelWifiRemoteStation *station)
initialize Minstrel Table
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
std::vector< std::vector< uint32_t > > SampleRate
Data structure for a Sample Rate table A vector of a vector uint32_t.
hold per-remote-station state.
uint32_t prob
(# pkts success )/(# total pkts)
Ptr< WifiMac > GetMac(void) const
Return the WifiMac.
WifiMode GetMode(uint32_t mode) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:3547
void UpdatePacketCounters(MinstrelWifiRemoteStation *station)
Update packet counters.
Time m_nextStatsUpdate
10 times every second