bug 602
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 ())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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',
|
||||
]
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user