port last rate control algorithms

This commit is contained in:
Mathieu Lacage
2008-03-03 04:03:39 +01:00
parent 163c32fc28
commit 9b37416720
9 changed files with 1281 additions and 32 deletions

View File

@@ -0,0 +1,290 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2003,2007 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "amrr-wifi-manager.h"
#include "ns3/simulator.h"
#include "ns3/log.h"
#include "ns3/uinteger.h"
#include "ns3/double.h"
NS_LOG_COMPONENT_DEFINE ("AmrrWifiRemoteStation");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (AmrrWifiManager);
TypeId
AmrrWifiManager::GetTypeId (void)
{
static TypeId tid = TypeId ("AmrrWifiManager")
.SetParent<WifiRemoteStationManager> ()
.AddConstructor<AmrrWifiManager> ()
.AddAttribute ("UpdatePeriod",
"The interval between decisions about rate control changes",
Seconds (1.0),
MakeTimeAccessor (&AmrrWifiManager::m_updatePeriod),
MakeTimeChecker ())
.AddAttribute ("FailureRatio",
"Ratio of minimum erronous transmissions needed to switch to a lower rate",
Double (1.0/3.0),
MakeDoubleAccessor (&AmrrWifiManager::m_failureRatio),
MakeDoubleChecker (0.0, 1.0))
.AddAttribute ("SuccessRatio",
"Ratio of maximum erronous transmissions needed to switch to a higher rate",
Double (1.0/10.0),
MakeDoubleAccessor (&AmrrWifiManager::m_successRatio),
MakeDoubleChecker (0.0, 1.0))
.AddAttribute ("MaxSuccessThreshold",
"Maximum number of consecutive success periods needed to switch to a higher rate",
Uinteger (10),
MakeUintegerAccessor (&AmrrWifiManager::m_maxSuccessThreshold),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("MinSuccessThreshold",
"Minimum number of consecutive success periods needed to switch to a higher rate",
Uinteger (1),
MakeUintegerAccessor (&AmrrWifiManager::m_minSuccessThreshold),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
AmrrWifiManager::AmrrWifiManager ()
{}
WifiRemoteStation *
AmrrWifiManager::CreateStation (void)
{
return new AmrrWifiRemoteStation (this);
}
AmrrWifiRemoteStation::AmrrWifiRemoteStation (Ptr<AmrrWifiManager> stations)
: m_stations (stations),
m_nextModeUpdate (Simulator::Now () + stations->m_updatePeriod),
m_tx_ok (0),
m_tx_err (0),
m_tx_retr (0),
m_retry (0),
m_txrate (0),
m_successThreshold (m_stations->m_minSuccessThreshold),
m_success (0),
m_recovery (false)
{}
AmrrWifiRemoteStation::~AmrrWifiRemoteStation ()
{}
void
AmrrWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
{}
void
AmrrWifiRemoteStation::ReportRtsFailed (void)
{}
void
AmrrWifiRemoteStation::ReportDataFailed (void)
{
m_retry++;
m_tx_retr++;
}
void
AmrrWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{}
void
AmrrWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
m_retry = 0;
m_tx_ok++;
}
void
AmrrWifiRemoteStation::ReportFinalRtsFailed (void)
{}
void
AmrrWifiRemoteStation::ReportFinalDataFailed (void)
{
m_retry = 0;
m_tx_err++;
}
bool
AmrrWifiRemoteStation::IsMinRate (void) const
{
return (m_txrate == 0);
}
bool
AmrrWifiRemoteStation::IsMaxRate (void) const
{
NS_ASSERT (m_txrate + 1 <= GetNSupportedModes ());
return (m_txrate + 1 == GetNSupportedModes ());
}
bool
AmrrWifiRemoteStation::IsSuccess (void) const
{
return (m_tx_retr + m_tx_err) < m_tx_ok * m_stations->m_successRatio;
}
bool
AmrrWifiRemoteStation::IsFailure (void) const
{
return (m_tx_retr + m_tx_err) > m_tx_ok * m_stations->m_failureRatio;
}
bool
AmrrWifiRemoteStation::IsEnough (void) const
{
return (m_tx_retr + m_tx_err + m_tx_ok) > 10;
}
void
AmrrWifiRemoteStation::ResetCnt (void)
{
m_tx_ok = 0;
m_tx_err = 0;
m_tx_retr = 0;
}
void
AmrrWifiRemoteStation::IncreaseRate (void)
{
m_txrate++;
NS_ASSERT (m_txrate < GetNSupportedModes ());
}
void
AmrrWifiRemoteStation::DecreaseRate (void)
{
m_txrate--;
}
void
AmrrWifiRemoteStation::UpdateMode (void)
{
if (Simulator::Now () < m_nextModeUpdate)
{
return;
}
m_nextModeUpdate = Simulator::Now () + m_stations->m_updatePeriod;
NS_LOG_DEBUG ("Update");
bool needChange = false;
if (IsSuccess () && IsEnough ())
{
m_success++;
NS_LOG_DEBUG ("++ success="<<m_success<<" successThreshold="<<m_successThreshold<<
" tx_ok="<<m_tx_ok<<" tx_err="<<m_tx_err<<" tx_retr="<<m_tx_retr<<
" rate="<<m_txrate<<" n-supported-rates="<<GetNSupportedModes ());
if (m_success >= m_successThreshold &&
!IsMaxRate ())
{
m_recovery = true;
m_success = 0;
IncreaseRate ();
needChange = true;
}
else
{
m_recovery = false;
}
}
else if (IsFailure ())
{
m_success = 0;
NS_LOG_DEBUG ("-- success="<<m_success<<" successThreshold="<<m_successThreshold<<
" tx_ok="<<m_tx_ok<<" tx_err="<<m_tx_err<<" tx_retr="<<m_tx_retr<<
" rate="<<m_txrate<<" n-supported-rates="<<GetNSupportedModes ());
if (!IsMinRate ())
{
if (m_recovery)
{
m_successThreshold *= 2;
m_successThreshold = std::min (m_successThreshold,
m_stations->m_maxSuccessThreshold);
}
else
{
m_successThreshold = m_stations->m_minSuccessThreshold;
}
m_recovery = false;
DecreaseRate ();
needChange = true;
}
else
{
m_recovery = false;
}
}
if (IsEnough () || needChange)
{
NS_LOG_DEBUG ("Reset");
ResetCnt ();
}
}
Ptr<WifiRemoteStationManager>
AmrrWifiRemoteStation::GetManager (void) const
{
return m_stations;
}
WifiMode
AmrrWifiRemoteStation::DoGetDataMode (uint32_t size)
{
UpdateMode ();
NS_ASSERT (m_txrate < GetNSupportedModes ());
uint32_t rateIndex;
if (m_retry < 1)
{
rateIndex = m_txrate;
}
else if (m_retry < 2)
{
if (m_txrate > 0)
{
rateIndex = m_txrate - 1;
}
else
{
rateIndex = m_txrate;
}
}
else if (m_retry < 3)
{
if (m_txrate > 1)
{
rateIndex = m_txrate - 2;
}
else
{
rateIndex = m_txrate;
}
}
else
{
if (m_txrate > 2)
{
rateIndex = m_txrate - 3;
}
else
{
rateIndex = m_txrate;
}
}
return GetSupportedMode (rateIndex);
}
WifiMode
AmrrWifiRemoteStation::DoGetRtsMode (void)
{
UpdateMode ();
// XXX: can we implement something smarter ?
return GetSupportedMode (0);
}
} // namespace ns3

View File

@@ -0,0 +1,93 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2003,2007 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef AMRR_WIFI_MANAGER_H
#define AMRR_WIFI_MANAGER_H
#include "wifi-remote-station-manager.h"
#include "ns3/nstime.h"
namespace ns3 {
class AmrrWifiManager : public WifiRemoteStationManager
{
public:
static TypeId GetTypeId (void);
AmrrWifiManager ();
private:
friend class AmrrWifiRemoteStation;
virtual WifiRemoteStation *CreateStation (void);
Time m_updatePeriod;
double m_failureRatio;
double m_successRatio;
uint32_t m_maxSuccessThreshold;
uint32_t m_minSuccessThreshold;
};
/**
*/
class AmrrWifiRemoteStation : public WifiRemoteStation
{
public:
AmrrWifiRemoteStation (Ptr<AmrrWifiManager> stations);
virtual ~AmrrWifiRemoteStation ();
virtual void ReportRxOk (double rxSnr, WifiMode txMode);
virtual void ReportRtsFailed (void);
virtual void ReportDataFailed (void);
virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void ReportFinalRtsFailed (void);
virtual void ReportFinalDataFailed (void);
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
void UpdateRetry (void);
void UpdateMode (void);
void ResetCnt (void);
void IncreaseRate (void);
void DecreaseRate (void);
bool IsMinRate (void) const;
bool IsMaxRate (void) const;
bool IsSuccess (void) const;
bool IsFailure (void) const;
bool IsEnough (void) const;
Ptr<AmrrWifiManager> m_stations;
Time m_nextModeUpdate;
uint32_t m_tx_ok;
uint32_t m_tx_err;
uint32_t m_tx_retr;
uint32_t m_retry;
uint32_t m_txrate;
uint32_t m_successThreshold;
uint32_t m_success;
bool m_recovery;
};
} // namespace ns3
#endif /* AMRR_WIFI_MANAGER_H */

View File

@@ -18,13 +18,11 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "onoe-mac-stations.h"
#include "ns3/default-value.h"
#include "ns3/time-default-value.h"
#include "onoe-wifi-manager.h"
#include "ns3/simulator.h"
#include "ns3/log.h"
NS_LOG_COMPONENT_DEFINE ("OnoeMacStation");
NS_LOG_COMPONENT_DEFINE ("OnoeWifiRemoteStation");
namespace ns3 {
@@ -41,19 +39,19 @@ static NumericDefaultValue<uint32_t> g_raiseThreshold
"Raise threshold",
10);
OnoeMacStations::OnoeMacStations (WifiMode defaultTxMode)
OnoeWifiManager::OnoeWifiManager (WifiMode defaultTxMode)
: MacStations (defaultTxMode),
m_updatePeriod (g_updatePeriod.GetValue ()),
m_addCreditThreshold (g_addCreditThreshold.GetValue ()),
m_raiseThreshold (g_raiseThreshold.GetValue ())
{}
MacStation *
OnoeMacStations::CreateStation (void)
OnoeWifiManager::CreateStation (void)
{
return new OnoeMacStation (this);
return new OnoeWifiRemoteStation (this);
}
OnoeMacStation::OnoeMacStation (OnoeMacStations *stations)
OnoeWifiRemoteStation::OnoeWifiRemoteStation (OnoeWifiManager *stations)
: m_stations (stations),
m_nextModeUpdate (Simulator::Now () + stations->m_updatePeriod),
m_shortRetry (0),
@@ -64,52 +62,52 @@ OnoeMacStation::OnoeMacStation (OnoeMacStations *stations)
m_tx_upper (0),
m_txrate (0)
{}
OnoeMacStation::~OnoeMacStation ()
OnoeWifiRemoteStation::~OnoeWifiRemoteStation ()
{}
void
OnoeMacStation::ReportRxOk (double rxSnr, WifiMode txMode)
OnoeWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
{}
void
OnoeMacStation::ReportRtsFailed (void)
OnoeWifiRemoteStation::ReportRtsFailed (void)
{
m_shortRetry++;
}
void
OnoeMacStation::ReportDataFailed (void)
OnoeWifiRemoteStation::ReportDataFailed (void)
{
m_longRetry++;
}
void
OnoeMacStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
OnoeWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{}
void
OnoeMacStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
OnoeWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
UpdateRetry ();
m_tx_ok++;
}
void
OnoeMacStation::ReportFinalRtsFailed (void)
OnoeWifiRemoteStation::ReportFinalRtsFailed (void)
{
UpdateRetry ();
m_tx_err++;
}
void
OnoeMacStation::ReportFinalDataFailed (void)
OnoeWifiRemoteStation::ReportFinalDataFailed (void)
{
UpdateRetry ();
m_tx_err++;
}
void
OnoeMacStation::UpdateRetry (void)
OnoeWifiRemoteStation::UpdateRetry (void)
{
m_tx_retr += m_shortRetry + m_longRetry;
m_shortRetry = 0;
m_longRetry = 0;
}
void
OnoeMacStation::UpdateMode (void)
OnoeWifiRemoteStation::UpdateMode (void)
{
if (Simulator::Now () < m_nextModeUpdate)
{
@@ -173,13 +171,13 @@ OnoeMacStation::UpdateMode (void)
}
OnoeMacStations *
OnoeMacStation::GetStations (void) const
OnoeWifiManager *
OnoeWifiRemoteStation::GetStations (void) const
{
return m_stations;
}
WifiMode
OnoeMacStation::DoGetDataMode (uint32_t size)
OnoeWifiRemoteStation::DoGetDataMode (uint32_t size)
{
UpdateMode ();
NS_ASSERT (m_txrate < GetNSupportedModes ());
@@ -224,7 +222,7 @@ OnoeMacStation::DoGetDataMode (uint32_t size)
return GetSupportedMode (rateIndex);
}
WifiMode
OnoeMacStation::DoGetRtsMode (void)
OnoeWifiRemoteStation::DoGetRtsMode (void)
{
UpdateMode ();
// XXX: can we implement something smarter ?

View File

@@ -20,19 +20,19 @@
#ifndef ONOE_MAC_STATIONS_H
#define ONOE_MAC_STATIONS_H
#include "mac-stations.h"
#include "wifi-remote-station-manager.h"
#include "ns3/nstime.h"
namespace ns3 {
class OnoeMacStations : public MacStations
class OnoeWifiManager : public WifiRemoteStationManager
{
public:
OnoeMacStations (WifiMode defaultTxMode);
OnoeWifiManager ();
private:
friend class OnoeMacStation;
virtual MacStation *CreateStation (void);
friend class OnoeWifiRemoteStation;
virtual WifiRemoteStation *CreateStation (void);
Time m_updatePeriod;
uint32_t m_addCreditThreshold;
@@ -48,12 +48,12 @@ private:
* any publication or reference about this algorithm beyond the madwifi
* source code.
*/
class OnoeMacStation : public MacStation
class OnoeWifiRemoteStation : public WifiRemoteStation
{
public:
OnoeMacStation (OnoeMacStations *stations);
OnoeWifiRemoteStation (OnoeWifiManager *stations);
virtual ~OnoeMacStation ();
virtual ~OnoeWifiRemoteStation ();
virtual void ReportRxOk (double rxSnr, WifiMode txMode);
virtual void ReportRtsFailed (void);
@@ -64,14 +64,14 @@ public:
virtual void ReportFinalDataFailed (void);
private:
virtual OnoeMacStations *GetStations (void) const;
virtual OnoeWifiManager *GetStations (void) const;
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
void UpdateRetry (void);
void UpdateMode (void);
OnoeMacStations *m_stations;
OnoeWifiManager *m_stations;
Time m_nextModeUpdate;
uint32_t m_shortRetry;
uint32_t m_longRetry;

View File

@@ -0,0 +1,239 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2003,2007 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "onoe-wifi-manager.h"
#include "ns3/simulator.h"
#include "ns3/log.h"
#include "ns3/uinteger.h"
NS_LOG_COMPONENT_DEFINE ("OnoeWifiRemoteStation");
namespace ns3 {
TypeId
OnoeWifiManager::GetTypeId (void)
{
static TypeId tid = TypeId ("OnoeWifiManager")
.SetParent<WifiRemoteStationManager> ()
.AddConstructor<OnoeWifiManager> ()
.AddAttribute ("UpdatePeriod",
"The interval between decisions about rate control changes",
Seconds (1.0),
MakeTimeAccessor (&OnoeWifiManager::m_updatePeriod),
MakeTimeChecker ())
.AddAttribute ("RaiseThreshold", "XXX",
Uinteger (10),
MakeUintegerAccessor (&OnoeWifiManager::m_raiseThreshold),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("AddCreditThreshold", "Add credit threshold",
Uinteger (10),
MakeUintegerAccessor (&OnoeWifiManager::m_addCreditThreshold),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
OnoeWifiManager::OnoeWifiManager ()
{}
WifiRemoteStation *
OnoeWifiManager::CreateStation (void)
{
return new OnoeWifiRemoteStation (this);
}
OnoeWifiRemoteStation::OnoeWifiRemoteStation (Ptr<OnoeWifiManager> stations)
: m_stations (stations),
m_nextModeUpdate (Simulator::Now () + stations->m_updatePeriod),
m_shortRetry (0),
m_longRetry (0),
m_tx_ok (0),
m_tx_err (0),
m_tx_retr (0),
m_tx_upper (0),
m_txrate (0)
{}
OnoeWifiRemoteStation::~OnoeWifiRemoteStation ()
{}
void
OnoeWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
{}
void
OnoeWifiRemoteStation::ReportRtsFailed (void)
{
m_shortRetry++;
}
void
OnoeWifiRemoteStation::ReportDataFailed (void)
{
m_longRetry++;
}
void
OnoeWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{}
void
OnoeWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
UpdateRetry ();
m_tx_ok++;
}
void
OnoeWifiRemoteStation::ReportFinalRtsFailed (void)
{
UpdateRetry ();
m_tx_err++;
}
void
OnoeWifiRemoteStation::ReportFinalDataFailed (void)
{
UpdateRetry ();
m_tx_err++;
}
void
OnoeWifiRemoteStation::UpdateRetry (void)
{
m_tx_retr += m_shortRetry + m_longRetry;
m_shortRetry = 0;
m_longRetry = 0;
}
void
OnoeWifiRemoteStation::UpdateMode (void)
{
if (Simulator::Now () < m_nextModeUpdate)
{
return;
}
m_nextModeUpdate = Simulator::Now () + m_stations->m_updatePeriod;
/**
* The following 20 lines of code were copied from the Onoe
* rate control kernel module used in the madwifi driver.
*/
int dir = 0, enough;
uint32_t nrate;
enough = (m_tx_ok + m_tx_err >= 10);
/* no packet reached -> down */
if (m_tx_err > 0 && m_tx_ok == 0)
dir = -1;
/* all packets needs retry in average -> down */
if (enough && m_tx_ok < m_tx_retr)
dir = -1;
/* no error and less than rate_raise% of packets need retry -> up */
if (enough && m_tx_err == 0 &&
m_tx_retr < (m_tx_ok * m_stations->m_addCreditThreshold) / 100)
dir = 1;
NS_LOG_DEBUG (this << " ok " << m_tx_ok << " err " << m_tx_err << " retr " << m_tx_retr <<
" upper " << m_tx_upper << " dir " << dir);
nrate = m_txrate;
switch (dir) {
case 0:
if (enough && m_tx_upper > 0)
m_tx_upper--;
break;
case -1:
if (nrate > 0) {
nrate--;
}
m_tx_upper = 0;
break;
case 1:
/* raise rate if we hit rate_raise_threshold */
if (++m_tx_upper < m_stations->m_raiseThreshold)
break;
m_tx_upper = 0;
if (nrate + 1 < GetNSupportedModes ()) {
nrate++;
}
break;
}
if (nrate != m_txrate) {
NS_ASSERT (nrate < GetNSupportedModes ());
m_txrate = nrate;
m_tx_ok = m_tx_err = m_tx_retr = m_tx_upper = 0;
} else if (enough)
m_tx_ok = m_tx_err = m_tx_retr = 0;
}
Ptr<WifiRemoteStationManager>
OnoeWifiRemoteStation::GetManager (void) const
{
return m_stations;
}
WifiMode
OnoeWifiRemoteStation::DoGetDataMode (uint32_t size)
{
UpdateMode ();
NS_ASSERT (m_txrate < GetNSupportedModes ());
uint32_t rateIndex;
if (m_longRetry < 4)
{
rateIndex = m_txrate;
}
else if (m_longRetry < 6)
{
if (m_txrate > 0)
{
rateIndex = m_txrate - 1;
}
else
{
rateIndex = m_txrate;
}
}
else if (m_longRetry < 8)
{
if (m_txrate > 1)
{
rateIndex = m_txrate - 2;
}
else
{
rateIndex = m_txrate;
}
}
else
{
if (m_txrate > 2)
{
rateIndex = m_txrate - 3;
}
else
{
rateIndex = m_txrate;
}
}
return GetSupportedMode (rateIndex);
}
WifiMode
OnoeWifiRemoteStation::DoGetRtsMode (void)
{
UpdateMode ();
// XXX: can we implement something smarter ?
return GetSupportedMode (0);
}
} // namespace ns3

View File

@@ -0,0 +1,89 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2003,2007 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef ONOE_WIFI_MANAGER_H
#define ONOE_WIFI_MANAGER_H
#include "wifi-remote-station-manager.h"
#include "ns3/nstime.h"
namespace ns3 {
class OnoeWifiManager : public WifiRemoteStationManager
{
public:
static TypeId GetTypeId (void);
OnoeWifiManager ();
private:
friend class OnoeWifiRemoteStation;
virtual WifiRemoteStation *CreateStation (void);
Time m_updatePeriod;
uint32_t m_addCreditThreshold;
uint32_t m_raiseThreshold;
};
/**
* \brief an implementation of rate control algorithm developed
* by Atsushi Onoe
*
* This algorithm is well known because it has been used as the default
* rate control algorithm for the madwifi driver. I am not aware of
* any publication or reference about this algorithm beyond the madwifi
* source code.
*/
class OnoeWifiRemoteStation : public WifiRemoteStation
{
public:
OnoeWifiRemoteStation (Ptr<OnoeWifiManager> stations);
virtual ~OnoeWifiRemoteStation ();
virtual void ReportRxOk (double rxSnr, WifiMode txMode);
virtual void ReportRtsFailed (void);
virtual void ReportDataFailed (void);
virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void ReportFinalRtsFailed (void);
virtual void ReportFinalDataFailed (void);
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
void UpdateRetry (void);
void UpdateMode (void);
Ptr<OnoeWifiManager> m_stations;
Time m_nextModeUpdate;
uint32_t m_shortRetry;
uint32_t m_longRetry;
uint32_t m_tx_ok;
uint32_t m_tx_err;
uint32_t m_tx_retr;
uint32_t m_tx_upper;
uint32_t m_txrate;
};
} // namespace ns3
#endif /* ONOE_WIFI_MANAGER_H */

View File

@@ -0,0 +1,407 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2004,2005,2006 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Federico Maguolo <maguolof@dei.unipd.it>
*/
#include "rraa-wifi-manager.h"
#include "ns3/assert.h"
#include "ns3/log.h"
#include "ns3/boolean.h"
#include "ns3/double.h"
#include "ns3/uinteger.h"
#include "ns3/simulator.h"
NS_LOG_COMPONENT_DEFINE ("RraaWifiManager");
namespace ns3 {
RraaWifiRemoteStation::RraaWifiRemoteStation (Ptr<RraaWifiManager> stations)
: m_stations (stations)
{
m_initialized = false;
m_rtsWnd = 0;
m_rtsCounter = 0;
m_rtsOn = false;
m_lastFrameFail = false;
}
RraaWifiRemoteStation::~RraaWifiRemoteStation ()
{}
void
RraaWifiRemoteStation::ResetCountersBasic (void)
{
if (!m_initialized) {
m_rate = GetMaxRate ();
m_initialized = true;
}
m_failed = 0;
m_counter = GetThresholds (m_rate).ewnd;
m_lastReset = Simulator::Now ();
}
Ptr<WifiRemoteStationManager>
RraaWifiRemoteStation::GetManager (void) const
{
return m_stations;
}
uint32_t
RraaWifiRemoteStation::GetMaxRate (void)
{
return GetNSupportedModes () - 1;
}
uint32_t
RraaWifiRemoteStation::GetMinRate (void)
{
return 0;
}
ThresholdsItem
RraaWifiRemoteStation::GetThresholds (uint32_t rate)
{
WifiMode mode = GetSupportedMode (rate);
return m_stations->GetThresholds (mode);
}
void
RraaWifiRemoteStation::ReportRtsFailed (void)
{}
void
RraaWifiRemoteStation::ReportDataFailed (void)
{
m_lastFrameFail = true;
CheckTimeout ();
m_counter--;
m_failed++;
RunBasicAlgorithm ();
}
void
RraaWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
{}
void
RraaWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("self="<<this<<" rts ok");
}
void
RraaWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
m_lastFrameFail = false;
CheckTimeout ();
m_counter--;
RunBasicAlgorithm ();
}
void
RraaWifiRemoteStation::ReportFinalRtsFailed (void)
{}
void
RraaWifiRemoteStation::ReportFinalDataFailed (void)
{}
WifiMode
RraaWifiRemoteStation::DoGetDataMode (uint32_t size)
{
if (!m_initialized)
ResetCountersBasic ();
return GetSupportedMode (m_rate);
}
WifiMode
RraaWifiRemoteStation::DoGetRtsMode (void)
{
return GetSupportedMode (0);
}
bool
RraaWifiRemoteStation::NeedRts (Ptr<const Packet> packet)
{
if (m_stations->OnlyBasic ())
return WifiRemoteStation::NeedRts (packet);
ARts ();
return m_rtsOn;
}
void
RraaWifiRemoteStation::CheckTimeout (void)
{
Time d = Simulator::Now () - m_lastReset;
if (m_counter == 0 || d > m_stations->GetTimeout ()) {
ResetCountersBasic ();
}
}
void
RraaWifiRemoteStation::RunBasicAlgorithm (void)
{
ThresholdsItem thresholds = GetThresholds (m_rate);
double ploss = (double) m_failed / (double) thresholds.ewnd;
if (m_counter == 0 || ploss > thresholds.pmtl) {
if (m_rate > GetMinRate () && ploss > thresholds.pmtl) {
m_rate--;
}
else if (m_rate < GetMaxRate () && ploss < thresholds.pori) {
m_rate++;
}
ResetCountersBasic ();
}
}
void
RraaWifiRemoteStation::ARts (void)
{
if (!m_rtsOn && m_lastFrameFail) {
m_rtsWnd++;
m_rtsCounter = m_rtsWnd;
}
else if ((m_rtsOn && m_lastFrameFail) ||
(!m_rtsOn && !m_lastFrameFail)) {
m_rtsWnd = m_rtsWnd / 2;
m_rtsCounter = m_rtsWnd;
}
if (m_rtsCounter > 0) {
m_rtsOn = true;
m_rtsCounter--;
}
else {
m_rtsOn = false;
}
}
TypeId
RraaWifiManager::GetTypeId (void)
{
static TypeId tid = TypeId ("RraaWifiManager")
.SetParent<WifiRemoteStationManager> ()
.AddConstructor<RraaWifiManager> ()
.AddAttribute ("Basic",
"If true the RRAA-BASIC algorithm will be used, otherwise the RRAA wil be used",
Boolean (false),
MakeBooleanAccessor (&RraaWifiManager::m_basic),
MakeBooleanChecker ())
.AddAttribute ("Timeout",
"Timeout for the RRAA BASIC loss estimaton block (s)",
Seconds (0.05),
MakeTimeAccessor (&RraaWifiManager::m_timeout),
MakeTimeChecker ())
.AddAttribute ("ewndFor54mbps",
"ewnd parameter for 54 Mbs data mode",
Uinteger (40),
MakeUintegerAccessor (&RraaWifiManager::m_ewndfor54),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ewndFor48mbps",
"ewnd parameter for 48 Mbs data mode",
Uinteger (40),
MakeUintegerAccessor (&RraaWifiManager::m_ewndfor48),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ewndFor36mbps",
"ewnd parameter for 36 Mbs data mode",
Uinteger (40),
MakeUintegerAccessor (&RraaWifiManager::m_ewndfor36),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ewndFor24mbps",
"ewnd parameter for 24 Mbs data mode",
Uinteger (40),
MakeUintegerAccessor (&RraaWifiManager::m_ewndfor24),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ewndFor18mbps",
"ewnd parameter for 18 Mbs data mode",
Uinteger (20),
MakeUintegerAccessor (&RraaWifiManager::m_ewndfor18),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ewndFor12mbps",
"ewnd parameter for 12 Mbs data mode",
Uinteger (20),
MakeUintegerAccessor (&RraaWifiManager::m_ewndfor12),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ewndFor9mbps",
"ewnd parameter for 9 Mbs data mode",
Uinteger (10),
MakeUintegerAccessor (&RraaWifiManager::m_ewndfor9),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ewndFor6mbps",
"ewnd parameter for 6 Mbs data mode",
Uinteger (6),
MakeUintegerAccessor (&RraaWifiManager::m_ewndfor6),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("poriFor48mbps",
"Pori parameter for 48 Mbs data mode",
Double (0.047),
MakeDoubleAccessor (&RraaWifiManager::m_porifor48),
MakeDoubleChecker<double> ())
.AddAttribute ("poriFor36mbps",
"Pori parameter for 36 Mbs data mode",
Double (0.115),
MakeDoubleAccessor (&RraaWifiManager::m_porifor36),
MakeDoubleChecker<double> ())
.AddAttribute ("poriFor24mbps",
"Pori parameter for 24 Mbs data mode",
Double (0.1681),
MakeDoubleAccessor (&RraaWifiManager::m_porifor24),
MakeDoubleChecker<double> ())
.AddAttribute ("poriFor18mbps",
"Pori parameter for 18 Mbs data mode",
Double (0.1325),
MakeDoubleAccessor (&RraaWifiManager::m_porifor18),
MakeDoubleChecker<double> ())
.AddAttribute ("poriFor12mbps",
"Pori parameter for 12 Mbs data mode",
Double (0.1861),
MakeDoubleAccessor (&RraaWifiManager::m_porifor12),
MakeDoubleChecker<double> ())
.AddAttribute ("poriFor9mbps",
"Pori parameter for 9 Mbs data mode",
Double (0.1434),
MakeDoubleAccessor (&RraaWifiManager::m_porifor9),
MakeDoubleChecker<double> ())
.AddAttribute ("poriFor6mbps",
"Pori parameter for 6 Mbs data mode",
Double (0.5),
MakeDoubleAccessor (&RraaWifiManager::m_porifor6),
MakeDoubleChecker<double> ())
.AddAttribute ("pmtlFor54mbps",
"Pmtl parameter for 54 Mbs data mode",
Double (0.094),
MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor54),
MakeDoubleChecker<double> ())
.AddAttribute ("pmtlFor48mbps",
"Pmtl parameter for 48 Mbs data mode",
Double (0.23),
MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor48),
MakeDoubleChecker<double> ())
.AddAttribute ("pmtlFor36mbps",
"Pmtl parameter for 36 Mbs data mode",
Double (0.3363),
MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor36),
MakeDoubleChecker<double> ())
.AddAttribute ("pmtlFor24mbps",
"Pmtl parameter for 24 Mbs data mode",
Double (0.265),
MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor24),
MakeDoubleChecker<double> ())
.AddAttribute ("pmtlFor18mbps",
"Pmtl parameter for 18 Mbs data mode",
Double (0.3722),
MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor18),
MakeDoubleChecker<double> ())
.AddAttribute ("pmtlFor12mbps",
"Pmtl parameter for 12 Mbs data mode",
Double(0.2868),
MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor12),
MakeDoubleChecker<double> ())
.AddAttribute ("pmtlFor9mbps",
"Pmtl parameter for 9 Mbs data mode",
Double (0.3932),
MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor9),
MakeDoubleChecker<double> ())
;
return tid;
}
RraaWifiManager::RraaWifiManager ()
{}
RraaWifiManager::~RraaWifiManager ()
{}
WifiRemoteStation *
RraaWifiManager::CreateStation (void)
{
return new RraaWifiRemoteStation (this);
}
bool
RraaWifiManager::OnlyBasic (void)
{
return m_basic;
}
Time
RraaWifiManager::GetTimeout (void) const
{
return m_timeout;
}
ThresholdsItem
RraaWifiManager::GetThresholds (WifiMode mode) const
{
switch (mode.GetDataRate () / 1000000) {
case 54: {
ThresholdsItem mode54 = {54000000,
0.0,
m_pmtlfor54,
m_ewndfor54};
return mode54;
} break;
case 48: {
ThresholdsItem mode48 = {48000000,
m_porifor48,
m_pmtlfor48,
m_ewndfor48};
return mode48;
} break;
case 36: {
ThresholdsItem mode36 = {36000000,
m_porifor36,
m_pmtlfor36,
m_ewndfor36};
return mode36;
} break;
case 24: {
ThresholdsItem mode24 = {24000000,
m_porifor24,
m_pmtlfor24,
m_ewndfor24};
return mode24;
} break;
case 18: {
ThresholdsItem mode18 = {18000000,
m_porifor18,
m_pmtlfor18,
m_ewndfor18};
return mode18;
} break;
case 12: {
ThresholdsItem mode12 = {12000000,
m_porifor12,
m_pmtlfor12,
m_ewndfor12};
return mode12;
} break;
case 9: {
ThresholdsItem mode9 = {9000000,
m_porifor9,
m_pmtlfor9,
m_ewndfor9};
return mode9;
} break;
case 6: {
ThresholdsItem mode6 = {6000000,
m_porifor6,
1.0,
m_ewndfor6};
return mode6;
} break;
}
NS_ASSERT("Thresholds for an unknown mode are asked");
return ThresholdsItem ();
}
} // namespace ns3

View File

@@ -0,0 +1,127 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Federico Maguolo <maguolof@dei.unipd.it>
*/
#ifndef RRAA_WIFI_MANAGER_H
#define RRAA_WIFI_MANAGER_H
#include "ns3/nstime.h"
#include "wifi-remote-station-manager.h"
namespace ns3 {
struct ThresholdsItem {
uint32_t datarate;
double pori;
double pmtl;
uint32_t ewnd;
};
typedef std::vector<ThresholdsItem> Thresholds;
/**
* \brief Robust Rate Adaptation Algorithm
*
* This is an implementation of RRAA as described in
* "Robust rate adaptation for 802.11 wireless networks"
* by "Starsky H. Y. Wong", "Hao Yang", "Songwu Lu", and,
* "Vaduvur Bharghavan" published in Mobicom 06.
*/
class RraaWifiManager : public WifiRemoteStationManager
{
public:
static TypeId GetTypeId (void);
RraaWifiManager ();
virtual ~RraaWifiManager ();
bool OnlyBasic (void);
Time GetTimeout (void) const;
ThresholdsItem GetThresholds (WifiMode mode) const;
private:
virtual class WifiRemoteStation *CreateStation (void);
bool m_basic;
Time m_timeout;
uint32_t m_ewndfor54;
uint32_t m_ewndfor48;
uint32_t m_ewndfor36;
uint32_t m_ewndfor24;
uint32_t m_ewndfor18;
uint32_t m_ewndfor12;
uint32_t m_ewndfor9;
uint32_t m_ewndfor6;
double m_porifor48;
double m_porifor36;
double m_porifor24;
double m_porifor18;
double m_porifor12;
double m_porifor9;
double m_porifor6;
double m_pmtlfor54;
double m_pmtlfor48;
double m_pmtlfor36;
double m_pmtlfor24;
double m_pmtlfor18;
double m_pmtlfor12;
double m_pmtlfor9;
};
class RraaWifiRemoteStation : public WifiRemoteStation
{
public:
RraaWifiRemoteStation (Ptr<RraaWifiManager> stations);
virtual ~RraaWifiRemoteStation ();
virtual void ReportRxOk (double rxSnr, WifiMode txMode);
virtual void ReportRtsFailed (void);
virtual void ReportDataFailed (void);
virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void ReportFinalRtsFailed (void);
virtual void ReportFinalDataFailed (void);
virtual bool NeedRts (Ptr<const Packet> packet);
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
uint32_t GetMaxRate (void);
uint32_t GetMinRate (void);
ThresholdsItem GetThresholds (uint32_t rate);
void CheckTimeout (void);
void RunBasicAlgorithm (void);
void ARts (void);
void ResetCountersBasic (void);
uint32_t m_counter;
uint32_t m_failed;
uint32_t m_rtsWnd;
uint32_t m_rtsCounter;
Time m_lastReset;
bool m_rtsOn;
bool m_lastFrameFail;
bool m_initialized;
uint32_t m_rate;
Ptr<RraaWifiManager> m_stations;
};
} // namespace ns3
#endif /* RRAA_WIFI_MANAGER_H */

View File

@@ -32,6 +32,9 @@ def build(bld):
'arf-wifi-manager.cc',
'aarf-wifi-manager.cc',
'ideal-wifi-manager.cc',
'amrr-wifi-manager.cc',
'onoe-wifi-manager.cc',
'rraa-wifi-manager.cc',
'constant-rate-wifi-manager.cc',
'wifi-helper.cc',
]
@@ -51,6 +54,9 @@ def build(bld):
'aarf-wifi-manager.h',
'constant-rate-wifi-manager.h',
'ideal-wifi-manager.h',
'amrr-wifi-manager.h',
'onoe-wifi-manager.h',
'rraa-wifi-manager.h',
'wifi-mac.h',
'adhoc-wifi-mac.h',
'nqsta-wifi-mac.h',