This commit is contained in:
Mathieu Lacage
2010-01-06 16:26:07 +01:00
parent 8e113fb006
commit 6dfc2e2c32
39 changed files with 2644 additions and 2827 deletions

View File

@@ -22,6 +22,7 @@
#include "ns3/mesh-wifi-interface-mac.h"
#include "ns3/mesh-wifi-beacon.h"
#include "ns3/log.h"
#include "ns3/boolean.h"
#include "ns3/wifi-phy.h"
#include "ns3/dcf-manager.h"
#include "ns3/mac-rx-middle.h"
@@ -384,16 +385,15 @@ MeshWifiInterfaceMac::ForwardDown (Ptr<const Packet> const_packet, Mac48Address
// Assert that address1 is set. Assert will fail e.g. if there is no installed routing plugin.
NS_ASSERT (hdr.GetAddr1 () != Mac48Address ());
// Queue frame
WifiRemoteStation *destination = m_stationManager->Lookup (to);
if (destination->IsBrandNew ())
if (m_stationManager->IsBrandNew (to))
{
// in adhoc mode, we assume that every destination
// supports all the rates we support.
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
destination->AddSupportedMode (m_phy->GetMode (i));
m_stationManager->AddSupportedMode (to, m_phy->GetMode (i));
}
destination->RecordDisassociated ();
m_stationManager->RecordDisassociated (to);
}
//Classify: application sets a tag, which is removed here
// Get Qos tag:
@@ -592,14 +592,13 @@ MeshWifiInterfaceMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
if (beacon_hdr.GetSsid ().IsEqual (GetSsid ()))
{
SupportedRates rates = beacon_hdr.GetSupportedRates ();
WifiRemoteStation * peerSta = m_stationManager->Lookup (hdr->GetAddr2 ());
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
WifiMode mode = m_phy->GetMode (i);
if (rates.IsSupportedRate (mode.GetDataRate ()))
{
peerSta->AddSupportedMode (mode);
m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
if (rates.IsBasicRate (mode.GetDataRate ()))
{
m_stationManager->AddBasicMode (mode);

View File

@@ -22,19 +22,37 @@
#include "ns3/double.h"
#include "ns3/uinteger.h"
#include "ns3/log.h"
#define Min(a,b) ((a<b)?a:b)
#define Max(a,b) ((a>b)?a:b)
NS_LOG_COMPONENT_DEFINE ("ns3::AarfWifiManager");
namespace ns3 {
struct AarfWifiRemoteStation : public WifiRemoteStation
{
uint32_t m_timer;
uint32_t m_success;
uint32_t m_failed;
bool m_recovery;
uint32_t m_retry;
uint32_t m_timerTimeout;
uint32_t m_successThreshold;
uint32_t m_rate;
};
NS_OBJECT_ENSURE_REGISTERED (AarfWifiManager);
TypeId
AarfWifiManager::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::AarfWifiManager")
.SetParent<ArfWifiManager> ()
.SetParent<WifiRemoteStationManager> ()
.AddConstructor<AarfWifiManager> ()
.AddAttribute ("SuccessK", "Multiplication factor for the success threshold in the AARF algorithm.",
DoubleValue (2.0),
@@ -68,44 +86,139 @@ AarfWifiManager::AarfWifiManager ()
{}
AarfWifiManager::~AarfWifiManager ()
{}
WifiRemoteStation *
AarfWifiManager::CreateStation (void)
AarfWifiManager::DoCreateStation (void) const
{
return new AarfWifiRemoteStation (this);
}
AarfWifiRemoteStation *station = new AarfWifiRemoteStation ();
station->m_successThreshold = m_minSuccessThreshold;
station->m_timerTimeout = m_minTimerThreshold;
station->m_rate = 0;
station->m_success = 0;
station->m_failed = 0;
station->m_recovery = false;
station->m_retry = 0;
station->m_timer = 0;
AarfWifiRemoteStation::AarfWifiRemoteStation (Ptr<AarfWifiManager> manager)
: ArfWifiRemoteStation (manager),
m_manager (manager)
{}
AarfWifiRemoteStation::~AarfWifiRemoteStation ()
{}
Ptr<WifiRemoteStationManager>
AarfWifiRemoteStation::GetManager (void) const
{
return m_manager;
return station;
}
void
AarfWifiRemoteStation::ReportRecoveryFailure (void)
AarfWifiManager::DoReportRtsFailed (WifiRemoteStation *station)
{}
/**
* It is important to realize that "recovery" mode starts after failure of
* the first transmission after a rate increase and ends at the first successful
* transmission. Specifically, recovery mode transcends retransmissions boundaries.
* Fundamentally, ARF handles each data transmission independently, whether it
* is the initial transmission of a packet or the retransmission of a packet.
* The fundamental reason for this is that there is a backoff between each data
* transmission, be it an initial transmission or a retransmission.
*/
void
AarfWifiManager::DoReportDataFailed (WifiRemoteStation *st)
{
SetSuccessThreshold ((int)(Min (GetSuccessThreshold () * m_manager->m_successK,
m_manager->m_maxSuccessThreshold)));
SetTimerTimeout ((int)(Max (GetMinTimerTimeout (),
GetSuccessThreshold () * m_manager->m_timerK)));
AarfWifiRemoteStation *station = (AarfWifiRemoteStation *)st;
station->m_timer++;
station->m_failed++;
station->m_retry++;
station->m_success = 0;
if (station->m_recovery)
{
NS_ASSERT (station->m_retry >= 1);
if (station->m_retry == 1)
{
// need recovery fallback
station->m_successThreshold = (int)(Min (station->m_successThreshold * m_successK,
m_maxSuccessThreshold));
station->m_timerTimeout = (int)(Max (station->m_timerTimeout * m_timerK,
m_minSuccessThreshold));
if (station->m_rate != 0)
{
station->m_rate--;
}
}
station->m_timer = 0;
}
else
{
NS_ASSERT (station->m_retry >= 1);
if (((station->m_retry - 1) % 2) == 1)
{
// need normal fallback
station->m_timerTimeout = m_minTimerThreshold;
station->m_successThreshold = m_minSuccessThreshold;
if (station->m_rate != 0)
{
station->m_rate--;
}
}
if (station->m_retry >= 2)
{
station->m_timer = 0;
}
}
}
void
AarfWifiManager::DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode)
{}
void
AarfWifiManager::DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("station=" << station << " rts ok");
}
void
AarfWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st;
station->m_timer++;
station->m_success++;
station->m_failed = 0;
station->m_recovery = false;
station->m_retry = 0;
NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_success << ", timer=" << station->m_timer);
if ((station->m_success == station->m_successThreshold ||
station->m_timer == station->m_timerTimeout) &&
(station->m_rate < (GetNSupported (station) - 1)))
{
NS_LOG_DEBUG ("station="<<station<<" inc rate");
station->m_rate++;
station->m_timer = 0;
station->m_success = 0;
station->m_recovery = true;
}
}
void
AarfWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *station)
{}
void
AarfWifiManager::DoReportFinalDataFailed (WifiRemoteStation *station)
{}
WifiMode
AarfWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
{
AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st;
return GetSupported (station, station->m_rate);
}
WifiMode
AarfWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
// XXX: we could/should implement the Aarf algorithm for
// RTS only by picking a single rate within the BasicRateSet.
AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st;
return GetSupported (station, 0);
}
void
AarfWifiRemoteStation::ReportFailure (void)
bool
AarfWifiManager::IsLowLatency (void) const
{
SetTimerTimeout (GetMinTimerTimeout ());
SetSuccessThreshold (GetMinSuccessThreshold ());
return true;
}
} // namespace ns3

View File

@@ -32,15 +32,29 @@ namespace ns3 {
* A Practical Approach</i>, by M. Lacage, M.H. Manshaei, and
* T. Turletti.
*/
class AarfWifiManager : public ArfWifiManager
class AarfWifiManager : public WifiRemoteStationManager
{
public:
static TypeId GetTypeId (void);
AarfWifiManager ();
virtual ~AarfWifiManager ();
private:
friend class AarfWifiRemoteStation;
virtual class WifiRemoteStation *CreateStation (void);
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool IsLowLatency (void) const;
uint32_t m_minTimerThreshold;
uint32_t m_minSuccessThreshold;
double m_successK;
@@ -48,20 +62,6 @@ private:
double m_timerK;
};
class AarfWifiRemoteStation : public ArfWifiRemoteStation
{
public:
AarfWifiRemoteStation (Ptr<AarfWifiManager> stations);
virtual ~AarfWifiRemoteStation ();
private:
virtual void ReportRecoveryFailure (void);
virtual void ReportFailure (void);
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
Ptr<AarfWifiManager> m_manager;
};
} // namespace ns3

View File

@@ -23,321 +23,38 @@
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/boolean.h"
#include "ns3/double.h"
#include "ns3/uinteger.h"
#include <algorithm>
#define Min(a,b) ((a<b)?a:b)
#define Max(a,b) ((a>b)?a:b)
NS_LOG_COMPONENT_DEFINE ("Aarfcd");
namespace ns3 {
struct AarfcdWifiRemoteStation : public WifiRemoteStation
{
uint32_t m_timer;
uint32_t m_success;
uint32_t m_failed;
bool m_recovery;
bool m_justModifyRate;
uint32_t m_retry;
uint32_t m_successThreshold;
uint32_t m_timerTimeout;
uint32_t m_rate;
bool m_rtsOn;
uint32_t m_rtsWnd;
uint32_t m_rtsCounter;
bool m_haveASuccess;
};
NS_OBJECT_ENSURE_REGISTERED(AarfcdWifiManager);
AarfcdWifiRemoteStation::AarfcdWifiRemoteStation (Ptr<AarfcdWifiManager> manager)
: m_manager (manager)
{
m_timerTimeout = m_manager->m_minTimerThreshold;
m_successThreshold = m_manager->m_minSuccessThreshold;
m_rate = GetMinRate ();
m_success = 0;
m_failed = 0;
m_recovery = false;
m_retry = 0;
m_timer = 0;
m_rtsOn = false;
m_rtsWnd = m_manager->m_minRtsWnd;
m_rtsCounter = 0;
m_justModifyRate = true;
m_haveASuccess = false;
}
AarfcdWifiRemoteStation::~AarfcdWifiRemoteStation ()
{}
uint32_t
AarfcdWifiRemoteStation::GetMaxRate (void)
{
return GetNSupportedModes () - 1;
}
uint32_t
AarfcdWifiRemoteStation::GetMinRate (void)
{
return 0;
}
void
AarfcdWifiRemoteStation::ReportRecoveryFailure (void)
{
m_successThreshold = (int)(std::min ((uint32_t)(m_successThreshold * m_manager->m_successK),
m_manager->m_maxSuccessThreshold));
m_timerTimeout = (int)(std::max (m_manager->m_minTimerThreshold,
(uint32_t)(m_successThreshold * m_manager->m_timerK)));
}
void
AarfcdWifiRemoteStation::ReportFailure (void)
{
m_timerTimeout = m_manager->m_minTimerThreshold;
m_successThreshold = m_manager->m_minSuccessThreshold;
}
bool
AarfcdWifiRemoteStation::NeedRecoveryFallback (void)
{
if (m_retry >= 1)
{
return true;
}
else
{
return false;
}
}
bool
AarfcdWifiRemoteStation::NeedNormalFallback (void)
{
int retryMod = (m_retry - 1) % 2;
if (retryMod == 1)
{
return true;
}
else
{
return false;
}
}
void
AarfcdWifiRemoteStation::DoReportRtsFailed (void)
{
//printf ("%.9f %p RtsFail %d %d %d\n",Simulator::Now ().GetSeconds (),this,m_rate,m_timer,m_retry);
NS_LOG_INFO ("" << this << " RtsFail rate=" << m_rate);
if (m_manager->m_rtsFailsAsDataFails)
{
m_rtsCounter--;
ReportDataFailed ();
}
}
/**
* It is important to realize that "recovery" mode starts after failure of
* the first transmission after a rate increase and ends at the first successful
* transmission. Specifically, recovery mode transcends retransmissions boundaries.
* Fundamentally, ARF handles each data transmission independently, whether it
* is the initial transmission of a packet or the retransmission of a packet.
* The fundamental reason for this is that there is a backoff between each data
* transmission, be it an initial transmission or a retransmission.
*/
void
AarfcdWifiRemoteStation::DoReportDataFailed (void)
{
NS_LOG_INFO ("" << this << " TxFail rate=" << m_rate);
m_timer++;
m_failed++;
m_retry++;
m_success = 0;
//printf ("%.9f %p Fail %d %d %d\n",Simulator::Now ().GetSeconds (),this,m_rate,m_timer,m_retry);
if (!m_rtsOn)
{
TurnOnRts ();
if (!m_justModifyRate && !m_haveASuccess)
{
//printf ("%p Increase RTS Windows\n",this);
IncreaseRtsWnd ();
}
else
{
//printf ("%p Reset RTS Window\n",this);
ResetRtsWnd ();
}
m_rtsCounter = m_rtsWnd;
if (m_retry >= 2)
{
m_timer = 0;
}
//printf ("%.9f %p AtcivateRTS %d %d\n",Simulator::Now ().GetSeconds (),this, m_rate, m_rtsCounter);
}
else if (m_recovery)
{
NS_ASSERT (m_retry >= 1);
m_justModifyRate = false;
m_rtsCounter = m_rtsWnd;
if (NeedRecoveryFallback ())
{
if (m_manager->m_turnOffRtsAfterRateDecrease)
{
TurnOffRts ();
}
m_justModifyRate = true;
ReportRecoveryFailure ();
if (m_rate != GetMinRate ())
{
m_rate--;
}
NS_LOG_INFO ("" << this << " JD rate=" << m_rate << " Sthr=" << m_successThreshold);
//printf ("%.9f %p DecreaseRateRecovery %d\n", Simulator::Now ().GetSeconds (),this, m_rate);
}
m_timer = 0;
}
else
{
NS_ASSERT (m_retry >= 1);
m_justModifyRate = false;
m_rtsCounter = m_rtsWnd;
if (NeedNormalFallback ())
{
if (m_manager->m_turnOffRtsAfterRateDecrease)
{
TurnOffRts ();
}
m_justModifyRate = true;
ReportFailure ();
if (m_rate != GetMinRate ())
{
m_rate--;
}
NS_LOG_INFO ("" << this << " JD rate=" << m_rate << " Sthr=" << m_successThreshold);
//printf ("%.9f %p DecreaseRate %d\n", Simulator::Now ().GetSeconds (),this,m_rate);
}
if (m_retry >= 2)
{
m_timer = 0;
}
}
CheckRts ();
}
void
AarfcdWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
{}
void
AarfcdWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_INFO ("" << this << " RtsOk rate=" << m_rate);
NS_LOG_DEBUG ("self="<<this<<" rts ok");
m_rtsCounter--;
}
void
AarfcdWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
NS_LOG_INFO ("" << this << " TxOk rate=" << m_rate);
m_timer++;
m_success++;
m_failed = 0;
m_recovery = false;
m_retry = 0;
m_justModifyRate = false;
m_haveASuccess = true;
//printf ("%.9f %p Ok %d %d %d\n",Simulator::Now ().GetSeconds (),this,m_rate,m_timer,m_retry);
//printf ("%p OK (m_success=%d, th=%d, m_rate=%d, maxRate=%d)\n",this,m_success,GetSuccessThreshold (), m_rate, GetMaxRate ());
NS_LOG_DEBUG ("self="<<this<<" data ok success="<<m_success<<", timer="<<m_timer);
if ((m_success == m_successThreshold ||
m_timer >= m_timerTimeout) &&
(m_rate < GetMaxRate ()))
{
NS_LOG_DEBUG ("self="<<this<<" inc rate");
m_rate++;
NS_LOG_INFO ("" << this << " JI rate=" << m_rate << " Sthr=" << m_successThreshold);
m_timer = 0;
m_success = 0;
m_recovery = true;
m_justModifyRate = true;
if (m_manager->m_turnOnRtsAfterRateIncrease)
{
TurnOnRts ();
ResetRtsWnd ();
m_rtsCounter = m_rtsWnd;
}
//printf ("%.9f %p IncreaseRate %d %d\n", Simulator::Now ().GetSeconds (),this,m_rate,(m_rtsOn?1:0));
}
else if (m_success == m_successThreshold ||
m_timer >= m_timerTimeout)
{
NS_LOG_INFO ("" << this << " JI rate=" << m_rate << " Sthr=" << m_successThreshold);
}
CheckRts ();
}
void
AarfcdWifiRemoteStation::DoReportFinalRtsFailed (void)
{}
void
AarfcdWifiRemoteStation::DoReportFinalDataFailed (void)
{}
WifiMode
AarfcdWifiRemoteStation::DoGetDataMode (uint32_t size)
{
return GetSupportedMode (m_rate);
}
WifiMode
AarfcdWifiRemoteStation::DoGetRtsMode (void)
{
// XXX: we could/should implement the Arf algorithm for
// RTS only by picking a single rate within the BasicRateSet.
return GetSupportedMode (0);
}
Ptr<WifiRemoteStationManager>
AarfcdWifiRemoteStation::GetManager (void) const
{
return m_manager;
}
void
AarfcdWifiRemoteStation::CheckRts (void)
{
if (m_rtsCounter == 0 && m_rtsOn)
{
//printf ("%p Turn off RTS\n",this);
TurnOffRts ();
}
}
void
AarfcdWifiRemoteStation::TurnOffRts (void)
{
//printf ("%.9f %p DeatcivateRTS %d %d\n",Simulator::Now ().GetSeconds (),this, m_rate, m_rtsCounter);
m_rtsOn = false;
m_haveASuccess = false;
}
void
AarfcdWifiRemoteStation::TurnOnRts (void)
{
m_rtsOn = true;
}
void
AarfcdWifiRemoteStation::IncreaseRtsWnd (void)
{
if (m_rtsWnd == m_manager->m_maxRtsWnd)
{
return;
}
m_rtsWnd *= 2;
if (m_rtsWnd > m_manager->m_maxRtsWnd)
{
m_rtsWnd = m_manager->m_maxRtsWnd;
}
}
void
AarfcdWifiRemoteStation::ResetRtsWnd (void)
{
m_rtsWnd = m_manager->m_minRtsWnd;
}
bool
AarfcdWifiRemoteStation::NeedRts (Ptr<const Packet> packet)
{
//printf ("%.9f %p NeedRts %d %d\n",Simulator::Now ().GetSeconds (),this,m_rate,(m_rtsOn?1:0));
NS_LOG_INFO ("" << this << " rate=" << m_rate << " rts=" << (m_rtsOn?"RTS":"BASIC") << " rtsCounter=" << m_rtsCounter);
return m_rtsOn;
}
TypeId
AarfcdWifiManager::GetTypeId (void)
{
@@ -378,11 +95,6 @@ AarfcdWifiManager::GetTypeId (void)
UintegerValue (40),
MakeUintegerAccessor (&AarfcdWifiManager::m_maxRtsWnd),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("RtsFailsAsDataFails",
"If true the RTS failures will be treated by Aarf-CD as Data failures",
BooleanValue (false),
MakeBooleanAccessor (&AarfcdWifiManager::m_rtsFailsAsDataFails),
MakeBooleanChecker ())
.AddAttribute ("TurnOffRtsAfterRateDecrease",
"If true the RTS mechanism will be turned off when the rate will be decreased",
BooleanValue (true),
@@ -402,9 +114,244 @@ AarfcdWifiManager::AarfcdWifiManager ()
AarfcdWifiManager::~AarfcdWifiManager ()
{}
WifiRemoteStation *
AarfcdWifiManager::CreateStation (void)
AarfcdWifiManager::DoCreateStation (void) const
{
return new AarfcdWifiRemoteStation (this);
AarfcdWifiRemoteStation *station = new AarfcdWifiRemoteStation ();
// aarf fields below
station->m_successThreshold = m_minSuccessThreshold;
station->m_timerTimeout = m_minTimerThreshold;
station->m_rate = 0;
station->m_success = 0;
station->m_failed = 0;
station->m_recovery = false;
station->m_retry = 0;
station->m_timer = 0;
// aarf-cd specific fields below
station->m_rtsOn = false;
station->m_rtsWnd = m_minRtsWnd;
station->m_rtsCounter = 0;
station->m_justModifyRate = true;
station->m_haveASuccess = false;
return station;
}
void
AarfcdWifiManager::DoReportRtsFailed (WifiRemoteStation *station)
{}
/**
* It is important to realize that "recovery" mode starts after failure of
* the first transmission after a rate increase and ends at the first successful
* transmission. Specifically, recovery mode transcends retransmissions boundaries.
* Fundamentally, ARF handles each data transmission independently, whether it
* is the initial transmission of a packet or the retransmission of a packet.
* The fundamental reason for this is that there is a backoff between each data
* transmission, be it an initial transmission or a retransmission.
*/
void
AarfcdWifiManager::DoReportDataFailed (WifiRemoteStation *st)
{
AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *)st;
station->m_timer++;
station->m_failed++;
station->m_retry++;
station->m_success = 0;
if (!station->m_rtsOn)
{
TurnOnRts (station);
if (!station->m_justModifyRate && !station->m_haveASuccess)
{
IncreaseRtsWnd (station);
}
else
{
ResetRtsWnd (station);
}
station->m_rtsCounter = station->m_rtsWnd;
if (station->m_retry >= 2)
{
station->m_timer = 0;
}
}
else if (station->m_recovery)
{
NS_ASSERT (station->m_retry >= 1);
station->m_justModifyRate = false;
station->m_rtsCounter = station->m_rtsWnd;
if (station->m_retry == 1)
{
// need recovery fallback
if (m_turnOffRtsAfterRateDecrease)
{
TurnOffRts (station);
}
station->m_justModifyRate = true;
station->m_successThreshold = (int)(Min (station->m_successThreshold * m_successK,
m_maxSuccessThreshold));
station->m_timerTimeout = (int)(Max (station->m_timerTimeout * m_timerK,
m_minSuccessThreshold));
if (station->m_rate != 0)
{
station->m_rate--;
}
}
station->m_timer = 0;
}
else
{
NS_ASSERT (station->m_retry >= 1);
station->m_justModifyRate = false;
station->m_rtsCounter = station->m_rtsWnd;
if (((station->m_retry - 1) % 2) == 1)
{
// need normal fallback
if (m_turnOffRtsAfterRateDecrease)
{
TurnOffRts (station);
}
station->m_justModifyRate = true;
station->m_timerTimeout = m_minTimerThreshold;
station->m_successThreshold = m_minSuccessThreshold;
if (station->m_rate != 0)
{
station->m_rate--;
}
}
if (station->m_retry >= 2)
{
station->m_timer = 0;
}
}
CheckRts (station);
}
void
AarfcdWifiManager::DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode)
{}
void
AarfcdWifiManager::DoReportRtsOk (WifiRemoteStation *st,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
NS_LOG_DEBUG ("station=" << station << " rts ok");
station->m_rtsCounter--;
}
void
AarfcdWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
station->m_timer++;
station->m_success++;
station->m_failed = 0;
station->m_recovery = false;
station->m_retry = 0;
station->m_justModifyRate = false;
station->m_haveASuccess = true;
NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_success << ", timer=" << station->m_timer);
if ((station->m_success == station->m_successThreshold ||
station->m_timer == station->m_timerTimeout) &&
(station->m_rate < (GetNSupported (station) - 1)))
{
NS_LOG_DEBUG ("station="<<station<<" inc rate");
station->m_rate++;
station->m_timer = 0;
station->m_success = 0;
station->m_recovery = true;
station->m_justModifyRate = true;
if (m_turnOnRtsAfterRateIncrease)
{
TurnOnRts (station);
ResetRtsWnd (station);
station->m_rtsCounter = station->m_rtsWnd;
}
}
CheckRts (station);
}
void
AarfcdWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *station)
{}
void
AarfcdWifiManager::DoReportFinalDataFailed (WifiRemoteStation *station)
{}
WifiMode
AarfcdWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
{
AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
return GetSupported (station, station->m_rate);
}
WifiMode
AarfcdWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
// XXX: we could/should implement the Aarf algorithm for
// RTS only by picking a single rate within the BasicRateSet.
AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
return GetSupported (station, 0);
}
bool
AarfcdWifiManager::DoNeedRts (WifiRemoteStation *st,
Ptr<const Packet> packet, bool normally)
{
AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
NS_LOG_INFO ("" << station << " rate=" << station->m_rate << " rts=" << (station->m_rtsOn?"RTS":"BASIC") <<
" rtsCounter=" << station->m_rtsCounter);
return station->m_rtsOn;
}
bool
AarfcdWifiManager::IsLowLatency (void) const
{
return true;
}
void
AarfcdWifiManager::CheckRts (AarfcdWifiRemoteStation *station)
{
if (station->m_rtsCounter == 0 && station->m_rtsOn)
{
TurnOffRts (station);
}
}
void
AarfcdWifiManager::TurnOffRts (AarfcdWifiRemoteStation *station)
{
station->m_rtsOn = false;
station->m_haveASuccess = false;
}
void
AarfcdWifiManager::TurnOnRts (AarfcdWifiRemoteStation *station)
{
station->m_rtsOn = true;
}
void
AarfcdWifiManager::IncreaseRtsWnd (AarfcdWifiRemoteStation *station)
{
if (station->m_rtsWnd == m_maxRtsWnd)
{
return;
}
station->m_rtsWnd *= 2;
if (station->m_rtsWnd > m_maxRtsWnd)
{
station->m_rtsWnd = m_maxRtsWnd;
}
}
void
AarfcdWifiManager::ResetRtsWnd (AarfcdWifiRemoteStation *station)
{
station->m_rtsWnd = m_minRtsWnd;
}
} // namespace ns3

View File

@@ -24,6 +24,8 @@
namespace ns3 {
class AarfcdWifiRemoteStation;
/**
* \brief an implementation of the AARF-CD algorithm
*
@@ -40,13 +42,38 @@ public:
virtual ~AarfcdWifiManager ();
private:
friend class AarfcdWifiRemoteStation;
virtual WifiRemoteStation *CreateStation (void);
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool DoNeedRts (WifiRemoteStation *station,
Ptr<const Packet> packet, bool normally);
virtual bool IsLowLatency (void) const;
void CheckRts (AarfcdWifiRemoteStation *station);
void IncreaseRtsWnd (AarfcdWifiRemoteStation *station);
void ResetRtsWnd (AarfcdWifiRemoteStation *station);
void TurnOffRts (AarfcdWifiRemoteStation *station);
void TurnOnRts (AarfcdWifiRemoteStation *station);
// aarf fields below
uint32_t m_minTimerThreshold;
uint32_t m_minSuccessThreshold;
double m_successK;
uint32_t m_maxSuccessThreshold;
double m_timerK;
// aarf-cd fields below
uint32_t m_minRtsWnd;
uint32_t m_maxRtsWnd;
bool m_rtsFailsAsDataFails;
@@ -54,59 +81,6 @@ private:
bool m_turnOnRtsAfterRateIncrease;
};
class AarfcdWifiRemoteStation : public WifiRemoteStation
{
public:
AarfcdWifiRemoteStation (Ptr<AarfcdWifiManager> manager);
virtual ~AarfcdWifiRemoteStation ();
private:
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (void);
virtual void DoReportDataFailed (void);
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (void);
virtual void DoReportFinalDataFailed (void);
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
virtual bool NeedRts (Ptr<const Packet> packet);
void ReportRecoveryFailure (void);
void ReportFailure (void);
uint32_t GetMaxRate (void);
uint32_t GetMinRate (void);
void CheckRts (void);
void IncreaseRtsWnd (void);
void ResetRtsWnd (void);
void TurnOffRts (void);
void TurnOnRts (void);
bool NeedRecoveryFallback (void);
bool NeedNormalFallback (void);
uint32_t m_timer;
uint32_t m_success;
uint32_t m_failed;
bool m_recovery;
bool m_justModifyRate;
uint32_t m_retry;
uint32_t m_successThreshold;
uint32_t m_timerTimeout;
uint32_t m_rate;
bool m_rtsOn;
uint32_t m_rtsWnd;
uint32_t m_rtsCounter;
bool m_haveASuccess;
Ptr<AarfcdWifiManager> m_manager;
};
} // namespace ns3
#endif /* MAARF_MAC_STATIONS_H */
#endif /* AARFCD_WIFI_MANAGER_H */

View File

@@ -234,16 +234,15 @@ AdhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
hdr.SetDsNotFrom ();
hdr.SetDsNotTo ();
WifiRemoteStation *destination = m_stationManager->Lookup (to);
if (destination->IsBrandNew ())
if (m_stationManager->IsBrandNew (to))
{
// in adhoc mode, we assume that every destination
// supports all the rates we support.
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
destination->AddSupportedMode (m_phy->GetMode (i));
m_stationManager->AddSupportedMode (to, m_phy->GetMode (i));
}
destination->RecordDisassociated ();
m_stationManager->RecordDisassociated (to);
}
m_dca->Queue (packet, hdr);

View File

@@ -28,6 +28,20 @@ NS_LOG_COMPONENT_DEFINE ("AmrrWifiRemoteStation");
namespace ns3 {
struct AmrrWifiRemoteStation : public WifiRemoteStation
{
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;
};
NS_OBJECT_ENSURE_REGISTERED (AmrrWifiManager);
TypeId
@@ -67,224 +81,231 @@ AmrrWifiManager::GetTypeId (void)
AmrrWifiManager::AmrrWifiManager ()
{}
WifiRemoteStation *
AmrrWifiManager::CreateStation (void)
AmrrWifiManager::DoCreateStation (void) const
{
return new AmrrWifiRemoteStation (this);
AmrrWifiRemoteStation *station = new AmrrWifiRemoteStation ();
station->m_nextModeUpdate = Simulator::Now () + m_updatePeriod;
station->m_tx_ok = 0;
station->m_tx_err = 0;
station->m_tx_retr = 0;
station->m_retry = 0;
station->m_txrate = 0;
station->m_successThreshold = m_minSuccessThreshold;
station->m_success = 0;
station->m_recovery = false;
return station;
}
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::DoReportRxOk (double rxSnr, WifiMode txMode)
AmrrWifiManager::DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode)
{}
void
AmrrWifiRemoteStation::DoReportRtsFailed (void)
AmrrWifiManager::DoReportRtsFailed (WifiRemoteStation *station)
{}
void
AmrrWifiRemoteStation::DoReportDataFailed (void)
AmrrWifiManager::DoReportDataFailed (WifiRemoteStation *st)
{
m_retry++;
m_tx_retr++;
AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st;
station->m_retry++;
station->m_tx_retr++;
}
void
AmrrWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
AmrrWifiManager::DoReportRtsOk (WifiRemoteStation *st,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
}
void
AmrrWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st;
station->m_retry = 0;
station->m_tx_ok++;
}
void
AmrrWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *station)
{}
void
AmrrWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
AmrrWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st)
{
m_retry = 0;
m_tx_ok++;
}
void
AmrrWifiRemoteStation::DoReportFinalRtsFailed (void)
{}
void
AmrrWifiRemoteStation::DoReportFinalDataFailed (void)
{
m_retry = 0;
m_tx_err++;
AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st;
station->m_retry = 0;
station->m_tx_err++;
}
bool
AmrrWifiRemoteStation::IsMinRate (void) const
AmrrWifiManager::IsMinRate (AmrrWifiRemoteStation *station) const
{
return (m_txrate == 0);
return (station->m_txrate == 0);
}
bool
AmrrWifiRemoteStation::IsMaxRate (void) const
AmrrWifiManager::IsMaxRate (AmrrWifiRemoteStation *station) const
{
NS_ASSERT (m_txrate + 1 <= GetNSupportedModes ());
return (m_txrate + 1 == GetNSupportedModes ());
NS_ASSERT (station->m_txrate + 1 <= GetNSupported (station));
return (station->m_txrate + 1 == GetNSupported (station));
}
bool
AmrrWifiRemoteStation::IsSuccess (void) const
AmrrWifiManager::IsSuccess (AmrrWifiRemoteStation *station) const
{
return (m_tx_retr + m_tx_err) < m_tx_ok * m_stations->m_successRatio;
return (station->m_tx_retr + station->m_tx_err) < station->m_tx_ok * m_successRatio;
}
bool
AmrrWifiRemoteStation::IsFailure (void) const
AmrrWifiManager::IsFailure (AmrrWifiRemoteStation *station) const
{
return (m_tx_retr + m_tx_err) > m_tx_ok * m_stations->m_failureRatio;
return (station->m_tx_retr + station->m_tx_err) > station->m_tx_ok * m_failureRatio;
}
bool
AmrrWifiRemoteStation::IsEnough (void) const
AmrrWifiManager::IsEnough (AmrrWifiRemoteStation *station) const
{
return (m_tx_retr + m_tx_err + m_tx_ok) > 10;
return (station->m_tx_retr + station->m_tx_err + station->m_tx_ok) > 10;
}
void
AmrrWifiRemoteStation::ResetCnt (void)
AmrrWifiManager::ResetCnt (AmrrWifiRemoteStation *station)
{
m_tx_ok = 0;
m_tx_err = 0;
m_tx_retr = 0;
station->m_tx_ok = 0;
station->m_tx_err = 0;
station->m_tx_retr = 0;
}
void
AmrrWifiRemoteStation::IncreaseRate (void)
AmrrWifiManager::IncreaseRate (AmrrWifiRemoteStation *station)
{
m_txrate++;
NS_ASSERT (m_txrate < GetNSupportedModes ());
station->m_txrate++;
NS_ASSERT (station->m_txrate < GetNSupported (station));
}
void
AmrrWifiRemoteStation::DecreaseRate (void)
AmrrWifiManager::DecreaseRate (AmrrWifiRemoteStation *station)
{
m_txrate--;
station->m_txrate--;
}
void
AmrrWifiRemoteStation::UpdateMode (void)
AmrrWifiManager::UpdateMode (AmrrWifiRemoteStation *station)
{
if (Simulator::Now () < m_nextModeUpdate)
if (Simulator::Now () < station->m_nextModeUpdate)
{
return;
}
m_nextModeUpdate = Simulator::Now () + m_stations->m_updatePeriod;
station->m_nextModeUpdate = Simulator::Now () + m_updatePeriod;
NS_LOG_DEBUG ("Update");
bool needChange = false;
if (IsSuccess () && IsEnough ())
if (IsSuccess (station) && IsEnough (station))
{
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 ())
station->m_success++;
NS_LOG_DEBUG ("++ success="<<station->m_success<<" successThreshold="<<station->m_successThreshold<<
" tx_ok="<<station->m_tx_ok<<" tx_err="<<station->m_tx_err<<" tx_retr="<<station->m_tx_retr<<
" rate="<<station->m_txrate<<" n-supported-rates="<<GetNSupported (station));
if (station->m_success >= station->m_successThreshold &&
!IsMaxRate (station))
{
m_recovery = true;
m_success = 0;
IncreaseRate ();
station->m_recovery = true;
station->m_success = 0;
IncreaseRate (station);
needChange = true;
}
else
{
m_recovery = false;
station->m_recovery = false;
}
}
else if (IsFailure ())
else if (IsFailure (station))
{
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 ())
station->m_success = 0;
NS_LOG_DEBUG ("-- success="<<station->m_success<<" successThreshold="<<station->m_successThreshold<<
" tx_ok="<<station->m_tx_ok<<" tx_err="<<station->m_tx_err<<" tx_retr="<<station->m_tx_retr<<
" rate="<<station->m_txrate<<" n-supported-rates="<<GetNSupported (station));
if (!IsMinRate (station))
{
if (m_recovery)
if (station->m_recovery)
{
m_successThreshold *= 2;
m_successThreshold = std::min (m_successThreshold,
m_stations->m_maxSuccessThreshold);
station->m_successThreshold *= 2;
station->m_successThreshold = std::min (station->m_successThreshold,
m_maxSuccessThreshold);
}
else
{
m_successThreshold = m_stations->m_minSuccessThreshold;
station->m_successThreshold = m_minSuccessThreshold;
}
m_recovery = false;
DecreaseRate ();
station->m_recovery = false;
DecreaseRate (station);
needChange = true;
}
else
{
m_recovery = false;
station->m_recovery = false;
}
}
if (IsEnough () || needChange)
if (IsEnough (station) || needChange)
{
NS_LOG_DEBUG ("Reset");
ResetCnt ();
ResetCnt (station);
}
}
Ptr<WifiRemoteStationManager>
AmrrWifiRemoteStation::GetManager (void) const
{
return m_stations;
}
WifiMode
AmrrWifiRemoteStation::DoGetDataMode (uint32_t size)
AmrrWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
{
UpdateMode ();
NS_ASSERT (m_txrate < GetNSupportedModes ());
AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st;
UpdateMode (station);
NS_ASSERT (station->m_txrate < GetNSupported (station));
uint32_t rateIndex;
if (m_retry < 1)
if (station->m_retry < 1)
{
rateIndex = m_txrate;
rateIndex = station->m_txrate;
}
else if (m_retry < 2)
else if (station->m_retry < 2)
{
if (m_txrate > 0)
if (station->m_txrate > 0)
{
rateIndex = m_txrate - 1;
rateIndex = station->m_txrate - 1;
}
else
{
rateIndex = m_txrate;
rateIndex = station->m_txrate;
}
}
else if (m_retry < 3)
else if (station->m_retry < 3)
{
if (m_txrate > 1)
if (station->m_txrate > 1)
{
rateIndex = m_txrate - 2;
rateIndex = station->m_txrate - 2;
}
else
{
rateIndex = m_txrate;
rateIndex = station->m_txrate;
}
}
else
{
if (m_txrate > 2)
if (station->m_txrate > 2)
{
rateIndex = m_txrate - 3;
rateIndex = station->m_txrate - 3;
}
else
{
rateIndex = m_txrate;
rateIndex = station->m_txrate;
}
}
return GetSupportedMode (rateIndex);
return GetSupported (station, rateIndex);
}
WifiMode
AmrrWifiRemoteStation::DoGetRtsMode (void)
AmrrWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
UpdateMode ();
AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st;
UpdateMode (station);
// XXX: can we implement something smarter ?
return GetSupportedMode (0);
return GetSupported (station, 0);
}
bool
AmrrWifiManager::IsLowLatency (void) const
{
return true;
}
} // namespace ns3

View File

@@ -25,6 +25,8 @@
namespace ns3 {
class AmrrWifiRemoteStation;
/**
* \brief AMRR Rate control algorithm
*
@@ -41,8 +43,32 @@ public:
AmrrWifiManager ();
private:
friend class AmrrWifiRemoteStation;
virtual WifiRemoteStation *CreateStation (void);
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool IsLowLatency (void) const;
void UpdateRetry (AmrrWifiRemoteStation *station);
void UpdateMode (AmrrWifiRemoteStation *station);
void ResetCnt (AmrrWifiRemoteStation *station);
void IncreaseRate (AmrrWifiRemoteStation *station);
void DecreaseRate (AmrrWifiRemoteStation *station);
bool IsMinRate (AmrrWifiRemoteStation *station) const;
bool IsMaxRate (AmrrWifiRemoteStation *station) const;
bool IsSuccess (AmrrWifiRemoteStation *station) const;
bool IsFailure (AmrrWifiRemoteStation *station) const;
bool IsEnough (AmrrWifiRemoteStation *station) const;
Time m_updatePeriod;
double m_failureRatio;
@@ -51,52 +77,6 @@ private:
uint32_t m_minSuccessThreshold;
};
/**
*/
class AmrrWifiRemoteStation : public WifiRemoteStation
{
public:
AmrrWifiRemoteStation (Ptr<AmrrWifiManager> stations);
virtual ~AmrrWifiRemoteStation ();
protected:
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (void);
virtual void DoReportDataFailed (void);
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (void);
virtual void DoReportFinalDataFailed (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

@@ -27,193 +27,20 @@ NS_LOG_COMPONENT_DEFINE ("ns3::ArfWifiManager");
namespace ns3 {
struct ArfWifiRemoteStation : public WifiRemoteStation
{
uint32_t m_timer;
uint32_t m_success;
uint32_t m_failed;
bool m_recovery;
uint32_t m_retry;
ArfWifiRemoteStation::ArfWifiRemoteStation (Ptr<ArfWifiManager> manager)
: m_manager (manager)
{
m_successThreshold = m_manager->m_successThreshold;
m_timerTimeout = m_manager->m_timerThreshold;
m_rate = GetMinRate ();
uint32_t m_timerTimeout;
uint32_t m_successThreshold;
m_success = 0;
m_failed = 0;
m_recovery = false;
m_retry = 0;
m_timer = 0;
}
ArfWifiRemoteStation::~ArfWifiRemoteStation ()
{}
uint32_t
ArfWifiRemoteStation::GetMaxRate (void)
{
return GetNSupportedModes ();
}
uint32_t
ArfWifiRemoteStation::GetMinRate (void)
{
return 0;
}
bool
ArfWifiRemoteStation::NeedRecoveryFallback (void)
{
if (m_retry == 1)
{
return true;
}
else
{
return false;
}
}
bool
ArfWifiRemoteStation::NeedNormalFallback (void)
{
int retryMod = (m_retry - 1) % 2;
if (retryMod == 1)
{
return true;
}
else
{
return false;
}
}
void
ArfWifiRemoteStation::DoReportRtsFailed (void)
{}
/**
* It is important to realize that "recovery" mode starts after failure of
* the first transmission after a rate increase and ends at the first successful
* transmission. Specifically, recovery mode transcends retransmissions boundaries.
* Fundamentally, ARF handles each data transmission independently, whether it
* is the initial transmission of a packet or the retransmission of a packet.
* The fundamental reason for this is that there is a backoff between each data
* transmission, be it an initial transmission or a retransmission.
*/
void
ArfWifiRemoteStation::DoReportDataFailed (void)
{
m_timer++;
m_failed++;
m_retry++;
m_success = 0;
if (m_recovery)
{
NS_ASSERT (m_retry >= 1);
if (NeedRecoveryFallback ())
{
ReportRecoveryFailure ();
if (m_rate != GetMinRate ())
{
m_rate--;
}
}
m_timer = 0;
}
else
{
NS_ASSERT (m_retry >= 1);
if (NeedNormalFallback ())
{
ReportFailure ();
if (m_rate != GetMinRate ())
{
m_rate--;
}
}
if (m_retry >= 2)
{
m_timer = 0;
}
}
}
void
ArfWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
{}
void ArfWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("self="<<this<<" rts ok");
}
void ArfWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
m_timer++;
m_success++;
m_failed = 0;
m_recovery = false;
m_retry = 0;
NS_LOG_DEBUG ("self="<<this<<" data ok success="<<m_success<<", timer="<<m_timer);
if ((m_success == GetSuccessThreshold () ||
m_timer == GetTimerTimeout ()) &&
(m_rate < (GetMaxRate () - 1)))
{
NS_LOG_DEBUG ("self="<<this<<" inc rate");
m_rate++;
m_timer = 0;
m_success = 0;
m_recovery = true;
}
}
void
ArfWifiRemoteStation::DoReportFinalRtsFailed (void)
{}
void
ArfWifiRemoteStation::DoReportFinalDataFailed (void)
{}
WifiMode
ArfWifiRemoteStation::DoGetDataMode (uint32_t size)
{
return GetSupportedMode (m_rate);
}
WifiMode
ArfWifiRemoteStation::DoGetRtsMode (void)
{
// XXX: we could/should implement the Arf algorithm for
// RTS only by picking a single rate within the BasicRateSet.
return GetSupportedMode (0);
}
void ArfWifiRemoteStation::ReportRecoveryFailure (void)
{}
void ArfWifiRemoteStation::ReportFailure (void)
{}
uint32_t ArfWifiRemoteStation::GetMinTimerTimeout (void)
{
return m_manager->m_timerThreshold;
}
uint32_t ArfWifiRemoteStation::GetMinSuccessThreshold (void)
{
return m_manager->m_successThreshold;
}
uint32_t ArfWifiRemoteStation::GetTimerTimeout (void)
{
return m_timerTimeout;
}
uint32_t ArfWifiRemoteStation::GetSuccessThreshold (void)
{
return m_successThreshold;
}
void ArfWifiRemoteStation::SetTimerTimeout (uint32_t timerTimeout)
{
NS_ASSERT (timerTimeout >= m_manager->m_timerThreshold);
m_timerTimeout = timerTimeout;
}
void ArfWifiRemoteStation::SetSuccessThreshold (uint32_t successThreshold)
{
NS_ASSERT (successThreshold >= m_manager->m_successThreshold);
m_successThreshold = successThreshold;
}
Ptr<WifiRemoteStationManager>
ArfWifiRemoteStation::GetManager (void) const
{
return m_manager;
}
uint32_t m_rate;
};
NS_OBJECT_ENSURE_REGISTERED (ArfWifiManager);
@@ -241,9 +68,129 @@ ArfWifiManager::ArfWifiManager ()
ArfWifiManager::~ArfWifiManager ()
{}
WifiRemoteStation *
ArfWifiManager::CreateStation (void)
ArfWifiManager::DoCreateStation (void) const
{
return new ArfWifiRemoteStation (this);
ArfWifiRemoteStation *station = new ArfWifiRemoteStation ();
station->m_successThreshold = m_successThreshold;
station->m_timerTimeout = m_timerThreshold;
station->m_rate = 0;
station->m_success = 0;
station->m_failed = 0;
station->m_recovery = false;
station->m_retry = 0;
station->m_timer = 0;
return station;
}
void
ArfWifiManager::DoReportRtsFailed (WifiRemoteStation *station)
{}
/**
* It is important to realize that "recovery" mode starts after failure of
* the first transmission after a rate increase and ends at the first successful
* transmission. Specifically, recovery mode transcends retransmissions boundaries.
* Fundamentally, ARF handles each data transmission independently, whether it
* is the initial transmission of a packet or the retransmission of a packet.
* The fundamental reason for this is that there is a backoff between each data
* transmission, be it an initial transmission or a retransmission.
*/
void
ArfWifiManager::DoReportDataFailed (WifiRemoteStation *st)
{
ArfWifiRemoteStation *station = (ArfWifiRemoteStation *)st;
station->m_timer++;
station->m_failed++;
station->m_retry++;
station->m_success = 0;
if (station->m_recovery)
{
NS_ASSERT (station->m_retry >= 1);
if (station->m_retry == 1)
{
// need recovery fallback
if (station->m_rate != 0)
{
station->m_rate--;
}
}
station->m_timer = 0;
}
else
{
NS_ASSERT (station->m_retry >= 1);
if (((station->m_retry - 1) % 2) == 1)
{
// need normal fallback
if (station->m_rate != 0)
{
station->m_rate--;
}
}
if (station->m_retry >= 2)
{
station->m_timer = 0;
}
}
}
void
ArfWifiManager::DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode)
{}
void ArfWifiManager::DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("station="<<station<<" rts ok");
}
void ArfWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st;
station->m_timer++;
station->m_success++;
station->m_failed = 0;
station->m_recovery = false;
station->m_retry = 0;
NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_success << ", timer=" << station->m_timer);
if ((station->m_success == m_successThreshold ||
station->m_timer == m_timerThreshold) &&
(station->m_rate < (station->m_state->m_modes.size () - 1)))
{
NS_LOG_DEBUG ("station="<<station<<" inc rate");
station->m_rate++;
station->m_timer = 0;
station->m_success = 0;
station->m_recovery = true;
}
}
void
ArfWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *station)
{}
void
ArfWifiManager::DoReportFinalDataFailed (WifiRemoteStation *station)
{}
WifiMode
ArfWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
{
ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st;
return GetSupported (station, station->m_rate);
}
WifiMode
ArfWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
// XXX: we could/should implement the Arf algorithm for
// RTS only by picking a single rate within the BasicRateSet.
ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st;
return GetSupported (station, 0);
}
bool
ArfWifiManager::IsLowLatency (void) const
{
return true;
}
} // namespace ns3

View File

@@ -46,69 +46,26 @@ public:
virtual ~ArfWifiManager ();
private:
friend class ArfWifiRemoteStation;
virtual class WifiRemoteStation *CreateStation (void);
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool IsLowLatency (void) const;
uint32_t m_timerThreshold;
uint32_t m_successThreshold;
};
class ArfWifiRemoteStation : public WifiRemoteStation
{
public:
ArfWifiRemoteStation (Ptr<ArfWifiManager> manager);
virtual ~ArfWifiRemoteStation ();
protected:
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (void);
virtual void DoReportDataFailed (void);
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (void);
virtual void DoReportFinalDataFailed (void);
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
uint32_t m_timer;
uint32_t m_success;
uint32_t m_failed;
bool m_recovery;
uint32_t m_retry;
uint32_t m_timerTimeout;
uint32_t m_successThreshold;
uint32_t m_rate;
Ptr<ArfWifiManager> m_manager;
private:
// overriden by AarfMacStation.
virtual void ReportRecoveryFailure (void);
virtual void ReportFailure (void);
uint32_t GetMaxRate (void);
uint32_t GetMinRate (void);
bool NeedRecoveryFallback (void);
bool NeedNormalFallback (void);
protected:
// called by AarfMacStation.
uint32_t GetMinTimerTimeout (void);
uint32_t GetMinSuccessThreshold (void);
uint32_t GetTimerTimeout (void);
uint32_t GetSuccessThreshold (void);
void SetTimerTimeout (uint32_t timerTimeout);
void SetSuccessThreshold (uint32_t successThreshold);
};
} // namespace ns3
#endif /* ARF_WIFI_MANAGER_H */

View File

@@ -21,6 +21,8 @@
#include "cara-wifi-manager.h"
#include "ns3/assert.h"
#include "ns3/log.h"
#include "ns3/double.h"
#include "ns3/uinteger.h"
#include "ns3/simulator.h"
NS_LOG_COMPONENT_DEFINE ("Cara");
@@ -28,126 +30,16 @@ NS_LOG_COMPONENT_DEFINE ("Cara");
namespace ns3 {
struct CaraWifiRemoteStation : public WifiRemoteStation
{
uint32_t m_timer;
uint32_t m_success;
uint32_t m_failed;
uint32_t m_rate;
};
NS_OBJECT_ENSURE_REGISTERED(CaraWifiManager);
CaraWifiRemoteStation::CaraWifiRemoteStation (Ptr<CaraWifiManager> manager)
: m_manager (manager)
{
m_rate = GetMinRate ();
m_success = 0;
m_failed = 0;
m_timer = 0;
}
CaraWifiRemoteStation::~CaraWifiRemoteStation ()
{}
uint32_t
CaraWifiRemoteStation::GetMaxRate (void)
{
return GetNSupportedModes () - 1;
}
uint32_t
CaraWifiRemoteStation::GetMinRate (void)
{
return 0;
}
bool
CaraWifiRemoteStation::NeedNormalFallback (void)
{
return (m_failed >= m_manager->m_failureThreshold);
}
void
CaraWifiRemoteStation::DoReportRtsFailed (void)
{}
void
CaraWifiRemoteStation::DoReportDataFailed (void)
{
NS_LOG_FUNCTION (this);
m_timer++;
m_failed++;
m_success = 0;
if (NeedNormalFallback ())
{
NS_LOG_DEBUG ("self="<<this<<" dec rate");
if (m_rate != GetMinRate ())
{
m_rate--;
}
m_failed = 0;
m_timer = 0;
}
}
void
CaraWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
{}
void
CaraWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("self="<<this<<" rts ok");
}
void
CaraWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
m_timer++;
m_success++;
m_failed = 0;
NS_LOG_DEBUG ("self="<<this<<" data ok success="<<m_success<<", timer="<<m_timer);
if ((m_success == m_manager->m_successThreshold ||
m_timer >= m_manager->m_timerTimeout))
{
if (m_rate < GetMaxRate ())
{
m_rate++;
}
NS_LOG_DEBUG ("self="<<this<<" inc rate=" << m_rate);
m_timer = 0;
m_success = 0;
}
}
void
CaraWifiRemoteStation::DoReportFinalRtsFailed (void)
{}
void
CaraWifiRemoteStation::DoReportFinalDataFailed (void)
{}
WifiMode
CaraWifiRemoteStation::DoGetDataMode (uint32_t size)
{
return GetSupportedMode (m_rate);
}
WifiMode
CaraWifiRemoteStation::DoGetRtsMode (void)
{
// XXX: we could/should implement the Arf algorithm for
// RTS only by picking a single rate within the BasicRateSet.
return GetSupportedMode (0);
}
Ptr<WifiRemoteStationManager>
CaraWifiRemoteStation::GetManager (void) const
{
return m_manager;
}
bool
CaraWifiRemoteStation::NeedRts (Ptr<const Packet> packet)
{
bool rts = WifiRemoteStation::NeedRts (packet);
if (rts || m_failed >= m_manager->m_probeThreshold)
{
return true;
}
return false;
}
TypeId
CaraWifiManager::GetTypeId (void)
{
@@ -185,9 +77,104 @@ CaraWifiManager::~CaraWifiManager ()
{}
WifiRemoteStation *
CaraWifiManager::CreateStation (void)
CaraWifiManager::DoCreateStation (void) const
{
return new CaraWifiRemoteStation (this);
CaraWifiRemoteStation *station = new CaraWifiRemoteStation ();
station->m_rate = 0;
station->m_success = 0;
station->m_failed = 0;
station->m_timer = 0;
return station;
}
void
CaraWifiManager::DoReportRtsFailed (WifiRemoteStation *st)
{}
void
CaraWifiManager::DoReportDataFailed (WifiRemoteStation *st)
{
CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st;
NS_LOG_FUNCTION (station);
station->m_timer++;
station->m_failed++;
station->m_success = 0;
if (station->m_failed >= m_failureThreshold)
{
NS_LOG_DEBUG ("self="<<station<<" dec rate");
if (station->m_rate != 0)
{
station->m_rate--;
}
station->m_failed = 0;
station->m_timer = 0;
}
}
void
CaraWifiManager::DoReportRxOk (WifiRemoteStation *st,
double rxSnr, WifiMode txMode)
{}
void
CaraWifiManager::DoReportRtsOk (WifiRemoteStation *st,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("self="<<st<<" rts ok");
}
void
CaraWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st;
station->m_timer++;
station->m_success++;
station->m_failed = 0;
NS_LOG_DEBUG ("self="<<station<<" data ok success="<<station->m_success<<", timer="<<station->m_timer);
if ((station->m_success == m_successThreshold ||
station->m_timer >= m_timerTimeout))
{
if (station->m_rate < GetNSupported (station) - 1)
{
station->m_rate++;
}
NS_LOG_DEBUG ("self="<<station<<" inc rate=" << station->m_rate);
station->m_timer = 0;
station->m_success = 0;
}
}
void
CaraWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *st)
{}
void
CaraWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st)
{}
WifiMode
CaraWifiManager::DoGetDataMode (WifiRemoteStation *st,
uint32_t size)
{
CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st;
return GetSupported (station, station->m_rate);
}
WifiMode
CaraWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
// XXX: we could/should implement the Arf algorithm for
// RTS only by picking a single rate within the BasicRateSet.
return GetSupported (st, 0);
}
bool
CaraWifiManager::DoNeedRts (WifiRemoteStation *st,
Ptr<const Packet> packet, bool normally)
{
CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st;
return normally || station->m_failed >= m_probeThreshold;
}
bool
CaraWifiManager::IsLowLatency (void) const
{
return true;
}
} // namespace ns3

View File

@@ -42,50 +42,30 @@ public:
virtual ~CaraWifiManager ();
private:
friend class CaraWifiRemoteStation;
virtual class WifiRemoteStation *CreateStation (void);
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool DoNeedRts (WifiRemoteStation *station,
Ptr<const Packet> packet, bool normally);
virtual bool IsLowLatency (void) const;
uint32_t m_timerTimeout;
uint32_t m_successThreshold;
uint32_t m_failureThreshold;
uint32_t m_probeThreshold;
};
class CaraWifiRemoteStation : public WifiRemoteStation
{
public:
CaraWifiRemoteStation (Ptr<CaraWifiManager> manager);
virtual ~CaraWifiRemoteStation ();
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
virtual void DoReportRtsFailed (void);
virtual void DoReportDataFailed (void);
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (void);
virtual void DoReportFinalDataFailed (void);
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
virtual bool NeedRts (Ptr<const Packet> packet);
uint32_t m_timer;
uint32_t m_success;
uint32_t m_failed;
uint32_t m_rate;
Ptr<CaraWifiManager> m_manager;
uint32_t GetMaxRate (void);
uint32_t GetMinRate (void);
bool NeedNormalFallback (void);
};
} // namespace ns3
#endif /* CARA_WIFI_MANAGER_H */

View File

@@ -25,50 +25,6 @@
namespace ns3 {
ConstantRateWifiRemoteStation::ConstantRateWifiRemoteStation (Ptr<ConstantRateWifiManager> manager)
: m_manager (manager)
{}
ConstantRateWifiRemoteStation::~ConstantRateWifiRemoteStation ()
{}
void
ConstantRateWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
{}
void
ConstantRateWifiRemoteStation::DoReportRtsFailed (void)
{}
void
ConstantRateWifiRemoteStation::DoReportDataFailed (void)
{}
void
ConstantRateWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{}
void
ConstantRateWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{}
void
ConstantRateWifiRemoteStation::DoReportFinalRtsFailed (void)
{}
void
ConstantRateWifiRemoteStation::DoReportFinalDataFailed (void)
{}
WifiMode
ConstantRateWifiRemoteStation::DoGetDataMode (uint32_t size)
{
return m_manager->GetDataMode ();
}
WifiMode
ConstantRateWifiRemoteStation::DoGetRtsMode (void)
{
return m_manager->GetCtlMode ();
}
Ptr<WifiRemoteStationManager>
ConstantRateWifiRemoteStation::GetManager (void) const
{
return m_manager;
}
NS_OBJECT_ENSURE_REGISTERED (ConstantRateWifiManager);
TypeId
@@ -94,22 +50,57 @@ ConstantRateWifiManager::ConstantRateWifiManager ()
ConstantRateWifiManager::~ConstantRateWifiManager ()
{}
WifiMode
ConstantRateWifiManager::GetDataMode (void) const
WifiRemoteStation *
ConstantRateWifiManager::DoCreateStation (void) const
{
WifiRemoteStation *station = new WifiRemoteStation ();
return station;
}
void
ConstantRateWifiManager::DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode)
{}
void
ConstantRateWifiManager::DoReportRtsFailed (WifiRemoteStation *station)
{}
void
ConstantRateWifiManager::DoReportDataFailed (WifiRemoteStation *station)
{}
void
ConstantRateWifiManager::DoReportRtsOk (WifiRemoteStation *st,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
}
void
ConstantRateWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
}
void
ConstantRateWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *station)
{}
void
ConstantRateWifiManager::DoReportFinalDataFailed (WifiRemoteStation *station)
{}
WifiMode
ConstantRateWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
{
return m_dataMode;
}
WifiMode
ConstantRateWifiManager::GetCtlMode (void) const
WifiMode
ConstantRateWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
return m_ctlMode;
}
WifiRemoteStation *
ConstantRateWifiManager::CreateStation (void)
bool
ConstantRateWifiManager::IsLowLatency (void) const
{
return new ConstantRateWifiRemoteStation (this);
return true;
}
} // namespace ns3

View File

@@ -39,38 +39,27 @@ public:
ConstantRateWifiManager ();
virtual ~ConstantRateWifiManager ();
WifiMode GetDataMode (void) const;
WifiMode GetCtlMode (void) const;
private:
virtual class WifiRemoteStation *CreateStation (void);
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool IsLowLatency (void) const;
WifiMode m_dataMode;
WifiMode m_ctlMode;
};
class ConstantRateWifiRemoteStation : public WifiRemoteStation
{
public:
ConstantRateWifiRemoteStation (Ptr<ConstantRateWifiManager> stations);
virtual ~ConstantRateWifiRemoteStation ();
protected:
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (void);
virtual void DoReportDataFailed (void);
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (void);
virtual void DoReportFinalDataFailed (void);
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
Ptr<ConstantRateWifiManager> m_manager;
};
} // namespace ns3

View File

@@ -225,18 +225,12 @@ DcaTxop::Queue (Ptr<const Packet> packet, const WifiMacHeader &hdr)
NS_LOG_FUNCTION (this << packet << &hdr);
WifiMacTrailer fcs;
uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
WifiRemoteStation *station = GetStation (hdr.GetAddr1 ());
station->PrepareForQueue (packet, fullPacketSize);
m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr,
packet, fullPacketSize);
m_queue->Enqueue (packet, hdr);
StartAccessIfNeeded ();
}
WifiRemoteStation *
DcaTxop::GetStation (Mac48Address ad) const
{
return m_stationManager->Lookup (ad);
}
void
DcaTxop::RestartAccessIfNeeded (void)
{
@@ -271,28 +265,28 @@ DcaTxop::Low (void)
bool
DcaTxop::NeedRts (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedRts (m_currentPacket);
return m_stationManager->NeedRts (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket);
}
bool
DcaTxop::NeedRtsRetransmission (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedRtsRetransmission (m_currentPacket);
return m_stationManager->NeedRtsRetransmission (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket);
}
bool
DcaTxop::NeedDataRetransmission (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedDataRetransmission (m_currentPacket);
return m_stationManager->NeedDataRetransmission (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket);
}
bool
DcaTxop::NeedFragmentation (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedFragmentation (m_currentPacket);
return m_stationManager->NeedFragmentation (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket);
}
void
@@ -304,28 +298,28 @@ DcaTxop::NextFragment (void)
uint32_t
DcaTxop::GetFragmentSize (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetFragmentSize (m_currentPacket, m_fragmentNumber);
return m_stationManager->GetFragmentSize (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket, m_fragmentNumber);
}
bool
DcaTxop::IsLastFragment (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->IsLastFragment (m_currentPacket, m_fragmentNumber);
return m_stationManager->IsLastFragment (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket, m_fragmentNumber);
}
uint32_t
DcaTxop::GetNextFragmentSize (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetFragmentSize (m_currentPacket, m_fragmentNumber + 1);
return m_stationManager->GetFragmentSize (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket, m_fragmentNumber + 1);
}
uint32_t
DcaTxop::GetFragmentOffset (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetFragmentOffset (m_currentPacket, m_fragmentNumber);
return m_stationManager->GetFragmentOffset (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket, m_fragmentNumber);
}
Ptr<Packet>
@@ -470,8 +464,7 @@ DcaTxop::MissedCts (void)
if (!NeedRtsRetransmission ())
{
MY_DEBUG ("Cts Fail");
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalRtsFailed ();
m_stationManager->ReportFinalRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
if (!m_txFailedCallback.IsNull ())
{
m_txFailedCallback (m_currentHdr);
@@ -521,8 +514,7 @@ DcaTxop::MissedAck (void)
if (!NeedDataRetransmission ())
{
MY_DEBUG ("Ack Fail");
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalDataFailed ();
m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
if (!m_txFailedCallback.IsNull ())
{
m_txFailedCallback (m_currentHdr);

View File

@@ -148,7 +148,6 @@ private:
uint32_t GetNextFragmentSize (void);
uint32_t GetFragmentSize (void);
uint32_t GetFragmentOffset (void);
WifiRemoteStation *GetStation (Mac48Address to) const;
bool IsLastFragment (void);
void NextFragment (void);
Ptr<Packet> GetFragmentPacket (WifiMacHeader *hdr);

View File

@@ -412,8 +412,7 @@ EdcaTxopN::MissedCts (void)
if (!NeedRtsRetransmission ())
{
MY_DEBUG ("Cts Fail");
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalRtsFailed ();
m_stationManager->ReportFinalRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
if (!m_txFailedCallback.IsNull ())
{
m_txFailedCallback (m_currentHdr);
@@ -443,8 +442,8 @@ EdcaTxopN::Queue (Ptr<const Packet> packet, const WifiMacHeader &hdr)
NS_LOG_FUNCTION (this << packet << &hdr);
WifiMacTrailer fcs;
uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
WifiRemoteStation *station = GetStation (hdr.GetAddr1 ());
station->PrepareForQueue (packet, fullPacketSize);
m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr,
packet, fullPacketSize);
m_queue->Enqueue (packet, hdr);
StartAccessIfNeeded ();
}
@@ -482,8 +481,7 @@ EdcaTxopN::MissedAck (void)
if (!NeedDataRetransmission ())
{
MY_DEBUG ("Ack Fail");
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalDataFailed ();
m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
if (!m_txFailedCallback.IsNull ())
{
m_txFailedCallback (m_currentHdr);
@@ -535,22 +533,22 @@ EdcaTxopN::StartAccessIfNeeded (void)
bool
EdcaTxopN::NeedRts (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedRts (m_currentPacket);
return m_stationManager->NeedRts (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket);
}
bool
EdcaTxopN::NeedRtsRetransmission (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedRtsRetransmission (m_currentPacket);
return m_stationManager->NeedRtsRetransmission (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket);
}
bool
EdcaTxopN::NeedDataRetransmission (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedDataRetransmission (m_currentPacket);
return m_stationManager->NeedDataRetransmission (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket);
}
void
@@ -593,42 +591,37 @@ EdcaTxopN::Cancel (void)
bool
EdcaTxopN::NeedFragmentation (void) const
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedFragmentation (m_currentPacket);
return m_stationManager->NeedFragmentation (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket);
}
uint32_t
EdcaTxopN::GetFragmentSize (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetFragmentSize (m_currentPacket, m_fragmentNumber);
return m_stationManager->GetFragmentSize (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket, m_fragmentNumber);
}
uint32_t
EdcaTxopN::GetNextFragmentSize (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetFragmentSize (m_currentPacket, m_fragmentNumber + 1);
return m_stationManager->GetFragmentSize (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket, m_fragmentNumber + 1);
}
uint32_t
EdcaTxopN::GetFragmentOffset (void)
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetFragmentOffset (m_currentPacket, m_fragmentNumber);
return m_stationManager->GetFragmentOffset (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket, m_fragmentNumber);
}
WifiRemoteStation *
EdcaTxopN::GetStation (Mac48Address ad) const
{
return m_stationManager->Lookup (ad);
}
bool
EdcaTxopN::IsLastFragment (void) const
{
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->IsLastFragment (m_currentPacket, m_fragmentNumber);
return m_stationManager->IsLastFragment (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket, m_fragmentNumber);
}
Ptr<Packet>

View File

@@ -123,7 +123,6 @@ public:
uint32_t GetNextFragmentSize (void);
uint32_t GetFragmentSize (void);
uint32_t GetFragmentOffset (void);
WifiRemoteStation *GetStation (Mac48Address to) const;
bool IsLastFragment (void) const;
void NextFragment (void);
Ptr<Packet> GetFragmentPacket (WifiMacHeader *hdr);

View File

@@ -25,6 +25,11 @@
namespace ns3 {
struct IdealWifiRemoteStation : public WifiRemoteStation
{
double m_lastSnr;
};
NS_OBJECT_ENSURE_REGISTERED (IdealWifiManager);
TypeId
@@ -60,12 +65,6 @@ IdealWifiManager::SetupPhy (Ptr<WifiPhy> phy)
WifiRemoteStationManager::SetupPhy (phy);
}
WifiRemoteStation *
IdealWifiManager::CreateStation (void)
{
return new IdealWifiRemoteStation (this);
}
double
IdealWifiManager::GetSnrThreshold (WifiMode mode) const
{
@@ -86,52 +85,61 @@ IdealWifiManager::AddModeSnrThreshold (WifiMode mode, double snr)
m_thresholds.push_back (std::make_pair (snr,mode));
}
IdealWifiRemoteStation::IdealWifiRemoteStation (Ptr<IdealWifiManager> manager)
: m_manager (manager),
m_lastSnr (0.0)
{}
IdealWifiRemoteStation::~IdealWifiRemoteStation ()
{}
void
IdealWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
{}
void
IdealWifiRemoteStation::DoReportRtsFailed (void)
{}
void
IdealWifiRemoteStation::DoReportDataFailed (void)
{}
void
IdealWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
WifiRemoteStation *
IdealWifiManager::DoCreateStation (void) const
{
m_lastSnr = rtsSnr;
IdealWifiRemoteStation *station = new IdealWifiRemoteStation ();
station->m_lastSnr = 0.0;
return station;
}
void
IdealWifiManager::DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode)
{}
void
IdealWifiManager::DoReportRtsFailed (WifiRemoteStation *station)
{}
void
IdealWifiManager::DoReportDataFailed (WifiRemoteStation *station)
{}
void
IdealWifiManager::DoReportRtsOk (WifiRemoteStation *st,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
station->m_lastSnr = rtsSnr;
}
void
IdealWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
IdealWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
m_lastSnr = dataSnr;
IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
station->m_lastSnr = dataSnr;
}
void
IdealWifiRemoteStation::DoReportFinalRtsFailed (void)
IdealWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *station)
{}
void
IdealWifiRemoteStation::DoReportFinalDataFailed (void)
IdealWifiManager::DoReportFinalDataFailed (WifiRemoteStation *station)
{}
WifiMode
IdealWifiRemoteStation::DoGetDataMode (uint32_t size)
IdealWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
{
IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
// We search within the Supported rate set the mode with the
// highest snr threshold possible which is smaller than m_lastSnr
// to ensure correct packet delivery.
double maxThreshold = 0.0;
WifiMode maxMode = m_manager->GetDefaultMode ();
for (uint32_t i = 0; i < GetNSupportedModes (); i++)
WifiMode maxMode = GetDefaultMode ();
for (uint32_t i = 0; i < GetNSupported (station); i++)
{
WifiMode mode = GetSupportedMode (i);
double threshold = m_manager->GetSnrThreshold (mode);
WifiMode mode = GetSupported (station, i);
double threshold = GetSnrThreshold (mode);
if (threshold > maxThreshold &&
threshold < m_lastSnr)
threshold < station->m_lastSnr)
{
maxThreshold = threshold;
maxMode = mode;
@@ -140,19 +148,20 @@ IdealWifiRemoteStation::DoGetDataMode (uint32_t size)
return maxMode;
}
WifiMode
IdealWifiRemoteStation::DoGetRtsMode (void)
IdealWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
// We search within the Basic rate set the mode with the highest
// snr threshold possible which is smaller than m_lastSnr to
// ensure correct packet delivery.
double maxThreshold = 0.0;
WifiMode maxMode = m_manager->GetDefaultMode ();
for (uint32_t i = 0; i < m_manager->GetNBasicModes (); i++)
WifiMode maxMode = GetDefaultMode ();
for (uint32_t i = 0; i < GetNBasicModes (); i++)
{
WifiMode mode = m_manager->GetBasicMode (i);
double threshold = m_manager->GetSnrThreshold (mode);
WifiMode mode = GetBasicMode (i);
double threshold = GetSnrThreshold (mode);
if (threshold > maxThreshold &&
threshold < m_lastSnr)
threshold < station->m_lastSnr)
{
maxThreshold = threshold;
maxMode = mode;
@@ -160,10 +169,11 @@ IdealWifiRemoteStation::DoGetRtsMode (void)
}
return maxMode;
}
Ptr<WifiRemoteStationManager>
IdealWifiRemoteStation::GetManager (void) const
bool
IdealWifiManager::IsLowLatency (void) const
{
return m_manager;
return true;
}
} // namespace ns3

View File

@@ -17,8 +17,8 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef IDEAL_MAC_STATIONS_H
#define IDEAL_MAC_STATIONS_H
#ifndef IDEAL_WIFI_MANAGER_H
#define IDEAL_WIFI_MANAGER_H
#include <stdint.h>
#include <vector>
@@ -50,12 +50,27 @@ public:
virtual void SetupPhy (Ptr<WifiPhy> phy);
private:
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool IsLowLatency (void) const;
// return the min snr needed to successfully transmit
// data with this mode at the specified ber.
double GetSnrThreshold (WifiMode mode) const;
void AddModeSnrThreshold (WifiMode mode, double ber);
private:
virtual class WifiRemoteStation *CreateStation (void);
typedef std::vector<std::pair<double,WifiMode> > Thresholds;
@@ -65,31 +80,6 @@ private:
double m_maxSnr;
};
class IdealWifiRemoteStation : public WifiRemoteStation
{
public:
IdealWifiRemoteStation (Ptr<IdealWifiManager> stations);
virtual ~IdealWifiRemoteStation ();
protected:
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (void);
virtual void DoReportDataFailed (void);
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (void);
virtual void DoReportFinalDataFailed (void);
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
virtual WifiMode DoGetDataMode (uint32_t size);
virtual WifiMode DoGetRtsMode (void);
Ptr<IdealWifiManager> m_manager;
double m_lastSnr;
};
} // namespace ns3
#endif /* MAC_STA_H */
#endif /* IDEAL_WIFI_MANAGER_H */

View File

@@ -24,6 +24,7 @@
#include "ns3/tag.h"
#include "ns3/log.h"
#include "ns3/node.h"
#include "ns3/double.h"
#include "mac-low.h"
#include "wifi-phy.h"
@@ -575,8 +576,8 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamb
{
NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
NS_ASSERT (m_sendCtsEvent.IsExpired ());
WifiRemoteStation *station = GetStation (hdr.GetAddr2 ());
station->ReportRxOk (rxSnr, txMode);
m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
rxSnr, txMode);
m_sendCtsEvent = Simulator::Schedule (GetSifs (),
&MacLow::SendCtsAfterRts, this,
hdr.GetAddr2 (),
@@ -597,9 +598,10 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamb
NS_LOG_DEBUG ("receive cts from="<<m_currentHdr.GetAddr1 ());
SnrTag tag;
packet->RemovePacketTag (tag);
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportRxOk (rxSnr, txMode);
station->ReportRtsOk (rxSnr, txMode, tag.Get ());
m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
rxSnr, txMode);
m_stationManager->ReportRtsOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
rxSnr, txMode, tag.Get ());
m_ctsTimeoutEvent.Cancel ();
NotifyCtsTimeoutResetNow ();
@@ -621,9 +623,10 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamb
NS_LOG_DEBUG ("receive ack from="<<m_currentHdr.GetAddr1 ());
SnrTag tag;
packet->RemovePacketTag (tag);
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportRxOk (rxSnr, txMode);
station->ReportDataOk (rxSnr, txMode, tag.Get ());
m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
rxSnr, txMode);
m_stationManager->ReportDataOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
rxSnr, txMode, tag.Get ());
bool gotAck = false;
if (m_txParams.MustWaitNormalAck () &&
m_normalAckTimeoutEvent.IsRunning ())
@@ -655,8 +658,8 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamb
}
else if (hdr.GetAddr1 () == m_self)
{
WifiRemoteStation *station = GetStation (hdr.GetAddr2 ());
station->ReportRxOk (rxSnr, txMode);
m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
rxSnr, txMode);
if (hdr.IsQosData () && hdr.IsQosNoAck ())
{
@@ -743,7 +746,7 @@ WifiMode
MacLow::GetRtsTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
{
Mac48Address to = hdr->GetAddr1 ();
return GetStation (to)->GetRtsMode (packet);
return m_stationManager->GetRtsMode (to, hdr, packet);
}
WifiMode
MacLow::GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
@@ -751,18 +754,18 @@ MacLow::GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
Mac48Address to = hdr->GetAddr1 ();
WifiMacTrailer fcs;
uint32_t size = packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
return GetStation (to)->GetDataMode (packet, size);
return m_stationManager->GetDataMode (to, hdr, packet, size);
}
WifiMode
MacLow::GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode) const
{
return GetStation (to)->GetCtsMode (rtsTxMode);
return m_stationManager->GetCtsMode (to, rtsTxMode);
}
WifiMode
MacLow::GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const
{
return GetStation (to)->GetAckMode (dataTxMode);
return m_stationManager->GetAckMode (to, dataTxMode);
}
@@ -937,8 +940,7 @@ MacLow::CtsTimeout (void)
// XXX: should check that there was no rx start before now.
// we should restart a new cts timeout now until the expected
// end of rx if there was a rx start before now.
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportRtsFailed ();
m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
m_currentPacket = 0;
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
@@ -952,8 +954,7 @@ MacLow::NormalAckTimeout (void)
// XXX: should check that there was no rx start before now.
// we should restart a new ack timeout now until the expected
// end of rx if there was a rx start before now.
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportDataFailed ();
m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
listener->MissedAck ();
@@ -962,8 +963,7 @@ void
MacLow::FastAckTimeout (void)
{
NS_LOG_FUNCTION (this);
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportDataFailed ();
m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
if (m_phy->IsStateIdle ())
@@ -980,8 +980,7 @@ void
MacLow::SuperFastAckTimeout ()
{
NS_LOG_FUNCTION (this);
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportDataFailed ();
m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
if (m_phy->IsStateIdle ())
@@ -1138,12 +1137,6 @@ MacLow::IsNavZero (void) const
}
}
WifiRemoteStation *
MacLow::GetStation (Mac48Address ad) const
{
return m_stationManager->Lookup (ad);
}
void
MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
{

View File

@@ -371,7 +371,6 @@ private:
uint32_t GetCtsSize (void) const;
uint32_t GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
Time NowUs (void) const;
WifiRemoteStation *GetStation (Mac48Address to) const;
void ForwardDown (Ptr<const Packet> packet, const WifiMacHeader *hdr,
WifiMode txMode);
Time CalculateOverallTxTime (Ptr<const Packet> packet,

View File

@@ -28,8 +28,6 @@
* http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/minstrel
*/
#include "minstrel-wifi-manager.h"
#include "wifi-phy.h"
#include "ns3/random-variable.h"
@@ -46,6 +44,83 @@ NS_LOG_COMPONENT_DEFINE ("MinstrelWifiManager");
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
* going row by row from 1st column until the 10th column(Minstrel defines 10)
* then we wrap back to the row 1 col 1.
* note: there are many other ways to do this.
*/
uint32_t m_col, m_index;
uint32_t m_maxTpRate; ///< the current throughput rate
uint32_t m_maxTpRate2; ///< second highest throughput rate
uint32_t m_maxProbRate; ///< rate with highest prob of success
int m_packetCount; ///< total number of packets as of now
int m_sampleCount; ///< how many packets we have sample so far
bool m_isSampling; ///< a flag to indicate we are currently sampling
uint32_t m_sampleRate; ///< current sample rate
bool m_sampleRateSlower; ///< a flag to indicate sample rate is slower
uint32_t m_currentRate; ///< current rate we are using
uint32_t m_shortRetry; ///< short retries such as control packts
uint32_t m_longRetry; ///< long retries such as data packets
uint32_t m_retry; ///< total retries short + long
uint32_t m_err; ///< retry errors
uint32_t m_txrate; ///< current transmit rate
bool m_initialized; ///< for initializing tables
};
NS_OBJECT_ENSURE_REGISTERED (MinstrelWifiManager);
TypeId
@@ -106,12 +181,6 @@ MinstrelWifiManager::SetupPhy (Ptr<WifiPhy> phy)
WifiRemoteStationManager::SetupPhy (phy);
}
WifiRemoteStation *
MinstrelWifiManager::CreateStation (void)
{
return new MinstrelWifiRemoteStation (this);
}
Time
MinstrelWifiManager::GetCalcTxTime (WifiMode mode) const
{
@@ -130,113 +199,139 @@ MinstrelWifiManager::GetCalcTxTime (WifiMode mode) const
void
MinstrelWifiManager::AddCalcTxTime (WifiMode mode, Time t)
{
m_calcTxTime.push_back (std::make_pair (t, mode));
m_calcTxTime.push_back (std::make_pair (t, mode));
}
MinstrelWifiRemoteStation::MinstrelWifiRemoteStation (Ptr<MinstrelWifiManager> stations)
:m_stations (stations),
m_nextStatsUpdate (Simulator::Now () + stations->m_updateStats),
m_col (0),
m_index (0),
m_maxTpRate (0),
m_maxTpRate2 (0),
m_maxProbRate (0),
m_packetCount (0),
m_sampleCount (0),
m_isSampling (false),
m_sampleRate (0),
m_sampleRateSlower (false),
m_currentRate (0),
m_shortRetry (0),
m_longRetry (0),
m_retry (0),
m_err (0),
m_txrate (0),
m_initialized (false)
{}
WifiRemoteStation *
MinstrelWifiManager::DoCreateStation (void) const
{
MinstrelWifiRemoteStation *station = new MinstrelWifiRemoteStation ();
MinstrelWifiRemoteStation::~MinstrelWifiRemoteStation ()
{}
station->m_nextStatsUpdate = Simulator::Now () + m_updateStats;
station->m_col = 0;
station->m_index = 0;
station->m_maxTpRate = 0;
station->m_maxTpRate2 = 0;
station->m_maxProbRate = 0;
station->m_packetCount = 0;
station->m_sampleCount = 0;
station->m_isSampling = false;
station->m_sampleRate = 0;
station->m_sampleRateSlower = false;
station->m_currentRate = 0;
station->m_shortRetry = 0;
station->m_longRetry = 0;
station->m_retry = 0;
station->m_err = 0;
station->m_txrate = 0;
station->m_initialized = false;
return station;
}
void
MinstrelWifiRemoteStation::CheckInit(void)
MinstrelWifiManager::CheckInit(MinstrelWifiRemoteStation *station)
{
if (!m_initialized)
if (!station->m_initialized)
{
m_minstrelTable = MinstrelRate(GetNSupportedModes ());
m_sampleTable = SampleRate(GetNSupportedModes (), std::vector<uint32_t> (m_stations->m_sampleCol));
InitSampleTable ();
RateInit ();
m_initialized = true;
// 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));
InitSampleTable (station);
RateInit (station);
station->m_initialized = true;
}
}
void
MinstrelWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
MinstrelWifiManager::DoReportRxOk (WifiRemoteStation *st,
double rxSnr, WifiMode txMode)
{
NS_LOG_DEBUG("DoReportRxOk m_txrate=" << m_txrate);
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *)st;
NS_LOG_DEBUG("DoReportRxOk m_txrate=" << station->m_txrate);
}
void
MinstrelWifiRemoteStation::DoReportRtsFailed (void)
MinstrelWifiManager::DoReportRtsFailed (WifiRemoteStation *st)
{
NS_LOG_DEBUG("DoReportRtsFailed m_txrate=" << m_txrate);
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *)st;
NS_LOG_DEBUG("DoReportRtsFailed m_txrate=" << station->m_txrate);
m_shortRetry++;
station->m_shortRetry++;
}
void
MinstrelWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
MinstrelWifiManager::DoReportRtsOk (WifiRemoteStation *st, double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("self="<<this<<" rts ok");
NS_LOG_DEBUG ("self="<<st<<" rts ok");
}
void
MinstrelWifiRemoteStation::DoReportFinalRtsFailed (void)
MinstrelWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *st)
{
UpdateRetry ();
m_err++;
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *)st;
UpdateRetry (station);
station->m_err++;
}
void
MinstrelWifiRemoteStation::DoReportDataFailed (void)
MinstrelWifiManager::DoReportDataFailed (WifiRemoteStation *st)
{
CheckInit();
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *)st;
/**
*
* Retry Chain table is implemented here
*
* Try | LOOKAROUND RATE | NORMAL RATE
* | random < best | random > best |
* --------------------------------------------------------------
* 1 | Best throughput | Random rate | Best throughput
* 2 | Random rate | Best throughput | Next best throughput
* 3 | Best probability | Best probability | Best probability
* 4 | Lowest Baserate | Lowest baserate | Lowest baserate
*
* Note: For clarity, multiple blocks of if's and else's are used
* After a failing 7 times, DoReportFinalDataFailed will be called
*/
m_longRetry++;
CheckInit(station);
NS_LOG_DEBUG ("DoReportDataFailed " << this << "\t rate " << m_txrate << "\tlongRetry \t" << m_longRetry);
station->m_longRetry++;
NS_LOG_DEBUG ("DoReportDataFailed " << station << "\t rate " << station->m_txrate << "\tlongRetry \t" << station->m_longRetry);
/// for normal rate, we're not currently sampling random rates
if (!m_isSampling)
if (!station->m_isSampling)
{
/// use best throughput rate
if( m_longRetry < m_minstrelTable[m_txrate].adjustedRetryCount)
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
{
; ///< there's still a few retries left
}
/// use second best throughput rate
else if (m_longRetry <= (m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_maxTpRate].adjustedRetryCount))
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
{
m_txrate = m_maxTpRate2;
station->m_txrate = station->m_maxTpRate2;
}
/// use best probability rate
else if (m_longRetry <= (m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_maxTpRate2].adjustedRetryCount +
m_minstrelTable[m_maxTpRate].adjustedRetryCount))
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))
{
m_txrate = m_maxProbRate;
station->m_txrate = station->m_maxProbRate;
}
/// use lowest base rate
else if (m_longRetry > (m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_maxTpRate2].adjustedRetryCount +
m_minstrelTable[m_maxTpRate].adjustedRetryCount))
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))
{
m_txrate = 0;
station->m_txrate = 0;
}
}
@@ -244,35 +339,35 @@ MinstrelWifiRemoteStation::DoReportDataFailed (void)
else
{
/// current sampling rate is slower than the current best rate
if (m_sampleRateSlower)
if (station->m_sampleRateSlower)
{
/// use best throughput rate
if (m_longRetry < m_minstrelTable[m_txrate].adjustedRetryCount)
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
{
; ///< there are a few retries left
}
/// use random rate
else if (m_longRetry <= (m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_maxTpRate].adjustedRetryCount))
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
{
m_txrate = m_sampleRate;
station->m_txrate = station->m_sampleRate;
}
/// use max probability rate
else if (m_longRetry <= (m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_sampleRate].adjustedRetryCount +
m_minstrelTable[m_maxTpRate].adjustedRetryCount ))
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 ))
{
m_txrate = m_maxProbRate;
station->m_txrate = station->m_maxProbRate;
}
/// use lowest base rate
else if (m_longRetry > (m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_sampleRate].adjustedRetryCount +
m_minstrelTable[m_maxTpRate].adjustedRetryCount))
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))
{
m_txrate = 0;
station->m_txrate = 0;
}
}
@@ -280,140 +375,146 @@ MinstrelWifiRemoteStation::DoReportDataFailed (void)
else
{
/// use random rate
if (m_longRetry < m_minstrelTable[m_txrate].adjustedRetryCount)
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
{
; ///< keep using it
}
/// use the best rate
else if (m_longRetry <= m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_sampleRate].adjustedRetryCount)
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
{
m_txrate = m_maxTpRate;
station->m_txrate = station->m_maxTpRate;
}
/// use the best probability rate
else if (m_longRetry <= m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_maxTpRate].adjustedRetryCount +
m_minstrelTable[m_sampleRate].adjustedRetryCount)
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))
{
m_txrate = m_maxProbRate;
station->m_txrate = station->m_maxProbRate;
}
/// use the lowest base rate
else if (m_longRetry > m_minstrelTable[m_txrate].adjustedRetryCount +
m_minstrelTable[m_maxTpRate].adjustedRetryCount +
m_minstrelTable[m_sampleRate].adjustedRetryCount)
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))
{
m_txrate = 0;
station->m_txrate = 0;
}
}
}
}
void
MinstrelWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
MinstrelWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
m_isSampling = false;
m_sampleRateSlower=false;
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st;
CheckInit ();
station->m_isSampling = false;
station->m_sampleRateSlower=false;
m_minstrelTable[m_txrate].numRateSuccess++;
m_minstrelTable[m_txrate].numRateAttempt++;
CheckInit (station);
station->m_minstrelTable[station->m_txrate].numRateSuccess++;
station->m_minstrelTable[station->m_txrate].numRateAttempt++;
UpdateRetry ();
UpdateRetry (station);
m_minstrelTable[m_txrate].numRateAttempt += m_retry;
m_packetCount++;
station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
station->m_packetCount++;
if (GetNSupportedModes () >= 1)
if (GetNSupported (station) >= 1)
{
m_txrate = FindRate ();
station->m_txrate = FindRate (station);
}
}
void
MinstrelWifiRemoteStation::DoReportFinalDataFailed (void)
MinstrelWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st)
{
NS_LOG_DEBUG ("DoReportFinalDataFailed m_txrate=" << m_txrate);
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st;
NS_LOG_DEBUG ("DoReportFinalDataFailed m_txrate=" << station->m_txrate);
m_isSampling = false;
m_sampleRateSlower=false;
station->m_isSampling = false;
station->m_sampleRateSlower=false;
UpdateRetry ();
UpdateRetry (station);
m_minstrelTable[m_txrate].numRateAttempt += m_retry;
m_err++;
station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
station->m_err++;
if (GetNSupportedModes () >= 1)
if (GetNSupported (station) >= 1)
{
m_txrate = FindRate ();
station->m_txrate = FindRate (station);
}
}
void
MinstrelWifiRemoteStation::UpdateRetry (void)
MinstrelWifiManager::UpdateRetry (MinstrelWifiRemoteStation *station)
{
m_retry = m_shortRetry + m_longRetry;
m_shortRetry = 0;
m_longRetry = 0;
}
Ptr<WifiRemoteStationManager>
MinstrelWifiRemoteStation::GetManager (void) const
{
return m_stations;
station->m_retry = station->m_shortRetry + station->m_longRetry;
station->m_shortRetry = 0;
station->m_longRetry = 0;
}
WifiMode
MinstrelWifiRemoteStation::DoGetDataMode (uint32_t size)
MinstrelWifiManager::DoGetDataMode (WifiRemoteStation *st,
uint32_t size)
{
if (!m_initialized)
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st;
if (!station->m_initialized)
{
CheckInit ();
CheckInit (station);
/// start the rate at half way
m_txrate = GetNSupportedModes () / 2;
station->m_txrate = GetNSupported (station) / 2;
}
UpdateStats ();
return GetSupportedMode (m_txrate);
UpdateStats (station);
return GetSupported (station, station->m_txrate);
}
WifiMode
MinstrelWifiRemoteStation::DoGetRtsMode (void)
MinstrelWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
NS_LOG_DEBUG ("DoGetRtsMode m_txrate=" << m_txrate);
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st;
NS_LOG_DEBUG ("DoGetRtsMode m_txrate=" << station->m_txrate);
return GetSupportedMode (0);
return GetSupported (station, 0);
}
bool
MinstrelWifiManager::IsLowLatency (void) const
{
return false;
}
uint32_t
MinstrelWifiRemoteStation::GetNextSample ()
MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station)
{
uint32_t bitrate;
bitrate = m_sampleTable[m_index][m_col];
m_index++;
bitrate = station->m_sampleTable[station->m_index][station->m_col];
station->m_index++;
/// bookeeping for m_index and m_col variables
if (m_index > (GetNSupportedModes () -2))
if (station->m_index > (GetNSupported (station) - 2))
{
m_index =0;
m_col++;
if (m_col >= m_stations->m_sampleCol)
station->m_index =0;
station->m_col++;
if (station->m_col >= m_sampleCol)
{
m_col = 0;
station->m_col = 0;
}
}
return bitrate;
}
uint32_t
MinstrelWifiRemoteStation::FindRate ()
MinstrelWifiManager::FindRate (MinstrelWifiRemoteStation *station)
{
NS_LOG_DEBUG ("FindRate " << "packet=" << m_packetCount );
NS_LOG_DEBUG ("FindRate " << "packet=" << station->m_packetCount );
if ((m_sampleCount + m_packetCount) == 0)
if ((station->m_sampleCount + station->m_packetCount) == 0)
{
return 0;
}
@@ -429,55 +530,56 @@ MinstrelWifiRemoteStation::FindRate ()
* note: do it randomly by flipping a coin instead sampling
* all at once until it reaches the look around rate
*/
if ( (((100* m_sampleCount) / (m_sampleCount + m_packetCount )) < m_stations->m_lookAroundRate) &&
((int)coinFlip.GetValue ()) % 2 == 1 )
if ( (((100* station->m_sampleCount) / (station->m_sampleCount + station->m_packetCount )) < m_lookAroundRate) &&
((int)coinFlip.GetValue ()) % 2 == 1 )
{
/// now go through the table and find an index rate
idx = GetNextSample();
idx = GetNextSample(station);
/**
* This if condition is used to make sure that we don't need to use
* the sample rate it is the same as our current rate
*/
if (idx != m_maxTpRate && idx != m_txrate)
if (idx != station->m_maxTpRate && idx != station->m_txrate)
{
/// start sample count
m_sampleCount++;
station->m_sampleCount++;
/// set flag that we are currently sampling
m_isSampling = true;
station->m_isSampling = true;
/// bookeeping for resetting stuff
if (m_packetCount >= 10000)
if (station->m_packetCount >= 10000)
{
m_sampleCount = 0;
m_packetCount = 0;
station->m_sampleCount = 0;
station->m_packetCount = 0;
}
/// error check
if (idx >= GetNSupportedModes () || idx < 0 )
if (idx >= GetNSupported (station) || idx < 0)
{
NS_LOG_DEBUG ("ALERT!!! ERROR");
}
/// set the rate that we're currently sampling
m_sampleRate = idx;
station->m_sampleRate = idx;
if (m_sampleRate == m_maxTpRate)
if (station->m_sampleRate == station->m_maxTpRate)
{
m_sampleRate = m_maxTpRate2;
station->m_sampleRate = station->m_maxTpRate2;
}
/// is this rate slower than the current best rate
m_sampleRateSlower = (m_minstrelTable[idx].perfectTxTime > m_minstrelTable[m_maxTpRate].perfectTxTime);
station->m_sampleRateSlower =
(station->m_minstrelTable[idx].perfectTxTime > station->m_minstrelTable[station->m_maxTpRate].perfectTxTime);
/// using the best rate instead
if (m_sampleRateSlower)
if (station->m_sampleRateSlower)
{
idx = m_maxTpRate;
idx = station->m_maxTpRate;
}
}
@@ -486,7 +588,7 @@ MinstrelWifiRemoteStation::FindRate ()
/// continue using the best rate
else
{
idx = m_maxTpRate;
idx = station->m_maxTpRate;
}
@@ -496,25 +598,25 @@ MinstrelWifiRemoteStation::FindRate ()
}
void
MinstrelWifiRemoteStation::UpdateStats ()
MinstrelWifiManager::UpdateStats (MinstrelWifiRemoteStation *station)
{
if (Simulator::Now () < m_nextStatsUpdate)
if (Simulator::Now () < station->m_nextStatsUpdate)
{
return;
}
NS_LOG_DEBUG ("Updating stats="<<this);
m_nextStatsUpdate = Simulator::Now () + m_stations->m_updateStats;
station->m_nextStatsUpdate = Simulator::Now () + m_updateStats;
Time txTime;
uint32_t tempProb;
for (uint32_t i =0; i < GetNSupportedModes (); i++)
for (uint32_t i =0; i < GetNSupported (station); i++)
{
/// calculate the perfect tx time for this rate
txTime = m_minstrelTable[i].perfectTxTime;
txTime = station->m_minstrelTable[i].perfectTxTime;
/// just for initialization
if (txTime.GetMicroSeconds () == 0)
@@ -522,60 +624,62 @@ MinstrelWifiRemoteStation::UpdateStats ()
txTime = Seconds (1);
}
NS_LOG_DEBUG ("m_txrate=" << m_txrate << "\t attempt=" << m_minstrelTable[i].numRateAttempt << "\t success=" << m_minstrelTable[i].numRateSuccess);
NS_LOG_DEBUG ("m_txrate=" << station->m_txrate <<
"\t attempt=" << station->m_minstrelTable[i].numRateAttempt <<
"\t success=" << station->m_minstrelTable[i].numRateSuccess);
/// if we've attempted something
if (m_minstrelTable[i].numRateAttempt)
if (station->m_minstrelTable[i].numRateAttempt)
{
/**
* calculate the probability of success
* assume probability scales from 0 to 18000
*/
tempProb = (m_minstrelTable[i].numRateSuccess * 18000) / m_minstrelTable[i].numRateAttempt;
tempProb = (station->m_minstrelTable[i].numRateSuccess * 18000) / station->m_minstrelTable[i].numRateAttempt;
/// bookeeping
m_minstrelTable[i].successHist += m_minstrelTable[i].numRateSuccess;
m_minstrelTable[i].attemptHist += m_minstrelTable[i].numRateAttempt;
m_minstrelTable[i].prob = tempProb;
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;
/// ewma probability (cast for gcc 3.4 compatibility)
tempProb = static_cast<uint32_t>(((tempProb * (100 - m_stations->m_ewmaLevel)) + (m_minstrelTable[i].ewmaProb * m_stations->m_ewmaLevel) )/100);
tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (station->m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100);
m_minstrelTable[i].ewmaProb = tempProb;
station->m_minstrelTable[i].ewmaProb = tempProb;
/// calculating throughput
m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds());
station->m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds());
}
/// bookeeping
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;
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;
/// Sample less often below 10% and above 95% of success
if ((m_minstrelTable[i].ewmaProb > 17100) || (m_minstrelTable[i].ewmaProb < 1800))
if ((station->m_minstrelTable[i].ewmaProb > 17100) || (station->m_minstrelTable[i].ewmaProb < 1800))
{
/**
* retry count denotes the number of retries permitted for each rate
* # retry_count/2
*/
m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount >> 1;
if (m_minstrelTable[i].adjustedRetryCount > 2)
station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount >> 1;
if (station->m_minstrelTable[i].adjustedRetryCount > 2)
{
m_minstrelTable[i].adjustedRetryCount = 2 ;
station->m_minstrelTable[i].adjustedRetryCount = 2 ;
}
}
else
{
m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount;
station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount;
}
/// if it's 0 allow one retry limit
if (m_minstrelTable[i].adjustedRetryCount == 0)
if (station->m_minstrelTable[i].adjustedRetryCount == 0)
{
m_minstrelTable[i].adjustedRetryCount = 1;
station->m_minstrelTable[i].adjustedRetryCount = 1;
}
}
@@ -583,85 +687,86 @@ MinstrelWifiRemoteStation::UpdateStats ()
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 < GetNSupportedModes (); i++)
for (uint32_t i =0; i < GetNSupported (station); i++)
{
NS_LOG_DEBUG ("throughput" << m_minstrelTable[i].throughput << "\n ewma" << m_minstrelTable[i].ewmaProb);
NS_LOG_DEBUG ("throughput" << station->m_minstrelTable[i].throughput <<
"\n ewma" << station->m_minstrelTable[i].ewmaProb);
if (max_tp < m_minstrelTable[i].throughput)
if (max_tp < station->m_minstrelTable[i].throughput)
{
index_max_tp = i;
max_tp = m_minstrelTable[i].throughput;
max_tp = station->m_minstrelTable[i].throughput;
}
if (max_prob < m_minstrelTable[i].ewmaProb)
if (max_prob < station->m_minstrelTable[i].ewmaProb)
{
index_max_prob = i;
max_prob = m_minstrelTable[i].ewmaProb;
max_prob = station->m_minstrelTable[i].ewmaProb;
}
}
max_tp = 0;
/// find the second highest max
for (uint32_t i =0; i < GetNSupportedModes (); i++)
for (uint32_t i =0; i < GetNSupported (station); i++)
{
if ((i != index_max_tp) && (max_tp < m_minstrelTable[i].throughput))
if ((i != index_max_tp) && (max_tp < station->m_minstrelTable[i].throughput))
{
index_max_tp2 = i;
max_tp = m_minstrelTable[i].throughput;
max_tp = station->m_minstrelTable[i].throughput;
}
}
m_maxTpRate = index_max_tp;
m_maxTpRate2 = index_max_tp2;
m_maxProbRate = index_max_prob;
m_currentRate = index_max_tp;
station->m_maxTpRate = index_max_tp;
station->m_maxTpRate2 = index_max_tp2;
station->m_maxProbRate = index_max_prob;
station->m_currentRate = index_max_tp;
if (index_max_tp > m_txrate)
if (index_max_tp > station->m_txrate)
{
m_txrate= index_max_tp;
station->m_txrate = index_max_tp;
}
NS_LOG_DEBUG ("max tp="<< index_max_tp << "\nmax tp2="<< index_max_tp2<< "\nmax prob="<< index_max_prob);
/// reset it
RateInit ();
RateInit (station);
}
void
MinstrelWifiRemoteStation::RateInit ()
MinstrelWifiManager::RateInit (MinstrelWifiRemoteStation *station)
{
NS_LOG_DEBUG ("RateInit="<<this);
NS_LOG_DEBUG ("RateInit="<<station);
for (uint32_t i = 0; i < GetNSupportedModes (); i++)
for (uint32_t i = 0; i < GetNSupported (station); i++)
{
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 = m_stations->GetCalcTxTime (GetSupportedMode (i));
m_minstrelTable[i].retryCount =1;
m_minstrelTable[i].adjustedRetryCount =1;
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;
}
}
void
MinstrelWifiRemoteStation::InitSampleTable ()
MinstrelWifiManager::InitSampleTable (MinstrelWifiRemoteStation *station)
{
NS_LOG_DEBUG ("InitSampleTable="<<this);
m_col = m_index = 0;
station->m_col = station->m_index = 0;
/// for off-seting to make rates fall between 0 and numrates
uint32_t numSampleRates= GetNSupportedModes () - 1;
uint32_t numSampleRates = GetNSupported (station);
uint32_t newIndex;
for (uint32_t col = 0; col < m_stations->m_sampleCol; col++)
for (uint32_t col = 0; col < m_sampleCol; col++)
{
for (uint32_t i = 0; i < numSampleRates; i++ )
{
@@ -674,40 +779,40 @@ MinstrelWifiRemoteStation::InitSampleTable ()
newIndex = (i + (uint32_t)uv.GetValue ()) % numSampleRates;
/// this loop is used for filling in other uninitilized places
while (m_sampleTable[newIndex][col] != 0)
while (station->m_sampleTable[newIndex][col] != 0)
{
newIndex = (newIndex + 1)%GetNSupportedModes ();
newIndex = (newIndex + 1)%GetNSupported (station);
}
m_sampleTable[newIndex][col] = i+1;
station->m_sampleTable[newIndex][col] = i+1;
}
}
}
void
MinstrelWifiRemoteStation::PrintSampleTable ()
MinstrelWifiManager::PrintSampleTable (MinstrelWifiRemoteStation *station)
{
NS_LOG_DEBUG ("PrintSampleTable="<<this );
NS_LOG_DEBUG ("PrintSampleTable="<<station);
uint32_t numSampleRates= GetNSupportedModes ();
for (uint32_t i=0; i < numSampleRates; i++)
uint32_t numSampleRates = GetNSupported (station);
for (uint32_t i = 0; i < numSampleRates; i++)
{
for (uint32_t j=0; j < m_stations->m_sampleCol; j++)
for (uint32_t j = 0; j < m_sampleCol; j++)
{
std::cout << m_sampleTable[i][j] << "\t";
std::cout << station->m_sampleTable[i][j] << "\t";
}
std::cout << std::endl;
}
}
void
MinstrelWifiRemoteStation::PrintTable ()
MinstrelWifiManager::PrintTable (MinstrelWifiRemoteStation *station)
{
NS_LOG_DEBUG ("PrintTable="<<this);
NS_LOG_DEBUG ("PrintTable="<<station);
for (uint32_t i=0; i < GetNSupportedModes (); i++)
for (uint32_t i=0; i < GetNSupported (station); i++)
{
std::cout << "index(" << i << ") = " << m_minstrelTable[i].perfectTxTime<< "\n";
std::cout << "index(" << i << ") = " << station->m_minstrelTable[i].perfectTxTime<< "\n";
}
}

View File

@@ -28,8 +28,6 @@
#include "ns3/nstime.h"
#include <vector>
/**
* \author Duy Nguyen
* \brief Implementation of Minstrel Rate Control Algorithm
@@ -41,49 +39,7 @@
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;
class MinstrelWifiRemoteStation;
class MinstrelWifiManager : public WifiRemoteStationManager
@@ -96,13 +52,53 @@ public:
virtual void SetupPhy (Ptr<WifiPhy> phy);
private:
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool IsLowLatency (void) const;
/// for estimating the TxTime of a packet with a given mode
Time GetCalcTxTime (WifiMode mode) const;
void AddCalcTxTime (WifiMode mode, Time t);
private:
friend class MinstrelWifiRemoteStation;
virtual class WifiRemoteStation *CreateStation (void);
/// update the number of retries and reset accordingly
void UpdateRetry (MinstrelWifiRemoteStation *station);
/// getting the next sample from Sample Table
uint32_t GetNextSample (MinstrelWifiRemoteStation *station);
/// find a rate to use from Minstrel Table
uint32_t FindRate (MinstrelWifiRemoteStation *station);
/// updating the Minstrel Table every 1/10 seconds
void UpdateStats (MinstrelWifiRemoteStation *station);
/// initialize Minstrel Table
void RateInit (MinstrelWifiRemoteStation *station);
/// initialize Sample Table
void InitSampleTable (MinstrelWifiRemoteStation *station);
/// printing Sample Table
void PrintSampleTable (MinstrelWifiRemoteStation *station);
/// printing Minstrel Table
void PrintTable (MinstrelWifiRemoteStation *station);
void CheckInit (MinstrelWifiRemoteStation *station); ///< check for initializations
typedef std::vector<std::pair<Time,WifiMode> > TxTime;
@@ -112,144 +108,9 @@ private:
double m_ewmaLevel; ///< exponential weighted moving average
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_pktLen; ///< packet length used for calculate mode TxTime
};
class MinstrelWifiRemoteStation : public WifiRemoteStation
{
public:
MinstrelWifiRemoteStation (Ptr<MinstrelWifiManager> stations);
virtual ~MinstrelWifiRemoteStation ();
protected:
/**
* when packet is successfully received
* see wifi-remote-station-manager.h for more documentation
*/
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
/// when RTS timeout expires
virtual void DoReportRtsFailed (void);
/**
*
* Retry Chain table is implemented here
*
* Try | LOOKAROUND RATE | NORMAL RATE
* | random < best | random > best |
* --------------------------------------------------------------
* 1 | Best throughput | Random rate | Best throughput
* 2 | Random rate | Best throughput | Next best throughput
* 3 | Best probability | Best probability | Best probability
* 4 | Lowest Baserate | Lowest baserate | Lowest baserate
*
* Note: For clarity, multiple blocks of if's and else's are used
* After a failing 7 times, DoReportFinalDataFailed will be called
*/
virtual void DoReportDataFailed (void);
/// when receive a CTS, associated with an RTS
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
/// when an ACK, associated with a data pkt, is received
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
/// after calling ReportRtsFailed if NeedRtsRetransmission returns false
virtual void DoReportFinalRtsFailed (void);
/// after calling ReportDataFailed if NeedDataRetransmission returns false
virtual void DoReportFinalDataFailed (void);
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
/**
* returns the transmission mode for sending this packet
* this function gets called when node is getting ready to send DATA
* see wifi-remote-station-manager.h for more documentation
*/
virtual WifiMode DoGetDataMode (uint32_t size);
/// returns the transmission mode for sending RTS packet
virtual WifiMode DoGetRtsMode (void);
/// update the number of retries and reset accordingly
void UpdateRetry (void);
/// getting the next sample from Sample Table
uint32_t GetNextSample (void);
/// find a rate to use from Minstrel Table
uint32_t FindRate (void);
/// updating the Minstrel Table every 1/10 seconds
void UpdateStats (void);
/// initialize Minstrel Table
void RateInit (void);
/// initialize Sample Table
void InitSampleTable (void);
/// printing Sample Table
void PrintSampleTable (void);
/// printing Minstrel Table
void PrintTable (void);
/**
* \param packet lenghth
* \param current WifiMode
* \returns calcuated transmit duration
*/
Time CalcRatePacket (uint32_t, WifiMode);
void CheckInit(void); ///< check for initializations
Ptr<MinstrelWifiManager> m_stations;
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
* going row by row from 1st column until the 10th column(Minstrel defines 10)
* then we wrap back to the row 1 col 1.
* note: there are many other ways to do this.
*/
uint32_t m_col, m_index;
uint32_t m_maxTpRate; ///< the current throughput rate
uint32_t m_maxTpRate2; ///< second highest throughput rate
uint32_t m_maxProbRate; ///< rate with highest prob of success
int m_packetCount; ///< total number of packets as of now
int m_sampleCount; ///< how many packets we have sample so far
bool m_isSampling; ///< a flag to indicate we are currently sampling
uint32_t m_sampleRate; ///< current sample rate
bool m_sampleRateSlower; ///< a flag to indicate sample rate is slower
uint32_t m_currentRate; ///< current rate we are using
uint32_t m_shortRetry; ///< short retries such as control packts
uint32_t m_longRetry; ///< long retries such as data packets
uint32_t m_retry; ///< total retries short + long
uint32_t m_err; ///< retry errors
uint32_t m_txrate; ///< current transmit rate
bool m_initialized; ///< for initializing tables
};
}// namespace ns3
#endif /* MINSTREL_WIFI_MANAGER_H */

View File

@@ -21,6 +21,7 @@
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/node.h"
#include "ns3/boolean.h"
#include "nqap-wifi-mac.h"
#include "dca-txop.h"
@@ -416,24 +417,22 @@ void
NqapWifiMac::TxOk (const WifiMacHeader &hdr)
{
NS_LOG_FUNCTION (this);
WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
if (hdr.IsAssocResp () &&
station->IsWaitAssocTxOk ())
m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
{
NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ());
station->RecordGotAssocTxOk ();
m_stationManager->RecordGotAssocTxOk (hdr.GetAddr1 ());
}
}
void
NqapWifiMac::TxFailed (const WifiMacHeader &hdr)
{
NS_LOG_FUNCTION (this);
WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
if (hdr.IsAssocResp () &&
station->IsWaitAssocTxOk ())
m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
{
NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ());
station->RecordGotAssocTxFailed ();
m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
}
}
void
@@ -442,7 +441,6 @@ NqapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
NS_LOG_FUNCTION (this << packet << hdr);
Mac48Address from = hdr->GetAddr2 ();
WifiRemoteStation *fromStation = m_stationManager->Lookup (from);
if (hdr->IsData ())
{
@@ -450,17 +448,16 @@ NqapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
if (!hdr->IsFromDs () &&
hdr->IsToDs () &&
bssid == GetAddress () &&
fromStation->IsAssociated ())
m_stationManager->IsAssociated (from))
{
Mac48Address to = hdr->GetAddr3 ();
WifiRemoteStation *toStation = m_stationManager->Lookup (to);
if (to == GetAddress ())
{
NS_LOG_DEBUG ("frame for me from="<<from);
ForwardUp (packet, from, bssid);
}
else if (to.IsGroup () ||
toStation->IsAssociated ())
m_stationManager->IsAssociated (to))
{
NS_LOG_DEBUG ("forwarding frame from="<<from<<", to="<<to);
Ptr<Packet> copy = packet->Copy ();
@@ -530,17 +527,17 @@ NqapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
WifiMode mode = m_phy->GetMode (j);
if (rates.IsSupportedRate (mode.GetDataRate ()))
{
fromStation->AddSupportedMode (mode);
m_stationManager->AddSupportedMode (from, mode);
}
}
fromStation->RecordWaitAssocTxOk ();
m_stationManager->RecordWaitAssocTxOk (from);
// send assoc response with success status.
SendAssocResp (hdr->GetAddr2 (), true);
}
}
else if (hdr->IsDisassociation ())
{
fromStation->RecordDisassociated ();
m_stationManager->RecordDisassociated (from);
}
else if (hdr->IsReassocReq ())
{

View File

@@ -24,6 +24,7 @@
#include "ns3/log.h"
#include "ns3/node.h"
#include "ns3/uinteger.h"
#include "ns3/boolean.h"
#include "ns3/trace-source-accessor.h"
#include "nqsta-wifi-mac.h"
@@ -609,13 +610,12 @@ NqstaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
SetState (ASSOCIATED);
NS_LOG_DEBUG ("assoc completed");
SupportedRates rates = assocResp.GetSupportedRates ();
WifiRemoteStation *ap = m_stationManager->Lookup (hdr->GetAddr2 ());
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
WifiMode mode = m_phy->GetMode (i);
if (rates.IsSupportedRate (mode.GetDataRate ()))
{
ap->AddSupportedMode (mode);
m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
if (rates.IsBasicRate (mode.GetDataRate ()))
{
m_stationManager->AddBasicMode (mode);

View File

@@ -27,6 +27,19 @@ NS_LOG_COMPONENT_DEFINE ("OnoeWifiRemoteStation");
namespace ns3 {
struct OnoeWifiRemoteStation : public WifiRemoteStation
{
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;
};
NS_OBJECT_ENSURE_REGISTERED (OnoeWifiManager);
TypeId
@@ -55,74 +68,76 @@ OnoeWifiManager::GetTypeId (void)
OnoeWifiManager::OnoeWifiManager ()
{}
WifiRemoteStation *
OnoeWifiManager::CreateStation (void)
OnoeWifiManager::DoCreateStation (void) const
{
return new OnoeWifiRemoteStation (this);
OnoeWifiRemoteStation *station = new OnoeWifiRemoteStation ();
station->m_nextModeUpdate = Simulator::Now () + m_updatePeriod;
station->m_shortRetry = 0;
station->m_longRetry = 0;
station->m_tx_ok = 0;
station->m_tx_err = 0;
station->m_tx_retr = 0;
station->m_tx_upper = 0;
station->m_txrate = 0;
return station;
}
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::DoReportRxOk (double rxSnr, WifiMode txMode)
OnoeWifiManager::DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode)
{}
void
OnoeWifiRemoteStation::DoReportRtsFailed (void)
OnoeWifiManager::DoReportRtsFailed (WifiRemoteStation *st)
{
m_shortRetry++;
OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
station->m_shortRetry++;
}
void
OnoeWifiRemoteStation::DoReportDataFailed (void)
OnoeWifiManager::DoReportDataFailed (WifiRemoteStation *st)
{
m_longRetry++;
OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
station->m_longRetry++;
}
void
OnoeWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
OnoeWifiManager::DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{}
void
OnoeWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
OnoeWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
UpdateRetry ();
m_tx_ok++;
OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
UpdateRetry (station);
station->m_tx_ok++;
}
void
OnoeWifiRemoteStation::DoReportFinalRtsFailed (void)
OnoeWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *st)
{
UpdateRetry ();
m_tx_err++;
OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
UpdateRetry (station);
station->m_tx_err++;
}
void
OnoeWifiRemoteStation::DoReportFinalDataFailed (void)
OnoeWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st)
{
UpdateRetry ();
m_tx_err++;
OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
UpdateRetry (station);
station->m_tx_err++;
}
void
OnoeWifiRemoteStation::UpdateRetry (void)
OnoeWifiManager::UpdateRetry (OnoeWifiRemoteStation *station)
{
m_tx_retr += m_shortRetry + m_longRetry;
m_shortRetry = 0;
m_longRetry = 0;
station->m_tx_retr += station->m_shortRetry + station->m_longRetry;
station->m_shortRetry = 0;
station->m_longRetry = 0;
}
void
OnoeWifiRemoteStation::UpdateMode (void)
OnoeWifiManager::UpdateMode (OnoeWifiRemoteStation *station)
{
if (Simulator::Now () < m_nextModeUpdate)
if (Simulator::Now () < station->m_nextModeUpdate)
{
return;
}
m_nextModeUpdate = Simulator::Now () + m_stations->m_updatePeriod;
station->m_nextModeUpdate = Simulator::Now () + m_updatePeriod;
/**
* The following 20 lines of code were copied from the Onoe
* rate control kernel module used in the madwifi driver.
@@ -130,112 +145,116 @@ OnoeWifiRemoteStation::UpdateMode (void)
int dir = 0, enough;
uint32_t nrate;
enough = (m_tx_ok + m_tx_err >= 10);
enough = (station->m_tx_ok + station->m_tx_err >= 10);
/* no packet reached -> down */
if (m_tx_err > 0 && m_tx_ok == 0)
if (station->m_tx_err > 0 && station->m_tx_ok == 0)
dir = -1;
/* all packets needs retry in average -> down */
if (enough && m_tx_ok < m_tx_retr)
if (enough && station->m_tx_ok < station->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)
if (enough && station->m_tx_err == 0 &&
station->m_tx_retr < (station->m_tx_ok * 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);
NS_LOG_DEBUG (this << " ok " << station->m_tx_ok << " err " << station->m_tx_err << " retr " << station->m_tx_retr <<
" upper " << station->m_tx_upper << " dir " << dir);
nrate = m_txrate;
nrate = station->m_txrate;
switch (dir) {
case 0:
if (enough && m_tx_upper > 0)
m_tx_upper--;
if (enough && station->m_tx_upper > 0)
station->m_tx_upper--;
break;
case -1:
if (nrate > 0) {
nrate--;
}
m_tx_upper = 0;
station->m_tx_upper = 0;
break;
case 1:
/* raise rate if we hit rate_raise_threshold */
if (++m_tx_upper < m_stations->m_raiseThreshold)
if (++station->m_tx_upper < m_raiseThreshold)
break;
m_tx_upper = 0;
if (nrate + 1 < GetNSupportedModes ()) {
station->m_tx_upper = 0;
if (nrate + 1 < GetNSupported (station)) {
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;
if (nrate != station->m_txrate) {
NS_ASSERT (nrate < GetNSupported (station));
station->m_txrate = nrate;
station->m_tx_ok = station->m_tx_err = station->m_tx_retr = station->m_tx_upper = 0;
} else if (enough)
m_tx_ok = m_tx_err = m_tx_retr = 0;
station->m_tx_ok = station->m_tx_err = station->m_tx_retr = 0;
}
Ptr<WifiRemoteStationManager>
OnoeWifiRemoteStation::GetManager (void) const
{
return m_stations;
}
WifiMode
OnoeWifiRemoteStation::DoGetDataMode (uint32_t size)
OnoeWifiManager::DoGetDataMode (WifiRemoteStation *st,
uint32_t size)
{
UpdateMode ();
NS_ASSERT (m_txrate < GetNSupportedModes ());
OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
UpdateMode (station);
NS_ASSERT (station->m_txrate < GetNSupported (station));
uint32_t rateIndex;
if (m_longRetry < 4)
if (station->m_longRetry < 4)
{
rateIndex = m_txrate;
rateIndex = station->m_txrate;
}
else if (m_longRetry < 6)
else if (station->m_longRetry < 6)
{
if (m_txrate > 0)
if (station->m_txrate > 0)
{
rateIndex = m_txrate - 1;
rateIndex = station->m_txrate - 1;
}
else
{
rateIndex = m_txrate;
rateIndex = station->m_txrate;
}
}
else if (m_longRetry < 8)
else if (station->m_longRetry < 8)
{
if (m_txrate > 1)
if (station->m_txrate > 1)
{
rateIndex = m_txrate - 2;
rateIndex = station->m_txrate - 2;
}
else
{
rateIndex = m_txrate;
rateIndex = station->m_txrate;
}
}
else
{
if (m_txrate > 2)
if (station->m_txrate > 2)
{
rateIndex = m_txrate - 3;
rateIndex = station->m_txrate - 3;
}
else
{
rateIndex = m_txrate;
rateIndex = station->m_txrate;
}
}
return GetSupportedMode (rateIndex);
return GetSupported (station, rateIndex);
}
WifiMode
OnoeWifiRemoteStation::DoGetRtsMode (void)
OnoeWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
UpdateMode ();
OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
UpdateMode (station);
// XXX: can we implement something smarter ?
return GetSupportedMode (0);
return GetSupported (station, 0);
}
bool
OnoeWifiManager::IsLowLatency (void) const
{
return false;
}
} // namespace ns3

View File

@@ -25,6 +25,8 @@
namespace ns3 {
class OnoeWifiRemoteStation;
/**
* \brief an implementation of rate control algorithm developed
* by Atsushi Onoe
@@ -42,49 +44,30 @@ public:
OnoeWifiManager ();
private:
friend class OnoeWifiRemoteStation;
virtual WifiRemoteStation *CreateStation (void);
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool IsLowLatency (void) const;
void UpdateRetry (OnoeWifiRemoteStation *station);
void UpdateMode (OnoeWifiRemoteStation *station);
Time m_updatePeriod;
uint32_t m_addCreditThreshold;
uint32_t m_raiseThreshold;
};
class OnoeWifiRemoteStation : public WifiRemoteStation
{
public:
OnoeWifiRemoteStation (Ptr<OnoeWifiManager> stations);
virtual ~OnoeWifiRemoteStation ();
protected:
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (void);
virtual void DoReportDataFailed (void);
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (void);
virtual void DoReportFinalDataFailed (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

@@ -23,6 +23,7 @@
#include "ns3/config.h"
#include "ns3/string.h"
#include "ns3/uinteger.h"
#include "ns3/double.h"
#include "ns3/data-rate.h"
#include "ns3/inet-socket-address.h"
#include "ns3/internet-stack-helper.h"

View File

@@ -243,16 +243,15 @@ QadhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
hdr.SetDsNotFrom ();
hdr.SetDsNotTo ();
WifiRemoteStation *destination = m_stationManager->Lookup (to);
if (destination->IsBrandNew ())
if (m_stationManager->IsBrandNew (to))
{
// in adhoc mode, we assume that every destination
// supports all the rates we support.
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
destination->AddSupportedMode (m_phy->GetMode (i));
m_stationManager->AddSupportedMode (to, m_phy->GetMode (i));
}
destination->RecordDisassociated ();
m_stationManager->RecordDisassociated (to);
}
uint8_t tid = QosUtilsGetTidForPacket (packet);

View File

@@ -24,6 +24,7 @@
#include "ns3/simulator.h"
#include "ns3/string.h"
#include "ns3/pointer.h"
#include "ns3/boolean.h"
#include "qos-tag.h"
#include "qap-wifi-mac.h"
@@ -529,12 +530,11 @@ void
QapWifiMac::TxOk (const WifiMacHeader &hdr)
{
NS_LOG_FUNCTION (this);
WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
if (hdr.IsAssocResp () &&
station->IsWaitAssocTxOk ())
m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
{
NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ());
station->RecordGotAssocTxOk ();
m_stationManager->RecordGotAssocTxOk (hdr.GetAddr1 ());
}
}
@@ -542,12 +542,11 @@ void
QapWifiMac::TxFailed (const WifiMacHeader &hdr)
{
NS_LOG_FUNCTION (this);
WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
if (hdr.IsAssocResp () &&
station->IsWaitAssocTxOk ())
m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
{
NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ());
station->RecordGotAssocTxFailed ();
m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
}
}
@@ -557,7 +556,6 @@ QapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
NS_LOG_FUNCTION (this << packet << hdr);
Mac48Address from = hdr->GetAddr2 ();
WifiRemoteStation *fromStation = m_stationManager->Lookup (from);
if (hdr->IsData ())
{
@@ -565,10 +563,9 @@ QapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
if (!hdr->IsFromDs () &&
hdr->IsToDs () &&
bssid == GetAddress () &&
fromStation->IsAssociated ())
m_stationManager->IsAssociated (from))
{
Mac48Address to = hdr->GetAddr3 ();
WifiRemoteStation *toStation = m_stationManager->Lookup (to);
if (to == GetAddress ())
{
@@ -592,7 +589,7 @@ QapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
}
}
else if (to.IsGroup () ||
toStation->IsAssociated ())
m_stationManager->IsAssociated (to))
{
NS_LOG_DEBUG ("forwarding frame from="<<from<<", to="<<to);
Ptr<Packet> copy = packet->Copy ();
@@ -658,17 +655,17 @@ QapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
WifiMode mode = m_phy->GetMode (j);
if (rates.IsSupportedRate (mode.GetDataRate ()))
{
fromStation->AddSupportedMode (mode);
m_stationManager->AddSupportedMode (from, mode);
}
}
fromStation->RecordWaitAssocTxOk ();
// send assoc response with success status.
SendAssocResp (hdr->GetAddr2 (), true);
}
}
m_stationManager->RecordWaitAssocTxOk (from);
// send assoc response with success status.
SendAssocResp (hdr->GetAddr2 (), true);
}
}
else if (hdr->IsDisassociation ())
{
fromStation->RecordDisassociated ();
m_stationManager->RecordDisassociated (from);
}
else if (hdr->IsReassocReq ())
{

View File

@@ -23,6 +23,7 @@
#include "ns3/simulator.h"
#include "ns3/string.h"
#include "ns3/pointer.h"
#include "ns3/boolean.h"
#include "qos-tag.h"
#include "edca-txop-n.h"
@@ -649,13 +650,12 @@ QstaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
m_state = ASSOCIATED;
NS_LOG_DEBUG ("assoc completed");
SupportedRates rates = assocResp.GetSupportedRates ();
WifiRemoteStation *ap = m_stationManager->Lookup (hdr->GetAddr2 ());
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
WifiMode mode = m_phy->GetMode (i);
if (rates.IsSupportedRate (mode.GetDataRate ()))
{
ap->AddSupportedMode (mode);
m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
if (rates.IsBasicRate (mode.GetDataRate ()))
{
m_stationManager->AddBasicMode (mode);

View File

@@ -30,162 +30,21 @@ NS_LOG_COMPONENT_DEFINE ("RraaWifiManager");
namespace ns3 {
struct RraaWifiRemoteStation : public WifiRemoteStation
{
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;
};
NS_OBJECT_ENSURE_REGISTERED(RraaWifiManager);
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::DoReportRtsFailed (void)
{}
void
RraaWifiRemoteStation::DoReportDataFailed (void)
{
m_lastFrameFail = true;
CheckTimeout ();
m_counter--;
m_failed++;
RunBasicAlgorithm ();
}
void
RraaWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
{}
void
RraaWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("self="<<this<<" rts ok");
}
void
RraaWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
{
m_lastFrameFail = false;
CheckTimeout ();
m_counter--;
RunBasicAlgorithm ();
}
void
RraaWifiRemoteStation::DoReportFinalRtsFailed (void)
{}
void
RraaWifiRemoteStation::DoReportFinalDataFailed (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)
@@ -323,87 +182,251 @@ RraaWifiManager::RraaWifiManager ()
RraaWifiManager::~RraaWifiManager ()
{}
WifiRemoteStation *
RraaWifiManager::CreateStation (void)
RraaWifiManager::DoCreateStation (void) const
{
return new RraaWifiRemoteStation (this);
RraaWifiRemoteStation *station = new RraaWifiRemoteStation ();
station->m_initialized = false;
station->m_rtsWnd = 0;
station->m_rtsCounter = 0;
station->m_rtsOn = false;
station->m_lastFrameFail = false;
return station;
}
void
RraaWifiManager::ResetCountersBasic (RraaWifiRemoteStation *station)
{
if (!station->m_initialized)
{
station->m_rate = GetMaxRate (station);
station->m_initialized = true;
}
station->m_failed = 0;
station->m_counter = GetThresholds (station, station->m_rate).ewnd;
station->m_lastReset = Simulator::Now ();
}
uint32_t
RraaWifiManager::GetMaxRate (RraaWifiRemoteStation *station)
{
return GetNSupported (station) - 1;
}
uint32_t
RraaWifiManager::GetMinRate (RraaWifiRemoteStation *station)
{
return 0;
}
void
RraaWifiManager::DoReportRtsFailed (WifiRemoteStation *st)
{}
void
RraaWifiManager::DoReportDataFailed (WifiRemoteStation *st)
{
RraaWifiRemoteStation *station = (RraaWifiRemoteStation *) st;
station->m_lastFrameFail = true;
CheckTimeout (station);
station->m_counter--;
station->m_failed++;
RunBasicAlgorithm (station);
}
void
RraaWifiManager::DoReportRxOk (WifiRemoteStation *st,
double rxSnr, WifiMode txMode)
{}
void
RraaWifiManager::DoReportRtsOk (WifiRemoteStation *st,
double ctsSnr, WifiMode ctsMode, double rtsSnr)
{
NS_LOG_DEBUG ("self="<<st<<" rts ok");
}
void
RraaWifiManager::DoReportDataOk (WifiRemoteStation *st,
double ackSnr, WifiMode ackMode, double dataSnr)
{
RraaWifiRemoteStation *station = (RraaWifiRemoteStation *) st;
station->m_lastFrameFail = false;
CheckTimeout (station);
station->m_counter--;
RunBasicAlgorithm (station);
}
void
RraaWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *st)
{}
void
RraaWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st)
{}
WifiMode
RraaWifiManager::DoGetDataMode (WifiRemoteStation *st,
uint32_t size)
{
RraaWifiRemoteStation *station = (RraaWifiRemoteStation *) st;
if (!station->m_initialized)
{
ResetCountersBasic (station);
}
return GetSupported (station, station->m_rate);
}
WifiMode
RraaWifiManager::DoGetRtsMode (WifiRemoteStation *st)
{
return GetSupported (st, 0);
}
bool
RraaWifiManager::OnlyBasic (void)
RraaWifiManager::DoNeedRts (WifiRemoteStation *st,
Ptr<const Packet> packet, bool normally)
{
return m_basic;
RraaWifiRemoteStation *station = (RraaWifiRemoteStation *) st;
if (m_basic)
{
return normally;
}
ARts (station);
return station->m_rtsOn;
}
Time
RraaWifiManager::GetTimeout (void) const
void
RraaWifiManager::CheckTimeout (RraaWifiRemoteStation *station)
{
return m_timeout;
Time d = Simulator::Now () - station->m_lastReset;
if (station->m_counter == 0 || d > m_timeout)
{
ResetCountersBasic (station);
}
}
ThresholdsItem
void
RraaWifiManager::RunBasicAlgorithm (RraaWifiRemoteStation *station)
{
ThresholdsItem thresholds = GetThresholds (station, station->m_rate);
double ploss = (double) station->m_failed / (double) thresholds.ewnd;
if (station->m_counter == 0 ||
ploss > thresholds.pmtl)
{
if (station->m_rate > GetMinRate (station) &&
ploss > thresholds.pmtl)
{
station->m_rate--;
}
else if (station->m_rate < GetMaxRate (station) &&
ploss < thresholds.pori)
{
station->m_rate++;
}
ResetCountersBasic (station);
}
}
void
RraaWifiManager::ARts (RraaWifiRemoteStation *station)
{
if (!station->m_rtsOn &&
station->m_lastFrameFail)
{
station->m_rtsWnd++;
station->m_rtsCounter = station->m_rtsWnd;
}
else if ((station->m_rtsOn && station->m_lastFrameFail) ||
(!station->m_rtsOn && !station->m_lastFrameFail))
{
station->m_rtsWnd = station->m_rtsWnd / 2;
station->m_rtsCounter = station->m_rtsWnd;
}
if (station->m_rtsCounter > 0)
{
station->m_rtsOn = true;
station->m_rtsCounter--;
}
else
{
station->m_rtsOn = false;
}
}
struct RraaWifiManager::ThresholdsItem
RraaWifiManager::GetThresholds (RraaWifiRemoteStation *station,
uint32_t rate) const
{
WifiMode mode = GetSupported (station, rate);
return GetThresholds (mode);
}
struct RraaWifiManager::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;
}
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_MSG(false, "Thresholds for an unknown mode are asked");
return ThresholdsItem ();
}
bool
RraaWifiManager::IsLowLatency (void) const
{
return true;
}
} // namespace ns3

View File

@@ -25,14 +25,7 @@
namespace ns3 {
struct ThresholdsItem {
uint32_t datarate;
double pori;
double pmtl;
uint32_t ewnd;
};
typedef std::vector<ThresholdsItem> Thresholds;
class RraaWifiRemoteStation;
/**
* \brief Robust Rate Adaptation Algorithm
@@ -49,11 +42,44 @@ public:
RraaWifiManager ();
virtual ~RraaWifiManager ();
bool OnlyBasic (void);
Time GetTimeout (void) const;
ThresholdsItem GetThresholds (WifiMode mode) const;
private:
virtual class WifiRemoteStation *CreateStation (void);
struct ThresholdsItem
{
uint32_t datarate;
double pori;
double pmtl;
uint32_t ewnd;
};
// overriden from base class
virtual class WifiRemoteStation *DoCreateStation (void) const;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (WifiRemoteStation *station);
virtual void DoReportDataFailed (WifiRemoteStation *station);
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
virtual bool DoNeedRts (WifiRemoteStation *st,
Ptr<const Packet> packet, bool normally);
virtual bool IsLowLatency (void) const;
uint32_t GetMaxRate (RraaWifiRemoteStation *station);
uint32_t GetMinRate (RraaWifiRemoteStation *station);
void CheckTimeout (RraaWifiRemoteStation *station);
void RunBasicAlgorithm (RraaWifiRemoteStation *station);
void ARts (RraaWifiRemoteStation *station);
void ResetCountersBasic (RraaWifiRemoteStation *station);
struct ThresholdsItem GetThresholds (WifiMode mode) const;
struct ThresholdsItem GetThresholds (RraaWifiRemoteStation *station, uint32_t rate) const;
bool m_basic;
Time m_timeout;
uint32_t m_ewndfor54;
@@ -80,49 +106,6 @@ private:
double m_pmtlfor9;
};
class RraaWifiRemoteStation : public WifiRemoteStation
{
public:
RraaWifiRemoteStation (Ptr<RraaWifiManager> stations);
virtual ~RraaWifiRemoteStation ();
virtual bool NeedRts (Ptr<const Packet> packet);
protected:
virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
virtual void DoReportRtsFailed (void);
virtual void DoReportDataFailed (void);
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
virtual void DoReportFinalRtsFailed (void);
virtual void DoReportFinalDataFailed (void);
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 */

File diff suppressed because it is too large Load Diff

View File

@@ -23,16 +23,17 @@
#include <vector>
#include <utility>
#include "ns3/mac48-address.h"
#include "ns3/traced-callback.h"
#include "ns3/packet.h"
#include "ns3/object.h"
#include "ns3/traced-value.h"
#include "wifi-mode.h"
namespace ns3 {
class WifiRemoteStation;
class NonUnicastWifiRemoteStation;
class WifiRemoteStationState;
class WifiPhy;
class WifiMacHeader;
/**
* \brief hold a list of per-remote-station state.
@@ -78,112 +79,14 @@ public:
BasicModesIterator BeginBasicModes (void) const;
BasicModesIterator EndBasicModes (void) const;
bool IsLowLatency (void) const;
WifiMode GetNonUnicastMode (void) const;
WifiRemoteStation *Lookup (Mac48Address address);
WifiRemoteStation *LookupNonUnicast (void);
protected:
friend class WifiRemoteStation;
virtual void DoDispose (void);
private:
typedef std::vector <WifiRemoteStation *> Stations;
virtual class WifiRemoteStation *CreateStation (void) = 0;
Stations m_stations;
WifiMode m_defaultTxMode;
NonUnicastWifiRemoteStation *m_nonUnicast;
BasicModes m_basicModes;
bool m_isLowLatency;
uint32_t m_maxSsrc;
uint32_t m_maxSlrc;
uint32_t m_rtsCtsThreshold;
uint32_t m_fragmentationThreshold;
WifiMode m_nonUnicastMode;
/**
* Public method used to fire a MacTxRtsFailed trace.
* Implemented for encapsulation purposes.
*/
void NotifyTxRtsFailed (Mac48Address address);
/**
* Public method used to fire a MacTxDataFailed trace.
* Implemented for encapsulation purposes.
*/
void NotifyTxDataFailed (Mac48Address address);
/**
* Public method used to fire a MacTxFinalRtsFailed trace.
* Implemented for encapsulation purposes.
*/
void NotifyTxFinalRtsFailed (Mac48Address address);
/**
* Public method used to fire a MacTxFinalDataFailed trace.
* Implemented for encapsulation purposes.
*/
void NotifyTxFinalDataFailed (Mac48Address address);
/**
* The trace source fired when the transmission of a RTS has failed
*
* \see class CallBackTraceSource
*/
TracedCallback<Mac48Address> m_macTxRtsFailed;
/**
* The trace source fired when the transmission of a data packet has failed
*
* \see class CallBackTraceSource
*/
TracedCallback<Mac48Address> m_macTxDataFailed;
/**
* The trace source fired when the transmission of a RTS has
* exceeded the maximum number of attempts
*
* \see class CallBackTraceSource
*/
TracedCallback<Mac48Address> m_macTxFinalRtsFailed;
/**
* The trace source fired when the transmission of a data packet has
* exceeded the maximum number of attempts
*
* \see class CallBackTraceSource
*/
TracedCallback<Mac48Address> m_macTxFinalDataFailed;
};
} // namespace ns3
namespace ns3 {
/**
* \brief hold per-remote-station state.
*
* The state in this class is used to keep track
* of association status if we are in an infrastructure
* network and to perform the selection of tx parameters
* on a per-packet basis.
*/
class WifiRemoteStation {
public:
static TypeId GetTypeId (void);
WifiRemoteStation ();
virtual ~WifiRemoteStation ();
/**
* Invoked in an AP upon disassociation of a
* specific STA.
*/
void Reset (void);
void Reset (Mac48Address address);
/**
* Invoked in a STA or AP to store the set of
* modes supported by a destination which is
@@ -191,15 +94,15 @@ public:
* The set of supported modes includes
* the BSSBasicRateSet.
*/
void AddSupportedMode (WifiMode mode);
void AddSupportedMode (Mac48Address address, WifiMode mode);
bool IsBrandNew (void) const;
bool IsAssociated (void) const;
bool IsWaitAssocTxOk (void) const;
void RecordWaitAssocTxOk (void);
void RecordGotAssocTxOk (void);
void RecordGotAssocTxFailed (void);
void RecordDisassociated (void);
bool IsBrandNew (Mac48Address address) const;
bool IsAssociated (Mac48Address address) const;
bool IsWaitAssocTxOk (Mac48Address address) const;
void RecordWaitAssocTxOk (Mac48Address address);
void RecordGotAssocTxOk (Mac48Address address);
void RecordGotAssocTxFailed (Mac48Address address);
void RecordDisassociated (Mac48Address address);
/**
* \param packet the packet to queue
@@ -210,49 +113,54 @@ public:
* is set to false, in which case, the tx parameters of the packet are calculated and stored in
* the packet as a tag. These tx parameters are later retrieved from GetDadaMode and GetRtsMode.
*/
void PrepareForQueue (Ptr<const Packet> packet, uint32_t fullPacketSize);
void PrepareForQueue (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet, uint32_t fullPacketSize);
/**
* \param packet the packet to send
* \param fullPacketSize the size of the packet after its 802.11 MAC header has been added.
* \returns the transmission mode to use to send this packet
*/
WifiMode GetDataMode (Ptr<const Packet> packet, uint32_t fullPacketSize);
WifiMode GetDataMode (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet, uint32_t fullPacketSize);
/**
* \param packet the packet to send
* \returns the transmission mode to use to send the RTS prior to the
* transmission of the data packet itself.
*/
WifiMode GetRtsMode (Ptr<const Packet> packet);
WifiMode GetRtsMode (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet);
/**
* Should be invoked whenever the RtsTimeout associated to a transmission
* attempt expires.
*/
void ReportRtsFailed (void);
void ReportRtsFailed (Mac48Address address, const WifiMacHeader *header);
/**
* Should be invoked whenever the AckTimeout associated to a transmission
* attempt expires.
*/
void ReportDataFailed (void);
void ReportDataFailed (Mac48Address address, const WifiMacHeader *header);
/**
* Should be invoked whenever we receive the Cts associated to an RTS
* we just sent.
*/
void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
void ReportRtsOk (Mac48Address address, const WifiMacHeader *header,
double ctsSnr, WifiMode ctsMode, double rtsSnr);
/**
* Should be invoked whenever we receive the Ack associated to a data packet
* we just sent.
*/
void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
void ReportDataOk (Mac48Address address, const WifiMacHeader *header,
double ackSnr, WifiMode ackMode, double dataSnr);
/**
* Should be invoked after calling ReportRtsFailed if
* NeedRtsRetransmission returns false
*/
void ReportFinalRtsFailed (void);
void ReportFinalRtsFailed (Mac48Address address, const WifiMacHeader *header);
/**
* Should be invoked after calling ReportDataFailed if
* NeedDataRetransmission returns false
*/
void ReportFinalDataFailed (void);
void ReportFinalDataFailed (Mac48Address address, const WifiMacHeader *header);
/**
* \param rxSnr the snr of the packet received
@@ -260,112 +168,246 @@ public:
*
* Should be invoked whenever a packet is successfully received.
*/
void ReportRxOk (double rxSnr, WifiMode txMode);
void ReportRxOk (Mac48Address address, const WifiMacHeader *header,
double rxSnr, WifiMode txMode);
/**
* \param packet the packet to send
* \returns true if we want to use an RTS/CTS handshake for this
* packet before sending it, false otherwise.
*/
virtual bool NeedRts (Ptr<const Packet> packet);
bool NeedRts (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet);
/**
* \param packet the packet to send
* \returns true if we want to restart a failed RTS/CTS
* handshake, false otherwise.
*/
virtual bool NeedRtsRetransmission (Ptr<const Packet> packet);
bool NeedRtsRetransmission (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet);
/**
* \param packet the packet to send
* \returns true if we want to resend a packet
* after a failed transmission attempt, false otherwise.
*/
virtual bool NeedDataRetransmission (Ptr<const Packet> packet);
bool NeedDataRetransmission (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet);
/**
* \param packet the packet to send
* \returns true if this packet should be fragmented, false otherwise.
*/
virtual bool NeedFragmentation (Ptr<const Packet> packet);
bool NeedFragmentation (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet);
/**
* \param packet the packet to send
* \param fragmentNumber the fragment index of the next fragment to send (starts at zero).
* \returns the size of the corresponding fragment.
*/
virtual uint32_t GetFragmentSize (Ptr<const Packet> packet, uint32_t fragmentNumber);
uint32_t GetFragmentSize (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet, uint32_t fragmentNumber);
/**
* \param packet the packet to send
* \param fragmentNumber the fragment index of the next fragment to send (starts at zero).
* \returns the offset within the original packet where this fragment starts.
*/
virtual uint32_t GetFragmentOffset (Ptr<const Packet> packet, uint32_t fragmentNumber);
uint32_t GetFragmentOffset (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet, uint32_t fragmentNumber);
/**
* \param packet the packet to send
* \param fragmentNumber the fragment index of the next fragment to send (starts at zero).
* \returns true if this is the last fragment, false otherwise.
*/
virtual bool IsLastFragment (Ptr<const Packet> packet, uint32_t fragmentNumber);
bool IsLastFragment (Mac48Address address, const WifiMacHeader *header,
Ptr<const Packet> packet, uint32_t fragmentNumber);
/**
* \param rtsMode the transmission mode used to send an RTS we just received
* \returns the transmission mode to use for the CTS to complete the RTS/CTS
* handshake.
*/
WifiMode GetCtsMode (WifiMode rtsMode);
WifiMode GetCtsMode (Mac48Address address, WifiMode rtsMode);
/**
* \param dataMode the transmission mode used to send an ACK we just received
* \returns the transmission mode to use for the ACK to complete the data/ACK
* handshake.
*/
WifiMode GetAckMode (WifiMode dataMode);
WifiMode GetAckMode (Mac48Address address, WifiMode dataMode);
/**
* \return exponentially weighted average SLRC, this is used by Airtime link metric of 802.11s
*/
double GetAvgSlrc () const;
/**
* set the address of the remote stationt represented by this instance of WifiRemoteStation
*
* @param address the MAC address of the remote station
*/
void SetAddress(Mac48Address address);
/**
* get the address of the remote stationt represented by this instance of WifiRemoteStation
*
* @return the MAC address of the remote station
*/
Mac48Address GetAddress();
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const = 0;
virtual WifiMode DoGetDataMode (uint32_t size) = 0;
virtual WifiMode DoGetRtsMode (void) = 0;
virtual void DoReportRtsFailed (void) = 0;
virtual void DoReportDataFailed (void) = 0;
virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr) = 0;
virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr) = 0;
virtual void DoReportFinalRtsFailed (void) = 0;
virtual void DoReportFinalDataFailed (void) = 0;
virtual void DoReportRxOk (double rxSnr, WifiMode txMode) = 0;
double GetAvgSlrc (Mac48Address address) const;
protected:
uint32_t GetNSupportedModes (void) const;
WifiMode GetSupportedMode (uint32_t i) const;
virtual void DoDispose (void);
// for convenience
WifiMode GetSupported (const WifiRemoteStation *station, uint32_t i) const;
uint32_t GetNSupported (const WifiRemoteStation *station) const;
private:
typedef std::vector<WifiMode> SupportedModes;
/**
* \param station the station with which we need to communicate
* \param packet the packet to send
* \param normally indicates whether the normal 802.11 rts enable mechanism would
* request that the rts is sent or not.
* \returns true if we want to use an RTS/CTS handshake for this
* packet before sending it, false otherwise.
*
* Note: This method is called before a unicast packet is sent on the medium.
*/
virtual bool DoNeedRts (WifiRemoteStation *station,
Ptr<const Packet> packet, bool normally);
/**
* \param station the station with which we need to communicate
* \param packet the packet to send
* \param normally indicates whether the normal 802.11 rts enable mechanism would
* request that the rts is retransmitted or not.
* \returns true if we want to restart a failed RTS/CTS
* handshake, false otherwise.
*
* Note: This method is called after an rts/cts handshake has been attempted
* and has failed.
*/
virtual bool DoNeedRtsRetransmission (WifiRemoteStation *station,
Ptr<const Packet> packet, bool normally);
/**
* \param station the station with which we need to communicate
* \param packet the packet to send
* \param normally indicates whether the normal 802.11 data retransmission mechanism
* would request that the data is retransmitted or not.
* \returns true if we want to resend a packet
* after a failed transmission attempt, false otherwise.
*
* Note: This method is called after a unicast packet transmission has been attempted
* and has failed.
*/
virtual bool DoNeedDataRetransmission (WifiRemoteStation *station,
Ptr<const Packet> packet, bool normally);
/**
* \param station the station with which we need to communicate
* \param packet the packet to send
* \param normally indicates whether the normal 802.11 data fragmentation mechanism
* would request that the data packet is fragmented or not.
* \returns true if this packet should be fragmented, false otherwise.
*
* Note: This method is called before sending a unicast packet.
*/
virtual bool DoNeedFragmentation (WifiRemoteStation *station,
Ptr<const Packet> packet, bool normally);
/**
* \returns whether this manager is a manager designed to work in low-latency
* environments.
*
* Note: In this context, low vs high latency is defined in <i>IEEE 802.11 Rate Adaptation:
* A Practical Approach</i>, by M. Lacage, M.H. Manshaei, and T. Turletti.
*/
virtual bool IsLowLatency (void) const = 0;
/**
* \return a new station data structure
*/
virtual class WifiRemoteStation *DoCreateStation (void) const = 0;
/**
* \param station the station with which we need to communicate
* \param size size of the packet or fragment we want to send
* \returns the transmission mode to use to send a packet to the station
*
* Note: This method is called before sending a unicast packet or a fragment
* of a unicast packet to decide which transmission mode to use.
*/
virtual WifiMode DoGetDataMode (WifiRemoteStation *station,
uint32_t size) = 0;
/**
* \param station the station with which we need to communicate
* \returns the transmission mode to use to send an rts to the station
*
* Note: This method is called before sending an rts to a station
* to decide which transmission mode to use for the rts.
*/
virtual WifiMode DoGetRtsMode (WifiRemoteStation *station) = 0;
virtual void DoReportRtsFailed (WifiRemoteStation *station) = 0;
virtual void DoReportDataFailed (WifiRemoteStation *station) = 0;
virtual void DoReportRtsOk (WifiRemoteStation *station,
double ctsSnr, WifiMode ctsMode, double rtsSnr) = 0;
virtual void DoReportDataOk (WifiRemoteStation *station,
double ackSnr, WifiMode ackMode, double dataSnr) = 0;
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station) = 0;
virtual void DoReportFinalDataFailed (WifiRemoteStation *station) = 0;
virtual void DoReportRxOk (WifiRemoteStation *station,
double rxSnr, WifiMode txMode) = 0;
WifiRemoteStationState *LookupState (Mac48Address address) const;
WifiRemoteStation *Lookup (Mac48Address address, const WifiMacHeader *header) const;
WifiRemoteStation *Lookup (Mac48Address address, uint8_t tid) const;
WifiMode GetControlAnswerMode (Mac48Address address, WifiMode reqMode);
uint32_t GetNFragments (Ptr<const Packet> packet);
bool IsIn (WifiMode mode) const;
WifiMode GetControlAnswerMode (WifiMode reqMode);
enum {
BRAND_NEW,
DISASSOC,
WAIT_ASSOC_TX_OK,
GOT_ASSOC_TX_OK
} m_state;
SupportedModes m_modes;
TracedValue<uint32_t> m_ssrc;
TracedValue<uint32_t> m_slrc;
typedef std::vector <WifiRemoteStation *> Stations;
typedef std::vector <WifiRemoteStationState *> StationStates;
StationStates m_states;
Stations m_stations;
WifiMode m_defaultTxMode;
BasicModes m_basicModes;
bool m_isLowLatency;
uint32_t m_maxSsrc;
uint32_t m_maxSlrc;
uint32_t m_rtsCtsThreshold;
uint32_t m_fragmentationThreshold;
WifiMode m_nonUnicastMode;
double m_avgSlrcCoefficient;
double m_avgSlrc;
/**
* The trace source fired when the transmission of a single RTS has failed
*/
TracedCallback<Mac48Address> m_macTxRtsFailed;
/**
* The trace source fired when the transmission of a single data packet has failed
*/
TracedCallback<Mac48Address> m_macTxDataFailed;
/**
* The trace source fired when the transmission of a RTS has
* exceeded the maximum number of attempts
*/
TracedCallback<Mac48Address> m_macTxFinalRtsFailed;
/**
* The trace source fired when the transmission of a data packet has
* exceeded the maximum number of attempts
*/
TracedCallback<Mac48Address> m_macTxFinalDataFailed;
};
struct WifiRemoteStationState
{
typedef std::vector<WifiMode> SupportedModes;
enum
{
BRAND_NEW,
DISASSOC,
WAIT_ASSOC_TX_OK,
GOT_ASSOC_TX_OK
} m_state;
SupportedModes m_modes;
Mac48Address m_address;
};
/**
* \brief hold per-remote-station state.
*
* The state in this class is used to keep track
* of association status if we are in an infrastructure
* network and to perform the selection of tx parameters
* on a per-packet basis.
*/
struct WifiRemoteStation
{
struct WifiRemoteStationState *m_state;
uint32_t m_ssrc;
uint32_t m_slrc;
double m_avgSlrc;
uint8_t m_tid;
};
} // namespace ns3
#endif /* MAC_STATIONS_H */
#endif /* WIFI_REMOTE_STATION_MANAGER_H */

View File

@@ -41,12 +41,13 @@ def build(bld):
'arf-wifi-manager.cc',
'aarf-wifi-manager.cc',
'ideal-wifi-manager.cc',
'constant-rate-wifi-manager.cc',
'amrr-wifi-manager.cc',
'onoe-wifi-manager.cc',
'rraa-wifi-manager.cc',
'aarfcd-wifi-manager.cc',
'cara-wifi-manager.cc',
'constant-rate-wifi-manager.cc',
'minstrel-wifi-manager.cc',
'wifi-test.cc',
'qos-tag.cc',
'qos-utils.cc',
@@ -57,7 +58,6 @@ def build(bld):
'msdu-aggregator.cc',
'amsdu-subframe-header.cc',
'msdu-standard-aggregator.cc',
'minstrel-wifi-manager.cc',
'dcf.cc',
]
headers = bld.new_task_gen('ns3header')
@@ -79,11 +79,14 @@ def build(bld):
'wifi-remote-station-manager.h',
'arf-wifi-manager.h',
'aarf-wifi-manager.h',
'constant-rate-wifi-manager.h',
'ideal-wifi-manager.h',
'constant-rate-wifi-manager.h',
'amrr-wifi-manager.h',
'onoe-wifi-manager.h',
'rraa-wifi-manager.h',
'aarfcd-wifi-manager.h',
'cara-wifi-manager.h',
'minstrel-wifi-manager.h',
'wifi-mac.h',
'adhoc-wifi-mac.h',
'nqsta-wifi-mac.h',
@@ -108,7 +111,6 @@ def build(bld):
'dcf-manager.h',
'mac-rx-middle.h',
'mac-low.h',
'minstrel-wifi-manager.h',
'dcf.h',
]

View File

@@ -27,6 +27,7 @@
*/
#include "aodv-routing-protocol.h"
#include "ns3/log.h"
#include "ns3/boolean.h"
#include "ns3/random-variable.h"
#include "ns3/inet-socket-address.h"
#include "ns3/trace-source-accessor.h"

View File

@@ -28,6 +28,7 @@
#include "ns3/config.h"
#include "ns3/string.h"
#include "ns3/uinteger.h"
#include "ns3/double.h"
#include "ns3/data-rate.h"
#include "ns3/inet-socket-address.h"
#include "ns3/internet-stack-helper.h"