1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2005,2006,2007 INRIA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 */
20
21 #include "ns3/log.h"
22 #include "ns3/boolean.h"
23 #include "ns3/uinteger.h"
24 #include "ns3/enum.h"
25 #include "ns3/simulator.h"
26 #include "wifi-remote-station-manager.h"
27 #include "wifi-phy.h"
28 #include "ap-wifi-mac.h"
29 #include "sta-wifi-mac.h"
30 #include "wifi-mac-header.h"
31 #include "wifi-mac-queue-item.h"
32 #include "wifi-mac-trailer.h"
33 #include "ns3/ht-configuration.h"
34 #include "ns3/ht-phy.h"
35 #include "ns3/vht-configuration.h"
36 #include "ns3/he-configuration.h"
37 #include "wifi-net-device.h"
38
39 namespace ns3 {
40
41 NS_LOG_COMPONENT_DEFINE ("WifiRemoteStationManager");
42
43 NS_OBJECT_ENSURE_REGISTERED (WifiRemoteStationManager);
44
45 TypeId
GetTypeId(void)46 WifiRemoteStationManager::GetTypeId (void)
47 {
48 static TypeId tid = TypeId ("ns3::WifiRemoteStationManager")
49 .SetParent<Object> ()
50 .SetGroupName ("Wifi")
51 .AddAttribute ("MaxSsrc",
52 "The maximum number of retransmission attempts for any packet with size <= RtsCtsThreshold. "
53 "This value will not have any effect on some rate control algorithms.",
54 UintegerValue (7),
55 MakeUintegerAccessor (&WifiRemoteStationManager::SetMaxSsrc),
56 MakeUintegerChecker<uint32_t> ())
57 .AddAttribute ("MaxSlrc",
58 "The maximum number of retransmission attempts for any packet with size > RtsCtsThreshold. "
59 "This value will not have any effect on some rate control algorithms.",
60 UintegerValue (4),
61 MakeUintegerAccessor (&WifiRemoteStationManager::SetMaxSlrc),
62 MakeUintegerChecker<uint32_t> ())
63 .AddAttribute ("RtsCtsThreshold",
64 "If the size of the PSDU is bigger than this value, we use an RTS/CTS handshake before sending the data frame."
65 "This value will not have any effect on some rate control algorithms.",
66 UintegerValue (65535),
67 MakeUintegerAccessor (&WifiRemoteStationManager::SetRtsCtsThreshold),
68 MakeUintegerChecker<uint32_t> ())
69 .AddAttribute ("FragmentationThreshold",
70 "If the size of the PSDU is bigger than this value, we fragment it such that the size of the fragments are equal or smaller. "
71 "This value does not apply when it is carried in an A-MPDU. "
72 "This value will not have any effect on some rate control algorithms.",
73 UintegerValue (65535),
74 MakeUintegerAccessor (&WifiRemoteStationManager::DoSetFragmentationThreshold,
75 &WifiRemoteStationManager::DoGetFragmentationThreshold),
76 MakeUintegerChecker<uint32_t> ())
77 .AddAttribute ("NonUnicastMode",
78 "Wifi mode used for non-unicast transmissions.",
79 WifiModeValue (),
80 MakeWifiModeAccessor (&WifiRemoteStationManager::m_nonUnicastMode),
81 MakeWifiModeChecker ())
82 .AddAttribute ("DefaultTxPowerLevel",
83 "Default power level to be used for transmissions. "
84 "This is the power level that is used by all those WifiManagers that do not implement TX power control.",
85 UintegerValue (0),
86 MakeUintegerAccessor (&WifiRemoteStationManager::m_defaultTxPowerLevel),
87 MakeUintegerChecker<uint8_t> ())
88 .AddAttribute ("ErpProtectionMode",
89 "Protection mode used when non-ERP STAs are connected to an ERP AP: Rts-Cts or Cts-To-Self",
90 EnumValue (WifiRemoteStationManager::CTS_TO_SELF),
91 MakeEnumAccessor (&WifiRemoteStationManager::m_erpProtectionMode),
92 MakeEnumChecker (WifiRemoteStationManager::RTS_CTS, "Rts-Cts",
93 WifiRemoteStationManager::CTS_TO_SELF, "Cts-To-Self"))
94 .AddAttribute ("HtProtectionMode",
95 "Protection mode used when non-HT STAs are connected to a HT AP: Rts-Cts or Cts-To-Self",
96 EnumValue (WifiRemoteStationManager::CTS_TO_SELF),
97 MakeEnumAccessor (&WifiRemoteStationManager::m_htProtectionMode),
98 MakeEnumChecker (WifiRemoteStationManager::RTS_CTS, "Rts-Cts",
99 WifiRemoteStationManager::CTS_TO_SELF, "Cts-To-Self"))
100 .AddTraceSource ("MacTxRtsFailed",
101 "The transmission of a RTS by the MAC layer has failed",
102 MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxRtsFailed),
103 "ns3::Mac48Address::TracedCallback")
104 .AddTraceSource ("MacTxDataFailed",
105 "The transmission of a data packet by the MAC layer has failed",
106 MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxDataFailed),
107 "ns3::Mac48Address::TracedCallback")
108 .AddTraceSource ("MacTxFinalRtsFailed",
109 "The transmission of a RTS has exceeded the maximum number of attempts",
110 MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalRtsFailed),
111 "ns3::Mac48Address::TracedCallback")
112 .AddTraceSource ("MacTxFinalDataFailed",
113 "The transmission of a data packet has exceeded the maximum number of attempts",
114 MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalDataFailed),
115 "ns3::Mac48Address::TracedCallback")
116 ;
117 return tid;
118 }
119
WifiRemoteStationManager()120 WifiRemoteStationManager::WifiRemoteStationManager ()
121 : m_useNonErpProtection (false),
122 m_useNonHtProtection (false),
123 m_shortPreambleEnabled (false),
124 m_shortSlotTimeEnabled (false)
125 {
126 NS_LOG_FUNCTION (this);
127 }
128
~WifiRemoteStationManager()129 WifiRemoteStationManager::~WifiRemoteStationManager ()
130 {
131 NS_LOG_FUNCTION (this);
132 }
133
134 void
DoDispose(void)135 WifiRemoteStationManager::DoDispose (void)
136 {
137 NS_LOG_FUNCTION (this);
138 Reset ();
139 }
140
141 void
SetupPhy(const Ptr<WifiPhy> phy)142 WifiRemoteStationManager::SetupPhy (const Ptr<WifiPhy> phy)
143 {
144 NS_LOG_FUNCTION (this << phy);
145 //We need to track our PHY because it is the object that knows the
146 //full set of transmit rates that are supported. We need to know
147 //this in order to find the relevant mandatory rates when choosing a
148 //transmit rate for automatic control responses like
149 //acknowledgments.
150 m_wifiPhy = phy;
151 m_defaultTxMode = phy->GetDefaultMode ();
152 NS_ASSERT (m_defaultTxMode.IsMandatory ());
153 if (GetHtSupported ())
154 {
155 m_defaultTxMcs = HtPhy::GetHtMcs (0);
156 }
157 Reset ();
158 }
159
160 void
SetupMac(const Ptr<WifiMac> mac)161 WifiRemoteStationManager::SetupMac (const Ptr<WifiMac> mac)
162 {
163 NS_LOG_FUNCTION (this << mac);
164 //We need to track our MAC because it is the object that knows the
165 //full set of interframe spaces.
166 m_wifiMac = mac;
167 Reset ();
168 }
169
170 int64_t
AssignStreams(int64_t stream)171 WifiRemoteStationManager::AssignStreams (int64_t stream)
172 {
173 NS_LOG_FUNCTION (this << stream);
174 return 0;
175 }
176
177 void
SetMaxSsrc(uint32_t maxSsrc)178 WifiRemoteStationManager::SetMaxSsrc (uint32_t maxSsrc)
179 {
180 NS_LOG_FUNCTION (this << maxSsrc);
181 m_maxSsrc = maxSsrc;
182 }
183
184 void
SetMaxSlrc(uint32_t maxSlrc)185 WifiRemoteStationManager::SetMaxSlrc (uint32_t maxSlrc)
186 {
187 NS_LOG_FUNCTION (this << maxSlrc);
188 m_maxSlrc = maxSlrc;
189 }
190
191 void
SetRtsCtsThreshold(uint32_t threshold)192 WifiRemoteStationManager::SetRtsCtsThreshold (uint32_t threshold)
193 {
194 NS_LOG_FUNCTION (this << threshold);
195 m_rtsCtsThreshold = threshold;
196 }
197
198 void
SetFragmentationThreshold(uint32_t threshold)199 WifiRemoteStationManager::SetFragmentationThreshold (uint32_t threshold)
200 {
201 NS_LOG_FUNCTION (this << threshold);
202 DoSetFragmentationThreshold (threshold);
203 }
204
205 void
SetShortPreambleEnabled(bool enable)206 WifiRemoteStationManager::SetShortPreambleEnabled (bool enable)
207 {
208 NS_LOG_FUNCTION (this << enable);
209 m_shortPreambleEnabled = enable;
210 }
211
212 void
SetShortSlotTimeEnabled(bool enable)213 WifiRemoteStationManager::SetShortSlotTimeEnabled (bool enable)
214 {
215 NS_LOG_FUNCTION (this << enable);
216 m_shortSlotTimeEnabled = enable;
217 }
218
219 bool
GetShortSlotTimeEnabled(void) const220 WifiRemoteStationManager::GetShortSlotTimeEnabled (void) const
221 {
222 return m_shortSlotTimeEnabled;
223 }
224
225 bool
GetShortPreambleEnabled(void) const226 WifiRemoteStationManager::GetShortPreambleEnabled (void) const
227 {
228 return m_shortPreambleEnabled;
229 }
230
231 bool
GetHtSupported(void) const232 WifiRemoteStationManager::GetHtSupported (void) const
233 {
234 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
235 Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
236 if (htConfiguration)
237 {
238 return true;
239 }
240 return false;
241 }
242
243 bool
GetVhtSupported(void) const244 WifiRemoteStationManager::GetVhtSupported (void) const
245 {
246 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
247 Ptr<VhtConfiguration> vhtConfiguration = device->GetVhtConfiguration ();
248 if (vhtConfiguration)
249 {
250 return true;
251 }
252 return false;
253 }
254
255 bool
GetHeSupported(void) const256 WifiRemoteStationManager::GetHeSupported (void) const
257 {
258 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
259 Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
260 if (heConfiguration)
261 {
262 return true;
263 }
264 return false;
265 }
266
267 bool
GetLdpcSupported(void) const268 WifiRemoteStationManager::GetLdpcSupported (void) const
269 {
270 if (GetHtSupported ())
271 {
272 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
273 Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
274 NS_ASSERT (htConfiguration); //If HT is supported, we should have a HT configuration attached
275 return htConfiguration->GetLdpcSupported ();
276 }
277 return false;
278 }
279
280 bool
GetShortGuardIntervalSupported(void) const281 WifiRemoteStationManager::GetShortGuardIntervalSupported (void) const
282 {
283 if (GetHtSupported ())
284 {
285 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
286 Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
287 NS_ASSERT (htConfiguration); //If HT is supported, we should have a HT configuration attached
288 if (htConfiguration->GetShortGuardIntervalSupported ())
289 {
290 return true;
291 }
292 }
293 return false;
294 }
295
296 uint16_t
GetGuardInterval(void) const297 WifiRemoteStationManager::GetGuardInterval (void) const
298 {
299 uint16_t gi = 0;
300 if (GetHeSupported ())
301 {
302 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
303 Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
304 NS_ASSERT (heConfiguration); //If HE is supported, we should have a HE configuration attached
305 gi = static_cast<uint16_t>(heConfiguration->GetGuardInterval ().GetNanoSeconds ());
306 }
307 return gi;
308 }
309
310 uint32_t
GetFragmentationThreshold(void) const311 WifiRemoteStationManager::GetFragmentationThreshold (void) const
312 {
313 return DoGetFragmentationThreshold ();
314 }
315
316 void
AddSupportedPhyPreamble(Mac48Address address,bool isShortPreambleSupported)317 WifiRemoteStationManager::AddSupportedPhyPreamble (Mac48Address address, bool isShortPreambleSupported)
318 {
319 NS_LOG_FUNCTION (this << address << isShortPreambleSupported);
320 NS_ASSERT (!address.IsGroup ());
321 WifiRemoteStationState *state = LookupState (address);
322 state->m_shortPreamble = isShortPreambleSupported;
323 }
324
325 void
AddSupportedErpSlotTime(Mac48Address address,bool isShortSlotTimeSupported)326 WifiRemoteStationManager::AddSupportedErpSlotTime (Mac48Address address, bool isShortSlotTimeSupported)
327 {
328 NS_LOG_FUNCTION (this << address << isShortSlotTimeSupported);
329 NS_ASSERT (!address.IsGroup ());
330 WifiRemoteStationState *state = LookupState (address);
331 state->m_shortSlotTime = isShortSlotTimeSupported;
332 }
333
334 void
AddSupportedMode(Mac48Address address,WifiMode mode)335 WifiRemoteStationManager::AddSupportedMode (Mac48Address address, WifiMode mode)
336 {
337 NS_LOG_FUNCTION (this << address << mode);
338 NS_ASSERT (!address.IsGroup ());
339 WifiRemoteStationState *state = LookupState (address);
340 for (WifiModeListIterator i = state->m_operationalRateSet.begin (); i != state->m_operationalRateSet.end (); i++)
341 {
342 if ((*i) == mode)
343 {
344 //already in.
345 return;
346 }
347 }
348 if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS))
349 {
350 state->m_dsssSupported = true;
351 }
352 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
353 {
354 state->m_erpOfdmSupported = true;
355 }
356 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM)
357 {
358 state->m_ofdmSupported = true;
359 }
360 state->m_operationalRateSet.push_back (mode);
361 }
362
363 void
AddAllSupportedModes(Mac48Address address)364 WifiRemoteStationManager::AddAllSupportedModes (Mac48Address address)
365 {
366 NS_LOG_FUNCTION (this << address);
367 NS_ASSERT (!address.IsGroup ());
368 WifiRemoteStationState *state = LookupState (address);
369 state->m_operationalRateSet.clear ();
370 for (const auto & mode : m_wifiPhy->GetModeList ())
371 {
372 state->m_operationalRateSet.push_back (mode);
373 if (mode.IsMandatory ())
374 {
375 AddBasicMode (mode);
376 }
377 }
378 }
379
380 void
AddAllSupportedMcs(Mac48Address address)381 WifiRemoteStationManager::AddAllSupportedMcs (Mac48Address address)
382 {
383 NS_LOG_FUNCTION (this << address);
384 NS_ASSERT (!address.IsGroup ());
385 WifiRemoteStationState *state = LookupState (address);
386 state->m_operationalMcsSet.clear ();
387 for (const auto & mcs : m_wifiPhy->GetMcsList ())
388 {
389 state->m_operationalMcsSet.push_back (mcs);
390 }
391 }
392
393 void
RemoveAllSupportedMcs(Mac48Address address)394 WifiRemoteStationManager::RemoveAllSupportedMcs (Mac48Address address)
395 {
396 NS_LOG_FUNCTION (this << address);
397 NS_ASSERT (!address.IsGroup ());
398 WifiRemoteStationState *state = LookupState (address);
399 state->m_operationalMcsSet.clear ();
400 }
401
402 void
AddSupportedMcs(Mac48Address address,WifiMode mcs)403 WifiRemoteStationManager::AddSupportedMcs (Mac48Address address, WifiMode mcs)
404 {
405 NS_LOG_FUNCTION (this << address << mcs);
406 NS_ASSERT (!address.IsGroup ());
407 WifiRemoteStationState *state = LookupState (address);
408 for (WifiModeListIterator i = state->m_operationalMcsSet.begin (); i != state->m_operationalMcsSet.end (); i++)
409 {
410 if ((*i) == mcs)
411 {
412 //already in.
413 return;
414 }
415 }
416 state->m_operationalMcsSet.push_back (mcs);
417 }
418
419 bool
GetShortPreambleSupported(Mac48Address address) const420 WifiRemoteStationManager::GetShortPreambleSupported (Mac48Address address) const
421 {
422 return LookupState (address)->m_shortPreamble;
423 }
424
425 bool
GetShortSlotTimeSupported(Mac48Address address) const426 WifiRemoteStationManager::GetShortSlotTimeSupported (Mac48Address address) const
427 {
428 return LookupState (address)->m_shortSlotTime;
429 }
430
431 bool
GetQosSupported(Mac48Address address) const432 WifiRemoteStationManager::GetQosSupported (Mac48Address address) const
433 {
434 return LookupState (address)->m_qosSupported;
435 }
436
437 bool
IsBrandNew(Mac48Address address) const438 WifiRemoteStationManager::IsBrandNew (Mac48Address address) const
439 {
440 if (address.IsGroup ())
441 {
442 return false;
443 }
444 return LookupState (address)->m_state == WifiRemoteStationState::BRAND_NEW;
445 }
446
447 bool
IsAssociated(Mac48Address address) const448 WifiRemoteStationManager::IsAssociated (Mac48Address address) const
449 {
450 if (address.IsGroup ())
451 {
452 return true;
453 }
454 return LookupState (address)->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK;
455 }
456
457 bool
IsWaitAssocTxOk(Mac48Address address) const458 WifiRemoteStationManager::IsWaitAssocTxOk (Mac48Address address) const
459 {
460 if (address.IsGroup ())
461 {
462 return false;
463 }
464 return LookupState (address)->m_state == WifiRemoteStationState::WAIT_ASSOC_TX_OK;
465 }
466
467 void
RecordWaitAssocTxOk(Mac48Address address)468 WifiRemoteStationManager::RecordWaitAssocTxOk (Mac48Address address)
469 {
470 NS_ASSERT (!address.IsGroup ());
471 LookupState (address)->m_state = WifiRemoteStationState::WAIT_ASSOC_TX_OK;
472 }
473
474 void
RecordGotAssocTxOk(Mac48Address address)475 WifiRemoteStationManager::RecordGotAssocTxOk (Mac48Address address)
476 {
477 NS_ASSERT (!address.IsGroup ());
478 LookupState (address)->m_state = WifiRemoteStationState::GOT_ASSOC_TX_OK;
479 }
480
481 void
RecordGotAssocTxFailed(Mac48Address address)482 WifiRemoteStationManager::RecordGotAssocTxFailed (Mac48Address address)
483 {
484 NS_ASSERT (!address.IsGroup ());
485 LookupState (address)->m_state = WifiRemoteStationState::DISASSOC;
486 }
487
488 void
RecordDisassociated(Mac48Address address)489 WifiRemoteStationManager::RecordDisassociated (Mac48Address address)
490 {
491 NS_ASSERT (!address.IsGroup ());
492 LookupState (address)->m_state = WifiRemoteStationState::DISASSOC;
493 }
494
495 uint16_t
GetAssociationId(Mac48Address remoteAddress) const496 WifiRemoteStationManager::GetAssociationId (Mac48Address remoteAddress) const
497 {
498 WifiRemoteStationState* state;
499 if (!remoteAddress.IsGroup ()
500 && (state = LookupState (remoteAddress))->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK)
501 {
502 return state->m_aid;
503 }
504 return SU_STA_ID;
505 }
506
507 uint16_t
GetStaId(Mac48Address address,const WifiTxVector & txVector) const508 WifiRemoteStationManager::GetStaId (Mac48Address address, const WifiTxVector& txVector) const
509 {
510 NS_LOG_FUNCTION (this << address << txVector);
511
512 uint16_t staId = SU_STA_ID;
513
514 if (txVector.IsMu ())
515 {
516 if (m_wifiMac->GetTypeOfStation () == AP)
517 {
518 staId = GetAssociationId (address);
519 }
520 else if (m_wifiMac->GetTypeOfStation () == STA)
521 {
522 Ptr<StaWifiMac> staMac = StaticCast<StaWifiMac> (m_wifiMac);
523 if (staMac->IsAssociated ())
524 {
525 staId = staMac->GetAssociationId ();
526 }
527 }
528 }
529
530 NS_LOG_DEBUG ("Returning STAID = " << staId);
531 return staId;
532 }
533
534 WifiTxVector
GetDataTxVector(const WifiMacHeader & header)535 WifiRemoteStationManager::GetDataTxVector (const WifiMacHeader &header)
536 {
537 NS_LOG_FUNCTION (this << header);
538 Mac48Address address = header.GetAddr1 ();
539 if (!header.IsMgt () && address.IsGroup ())
540 {
541 WifiMode mode = GetNonUnicastMode ();
542 WifiTxVector v;
543 v.SetMode (mode);
544 v.SetPreambleType (GetPreambleForTransmission (mode.GetModulationClass (), GetShortPreambleEnabled ()));
545 v.SetTxPowerLevel (m_defaultTxPowerLevel);
546 v.SetChannelWidth (GetChannelWidthForTransmission (mode, m_wifiPhy->GetChannelWidth ()));
547 v.SetGuardInterval (ConvertGuardIntervalToNanoSeconds (mode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())));
548 v.SetNTx (GetNumberOfAntennas ());
549 v.SetNss (1);
550 v.SetNess (0);
551 return v;
552 }
553 WifiTxVector txVector;
554 if (header.IsMgt ())
555 {
556 //Use the lowest basic rate for management frames
557 WifiMode mgtMode;
558 if (GetNBasicModes () > 0)
559 {
560 mgtMode = GetBasicMode (0);
561 }
562 else
563 {
564 mgtMode = GetDefaultMode ();
565 }
566 txVector.SetMode (mgtMode);
567 txVector.SetPreambleType (GetPreambleForTransmission (mgtMode.GetModulationClass (), GetShortPreambleEnabled ()));
568 txVector.SetTxPowerLevel (m_defaultTxPowerLevel);
569 txVector.SetChannelWidth (GetChannelWidthForTransmission (mgtMode, m_wifiPhy->GetChannelWidth ()));
570 txVector.SetGuardInterval (ConvertGuardIntervalToNanoSeconds (mgtMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())));
571 }
572 else
573 {
574 txVector = DoGetDataTxVector (Lookup (address));
575 txVector.SetLdpc (txVector.GetMode ().GetModulationClass () < WIFI_MOD_CLASS_HT ? 0 : UseLdpcForDestination (address));
576 }
577 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
578 Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
579 if (heConfiguration)
580 {
581 txVector.SetBssColor (heConfiguration->GetBssColor ());
582 }
583 return txVector;
584 }
585
586 WifiTxVector
GetCtsToSelfTxVector(void)587 WifiRemoteStationManager::GetCtsToSelfTxVector (void)
588 {
589 WifiMode defaultMode = GetDefaultMode ();
590 WifiPreamble defaultPreamble;
591 if (defaultMode.GetModulationClass () == WIFI_MOD_CLASS_HE)
592 {
593 defaultPreamble = WIFI_PREAMBLE_HE_SU;
594 }
595 else if (defaultMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
596 {
597 defaultPreamble = WIFI_PREAMBLE_VHT_SU;
598 }
599 else if (defaultMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
600 {
601 defaultPreamble = WIFI_PREAMBLE_HT_MF;
602 }
603 else
604 {
605 defaultPreamble = WIFI_PREAMBLE_LONG;
606 }
607
608 return WifiTxVector (defaultMode,
609 GetDefaultTxPowerLevel (),
610 defaultPreamble,
611 ConvertGuardIntervalToNanoSeconds (defaultMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())),
612 GetNumberOfAntennas (),
613 1,
614 0,
615 GetChannelWidthForTransmission (defaultMode, m_wifiPhy->GetChannelWidth ()),
616 false);
617 }
618
619 WifiTxVector
GetRtsTxVector(Mac48Address address)620 WifiRemoteStationManager::GetRtsTxVector (Mac48Address address)
621 {
622 NS_LOG_FUNCTION (this << address);
623 if (address.IsGroup ())
624 {
625 WifiMode mode = GetNonUnicastMode ();
626 WifiTxVector v;
627 v.SetMode (mode);
628 v.SetPreambleType (GetPreambleForTransmission (mode.GetModulationClass (), GetShortPreambleEnabled ()));
629 v.SetTxPowerLevel (m_defaultTxPowerLevel);
630 v.SetChannelWidth (GetChannelWidthForTransmission (mode, m_wifiPhy->GetChannelWidth ()));
631 v.SetGuardInterval (ConvertGuardIntervalToNanoSeconds (mode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())));
632 v.SetNTx (GetNumberOfAntennas ());
633 v.SetNss (1);
634 v.SetNess (0);
635 return v;
636 }
637 return DoGetRtsTxVector (Lookup (address));
638 }
639
640 WifiTxVector
GetCtsTxVector(Mac48Address to,WifiMode rtsTxMode) const641 WifiRemoteStationManager::GetCtsTxVector (Mac48Address to, WifiMode rtsTxMode) const
642 {
643 NS_ASSERT (!to.IsGroup ());
644 WifiMode ctsMode = GetControlAnswerMode (rtsTxMode);
645 WifiTxVector v;
646 v.SetMode (ctsMode);
647 v.SetPreambleType (GetPreambleForTransmission (ctsMode.GetModulationClass (), GetShortPreambleEnabled ()));
648 v.SetTxPowerLevel (GetDefaultTxPowerLevel ());
649 v.SetChannelWidth (GetChannelWidthForTransmission (ctsMode, m_wifiPhy->GetChannelWidth ()));
650 uint16_t ctsTxGuardInterval = ConvertGuardIntervalToNanoSeconds (ctsMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ()));
651 v.SetGuardInterval (ctsTxGuardInterval);
652 v.SetNss (1);
653 return v;
654 }
655
656 WifiTxVector
GetAckTxVector(Mac48Address to,const WifiTxVector & dataTxVector) const657 WifiRemoteStationManager::GetAckTxVector (Mac48Address to, const WifiTxVector& dataTxVector) const
658 {
659 NS_ASSERT (!to.IsGroup ());
660 WifiMode ackMode = GetControlAnswerMode (dataTxVector.GetMode (GetStaId (to, dataTxVector)));
661 WifiTxVector v;
662 v.SetMode (ackMode);
663 v.SetPreambleType (GetPreambleForTransmission (ackMode.GetModulationClass (), GetShortPreambleEnabled ()));
664 v.SetTxPowerLevel (GetDefaultTxPowerLevel ());
665 v.SetChannelWidth (GetChannelWidthForTransmission (ackMode, m_wifiPhy->GetChannelWidth ()));
666 uint16_t ackTxGuardInterval = ConvertGuardIntervalToNanoSeconds (ackMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ()));
667 v.SetGuardInterval (ackTxGuardInterval);
668 v.SetNss (1);
669 return v;
670 }
671
672 WifiTxVector
GetBlockAckTxVector(Mac48Address to,const WifiTxVector & dataTxVector) const673 WifiRemoteStationManager::GetBlockAckTxVector (Mac48Address to, const WifiTxVector& dataTxVector) const
674 {
675 NS_ASSERT (!to.IsGroup ());
676 WifiMode blockAckMode = GetControlAnswerMode (dataTxVector.GetMode (GetStaId (to, dataTxVector)));
677 WifiTxVector v;
678 v.SetMode (blockAckMode);
679 v.SetPreambleType (GetPreambleForTransmission (blockAckMode.GetModulationClass (), GetShortPreambleEnabled ()));
680 v.SetTxPowerLevel (GetDefaultTxPowerLevel ());
681 v.SetChannelWidth (GetChannelWidthForTransmission (blockAckMode, m_wifiPhy->GetChannelWidth ()));
682 uint16_t blockAckTxGuardInterval = ConvertGuardIntervalToNanoSeconds (blockAckMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ()));
683 v.SetGuardInterval (blockAckTxGuardInterval);
684 v.SetNss (1);
685 return v;
686 }
687
688 WifiMode
GetControlAnswerMode(WifiMode reqMode) const689 WifiRemoteStationManager::GetControlAnswerMode (WifiMode reqMode) const
690 {
691 /**
692 * The standard has relatively unambiguous rules for selecting a
693 * control response rate (the below is quoted from IEEE 802.11-2012,
694 * Section 9.7):
695 *
696 * To allow the transmitting STA to calculate the contents of the
697 * Duration/ID field, a STA responding to a received frame shall
698 * transmit its Control Response frame (either CTS or Ack), other
699 * than the BlockAck control frame, at the highest rate in the
700 * BSSBasicRateSet parameter that is less than or equal to the
701 * rate of the immediately previous frame in the frame exchange
702 * sequence (as defined in Annex G) and that is of the same
703 * modulation class (see Section 9.7.8) as the received frame...
704 */
705 NS_LOG_FUNCTION (this << reqMode);
706 WifiMode mode = GetDefaultMode ();
707 bool found = false;
708 //First, search the BSS Basic Rate set
709 for (uint8_t i = 0; i < GetNBasicModes (); i++)
710 {
711 WifiMode testMode = GetBasicMode (i);
712 if ((!found || testMode.IsHigherDataRate (mode))
713 && (!testMode.IsHigherDataRate (reqMode))
714 && (IsAllowedControlAnswerModulationClass (reqMode.GetModulationClass (), testMode.GetModulationClass ())))
715 {
716 mode = testMode;
717 //We've found a potentially-suitable transmit rate, but we
718 //need to continue and consider all the basic rates before
719 //we can be sure we've got the right one.
720 found = true;
721 }
722 }
723 if (GetHtSupported ())
724 {
725 if (!found)
726 {
727 mode = GetDefaultMcs ();
728 for (uint8_t i = 0; i != GetNBasicMcs (); i++)
729 {
730 WifiMode testMode = GetBasicMcs (i);
731 if ((!found || testMode.IsHigherDataRate (mode))
732 && (!testMode.IsHigherDataRate (reqMode))
733 && (testMode.GetModulationClass () == reqMode.GetModulationClass ()))
734 {
735 mode = testMode;
736 //We've found a potentially-suitable transmit rate, but we
737 //need to continue and consider all the basic rates before
738 //we can be sure we've got the right one.
739 found = true;
740 }
741 }
742 }
743 }
744 //If we found a suitable rate in the BSSBasicRateSet, then we are
745 //done and can return that mode.
746 if (found)
747 {
748 NS_LOG_DEBUG ("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
749 return mode;
750 }
751
752 /**
753 * If no suitable basic rate was found, we search the mandatory
754 * rates. The standard (IEEE 802.11-2007, Section 9.6) says:
755 *
756 * ...If no rate contained in the BSSBasicRateSet parameter meets
757 * these conditions, then the control frame sent in response to a
758 * received frame shall be transmitted at the highest mandatory
759 * rate of the PHY that is less than or equal to the rate of the
760 * received frame, and that is of the same modulation class as the
761 * received frame. In addition, the Control Response frame shall
762 * be sent using the same PHY options as the received frame,
763 * unless they conflict with the requirement to use the
764 * BSSBasicRateSet parameter.
765 *
766 * \todo Note that we're ignoring the last sentence for now, because
767 * there is not yet any manipulation here of PHY options.
768 */
769 for (const auto & thismode : m_wifiPhy->GetModeList ())
770 {
771 /* If the rate:
772 *
773 * - is a mandatory rate for the PHY, and
774 * - is equal to or faster than our current best choice, and
775 * - is less than or equal to the rate of the received frame, and
776 * - is of the same modulation class as the received frame
777 *
778 * ...then it's our best choice so far.
779 */
780 if (thismode.IsMandatory ()
781 && (!found || thismode.IsHigherDataRate (mode))
782 && (!thismode.IsHigherDataRate (reqMode))
783 && (IsAllowedControlAnswerModulationClass (reqMode.GetModulationClass (), thismode.GetModulationClass ())))
784 {
785 mode = thismode;
786 //As above; we've found a potentially-suitable transmit
787 //rate, but we need to continue and consider all the
788 //mandatory rates before we can be sure we've got the right one.
789 found = true;
790 }
791 }
792 if (GetHtSupported () )
793 {
794 for (const auto & thismode : m_wifiPhy->GetMcsList ())
795 {
796 if (thismode.IsMandatory ()
797 && (!found || thismode.IsHigherDataRate (mode))
798 && (!thismode.IsHigherCodeRate (reqMode))
799 && (thismode.GetModulationClass () == reqMode.GetModulationClass ()))
800 {
801 mode = thismode;
802 //As above; we've found a potentially-suitable transmit
803 //rate, but we need to continue and consider all the
804 //mandatory rates before we can be sure we've got the right one.
805 found = true;
806 }
807 }
808 }
809
810 /**
811 * If we still haven't found a suitable rate for the response then
812 * someone has messed up the simulation configuration. This probably means
813 * that the WifiPhyStandard is not set correctly, or that a rate that
814 * is not supported by the PHY has been explicitly requested.
815 *
816 * Either way, it is serious - we can either disobey the standard or
817 * fail, and I have chosen to do the latter...
818 */
819 if (!found)
820 {
821 NS_FATAL_ERROR ("Can't find response rate for " << reqMode);
822 }
823
824 NS_LOG_DEBUG ("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
825 return mode;
826 }
827
828 void
ReportRtsFailed(const WifiMacHeader & header)829 WifiRemoteStationManager::ReportRtsFailed (const WifiMacHeader& header)
830 {
831 NS_LOG_FUNCTION (this << header);
832 NS_ASSERT (!header.GetAddr1 ().IsGroup ());
833 AcIndex ac = QosUtilsMapTidToAc ((header.IsQosData ()) ? header.GetQosTid () : 0);
834 m_ssrc[ac]++;
835 m_macTxRtsFailed (header.GetAddr1 ());
836 DoReportRtsFailed (Lookup (header.GetAddr1 ()));
837 }
838
839 void
ReportDataFailed(Ptr<const WifiMacQueueItem> mpdu)840 WifiRemoteStationManager::ReportDataFailed (Ptr<const WifiMacQueueItem> mpdu)
841 {
842 NS_LOG_FUNCTION (this << *mpdu);
843 NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
844 AcIndex ac = QosUtilsMapTidToAc ((mpdu->GetHeader ().IsQosData ()) ? mpdu->GetHeader ().GetQosTid () : 0);
845 bool longMpdu = (mpdu->GetSize () > m_rtsCtsThreshold);
846 if (longMpdu)
847 {
848 m_slrc[ac]++;
849 }
850 else
851 {
852 m_ssrc[ac]++;
853 }
854 m_macTxDataFailed (mpdu->GetHeader ().GetAddr1 ());
855 DoReportDataFailed (Lookup (mpdu->GetHeader ().GetAddr1 ()));
856 }
857
858 void
ReportRtsOk(const WifiMacHeader & header,double ctsSnr,WifiMode ctsMode,double rtsSnr)859 WifiRemoteStationManager::ReportRtsOk (const WifiMacHeader& header,
860 double ctsSnr, WifiMode ctsMode, double rtsSnr)
861 {
862 NS_LOG_FUNCTION (this << header << ctsSnr << ctsMode << rtsSnr);
863 NS_ASSERT (!header.GetAddr1 ().IsGroup ());
864 WifiRemoteStation *station = Lookup (header.GetAddr1 ());
865 AcIndex ac = QosUtilsMapTidToAc ((header.IsQosData ()) ? header.GetQosTid () : 0);
866 station->m_state->m_info.NotifyTxSuccess (m_ssrc[ac]);
867 m_ssrc[ac] = 0;
868 DoReportRtsOk (station, ctsSnr, ctsMode, rtsSnr);
869 }
870
871 void
ReportDataOk(Ptr<const WifiMacQueueItem> mpdu,double ackSnr,WifiMode ackMode,double dataSnr,WifiTxVector dataTxVector)872 WifiRemoteStationManager::ReportDataOk (Ptr<const WifiMacQueueItem> mpdu, double ackSnr,
873 WifiMode ackMode, double dataSnr, WifiTxVector dataTxVector)
874 {
875 NS_LOG_FUNCTION (this << *mpdu << ackSnr << ackMode << dataSnr << dataTxVector);
876 const WifiMacHeader& hdr = mpdu->GetHeader ();
877 NS_ASSERT (!hdr.GetAddr1 ().IsGroup ());
878 WifiRemoteStation *station = Lookup (hdr.GetAddr1 ());
879 AcIndex ac = QosUtilsMapTidToAc ((hdr.IsQosData ()) ? hdr.GetQosTid () : 0);
880 bool longMpdu = (mpdu->GetSize () > m_rtsCtsThreshold);
881 if (longMpdu)
882 {
883 station->m_state->m_info.NotifyTxSuccess (m_slrc[ac]);
884 m_slrc[ac] = 0;
885 }
886 else
887 {
888 station->m_state->m_info.NotifyTxSuccess (m_ssrc[ac]);
889 m_ssrc[ac] = 0;
890 }
891 DoReportDataOk (station, ackSnr, ackMode, dataSnr, dataTxVector.GetChannelWidth (),
892 dataTxVector.GetNss (GetStaId (hdr.GetAddr1 (), dataTxVector)));
893 }
894
895 void
ReportFinalRtsFailed(const WifiMacHeader & header)896 WifiRemoteStationManager::ReportFinalRtsFailed (const WifiMacHeader& header)
897 {
898 NS_LOG_FUNCTION (this << header);
899 NS_ASSERT (!header.GetAddr1 ().IsGroup ());
900 WifiRemoteStation *station = Lookup (header.GetAddr1 ());
901 AcIndex ac = QosUtilsMapTidToAc ((header.IsQosData ()) ? header.GetQosTid () : 0);
902 station->m_state->m_info.NotifyTxFailed ();
903 m_ssrc[ac] = 0;
904 m_macTxFinalRtsFailed (header.GetAddr1 ());
905 DoReportFinalRtsFailed (station);
906 }
907
908 void
ReportFinalDataFailed(Ptr<const WifiMacQueueItem> mpdu)909 WifiRemoteStationManager::ReportFinalDataFailed (Ptr<const WifiMacQueueItem> mpdu)
910 {
911 NS_LOG_FUNCTION (this << *mpdu);
912 NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
913 WifiRemoteStation *station = Lookup (mpdu->GetHeader ().GetAddr1 ());
914 AcIndex ac = QosUtilsMapTidToAc ((mpdu->GetHeader ().IsQosData ()) ? mpdu->GetHeader ().GetQosTid () : 0);
915 station->m_state->m_info.NotifyTxFailed ();
916 bool longMpdu = (mpdu->GetSize () > m_rtsCtsThreshold);
917 if (longMpdu)
918 {
919 m_slrc[ac] = 0;
920 }
921 else
922 {
923 m_ssrc[ac] = 0;
924 }
925 m_macTxFinalDataFailed (mpdu->GetHeader ().GetAddr1 ());
926 DoReportFinalDataFailed (station);
927 }
928
929 void
ReportRxOk(Mac48Address address,RxSignalInfo rxSignalInfo,WifiTxVector txVector)930 WifiRemoteStationManager::ReportRxOk (Mac48Address address, RxSignalInfo rxSignalInfo, WifiTxVector txVector)
931 {
932 NS_LOG_FUNCTION (this << address << rxSignalInfo << txVector);
933 if (address.IsGroup ())
934 {
935 return;
936 }
937 WifiRemoteStation *station = Lookup (address);
938 DoReportRxOk (station, rxSignalInfo.snr, txVector.GetMode (GetStaId (address, txVector)));
939 station->m_rssiAndUpdateTimePair = std::make_pair (rxSignalInfo.rssi, Simulator::Now ());
940 }
941
942 void
ReportAmpduTxStatus(Mac48Address address,uint16_t nSuccessfulMpdus,uint16_t nFailedMpdus,double rxSnr,double dataSnr,WifiTxVector dataTxVector)943 WifiRemoteStationManager::ReportAmpduTxStatus (Mac48Address address,
944 uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus,
945 double rxSnr, double dataSnr, WifiTxVector dataTxVector)
946 {
947 NS_LOG_FUNCTION (this << address << nSuccessfulMpdus << nFailedMpdus << rxSnr << dataSnr << dataTxVector);
948 NS_ASSERT (!address.IsGroup ());
949 for (uint8_t i = 0; i < nFailedMpdus; i++)
950 {
951 m_macTxDataFailed (address);
952 }
953 DoReportAmpduTxStatus (Lookup (address), nSuccessfulMpdus, nFailedMpdus, rxSnr, dataSnr, dataTxVector.GetChannelWidth (), dataTxVector.GetNss (GetStaId (address, dataTxVector)));
954 }
955
956 bool
NeedRts(const WifiMacHeader & header,uint32_t size)957 WifiRemoteStationManager::NeedRts (const WifiMacHeader &header, uint32_t size)
958 {
959 NS_LOG_FUNCTION (this << header << size);
960 Mac48Address address = header.GetAddr1 ();
961 WifiTxVector txVector = GetDataTxVector (header);
962 WifiMode mode = txVector.GetMode ();
963 if (address.IsGroup ())
964 {
965 return false;
966 }
967 if (m_erpProtectionMode == RTS_CTS
968 && ((mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
969 || (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
970 || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
971 || (mode.GetModulationClass () == WIFI_MOD_CLASS_HE))
972 && m_useNonErpProtection)
973 {
974 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRTS returning true to protect non-ERP stations");
975 return true;
976 }
977 else if (m_htProtectionMode == RTS_CTS
978 && ((mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
979 || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
980 && m_useNonHtProtection
981 && !(m_erpProtectionMode != RTS_CTS && m_useNonErpProtection))
982 {
983 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRTS returning true to protect non-HT stations");
984 return true;
985 }
986 bool normally = (size > m_rtsCtsThreshold);
987 return DoNeedRts (Lookup (address), size, normally);
988 }
989
990 bool
NeedCtsToSelf(WifiTxVector txVector)991 WifiRemoteStationManager::NeedCtsToSelf (WifiTxVector txVector)
992 {
993 WifiMode mode = txVector.GetMode ();
994 NS_LOG_FUNCTION (this << mode);
995 if (m_erpProtectionMode == CTS_TO_SELF
996 && ((mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
997 || (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
998 || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
999 || (mode.GetModulationClass () == WIFI_MOD_CLASS_HE))
1000 && m_useNonErpProtection)
1001 {
1002 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-ERP stations");
1003 return true;
1004 }
1005 else if (m_htProtectionMode == CTS_TO_SELF
1006 && ((mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
1007 || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
1008 && m_useNonHtProtection
1009 && !(m_erpProtectionMode != CTS_TO_SELF && m_useNonErpProtection))
1010 {
1011 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-HT stations");
1012 return true;
1013 }
1014 else if (!m_useNonErpProtection)
1015 {
1016 //search for the BSS Basic Rate set, if the used mode is in the basic set then there is no need for CTS To Self
1017 for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++)
1018 {
1019 if (mode == *i)
1020 {
1021 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning false");
1022 return false;
1023 }
1024 }
1025 if (GetHtSupported ())
1026 {
1027 //search for the BSS Basic MCS set, if the used mode is in the basic set then there is no need for CTS To Self
1028 for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++)
1029 {
1030 if (mode == *i)
1031 {
1032 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning false");
1033 return false;
1034 }
1035 }
1036 }
1037 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true");
1038 return true;
1039 }
1040 return false;
1041 }
1042
1043 void
SetUseNonErpProtection(bool enable)1044 WifiRemoteStationManager::SetUseNonErpProtection (bool enable)
1045 {
1046 NS_LOG_FUNCTION (this << enable);
1047 m_useNonErpProtection = enable;
1048 }
1049
1050 bool
GetUseNonErpProtection(void) const1051 WifiRemoteStationManager::GetUseNonErpProtection (void) const
1052 {
1053 return m_useNonErpProtection;
1054 }
1055
1056 void
SetUseNonHtProtection(bool enable)1057 WifiRemoteStationManager::SetUseNonHtProtection (bool enable)
1058 {
1059 NS_LOG_FUNCTION (this << enable);
1060 m_useNonHtProtection = enable;
1061 }
1062
1063 bool
GetUseNonHtProtection(void) const1064 WifiRemoteStationManager::GetUseNonHtProtection (void) const
1065 {
1066 return m_useNonHtProtection;
1067 }
1068
1069 bool
NeedRetransmission(Ptr<const WifiMacQueueItem> mpdu)1070 WifiRemoteStationManager::NeedRetransmission (Ptr<const WifiMacQueueItem> mpdu)
1071 {
1072 NS_LOG_FUNCTION (this << *mpdu);
1073 NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
1074 AcIndex ac = QosUtilsMapTidToAc ((mpdu->GetHeader ().IsQosData ()) ? mpdu->GetHeader ().GetQosTid () : 0);
1075 bool longMpdu = (mpdu->GetSize () > m_rtsCtsThreshold);
1076 uint32_t retryCount, maxRetryCount;
1077 if (longMpdu)
1078 {
1079 retryCount = m_slrc[ac];
1080 maxRetryCount = m_maxSlrc;
1081 }
1082 else
1083 {
1084 retryCount = m_ssrc[ac];
1085 maxRetryCount = m_maxSsrc;
1086 }
1087 bool normally = retryCount < maxRetryCount;
1088 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRetransmission count: " << retryCount << " result: " << std::boolalpha << normally);
1089 return DoNeedRetransmission (Lookup (mpdu->GetHeader ().GetAddr1 ()), mpdu->GetPacket (), normally);
1090 }
1091
1092 bool
NeedFragmentation(Ptr<const WifiMacQueueItem> mpdu)1093 WifiRemoteStationManager::NeedFragmentation (Ptr<const WifiMacQueueItem> mpdu)
1094 {
1095 NS_LOG_FUNCTION (this << *mpdu);
1096 if (mpdu->GetHeader ().GetAddr1 ().IsGroup ())
1097 {
1098 return false;
1099 }
1100 bool normally = mpdu->GetSize () > GetFragmentationThreshold ();
1101 NS_LOG_DEBUG ("WifiRemoteStationManager::NeedFragmentation result: " << std::boolalpha << normally);
1102 return DoNeedFragmentation (Lookup (mpdu->GetHeader ().GetAddr1 ()), mpdu->GetPacket (), normally);
1103 }
1104
1105 void
DoSetFragmentationThreshold(uint32_t threshold)1106 WifiRemoteStationManager::DoSetFragmentationThreshold (uint32_t threshold)
1107 {
1108 NS_LOG_FUNCTION (this << threshold);
1109 if (threshold < 256)
1110 {
1111 /*
1112 * ASN.1 encoding of the MAC and PHY MIB (256 ... 8000)
1113 */
1114 NS_LOG_WARN ("Fragmentation threshold should be larger than 256. Setting to 256.");
1115 m_fragmentationThreshold = 256;
1116 }
1117 else
1118 {
1119 /*
1120 * The length of each fragment shall be an even number of octets, except for the last fragment if an MSDU or
1121 * MMPDU, which may be either an even or an odd number of octets.
1122 */
1123 if (threshold % 2 != 0)
1124 {
1125 NS_LOG_WARN ("Fragmentation threshold should be an even number. Setting to " << threshold - 1);
1126 m_fragmentationThreshold = threshold - 1;
1127 }
1128 else
1129 {
1130 m_fragmentationThreshold = threshold;
1131 }
1132 }
1133 }
1134
1135 uint32_t
DoGetFragmentationThreshold(void) const1136 WifiRemoteStationManager::DoGetFragmentationThreshold (void) const
1137 {
1138 return m_fragmentationThreshold;
1139 }
1140
1141 uint32_t
GetNFragments(Ptr<const WifiMacQueueItem> mpdu)1142 WifiRemoteStationManager::GetNFragments (Ptr<const WifiMacQueueItem> mpdu)
1143 {
1144 NS_LOG_FUNCTION (this << *mpdu);
1145 //The number of bytes a fragment can support is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1146 uint32_t nFragments = (mpdu->GetPacket ()->GetSize () / (GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH));
1147
1148 //If the size of the last fragment is not 0.
1149 if ((mpdu->GetPacket ()->GetSize () % (GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH)) > 0)
1150 {
1151 nFragments++;
1152 }
1153 NS_LOG_DEBUG ("WifiRemoteStationManager::GetNFragments returning " << nFragments);
1154 return nFragments;
1155 }
1156
1157 uint32_t
GetFragmentSize(Ptr<const WifiMacQueueItem> mpdu,uint32_t fragmentNumber)1158 WifiRemoteStationManager::GetFragmentSize (Ptr<const WifiMacQueueItem> mpdu, uint32_t fragmentNumber)
1159 {
1160 NS_LOG_FUNCTION (this << *mpdu << fragmentNumber);
1161 NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
1162 uint32_t nFragment = GetNFragments (mpdu);
1163 if (fragmentNumber >= nFragment)
1164 {
1165 NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning 0");
1166 return 0;
1167 }
1168 //Last fragment
1169 if (fragmentNumber == nFragment - 1)
1170 {
1171 uint32_t lastFragmentSize = mpdu->GetPacket ()->GetSize () - (fragmentNumber * (GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH));
1172 NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning " << lastFragmentSize);
1173 return lastFragmentSize;
1174 }
1175 //All fragments but the last, the number of bytes is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1176 else
1177 {
1178 uint32_t fragmentSize = GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH;
1179 NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning " << fragmentSize);
1180 return fragmentSize;
1181 }
1182 }
1183
1184 uint32_t
GetFragmentOffset(Ptr<const WifiMacQueueItem> mpdu,uint32_t fragmentNumber)1185 WifiRemoteStationManager::GetFragmentOffset (Ptr<const WifiMacQueueItem> mpdu, uint32_t fragmentNumber)
1186 {
1187 NS_LOG_FUNCTION (this << *mpdu << fragmentNumber);
1188 NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
1189 NS_ASSERT (fragmentNumber < GetNFragments (mpdu));
1190 uint32_t fragmentOffset = fragmentNumber * (GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH);
1191 NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentOffset returning " << fragmentOffset);
1192 return fragmentOffset;
1193 }
1194
1195 bool
IsLastFragment(Ptr<const WifiMacQueueItem> mpdu,uint32_t fragmentNumber)1196 WifiRemoteStationManager::IsLastFragment (Ptr<const WifiMacQueueItem> mpdu, uint32_t fragmentNumber)
1197 {
1198 NS_LOG_FUNCTION (this << *mpdu << fragmentNumber);
1199 NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
1200 bool isLast = fragmentNumber == (GetNFragments (mpdu) - 1);
1201 NS_LOG_DEBUG ("WifiRemoteStationManager::IsLastFragment returning " << std::boolalpha << isLast);
1202 return isLast;
1203 }
1204
1205 uint8_t
GetDefaultTxPowerLevel(void) const1206 WifiRemoteStationManager::GetDefaultTxPowerLevel (void) const
1207 {
1208 return m_defaultTxPowerLevel;
1209 }
1210
1211 WifiRemoteStationInfo
GetInfo(Mac48Address address)1212 WifiRemoteStationManager::GetInfo (Mac48Address address)
1213 {
1214 WifiRemoteStationState *state = LookupState (address);
1215 return state->m_info;
1216 }
1217
1218 double
GetMostRecentRssi(Mac48Address address) const1219 WifiRemoteStationManager::GetMostRecentRssi (Mac48Address address) const
1220 {
1221 auto stationIt = m_stations.find (address);
1222 NS_ASSERT_MSG (stationIt != m_stations.end(), "Address: " << address << " not found");
1223 auto station = stationIt->second;
1224 auto rssi = station->m_rssiAndUpdateTimePair.first;
1225 auto ts = station->m_rssiAndUpdateTimePair.second;
1226 NS_ASSERT_MSG (ts.IsStrictlyPositive(), "address: " << address << " ts:" << ts);
1227 return rssi;
1228 }
1229
1230 WifiRemoteStationState *
LookupState(Mac48Address address) const1231 WifiRemoteStationManager::LookupState (Mac48Address address) const
1232 {
1233 NS_LOG_FUNCTION (this << address);
1234 auto stateIt = m_states.find (address);
1235
1236 if (stateIt != m_states.end ())
1237 {
1238 NS_LOG_DEBUG ("WifiRemoteStationManager::LookupState returning existing state");
1239 return stateIt->second;
1240 }
1241
1242 WifiRemoteStationState *state = new WifiRemoteStationState ();
1243 state->m_state = WifiRemoteStationState::BRAND_NEW;
1244 state->m_address = address;
1245 state->m_aid = 0;
1246 state->m_operationalRateSet.push_back (GetDefaultMode ());
1247 state->m_operationalMcsSet.push_back (GetDefaultMcs ());
1248 state->m_dsssSupported = false;
1249 state->m_erpOfdmSupported = false;
1250 state->m_ofdmSupported = false;
1251 state->m_htCapabilities = 0;
1252 state->m_vhtCapabilities = 0;
1253 state->m_heCapabilities = 0;
1254 state->m_channelWidth = m_wifiPhy->GetChannelWidth ();
1255 state->m_guardInterval = GetGuardInterval ();
1256 state->m_ness = 0;
1257 state->m_aggregation = false;
1258 state->m_qosSupported = false;
1259 const_cast<WifiRemoteStationManager *> (this)->m_states.insert ({address, state});
1260 NS_LOG_DEBUG ("WifiRemoteStationManager::LookupState returning new state");
1261 return state;
1262 }
1263
1264 WifiRemoteStation *
Lookup(Mac48Address address) const1265 WifiRemoteStationManager::Lookup (Mac48Address address) const
1266 {
1267 NS_LOG_FUNCTION (this << address);
1268 auto stationIt = m_stations.find (address);
1269
1270 if (stationIt != m_stations.end ())
1271 {
1272 return stationIt->second;
1273 }
1274
1275 WifiRemoteStationState *state = LookupState (address);
1276
1277 WifiRemoteStation *station = DoCreateStation ();
1278 station->m_state = state;
1279 station->m_rssiAndUpdateTimePair = std::make_pair (0, Seconds (0));
1280 const_cast<WifiRemoteStationManager *> (this)->m_stations.insert ({address, station});
1281 return station;
1282 }
1283
1284 void
SetAssociationId(Mac48Address remoteAddress,uint16_t aid)1285 WifiRemoteStationManager::SetAssociationId (Mac48Address remoteAddress, uint16_t aid)
1286 {
1287 NS_LOG_FUNCTION (this << remoteAddress << aid);
1288 LookupState (remoteAddress)->m_aid = aid;
1289 }
1290
1291 void
SetQosSupport(Mac48Address from,bool qosSupported)1292 WifiRemoteStationManager::SetQosSupport (Mac48Address from, bool qosSupported)
1293 {
1294 NS_LOG_FUNCTION (this << from << qosSupported);
1295 WifiRemoteStationState *state;
1296 state = LookupState (from);
1297 state->m_qosSupported = qosSupported;
1298 }
1299
1300 void
AddStationHtCapabilities(Mac48Address from,HtCapabilities htCapabilities)1301 WifiRemoteStationManager::AddStationHtCapabilities (Mac48Address from, HtCapabilities htCapabilities)
1302 {
1303 //Used by all stations to record HT capabilities of remote stations
1304 NS_LOG_FUNCTION (this << from << htCapabilities);
1305 WifiRemoteStationState *state;
1306 state = LookupState (from);
1307 if (htCapabilities.GetSupportedChannelWidth () == 1)
1308 {
1309 state->m_channelWidth = 40;
1310 }
1311 else
1312 {
1313 state->m_channelWidth = 20;
1314 }
1315 SetQosSupport (from, true);
1316 for (const auto & mcs : m_wifiPhy->GetMcsList (WIFI_MOD_CLASS_HT))
1317 {
1318 if (htCapabilities.IsSupportedMcs (mcs.GetMcsValue ()))
1319 {
1320 AddSupportedMcs (from, mcs);
1321 }
1322 }
1323 state->m_htCapabilities = Create<const HtCapabilities> (htCapabilities);
1324 }
1325
1326 void
AddStationVhtCapabilities(Mac48Address from,VhtCapabilities vhtCapabilities)1327 WifiRemoteStationManager::AddStationVhtCapabilities (Mac48Address from, VhtCapabilities vhtCapabilities)
1328 {
1329 //Used by all stations to record VHT capabilities of remote stations
1330 NS_LOG_FUNCTION (this << from << vhtCapabilities);
1331 WifiRemoteStationState *state;
1332 state = LookupState (from);
1333 if (vhtCapabilities.GetSupportedChannelWidthSet () == 1)
1334 {
1335 state->m_channelWidth = 160;
1336 }
1337 else
1338 {
1339 state->m_channelWidth = 80;
1340 }
1341 //This is a workaround to enable users to force a 20 or 40 MHz channel for a VHT-compliant device,
1342 //since IEEE 802.11ac standard says that 20, 40 and 80 MHz channels are mandatory.
1343 if (m_wifiPhy->GetChannelWidth () < state->m_channelWidth)
1344 {
1345 state->m_channelWidth = m_wifiPhy->GetChannelWidth ();
1346 }
1347 for (uint8_t i = 1; i <= m_wifiPhy->GetMaxSupportedTxSpatialStreams (); i++)
1348 {
1349 for (const auto & mcs : m_wifiPhy->GetMcsList (WIFI_MOD_CLASS_VHT))
1350 {
1351 if (vhtCapabilities.IsSupportedMcs (mcs.GetMcsValue (), i))
1352 {
1353 AddSupportedMcs (from, mcs);
1354 }
1355 }
1356 }
1357 state->m_vhtCapabilities = Create<const VhtCapabilities> (vhtCapabilities);
1358 }
1359
1360 void
AddStationHeCapabilities(Mac48Address from,HeCapabilities heCapabilities)1361 WifiRemoteStationManager::AddStationHeCapabilities (Mac48Address from, HeCapabilities heCapabilities)
1362 {
1363 //Used by all stations to record HE capabilities of remote stations
1364 NS_LOG_FUNCTION (this << from << heCapabilities);
1365 WifiRemoteStationState *state;
1366 state = LookupState (from);
1367 if ((m_wifiPhy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (m_wifiPhy->GetPhyBand () == WIFI_PHY_BAND_6GHZ))
1368 {
1369 if (heCapabilities.GetChannelWidthSet () & 0x04)
1370 {
1371 state->m_channelWidth = 160;
1372 }
1373 else if (heCapabilities.GetChannelWidthSet () & 0x02)
1374 {
1375 state->m_channelWidth = 80;
1376 }
1377 //For other cases at 5 GHz, the supported channel width is set by the VHT capabilities
1378 }
1379 else if (m_wifiPhy->GetPhyBand () == WIFI_PHY_BAND_2_4GHZ)
1380 {
1381 if (heCapabilities.GetChannelWidthSet () & 0x01)
1382 {
1383 state->m_channelWidth = 40;
1384 }
1385 else
1386 {
1387 state->m_channelWidth = 20;
1388 }
1389 }
1390 if (heCapabilities.GetHeLtfAndGiForHePpdus () >= 2)
1391 {
1392 state->m_guardInterval = 800;
1393 }
1394 else if (heCapabilities.GetHeLtfAndGiForHePpdus () == 1)
1395 {
1396 state->m_guardInterval = 1600;
1397 }
1398 else
1399 {
1400 state->m_guardInterval = 3200;
1401 }
1402 for (uint8_t i = 1; i <= m_wifiPhy->GetMaxSupportedTxSpatialStreams (); i++)
1403 {
1404 for (const auto & mcs : m_wifiPhy->GetMcsList (WIFI_MOD_CLASS_HE))
1405 {
1406 if (heCapabilities.GetHighestNssSupported () >= i
1407 && heCapabilities.GetHighestMcsSupported () >= mcs.GetMcsValue ())
1408 {
1409 AddSupportedMcs (from, mcs);
1410 }
1411 }
1412 }
1413 state->m_heCapabilities = Create<const HeCapabilities> (heCapabilities);
1414 SetQosSupport (from, true);
1415 }
1416
1417 Ptr<const HtCapabilities>
GetStationHtCapabilities(Mac48Address from)1418 WifiRemoteStationManager::GetStationHtCapabilities (Mac48Address from)
1419 {
1420 return LookupState (from)->m_htCapabilities;
1421 }
1422
1423 Ptr<const VhtCapabilities>
GetStationVhtCapabilities(Mac48Address from)1424 WifiRemoteStationManager::GetStationVhtCapabilities (Mac48Address from)
1425 {
1426 return LookupState (from)->m_vhtCapabilities;
1427 }
1428
1429 Ptr<const HeCapabilities>
GetStationHeCapabilities(Mac48Address from)1430 WifiRemoteStationManager::GetStationHeCapabilities (Mac48Address from)
1431 {
1432 return LookupState (from)->m_heCapabilities;
1433 }
1434
1435 bool
GetLdpcSupported(Mac48Address address) const1436 WifiRemoteStationManager::GetLdpcSupported (Mac48Address address) const
1437 {
1438 Ptr<const HtCapabilities> htCapabilities = LookupState (address)->m_htCapabilities;
1439 Ptr<const VhtCapabilities> vhtCapabilities = LookupState (address)->m_vhtCapabilities;
1440 Ptr<const HeCapabilities> heCapabilities = LookupState (address)->m_heCapabilities;
1441 bool supported = false;
1442 if (htCapabilities)
1443 {
1444 supported |= htCapabilities->GetLdpc ();
1445 }
1446 if (vhtCapabilities)
1447 {
1448 supported |= vhtCapabilities->GetRxLdpc ();
1449 }
1450 if (heCapabilities)
1451 {
1452 supported |= heCapabilities->GetLdpcCodingInPayload ();
1453 }
1454 return supported;
1455 }
1456
1457 WifiMode
GetDefaultMode(void) const1458 WifiRemoteStationManager::GetDefaultMode (void) const
1459 {
1460 return m_defaultTxMode;
1461 }
1462
1463 WifiMode
GetDefaultMcs(void) const1464 WifiRemoteStationManager::GetDefaultMcs (void) const
1465 {
1466 return m_defaultTxMcs;
1467 }
1468
1469 void
Reset(void)1470 WifiRemoteStationManager::Reset (void)
1471 {
1472 NS_LOG_FUNCTION (this);
1473 for (auto& state : m_states)
1474 {
1475 delete (state.second);
1476 }
1477 m_states.clear ();
1478 for (auto& state: m_stations)
1479 {
1480 delete (state.second);
1481 }
1482 m_stations.clear ();
1483 m_bssBasicRateSet.clear ();
1484 m_bssBasicMcsSet.clear ();
1485 m_ssrc.fill (0);
1486 m_slrc.fill (0);
1487 }
1488
1489 void
AddBasicMode(WifiMode mode)1490 WifiRemoteStationManager::AddBasicMode (WifiMode mode)
1491 {
1492 NS_LOG_FUNCTION (this << mode);
1493 if (mode.GetModulationClass () >= WIFI_MOD_CLASS_HT)
1494 {
1495 NS_FATAL_ERROR ("It is not allowed to add a HT rate in the BSSBasicRateSet!");
1496 }
1497 for (uint8_t i = 0; i < GetNBasicModes (); i++)
1498 {
1499 if (GetBasicMode (i) == mode)
1500 {
1501 return;
1502 }
1503 }
1504 m_bssBasicRateSet.push_back (mode);
1505 }
1506
1507 uint8_t
GetNBasicModes(void) const1508 WifiRemoteStationManager::GetNBasicModes (void) const
1509 {
1510 return static_cast<uint8_t> (m_bssBasicRateSet.size ());
1511 }
1512
1513 WifiMode
GetBasicMode(uint8_t i) const1514 WifiRemoteStationManager::GetBasicMode (uint8_t i) const
1515 {
1516 NS_ASSERT (i < GetNBasicModes ());
1517 return m_bssBasicRateSet[i];
1518 }
1519
1520 uint32_t
GetNNonErpBasicModes(void) const1521 WifiRemoteStationManager::GetNNonErpBasicModes (void) const
1522 {
1523 uint32_t size = 0;
1524 for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++)
1525 {
1526 if (i->GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
1527 {
1528 continue;
1529 }
1530 size++;
1531 }
1532 return size;
1533 }
1534
1535 WifiMode
GetNonErpBasicMode(uint8_t i) const1536 WifiRemoteStationManager::GetNonErpBasicMode (uint8_t i) const
1537 {
1538 NS_ASSERT (i < GetNNonErpBasicModes ());
1539 uint32_t index = 0;
1540 bool found = false;
1541 for (WifiModeListIterator j = m_bssBasicRateSet.begin (); j != m_bssBasicRateSet.end (); )
1542 {
1543 if (i == index)
1544 {
1545 found = true;
1546 }
1547 if (j->GetModulationClass () != WIFI_MOD_CLASS_ERP_OFDM)
1548 {
1549 if (found)
1550 {
1551 break;
1552 }
1553 }
1554 index++;
1555 j++;
1556 }
1557 return m_bssBasicRateSet[index];
1558 }
1559
1560 void
AddBasicMcs(WifiMode mcs)1561 WifiRemoteStationManager::AddBasicMcs (WifiMode mcs)
1562 {
1563 NS_LOG_FUNCTION (this << +mcs.GetMcsValue ());
1564 for (uint8_t i = 0; i < GetNBasicMcs (); i++)
1565 {
1566 if (GetBasicMcs (i) == mcs)
1567 {
1568 return;
1569 }
1570 }
1571 m_bssBasicMcsSet.push_back (mcs);
1572 }
1573
1574 uint8_t
GetNBasicMcs(void) const1575 WifiRemoteStationManager::GetNBasicMcs (void) const
1576 {
1577 return static_cast<uint8_t> (m_bssBasicMcsSet.size ());
1578 }
1579
1580 WifiMode
GetBasicMcs(uint8_t i) const1581 WifiRemoteStationManager::GetBasicMcs (uint8_t i) const
1582 {
1583 NS_ASSERT (i < GetNBasicMcs ());
1584 return m_bssBasicMcsSet[i];
1585 }
1586
1587 WifiMode
GetNonUnicastMode(void) const1588 WifiRemoteStationManager::GetNonUnicastMode (void) const
1589 {
1590 if (m_nonUnicastMode == WifiMode ())
1591 {
1592 if (GetNBasicModes () > 0)
1593 {
1594 return GetBasicMode (0);
1595 }
1596 else
1597 {
1598 return GetDefaultMode ();
1599 }
1600 }
1601 else
1602 {
1603 return m_nonUnicastMode;
1604 }
1605 }
1606
1607 bool
DoNeedRts(WifiRemoteStation * station,uint32_t size,bool normally)1608 WifiRemoteStationManager::DoNeedRts (WifiRemoteStation *station,
1609 uint32_t size, bool normally)
1610 {
1611 return normally;
1612 }
1613
1614 bool
DoNeedRetransmission(WifiRemoteStation * station,Ptr<const Packet> packet,bool normally)1615 WifiRemoteStationManager::DoNeedRetransmission (WifiRemoteStation *station,
1616 Ptr<const Packet> packet, bool normally)
1617 {
1618 return normally;
1619 }
1620
1621 bool
DoNeedFragmentation(WifiRemoteStation * station,Ptr<const Packet> packet,bool normally)1622 WifiRemoteStationManager::DoNeedFragmentation (WifiRemoteStation *station,
1623 Ptr<const Packet> packet, bool normally)
1624 {
1625 return normally;
1626 }
1627
1628 void
DoReportAmpduTxStatus(WifiRemoteStation * station,uint16_t nSuccessfulMpdus,uint16_t nFailedMpdus,double rxSnr,double dataSnr,uint16_t dataChannelWidth,uint8_t dataNss)1629 WifiRemoteStationManager::DoReportAmpduTxStatus (WifiRemoteStation *station, uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus, double rxSnr, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss)
1630 {
1631 NS_LOG_DEBUG ("DoReportAmpduTxStatus received but the manager does not handle A-MPDUs!");
1632 }
1633
1634 WifiMode
GetSupported(const WifiRemoteStation * station,uint8_t i) const1635 WifiRemoteStationManager::GetSupported (const WifiRemoteStation *station, uint8_t i) const
1636 {
1637 NS_ASSERT (i < GetNSupported (station));
1638 return station->m_state->m_operationalRateSet[i];
1639 }
1640
1641 WifiMode
GetMcsSupported(const WifiRemoteStation * station,uint8_t i) const1642 WifiRemoteStationManager::GetMcsSupported (const WifiRemoteStation *station, uint8_t i) const
1643 {
1644 NS_ASSERT (i < GetNMcsSupported (station));
1645 return station->m_state->m_operationalMcsSet[i];
1646 }
1647
1648 WifiMode
GetNonErpSupported(const WifiRemoteStation * station,uint8_t i) const1649 WifiRemoteStationManager::GetNonErpSupported (const WifiRemoteStation *station, uint8_t i) const
1650 {
1651 NS_ASSERT (i < GetNNonErpSupported (station));
1652 //IEEE 802.11g standard defines that if the protection mechanism is enabled, RTS, CTS and CTS-To-Self
1653 //frames should select a rate in the BSSBasicRateSet that corresponds to an 802.11b basic rate.
1654 //This is a implemented here to avoid changes in every RAA, but should maybe be moved in case it breaks standard rules.
1655 uint32_t index = 0;
1656 bool found = false;
1657 for (WifiModeListIterator j = station->m_state->m_operationalRateSet.begin (); j != station->m_state->m_operationalRateSet.end (); )
1658 {
1659 if (i == index)
1660 {
1661 found = true;
1662 }
1663 if (j->GetModulationClass () != WIFI_MOD_CLASS_ERP_OFDM)
1664 {
1665 if (found)
1666 {
1667 break;
1668 }
1669 }
1670 index++;
1671 j++;
1672 }
1673 return station->m_state->m_operationalRateSet[index];
1674 }
1675
1676 Mac48Address
GetAddress(const WifiRemoteStation * station) const1677 WifiRemoteStationManager::GetAddress (const WifiRemoteStation *station) const
1678 {
1679 return station->m_state->m_address;
1680 }
1681
1682 uint16_t
GetChannelWidth(const WifiRemoteStation * station) const1683 WifiRemoteStationManager::GetChannelWidth (const WifiRemoteStation *station) const
1684 {
1685 return station->m_state->m_channelWidth;
1686 }
1687
1688 bool
GetShortGuardIntervalSupported(const WifiRemoteStation * station) const1689 WifiRemoteStationManager::GetShortGuardIntervalSupported (const WifiRemoteStation *station) const
1690 {
1691 Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1692
1693 if (!htCapabilities)
1694 {
1695 return false;
1696 }
1697 return htCapabilities->GetShortGuardInterval20 ();
1698 }
1699
1700 uint16_t
GetGuardInterval(const WifiRemoteStation * station) const1701 WifiRemoteStationManager::GetGuardInterval (const WifiRemoteStation *station) const
1702 {
1703 return station->m_state->m_guardInterval;
1704 }
1705
1706 bool
GetAggregation(const WifiRemoteStation * station) const1707 WifiRemoteStationManager::GetAggregation (const WifiRemoteStation *station) const
1708 {
1709 return station->m_state->m_aggregation;
1710 }
1711
1712 uint8_t
GetNumberOfSupportedStreams(const WifiRemoteStation * station) const1713 WifiRemoteStationManager::GetNumberOfSupportedStreams (const WifiRemoteStation *station) const
1714 {
1715 Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1716
1717 if (!htCapabilities)
1718 {
1719 return 1;
1720 }
1721 return htCapabilities->GetRxHighestSupportedAntennas ();
1722 }
1723
1724 uint8_t
GetNess(const WifiRemoteStation * station) const1725 WifiRemoteStationManager::GetNess (const WifiRemoteStation *station) const
1726 {
1727 return station->m_state->m_ness;
1728 }
1729
1730 Ptr<WifiPhy>
GetPhy(void) const1731 WifiRemoteStationManager::GetPhy (void) const
1732 {
1733 return m_wifiPhy;
1734 }
1735
1736 Ptr<WifiMac>
GetMac(void) const1737 WifiRemoteStationManager::GetMac (void) const
1738 {
1739 return m_wifiMac;
1740 }
1741
1742 uint8_t
GetNSupported(const WifiRemoteStation * station) const1743 WifiRemoteStationManager::GetNSupported (const WifiRemoteStation *station) const
1744 {
1745 return static_cast<uint8_t> (station->m_state->m_operationalRateSet.size ());
1746 }
1747
1748 bool
GetQosSupported(const WifiRemoteStation * station) const1749 WifiRemoteStationManager::GetQosSupported (const WifiRemoteStation *station) const
1750 {
1751 return station->m_state->m_qosSupported;
1752 }
1753
1754 bool
GetHtSupported(const WifiRemoteStation * station) const1755 WifiRemoteStationManager::GetHtSupported (const WifiRemoteStation *station) const
1756 {
1757 return (station->m_state->m_htCapabilities != 0);
1758 }
1759
1760 bool
GetVhtSupported(const WifiRemoteStation * station) const1761 WifiRemoteStationManager::GetVhtSupported (const WifiRemoteStation *station) const
1762 {
1763 return (station->m_state->m_vhtCapabilities != 0);
1764 }
1765
1766 bool
GetHeSupported(const WifiRemoteStation * station) const1767 WifiRemoteStationManager::GetHeSupported (const WifiRemoteStation *station) const
1768 {
1769 return (station->m_state->m_heCapabilities != 0);
1770 }
1771
1772 uint8_t
GetNMcsSupported(const WifiRemoteStation * station) const1773 WifiRemoteStationManager::GetNMcsSupported (const WifiRemoteStation *station) const
1774 {
1775 return static_cast<uint8_t> (station->m_state->m_operationalMcsSet.size ());
1776 }
1777
1778 uint32_t
GetNNonErpSupported(const WifiRemoteStation * station) const1779 WifiRemoteStationManager::GetNNonErpSupported (const WifiRemoteStation *station) const
1780 {
1781 uint32_t size = 0;
1782 for (WifiModeListIterator i = station->m_state->m_operationalRateSet.begin (); i != station->m_state->m_operationalRateSet.end (); i++)
1783 {
1784 if (i->GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
1785 {
1786 continue;
1787 }
1788 size++;
1789 }
1790 return size;
1791 }
1792
1793 uint16_t
GetChannelWidthSupported(Mac48Address address) const1794 WifiRemoteStationManager::GetChannelWidthSupported (Mac48Address address) const
1795 {
1796 return LookupState (address)->m_channelWidth;
1797 }
1798
1799 bool
GetShortGuardIntervalSupported(Mac48Address address) const1800 WifiRemoteStationManager::GetShortGuardIntervalSupported (Mac48Address address) const
1801 {
1802 Ptr<const HtCapabilities> htCapabilities = LookupState (address)->m_htCapabilities;
1803
1804 if (!htCapabilities)
1805 {
1806 return false;
1807 }
1808 return htCapabilities->GetShortGuardInterval20 ();
1809 }
1810
1811 uint8_t
GetNumberOfSupportedStreams(Mac48Address address) const1812 WifiRemoteStationManager::GetNumberOfSupportedStreams (Mac48Address address) const
1813 {
1814 Ptr<const HtCapabilities> htCapabilities = LookupState (address)->m_htCapabilities;
1815
1816 if (!htCapabilities)
1817 {
1818 return 1;
1819 }
1820 return htCapabilities->GetRxHighestSupportedAntennas ();
1821 }
1822
1823 uint8_t
GetNMcsSupported(Mac48Address address) const1824 WifiRemoteStationManager::GetNMcsSupported (Mac48Address address) const
1825 {
1826 return static_cast<uint8_t> (LookupState (address)->m_operationalMcsSet.size ());
1827 }
1828
1829 bool
GetDsssSupported(const Mac48Address & address) const1830 WifiRemoteStationManager::GetDsssSupported (const Mac48Address& address) const
1831 {
1832 return (LookupState (address)->m_dsssSupported);
1833 }
1834
1835 bool
GetErpOfdmSupported(const Mac48Address & address) const1836 WifiRemoteStationManager::GetErpOfdmSupported (const Mac48Address& address) const
1837 {
1838 return (LookupState (address)->m_erpOfdmSupported);
1839 }
1840
1841 bool
GetOfdmSupported(const Mac48Address & address) const1842 WifiRemoteStationManager::GetOfdmSupported (const Mac48Address& address) const
1843 {
1844 return (LookupState (address)->m_ofdmSupported);
1845 }
1846
1847 bool
GetHtSupported(Mac48Address address) const1848 WifiRemoteStationManager::GetHtSupported (Mac48Address address) const
1849 {
1850 return (LookupState (address)->m_htCapabilities != 0);
1851 }
1852
1853 bool
GetVhtSupported(Mac48Address address) const1854 WifiRemoteStationManager::GetVhtSupported (Mac48Address address) const
1855 {
1856 return (LookupState (address)->m_vhtCapabilities != 0);
1857 }
1858
1859 bool
GetHeSupported(Mac48Address address) const1860 WifiRemoteStationManager::GetHeSupported (Mac48Address address) const
1861 {
1862 return (LookupState (address)->m_heCapabilities != 0);
1863 }
1864
1865 void
SetDefaultTxPowerLevel(uint8_t txPower)1866 WifiRemoteStationManager::SetDefaultTxPowerLevel (uint8_t txPower)
1867 {
1868 m_defaultTxPowerLevel = txPower;
1869 }
1870
1871 uint8_t
GetNumberOfAntennas(void) const1872 WifiRemoteStationManager::GetNumberOfAntennas (void) const
1873 {
1874 return m_wifiPhy->GetNumberOfAntennas ();
1875 }
1876
1877 uint8_t
GetMaxNumberOfTransmitStreams(void) const1878 WifiRemoteStationManager::GetMaxNumberOfTransmitStreams (void) const
1879 {
1880 return m_wifiPhy->GetMaxSupportedTxSpatialStreams ();
1881 }
1882
1883 bool
UseLdpcForDestination(Mac48Address dest) const1884 WifiRemoteStationManager::UseLdpcForDestination (Mac48Address dest) const
1885 {
1886 return (GetLdpcSupported () && GetLdpcSupported (dest));
1887 }
1888
1889 } //namespace ns3
1890