View | Details | Raw Unified | Return to bug 802
Collapse All | Expand All

(-)a/src/devices/wifi/minstrel-wifi-manager.cc (-140 / +111 lines)
 Lines 44-97    Link Here 
44
44
45
namespace ns3 {
45
namespace ns3 {
46
46
47
/**
48
 * A struct to contain all information related to a data rate 
49
 */
50
struct RateInfo
51
{
52
  /**
53
   * Perfect transmission time calculation, or frame calculation
54
   * Given a bit rate and a packet length n bytes 
55
   */
56
  Time perfectTxTime;		
57
  
58
  
59
  uint32_t retryCount;  ///< retry limit
60
  uint32_t adjustedRetryCount;  ///< adjust the retry limit for this rate
61
  uint32_t numRateAttempt;  ///< how many number of attempts so far
62
    uint32_t numRateSuccess;  ///< number of successful pkts 
63
  uint32_t prob;  ///< (# pkts success )/(# total pkts)
64
65
  /**
66
   * EWMA calculation
67
   * ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100 
68
   */
69
  uint32_t ewmaProb;
70
  
71
  uint32_t prevNumRateAttempt;  ///< from last rate
72
  uint32_t prevNumRateSuccess;  ///< from last rate
73
  uint64_t successHist;  ///< aggregate of all successes
74
  uint64_t attemptHist;  ///< aggregate of all attempts
75
  uint32_t throughput;  ///< throughput of a rate
76
};
77
  
78
/**
79
 * Data structure for a Minstrel Rate table 
80
 * A vector of a struct RateInfo 
81
 */
82
typedef std::vector<struct RateInfo> MinstrelRate;
83
84
/**
85
 * Data structure for a Sample Rate table
86
 * A vector of a vector uint32_t 
87
 */
88
typedef std::vector<std::vector<uint32_t> > SampleRate;
89
47
90
struct MinstrelWifiRemoteStation : public WifiRemoteStation
48
struct MinstrelWifiRemoteStation : public WifiRemoteStation
91
{
49
{
92
  Time m_nextStatsUpdate;  ///< 10 times every second
50
  Time m_nextStatsUpdate;  ///< 10 times every second
93
  MinstrelRate m_minstrelTable;  ///< minstrel table	
94
  SampleRate m_sampleTable;  ///< sample table
95
51
96
  /**
52
  /**
97
   * To keep track of the current position in the our random sample table
53
   * To keep track of the current position in the our random sample table
 Lines 164-170    Link Here 
164
}
120
}
165
121
166
MinstrelWifiManager::MinstrelWifiManager ()
122
MinstrelWifiManager::MinstrelWifiManager ()
167
{}
123
{
124
  m_nsupported = 0;
125
}
168
126
169
MinstrelWifiManager::~MinstrelWifiManager ()
127
MinstrelWifiManager::~MinstrelWifiManager ()
170
{}
128
{}
 Lines 232-244    Link Here 
232
void 
190
void 
233
MinstrelWifiManager::CheckInit(MinstrelWifiRemoteStation *station)
191
MinstrelWifiManager::CheckInit(MinstrelWifiRemoteStation *station)
234
{
192
{
235
  if (!station->m_initialized)
193
  if (!station->m_initialized && GetNSupported (station) > 1)
236
    {
194
    {
237
      // Note: we appear to be doing late initialization of the table 
195
      // Note: we appear to be doing late initialization of the table 
238
      // to make sure that the set of supported rates has been initialized
196
      // to make sure that the set of supported rates has been initialized
239
      // before we perform our own initialization.
197
      // before we perform our own initialization.
240
      station->m_minstrelTable = MinstrelRate(GetNSupported (station));
198
      m_nsupported = GetNSupported (station);
241
      station->m_sampleTable = SampleRate(GetNSupported (station), std::vector<uint32_t> (m_sampleCol));
199
      m_minstrelTable = MinstrelRate(m_nsupported);
200
      m_sampleTable = SampleRate(m_nsupported, std::vector<uint32_t> (m_sampleCol));
242
      InitSampleTable (station);
201
      InitSampleTable (station);
243
      RateInit (station);
202
      RateInit (station);
244
      station->m_initialized = true;
203
      station->m_initialized = true;
 Lines 296-301    Link Here 
296
   */
255
   */
297
256
298
  CheckInit(station);
257
  CheckInit(station);
258
  if (!station->m_initialized)
259
    {
260
      return;
261
    }
299
262
300
  station->m_longRetry++;
263
  station->m_longRetry++;
301
264
 Lines 305-334    Link Here 
305
  if (!station->m_isSampling)
268
  if (!station->m_isSampling)
306
    {
269
    {
307
      /// use best throughput rate
270
      /// use best throughput rate
308
      if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
271
      if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
309
        {
272
        {
310
          ;  ///<  there's still a few retries left
273
          ;  ///<  there's still a few retries left
311
        }
274
        }
312
275
313
      /// use second best throughput rate
276
      /// use second best throughput rate
314
      else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
277
      else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
315
                                        station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
278
                                        m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
316
        {
279
        {
317
          station->m_txrate = station->m_maxTpRate2;
280
          station->m_txrate = station->m_maxTpRate2;
318
        }
281
        }
319
282
320
      /// use best probability rate
283
      /// use best probability rate
321
      else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
284
      else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
322
                                        station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + 
285
                                        m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + 
323
                                        station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
286
                                        m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
324
        {
287
        {
325
          station->m_txrate = station->m_maxProbRate;
288
          station->m_txrate = station->m_maxProbRate;
326
        }
289
        }
327
290
328
      /// use lowest base rate	
291
      /// use lowest base rate	
329
      else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
292
      else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
330
                              station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + 
293
                              m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + 
331
                              station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
294
                              m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
332
        {
295
        {
333
          station->m_txrate = 0;
296
          station->m_txrate = 0;
334
        }
297
        }
 Lines 341-370    Link Here 
341
      if (station->m_sampleRateSlower)
304
      if (station->m_sampleRateSlower)
342
        {
305
        {
343
          /// use best throughput rate
306
          /// use best throughput rate
344
          if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
307
          if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
345
            {
308
            {
346
              ;	///<  there are a few retries left
309
              ;	///<  there are a few retries left
347
            }
310
            }
348
311
349
          ///	use random rate
312
          ///	use random rate
350
          else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + 
313
          else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + 
351
                                            station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
314
                                            m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
352
            {
315
            {
353
              station->m_txrate = station->m_sampleRate;
316
              station->m_txrate = station->m_sampleRate;
354
            }
317
            }
355
318
356
          /// use max probability rate
319
          /// use max probability rate
357
          else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
320
          else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
358
                                            station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount + 
321
                                            m_minstrelTable[station->m_sampleRate].adjustedRetryCount + 
359
                                            station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount ))
322
                                            m_minstrelTable[station->m_maxTpRate].adjustedRetryCount ))
360
            {
323
            {
361
              station->m_txrate = station->m_maxProbRate;
324
              station->m_txrate = station->m_maxProbRate;
362
            }
325
            }
363
326
364
          /// use lowest base rate
327
          /// use lowest base rate
365
          else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
328
          else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
366
                                           station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount + 
329
                                           m_minstrelTable[station->m_sampleRate].adjustedRetryCount + 
367
                                           station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
330
                                           m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
368
            {
331
            {
369
              station->m_txrate = 0;
332
              station->m_txrate = 0;
370
            }
333
            }
 Lines 374-403    Link Here 
374
        else
337
        else
375
          {
338
          {
376
            /// use random rate
339
            /// use random rate
377
            if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
340
            if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
378
              {
341
              {
379
                ;  ///< keep using it
342
                ;  ///< keep using it
380
              }
343
              }
381
344
382
            /// use the best rate
345
            /// use the best rate
383
            else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + 
346
            else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + 
384
                                              station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
347
                                              m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
385
              {
348
              {
386
                station->m_txrate = station->m_maxTpRate;
349
                station->m_txrate = station->m_maxTpRate;
387
              }
350
              }
388
351
389
            /// use the best probability rate
352
            /// use the best probability rate
390
            else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + 
353
            else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + 
391
                                              station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +  
354
                                              m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +  
392
                                              station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
355
                                              m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
393
              {
356
              {
394
                station->m_txrate = station->m_maxProbRate;
357
                station->m_txrate = station->m_maxProbRate;
395
              }
358
              }
396
359
397
            /// use the lowest base rate
360
            /// use the lowest base rate
398
            else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + 
361
            else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount + 
399
                                             station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +  
362
                                             m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +  
400
                                             station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
363
                                             m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
401
              {
364
              {
402
                station->m_txrate = 0;
365
                station->m_txrate = 0;
403
              }
366
              }
 Lines 415-430    Link Here 
415
  station->m_sampleRateSlower=false;
378
  station->m_sampleRateSlower=false;
416
379
417
  CheckInit (station);
380
  CheckInit (station);
381
  if (!station->m_initialized)
382
    {
383
      return;
384
    }
418
385
419
  station->m_minstrelTable[station->m_txrate].numRateSuccess++;
386
  m_minstrelTable[station->m_txrate].numRateSuccess++;
420
  station->m_minstrelTable[station->m_txrate].numRateAttempt++;
387
  m_minstrelTable[station->m_txrate].numRateAttempt++;
421
	
388
	
422
  UpdateRetry (station);
389
  UpdateRetry (station);
423
390
424
  station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
391
  m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
425
  station->m_packetCount++;
392
  station->m_packetCount++;
426
393
427
  if (GetNSupported (station) >= 1)
394
  if (m_nsupported >= 1)
428
    {
395
    {
429
      station->m_txrate = FindRate (station);
396
      station->m_txrate = FindRate (station);
430
    }
397
    }
 Lines 441-450    Link Here 
441
408
442
  UpdateRetry (station);
409
  UpdateRetry (station);
443
410
444
  station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
411
  m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
445
  station->m_err++;
412
  station->m_err++;
446
413
447
  if (GetNSupported (station) >= 1)
414
  if (m_nsupported >= 1)
448
    {
415
    {
449
      station->m_txrate = FindRate (station);
416
      station->m_txrate = FindRate (station);
450
    }
417
    }
 Lines 468-474    Link Here 
468
      CheckInit (station);
435
      CheckInit (station);
469
436
470
      /// start the rate at half way
437
      /// start the rate at half way
471
      station->m_txrate = GetNSupported (station) / 2;
438
      station->m_txrate = m_nsupported / 2;
472
    }
439
    }
473
  UpdateStats (station);
440
  UpdateStats (station);
474
  return GetSupported (station, station->m_txrate);
441
  return GetSupported (station, station->m_txrate);
 Lines 492-502    Link Here 
492
MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station)
459
MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station)
493
{
460
{
494
  uint32_t bitrate;
461
  uint32_t bitrate;
495
  bitrate = station->m_sampleTable[station->m_index][station->m_col];
462
  bitrate = m_sampleTable[station->m_index][station->m_col];
496
  station->m_index++;
463
  station->m_index++;
497
464
498
  /// bookeeping for m_index and m_col variables
465
  /// bookeeping for m_index and m_col variables
499
  if (station->m_index > (GetNSupported (station) - 2)) 
466
  if (station->m_index > (m_nsupported - 2)) 
500
    {
467
    {
501
      station->m_index =0;
468
      station->m_index =0;
502
      station->m_col++;
469
      station->m_col++;
 Lines 558-564    Link Here 
558
            }
525
            }
559
526
560
          /// error check
527
          /// error check
561
          if (idx >= GetNSupported (station) || idx < 0)
528
          if (idx >= m_nsupported || idx < 0)
562
            {
529
            {
563
              NS_LOG_DEBUG ("ALERT!!! ERROR");
530
              NS_LOG_DEBUG ("ALERT!!! ERROR");
564
            }
531
            }
 Lines 573-579    Link Here 
573
540
574
          /// is this rate slower than the current best rate
541
          /// is this rate slower than the current best rate
575
          station->m_sampleRateSlower = 
542
          station->m_sampleRateSlower = 
576
            (station->m_minstrelTable[idx].perfectTxTime > station->m_minstrelTable[station->m_maxTpRate].perfectTxTime);
543
            (m_minstrelTable[idx].perfectTxTime > m_minstrelTable[station->m_maxTpRate].perfectTxTime);
577
544
578
          /// using the best rate instead
545
          /// using the best rate instead
579
          if (station->m_sampleRateSlower)
546
          if (station->m_sampleRateSlower)
 Lines 604-609    Link Here 
604
      return;
571
      return;
605
    }
572
    }
606
573
574
  if (!station->m_initialized)
575
    {
576
      return;
577
    }
607
  NS_LOG_DEBUG ("Updating stats="<<this);
578
  NS_LOG_DEBUG ("Updating stats="<<this);
608
579
609
  station->m_nextStatsUpdate = Simulator::Now () + m_updateStats;
580
  station->m_nextStatsUpdate = Simulator::Now () + m_updateStats;
 Lines 611-621    Link Here 
611
  Time txTime;
582
  Time txTime;
612
  uint32_t tempProb;
583
  uint32_t tempProb;
613
584
614
  for (uint32_t i =0; i < GetNSupported (station); i++)
585
  for (uint32_t i =0; i < m_nsupported; i++)
615
    {        
586
    {        
616
587
617
      /// calculate the perfect tx time for this rate
588
      /// calculate the perfect tx time for this rate
618
      txTime = station->m_minstrelTable[i].perfectTxTime;       
589
      txTime = m_minstrelTable[i].perfectTxTime;       
619
590
620
      /// just for initialization
591
      /// just for initialization
621
      if (txTime.GetMicroSeconds () == 0)
592
      if (txTime.GetMicroSeconds () == 0)
 Lines 624-684    Link Here 
624
        }
595
        }
625
596
626
      NS_LOG_DEBUG ("m_txrate=" << station->m_txrate << 
597
      NS_LOG_DEBUG ("m_txrate=" << station->m_txrate << 
627
                    "\t attempt=" << station->m_minstrelTable[i].numRateAttempt << 
598
                    "\t attempt=" << m_minstrelTable[i].numRateAttempt << 
628
                    "\t success=" << station->m_minstrelTable[i].numRateSuccess);
599
                    "\t success=" << m_minstrelTable[i].numRateSuccess);
629
600
630
      /// if we've attempted something
601
      /// if we've attempted something
631
      if (station->m_minstrelTable[i].numRateAttempt)
602
      if (m_minstrelTable[i].numRateAttempt)
632
        {
603
        {
633
          /**
604
          /**
634
           * calculate the probability of success
605
           * calculate the probability of success
635
           * assume probability scales from 0 to 18000
606
           * assume probability scales from 0 to 18000
636
           */
607
           */
637
          tempProb = (station->m_minstrelTable[i].numRateSuccess * 18000) / station->m_minstrelTable[i].numRateAttempt;
608
          tempProb = (m_minstrelTable[i].numRateSuccess * 18000) / m_minstrelTable[i].numRateAttempt;
638
609
639
          /// bookeeping
610
          /// bookeeping
640
          station->m_minstrelTable[i].successHist += station->m_minstrelTable[i].numRateSuccess;
611
          m_minstrelTable[i].successHist += m_minstrelTable[i].numRateSuccess;
641
          station->m_minstrelTable[i].attemptHist += station->m_minstrelTable[i].numRateAttempt;
612
          m_minstrelTable[i].attemptHist += m_minstrelTable[i].numRateAttempt;
642
          station->m_minstrelTable[i].prob = tempProb;
613
          m_minstrelTable[i].prob = tempProb;
643
614
644
          /// ewma probability (cast for gcc 3.4 compatibility)
615
          /// ewma probability (cast for gcc 3.4 compatibility)
645
          tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (station->m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100);
616
          tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100);
646
617
647
          station->m_minstrelTable[i].ewmaProb = tempProb;
618
          m_minstrelTable[i].ewmaProb = tempProb;
648
619
649
          /// calculating throughput
620
          /// calculating throughput
650
          station->m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds());
621
          m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds());
651
622
652
        }
623
        }
653
624
654
      /// bookeeping
625
      /// bookeeping
655
      station->m_minstrelTable[i].prevNumRateAttempt = station->m_minstrelTable[i].numRateAttempt;
626
      m_minstrelTable[i].prevNumRateAttempt = m_minstrelTable[i].numRateAttempt;
656
      station->m_minstrelTable[i].prevNumRateSuccess = station->m_minstrelTable[i].numRateSuccess;
627
      m_minstrelTable[i].prevNumRateSuccess = m_minstrelTable[i].numRateSuccess;
657
      station->m_minstrelTable[i].numRateSuccess = 0;
628
      m_minstrelTable[i].numRateSuccess = 0;
658
      station->m_minstrelTable[i].numRateAttempt = 0;
629
      m_minstrelTable[i].numRateAttempt = 0;
659
630
660
      /// Sample less often below 10% and  above 95% of success
631
      /// Sample less often below 10% and  above 95% of success
661
      if ((station->m_minstrelTable[i].ewmaProb > 17100) || (station->m_minstrelTable[i].ewmaProb < 1800)) 
632
      if ((m_minstrelTable[i].ewmaProb > 17100) || (m_minstrelTable[i].ewmaProb < 1800)) 
662
        {
633
        {
663
          /**
634
          /**
664
           * retry count denotes the number of retries permitted for each rate
635
           * retry count denotes the number of retries permitted for each rate
665
           * # retry_count/2
636
           * # retry_count/2
666
           */
637
           */
667
          station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount >> 1;
638
          m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount >> 1;
668
          if (station->m_minstrelTable[i].adjustedRetryCount > 2)
639
          if (m_minstrelTable[i].adjustedRetryCount > 2)
669
            {
640
            {
670
              station->m_minstrelTable[i].adjustedRetryCount = 2 ;
641
              m_minstrelTable[i].adjustedRetryCount = 2 ;
671
            }
642
            }
672
        }
643
        }
673
      else
644
      else
674
        {
645
        {
675
          station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount;
646
          m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount;
676
        }
647
        }
677
648
678
      /// if it's 0 allow one retry limit
649
      /// if it's 0 allow one retry limit
679
      if (station->m_minstrelTable[i].adjustedRetryCount == 0)
650
      if (m_minstrelTable[i].adjustedRetryCount == 0)
680
        {
651
        {
681
          station->m_minstrelTable[i].adjustedRetryCount = 1;
652
          m_minstrelTable[i].adjustedRetryCount = 1;
682
        }
653
        }
683
    }
654
    }
684
655
 Lines 686-718    Link Here 
686
  uint32_t max_prob = 0, index_max_prob =0, max_tp =0, index_max_tp=0, index_max_tp2=0;
657
  uint32_t max_prob = 0, index_max_prob =0, max_tp =0, index_max_tp=0, index_max_tp2=0;
687
658
688
  /// go find max throughput, second maximum throughput, high probability succ
659
  /// go find max throughput, second maximum throughput, high probability succ
689
  for (uint32_t i =0; i < GetNSupported (station); i++) 
660
  for (uint32_t i =0; i < m_nsupported; i++) 
690
    {
661
    {
691
      NS_LOG_DEBUG ("throughput" << station->m_minstrelTable[i].throughput << 
662
      NS_LOG_DEBUG ("throughput" << m_minstrelTable[i].throughput << 
692
                    "\n ewma" << station->m_minstrelTable[i].ewmaProb);
663
                    "\n ewma" << m_minstrelTable[i].ewmaProb);
693
664
694
      if (max_tp < station->m_minstrelTable[i].throughput) 
665
      if (max_tp < m_minstrelTable[i].throughput) 
695
        {
666
        {
696
          index_max_tp = i;
667
          index_max_tp = i;
697
          max_tp = station->m_minstrelTable[i].throughput;
668
          max_tp = m_minstrelTable[i].throughput;
698
        }
669
        }
699
670
700
      if (max_prob < station->m_minstrelTable[i].ewmaProb) 
671
      if (max_prob < m_minstrelTable[i].ewmaProb) 
701
        {
672
        {
702
          index_max_prob = i;
673
          index_max_prob = i;
703
          max_prob = station->m_minstrelTable[i].ewmaProb;
674
          max_prob = m_minstrelTable[i].ewmaProb;
704
        }
675
        }
705
    }
676
    }
706
677
707
678
708
  max_tp = 0;
679
  max_tp = 0;
709
  /// find the second highest max
680
  /// find the second highest max
710
  for (uint32_t i =0; i < GetNSupported (station); i++) 
681
  for (uint32_t i =0; i < m_nsupported; i++) 
711
    {
682
    {
712
      if ((i != index_max_tp) && (max_tp < station->m_minstrelTable[i].throughput))
683
      if ((i != index_max_tp) && (max_tp < m_minstrelTable[i].throughput))
713
        {
684
        {
714
          index_max_tp2 = i;
685
          index_max_tp2 = i;
715
          max_tp = station->m_minstrelTable[i].throughput;
686
          max_tp = m_minstrelTable[i].throughput;
716
        }
687
        }
717
    }
688
    }
718
689
 Lines 737-756    Link Here 
737
{
708
{
738
  NS_LOG_DEBUG ("RateInit="<<station);
709
  NS_LOG_DEBUG ("RateInit="<<station);
739
710
740
  for (uint32_t i = 0; i < GetNSupported (station); i++)
711
  for (uint32_t i = 0; i < m_nsupported; i++)
741
    {
712
    {
742
      station->m_minstrelTable[i].numRateAttempt = 0;
713
      m_minstrelTable[i].numRateAttempt = 0;
743
      station->m_minstrelTable[i].numRateSuccess = 0;
714
      m_minstrelTable[i].numRateSuccess = 0;
744
      station->m_minstrelTable[i].prob = 0;
715
      m_minstrelTable[i].prob = 0;
745
      station->m_minstrelTable[i].ewmaProb = 0;
716
      m_minstrelTable[i].ewmaProb = 0;
746
      station->m_minstrelTable[i].prevNumRateAttempt = 0;
717
      m_minstrelTable[i].prevNumRateAttempt = 0;
747
      station->m_minstrelTable[i].prevNumRateSuccess = 0;
718
      m_minstrelTable[i].prevNumRateSuccess = 0;
748
      station->m_minstrelTable[i].successHist = 0;
719
      m_minstrelTable[i].successHist = 0;
749
      station->m_minstrelTable[i].attemptHist = 0;
720
      m_minstrelTable[i].attemptHist = 0;
750
      station->m_minstrelTable[i].throughput = 0;
721
      m_minstrelTable[i].throughput = 0;
751
      station->m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i));
722
      m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i));
752
      station->m_minstrelTable[i].retryCount = 1;
723
      m_minstrelTable[i].retryCount = 1;
753
      station->m_minstrelTable[i].adjustedRetryCount = 1;
724
      m_minstrelTable[i].adjustedRetryCount = 1;
754
    }
725
    }
755
}
726
}
756
727
 Lines 762-768    Link Here 
762
  station->m_col = station->m_index = 0;
733
  station->m_col = station->m_index = 0;
763
734
764
  /// for off-seting to make rates fall between 0 and numrates 
735
  /// for off-seting to make rates fall between 0 and numrates 
765
  uint32_t numSampleRates = GetNSupported (station);
736
  uint32_t numSampleRates = m_nsupported;
766
737
767
  uint32_t newIndex;
738
  uint32_t newIndex;
768
  for (uint32_t col = 0; col < m_sampleCol; col++)
739
  for (uint32_t col = 0; col < m_sampleCol; col++)
 Lines 778-788    Link Here 
778
          newIndex = (i + (uint32_t)uv.GetValue	()) % numSampleRates;	
749
          newIndex = (i + (uint32_t)uv.GetValue	()) % numSampleRates;	
779
750
780
          /// this loop is used for filling in other uninitilized places
751
          /// this loop is used for filling in other uninitilized places
781
          while	(station->m_sampleTable[newIndex][col] != 0)
752
          while	(m_sampleTable[newIndex][col] != 0)
782
            {
753
            {
783
              newIndex = (newIndex + 1)%GetNSupported (station);
754
              newIndex = (newIndex + 1) % m_nsupported;
784
            }
755
            }
785
          station->m_sampleTable[newIndex][col] = i;
756
          m_sampleTable[newIndex][col] = i;
786
757
787
        }
758
        }
788
    }
759
    }
 Lines 793-804    Link Here 
793
{
764
{
794
  NS_LOG_DEBUG ("PrintSampleTable="<<station);
765
  NS_LOG_DEBUG ("PrintSampleTable="<<station);
795
766
796
  uint32_t numSampleRates = GetNSupported (station);
767
  uint32_t numSampleRates = m_nsupported;
797
  for (uint32_t i = 0; i < numSampleRates; i++)
768
  for (uint32_t i = 0; i < numSampleRates; i++)
798
    {
769
    {
799
      for (uint32_t j = 0; j < m_sampleCol; j++)
770
      for (uint32_t j = 0; j < m_sampleCol; j++)
800
        {
771
        {
801
          std::cout << station->m_sampleTable[i][j] << "\t";
772
          std::cout << m_sampleTable[i][j] << "\t";
802
        }
773
        }
803
      std::cout << std::endl;
774
      std::cout << std::endl;
804
    }
775
    }
 Lines 809-817    Link Here 
809
{
780
{
810
  NS_LOG_DEBUG ("PrintTable="<<station);
781
  NS_LOG_DEBUG ("PrintTable="<<station);
811
782
812
  for (uint32_t i=0; i < GetNSupported (station); i++)
783
  for (uint32_t i=0; i < m_nsupported; i++)
813
    {
784
    {
814
      std::cout << "index(" << i << ") = " << station->m_minstrelTable[i].perfectTxTime<< "\n";
785
      std::cout << "index(" << i << ") = " << m_minstrelTable[i].perfectTxTime<< "\n";
815
    }
786
    }
816
}
787
}
817
788
(-)a/src/devices/wifi/minstrel-wifi-manager.h (+48 lines)
 Lines 40-45    Link Here 
40
namespace ns3 {
40
namespace ns3 {
41
41
42
class MinstrelWifiRemoteStation;
42
class MinstrelWifiRemoteStation;
43
44
/**
45
 * A struct to contain all information related to a data rate
46
 */
47
struct RateInfo
48
{
49
  /**
50
   * Perfect transmission time calculation, or frame calculation
51
   * Given a bit rate and a packet length n bytes
52
   */
53
  Time perfectTxTime;
54
55
56
  uint32_t retryCount;  ///< retry limit
57
  uint32_t adjustedRetryCount;  ///< adjust the retry limit for this rate
58
  uint32_t numRateAttempt;  ///< how many number of attempts so far
59
    uint32_t numRateSuccess;  ///< number of successful pkts
60
  uint32_t prob;  ///< (# pkts success )/(# total pkts)
61
62
  /**
63
   * EWMA calculation
64
   * ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100
65
   */
66
  uint32_t ewmaProb;
67
68
  uint32_t prevNumRateAttempt;  ///< from last rate
69
  uint32_t prevNumRateSuccess;  ///< from last rate
70
  uint64_t successHist;  ///< aggregate of all successes
71
  uint64_t attemptHist;  ///< aggregate of all attempts
72
  uint32_t throughput;  ///< throughput of a rate
73
};
74
75
/**
76
 * Data structure for a Minstrel Rate table
77
 * A vector of a struct RateInfo
78
 */
79
typedef std::vector<struct RateInfo> MinstrelRate;
80
81
/**
82
 * Data structure for a Sample Rate table
83
 * A vector of a vector uint32_t
84
 */
85
typedef std::vector<std::vector<uint32_t> > SampleRate;
86
43
87
44
88
45
class MinstrelWifiManager : public WifiRemoteStationManager
89
class MinstrelWifiManager : public WifiRemoteStationManager
 Lines 101-106    Link Here 
101
145
102
146
103
  typedef std::vector<std::pair<Time,WifiMode> > TxTime;
147
  typedef std::vector<std::pair<Time,WifiMode> > TxTime;
148
  MinstrelRate m_minstrelTable;  ///< minstrel table
149
  SampleRate m_sampleTable;  ///< sample table
150
104
151
105
  TxTime m_calcTxTime;  ///< to hold all the calculated TxTime for all modes
152
  TxTime m_calcTxTime;  ///< to hold all the calculated TxTime for all modes
106
  Time m_updateStats;  ///< how frequent do we calculate the stats(1/10 seconds)
153
  Time m_updateStats;  ///< how frequent do we calculate the stats(1/10 seconds)
 Lines 109-114    Link Here 
109
  uint32_t m_segmentSize;  ///< largest allowable segment size
156
  uint32_t m_segmentSize;  ///< largest allowable segment size
110
  uint32_t m_sampleCol;  ///< number of sample columns
157
  uint32_t m_sampleCol;  ///< number of sample columns
111
  uint32_t m_pktLen;  ///< packet length used  for calculate mode TxTime  
158
  uint32_t m_pktLen;  ///< packet length used  for calculate mode TxTime  
159
  uint32_t m_nsupported;  ///< modes supported
112
};
160
};
113
161
114
}// namespace ns3
162
}// namespace ns3
(-)a/test.py (+1 lines)
 Lines 148-153    Link Here 
148
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::AmrrWifiManager", "True", "True"), 
148
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::AmrrWifiManager", "True", "True"), 
149
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::CaraWifiManager", "True", "True"), 
149
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::CaraWifiManager", "True", "True"), 
150
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::IdealWifiManager", "True", "True"), 
150
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::IdealWifiManager", "True", "True"), 
151
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::MinstrelWifiManager", "True", "True"), 
151
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::OnoeWifiManager", "True", "True"), 
152
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::OnoeWifiManager", "True", "True"), 
152
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::RraaWifiManager", "True", "True"), 
153
    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::RraaWifiManager", "True", "True"), 
153
    ("wireless/simple-wifi-frame-aggregation", "True", "True"),
154
    ("wireless/simple-wifi-frame-aggregation", "True", "True"),

Return to bug 802