diff --git a/src/devices/mesh/mesh-wifi-interface-mac.cc b/src/devices/mesh/mesh-wifi-interface-mac.cc index e5404cbaa..292648603 100644 --- a/src/devices/mesh/mesh-wifi-interface-mac.cc +++ b/src/devices/mesh/mesh-wifi-interface-mac.cc @@ -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, 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, 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); diff --git a/src/devices/wifi/aarf-wifi-manager.cc b/src/devices/wifi/aarf-wifi-manager.cc index 765fec03a..eb6c1582a 100644 --- a/src/devices/wifi/aarf-wifi-manager.cc +++ b/src/devices/wifi/aarf-wifi-manager.cc @@ -22,19 +22,37 @@ #include "ns3/double.h" #include "ns3/uinteger.h" +#include "ns3/log.h" #define Min(a,b) ((ab)?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 () + .SetParent () .AddConstructor () .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 manager) - : ArfWifiRemoteStation (manager), - m_manager (manager) -{} - - -AarfWifiRemoteStation::~AarfWifiRemoteStation () -{} - -Ptr -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="<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 diff --git a/src/devices/wifi/aarf-wifi-manager.h b/src/devices/wifi/aarf-wifi-manager.h index 79a70789b..edb278345 100644 --- a/src/devices/wifi/aarf-wifi-manager.h +++ b/src/devices/wifi/aarf-wifi-manager.h @@ -32,15 +32,29 @@ namespace ns3 { * A Practical Approach, 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 stations); - virtual ~AarfWifiRemoteStation (); - -private: - virtual void ReportRecoveryFailure (void); - virtual void ReportFailure (void); - virtual Ptr GetManager (void) const; - - Ptr m_manager; -}; - } // namespace ns3 diff --git a/src/devices/wifi/aarfcd-wifi-manager.cc b/src/devices/wifi/aarfcd-wifi-manager.cc index 5f1b6c721..42b16b662 100644 --- a/src/devices/wifi/aarfcd-wifi-manager.cc +++ b/src/devices/wifi/aarfcd-wifi-manager.cc @@ -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 +#define Min(a,b) ((ab)?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 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="<= 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 -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 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 ()) - .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="<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 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 diff --git a/src/devices/wifi/aarfcd-wifi-manager.h b/src/devices/wifi/aarfcd-wifi-manager.h index f95d45356..19ea13d94 100644 --- a/src/devices/wifi/aarfcd-wifi-manager.h +++ b/src/devices/wifi/aarfcd-wifi-manager.h @@ -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 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 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 GetManager (void) const; - virtual WifiMode DoGetDataMode (uint32_t size); - virtual WifiMode DoGetRtsMode (void); - virtual bool NeedRts (Ptr 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 m_manager; -}; - } // namespace ns3 -#endif /* MAARF_MAC_STATIONS_H */ +#endif /* AARFCD_WIFI_MANAGER_H */ diff --git a/src/devices/wifi/adhoc-wifi-mac.cc b/src/devices/wifi/adhoc-wifi-mac.cc index 44af9e4d8..0e63b962c 100644 --- a/src/devices/wifi/adhoc-wifi-mac.cc +++ b/src/devices/wifi/adhoc-wifi-mac.cc @@ -234,16 +234,15 @@ AdhocWifiMac::Enqueue (Ptr 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); diff --git a/src/devices/wifi/amrr-wifi-manager.cc b/src/devices/wifi/amrr-wifi-manager.cc index 05f0ae2e8..1474fec90 100644 --- a/src/devices/wifi/amrr-wifi-manager.cc +++ b/src/devices/wifi/amrr-wifi-manager.cc @@ -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 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="< -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 diff --git a/src/devices/wifi/amrr-wifi-manager.h b/src/devices/wifi/amrr-wifi-manager.h index c639f6666..2ddc0f1b5 100644 --- a/src/devices/wifi/amrr-wifi-manager.h +++ b/src/devices/wifi/amrr-wifi-manager.h @@ -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 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 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 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 */ diff --git a/src/devices/wifi/arf-wifi-manager.cc b/src/devices/wifi/arf-wifi-manager.cc index fbbc0391f..dec47835e 100644 --- a/src/devices/wifi/arf-wifi-manager.cc +++ b/src/devices/wifi/arf-wifi-manager.cc @@ -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 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="<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 -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="<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="<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 diff --git a/src/devices/wifi/arf-wifi-manager.h b/src/devices/wifi/arf-wifi-manager.h index 6fb68a86b..7c5e308f6 100644 --- a/src/devices/wifi/arf-wifi-manager.h +++ b/src/devices/wifi/arf-wifi-manager.h @@ -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 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 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 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 */ diff --git a/src/devices/wifi/cara-wifi-manager.cc b/src/devices/wifi/cara-wifi-manager.cc index 9224960b0..503e87795 100644 --- a/src/devices/wifi/cara-wifi-manager.cc +++ b/src/devices/wifi/cara-wifi-manager.cc @@ -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 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="<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="<m_timer++; + station->m_success++; + station->m_failed = 0; + NS_LOG_DEBUG ("self="<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); diff --git a/src/devices/wifi/dca-txop.h b/src/devices/wifi/dca-txop.h index 69b8a050f..bf25ce1c4 100644 --- a/src/devices/wifi/dca-txop.h +++ b/src/devices/wifi/dca-txop.h @@ -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 GetFragmentPacket (WifiMacHeader *hdr); diff --git a/src/devices/wifi/edca-txop-n.cc b/src/devices/wifi/edca-txop-n.cc index 68b9f8db0..c465c754e 100644 --- a/src/devices/wifi/edca-txop-n.cc +++ b/src/devices/wifi/edca-txop-n.cc @@ -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 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 diff --git a/src/devices/wifi/edca-txop-n.h b/src/devices/wifi/edca-txop-n.h index 298eb2700..c794aca29 100644 --- a/src/devices/wifi/edca-txop-n.h +++ b/src/devices/wifi/edca-txop-n.h @@ -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 GetFragmentPacket (WifiMacHeader *hdr); diff --git a/src/devices/wifi/ideal-wifi-manager.cc b/src/devices/wifi/ideal-wifi-manager.cc index 235d887af..a85154b70 100644 --- a/src/devices/wifi/ideal-wifi-manager.cc +++ b/src/devices/wifi/ideal-wifi-manager.cc @@ -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 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 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 -IdealWifiRemoteStation::GetManager (void) const + +bool +IdealWifiManager::IsLowLatency (void) const { - return m_manager; + return true; } } // namespace ns3 diff --git a/src/devices/wifi/ideal-wifi-manager.h b/src/devices/wifi/ideal-wifi-manager.h index 80d3b7503..afd32a68f 100644 --- a/src/devices/wifi/ideal-wifi-manager.h +++ b/src/devices/wifi/ideal-wifi-manager.h @@ -17,8 +17,8 @@ * * Author: Mathieu Lacage */ -#ifndef IDEAL_MAC_STATIONS_H -#define IDEAL_MAC_STATIONS_H +#ifndef IDEAL_WIFI_MANAGER_H +#define IDEAL_WIFI_MANAGER_H #include #include @@ -50,12 +50,27 @@ public: virtual void SetupPhy (Ptr 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 > Thresholds; @@ -65,31 +80,6 @@ private: double m_maxSnr; }; -class IdealWifiRemoteStation : public WifiRemoteStation -{ -public: - IdealWifiRemoteStation (Ptr 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 GetManager (void) const; - virtual WifiMode DoGetDataMode (uint32_t size); - virtual WifiMode DoGetRtsMode (void); - - Ptr m_manager; - double m_lastSnr; -}; - } // namespace ns3 -#endif /* MAC_STA_H */ +#endif /* IDEAL_WIFI_MANAGER_H */ diff --git a/src/devices/wifi/mac-low.cc b/src/devices/wifi/mac-low.cc index 116b679b6..4667bd4be 100644 --- a/src/devices/wifi/mac-low.cc +++ b/src/devices/wifi/mac-low.cc @@ -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, 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, double rxSnr, WifiMode txMode, WifiPreamb NS_LOG_DEBUG ("receive cts from="<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, double rxSnr, WifiMode txMode, WifiPreamb NS_LOG_DEBUG ("receive ack from="<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, 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 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 packet, const WifiMacHeader *hdr) const @@ -751,18 +754,18 @@ MacLow::GetDataTxMode (Ptr 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) { diff --git a/src/devices/wifi/mac-low.h b/src/devices/wifi/mac-low.h index c6104faf9..6bb1c9964 100644 --- a/src/devices/wifi/mac-low.h +++ b/src/devices/wifi/mac-low.h @@ -371,7 +371,6 @@ private: uint32_t GetCtsSize (void) const; uint32_t GetSize (Ptr packet, const WifiMacHeader *hdr) const; Time NowUs (void) const; - WifiRemoteStation *GetStation (Mac48Address to) const; void ForwardDown (Ptr packet, const WifiMacHeader *hdr, WifiMode txMode); Time CalculateOverallTxTime (Ptr packet, diff --git a/src/devices/wifi/minstrel-wifi-manager.cc b/src/devices/wifi/minstrel-wifi-manager.cc index ac24b1543..7032cf3d3 100644 --- a/src/devices/wifi/minstrel-wifi-manager.cc +++ b/src/devices/wifi/minstrel-wifi-manager.cc @@ -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 MinstrelRate; + +/** + * Data structure for a Sample Rate table + * A vector of a vector uint32_t + */ +typedef std::vector > 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 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 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 (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 (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="<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 -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="<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(((tempProb * (100 - m_stations->m_ewmaLevel)) + (m_minstrelTable[i].ewmaProb * m_stations->m_ewmaLevel) )/100); + tempProb = static_cast(((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="<m_sampleTable[i][j] << "\t"; } std::cout << std::endl; } } void -MinstrelWifiRemoteStation::PrintTable () +MinstrelWifiManager::PrintTable (MinstrelWifiRemoteStation *station) { - NS_LOG_DEBUG ("PrintTable="< - - /** * \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 MinstrelRate; - -/** - * Data structure for a Sample Rate table - * A vector of a vector uint32_t - */ -typedef std::vector > SampleRate; +class MinstrelWifiRemoteStation; class MinstrelWifiManager : public WifiRemoteStationManager @@ -96,13 +52,53 @@ public: virtual void SetupPhy (Ptr 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 > 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 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 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 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 */ diff --git a/src/devices/wifi/nqap-wifi-mac.cc b/src/devices/wifi/nqap-wifi-mac.cc index 437de6108..e1b73ab92 100644 --- a/src/devices/wifi/nqap-wifi-mac.cc +++ b/src/devices/wifi/nqap-wifi-mac.cc @@ -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="<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="<RecordGotAssocTxFailed (); + m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ()); } } void @@ -442,7 +441,6 @@ NqapWifiMac::Receive (Ptr 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, 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="<IsAssociated ()) + m_stationManager->IsAssociated (to)) { NS_LOG_DEBUG ("forwarding frame from="< 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); diff --git a/src/devices/wifi/onoe-wifi-manager.cc b/src/devices/wifi/onoe-wifi-manager.cc index eca505d3b..32da90b57 100644 --- a/src/devices/wifi/onoe-wifi-manager.cc +++ b/src/devices/wifi/onoe-wifi-manager.cc @@ -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 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 -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 diff --git a/src/devices/wifi/onoe-wifi-manager.h b/src/devices/wifi/onoe-wifi-manager.h index 68eb5a7f7..0aae8dd12 100644 --- a/src/devices/wifi/onoe-wifi-manager.h +++ b/src/devices/wifi/onoe-wifi-manager.h @@ -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 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 GetManager (void) const; - virtual WifiMode DoGetDataMode (uint32_t size); - virtual WifiMode DoGetRtsMode (void); - - void UpdateRetry (void); - void UpdateMode (void); - - Ptr 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 */ diff --git a/src/devices/wifi/propagation-loss-model-test-suite.cc b/src/devices/wifi/propagation-loss-model-test-suite.cc index 2e3a40a0b..8f3199732 100644 --- a/src/devices/wifi/propagation-loss-model-test-suite.cc +++ b/src/devices/wifi/propagation-loss-model-test-suite.cc @@ -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" diff --git a/src/devices/wifi/qadhoc-wifi-mac.cc b/src/devices/wifi/qadhoc-wifi-mac.cc index a2bff3114..cfbf34554 100644 --- a/src/devices/wifi/qadhoc-wifi-mac.cc +++ b/src/devices/wifi/qadhoc-wifi-mac.cc @@ -243,16 +243,15 @@ QadhocWifiMac::Enqueue (Ptr 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); diff --git a/src/devices/wifi/qap-wifi-mac.cc b/src/devices/wifi/qap-wifi-mac.cc index ec9a8d6f1..05093f058 100644 --- a/src/devices/wifi/qap-wifi-mac.cc +++ b/src/devices/wifi/qap-wifi-mac.cc @@ -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="<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="<RecordGotAssocTxFailed (); + m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ()); } } @@ -557,7 +556,6 @@ QapWifiMac::Receive (Ptr 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, 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, const WifiMacHeader *hdr) } } else if (to.IsGroup () || - toStation->IsAssociated ()) + m_stationManager->IsAssociated (to)) { NS_LOG_DEBUG ("forwarding frame from="< 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); diff --git a/src/devices/wifi/rraa-wifi-manager.cc b/src/devices/wifi/rraa-wifi-manager.cc index 93285a4fa..b151ff21a 100644 --- a/src/devices/wifi/rraa-wifi-manager.cc +++ b/src/devices/wifi/rraa-wifi-manager.cc @@ -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 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 -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="< 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="<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 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 diff --git a/src/devices/wifi/rraa-wifi-manager.h b/src/devices/wifi/rraa-wifi-manager.h index afb856832..e2e1b9772 100644 --- a/src/devices/wifi/rraa-wifi-manager.h +++ b/src/devices/wifi/rraa-wifi-manager.h @@ -25,14 +25,7 @@ namespace ns3 { -struct ThresholdsItem { - uint32_t datarate; - double pori; - double pmtl; - uint32_t ewnd; -}; - -typedef std::vector 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 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 stations); - virtual ~RraaWifiRemoteStation (); - - virtual bool NeedRts (Ptr 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 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 m_stations; -}; - } // namespace ns3 #endif /* RRAA_WIFI_MANAGER_H */ diff --git a/src/devices/wifi/wifi-remote-station-manager.cc b/src/devices/wifi/wifi-remote-station-manager.cc index 1e09f5f62..bd493fa39 100644 --- a/src/devices/wifi/wifi-remote-station-manager.cc +++ b/src/devices/wifi/wifi-remote-station-manager.cc @@ -23,342 +23,14 @@ #include "ns3/log.h" #include "ns3/tag.h" #include "ns3/boolean.h" +#include "ns3/double.h" #include "ns3/uinteger.h" #include "ns3/wifi-phy.h" #include "ns3/trace-source-accessor.h" +#include "wifi-mac-header.h" NS_LOG_COMPONENT_DEFINE ("WifiRemoteStationManager"); -namespace ns3 { - -/** - * _all_ broadcast and multicast frames are transmitted - * at the same constant default rate because since we don't - * have any kind of feedback from their transmission, - * we cannot adjust the rate, so, we pick one which ensures - * that all frames reach destination. - */ -class NonUnicastWifiRemoteStation : public WifiRemoteStation -{ -public: - NonUnicastWifiRemoteStation (Ptr stations); -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 GetManager (void) const; - virtual WifiMode DoGetDataMode (uint32_t size); - virtual WifiMode DoGetRtsMode (void); - Ptr m_stations; -}; - -NonUnicastWifiRemoteStation::NonUnicastWifiRemoteStation (Ptr stations) - : m_stations (stations) -{ - RecordDisassociated (); -} -void -NonUnicastWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode) -{ - NS_ASSERT (false); -} -void -NonUnicastWifiRemoteStation::DoReportRtsFailed (void) -{ - NS_ASSERT (false); -} -void -NonUnicastWifiRemoteStation::DoReportDataFailed (void) -{ - NS_ASSERT (false); -} -void -NonUnicastWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr) -{ - NS_ASSERT (false); -} -void -NonUnicastWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr) -{ - NS_ASSERT (false); -} -void -NonUnicastWifiRemoteStation::DoReportFinalRtsFailed (void) -{} -void -NonUnicastWifiRemoteStation::DoReportFinalDataFailed (void) -{} - -WifiMode -NonUnicastWifiRemoteStation::DoGetDataMode (uint32_t size) -{ - WifiMode mode = m_stations->GetNonUnicastMode (); - NS_LOG_DEBUG ("non-unicast size="< () - .AddAttribute ("IsLowLatency", "If true, we attempt to modelize a so-called low-latency device: a device" - " where decisions about tx parameters can be made on a per-packet basis and feedback about the" - " transmission of each packet is obtained before sending the next. Otherwise, we modelize a " - " high-latency device, that is a device where we cannot update our decision about tx parameters" - " after every packet transmission.", - BooleanValue (true), - MakeBooleanAccessor (&WifiRemoteStationManager::m_isLowLatency), - MakeBooleanChecker ()) - .AddAttribute ("MaxSsrc", "The maximum number of retransmission attempts for an RTS. This value" - " will not have any effect on some rate control algorithms.", - UintegerValue (7), - MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSsrc), - MakeUintegerChecker ()) - .AddAttribute ("MaxSlrc", "The maximum number of retransmission attempts for a DATA packet. This value" - " will not have any effect on some rate control algorithms.", - UintegerValue (7), - MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSlrc), - MakeUintegerChecker ()) - .AddAttribute ("RtsCtsThreshold", "If a data packet is bigger than this value, we use an RTS/CTS handshake" - " before sending the data. This value will not have any effect on some rate control algorithms.", - UintegerValue (1500), - MakeUintegerAccessor (&WifiRemoteStationManager::m_rtsCtsThreshold), - MakeUintegerChecker ()) - .AddAttribute ("FragmentationThreshold", "If a data packet is bigger than this value, we fragment it such that" - " the size of the fragments are equal or smaller than this value. This value will not have any effect" - " on some rate control algorithms.", - UintegerValue (1500), - MakeUintegerAccessor (&WifiRemoteStationManager::m_fragmentationThreshold), - MakeUintegerChecker ()) - .AddAttribute ("NonUnicastMode", "Wifi mode used for non-unicast transmissions.", - WifiModeValue (), - MakeWifiModeAccessor (&WifiRemoteStationManager::m_nonUnicastMode), - MakeWifiModeChecker ()) - .AddTraceSource ("MacTxRtsFailed", - "The transmission of a RTS by the MAC layer has failed", - MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxRtsFailed)) - .AddTraceSource ("MacTxDataFailed", - "The transmission of a data packet by the MAC layer has failed", - MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxDataFailed)) - .AddTraceSource ("MacTxFinalRtsFailed", - "The transmission of a RTS has exceeded the maximum number of attempts", - MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalRtsFailed)) - .AddTraceSource ("MacTxFinalDataFailed", - "The transmission of a data packet has exceeded the maximum number of attempts", - MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalDataFailed)) - ; - return tid; -} - -WifiRemoteStationManager::WifiRemoteStationManager () - : m_nonUnicast (new NonUnicastWifiRemoteStation (this)) -{} - -WifiRemoteStationManager::~WifiRemoteStationManager () -{ -} -void -WifiRemoteStationManager::DoDispose (void) -{ - for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) - { - delete (*i); - } - m_stations.clear (); - delete m_nonUnicast; -} -void -WifiRemoteStationManager::SetupPhy (Ptr phy) -{ - m_defaultTxMode = phy->GetMode (0); - Reset (); -} - -uint32_t -WifiRemoteStationManager::GetMaxSsrc (void) const -{ - return m_maxSsrc; -} -uint32_t -WifiRemoteStationManager::GetMaxSlrc (void) const -{ - return m_maxSlrc; -} -uint32_t -WifiRemoteStationManager::GetRtsCtsThreshold (void) const -{ - return m_rtsCtsThreshold; -} -uint32_t -WifiRemoteStationManager::GetFragmentationThreshold (void) const -{ - return m_fragmentationThreshold; -} -void -WifiRemoteStationManager::SetMaxSsrc (uint32_t maxSsrc) -{ - m_maxSsrc = maxSsrc; -} -void -WifiRemoteStationManager::SetMaxSlrc (uint32_t maxSlrc) -{ - m_maxSlrc = maxSlrc; -} -void -WifiRemoteStationManager::SetRtsCtsThreshold (uint32_t threshold) -{ - m_rtsCtsThreshold = threshold; -} -void -WifiRemoteStationManager::SetFragmentationThreshold (uint32_t threshold) -{ - m_fragmentationThreshold = threshold; -} - -WifiRemoteStation * -WifiRemoteStationManager::Lookup (Mac48Address address) -{ - if (address.IsGroup ()) - { - return m_nonUnicast; - } - for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) - { - if ((*i)->GetAddress () == address) - { - return (*i); - } - } - WifiRemoteStation *station = CreateStation (); - station->SetAddress(address); - station->Reset (); - m_stations.push_back (station); - return station; -} - -WifiRemoteStation * -WifiRemoteStationManager::LookupNonUnicast (void) -{ - return m_nonUnicast; -} - -WifiMode -WifiRemoteStationManager::GetDefaultMode (void) const -{ - return m_defaultTxMode; -} -void -WifiRemoteStationManager::Reset (void) -{ - for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) - { - delete (*i); - } - m_stations.clear (); - m_basicModes.clear (); - m_basicModes.push_back (m_defaultTxMode); - NS_ASSERT (m_defaultTxMode.IsMandatory ()); -} -void -WifiRemoteStationManager::AddBasicMode (WifiMode mode) -{ - for (uint32_t i = 0; i < GetNBasicModes (); i++) - { - if (GetBasicMode (i) == mode) - { - return; - } - } - m_basicModes.push_back (mode); -} -uint32_t -WifiRemoteStationManager::GetNBasicModes (void) const -{ - return m_basicModes.size (); -} -WifiMode -WifiRemoteStationManager::GetBasicMode (uint32_t i) const -{ - NS_ASSERT (i < m_basicModes.size ()); - return m_basicModes[i]; -} -WifiRemoteStationManager::BasicModesIterator -WifiRemoteStationManager::BeginBasicModes (void) const -{ - return m_basicModes.begin (); -} -WifiRemoteStationManager::BasicModesIterator -WifiRemoteStationManager::EndBasicModes (void) const -{ - return m_basicModes.end (); -} -bool -WifiRemoteStationManager::IsLowLatency (void) const -{ - return m_isLowLatency; -} -WifiMode -WifiRemoteStationManager::GetNonUnicastMode (void) const -{ - if (m_nonUnicastMode == WifiMode ()) - return GetBasicMode(0); - else - return m_nonUnicastMode; -} - - -void -WifiRemoteStationManager::NotifyTxRtsFailed (Mac48Address address) -{ - m_macTxRtsFailed (address); -} - -void -WifiRemoteStationManager::NotifyTxDataFailed (Mac48Address address) -{ - m_macTxDataFailed (address); -} - -void -WifiRemoteStationManager::NotifyTxFinalRtsFailed (Mac48Address address) -{ - m_macTxFinalRtsFailed (address); -} - -void -WifiRemoteStationManager::NotifyTxFinalDataFailed (Mac48Address address) -{ - m_macTxFinalDataFailed (address); -} - - - -} // namespace ns3 /*************************************************************** * Packet Mode Tagger @@ -451,103 +123,409 @@ TxModeTag::Print (std::ostream &os) const } // namespace ns3 -/*************************************************************** - * WifiRemoteStation below. - ***************************************************************/ - namespace ns3 { +NS_OBJECT_ENSURE_REGISTERED (WifiRemoteStationManager); + TypeId -WifiRemoteStation::GetTypeId (void) +WifiRemoteStationManager::GetTypeId (void) { - static TypeId tid = TypeId ("ns3::WifiRemoteStation") + static TypeId tid = TypeId ("ns3::WifiRemoteStationManager") .SetParent () - .AddTraceSource ("Ssrc", "The value of the ssrc counter: indicates the number of retransmissions of RTS.", - MakeTraceSourceAccessor (&WifiRemoteStation::m_ssrc)) - .AddTraceSource ("Slrc", "The value of the slrc counter: indicates the number of retransmissions of DATA.", - MakeTraceSourceAccessor (&WifiRemoteStation::m_slrc)) + .AddAttribute ("IsLowLatency", "If true, we attempt to modelize a so-called low-latency device: a device" + " where decisions about tx parameters can be made on a per-packet basis and feedback about the" + " transmission of each packet is obtained before sending the next. Otherwise, we modelize a " + " high-latency device, that is a device where we cannot update our decision about tx parameters" + " after every packet transmission.", + BooleanValue (true), + MakeBooleanAccessor (&WifiRemoteStationManager::IsLowLatency), + MakeBooleanChecker ()) + .AddAttribute ("MaxSsrc", "The maximum number of retransmission attempts for an RTS. This value" + " will not have any effect on some rate control algorithms.", + UintegerValue (7), + MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSsrc), + MakeUintegerChecker ()) + .AddAttribute ("MaxSlrc", "The maximum number of retransmission attempts for a DATA packet. This value" + " will not have any effect on some rate control algorithms.", + UintegerValue (7), + MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSlrc), + MakeUintegerChecker ()) + .AddAttribute ("RtsCtsThreshold", "If a data packet is bigger than this value, we use an RTS/CTS handshake" + " before sending the data. This value will not have any effect on some rate control algorithms.", + UintegerValue (1500), + MakeUintegerAccessor (&WifiRemoteStationManager::m_rtsCtsThreshold), + MakeUintegerChecker ()) + .AddAttribute ("FragmentationThreshold", "If a data packet is bigger than this value, we fragment it such that" + " the size of the fragments are equal or smaller than this value. This value will not have any effect" + " on some rate control algorithms.", + UintegerValue (1500), + MakeUintegerAccessor (&WifiRemoteStationManager::m_fragmentationThreshold), + MakeUintegerChecker ()) + .AddAttribute ("NonUnicastMode", "Wifi mode used for non-unicast transmissions.", + WifiModeValue (), + MakeWifiModeAccessor (&WifiRemoteStationManager::m_nonUnicastMode), + MakeWifiModeChecker ()) + .AddTraceSource ("MacTxRtsFailed", + "The transmission of a RTS by the MAC layer has failed", + MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxRtsFailed)) + .AddTraceSource ("MacTxDataFailed", + "The transmission of a data packet by the MAC layer has failed", + MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxDataFailed)) + .AddTraceSource ("MacTxFinalRtsFailed", + "The transmission of a RTS has exceeded the maximum number of attempts", + MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalRtsFailed)) + .AddTraceSource ("MacTxFinalDataFailed", + "The transmission of a data packet has exceeded the maximum number of attempts", + MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalDataFailed)) + .AddAttribute("AvgSlrcCoefficient", "The weigh of the slrc count in the slrc avg calculation", + DoubleValue (0.9), + MakeDoubleAccessor (&WifiRemoteStationManager::m_avgSlrcCoefficient), + MakeDoubleChecker ()) ; return tid; } -WifiRemoteStation::WifiRemoteStation () - : m_state (BRAND_NEW), - m_ssrc (0), - m_slrc (0), - m_avgSlrcCoefficient(0.9), - m_avgSlrc (0) -{} -WifiRemoteStation::~WifiRemoteStation () +WifiRemoteStationManager::WifiRemoteStationManager () {} -bool -WifiRemoteStation::IsBrandNew (void) const +WifiRemoteStationManager::~WifiRemoteStationManager () { - return m_state == BRAND_NEW; -} - -bool -WifiRemoteStation::IsAssociated (void) const -{ - return m_state == GOT_ASSOC_TX_OK; -} -bool -WifiRemoteStation::IsWaitAssocTxOk (void) const -{ - return m_state == WAIT_ASSOC_TX_OK; } void -WifiRemoteStation::RecordWaitAssocTxOk (void) +WifiRemoteStationManager::DoDispose (void) { - m_state = WAIT_ASSOC_TX_OK; -} -void -WifiRemoteStation::RecordGotAssocTxOk (void) -{ - m_state = GOT_ASSOC_TX_OK; -} -void -WifiRemoteStation::RecordGotAssocTxFailed (void) -{ - m_state = DISASSOC; -} -void -WifiRemoteStation::RecordDisassociated (void) -{ - m_state = DISASSOC; -} - -void -WifiRemoteStation::Reset (void) -{ - m_modes.clear (); - AddSupportedMode (GetManager ()->GetDefaultMode ()); -} -void -WifiRemoteStation::AddSupportedMode (WifiMode mode) -{ - if (IsIn (mode)) + for (StationStates::const_iterator i = m_states.begin (); i != m_states.end (); i++) { - return; + delete (*i); } - m_modes.push_back (mode); + m_states.clear (); + for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) + { + delete (*i); + } + m_stations.clear (); +} +void +WifiRemoteStationManager::SetupPhy (Ptr phy) +{ + m_defaultTxMode = phy->GetMode (0); + Reset (); } -bool -WifiRemoteStation::IsIn (WifiMode mode) const +uint32_t +WifiRemoteStationManager::GetMaxSsrc (void) const { - for (SupportedModes::const_iterator i = m_modes.begin (); i != m_modes.end (); i++) + return m_maxSsrc; +} +uint32_t +WifiRemoteStationManager::GetMaxSlrc (void) const +{ + return m_maxSlrc; +} +uint32_t +WifiRemoteStationManager::GetRtsCtsThreshold (void) const +{ + return m_rtsCtsThreshold; +} +uint32_t +WifiRemoteStationManager::GetFragmentationThreshold (void) const +{ + return m_fragmentationThreshold; +} +void +WifiRemoteStationManager::SetMaxSsrc (uint32_t maxSsrc) +{ + m_maxSsrc = maxSsrc; +} +void +WifiRemoteStationManager::SetMaxSlrc (uint32_t maxSlrc) +{ + m_maxSlrc = maxSlrc; +} +void +WifiRemoteStationManager::SetRtsCtsThreshold (uint32_t threshold) +{ + m_rtsCtsThreshold = threshold; +} +void +WifiRemoteStationManager::SetFragmentationThreshold (uint32_t threshold) +{ + m_fragmentationThreshold = threshold; +} + +void +WifiRemoteStationManager::Reset (Mac48Address address) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStationState *state = LookupState (address); + state->m_modes.clear (); + AddSupportedMode (address, GetDefaultMode ()); +} +void +WifiRemoteStationManager::AddSupportedMode (Mac48Address address, WifiMode mode) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStationState *state = LookupState (address); + for (WifiRemoteStationState::SupportedModes::const_iterator i = state->m_modes.begin (); i != state->m_modes.end (); i++) { if ((*i) == mode) { - return true; + // already in. + return; } } - return false; + state->m_modes.push_back (mode); +} +bool +WifiRemoteStationManager::IsBrandNew (Mac48Address address) const +{ + if (address.IsGroup ()) + { + return false; + } + return LookupState (address)->m_state == WifiRemoteStationState::BRAND_NEW; +} +bool +WifiRemoteStationManager::IsAssociated (Mac48Address address) const +{ + if (address.IsGroup ()) + { + return true; + } + return LookupState (address)->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK; +} +bool +WifiRemoteStationManager::IsWaitAssocTxOk (Mac48Address address) const +{ + if (address.IsGroup ()) + { + return false; + } + return LookupState (address)->m_state == WifiRemoteStationState::WAIT_ASSOC_TX_OK; +} +void +WifiRemoteStationManager::RecordWaitAssocTxOk (Mac48Address address) +{ + NS_ASSERT (!address.IsGroup ()); + LookupState (address)->m_state = WifiRemoteStationState::WAIT_ASSOC_TX_OK; +} +void +WifiRemoteStationManager::RecordGotAssocTxOk (Mac48Address address) +{ + NS_ASSERT (!address.IsGroup ()); + LookupState (address)->m_state = WifiRemoteStationState::GOT_ASSOC_TX_OK; +} +void +WifiRemoteStationManager::RecordGotAssocTxFailed (Mac48Address address) +{ + NS_ASSERT (!address.IsGroup ()); + LookupState (address)->m_state = WifiRemoteStationState::DISASSOC; +} +void +WifiRemoteStationManager::RecordDisassociated (Mac48Address address) +{ + NS_ASSERT (!address.IsGroup ()); + LookupState (address)->m_state = WifiRemoteStationState::DISASSOC; +} +void +WifiRemoteStationManager::PrepareForQueue (Mac48Address address, const WifiMacHeader *header, + Ptr packet, uint32_t fullPacketSize) +{ + if (IsLowLatency () || address.IsGroup ()) + { + return; + } + TxModeTag tag = TxModeTag (GetRtsMode (address, header, packet), + GetDataMode (address, header, packet, fullPacketSize)); + packet->AddPacketTag (tag); +} +WifiMode +WifiRemoteStationManager::GetDataMode (Mac48Address address, const WifiMacHeader *header, + Ptr packet, uint32_t fullPacketSize) +{ + if (address.IsGroup ()) + { + return GetNonUnicastMode (); + } + if (!IsLowLatency ()) + { + // Note: removing the packet below is wrong: what happens in case of retransmissions ??? + TxModeTag tag; + bool found; + found = ConstCast (packet)->RemovePacketTag (tag); + NS_ASSERT (found); + return tag.GetDataMode (); + } + return DoGetDataMode (Lookup (address, header), fullPacketSize); +} +WifiMode +WifiRemoteStationManager::GetRtsMode (Mac48Address address, const WifiMacHeader *header, + Ptr packet) +{ + NS_ASSERT (!address.IsGroup ()); + if (!IsLowLatency ()) + { + TxModeTag tag; + bool found; + found = ConstCast (packet)->RemovePacketTag (tag); + NS_ASSERT (found); + return tag.GetRtsMode (); + } + return DoGetRtsMode (Lookup (address, header)); +} +void +WifiRemoteStationManager::ReportRtsFailed (Mac48Address address, const WifiMacHeader *header) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, header); + station->m_ssrc++; + m_macTxRtsFailed (address); + DoReportRtsFailed (station); +} +void +WifiRemoteStationManager::ReportDataFailed (Mac48Address address, const WifiMacHeader *header) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, header); + station->m_slrc++; + m_macTxDataFailed (address); + DoReportDataFailed (station); +} +void +WifiRemoteStationManager::ReportRtsOk (Mac48Address address, const WifiMacHeader *header, + double ctsSnr, WifiMode ctsMode, double rtsSnr) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, header); + station->m_ssrc = 0; + DoReportRtsOk (station, ctsSnr, ctsMode, rtsSnr); +} +void +WifiRemoteStationManager::ReportDataOk (Mac48Address address, const WifiMacHeader *header, + double ackSnr, WifiMode ackMode, double dataSnr) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, header); + station->m_avgSlrc = station->m_avgSlrc * m_avgSlrcCoefficient + (double) station->m_slrc * (1 - m_avgSlrcCoefficient); + station->m_slrc = 0; + DoReportDataOk (station, ackSnr, ackMode, dataSnr); +} +void +WifiRemoteStationManager::ReportFinalRtsFailed (Mac48Address address, const WifiMacHeader *header) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, header); + station->m_ssrc = 0; + m_macTxFinalRtsFailed (address); + DoReportFinalRtsFailed (station); +} +void +WifiRemoteStationManager::ReportFinalDataFailed (Mac48Address address, const WifiMacHeader *header) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, header); + station->m_slrc = 0; + m_macTxFinalDataFailed (address); + DoReportFinalDataFailed (station); +} +void +WifiRemoteStationManager::ReportRxOk (Mac48Address address, const WifiMacHeader *header, + double rxSnr, WifiMode txMode) +{ + if (address.IsGroup ()) + { + return; + } + WifiRemoteStation *station = Lookup (address, header); + DoReportRxOk (station, rxSnr, txMode); +} +bool +WifiRemoteStationManager::NeedRts (Mac48Address address, const WifiMacHeader *header, + Ptr packet) +{ + if (address.IsGroup ()) + { + return false; + } + bool normally = packet->GetSize () > GetRtsCtsThreshold (); + return DoNeedRts (Lookup (address, header), packet, normally); +} +bool +WifiRemoteStationManager::NeedRtsRetransmission (Mac48Address address, const WifiMacHeader *header, + Ptr packet) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, header); + bool normally = station->m_ssrc < GetMaxSsrc (); + return DoNeedRtsRetransmission (station, packet, normally); +} +bool +WifiRemoteStationManager::NeedDataRetransmission (Mac48Address address, const WifiMacHeader *header, + Ptr packet) +{ + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, header); + bool normally = station->m_slrc < GetMaxSlrc (); + return DoNeedDataRetransmission (station, packet, normally); +} +bool +WifiRemoteStationManager::NeedFragmentation (Mac48Address address, const WifiMacHeader *header, + Ptr packet) +{ + if (address.IsGroup ()) + { + return false; + } + WifiRemoteStation *station = Lookup (address, header); + bool normally = packet->GetSize () > GetFragmentationThreshold (); + return DoNeedFragmentation (station, packet, normally); +} +uint32_t +WifiRemoteStationManager::GetNFragments (Ptr packet) +{ + uint32_t nFragments = packet->GetSize () / GetFragmentationThreshold () + 1; + return nFragments; } +uint32_t +WifiRemoteStationManager::GetFragmentSize (Mac48Address address, const WifiMacHeader *header, + Ptr packet, uint32_t fragmentNumber) +{ + NS_ASSERT (!address.IsGroup ()); + uint32_t nFragment = GetNFragments (packet); + if (fragmentNumber >= nFragment) + { + return 0; + } + if (fragmentNumber == nFragment - 1) + { + uint32_t lastFragmentSize = packet->GetSize () % GetFragmentationThreshold (); + return lastFragmentSize; + } + else + { + return GetFragmentationThreshold (); + } +} +uint32_t +WifiRemoteStationManager::GetFragmentOffset (Mac48Address address, const WifiMacHeader *header, + Ptr packet, uint32_t fragmentNumber) +{ + NS_ASSERT (!address.IsGroup ()); + NS_ASSERT (fragmentNumber < GetNFragments (packet)); + uint32_t fragmentOffset = fragmentNumber * GetFragmentationThreshold (); + return fragmentOffset; +} +bool +WifiRemoteStationManager::IsLastFragment (Mac48Address address, const WifiMacHeader *header, + Ptr packet, uint32_t fragmentNumber) +{ + NS_ASSERT (!address.IsGroup ()); + bool isLast = fragmentNumber == (GetNFragments (packet) - 1); + return isLast; +} WifiMode -WifiRemoteStation::GetControlAnswerMode (WifiMode reqMode) +WifiRemoteStationManager::GetControlAnswerMode (Mac48Address address, WifiMode reqMode) { /** * see ieee 802.11e, section 9.6: @@ -569,19 +547,16 @@ WifiRemoteStation::GetControlAnswerMode (WifiMode reqMode) * received frame, unless they conflict with the requirement to use * the BSSBasicRateSet parameter. */ - WifiMode mode = GetManager ()->GetDefaultMode (); - bool found = false; + WifiMode mode = GetDefaultMode (); // First, search the BSS Basic Rate set - for (WifiRemoteStationManager::BasicModesIterator i = GetManager ()->BeginBasicModes (); - i != GetManager ()->EndBasicModes (); i++) + for (WifiRemoteStationManager::BasicModesIterator i = BeginBasicModes (); i != EndBasicModes (); i++) { if (i->GetPhyRate () > mode.GetPhyRate () && i->GetPhyRate () <= reqMode.GetPhyRate () && i->GetModulationType () == reqMode.GetModulationType ()) { mode = *i; - found = true; } } // no need to search Mandatory rate set because it is included @@ -589,212 +564,181 @@ WifiRemoteStation::GetControlAnswerMode (WifiMode reqMode) return mode; } -WifiMode -WifiRemoteStation::GetCtsMode (WifiMode rtsMode) +WifiMode +WifiRemoteStationManager::GetCtsMode (Mac48Address address, WifiMode rtsMode) { - return GetControlAnswerMode (rtsMode); + NS_ASSERT (!address.IsGroup ()); + return GetControlAnswerMode (address, rtsMode); } -WifiMode -WifiRemoteStation::GetAckMode (WifiMode dataMode) +WifiMode +WifiRemoteStationManager::GetAckMode (Mac48Address address, WifiMode dataMode) { - return GetControlAnswerMode (dataMode); + NS_ASSERT (!address.IsGroup ()); + return GetControlAnswerMode (address, dataMode); } double -WifiRemoteStation::GetAvgSlrc () const +WifiRemoteStationManager::GetAvgSlrc (Mac48Address address) const { - return m_avgSlrc; -} -void -WifiRemoteStation::SetAddress(Mac48Address address) -{ - m_address = address; -} -Mac48Address -WifiRemoteStation::GetAddress() -{ - return m_address; -} -uint32_t -WifiRemoteStation::GetNSupportedModes (void) const -{ - return m_modes.size (); -} -WifiMode -WifiRemoteStation::GetSupportedMode (uint32_t i) const -{ - NS_ASSERT (i < m_modes.size ()); - return m_modes[i]; -} -void -WifiRemoteStation::PrepareForQueue (Ptr packet, uint32_t fullPacketSize) -{ - if (GetManager ()->IsLowLatency ()) - { - return; - } - TxModeTag tag = TxModeTag (DoGetRtsMode (), DoGetDataMode (fullPacketSize)); - packet->AddPacketTag (tag); -} -WifiMode -WifiRemoteStation::GetDataMode (Ptr packet, uint32_t fullPacketSize) -{ - if (GetManager ()->IsLowLatency ()) - { - return DoGetDataMode (fullPacketSize); - } - TxModeTag tag; - bool found; - found = ConstCast (packet)->RemovePacketTag (tag); - NS_ASSERT (found); - return tag.GetDataMode (); -} -WifiMode -WifiRemoteStation::GetRtsMode (Ptr packet) -{ - if (GetManager ()->IsLowLatency ()) - { - return DoGetRtsMode (); - } - TxModeTag tag; - bool found; - found = ConstCast (packet)->RemovePacketTag (tag); - NS_ASSERT (found); - return tag.GetRtsMode (); + NS_FATAL_ERROR ("XXX"); + NS_ASSERT (!address.IsGroup ()); + WifiRemoteStation *station = Lookup (address, (uint8_t)0); + return station->m_avgSlrc; } -bool -WifiRemoteStation::NeedRts (Ptr packet) +WifiRemoteStationState * +WifiRemoteStationManager::LookupState (Mac48Address address) const { - if (packet->GetSize () > GetManager ()->GetRtsCtsThreshold ()) + for (StationStates::const_iterator i = m_states.begin (); i != m_states.end (); i++) { - return true; - } - else - { - return false; + if ((*i)->m_address == address) + { + return (*i); + } } + WifiRemoteStationState *state = new WifiRemoteStationState (); + state->m_state = WifiRemoteStationState::BRAND_NEW; + state->m_address = address; + state->m_modes.push_back (GetDefaultMode ()); + return state; } -bool -WifiRemoteStation::NeedRtsRetransmission (Ptr packet) +WifiRemoteStation * +WifiRemoteStationManager::Lookup (Mac48Address address, const WifiMacHeader *header) const { - return (m_ssrc < GetManager ()->GetMaxSsrc ()); -} - -bool -WifiRemoteStation::NeedDataRetransmission (Ptr packet) -{ - return (m_slrc < GetManager ()->GetMaxSlrc ()); -} - -bool -WifiRemoteStation::NeedFragmentation (Ptr packet) -{ - if (packet->GetSize () > GetManager ()->GetFragmentationThreshold ()) + uint8_t tid; + if (header->IsQosData ()) { - return true; - } - else - { - return false; - } -} -uint32_t -WifiRemoteStation::GetNFragments (Ptr packet) -{ - uint32_t nFragments = packet->GetSize () / GetManager ()->GetFragmentationThreshold () + 1; - return nFragments; -} - -uint32_t -WifiRemoteStation::GetFragmentSize (Ptr packet, uint32_t fragmentNumber) -{ - uint32_t nFragment = GetNFragments (packet); - if (fragmentNumber >= nFragment) - { - return 0; - } - if (fragmentNumber == nFragment - 1) - { - uint32_t lastFragmentSize = packet->GetSize () % GetManager ()->GetFragmentationThreshold (); - return lastFragmentSize; + tid = header->GetQosTid (); } else { - return GetManager ()->GetFragmentationThreshold (); + tid = 0; } + return Lookup (address, tid); } -uint32_t -WifiRemoteStation::GetFragmentOffset (Ptr packet, uint32_t fragmentNumber) +WifiRemoteStation * +WifiRemoteStationManager::Lookup (Mac48Address address, uint8_t tid) const { - NS_ASSERT (fragmentNumber < GetNFragments (packet)); - uint32_t fragmentOffset = fragmentNumber * GetManager ()->GetFragmentationThreshold (); - return fragmentOffset; + for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) + { + if ((*i)->m_tid == tid && + (*i)->m_state->m_address == address) + { + return (*i); + } + } + WifiRemoteStationState *state = LookupState (address); + + WifiRemoteStation *station = DoCreateStation (); + station->m_state = state; + station->m_ssrc = 0; + station->m_slrc = 0; + station->m_avgSlrc = 0; + // XXX + const_cast (this)->m_stations.push_back (station); + return station; + } +WifiMode +WifiRemoteStationManager::GetDefaultMode (void) const +{ + return m_defaultTxMode; +} +void +WifiRemoteStationManager::Reset (void) +{ + for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) + { + delete (*i); + } + m_stations.clear (); + m_basicModes.clear (); + m_basicModes.push_back (m_defaultTxMode); + NS_ASSERT (m_defaultTxMode.IsMandatory ()); +} +void +WifiRemoteStationManager::AddBasicMode (WifiMode mode) +{ + for (uint32_t i = 0; i < GetNBasicModes (); i++) + { + if (GetBasicMode (i) == mode) + { + return; + } + } + m_basicModes.push_back (mode); +} +uint32_t +WifiRemoteStationManager::GetNBasicModes (void) const +{ + return m_basicModes.size (); +} +WifiMode +WifiRemoteStationManager::GetBasicMode (uint32_t i) const +{ + NS_ASSERT (i < m_basicModes.size ()); + return m_basicModes[i]; +} +WifiRemoteStationManager::BasicModesIterator +WifiRemoteStationManager::BeginBasicModes (void) const +{ + return m_basicModes.begin (); +} +WifiRemoteStationManager::BasicModesIterator +WifiRemoteStationManager::EndBasicModes (void) const +{ + return m_basicModes.end (); +} + +WifiMode +WifiRemoteStationManager::GetNonUnicastMode (void) const +{ + if (m_nonUnicastMode == WifiMode ()) + { + return GetBasicMode(0); + } + else + { + return m_nonUnicastMode; + } +} + +bool +WifiRemoteStationManager::DoNeedRts (WifiRemoteStation *station, + Ptr packet, bool normally) +{ + return normally; +} +bool +WifiRemoteStationManager::DoNeedRtsRetransmission (WifiRemoteStation *station, + Ptr packet, bool normally) +{ + return normally; +} bool -WifiRemoteStation::IsLastFragment (Ptr packet, uint32_t fragmentNumber) +WifiRemoteStationManager::DoNeedDataRetransmission (WifiRemoteStation *station, + Ptr packet, bool normally) { - if (fragmentNumber == (GetNFragments (packet) - 1)) - { - return true; - } - else - { - return false; - } + return normally; +} +bool +WifiRemoteStationManager::DoNeedFragmentation (WifiRemoteStation *station, + Ptr packet, bool normally) +{ + return normally; } -void -WifiRemoteStation::ReportRtsFailed (void) +WifiMode +WifiRemoteStationManager::GetSupported (const WifiRemoteStation *station, uint32_t i) const { - m_ssrc++; - GetManager ()->NotifyTxRtsFailed (m_address); - DoReportRtsFailed (); + NS_ASSERT (i < GetNSupported (station)); + return station->m_state->m_modes[i]; +} +uint32_t +WifiRemoteStationManager::GetNSupported (const WifiRemoteStation *station) const +{ + return station->m_state->m_modes.size (); } -void -WifiRemoteStation::ReportDataFailed (void) -{ - m_slrc++; - GetManager ()->NotifyTxDataFailed (m_address); - DoReportDataFailed (); -} -void -WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr) -{ - m_ssrc = 0; - DoReportRtsOk (ctsSnr, ctsMode, rtsSnr); -} - -void -WifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr) -{ - m_avgSlrc = m_avgSlrc * m_avgSlrcCoefficient + (double) m_slrc * (1 - m_avgSlrcCoefficient); - m_slrc = 0; - DoReportDataOk (ackSnr, ackMode, dataSnr); -} - -void -WifiRemoteStation::ReportFinalRtsFailed (void) -{ - m_ssrc = 0; - GetManager ()->NotifyTxFinalRtsFailed (m_address); - DoReportFinalRtsFailed (); -} - -void -WifiRemoteStation::ReportFinalDataFailed (void) -{ - m_slrc = 0; - GetManager ()->NotifyTxFinalDataFailed (m_address); - DoReportFinalDataFailed (); -} - -void -WifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode) -{ - DoReportRxOk (rxSnr, txMode); -} } // namespace ns3 - diff --git a/src/devices/wifi/wifi-remote-station-manager.h b/src/devices/wifi/wifi-remote-station-manager.h index c6531d441..aa44757d0 100644 --- a/src/devices/wifi/wifi-remote-station-manager.h +++ b/src/devices/wifi/wifi-remote-station-manager.h @@ -23,16 +23,17 @@ #include #include #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 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 m_macTxRtsFailed; - - /** - * The trace source fired when the transmission of a data packet has failed - * - * \see class CallBackTraceSource - */ - TracedCallback m_macTxDataFailed; - - /** - * The trace source fired when the transmission of a RTS has - * exceeded the maximum number of attempts - * - * \see class CallBackTraceSource - */ - TracedCallback m_macTxFinalRtsFailed; - - /** - * The trace source fired when the transmission of a data packet has - * exceeded the maximum number of attempts - * - * \see class CallBackTraceSource - */ - TracedCallback 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 packet, uint32_t fullPacketSize); + void PrepareForQueue (Mac48Address address, const WifiMacHeader *header, + Ptr 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 packet, uint32_t fullPacketSize); + WifiMode GetDataMode (Mac48Address address, const WifiMacHeader *header, + Ptr 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 packet); + WifiMode GetRtsMode (Mac48Address address, const WifiMacHeader *header, + Ptr 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 packet); + bool NeedRts (Mac48Address address, const WifiMacHeader *header, + Ptr 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 packet); + bool NeedRtsRetransmission (Mac48Address address, const WifiMacHeader *header, + Ptr 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 packet); + bool NeedDataRetransmission (Mac48Address address, const WifiMacHeader *header, + Ptr packet); /** * \param packet the packet to send * \returns true if this packet should be fragmented, false otherwise. */ - virtual bool NeedFragmentation (Ptr packet); + bool NeedFragmentation (Mac48Address address, const WifiMacHeader *header, + Ptr 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 packet, uint32_t fragmentNumber); + uint32_t GetFragmentSize (Mac48Address address, const WifiMacHeader *header, + Ptr 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 packet, uint32_t fragmentNumber); + uint32_t GetFragmentOffset (Mac48Address address, const WifiMacHeader *header, + Ptr 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 packet, uint32_t fragmentNumber); + bool IsLastFragment (Mac48Address address, const WifiMacHeader *header, + Ptr 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 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 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 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 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 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 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 IEEE 802.11 Rate Adaptation: + * A Practical Approach, 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 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 m_ssrc; - TracedValue m_slrc; + + typedef std::vector Stations; + typedef std::vector 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 m_macTxRtsFailed; + /** + * The trace source fired when the transmission of a single data packet has failed + */ + TracedCallback m_macTxDataFailed; + /** + * The trace source fired when the transmission of a RTS has + * exceeded the maximum number of attempts + */ + TracedCallback m_macTxFinalRtsFailed; + /** + * The trace source fired when the transmission of a data packet has + * exceeded the maximum number of attempts + */ + TracedCallback m_macTxFinalDataFailed; + +}; + +struct WifiRemoteStationState +{ + typedef std::vector 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 */ diff --git a/src/devices/wifi/wscript b/src/devices/wifi/wscript index 63385c236..5696ee5f6 100644 --- a/src/devices/wifi/wscript +++ b/src/devices/wifi/wscript @@ -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', ] diff --git a/src/routing/aodv/aodv-routing-protocol.cc b/src/routing/aodv/aodv-routing-protocol.cc index 005007bbe..f86f1b502 100644 --- a/src/routing/aodv/aodv-routing-protocol.cc +++ b/src/routing/aodv/aodv-routing-protocol.cc @@ -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" diff --git a/src/test/ns3wifi/wifi-interference-test-suite.cc b/src/test/ns3wifi/wifi-interference-test-suite.cc index 200d64851..b0752ad0a 100644 --- a/src/test/ns3wifi/wifi-interference-test-suite.cc +++ b/src/test/ns3wifi/wifi-interference-test-suite.cc @@ -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"