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