src/devices/wifi/amrr-mac-stations.cc
changeset 2545 7a38029a2e5b
parent 2544 2e6e1a6e0d94
child 2546 3fc951966b1b
equal deleted inserted replaced
2544:2e6e1a6e0d94 2545:7a38029a2e5b
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2003,2007 INRIA
       
     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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
       
    19  */
       
    20 
       
    21 #include "amrr-mac-stations.h"
       
    22 #include "ns3/default-value.h"
       
    23 #include "ns3/time-default-value.h"
       
    24 #include "ns3/simulator.h"
       
    25 #include "ns3/log.h"
       
    26 
       
    27 NS_LOG_COMPONENT_DEFINE ("AmrrMacStation");
       
    28 
       
    29 namespace ns3 {
       
    30 
       
    31 static TimeDefaultValue g_updatePeriod
       
    32 ("WifiAmrrUpdatePeriod",
       
    33  "The interval between decisions about rate control changes",
       
    34  Seconds (1.0));
       
    35 static NumericDefaultValue<double> g_failureRatio
       
    36 ("WifiAmrrFailureRatio",
       
    37  "Ratio of erronous transmissions needed to switch to a lower rate",
       
    38  1.0/3.0);
       
    39 static NumericDefaultValue<double> g_successRatio
       
    40 ("WifiAmrrSuccessRatio",
       
    41  "Ratio of erronous transmissions needed to switch to a higher rate",
       
    42  1.0/10.0);
       
    43 static NumericDefaultValue<uint32_t> g_maxSuccessThreshold
       
    44 ("WifiAmrrMaxSuccessThreshold",
       
    45  "maximum number of consecutive success periods needed to switch to a higher rate",
       
    46  10);
       
    47 static NumericDefaultValue<uint32_t> g_minSuccessThreshold
       
    48 ("WifiAmrrMinSuccessThreshold",
       
    49  "minimum number of consecutive success periods needed to switch to a higher rate",
       
    50  1);
       
    51 
       
    52 AmrrMacStations::AmrrMacStations (WifiMode defaultTxMode)
       
    53   : MacStations (defaultTxMode),
       
    54     m_updatePeriod (g_updatePeriod.GetValue ()),
       
    55     m_failureRatio (g_failureRatio.GetValue ()),
       
    56     m_successRatio (g_successRatio.GetValue ()),
       
    57     m_maxSuccessThreshold (g_maxSuccessThreshold.GetValue ()),
       
    58     m_minSuccessThreshold (g_minSuccessThreshold.GetValue ())
       
    59 {}
       
    60 MacStation *
       
    61 AmrrMacStations::CreateStation (void)
       
    62 {
       
    63   return new AmrrMacStation (this);
       
    64 }
       
    65 
       
    66 AmrrMacStation::AmrrMacStation (AmrrMacStations *stations)
       
    67   : m_stations (stations),
       
    68     m_nextModeUpdate (Simulator::Now () + stations->m_updatePeriod),
       
    69     m_tx_ok (0),
       
    70     m_tx_err (0),
       
    71     m_tx_retr (0),
       
    72     m_retry (0),
       
    73     m_txrate (0),
       
    74     m_successThreshold (m_stations->m_minSuccessThreshold),
       
    75     m_success (0),
       
    76     m_recovery (false)
       
    77 {}
       
    78 AmrrMacStation::~AmrrMacStation ()
       
    79 {}
       
    80 
       
    81 void 
       
    82 AmrrMacStation::ReportRxOk (double rxSnr, WifiMode txMode)
       
    83 {}
       
    84 void 
       
    85 AmrrMacStation::ReportRtsFailed (void)
       
    86 {}
       
    87 void 
       
    88 AmrrMacStation::ReportDataFailed (void)
       
    89 {
       
    90   m_retry++;
       
    91   m_tx_retr++;
       
    92 }
       
    93 void 
       
    94 AmrrMacStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
       
    95 {}
       
    96 void 
       
    97 AmrrMacStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
       
    98 {
       
    99   m_retry = 0;
       
   100   m_tx_ok++;
       
   101 }
       
   102 void 
       
   103 AmrrMacStation::ReportFinalRtsFailed (void)
       
   104 {}
       
   105 void 
       
   106 AmrrMacStation::ReportFinalDataFailed (void)
       
   107 {
       
   108   m_retry = 0;
       
   109   m_tx_err++;
       
   110 }
       
   111 bool
       
   112 AmrrMacStation::IsMinRate (void) const
       
   113 {
       
   114   return (m_txrate == 0);
       
   115 }
       
   116 bool
       
   117 AmrrMacStation::IsMaxRate (void) const
       
   118 {
       
   119   NS_ASSERT (m_txrate + 1 <= GetNSupportedModes ());
       
   120   return (m_txrate + 1 == GetNSupportedModes ());
       
   121 }
       
   122 bool
       
   123 AmrrMacStation::IsSuccess (void) const
       
   124 {
       
   125   return (m_tx_retr + m_tx_err) < m_tx_ok * m_stations->m_successRatio;
       
   126 }
       
   127 bool
       
   128 AmrrMacStation::IsFailure (void) const
       
   129 {
       
   130   return (m_tx_retr + m_tx_err) > m_tx_ok * m_stations->m_failureRatio;
       
   131 }
       
   132 bool
       
   133 AmrrMacStation::IsEnough (void) const
       
   134 {
       
   135   return (m_tx_retr + m_tx_err + m_tx_ok) > 10;
       
   136 }
       
   137 void 
       
   138 AmrrMacStation::ResetCnt (void)
       
   139 {
       
   140   m_tx_ok = 0;
       
   141   m_tx_err = 0;
       
   142   m_tx_retr = 0;
       
   143 }
       
   144 void 
       
   145 AmrrMacStation::IncreaseRate (void)
       
   146 {
       
   147   m_txrate++;
       
   148   NS_ASSERT (m_txrate < GetNSupportedModes ());
       
   149 }
       
   150 void 
       
   151 AmrrMacStation::DecreaseRate (void)
       
   152 {
       
   153   m_txrate--;
       
   154 }
       
   155 
       
   156 void
       
   157 AmrrMacStation::UpdateMode (void)
       
   158 {
       
   159   if (Simulator::Now () < m_nextModeUpdate)
       
   160     {
       
   161       return;
       
   162     }
       
   163   m_nextModeUpdate = Simulator::Now () + m_stations->m_updatePeriod;
       
   164   NS_LOG_DEBUG ("Update");
       
   165 
       
   166   bool needChange = false;
       
   167 
       
   168   if (IsSuccess () && IsEnough ()) 
       
   169     {
       
   170       m_success++;
       
   171       NS_LOG_DEBUG ("++ success="<<m_success<<" successThreshold="<<m_successThreshold<<
       
   172                     " tx_ok="<<m_tx_ok<<" tx_err="<<m_tx_err<<" tx_retr="<<m_tx_retr<<
       
   173                     " rate="<<m_txrate<<" n-supported-rates="<<GetNSupportedModes ());
       
   174       if (m_success >= m_successThreshold &&
       
   175           !IsMaxRate ()) 
       
   176         {
       
   177           m_recovery = true;
       
   178           m_success = 0;
       
   179           IncreaseRate ();
       
   180           needChange = true;
       
   181         } 
       
   182       else 
       
   183         {
       
   184           m_recovery = false;
       
   185         }
       
   186     } 
       
   187   else if (IsFailure ()) 
       
   188     {
       
   189       m_success = 0;
       
   190       NS_LOG_DEBUG ("-- success="<<m_success<<" successThreshold="<<m_successThreshold<<
       
   191                     " tx_ok="<<m_tx_ok<<" tx_err="<<m_tx_err<<" tx_retr="<<m_tx_retr<<
       
   192                     " rate="<<m_txrate<<" n-supported-rates="<<GetNSupportedModes ());
       
   193       if (!IsMinRate ()) 
       
   194         {
       
   195           if (m_recovery) 
       
   196             {
       
   197               m_successThreshold *= 2;
       
   198               m_successThreshold = std::min (m_successThreshold,
       
   199                                              m_stations->m_maxSuccessThreshold);
       
   200             } 
       
   201           else 
       
   202             {
       
   203               m_successThreshold = m_stations->m_minSuccessThreshold;
       
   204             }
       
   205           m_recovery = false;
       
   206           DecreaseRate ();
       
   207           needChange = true;
       
   208         } 
       
   209       else 
       
   210         {
       
   211           m_recovery = false;
       
   212         }
       
   213     }
       
   214   if (IsEnough () || needChange) 
       
   215     {
       
   216       NS_LOG_DEBUG ("Reset");
       
   217       ResetCnt ();
       
   218     }
       
   219 }
       
   220 
       
   221 AmrrMacStations *
       
   222 AmrrMacStation::GetStations (void) const
       
   223 {
       
   224   return m_stations;
       
   225 }
       
   226 WifiMode 
       
   227 AmrrMacStation::DoGetDataMode (uint32_t size)
       
   228 {
       
   229   UpdateMode ();
       
   230   NS_ASSERT (m_txrate < GetNSupportedModes ());
       
   231   uint32_t rateIndex;
       
   232   if (m_retry < 1)
       
   233     {
       
   234       rateIndex = m_txrate;
       
   235     }
       
   236   else if (m_retry < 2)
       
   237     {
       
   238       if (m_txrate > 0)
       
   239         {
       
   240           rateIndex = m_txrate - 1;
       
   241         }
       
   242       else
       
   243         {
       
   244           rateIndex = m_txrate;
       
   245         }
       
   246     }
       
   247   else if (m_retry < 3)
       
   248     {
       
   249       if (m_txrate > 1)
       
   250         {
       
   251           rateIndex = m_txrate - 2;
       
   252         }
       
   253       else
       
   254         {
       
   255           rateIndex = m_txrate;
       
   256         }
       
   257     }
       
   258   else
       
   259     {
       
   260       if (m_txrate > 2)
       
   261         {
       
   262           rateIndex = m_txrate - 3;
       
   263         }
       
   264       else
       
   265         {
       
   266           rateIndex = m_txrate;
       
   267         }
       
   268     }
       
   269 
       
   270   return GetSupportedMode (rateIndex);
       
   271 }
       
   272 WifiMode 
       
   273 AmrrMacStation::DoGetRtsMode (void)
       
   274 {
       
   275   UpdateMode ();
       
   276   // XXX: can we implement something smarter ?
       
   277   return GetSupportedMode (0);
       
   278 }
       
   279 
       
   280 } // namespace ns3