A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
amrr-wifi-manager.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003,2007 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#include "amrr-wifi-manager.h"
21
22#include "ns3/log.h"
23#include "ns3/simulator.h"
24#include "ns3/wifi-tx-vector.h"
25
26#define Min(a, b) ((a < b) ? a : b)
27
28namespace ns3
29{
30
31NS_LOG_COMPONENT_DEFINE("AmrrWifiManager");
32
40{
46 uint8_t m_txrate;
50};
51
53
56{
57 static TypeId tid =
58 TypeId("ns3::AmrrWifiManager")
60 .SetGroupName("Wifi")
61 .AddConstructor<AmrrWifiManager>()
62 .AddAttribute("UpdatePeriod",
63 "The interval between decisions about rate control changes",
64 TimeValue(Seconds(1.0)),
67 .AddAttribute(
68 "FailureRatio",
69 "Ratio of minimum erroneous transmissions needed to switch to a lower rate",
70 DoubleValue(1.0 / 3.0),
72 MakeDoubleChecker<double>(0.0, 1.0))
73 .AddAttribute(
74 "SuccessRatio",
75 "Ratio of maximum erroneous transmissions needed to switch to a higher rate",
76 DoubleValue(1.0 / 10.0),
78 MakeDoubleChecker<double>(0.0, 1.0))
79 .AddAttribute(
80 "MaxSuccessThreshold",
81 "Maximum number of consecutive success periods needed to switch to a higher rate",
82 UintegerValue(10),
84 MakeUintegerChecker<uint32_t>())
85 .AddAttribute(
86 "MinSuccessThreshold",
87 "Minimum number of consecutive success periods needed to switch to a higher rate",
90 MakeUintegerChecker<uint32_t>())
91 .AddTraceSource("Rate",
92 "Traced value for rate changes (b/s)",
94 "ns3::TracedValueCallback::Uint64");
95 return tid;
96}
97
100 m_currentRate(0)
101{
102 NS_LOG_FUNCTION(this);
103}
104
106{
107 NS_LOG_FUNCTION(this);
108}
109
110void
112{
113 NS_LOG_FUNCTION(this);
114 if (GetHtSupported())
115 {
116 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HT rates");
117 }
118 if (GetVhtSupported())
119 {
120 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support VHT rates");
121 }
122 if (GetHeSupported())
123 {
124 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HE rates");
125 }
126}
127
130{
131 NS_LOG_FUNCTION(this);
134 station->m_tx_ok = 0;
135 station->m_tx_err = 0;
136 station->m_tx_retr = 0;
137 station->m_retry = 0;
138 station->m_txrate = 0;
140 station->m_success = 0;
141 station->m_recovery = false;
142 return station;
143}
144
145void
147{
148 NS_LOG_FUNCTION(this << station << rxSnr << txMode);
149}
150
151void
153{
154 NS_LOG_FUNCTION(this << station);
155}
156
157void
159{
160 NS_LOG_FUNCTION(this << st);
161 AmrrWifiRemoteStation* station = static_cast<AmrrWifiRemoteStation*>(st);
162 station->m_retry++;
163 station->m_tx_retr++;
164}
165
166void
168 double ctsSnr,
169 WifiMode ctsMode,
170 double rtsSnr)
171{
172 NS_LOG_FUNCTION(this << st << ctsSnr << ctsMode << rtsSnr);
173}
174
175void
177 double ackSnr,
178 WifiMode ackMode,
179 double dataSnr,
180 uint16_t dataChannelWidth,
181 uint8_t dataNss)
182{
183 NS_LOG_FUNCTION(this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
184 AmrrWifiRemoteStation* station = static_cast<AmrrWifiRemoteStation*>(st);
185 station->m_retry = 0;
186 station->m_tx_ok++;
187}
188
189void
191{
192 NS_LOG_FUNCTION(this << station);
193}
194
195void
197{
198 NS_LOG_FUNCTION(this << st);
199 AmrrWifiRemoteStation* station = static_cast<AmrrWifiRemoteStation*>(st);
200 station->m_retry = 0;
201 station->m_tx_err++;
202}
203
204bool
206{
207 NS_LOG_FUNCTION(this << station);
208 return (station->m_txrate == 0);
209}
210
211bool
213{
214 NS_LOG_FUNCTION(this << station);
215 NS_ASSERT(station->m_txrate + 1 <= GetNSupported(station));
216 return (station->m_txrate + 1 == GetNSupported(station));
217}
218
219bool
221{
222 NS_LOG_FUNCTION(this << station);
223 return (station->m_tx_retr + station->m_tx_err) < station->m_tx_ok * m_successRatio;
224}
225
226bool
228{
229 NS_LOG_FUNCTION(this << station);
230 return (station->m_tx_retr + station->m_tx_err) > station->m_tx_ok * m_failureRatio;
231}
232
233bool
235{
236 NS_LOG_FUNCTION(this << station);
237 return (station->m_tx_retr + station->m_tx_err + station->m_tx_ok) > 10;
238}
239
240void
242{
243 NS_LOG_FUNCTION(this << station);
244 station->m_tx_ok = 0;
245 station->m_tx_err = 0;
246 station->m_tx_retr = 0;
247}
248
249void
251{
252 NS_LOG_FUNCTION(this << station);
253 station->m_txrate++;
254 NS_ASSERT(station->m_txrate < GetNSupported(station));
255}
256
257void
259{
260 NS_LOG_FUNCTION(this << station);
261 station->m_txrate--;
262}
263
264void
266{
267 NS_LOG_FUNCTION(this << station);
268 if (Simulator::Now() < station->m_nextModeUpdate)
269 {
270 return;
271 }
273 NS_LOG_DEBUG("Update");
274
275 bool needChange = false;
276
277 if (IsSuccess(station) && IsEnough(station))
278 {
279 station->m_success++;
280 NS_LOG_DEBUG("++ success="
281 << station->m_success << " successThreshold=" << station->m_successThreshold
282 << " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err
283 << " tx_retr=" << station->m_tx_retr << " rate=" << +station->m_txrate
284 << " n-supported-rates=" << +GetNSupported(station));
285 if (station->m_success >= station->m_successThreshold && !IsMaxRate(station))
286 {
287 station->m_recovery = true;
288 station->m_success = 0;
289 IncreaseRate(station);
290 needChange = true;
291 }
292 else
293 {
294 station->m_recovery = false;
295 }
296 }
297 else if (IsFailure(station))
298 {
299 station->m_success = 0;
300 NS_LOG_DEBUG("-- success="
301 << station->m_success << " successThreshold=" << station->m_successThreshold
302 << " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err
303 << " tx_retr=" << station->m_tx_retr << " rate=" << +station->m_txrate
304 << " n-supported-rates=" << +GetNSupported(station));
305 if (!IsMinRate(station))
306 {
307 if (station->m_recovery)
308 {
309 station->m_successThreshold *= 2;
310 station->m_successThreshold =
311 std::min(station->m_successThreshold, m_maxSuccessThreshold);
312 }
313 else
314 {
316 }
317 station->m_recovery = false;
318 DecreaseRate(station);
319 needChange = true;
320 }
321 else
322 {
323 station->m_recovery = false;
324 }
325 }
326 if (IsEnough(station) || needChange)
327 {
328 NS_LOG_DEBUG("Reset");
329 ResetCnt(station);
330 }
331}
332
335{
336 NS_LOG_FUNCTION(this << st << allowedWidth);
337 AmrrWifiRemoteStation* station = static_cast<AmrrWifiRemoteStation*>(st);
338 UpdateMode(station);
339 NS_ASSERT(station->m_txrate < GetNSupported(station));
340 uint8_t rateIndex;
341 if (station->m_retry < 1)
342 {
343 rateIndex = station->m_txrate;
344 }
345 else if (station->m_retry < 2)
346 {
347 if (station->m_txrate > 0)
348 {
349 rateIndex = station->m_txrate - 1;
350 }
351 else
352 {
353 rateIndex = station->m_txrate;
354 }
355 }
356 else if (station->m_retry < 3)
357 {
358 if (station->m_txrate > 1)
359 {
360 rateIndex = station->m_txrate - 2;
361 }
362 else
363 {
364 rateIndex = station->m_txrate;
365 }
366 }
367 else
368 {
369 if (station->m_txrate > 2)
370 {
371 rateIndex = station->m_txrate - 3;
372 }
373 else
374 {
375 rateIndex = station->m_txrate;
376 }
377 }
378 uint16_t channelWidth = GetChannelWidth(station);
379 if (channelWidth > 20 && channelWidth != 22)
380 {
381 channelWidth = 20;
382 }
383 WifiMode mode = GetSupported(station, rateIndex);
384 uint64_t rate = mode.GetDataRate(channelWidth);
385 if (m_currentRate != rate)
386 {
387 NS_LOG_DEBUG("New datarate: " << rate);
388 m_currentRate = rate;
389 }
390 return WifiTxVector(
391 mode,
394 800,
395 1,
396 1,
397 0,
398 channelWidth,
399 GetAggregation(station));
400}
401
404{
405 NS_LOG_FUNCTION(this << st);
406 AmrrWifiRemoteStation* station = static_cast<AmrrWifiRemoteStation*>(st);
407 uint16_t channelWidth = GetChannelWidth(station);
408 if (channelWidth > 20 && channelWidth != 22)
409 {
410 channelWidth = 20;
411 }
412 UpdateMode(station);
413 WifiMode mode;
415 {
416 mode = GetSupported(station, 0);
417 }
418 else
419 {
420 mode = GetNonErpSupported(station, 0);
421 }
422 return WifiTxVector(
423 mode,
426 800,
427 1,
428 1,
429 0,
430 channelWidth,
431 GetAggregation(station));
432}
433
434} // namespace ns3
AMRR Rate control algorithm.
double m_failureRatio
failure ratio
static TypeId GetTypeId()
Get the type ID.
void UpdateMode(AmrrWifiRemoteStation *station)
Update the mode used to send to the given station.
void DoReportFinalRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
uint32_t m_minSuccessThreshold
minimum success threshold
bool IsMaxRate(AmrrWifiRemoteStation *station) const
Check if the current rate for the given station is the maximum rate.
TracedValue< uint64_t > m_currentRate
Trace rate changes.
bool IsMinRate(AmrrWifiRemoteStation *station) const
Check if the current rate for the given station is the minimum rate.
void DoInitialize() override
Initialize() implementation.
void DoReportRtsOk(WifiRemoteStation *station, double ctsSnr, WifiMode ctsMode, double rtsSnr) override
This method is a pure virtual method that must be implemented by the sub-class.
void ResetCnt(AmrrWifiRemoteStation *station)
Reset transmission statistics of the given station.
uint32_t m_maxSuccessThreshold
maximum success threshold
bool IsEnough(AmrrWifiRemoteStation *station) const
Check if the number of retransmission, transmission error, and successful transmission are greater th...
void DoReportRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
void DecreaseRate(AmrrWifiRemoteStation *station)
Decrease the transmission rate to the given station.
void DoReportFinalDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
bool IsSuccess(AmrrWifiRemoteStation *station) const
Check if the number of retransmission and transmission error is less than the number of successful tr...
WifiRemoteStation * DoCreateStation() const override
void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode) override
This method is a pure virtual method that must be implemented by the sub-class.
void DoReportDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
Time m_updatePeriod
update period
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station, uint16_t allowedWidth) override
void IncreaseRate(AmrrWifiRemoteStation *station)
Increase the transmission rate to the given station.
void DoReportDataOk(WifiRemoteStation *station, double ackSnr, WifiMode ackMode, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss) override
This method is a pure virtual method that must be implemented by the sub-class.
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station) override
bool IsFailure(AmrrWifiRemoteStation *station) const
Check if the number of retransmission and transmission error is greater than the number of successful...
double m_successRatio
success ratio
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
represent a single transmission mode
Definition: wifi-mode.h:51
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
hold a list of per-remote-station state.
uint16_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
uint8_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
bool GetHtSupported() const
Return whether the device has HT capability support enabled.
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether non-ERP mode associated with the specified station at the specified index.
bool GetUseNonErpProtection() const
Return whether the device supports protection of non-ERP stations.
bool GetVhtSupported() const
Return whether the device has VHT capability support enabled.
bool GetShortPreambleEnabled() const
Return whether the device uses short PHY preambles.
WifiMode GetSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether mode associated with the specified station at the specified index.
bool GetHeSupported() const
Return whether the device has HE capability support enabled.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble)
Return the preamble to be used for the transmission.
hold per-remote-station state for AMRR Wifi manager.
uint8_t m_txrate
transmit rate
Time m_nextModeUpdate
next mode update time
uint32_t m_tx_err
transmit error
uint32_t m_tx_ok
transmit OK
uint32_t m_tx_retr
transmit retry
uint32_t m_successThreshold
success threshold
hold per-remote-station state.