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
15#define Min(a, b) ((a < b) ? a : b)
16
17namespace ns3
18{
19
20NS_LOG_COMPONENT_DEFINE("OnoeWifiManager");
21
22/**
23 * \brief hold per-remote-station state for ONOE Wifi manager.
24 *
25 * This struct extends from WifiRemoteStation struct to hold additional
26 * information required by the ONOE Wifi manager
27 */
29{
30 Time m_nextModeUpdate; ///< next mode update
31 bool m_rateBlocked; ///< whether the rate cannot be changed
32 uint32_t m_shortRetry; ///< short retry
33 uint32_t m_longRetry; ///< long retry
34 uint32_t m_tx_ok; ///< transmit OK
35 uint32_t m_tx_err; ///< transmit error
36 uint32_t m_tx_retr; ///< transmit retry
37 uint32_t m_tx_upper; ///< transmit upper
38 uint8_t m_txrate; ///< transmit rate
39};
40
42
45{
46 static TypeId tid =
47 TypeId("ns3::OnoeWifiManager")
49 .SetGroupName("Wifi")
50 .AddConstructor<OnoeWifiManager>()
51 .AddAttribute("UpdatePeriod",
52 "The interval between decisions about rate control changes",
53 TimeValue(Seconds(1.0)),
56 .AddAttribute("RaiseThreshold",
57 "Attempt to raise the rate if we hit that threshold",
58 UintegerValue(10),
61 .AddAttribute("AddCreditThreshold",
62 "Add credit threshold",
63 UintegerValue(10),
66 .AddTraceSource("Rate",
67 "Traced value for rate changes (b/s)",
69 "ns3::TracedValueCallback::Uint64");
70 return tid;
71}
72
75 m_currentRate(0)
76{
77 NS_LOG_FUNCTION(this);
78}
79
84
85void
87{
88 NS_LOG_FUNCTION(this);
89 if (GetHtSupported())
90 {
91 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HT rates");
92 }
93 if (GetVhtSupported())
94 {
95 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support VHT rates");
96 }
97 if (GetHeSupported())
98 {
99 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HE rates");
100 }
101}
102
105{
106 NS_LOG_FUNCTION(this);
107 auto station = new OnoeWifiRemoteStation();
108 station->m_nextModeUpdate = Simulator::Now() + m_updatePeriod;
109 station->m_rateBlocked = false;
110 station->m_shortRetry = 0;
111 station->m_longRetry = 0;
112 station->m_tx_ok = 0;
113 station->m_tx_err = 0;
114 station->m_tx_retr = 0;
115 station->m_tx_upper = 0;
116 station->m_txrate = 0;
117 return station;
118}
119
120void
122{
123 NS_LOG_FUNCTION(this << station << rxSnr << txMode);
124}
125
126void
128{
129 NS_LOG_FUNCTION(this << st);
130 auto station = static_cast<OnoeWifiRemoteStation*>(st);
131 station->m_shortRetry++;
132 station->m_rateBlocked = true; // do not change rate for retransmission
133}
134
135void
137{
138 NS_LOG_FUNCTION(this << st);
139 auto station = static_cast<OnoeWifiRemoteStation*>(st);
140 station->m_longRetry++;
141 station->m_rateBlocked = true; // do not change rate for retransmission
142}
143
144void
146 double ctsSnr,
147 WifiMode ctsMode,
148 double rtsSnr)
149{
150 NS_LOG_FUNCTION(this << st << ctsSnr << ctsMode << rtsSnr);
151 auto station = static_cast<OnoeWifiRemoteStation*>(st);
152 station->m_rateBlocked = true; // do not change rate
153}
154
155void
157 double ackSnr,
158 WifiMode ackMode,
159 double dataSnr,
160 MHz_u dataChannelWidth,
161 uint8_t dataNss)
162{
163 NS_LOG_FUNCTION(this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
164 auto station = static_cast<OnoeWifiRemoteStation*>(st);
165 UpdateRetry(station);
166 station->m_tx_ok++;
167 station->m_rateBlocked = false; // we can change the rate for next packet
168}
169
170void
172{
173 NS_LOG_FUNCTION(this << st);
174 auto station = static_cast<OnoeWifiRemoteStation*>(st);
175 UpdateRetry(station);
176 station->m_tx_err++;
177 station->m_rateBlocked = false; // we can change the rate for next packet
178}
179
180void
182{
183 NS_LOG_FUNCTION(this << st);
184 auto station = static_cast<OnoeWifiRemoteStation*>(st);
185 UpdateRetry(station);
186 station->m_tx_err++;
187 station->m_rateBlocked = false; // we can change the rate for next packet
188}
189
190void
192{
193 NS_LOG_FUNCTION(this << station);
194 station->m_tx_retr += station->m_shortRetry + station->m_longRetry;
195 station->m_shortRetry = 0;
196 station->m_longRetry = 0;
197}
198
199void
201{
202 NS_LOG_FUNCTION(this << station);
203 if (Simulator::Now() < station->m_nextModeUpdate || station->m_rateBlocked)
204 {
205 return;
206 }
208 /**
209 * The following 20 lines of code were copied from the Onoe
210 * rate control kernel module used in the madwifi driver.
211 */
212
213 int dir = 0;
214 uint8_t nrate;
215 bool enough = (station->m_tx_ok + station->m_tx_err >= 10);
216
217 /* no packet reached -> down */
218 if (station->m_tx_err > 0 && station->m_tx_ok == 0)
219 {
220 dir = -1;
221 }
222
223 /* all packets needs retry in average -> down */
224 if (enough && station->m_tx_ok < station->m_tx_retr)
225 {
226 dir = -1;
227 }
228
229 /* no error and less than rate_raise% of packets need retry -> up */
230 if (enough && station->m_tx_err == 0 &&
231 station->m_tx_retr < (station->m_tx_ok * m_addCreditThreshold) / 100)
232 {
233 dir = 1;
234 }
235
236 NS_LOG_DEBUG(this << " ok " << station->m_tx_ok << " err " << station->m_tx_err << " retr "
237 << station->m_tx_retr << " upper " << station->m_tx_upper << " dir " << dir);
238
239 nrate = station->m_txrate;
240 switch (dir)
241 {
242 case 0:
243 if (enough && station->m_tx_upper > 0)
244 {
245 station->m_tx_upper--;
246 }
247 break;
248 case -1:
249 if (nrate > 0)
250 {
251 nrate--;
252 }
253 station->m_tx_upper = 0;
254 break;
255 case 1:
256 /* raise rate if we hit rate_raise_threshold */
257 if (++station->m_tx_upper < m_raiseThreshold)
258 {
259 break;
260 }
261 station->m_tx_upper = 0;
262 if (nrate + 1 < GetNSupported(station))
263 {
264 nrate++;
265 }
266 break;
267 }
268
269 if (nrate != station->m_txrate)
270 {
271 NS_ASSERT(nrate < GetNSupported(station));
272 station->m_txrate = nrate;
273 station->m_tx_ok = station->m_tx_err = station->m_tx_retr = station->m_tx_upper = 0;
274 }
275 else if (enough)
276 {
277 station->m_tx_ok = station->m_tx_err = station->m_tx_retr = 0;
278 }
279}
280
283{
284 NS_LOG_FUNCTION(this << st << allowedWidth);
285 auto station = static_cast<OnoeWifiRemoteStation*>(st);
286 UpdateMode(station);
287 NS_ASSERT(station->m_txrate < GetNSupported(station));
288 uint8_t rateIndex;
289 if (station->m_longRetry < 4)
290 {
291 rateIndex = station->m_txrate;
292 }
293 else if (station->m_longRetry < 6)
294 {
295 if (station->m_txrate > 0)
296 {
297 rateIndex = station->m_txrate - 1;
298 }
299 else
300 {
301 rateIndex = station->m_txrate;
302 }
303 }
304 else if (station->m_longRetry < 8)
305 {
306 if (station->m_txrate > 1)
307 {
308 rateIndex = station->m_txrate - 2;
309 }
310 else
311 {
312 rateIndex = station->m_txrate;
313 }
314 }
315 else
316 {
317 if (station->m_txrate > 2)
318 {
319 rateIndex = station->m_txrate - 3;
320 }
321 else
322 {
323 rateIndex = station->m_txrate;
324 }
325 }
326 auto channelWidth = GetChannelWidth(station);
327 if (channelWidth > 20 && channelWidth != 22)
328 {
329 channelWidth = 20;
330 }
331 WifiMode mode = GetSupported(station, rateIndex);
332 uint64_t rate = mode.GetDataRate(channelWidth);
333 if (m_currentRate != rate)
334 {
335 NS_LOG_DEBUG("New datarate: " << rate);
336 m_currentRate = rate;
337 }
338 return WifiTxVector(
339 mode,
342 NanoSeconds(800),
343 1,
344 1,
345 0,
346 channelWidth,
347 GetAggregation(station));
348}
349
352{
353 NS_LOG_FUNCTION(this << st);
354 auto station = static_cast<OnoeWifiRemoteStation*>(st);
355 auto channelWidth = GetChannelWidth(station);
356 if (channelWidth > 20 && channelWidth != 22)
357 {
358 channelWidth = 20;
359 }
360 UpdateMode(station);
361 WifiMode mode;
363 {
364 mode = GetSupported(station, 0);
365 }
366 else
367 {
368 mode = GetNonErpSupported(station, 0);
369 }
370 return WifiTxVector(
371 mode,
374 NanoSeconds(800),
375 1,
376 1,
377 0,
378 channelWidth,
379 GetAggregation(station));
380}
381
382} // 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:94
AttributeValue implementation for Time.
Definition nstime.h:1395
a unique identifier for an interface.
Definition type-id.h:48
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:40
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:174
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:111
hold a list of per-remote-station state.
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:1396
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416
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:1344
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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 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