Fixed Bug 802 and Bug 919
authorDuy Nguyen <duy@soe.ucsc.edu>
Thu, 03 Jun 2010 22:38:44 -0700
changeset 6337 92c95748a915
parent 6336 464e8093700d
child 6338 b0e7ab2e00d7
Fixed Bug 802 and Bug 919
src/devices/wifi/minstrel-wifi-manager.cc
src/devices/wifi/minstrel-wifi-manager.h
test.py
--- a/src/devices/wifi/minstrel-wifi-manager.cc	Fri Jun 04 10:17:51 2010 +0900
+++ b/src/devices/wifi/minstrel-wifi-manager.cc	Thu Jun 03 22:38:44 2010 -0700
@@ -44,54 +44,10 @@
 
 namespace ns3 {
 
-/**
- * A struct to contain all information related to a data rate 
- */
-struct RateInfo
-{
-  /**
-   * Perfect transmission time calculation, or frame calculation
-   * Given a bit rate and a packet length n bytes 
-   */
-  Time perfectTxTime;		
-  
-  
-  uint32_t retryCount;  ///< retry limit
-  uint32_t adjustedRetryCount;  ///< adjust the retry limit for this rate
-  uint32_t numRateAttempt;  ///< how many number of attempts so far
-    uint32_t numRateSuccess;  ///< number of successful pkts 
-  uint32_t prob;  ///< (# pkts success )/(# total pkts)
-
-  /**
-   * EWMA calculation
-   * ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100 
-   */
-  uint32_t ewmaProb;
-  
-  uint32_t prevNumRateAttempt;  ///< from last rate
-  uint32_t prevNumRateSuccess;  ///< from last rate
-  uint64_t successHist;  ///< aggregate of all successes
-  uint64_t attemptHist;  ///< aggregate of all attempts
-  uint32_t throughput;  ///< throughput of a rate
-};
-  
-/**
- * Data structure for a Minstrel Rate table 
- * A vector of a struct RateInfo 
- */
-typedef std::vector<struct RateInfo> MinstrelRate;
-
-/**
- * Data structure for a Sample Rate table
- * A vector of a vector uint32_t 
- */
-typedef std::vector<std::vector<uint32_t> > SampleRate;
 
 struct MinstrelWifiRemoteStation : public WifiRemoteStation
 {
   Time m_nextStatsUpdate;  ///< 10 times every second
-  MinstrelRate m_minstrelTable;  ///< minstrel table	
-  SampleRate m_sampleTable;  ///< sample table
 
   /**
    * To keep track of the current position in the our random sample table
@@ -164,7 +120,9 @@
 }
 
 MinstrelWifiManager::MinstrelWifiManager ()
-{}
+{
+  m_nsupported = 0;
+}
 
 MinstrelWifiManager::~MinstrelWifiManager ()
 {}
@@ -232,13 +190,14 @@
 void 
 MinstrelWifiManager::CheckInit(MinstrelWifiRemoteStation *station)
 {
-  if (!station->m_initialized)
+  if (!station->m_initialized && GetNSupported (station) > 1)
     {
       // Note: we appear to be doing late initialization of the table 
       // to make sure that the set of supported rates has been initialized
       // before we perform our own initialization.
-      station->m_minstrelTable = MinstrelRate(GetNSupported (station));
-      station->m_sampleTable = SampleRate(GetNSupported (station), std::vector<uint32_t> (m_sampleCol));
+      m_nsupported = GetNSupported (station);
+      m_minstrelTable = MinstrelRate(m_nsupported);
+      m_sampleTable = SampleRate(m_nsupported, std::vector<uint32_t> (m_sampleCol));
       InitSampleTable (station);
       RateInit (station);
       station->m_initialized = true;
@@ -296,6 +255,10 @@
    */
 
   CheckInit(station);
+  if (!station->m_initialized)
+    {
+      return;
+    }
 
   station->m_longRetry++;
 
@@ -305,30 +268,30 @@
   if (!station->m_isSampling)
     {
       /// use best throughput rate
-      if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
+      if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
         {
           ;  ///<  there's still a few retries left
         }
 
       /// use second best throughput rate
-      else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
-                                        station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
+      else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
+                                        m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
         {
           station->m_txrate = station->m_maxTpRate2;
         }
 
       /// use best probability rate
-      else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
-                                        station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + 
-                                        station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
+      else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
+                                        m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + 
+                                        m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
         {
           station->m_txrate = station->m_maxProbRate;
         }
 
       /// use lowest base rate	
-      else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
-                              station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + 
-                              station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
+      else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
+                              m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + 
+                              m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
         {
           station->m_txrate = 0;
         }
@@ -341,30 +304,30 @@
       if (station->m_sampleRateSlower)
         {
           /// use best throughput rate
-          if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
+          if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
             {
               ;	///<  there are a few retries left
             }
 
           ///	use random rate
-          else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + 
-                                            station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
+          else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + 
+                                            m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
             {
               station->m_txrate = station->m_sampleRate;
             }
 
           /// use max probability rate
-          else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
-                                            station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount + 
-                                            station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount ))
+          else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
+                                            m_minstrelTable[station->m_sampleRate].adjustedRetryCount + 
+                                            m_minstrelTable[station->m_maxTpRate].adjustedRetryCount ))
             {
               station->m_txrate = station->m_maxProbRate;
             }
 
           /// use lowest base rate
-          else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +  
-                                           station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount + 
-                                           station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
+          else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount +  
+                                           m_minstrelTable[station->m_sampleRate].adjustedRetryCount + 
+                                           m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
             {
               station->m_txrate = 0;
             }
@@ -374,30 +337,30 @@
         else
           {
             /// use random rate
-            if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
+            if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
               {
                 ;  ///< keep using it
               }
 
             /// use the best rate
-            else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + 
-                                              station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
+            else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + 
+                                              m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
               {
                 station->m_txrate = station->m_maxTpRate;
               }
 
             /// use the best probability rate
-            else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + 
-                                              station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +  
-                                              station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
+            else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + 
+                                              m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +  
+                                              m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
               {
                 station->m_txrate = station->m_maxProbRate;
               }
 
             /// use the lowest base rate
-            else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + 
-                                             station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +  
-                                             station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
+            else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount + 
+                                             m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +  
+                                             m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
               {
                 station->m_txrate = 0;
               }
@@ -415,16 +378,20 @@
   station->m_sampleRateSlower=false;
 
   CheckInit (station);
+  if (!station->m_initialized)
+    {
+      return;
+    }
 
-  station->m_minstrelTable[station->m_txrate].numRateSuccess++;
-  station->m_minstrelTable[station->m_txrate].numRateAttempt++;
+  m_minstrelTable[station->m_txrate].numRateSuccess++;
+  m_minstrelTable[station->m_txrate].numRateAttempt++;
 	
   UpdateRetry (station);
 
-  station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
+  m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
   station->m_packetCount++;
 
-  if (GetNSupported (station) >= 1)
+  if (m_nsupported >= 1)
     {
       station->m_txrate = FindRate (station);
     }
@@ -441,10 +408,10 @@
 
   UpdateRetry (station);
 
-  station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
+  m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
   station->m_err++;
 
-  if (GetNSupported (station) >= 1)
+  if (m_nsupported >= 1)
     {
       station->m_txrate = FindRate (station);
     }
@@ -468,7 +435,7 @@
       CheckInit (station);
 
       /// start the rate at half way
-      station->m_txrate = GetNSupported (station) / 2;
+      station->m_txrate = m_nsupported / 2;
     }
   UpdateStats (station);
   return GetSupported (station, station->m_txrate);
@@ -492,11 +459,11 @@
 MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station)
 {
   uint32_t bitrate;
-  bitrate = station->m_sampleTable[station->m_index][station->m_col];
+  bitrate = m_sampleTable[station->m_index][station->m_col];
   station->m_index++;
 
   /// bookeeping for m_index and m_col variables
-  if (station->m_index > (GetNSupported (station) - 2)) 
+  if (station->m_index > (m_nsupported - 2)) 
     {
       station->m_index =0;
       station->m_col++;
@@ -558,7 +525,7 @@
             }
 
           /// error check
-          if (idx >= GetNSupported (station) || idx < 0)
+          if (idx >= m_nsupported || idx < 0)
             {
               NS_LOG_DEBUG ("ALERT!!! ERROR");
             }
@@ -573,7 +540,7 @@
 
           /// is this rate slower than the current best rate
           station->m_sampleRateSlower = 
-            (station->m_minstrelTable[idx].perfectTxTime > station->m_minstrelTable[station->m_maxTpRate].perfectTxTime);
+            (m_minstrelTable[idx].perfectTxTime > m_minstrelTable[station->m_maxTpRate].perfectTxTime);
 
           /// using the best rate instead
           if (station->m_sampleRateSlower)
@@ -604,6 +571,10 @@
       return;
     }
 
+  if (!station->m_initialized)
+    {
+      return;
+    }
   NS_LOG_DEBUG ("Updating stats="<<this);
 
   station->m_nextStatsUpdate = Simulator::Now () + m_updateStats;
@@ -611,11 +582,11 @@
   Time txTime;
   uint32_t tempProb;
 
-  for (uint32_t i =0; i < GetNSupported (station); i++)
+  for (uint32_t i =0; i < m_nsupported; i++)
     {        
 
       /// calculate the perfect tx time for this rate
-      txTime = station->m_minstrelTable[i].perfectTxTime;       
+      txTime = m_minstrelTable[i].perfectTxTime;       
 
       /// just for initialization
       if (txTime.GetMicroSeconds () == 0)
@@ -624,61 +595,61 @@
         }
 
       NS_LOG_DEBUG ("m_txrate=" << station->m_txrate << 
-                    "\t attempt=" << station->m_minstrelTable[i].numRateAttempt << 
-                    "\t success=" << station->m_minstrelTable[i].numRateSuccess);
+                    "\t attempt=" << m_minstrelTable[i].numRateAttempt << 
+                    "\t success=" << m_minstrelTable[i].numRateSuccess);
 
       /// if we've attempted something
-      if (station->m_minstrelTable[i].numRateAttempt)
+      if (m_minstrelTable[i].numRateAttempt)
         {
           /**
            * calculate the probability of success
            * assume probability scales from 0 to 18000
            */
-          tempProb = (station->m_minstrelTable[i].numRateSuccess * 18000) / station->m_minstrelTable[i].numRateAttempt;
+          tempProb = (m_minstrelTable[i].numRateSuccess * 18000) / m_minstrelTable[i].numRateAttempt;
 
           /// bookeeping
-          station->m_minstrelTable[i].successHist += station->m_minstrelTable[i].numRateSuccess;
-          station->m_minstrelTable[i].attemptHist += station->m_minstrelTable[i].numRateAttempt;
-          station->m_minstrelTable[i].prob = tempProb;
+          m_minstrelTable[i].successHist += m_minstrelTable[i].numRateSuccess;
+          m_minstrelTable[i].attemptHist += m_minstrelTable[i].numRateAttempt;
+          m_minstrelTable[i].prob = tempProb;
 
           /// ewma probability (cast for gcc 3.4 compatibility)
-          tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (station->m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100);
+          tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100);
 
-          station->m_minstrelTable[i].ewmaProb = tempProb;
+          m_minstrelTable[i].ewmaProb = tempProb;
 
           /// calculating throughput
-          station->m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds());
+          m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds());
 
         }
 
       /// bookeeping
-      station->m_minstrelTable[i].prevNumRateAttempt = station->m_minstrelTable[i].numRateAttempt;
-      station->m_minstrelTable[i].prevNumRateSuccess = station->m_minstrelTable[i].numRateSuccess;
-      station->m_minstrelTable[i].numRateSuccess = 0;
-      station->m_minstrelTable[i].numRateAttempt = 0;
+      m_minstrelTable[i].prevNumRateAttempt = m_minstrelTable[i].numRateAttempt;
+      m_minstrelTable[i].prevNumRateSuccess = m_minstrelTable[i].numRateSuccess;
+      m_minstrelTable[i].numRateSuccess = 0;
+      m_minstrelTable[i].numRateAttempt = 0;
 
       /// Sample less often below 10% and  above 95% of success
-      if ((station->m_minstrelTable[i].ewmaProb > 17100) || (station->m_minstrelTable[i].ewmaProb < 1800)) 
+      if ((m_minstrelTable[i].ewmaProb > 17100) || (m_minstrelTable[i].ewmaProb < 1800)) 
         {
           /**
            * retry count denotes the number of retries permitted for each rate
            * # retry_count/2
            */
-          station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount >> 1;
-          if (station->m_minstrelTable[i].adjustedRetryCount > 2)
+          m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount >> 1;
+          if (m_minstrelTable[i].adjustedRetryCount > 2)
             {
-              station->m_minstrelTable[i].adjustedRetryCount = 2 ;
+              m_minstrelTable[i].adjustedRetryCount = 2 ;
             }
         }
       else
         {
-          station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount;
+          m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount;
         }
 
       /// if it's 0 allow one retry limit
-      if (station->m_minstrelTable[i].adjustedRetryCount == 0)
+      if (m_minstrelTable[i].adjustedRetryCount == 0)
         {
-          station->m_minstrelTable[i].adjustedRetryCount = 1;
+          m_minstrelTable[i].adjustedRetryCount = 1;
         }
     }
 
@@ -686,33 +657,33 @@
   uint32_t max_prob = 0, index_max_prob =0, max_tp =0, index_max_tp=0, index_max_tp2=0;
 
   /// go find max throughput, second maximum throughput, high probability succ
-  for (uint32_t i =0; i < GetNSupported (station); i++) 
+  for (uint32_t i =0; i < m_nsupported; i++) 
     {
-      NS_LOG_DEBUG ("throughput" << station->m_minstrelTable[i].throughput << 
-                    "\n ewma" << station->m_minstrelTable[i].ewmaProb);
+      NS_LOG_DEBUG ("throughput" << m_minstrelTable[i].throughput << 
+                    "\n ewma" << m_minstrelTable[i].ewmaProb);
 
-      if (max_tp < station->m_minstrelTable[i].throughput) 
+      if (max_tp < m_minstrelTable[i].throughput) 
         {
           index_max_tp = i;
-          max_tp = station->m_minstrelTable[i].throughput;
+          max_tp = m_minstrelTable[i].throughput;
         }
 
-      if (max_prob < station->m_minstrelTable[i].ewmaProb) 
+      if (max_prob < m_minstrelTable[i].ewmaProb) 
         {
           index_max_prob = i;
-          max_prob = station->m_minstrelTable[i].ewmaProb;
+          max_prob = m_minstrelTable[i].ewmaProb;
         }
     }
 
 
   max_tp = 0;
   /// find the second highest max
-  for (uint32_t i =0; i < GetNSupported (station); i++) 
+  for (uint32_t i =0; i < m_nsupported; i++) 
     {
-      if ((i != index_max_tp) && (max_tp < station->m_minstrelTable[i].throughput))
+      if ((i != index_max_tp) && (max_tp < m_minstrelTable[i].throughput))
         {
           index_max_tp2 = i;
-          max_tp = station->m_minstrelTable[i].throughput;
+          max_tp = m_minstrelTable[i].throughput;
         }
     }
 
@@ -737,20 +708,20 @@
 {
   NS_LOG_DEBUG ("RateInit="<<station);
 
-  for (uint32_t i = 0; i < GetNSupported (station); i++)
+  for (uint32_t i = 0; i < m_nsupported; i++)
     {
-      station->m_minstrelTable[i].numRateAttempt = 0;
-      station->m_minstrelTable[i].numRateSuccess = 0;
-      station->m_minstrelTable[i].prob = 0;
-      station->m_minstrelTable[i].ewmaProb = 0;
-      station->m_minstrelTable[i].prevNumRateAttempt = 0;
-      station->m_minstrelTable[i].prevNumRateSuccess = 0;
-      station->m_minstrelTable[i].successHist = 0;
-      station->m_minstrelTable[i].attemptHist = 0;
-      station->m_minstrelTable[i].throughput = 0;
-      station->m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i));
-      station->m_minstrelTable[i].retryCount = 1;
-      station->m_minstrelTable[i].adjustedRetryCount = 1;
+      m_minstrelTable[i].numRateAttempt = 0;
+      m_minstrelTable[i].numRateSuccess = 0;
+      m_minstrelTable[i].prob = 0;
+      m_minstrelTable[i].ewmaProb = 0;
+      m_minstrelTable[i].prevNumRateAttempt = 0;
+      m_minstrelTable[i].prevNumRateSuccess = 0;
+      m_minstrelTable[i].successHist = 0;
+      m_minstrelTable[i].attemptHist = 0;
+      m_minstrelTable[i].throughput = 0;
+      m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i));
+      m_minstrelTable[i].retryCount = 1;
+      m_minstrelTable[i].adjustedRetryCount = 1;
     }
 }
 
@@ -762,7 +733,7 @@
   station->m_col = station->m_index = 0;
 
   /// for off-seting to make rates fall between 0 and numrates 
-  uint32_t numSampleRates = GetNSupported (station);
+  uint32_t numSampleRates = m_nsupported;
 
   uint32_t newIndex;
   for (uint32_t col = 0; col < m_sampleCol; col++)
@@ -778,11 +749,11 @@
           newIndex = (i + (uint32_t)uv.GetValue	()) % numSampleRates;	
 
           /// this loop is used for filling in other uninitilized places
-          while	(station->m_sampleTable[newIndex][col] != 0)
+          while	(m_sampleTable[newIndex][col] != 0)
             {
-              newIndex = (newIndex + 1)%GetNSupported (station);
+              newIndex = (newIndex + 1) % m_nsupported;
             }
-          station->m_sampleTable[newIndex][col] = i;
+          m_sampleTable[newIndex][col] = i;
 
         }
     }
@@ -793,12 +764,12 @@
 {
   NS_LOG_DEBUG ("PrintSampleTable="<<station);
 
-  uint32_t numSampleRates = GetNSupported (station);
+  uint32_t numSampleRates = m_nsupported;
   for (uint32_t i = 0; i < numSampleRates; i++)
     {
       for (uint32_t j = 0; j < m_sampleCol; j++)
         {
-          std::cout << station->m_sampleTable[i][j] << "\t";
+          std::cout << m_sampleTable[i][j] << "\t";
         }
       std::cout << std::endl;
     }
@@ -809,9 +780,9 @@
 {
   NS_LOG_DEBUG ("PrintTable="<<station);
 
-  for (uint32_t i=0; i < GetNSupported (station); i++)
+  for (uint32_t i=0; i < m_nsupported; i++)
     {
-      std::cout << "index(" << i << ") = " << station->m_minstrelTable[i].perfectTxTime<< "\n";
+      std::cout << "index(" << i << ") = " << m_minstrelTable[i].perfectTxTime<< "\n";
     }
 }
 
--- a/src/devices/wifi/minstrel-wifi-manager.h	Fri Jun 04 10:17:51 2010 +0900
+++ b/src/devices/wifi/minstrel-wifi-manager.h	Thu Jun 03 22:38:44 2010 -0700
@@ -41,6 +41,50 @@
 
 class MinstrelWifiRemoteStation;
 
+/**
+ * A struct to contain all information related to a data rate
+ */
+struct RateInfo
+{
+  /**
+   * Perfect transmission time calculation, or frame calculation
+   * Given a bit rate and a packet length n bytes
+   */
+  Time perfectTxTime;
+
+
+  uint32_t retryCount;  ///< retry limit
+  uint32_t adjustedRetryCount;  ///< adjust the retry limit for this rate
+  uint32_t numRateAttempt;  ///< how many number of attempts so far
+    uint32_t numRateSuccess;  ///< number of successful pkts
+  uint32_t prob;  ///< (# pkts success )/(# total pkts)
+
+  /**
+   * EWMA calculation
+   * ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100
+   */
+  uint32_t ewmaProb;
+
+  uint32_t prevNumRateAttempt;  ///< from last rate
+  uint32_t prevNumRateSuccess;  ///< from last rate
+  uint64_t successHist;  ///< aggregate of all successes
+  uint64_t attemptHist;  ///< aggregate of all attempts
+  uint32_t throughput;  ///< throughput of a rate
+};
+
+/**
+ * Data structure for a Minstrel Rate table
+ * A vector of a struct RateInfo
+ */
+typedef std::vector<struct RateInfo> MinstrelRate;
+
+/**
+ * Data structure for a Sample Rate table
+ * A vector of a vector uint32_t
+ */
+typedef std::vector<std::vector<uint32_t> > SampleRate;
+
+
 
 class MinstrelWifiManager : public WifiRemoteStationManager
 {
@@ -101,6 +145,9 @@
 
 
   typedef std::vector<std::pair<Time,WifiMode> > TxTime;
+  MinstrelRate m_minstrelTable;  ///< minstrel table
+  SampleRate m_sampleTable;  ///< sample table
+
 
   TxTime m_calcTxTime;  ///< to hold all the calculated TxTime for all modes
   Time m_updateStats;  ///< how frequent do we calculate the stats(1/10 seconds)
@@ -109,6 +156,7 @@
   uint32_t m_segmentSize;  ///< largest allowable segment size
   uint32_t m_sampleCol;  ///< number of sample columns
   uint32_t m_pktLen;  ///< packet length used  for calculate mode TxTime  
+  uint32_t m_nsupported;  ///< modes supported
 };
 
 }// namespace ns3
--- a/test.py	Fri Jun 04 10:17:51 2010 +0900
+++ b/test.py	Thu Jun 03 22:38:44 2010 -0700
@@ -148,6 +148,7 @@
     ("wireless/multirate --totalTime=0.3s --rateManager=ns3::AmrrWifiManager", "True", "True"), 
     ("wireless/multirate --totalTime=0.3s --rateManager=ns3::CaraWifiManager", "True", "True"), 
     ("wireless/multirate --totalTime=0.3s --rateManager=ns3::IdealWifiManager", "True", "True"), 
+    ("wireless/multirate --totalTime=0.3s --rateManager=ns3::MinstrelWifiManager", "True", "True"), 
     ("wireless/multirate --totalTime=0.3s --rateManager=ns3::OnoeWifiManager", "True", "True"), 
     ("wireless/multirate --totalTime=0.3s --rateManager=ns3::RraaWifiManager", "True", "True"), 
     ("wireless/simple-wifi-frame-aggregation", "True", "True"),