A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
onoe-wifi-manager.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003,2007 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "onoe-wifi-manager.h"
10
11#include "ns3/log.h"
12#include "ns3/simulator.h"
13#include "ns3/wifi-tx-vector.h"
14
15namespace ns3
16{
17
18NS_LOG_COMPONENT_DEFINE("OnoeWifiManager");
19
20/**
21 * @brief hold per-remote-station state for ONOE Wifi manager.
22 *
23 * This struct extends from WifiRemoteStation struct to hold additional
24 * information required by the ONOE Wifi manager
25 */
27{
28 Time m_nextModeUpdate; ///< next mode update
29 bool m_rateBlocked; ///< whether the rate cannot be changed
30 uint32_t m_shortRetry; ///< short retry
31 uint32_t m_longRetry; ///< long retry
32 uint32_t m_tx_ok; ///< transmit OK
33 uint32_t m_tx_err; ///< transmit error
34 uint32_t m_tx_retr; ///< transmit retry
35 uint32_t m_tx_upper; ///< transmit upper
36 uint8_t m_txrate; ///< transmit rate
37};
38
40
43{
44 static TypeId tid =
45 TypeId("ns3::OnoeWifiManager")
47 .SetGroupName("Wifi")
48 .AddConstructor<OnoeWifiManager>()
49 .AddAttribute("UpdatePeriod",
50 "The interval between decisions about rate control changes",
54 .AddAttribute("RaiseThreshold",
55 "Attempt to raise the rate if we hit that threshold",
56 UintegerValue(10),
59 .AddAttribute("AddCreditThreshold",
60 "Add credit threshold",
61 UintegerValue(10),
64 .AddTraceSource("Rate",
65 "Traced value for rate changes (b/s)",
67 "ns3::TracedValueCallback::Uint64");
68 return tid;
69}
70
77
82
83void
85{
86 NS_LOG_FUNCTION(this);
87 if (GetHtSupported())
88 {
89 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HT rates");
90 }
91 if (GetVhtSupported())
92 {
93 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support VHT rates");
94 }
95 if (GetHeSupported())
96 {
97 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HE rates");
98 }
99}
100
103{
104 NS_LOG_FUNCTION(this);
105 auto station = new OnoeWifiRemoteStation();
106 station->m_nextModeUpdate = Simulator::Now() + m_updatePeriod;
107 station->m_rateBlocked = false;
108 station->m_shortRetry = 0;
109 station->m_longRetry = 0;
110 station->m_tx_ok = 0;
111 station->m_tx_err = 0;
112 station->m_tx_retr = 0;
113 station->m_tx_upper = 0;
114 station->m_txrate = 0;
115 return station;
116}
117
118void
120{
121 NS_LOG_FUNCTION(this << station << rxSnr << txMode);
122}
123
124void
126{
127 NS_LOG_FUNCTION(this << st);
128 auto station = static_cast<OnoeWifiRemoteStation*>(st);
129 station->m_shortRetry++;
130 station->m_rateBlocked = true; // do not change rate for retransmission
131}
132
133void
135{
136 NS_LOG_FUNCTION(this << st);
137 auto station = static_cast<OnoeWifiRemoteStation*>(st);
138 station->m_longRetry++;
139 station->m_rateBlocked = true; // do not change rate for retransmission
140}
141
142void
144 double ctsSnr,
145 WifiMode ctsMode,
146 double rtsSnr)
147{
148 NS_LOG_FUNCTION(this << st << ctsSnr << ctsMode << rtsSnr);
149 auto station = static_cast<OnoeWifiRemoteStation*>(st);
150 station->m_rateBlocked = true; // do not change rate
151}
152
153void
155 double ackSnr,
156 WifiMode ackMode,
157 double dataSnr,
158 MHz_u dataChannelWidth,
159 uint8_t dataNss)
160{
161 NS_LOG_FUNCTION(this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
162 auto station = static_cast<OnoeWifiRemoteStation*>(st);
163 UpdateRetry(station);
164 station->m_tx_ok++;
165 station->m_rateBlocked = false; // we can change the rate for next packet
166}
167
168void
170{
171 NS_LOG_FUNCTION(this << st);
172 auto station = static_cast<OnoeWifiRemoteStation*>(st);
173 UpdateRetry(station);
174 station->m_tx_err++;
175 station->m_rateBlocked = false; // we can change the rate for next packet
176}
177
178void
180{
181 NS_LOG_FUNCTION(this << st);
182 auto station = static_cast<OnoeWifiRemoteStation*>(st);
183 UpdateRetry(station);
184 station->m_tx_err++;
185 station->m_rateBlocked = false; // we can change the rate for next packet
186}
187
188void
190{
191 NS_LOG_FUNCTION(this << station);
192 station->m_tx_retr += station->m_shortRetry + station->m_longRetry;
193 station->m_shortRetry = 0;
194 station->m_longRetry = 0;
195}
196
197void
199{
200 NS_LOG_FUNCTION(this << station);
201 if (Simulator::Now() < station->m_nextModeUpdate || station->m_rateBlocked)
202 {
203 return;
204 }
206 /**
207 * The following 20 lines of code were copied from the Onoe
208 * rate control kernel module used in the madwifi driver.
209 */
210
211 int dir = 0;
212 uint8_t nrate;
213 bool enough = (station->m_tx_ok + station->m_tx_err >= 10);
214
215 /* no packet reached -> down */
216 if (station->m_tx_err > 0 && station->m_tx_ok == 0)
217 {
218 dir = -1;
219 }
220
221 /* all packets needs retry in average -> down */
222 if (enough && station->m_tx_ok < station->m_tx_retr)
223 {
224 dir = -1;
225 }
226
227 /* no error and less than rate_raise% of packets need retry -> up */
228 if (enough && station->m_tx_err == 0 &&
229 station->m_tx_retr < (station->m_tx_ok * m_addCreditThreshold) / 100)
230 {
231 dir = 1;
232 }
233
234 NS_LOG_DEBUG(this << " ok " << station->m_tx_ok << " err " << station->m_tx_err << " retr "
235 << station->m_tx_retr << " upper " << station->m_tx_upper << " dir " << dir);
236
237 nrate = station->m_txrate;
238 switch (dir)
239 {
240 case 0:
241 if (enough && station->m_tx_upper > 0)
242 {
243 station->m_tx_upper--;
244 }
245 break;
246 case -1:
247 if (nrate > 0)
248 {
249 nrate--;
250 }
251 station->m_tx_upper = 0;
252 break;
253 case 1:
254 /* raise rate if we hit rate_raise_threshold */
255 if (++station->m_tx_upper < m_raiseThreshold)
256 {
257 break;
258 }
259 station->m_tx_upper = 0;
260 if (nrate + 1 < GetNSupported(station))
261 {
262 nrate++;
263 }
264 break;
265 }
266
267 if (nrate != station->m_txrate)
268 {
269 NS_ASSERT(nrate < GetNSupported(station));
270 station->m_txrate = nrate;
271 station->m_tx_ok = station->m_tx_err = station->m_tx_retr = station->m_tx_upper = 0;
272 }
273 else if (enough)
274 {
275 station->m_tx_ok = station->m_tx_err = station->m_tx_retr = 0;
276 }
277}
278
281{
282 NS_LOG_FUNCTION(this << st << allowedWidth);
283 auto station = static_cast<OnoeWifiRemoteStation*>(st);
284 UpdateMode(station);
285 NS_ASSERT(station->m_txrate < GetNSupported(station));
286 uint8_t rateIndex;
287 if (station->m_longRetry < 4)
288 {
289 rateIndex = station->m_txrate;
290 }
291 else if (station->m_longRetry < 6)
292 {
293 if (station->m_txrate > 0)
294 {
295 rateIndex = station->m_txrate - 1;
296 }
297 else
298 {
299 rateIndex = station->m_txrate;
300 }
301 }
302 else if (station->m_longRetry < 8)
303 {
304 if (station->m_txrate > 1)
305 {
306 rateIndex = station->m_txrate - 2;
307 }
308 else
309 {
310 rateIndex = station->m_txrate;
311 }
312 }
313 else
314 {
315 if (station->m_txrate > 2)
316 {
317 rateIndex = station->m_txrate - 3;
318 }
319 else
320 {
321 rateIndex = station->m_txrate;
322 }
323 }
324 auto channelWidth = GetChannelWidth(station);
325 if (channelWidth > MHz_u{20} && channelWidth != MHz_u{22})
326 {
327 channelWidth = MHz_u{20};
328 }
329 WifiMode mode = GetSupported(station, rateIndex);
330 uint64_t rate = mode.GetDataRate(channelWidth);
331 if (m_currentRate != rate)
332 {
333 NS_LOG_DEBUG("New datarate: " << rate);
334 m_currentRate = rate;
335 }
336 return WifiTxVector(
337 mode,
340 NanoSeconds(800),
341 1,
342 1,
343 0,
344 channelWidth,
345 GetAggregation(station));
346}
347
350{
351 NS_LOG_FUNCTION(this << st);
352 auto station = static_cast<OnoeWifiRemoteStation*>(st);
353 auto channelWidth = GetChannelWidth(station);
354 if (channelWidth > MHz_u{20} && channelWidth != MHz_u{22})
355 {
356 channelWidth = MHz_u{20};
357 }
358 UpdateMode(station);
359 WifiMode mode;
361 {
362 mode = GetSupported(station, 0);
363 }
364 else
365 {
366 mode = GetNonErpSupported(station, 0);
367 }
368 return WifiTxVector(
369 mode,
372 NanoSeconds(800),
373 1,
374 1,
375 0,
376 channelWidth,
377 GetAggregation(station));
378}
379
380} // namespace ns3
an implementation of the rate control algorithm developed by Atsushi Onoe
WifiRemoteStation * DoCreateStation() const override
void DoInitialize() override
Initialize() implementation.
void UpdateRetry(OnoeWifiRemoteStation *station)
Update the number of retry (both short and long).
Time m_updatePeriod
update period
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.
TracedValue< uint64_t > m_currentRate
Trace rate changes.
void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode) override
This method is a pure virtual method that must be implemented by the sub-class.
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station) override
void DoReportRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
void DoReportFinalRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
uint32_t m_addCreditThreshold
add credit threshold
uint32_t m_raiseThreshold
raise threshold
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station, MHz_u allowedWidth) override
static TypeId GetTypeId()
Get the type ID.
void DoReportDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
void DoReportFinalDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
void DoReportDataOk(WifiRemoteStation *station, double ackSnr, WifiMode ackMode, double dataSnr, MHz_u dataChannelWidth, uint8_t dataNss) override
This method is a pure virtual method that must be implemented by the sub-class.
void UpdateMode(OnoeWifiRemoteStation *station)
Update the mode.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
AttributeValue implementation for Time.
Definition nstime.h:1456
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
represent a single transmission mode
Definition wifi-mode.h:38
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:172
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:110
uint8_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
MHz_u GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the 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 on the link this manager is associated wi...
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 on the link this manager is associated w...
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:55
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition nstime.h:1457
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1477
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:35
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1405
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
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.
double MHz_u
MHz weak type.
Definition wifi-units.h:31
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble)
Return the preamble to be used for the transmission.
hold per-remote-station state for ONOE Wifi manager.
uint32_t m_tx_retr
transmit retry
uint32_t m_shortRetry
short retry
uint8_t m_txrate
transmit rate
bool m_rateBlocked
whether the rate cannot be changed
Time m_nextModeUpdate
next mode update
uint32_t m_tx_upper
transmit upper
uint32_t m_tx_err
transmit error
hold per-remote-station state.
std::string dir