A Discrete-Event Network Simulator
API
wifi-remote-station-manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006,2007 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 
21 
22 #include "ap-wifi-mac.h"
23 #include "sta-wifi-mac.h"
24 #include "wifi-mac-header.h"
25 #include "wifi-mac-trailer.h"
26 #include "wifi-mpdu.h"
27 #include "wifi-net-device.h"
28 #include "wifi-phy.h"
29 
30 #include "ns3/boolean.h"
31 #include "ns3/eht-configuration.h"
32 #include "ns3/enum.h"
33 #include "ns3/he-configuration.h"
34 #include "ns3/ht-configuration.h"
35 #include "ns3/ht-phy.h"
36 #include "ns3/log.h"
37 #include "ns3/simulator.h"
38 #include "ns3/uinteger.h"
39 #include "ns3/vht-configuration.h"
40 
41 namespace ns3
42 {
43 
44 NS_LOG_COMPONENT_DEFINE("WifiRemoteStationManager");
45 
46 NS_OBJECT_ENSURE_REGISTERED(WifiRemoteStationManager);
47 
48 TypeId
50 {
51  static TypeId tid =
52  TypeId("ns3::WifiRemoteStationManager")
53  .SetParent<Object>()
54  .SetGroupName("Wifi")
55  .AddAttribute("MaxSsrc",
56  "The maximum number of retransmission attempts for any packet with size "
57  "<= RtsCtsThreshold. "
58  "This value will not have any effect on some rate control algorithms.",
59  UintegerValue(7),
61  MakeUintegerChecker<uint32_t>())
62  .AddAttribute("MaxSlrc",
63  "The maximum number of retransmission attempts for any packet with size "
64  "> RtsCtsThreshold. "
65  "This value will not have any effect on some rate control algorithms.",
66  UintegerValue(4),
68  MakeUintegerChecker<uint32_t>())
69  .AddAttribute("RtsCtsThreshold",
70  "If the size of the PSDU is bigger than this value, we use an RTS/CTS "
71  "handshake before sending the data frame."
72  "This value will not have any effect on some rate control algorithms.",
73  UintegerValue(65535),
75  MakeUintegerChecker<uint32_t>())
76  .AddAttribute(
77  "FragmentationThreshold",
78  "If the size of the PSDU is bigger than this value, we fragment it such that the "
79  "size of the fragments are equal or smaller. "
80  "This value does not apply when it is carried in an A-MPDU. "
81  "This value will not have any effect on some rate control algorithms.",
82  UintegerValue(65535),
85  MakeUintegerChecker<uint32_t>())
86  .AddAttribute("NonUnicastMode",
87  "Wifi mode used for non-unicast transmissions.",
88  WifiModeValue(),
89  MakeWifiModeAccessor(&WifiRemoteStationManager::m_nonUnicastMode),
90  MakeWifiModeChecker())
91  .AddAttribute("DefaultTxPowerLevel",
92  "Default power level to be used for transmissions. "
93  "This is the power level that is used by all those WifiManagers that do "
94  "not implement TX power control.",
95  UintegerValue(0),
97  MakeUintegerChecker<uint8_t>())
98  .AddAttribute("ErpProtectionMode",
99  "Protection mode used when non-ERP STAs are connected to an ERP AP: "
100  "Rts-Cts or Cts-To-Self",
104  "Rts-Cts",
106  "Cts-To-Self"))
107  .AddAttribute("HtProtectionMode",
108  "Protection mode used when non-HT STAs are connected to a HT AP: Rts-Cts "
109  "or Cts-To-Self",
113  "Rts-Cts",
115  "Cts-To-Self"))
116  .AddTraceSource("MacTxRtsFailed",
117  "The transmission of a RTS by the MAC layer has failed",
119  "ns3::Mac48Address::TracedCallback")
120  .AddTraceSource("MacTxDataFailed",
121  "The transmission of a data packet by the MAC layer has failed",
123  "ns3::Mac48Address::TracedCallback")
124  .AddTraceSource(
125  "MacTxFinalRtsFailed",
126  "The transmission of a RTS has exceeded the maximum number of attempts",
128  "ns3::Mac48Address::TracedCallback")
129  .AddTraceSource(
130  "MacTxFinalDataFailed",
131  "The transmission of a data packet has exceeded the maximum number of attempts",
133  "ns3::Mac48Address::TracedCallback");
134  return tid;
135 }
136 
138  : m_useNonErpProtection(false),
139  m_useNonHtProtection(false),
140  m_shortPreambleEnabled(false),
141  m_shortSlotTimeEnabled(false)
142 {
143  NS_LOG_FUNCTION(this);
144 }
145 
147 {
148  NS_LOG_FUNCTION(this);
149 }
150 
151 void
153 {
154  NS_LOG_FUNCTION(this);
155  Reset();
156 }
157 
158 void
160 {
161  NS_LOG_FUNCTION(this << phy);
162  // We need to track our PHY because it is the object that knows the
163  // full set of transmit rates that are supported. We need to know
164  // this in order to find the relevant mandatory rates when choosing a
165  // transmit rate for automatic control responses like
166  // acknowledgments.
167  m_wifiPhy = phy;
168  m_defaultTxMode = phy->GetDefaultMode();
170  if (GetHtSupported())
171  {
173  }
174  Reset();
175 }
176 
177 void
179 {
180  NS_LOG_FUNCTION(this << mac);
181  // We need to track our MAC because it is the object that knows the
182  // full set of interframe spaces.
183  m_wifiMac = mac;
184  Reset();
185 }
186 
187 int64_t
189 {
190  NS_LOG_FUNCTION(this << stream);
191  return 0;
192 }
193 
194 void
196 {
197  NS_LOG_FUNCTION(this << maxSsrc);
198  m_maxSsrc = maxSsrc;
199 }
200 
201 void
203 {
204  NS_LOG_FUNCTION(this << maxSlrc);
205  m_maxSlrc = maxSlrc;
206 }
207 
208 void
210 {
211  NS_LOG_FUNCTION(this << threshold);
212  m_rtsCtsThreshold = threshold;
213 }
214 
215 void
217 {
218  NS_LOG_FUNCTION(this << threshold);
219  DoSetFragmentationThreshold(threshold);
220 }
221 
222 void
224 {
225  NS_LOG_FUNCTION(this << enable);
226  m_shortPreambleEnabled = enable;
227 }
228 
229 void
231 {
232  NS_LOG_FUNCTION(this << enable);
233  m_shortSlotTimeEnabled = enable;
234 }
235 
236 bool
238 {
239  return m_shortSlotTimeEnabled;
240 }
241 
242 bool
244 {
245  return m_shortPreambleEnabled;
246 }
247 
248 bool
250 {
251  return bool(m_wifiPhy->GetDevice()->GetHtConfiguration());
252 }
253 
254 bool
256 {
257  return (m_wifiPhy->GetDevice()->GetVhtConfiguration() &&
259 }
260 
261 bool
263 {
264  return bool(m_wifiPhy->GetDevice()->GetHeConfiguration());
265 }
266 
267 bool
269 {
270  return bool(m_wifiPhy->GetDevice()->GetEhtConfiguration());
271 }
272 
273 bool
275 {
276  if (GetHtSupported())
277  {
279  NS_ASSERT(htConfiguration); // If HT is supported, we should have a HT configuration
280  // attached
281  return htConfiguration->GetLdpcSupported();
282  }
283  return false;
284 }
285 
286 bool
288 {
289  if (GetHtSupported())
290  {
292  NS_ASSERT(htConfiguration); // If HT is supported, we should have a HT configuration
293  // attached
294  if (htConfiguration->GetShortGuardIntervalSupported())
295  {
296  return true;
297  }
298  }
299  return false;
300 }
301 
302 uint16_t
304 {
305  uint16_t gi = 0;
306  if (GetHeSupported())
307  {
309  NS_ASSERT(heConfiguration); // If HE is supported, we should have a HE configuration
310  // attached
311  gi = static_cast<uint16_t>(heConfiguration->GetGuardInterval().GetNanoSeconds());
312  }
313  return gi;
314 }
315 
316 uint32_t
318 {
320 }
321 
322 void
324  bool isShortPreambleSupported)
325 {
326  NS_LOG_FUNCTION(this << address << isShortPreambleSupported);
327  NS_ASSERT(!address.IsGroup());
328  LookupState(address)->m_shortPreamble = isShortPreambleSupported;
329 }
330 
331 void
333  bool isShortSlotTimeSupported)
334 {
335  NS_LOG_FUNCTION(this << address << isShortSlotTimeSupported);
336  NS_ASSERT(!address.IsGroup());
337  LookupState(address)->m_shortSlotTime = isShortSlotTimeSupported;
338 }
339 
340 void
342 {
343  NS_LOG_FUNCTION(this << address << mode);
344  NS_ASSERT(!address.IsGroup());
345  auto state = LookupState(address);
346  for (const auto& i : state->m_operationalRateSet)
347  {
348  if (i == mode)
349  {
350  return; // already in
351  }
352  }
353  if ((mode.GetModulationClass() == WIFI_MOD_CLASS_DSSS) ||
355  {
356  state->m_dsssSupported = true;
357  }
358  else if (mode.GetModulationClass() == WIFI_MOD_CLASS_ERP_OFDM)
359  {
360  state->m_erpOfdmSupported = true;
361  }
362  else if (mode.GetModulationClass() == WIFI_MOD_CLASS_OFDM)
363  {
364  state->m_ofdmSupported = true;
365  }
366  state->m_operationalRateSet.push_back(mode);
367 }
368 
369 void
371 {
372  NS_LOG_FUNCTION(this << address);
373  NS_ASSERT(!address.IsGroup());
374  auto state = LookupState(address);
375  state->m_operationalRateSet.clear();
376  for (const auto& mode : m_wifiPhy->GetModeList())
377  {
378  state->m_operationalRateSet.push_back(mode);
379  if (mode.IsMandatory())
380  {
381  AddBasicMode(mode);
382  }
383  }
384 }
385 
386 void
388 {
389  NS_LOG_FUNCTION(this << address);
390  NS_ASSERT(!address.IsGroup());
391  auto state = LookupState(address);
392  state->m_operationalMcsSet.clear();
393  for (const auto& mcs : m_wifiPhy->GetMcsList())
394  {
395  state->m_operationalMcsSet.push_back(mcs);
396  }
397 }
398 
399 void
401 {
402  NS_LOG_FUNCTION(this << address);
403  NS_ASSERT(!address.IsGroup());
404  LookupState(address)->m_operationalMcsSet.clear();
405 }
406 
407 void
409 {
410  NS_LOG_FUNCTION(this << address << mcs);
411  NS_ASSERT(!address.IsGroup());
412  auto state = LookupState(address);
413  for (const auto& i : state->m_operationalMcsSet)
414  {
415  if (i == mcs)
416  {
417  return; // already in
418  }
419  }
420  state->m_operationalMcsSet.push_back(mcs);
421 }
422 
423 bool
425 {
426  return LookupState(address)->m_shortPreamble;
427 }
428 
429 bool
431 {
432  return LookupState(address)->m_shortSlotTime;
433 }
434 
435 bool
437 {
438  return LookupState(address)->m_qosSupported;
439 }
440 
441 bool
443 {
444  if (address.IsGroup())
445  {
446  return false;
447  }
449 }
450 
451 bool
453 {
454  if (address.IsGroup())
455  {
456  return true;
457  }
459 }
460 
461 bool
463 {
464  if (address.IsGroup())
465  {
466  return false;
467  }
469 }
470 
471 void
473 {
474  NS_ASSERT(!address.IsGroup());
476 }
477 
478 void
480 {
481  NS_ASSERT(!address.IsGroup());
483 }
484 
485 void
487 {
488  NS_ASSERT(!address.IsGroup());
490 }
491 
492 void
494 {
495  NS_ASSERT(!address.IsGroup());
497 }
498 
499 bool
501 {
502  if (address.IsGroup())
503  {
504  return false;
505  }
507 }
508 
509 void
511 {
512  NS_ASSERT(!address.IsGroup());
514 }
515 
516 uint16_t
518 {
519  std::shared_ptr<WifiRemoteStationState> state;
520  if (!remoteAddress.IsGroup() &&
521  (state = LookupState(remoteAddress))->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK)
522  {
523  return state->m_aid;
524  }
525  return SU_STA_ID;
526 }
527 
528 uint16_t
530 {
531  NS_LOG_FUNCTION(this << address << txVector);
532 
533  uint16_t staId = SU_STA_ID;
534 
535  if (txVector.IsMu())
536  {
537  if (m_wifiMac->GetTypeOfStation() == AP)
538  {
539  staId = GetAssociationId(address);
540  }
541  else if (m_wifiMac->GetTypeOfStation() == STA)
542  {
543  Ptr<StaWifiMac> staMac = StaticCast<StaWifiMac>(m_wifiMac);
544  if (staMac->IsAssociated())
545  {
546  staId = staMac->GetAssociationId();
547  }
548  }
549  }
550 
551  NS_LOG_DEBUG("Returning STAID = " << staId);
552  return staId;
553 }
554 
555 void
557 {
558  NS_LOG_FUNCTION(this << address << mldAddress);
559 
560  auto state = LookupState(address);
561  state->m_mldAddress = mldAddress;
562  // insert another entry in m_states indexed by the MLD address and pointing to the same state
563  const_cast<WifiRemoteStationManager*>(this)->m_states.insert({mldAddress, state});
564 }
565 
566 std::optional<Mac48Address>
567 WifiRemoteStationManager::GetMldAddress(const Mac48Address& address) const
568 {
569  return LookupState(address)->m_mldAddress;
570 }
571 
572 std::optional<Mac48Address>
573 WifiRemoteStationManager::GetAffiliatedStaAddress(const Mac48Address& mldAddress) const
574 {
575  auto stateIt = m_states.find(mldAddress);
576 
577  if (stateIt == m_states.end() || !stateIt->second->m_mldAddress)
578  {
579  // MLD address not found
580  return std::nullopt;
581  }
582 
583  NS_ASSERT(*stateIt->second->m_mldAddress == mldAddress);
584  return stateIt->second->m_address;
585 }
586 
588 WifiRemoteStationManager::GetDataTxVector(const WifiMacHeader& header, uint16_t allowedWidth)
589 {
590  NS_LOG_FUNCTION(this << header << allowedWidth);
591  Mac48Address address = header.GetAddr1();
592  if (!header.IsMgt() && address.IsGroup())
593  {
594  WifiMode mode = GetNonUnicastMode();
595  WifiTxVector v;
596  v.SetMode(mode);
597  v.SetPreambleType(
598  GetPreambleForTransmission(mode.GetModulationClass(), GetShortPreambleEnabled()));
599  v.SetTxPowerLevel(m_defaultTxPowerLevel);
600  v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(mode, allowedWidth));
601  v.SetGuardInterval(ConvertGuardIntervalToNanoSeconds(mode, m_wifiPhy->GetDevice()));
602  v.SetNTx(GetNumberOfAntennas());
603  v.SetNss(1);
604  v.SetNess(0);
605  return v;
606  }
607  WifiTxVector txVector;
608  if (header.IsMgt())
609  {
610  // Use the lowest basic rate for management frames
611  WifiMode mgtMode;
612  if (GetNBasicModes() > 0)
613  {
614  mgtMode = GetBasicMode(0);
615  }
616  else
617  {
618  mgtMode = GetDefaultMode();
619  }
620  txVector.SetMode(mgtMode);
621  txVector.SetPreambleType(
622  GetPreambleForTransmission(mgtMode.GetModulationClass(), GetShortPreambleEnabled()));
623  txVector.SetTxPowerLevel(m_defaultTxPowerLevel);
624  uint16_t channelWidth = allowedWidth;
625  if (!header.GetAddr1().IsGroup())
626  {
627  if (uint16_t rxWidth = GetChannelWidthSupported(header.GetAddr1());
628  rxWidth < channelWidth)
629  {
630  channelWidth = rxWidth;
631  }
632  }
633 
634  txVector.SetChannelWidth(m_wifiPhy->GetTxBandwidth(mgtMode, channelWidth));
635  txVector.SetGuardInterval(
636  ConvertGuardIntervalToNanoSeconds(mgtMode, m_wifiPhy->GetDevice()));
637  }
638  else
639  {
640  txVector = DoGetDataTxVector(Lookup(address), allowedWidth);
641  txVector.SetLdpc(txVector.GetMode().GetModulationClass() < WIFI_MOD_CLASS_HT
642  ? 0
643  : UseLdpcForDestination(address));
644  }
645  Ptr<HeConfiguration> heConfiguration = m_wifiPhy->GetDevice()->GetHeConfiguration();
646  if (heConfiguration)
647  {
648  txVector.SetBssColor(heConfiguration->GetBssColor());
649  }
650  // If both the allowed width and the TXVECTOR channel width are integer multiple
651  // of 20 MHz, then the TXVECTOR channel width must not exceed the allowed width
652  NS_ASSERT_MSG((txVector.GetChannelWidth() % 20 != 0) || (allowedWidth % 20 != 0) ||
653  (txVector.GetChannelWidth() <= allowedWidth),
654  "TXVECTOR channel width (" << txVector.GetChannelWidth()
655  << " MHz) exceeds allowed width (" << allowedWidth
656  << " MHz)");
657  return txVector;
658 }
659 
661 WifiRemoteStationManager::GetCtsToSelfTxVector()
662 {
663  WifiMode defaultMode = GetDefaultMode();
664  WifiPreamble defaultPreamble;
665  if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_EHT)
666  {
667  defaultPreamble = WIFI_PREAMBLE_EHT_MU;
668  }
669  else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_HE)
670  {
671  defaultPreamble = WIFI_PREAMBLE_HE_SU;
672  }
673  else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_VHT)
674  {
675  defaultPreamble = WIFI_PREAMBLE_VHT_SU;
676  }
677  else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_HT)
678  {
679  defaultPreamble = WIFI_PREAMBLE_HT_MF;
680  }
681  else
682  {
683  defaultPreamble = WIFI_PREAMBLE_LONG;
684  }
685 
686  return WifiTxVector(defaultMode,
687  GetDefaultTxPowerLevel(),
688  defaultPreamble,
689  ConvertGuardIntervalToNanoSeconds(defaultMode, m_wifiPhy->GetDevice()),
690  GetNumberOfAntennas(),
691  1,
692  0,
693  m_wifiPhy->GetTxBandwidth(defaultMode),
694  false);
695 }
696 
698 WifiRemoteStationManager::GetRtsTxVector(Mac48Address address)
699 {
700  NS_LOG_FUNCTION(this << address);
701  if (address.IsGroup())
702  {
703  WifiMode mode = GetNonUnicastMode();
704  WifiTxVector v;
705  v.SetMode(mode);
706  v.SetPreambleType(
707  GetPreambleForTransmission(mode.GetModulationClass(), GetShortPreambleEnabled()));
708  v.SetTxPowerLevel(m_defaultTxPowerLevel);
709  v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(mode));
710  v.SetGuardInterval(ConvertGuardIntervalToNanoSeconds(mode, m_wifiPhy->GetDevice()));
711  v.SetNTx(GetNumberOfAntennas());
712  v.SetNss(1);
713  v.SetNess(0);
714  return v;
715  }
716  return DoGetRtsTxVector(Lookup(address));
717 }
718 
720 WifiRemoteStationManager::GetCtsTxVector(Mac48Address to, WifiMode rtsTxMode) const
721 {
722  NS_ASSERT(!to.IsGroup());
723  WifiMode ctsMode = GetControlAnswerMode(rtsTxMode);
724  WifiTxVector v;
725  v.SetMode(ctsMode);
726  v.SetPreambleType(
727  GetPreambleForTransmission(ctsMode.GetModulationClass(), GetShortPreambleEnabled()));
728  v.SetTxPowerLevel(GetDefaultTxPowerLevel());
729  v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(ctsMode));
730  uint16_t ctsTxGuardInterval =
731  ConvertGuardIntervalToNanoSeconds(ctsMode, m_wifiPhy->GetDevice());
732  v.SetGuardInterval(ctsTxGuardInterval);
733  v.SetNss(1);
734  return v;
735 }
736 
738 WifiRemoteStationManager::GetAckTxVector(Mac48Address to, const WifiTxVector& dataTxVector) const
739 {
740  NS_ASSERT(!to.IsGroup());
741  WifiMode ackMode = GetControlAnswerMode(dataTxVector.GetMode(GetStaId(to, dataTxVector)));
742  WifiTxVector v;
743  v.SetMode(ackMode);
744  v.SetPreambleType(
745  GetPreambleForTransmission(ackMode.GetModulationClass(), GetShortPreambleEnabled()));
746  v.SetTxPowerLevel(GetDefaultTxPowerLevel());
747  v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(ackMode));
748  uint16_t ackTxGuardInterval =
749  ConvertGuardIntervalToNanoSeconds(ackMode, m_wifiPhy->GetDevice());
750  v.SetGuardInterval(ackTxGuardInterval);
751  v.SetNss(1);
752  return v;
753 }
754 
756 WifiRemoteStationManager::GetBlockAckTxVector(Mac48Address to,
757  const WifiTxVector& dataTxVector) const
758 {
759  NS_ASSERT(!to.IsGroup());
760  WifiMode blockAckMode = GetControlAnswerMode(dataTxVector.GetMode(GetStaId(to, dataTxVector)));
761  WifiTxVector v;
762  v.SetMode(blockAckMode);
763  v.SetPreambleType(
764  GetPreambleForTransmission(blockAckMode.GetModulationClass(), GetShortPreambleEnabled()));
765  v.SetTxPowerLevel(GetDefaultTxPowerLevel());
766  v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(blockAckMode));
767  uint16_t blockAckTxGuardInterval =
768  ConvertGuardIntervalToNanoSeconds(blockAckMode, m_wifiPhy->GetDevice());
769  v.SetGuardInterval(blockAckTxGuardInterval);
770  v.SetNss(1);
771  return v;
772 }
773 
774 WifiMode
775 WifiRemoteStationManager::GetControlAnswerMode(WifiMode reqMode) const
776 {
791  NS_LOG_FUNCTION(this << reqMode);
792  WifiMode mode = GetDefaultMode();
793  bool found = false;
794  // First, search the BSS Basic Rate set
795  for (uint8_t i = 0; i < GetNBasicModes(); i++)
796  {
797  WifiMode testMode = GetBasicMode(i);
798  if ((!found || testMode.IsHigherDataRate(mode)) && (!testMode.IsHigherDataRate(reqMode)) &&
800  testMode.GetModulationClass())))
801  {
802  mode = testMode;
803  // We've found a potentially-suitable transmit rate, but we
804  // need to continue and consider all the basic rates before
805  // we can be sure we've got the right one.
806  found = true;
807  }
808  }
809  if (GetHtSupported())
810  {
811  if (!found)
812  {
813  mode = GetDefaultMcs();
814  for (uint8_t i = 0; i != GetNBasicMcs(); i++)
815  {
816  WifiMode testMode = GetBasicMcs(i);
817  if ((!found || testMode.IsHigherDataRate(mode)) &&
818  (!testMode.IsHigherDataRate(reqMode)) &&
819  (testMode.GetModulationClass() == reqMode.GetModulationClass()))
820  {
821  mode = testMode;
822  // We've found a potentially-suitable transmit rate, but we
823  // need to continue and consider all the basic rates before
824  // we can be sure we've got the right one.
825  found = true;
826  }
827  }
828  }
829  }
830  // If we found a suitable rate in the BSSBasicRateSet, then we are
831  // done and can return that mode.
832  if (found)
833  {
834  NS_LOG_DEBUG("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
835  return mode;
836  }
837 
855  for (const auto& thismode : m_wifiPhy->GetModeList())
856  {
857  /* If the rate:
858  *
859  * - is a mandatory rate for the PHY, and
860  * - is equal to or faster than our current best choice, and
861  * - is less than or equal to the rate of the received frame, and
862  * - is of the same modulation class as the received frame
863  *
864  * ...then it's our best choice so far.
865  */
866  if (thismode.IsMandatory() && (!found || thismode.IsHigherDataRate(mode)) &&
867  (!thismode.IsHigherDataRate(reqMode)) &&
869  thismode.GetModulationClass())))
870  {
871  mode = thismode;
872  // As above; we've found a potentially-suitable transmit
873  // rate, but we need to continue and consider all the
874  // mandatory rates before we can be sure we've got the right one.
875  found = true;
876  }
877  }
878  if (GetHtSupported())
879  {
880  for (const auto& thismode : m_wifiPhy->GetMcsList())
881  {
882  if (thismode.IsMandatory() && (!found || thismode.IsHigherDataRate(mode)) &&
883  (!thismode.IsHigherCodeRate(reqMode)) &&
884  (thismode.GetModulationClass() == reqMode.GetModulationClass()))
885  {
886  mode = thismode;
887  // As above; we've found a potentially-suitable transmit
888  // rate, but we need to continue and consider all the
889  // mandatory rates before we can be sure we've got the right one.
890  found = true;
891  }
892  }
893  }
894 
904  if (!found)
905  {
906  NS_FATAL_ERROR("Can't find response rate for " << reqMode);
907  }
908 
909  NS_LOG_DEBUG("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
910  return mode;
911 }
912 
913 void
914 WifiRemoteStationManager::ReportRtsFailed(const WifiMacHeader& header)
915 {
916  NS_LOG_FUNCTION(this << header);
917  NS_ASSERT(!header.GetAddr1().IsGroup());
918  AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
919  m_ssrc[ac]++;
920  m_macTxRtsFailed(header.GetAddr1());
921  DoReportRtsFailed(Lookup(header.GetAddr1()));
922 }
923 
924 void
925 WifiRemoteStationManager::ReportDataFailed(Ptr<const WifiMpdu> mpdu)
926 {
927  NS_LOG_FUNCTION(this << *mpdu);
928  NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
929  AcIndex ac =
930  QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
931  bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
932  if (longMpdu)
933  {
934  m_slrc[ac]++;
935  }
936  else
937  {
938  m_ssrc[ac]++;
939  }
940  m_macTxDataFailed(mpdu->GetHeader().GetAddr1());
941  DoReportDataFailed(Lookup(mpdu->GetHeader().GetAddr1()));
942 }
943 
944 void
945 WifiRemoteStationManager::ReportRtsOk(const WifiMacHeader& header,
946  double ctsSnr,
947  WifiMode ctsMode,
948  double rtsSnr)
949 {
950  NS_LOG_FUNCTION(this << header << ctsSnr << ctsMode << rtsSnr);
951  NS_ASSERT(!header.GetAddr1().IsGroup());
952  WifiRemoteStation* station = Lookup(header.GetAddr1());
953  AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
954  station->m_state->m_info.NotifyTxSuccess(m_ssrc[ac]);
955  m_ssrc[ac] = 0;
956  DoReportRtsOk(station, ctsSnr, ctsMode, rtsSnr);
957 }
958 
959 void
960 WifiRemoteStationManager::ReportDataOk(Ptr<const WifiMpdu> mpdu,
961  double ackSnr,
962  WifiMode ackMode,
963  double dataSnr,
964  WifiTxVector dataTxVector)
965 {
966  NS_LOG_FUNCTION(this << *mpdu << ackSnr << ackMode << dataSnr << dataTxVector);
967  const WifiMacHeader& hdr = mpdu->GetHeader();
968  NS_ASSERT(!hdr.GetAddr1().IsGroup());
969  WifiRemoteStation* station = Lookup(hdr.GetAddr1());
970  AcIndex ac = QosUtilsMapTidToAc((hdr.IsQosData()) ? hdr.GetQosTid() : 0);
971  bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
972  if (longMpdu)
973  {
974  station->m_state->m_info.NotifyTxSuccess(m_slrc[ac]);
975  m_slrc[ac] = 0;
976  }
977  else
978  {
979  station->m_state->m_info.NotifyTxSuccess(m_ssrc[ac]);
980  m_ssrc[ac] = 0;
981  }
982  DoReportDataOk(station,
983  ackSnr,
984  ackMode,
985  dataSnr,
986  dataTxVector.GetChannelWidth(),
987  dataTxVector.GetNss(GetStaId(hdr.GetAddr1(), dataTxVector)));
988 }
989 
990 void
991 WifiRemoteStationManager::ReportFinalRtsFailed(const WifiMacHeader& header)
992 {
993  NS_LOG_FUNCTION(this << header);
994  NS_ASSERT(!header.GetAddr1().IsGroup());
995  WifiRemoteStation* station = Lookup(header.GetAddr1());
996  AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
997  station->m_state->m_info.NotifyTxFailed();
998  m_ssrc[ac] = 0;
999  m_macTxFinalRtsFailed(header.GetAddr1());
1000  DoReportFinalRtsFailed(station);
1001 }
1002 
1003 void
1004 WifiRemoteStationManager::ReportFinalDataFailed(Ptr<const WifiMpdu> mpdu)
1005 {
1006  NS_LOG_FUNCTION(this << *mpdu);
1007  NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1008  WifiRemoteStation* station = Lookup(mpdu->GetHeader().GetAddr1());
1009  AcIndex ac =
1010  QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
1011  station->m_state->m_info.NotifyTxFailed();
1012  bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
1013  if (longMpdu)
1014  {
1015  m_slrc[ac] = 0;
1016  }
1017  else
1018  {
1019  m_ssrc[ac] = 0;
1020  }
1021  m_macTxFinalDataFailed(mpdu->GetHeader().GetAddr1());
1022  DoReportFinalDataFailed(station);
1023 }
1024 
1025 void
1026 WifiRemoteStationManager::ReportRxOk(Mac48Address address,
1027  RxSignalInfo rxSignalInfo,
1028  WifiTxVector txVector)
1029 {
1030  NS_LOG_FUNCTION(this << address << rxSignalInfo << txVector);
1031  if (address.IsGroup())
1032  {
1033  return;
1034  }
1035  WifiRemoteStation* station = Lookup(address);
1036  DoReportRxOk(station, rxSignalInfo.snr, txVector.GetMode(GetStaId(address, txVector)));
1037  station->m_rssiAndUpdateTimePair = std::make_pair(rxSignalInfo.rssi, Simulator::Now());
1038 }
1039 
1040 void
1041 WifiRemoteStationManager::ReportAmpduTxStatus(Mac48Address address,
1042  uint16_t nSuccessfulMpdus,
1043  uint16_t nFailedMpdus,
1044  double rxSnr,
1045  double dataSnr,
1046  WifiTxVector dataTxVector)
1047 {
1048  NS_LOG_FUNCTION(this << address << nSuccessfulMpdus << nFailedMpdus << rxSnr << dataSnr
1049  << dataTxVector);
1050  NS_ASSERT(!address.IsGroup());
1051  for (uint16_t i = 0; i < nFailedMpdus; i++)
1052  {
1053  m_macTxDataFailed(address);
1054  }
1055  DoReportAmpduTxStatus(Lookup(address),
1056  nSuccessfulMpdus,
1057  nFailedMpdus,
1058  rxSnr,
1059  dataSnr,
1060  dataTxVector.GetChannelWidth(),
1061  dataTxVector.GetNss(GetStaId(address, dataTxVector)));
1062 }
1063 
1064 bool
1065 WifiRemoteStationManager::NeedRts(const WifiMacHeader& header, uint32_t size)
1066 {
1067  NS_LOG_FUNCTION(this << header << size);
1068  Mac48Address address = header.GetAddr1();
1069  WifiTxVector txVector = GetDataTxVector(header, m_wifiPhy->GetChannelWidth());
1070  const auto modulationClass = txVector.GetModulationClass();
1071  if (address.IsGroup())
1072  {
1073  return false;
1074  }
1075  if (m_erpProtectionMode == RTS_CTS &&
1076  ((modulationClass == WIFI_MOD_CLASS_ERP_OFDM) || (modulationClass == WIFI_MOD_CLASS_HT) ||
1077  (modulationClass == WIFI_MOD_CLASS_VHT) || (modulationClass == WIFI_MOD_CLASS_HE) ||
1078  (modulationClass == WIFI_MOD_CLASS_EHT)) &&
1079  m_useNonErpProtection)
1080  {
1081  NS_LOG_DEBUG(
1082  "WifiRemoteStationManager::NeedRTS returning true to protect non-ERP stations");
1083  return true;
1084  }
1085  else if (m_htProtectionMode == RTS_CTS &&
1086  ((modulationClass == WIFI_MOD_CLASS_HT) || (modulationClass == WIFI_MOD_CLASS_VHT)) &&
1087  m_useNonHtProtection && !(m_erpProtectionMode != RTS_CTS && m_useNonErpProtection))
1088  {
1089  NS_LOG_DEBUG("WifiRemoteStationManager::NeedRTS returning true to protect non-HT stations");
1090  return true;
1091  }
1092  bool normally = (size > m_rtsCtsThreshold);
1093  return DoNeedRts(Lookup(address), size, normally);
1094 }
1095 
1096 bool
1097 WifiRemoteStationManager::NeedCtsToSelf(WifiTxVector txVector)
1098 {
1099  WifiMode mode = txVector.GetMode();
1100  NS_LOG_FUNCTION(this << mode);
1101  if (m_erpProtectionMode == CTS_TO_SELF &&
1103  (mode.GetModulationClass() == WIFI_MOD_CLASS_HT) ||
1104  (mode.GetModulationClass() == WIFI_MOD_CLASS_VHT) ||
1105  (mode.GetModulationClass() == WIFI_MOD_CLASS_HE) ||
1106  (mode.GetModulationClass() == WIFI_MOD_CLASS_EHT)) &&
1107  m_useNonErpProtection)
1108  {
1109  NS_LOG_DEBUG(
1110  "WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-ERP stations");
1111  return true;
1112  }
1113  else if (m_htProtectionMode == CTS_TO_SELF &&
1114  ((mode.GetModulationClass() == WIFI_MOD_CLASS_HT) ||
1115  (mode.GetModulationClass() == WIFI_MOD_CLASS_VHT)) &&
1116  m_useNonHtProtection && !(m_erpProtectionMode != CTS_TO_SELF && m_useNonErpProtection))
1117  {
1118  NS_LOG_DEBUG(
1119  "WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-HT stations");
1120  return true;
1121  }
1122  else if (!m_useNonErpProtection)
1123  {
1124  // search for the BSS Basic Rate set, if the used mode is in the basic set then there is no
1125  // need for CTS To Self
1126  for (WifiModeListIterator i = m_bssBasicRateSet.begin(); i != m_bssBasicRateSet.end(); i++)
1127  {
1128  if (mode == *i)
1129  {
1130  NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning false");
1131  return false;
1132  }
1133  }
1134  if (GetHtSupported())
1135  {
1136  // search for the BSS Basic MCS set, if the used mode is in the basic set then there is
1137  // no need for CTS To Self
1138  for (WifiModeListIterator i = m_bssBasicMcsSet.begin(); i != m_bssBasicMcsSet.end();
1139  i++)
1140  {
1141  if (mode == *i)
1142  {
1143  NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning false");
1144  return false;
1145  }
1146  }
1147  }
1148  NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning true");
1149  return true;
1150  }
1151  return false;
1152 }
1153 
1154 void
1155 WifiRemoteStationManager::SetUseNonErpProtection(bool enable)
1156 {
1157  NS_LOG_FUNCTION(this << enable);
1158  m_useNonErpProtection = enable;
1159 }
1160 
1161 bool
1162 WifiRemoteStationManager::GetUseNonErpProtection() const
1163 {
1164  return m_useNonErpProtection;
1165 }
1166 
1167 void
1168 WifiRemoteStationManager::SetUseNonHtProtection(bool enable)
1169 {
1170  NS_LOG_FUNCTION(this << enable);
1171  m_useNonHtProtection = enable;
1172 }
1173 
1174 bool
1175 WifiRemoteStationManager::GetUseNonHtProtection() const
1176 {
1177  return m_useNonHtProtection;
1178 }
1179 
1180 bool
1181 WifiRemoteStationManager::NeedRetransmission(Ptr<const WifiMpdu> mpdu)
1182 {
1183  NS_LOG_FUNCTION(this << *mpdu);
1184  NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1185  AcIndex ac =
1186  QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
1187  bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
1188  uint32_t retryCount;
1189  uint32_t maxRetryCount;
1190  if (longMpdu)
1191  {
1192  retryCount = m_slrc[ac];
1193  maxRetryCount = m_maxSlrc;
1194  }
1195  else
1196  {
1197  retryCount = m_ssrc[ac];
1198  maxRetryCount = m_maxSsrc;
1199  }
1200  bool normally = retryCount < maxRetryCount;
1201  NS_LOG_DEBUG("WifiRemoteStationManager::NeedRetransmission count: "
1202  << retryCount << " result: " << std::boolalpha << normally);
1203  return DoNeedRetransmission(Lookup(mpdu->GetHeader().GetAddr1()), mpdu->GetPacket(), normally);
1204 }
1205 
1206 bool
1207 WifiRemoteStationManager::NeedFragmentation(Ptr<const WifiMpdu> mpdu)
1208 {
1209  NS_LOG_FUNCTION(this << *mpdu);
1210  if (mpdu->GetHeader().GetAddr1().IsGroup())
1211  {
1212  return false;
1213  }
1214  bool normally = mpdu->GetSize() > GetFragmentationThreshold();
1215  NS_LOG_DEBUG("WifiRemoteStationManager::NeedFragmentation result: " << std::boolalpha
1216  << normally);
1217  return DoNeedFragmentation(Lookup(mpdu->GetHeader().GetAddr1()), mpdu->GetPacket(), normally);
1218 }
1219 
1220 void
1221 WifiRemoteStationManager::DoSetFragmentationThreshold(uint32_t threshold)
1222 {
1223  NS_LOG_FUNCTION(this << threshold);
1224  if (threshold < 256)
1225  {
1226  /*
1227  * ASN.1 encoding of the MAC and PHY MIB (256 ... 8000)
1228  */
1229  NS_LOG_WARN("Fragmentation threshold should be larger than 256. Setting to 256.");
1230  m_fragmentationThreshold = 256;
1231  }
1232  else
1233  {
1234  /*
1235  * The length of each fragment shall be an even number of octets, except for the last
1236  * fragment if an MSDU or MMPDU, which may be either an even or an odd number of octets.
1237  */
1238  if (threshold % 2 != 0)
1239  {
1240  NS_LOG_WARN("Fragmentation threshold should be an even number. Setting to "
1241  << threshold - 1);
1242  m_fragmentationThreshold = threshold - 1;
1243  }
1244  else
1245  {
1246  m_fragmentationThreshold = threshold;
1247  }
1248  }
1249 }
1250 
1251 uint32_t
1252 WifiRemoteStationManager::DoGetFragmentationThreshold() const
1253 {
1254  return m_fragmentationThreshold;
1255 }
1256 
1257 uint32_t
1258 WifiRemoteStationManager::GetNFragments(Ptr<const WifiMpdu> mpdu)
1259 {
1260  NS_LOG_FUNCTION(this << *mpdu);
1261  // The number of bytes a fragment can support is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1262  uint32_t nFragments =
1263  (mpdu->GetPacket()->GetSize() /
1264  (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH));
1265 
1266  // If the size of the last fragment is not 0.
1267  if ((mpdu->GetPacket()->GetSize() %
1268  (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH)) > 0)
1269  {
1270  nFragments++;
1271  }
1272  NS_LOG_DEBUG("WifiRemoteStationManager::GetNFragments returning " << nFragments);
1273  return nFragments;
1274 }
1275 
1276 uint32_t
1277 WifiRemoteStationManager::GetFragmentSize(Ptr<const WifiMpdu> mpdu, uint32_t fragmentNumber)
1278 {
1279  NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1280  NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1281  uint32_t nFragment = GetNFragments(mpdu);
1282  if (fragmentNumber >= nFragment)
1283  {
1284  NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning 0");
1285  return 0;
1286  }
1287  // Last fragment
1288  if (fragmentNumber == nFragment - 1)
1289  {
1290  uint32_t lastFragmentSize =
1291  mpdu->GetPacket()->GetSize() -
1292  (fragmentNumber *
1293  (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH));
1294  NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning " << lastFragmentSize);
1295  return lastFragmentSize;
1296  }
1297  // All fragments but the last, the number of bytes is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1298  else
1299  {
1300  uint32_t fragmentSize =
1301  GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH;
1302  NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning " << fragmentSize);
1303  return fragmentSize;
1304  }
1305 }
1306 
1307 uint32_t
1308 WifiRemoteStationManager::GetFragmentOffset(Ptr<const WifiMpdu> mpdu, uint32_t fragmentNumber)
1309 {
1310  NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1311  NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1312  NS_ASSERT(fragmentNumber < GetNFragments(mpdu));
1313  uint32_t fragmentOffset = fragmentNumber * (GetFragmentationThreshold() -
1314  mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH);
1315  NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentOffset returning " << fragmentOffset);
1316  return fragmentOffset;
1317 }
1318 
1319 bool
1320 WifiRemoteStationManager::IsLastFragment(Ptr<const WifiMpdu> mpdu, uint32_t fragmentNumber)
1321 {
1322  NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1323  NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1324  bool isLast = fragmentNumber == (GetNFragments(mpdu) - 1);
1325  NS_LOG_DEBUG("WifiRemoteStationManager::IsLastFragment returning " << std::boolalpha << isLast);
1326  return isLast;
1327 }
1328 
1329 uint8_t
1330 WifiRemoteStationManager::GetDefaultTxPowerLevel() const
1331 {
1332  return m_defaultTxPowerLevel;
1333 }
1334 
1336 WifiRemoteStationManager::GetInfo(Mac48Address address)
1337 {
1338  return LookupState(address)->m_info;
1339 }
1340 
1341 std::optional<double>
1342 WifiRemoteStationManager::GetMostRecentRssi(Mac48Address address) const
1343 {
1344  auto station = Lookup(address);
1345  auto rssi = station->m_rssiAndUpdateTimePair.first;
1346  auto ts = station->m_rssiAndUpdateTimePair.second;
1347  if (ts.IsStrictlyPositive())
1348  {
1349  return rssi;
1350  }
1351  return std::nullopt;
1352 }
1353 
1354 std::shared_ptr<WifiRemoteStationState>
1355 WifiRemoteStationManager::LookupState(Mac48Address address) const
1356 {
1357  NS_LOG_FUNCTION(this << address);
1358  auto stateIt = m_states.find(address);
1359 
1360  if (stateIt != m_states.end())
1361  {
1362  NS_LOG_DEBUG("WifiRemoteStationManager::LookupState returning existing state");
1363  return stateIt->second;
1364  }
1365 
1366  auto state = std::make_shared<WifiRemoteStationState>();
1367  state->m_state = WifiRemoteStationState::BRAND_NEW;
1368  state->m_address = address;
1369  state->m_aid = 0;
1370  state->m_operationalRateSet.push_back(GetDefaultMode());
1371  state->m_operationalMcsSet.push_back(GetDefaultMcs());
1372  state->m_dsssSupported = false;
1373  state->m_erpOfdmSupported = false;
1374  state->m_ofdmSupported = false;
1375  state->m_htCapabilities = nullptr;
1376  state->m_vhtCapabilities = nullptr;
1377  state->m_heCapabilities = nullptr;
1378  state->m_ehtCapabilities = nullptr;
1379  state->m_channelWidth = m_wifiPhy->GetChannelWidth();
1380  state->m_guardInterval = GetGuardInterval();
1381  state->m_ness = 0;
1382  state->m_aggregation = false;
1383  state->m_qosSupported = false;
1384  const_cast<WifiRemoteStationManager*>(this)->m_states.insert({address, state});
1385  NS_LOG_DEBUG("WifiRemoteStationManager::LookupState returning new state");
1386  return state;
1387 }
1388 
1389 WifiRemoteStation*
1390 WifiRemoteStationManager::Lookup(Mac48Address address) const
1391 {
1392  NS_LOG_FUNCTION(this << address);
1393  auto stationIt = m_stations.find(address);
1394 
1395  if (stationIt != m_stations.end())
1396  {
1397  return stationIt->second;
1398  }
1399 
1400  WifiRemoteStation* station = DoCreateStation();
1401  station->m_state = LookupState(address).get();
1402  station->m_rssiAndUpdateTimePair = std::make_pair(0, Seconds(0));
1403  const_cast<WifiRemoteStationManager*>(this)->m_stations.insert({address, station});
1404  return station;
1405 }
1406 
1407 void
1408 WifiRemoteStationManager::SetAssociationId(Mac48Address remoteAddress, uint16_t aid)
1409 {
1410  NS_LOG_FUNCTION(this << remoteAddress << aid);
1411  LookupState(remoteAddress)->m_aid = aid;
1412 }
1413 
1414 void
1415 WifiRemoteStationManager::SetQosSupport(Mac48Address from, bool qosSupported)
1416 {
1417  NS_LOG_FUNCTION(this << from << qosSupported);
1418  LookupState(from)->m_qosSupported = qosSupported;
1419 }
1420 
1421 void
1422 WifiRemoteStationManager::AddStationHtCapabilities(Mac48Address from, HtCapabilities htCapabilities)
1423 {
1424  // Used by all stations to record HT capabilities of remote stations
1425  NS_LOG_FUNCTION(this << from << htCapabilities);
1426  auto state = LookupState(from);
1427  if (htCapabilities.GetSupportedChannelWidth() == 1)
1428  {
1429  state->m_channelWidth = 40;
1430  }
1431  else
1432  {
1433  state->m_channelWidth = 20;
1434  }
1435  SetQosSupport(from, true);
1436  for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_HT))
1437  {
1438  if (htCapabilities.IsSupportedMcs(mcs.GetMcsValue()))
1439  {
1440  AddSupportedMcs(from, mcs);
1441  }
1442  }
1443  state->m_htCapabilities = Create<const HtCapabilities>(htCapabilities);
1444 }
1445 
1446 void
1447 WifiRemoteStationManager::AddStationVhtCapabilities(Mac48Address from,
1448  VhtCapabilities vhtCapabilities)
1449 {
1450  // Used by all stations to record VHT capabilities of remote stations
1451  NS_LOG_FUNCTION(this << from << vhtCapabilities);
1452  auto state = LookupState(from);
1453  if (vhtCapabilities.GetSupportedChannelWidthSet() == 1)
1454  {
1455  state->m_channelWidth = 160;
1456  }
1457  else
1458  {
1459  state->m_channelWidth = 80;
1460  }
1461  for (uint8_t i = 1; i <= m_wifiPhy->GetMaxSupportedTxSpatialStreams(); i++)
1462  {
1463  for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_VHT))
1464  {
1465  if (vhtCapabilities.IsSupportedMcs(mcs.GetMcsValue(), i))
1466  {
1467  AddSupportedMcs(from, mcs);
1468  }
1469  }
1470  }
1471  state->m_vhtCapabilities = Create<const VhtCapabilities>(vhtCapabilities);
1472 }
1473 
1474 void
1475 WifiRemoteStationManager::AddStationHeCapabilities(Mac48Address from, HeCapabilities heCapabilities)
1476 {
1477  // Used by all stations to record HE capabilities of remote stations
1478  NS_LOG_FUNCTION(this << from << heCapabilities);
1479  auto state = LookupState(from);
1480  if ((m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) ||
1481  (m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_6GHZ))
1482  {
1483  if (heCapabilities.GetChannelWidthSet() & 0x04)
1484  {
1485  state->m_channelWidth = 160;
1486  }
1487  else if (heCapabilities.GetChannelWidthSet() & 0x02)
1488  {
1489  state->m_channelWidth = 80;
1490  }
1491  // For other cases at 5 GHz, the supported channel width is set by the VHT capabilities
1492  }
1493  else if (m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ)
1494  {
1495  if (heCapabilities.GetChannelWidthSet() & 0x01)
1496  {
1497  state->m_channelWidth = 40;
1498  }
1499  else
1500  {
1501  state->m_channelWidth = 20;
1502  }
1503  }
1504  if (heCapabilities.GetHeSuPpdu1xHeLtf800nsGi() == 1)
1505  {
1506  state->m_guardInterval = 800;
1507  }
1508  else
1509  {
1510  // todo: Using 3200ns, default value for HeConfiguration::GuardInterval
1511  state->m_guardInterval = 3200;
1512  }
1513  for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_HE))
1514  {
1515  if (heCapabilities.GetHighestMcsSupported() >= mcs.GetMcsValue())
1516  {
1517  AddSupportedMcs(from, mcs);
1518  }
1519  }
1520  state->m_heCapabilities = Create<const HeCapabilities>(heCapabilities);
1521  SetQosSupport(from, true);
1522 }
1523 
1524 void
1525 WifiRemoteStationManager::AddStationEhtCapabilities(Mac48Address from,
1526  EhtCapabilities ehtCapabilities)
1527 {
1528  // Used by all stations to record EHT capabilities of remote stations
1529  NS_LOG_FUNCTION(this << from << ehtCapabilities);
1530  auto state = LookupState(from);
1531  for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_EHT))
1532  {
1533  for (uint8_t mapType = 0; mapType < EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_MAX; ++mapType)
1534  {
1535  if (ehtCapabilities.GetHighestSupportedRxMcs(
1536  static_cast<EhtMcsAndNssSet::EhtMcsMapType>(mapType)) >= mcs.GetMcsValue())
1537  {
1538  AddSupportedMcs(from, mcs);
1539  }
1540  }
1541  }
1542  state->m_ehtCapabilities = Create<const EhtCapabilities>(ehtCapabilities);
1543  SetQosSupport(from, true);
1544 }
1545 
1547 WifiRemoteStationManager::GetStationHtCapabilities(Mac48Address from)
1548 {
1549  return LookupState(from)->m_htCapabilities;
1550 }
1551 
1553 WifiRemoteStationManager::GetStationVhtCapabilities(Mac48Address from)
1554 {
1555  return LookupState(from)->m_vhtCapabilities;
1556 }
1557 
1559 WifiRemoteStationManager::GetStationHeCapabilities(Mac48Address from)
1560 {
1561  return LookupState(from)->m_heCapabilities;
1562 }
1563 
1565 WifiRemoteStationManager::GetStationEhtCapabilities(Mac48Address from)
1566 {
1567  return LookupState(from)->m_ehtCapabilities;
1568 }
1569 
1570 bool
1571 WifiRemoteStationManager::GetLdpcSupported(Mac48Address address) const
1572 {
1573  Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
1574  Ptr<const VhtCapabilities> vhtCapabilities = LookupState(address)->m_vhtCapabilities;
1575  Ptr<const HeCapabilities> heCapabilities = LookupState(address)->m_heCapabilities;
1576  bool supported = false;
1577  if (htCapabilities)
1578  {
1579  supported |= htCapabilities->GetLdpc();
1580  }
1581  if (vhtCapabilities)
1582  {
1583  supported |= vhtCapabilities->GetRxLdpc();
1584  }
1585  if (heCapabilities)
1586  {
1587  supported |= heCapabilities->GetLdpcCodingInPayload();
1588  }
1589  return supported;
1590 }
1591 
1592 WifiMode
1593 WifiRemoteStationManager::GetDefaultMode() const
1594 {
1595  return m_defaultTxMode;
1596 }
1597 
1598 WifiMode
1599 WifiRemoteStationManager::GetDefaultMcs() const
1600 {
1601  return m_defaultTxMcs;
1602 }
1603 
1604 WifiMode
1605 WifiRemoteStationManager::GetDefaultModeForSta(const WifiRemoteStation* st) const
1606 {
1607  NS_LOG_FUNCTION(this << st);
1608 
1609  if (!GetHtSupported() || !GetHtSupported(st))
1610  {
1611  return GetDefaultMode();
1612  }
1613 
1614  // find the highest modulation class supported by both stations
1616  if (GetHeSupported() && GetHeSupported(st))
1617  {
1618  modClass = WIFI_MOD_CLASS_HE;
1619  }
1620  else if (GetVhtSupported() && GetVhtSupported(st))
1621  {
1622  modClass = WIFI_MOD_CLASS_VHT;
1623  }
1624 
1625  // return the MCS with lowest index
1626  return *m_wifiPhy->GetPhyEntity(modClass)->begin();
1627 }
1628 
1629 void
1631 {
1632  NS_LOG_FUNCTION(this);
1633  m_states.clear();
1634  for (auto& state : m_stations)
1635  {
1636  delete (state.second);
1637  }
1638  m_stations.clear();
1639  m_bssBasicRateSet.clear();
1640  m_bssBasicMcsSet.clear();
1641  m_ssrc.fill(0);
1642  m_slrc.fill(0);
1643 }
1644 
1645 void
1646 WifiRemoteStationManager::AddBasicMode(WifiMode mode)
1647 {
1648  NS_LOG_FUNCTION(this << mode);
1649  if (mode.GetModulationClass() >= WIFI_MOD_CLASS_HT)
1650  {
1651  NS_FATAL_ERROR("It is not allowed to add a HT rate in the BSSBasicRateSet!");
1652  }
1653  for (uint8_t i = 0; i < GetNBasicModes(); i++)
1654  {
1655  if (GetBasicMode(i) == mode)
1656  {
1657  return;
1658  }
1659  }
1660  m_bssBasicRateSet.push_back(mode);
1661 }
1662 
1663 uint8_t
1664 WifiRemoteStationManager::GetNBasicModes() const
1665 {
1666  return static_cast<uint8_t>(m_bssBasicRateSet.size());
1667 }
1668 
1669 WifiMode
1670 WifiRemoteStationManager::GetBasicMode(uint8_t i) const
1671 {
1672  NS_ASSERT(i < GetNBasicModes());
1673  return m_bssBasicRateSet[i];
1674 }
1675 
1676 uint32_t
1677 WifiRemoteStationManager::GetNNonErpBasicModes() const
1678 {
1679  uint32_t size = 0;
1680  for (WifiModeListIterator i = m_bssBasicRateSet.begin(); i != m_bssBasicRateSet.end(); i++)
1681  {
1682  if (i->GetModulationClass() == WIFI_MOD_CLASS_ERP_OFDM)
1683  {
1684  continue;
1685  }
1686  size++;
1687  }
1688  return size;
1689 }
1690 
1691 WifiMode
1692 WifiRemoteStationManager::GetNonErpBasicMode(uint8_t i) const
1693 {
1694  NS_ASSERT(i < GetNNonErpBasicModes());
1695  uint32_t index = 0;
1696  bool found = false;
1697  for (WifiModeListIterator j = m_bssBasicRateSet.begin(); j != m_bssBasicRateSet.end();)
1698  {
1699  if (i == index)
1700  {
1701  found = true;
1702  }
1703  if (j->GetModulationClass() != WIFI_MOD_CLASS_ERP_OFDM)
1704  {
1705  if (found)
1706  {
1707  break;
1708  }
1709  }
1710  index++;
1711  j++;
1712  }
1713  return m_bssBasicRateSet[index];
1714 }
1715 
1716 void
1717 WifiRemoteStationManager::AddBasicMcs(WifiMode mcs)
1718 {
1719  NS_LOG_FUNCTION(this << +mcs.GetMcsValue());
1720  for (uint8_t i = 0; i < GetNBasicMcs(); i++)
1721  {
1722  if (GetBasicMcs(i) == mcs)
1723  {
1724  return;
1725  }
1726  }
1727  m_bssBasicMcsSet.push_back(mcs);
1728 }
1729 
1730 uint8_t
1731 WifiRemoteStationManager::GetNBasicMcs() const
1732 {
1733  return static_cast<uint8_t>(m_bssBasicMcsSet.size());
1734 }
1735 
1736 WifiMode
1737 WifiRemoteStationManager::GetBasicMcs(uint8_t i) const
1738 {
1739  NS_ASSERT(i < GetNBasicMcs());
1740  return m_bssBasicMcsSet[i];
1741 }
1742 
1743 WifiMode
1744 WifiRemoteStationManager::GetNonUnicastMode() const
1745 {
1746  if (m_nonUnicastMode == WifiMode())
1747  {
1748  if (GetNBasicModes() > 0)
1749  {
1750  return GetBasicMode(0);
1751  }
1752  else
1753  {
1754  return GetDefaultMode();
1755  }
1756  }
1757  else
1758  {
1759  return m_nonUnicastMode;
1760  }
1761 }
1762 
1763 bool
1764 WifiRemoteStationManager::DoNeedRts(WifiRemoteStation* station, uint32_t size, bool normally)
1765 {
1766  return normally;
1767 }
1768 
1769 bool
1770 WifiRemoteStationManager::DoNeedRetransmission(WifiRemoteStation* station,
1771  Ptr<const Packet> packet,
1772  bool normally)
1773 {
1774  return normally;
1775 }
1776 
1777 bool
1778 WifiRemoteStationManager::DoNeedFragmentation(WifiRemoteStation* station,
1779  Ptr<const Packet> packet,
1780  bool normally)
1781 {
1782  return normally;
1783 }
1784 
1785 void
1786 WifiRemoteStationManager::DoReportAmpduTxStatus(WifiRemoteStation* station,
1787  uint16_t nSuccessfulMpdus,
1788  uint16_t nFailedMpdus,
1789  double rxSnr,
1790  double dataSnr,
1791  uint16_t dataChannelWidth,
1792  uint8_t dataNss)
1793 {
1794  NS_LOG_DEBUG("DoReportAmpduTxStatus received but the manager does not handle A-MPDUs!");
1795 }
1796 
1797 WifiMode
1798 WifiRemoteStationManager::GetSupported(const WifiRemoteStation* station, uint8_t i) const
1799 {
1800  NS_ASSERT(i < GetNSupported(station));
1801  return station->m_state->m_operationalRateSet[i];
1802 }
1803 
1804 WifiMode
1805 WifiRemoteStationManager::GetMcsSupported(const WifiRemoteStation* station, uint8_t i) const
1806 {
1807  NS_ASSERT(i < GetNMcsSupported(station));
1808  return station->m_state->m_operationalMcsSet[i];
1809 }
1810 
1811 WifiMode
1812 WifiRemoteStationManager::GetNonErpSupported(const WifiRemoteStation* station, uint8_t i) const
1813 {
1814  NS_ASSERT(i < GetNNonErpSupported(station));
1815  // IEEE 802.11g standard defines that if the protection mechanism is enabled, RTS, CTS and
1816  // CTS-To-Self frames should select a rate in the BSSBasicRateSet that corresponds to an 802.11b
1817  // basic rate. This is a implemented here to avoid changes in every RAA, but should maybe be
1818  // moved in case it breaks standard rules.
1819  uint32_t index = 0;
1820  bool found = false;
1821  for (WifiModeListIterator j = station->m_state->m_operationalRateSet.begin();
1822  j != station->m_state->m_operationalRateSet.end();)
1823  {
1824  if (i == index)
1825  {
1826  found = true;
1827  }
1828  if (j->GetModulationClass() != WIFI_MOD_CLASS_ERP_OFDM)
1829  {
1830  if (found)
1831  {
1832  break;
1833  }
1834  }
1835  index++;
1836  j++;
1837  }
1838  return station->m_state->m_operationalRateSet[index];
1839 }
1840 
1842 WifiRemoteStationManager::GetAddress(const WifiRemoteStation* station) const
1843 {
1844  return station->m_state->m_address;
1845 }
1846 
1847 uint16_t
1848 WifiRemoteStationManager::GetChannelWidth(const WifiRemoteStation* station) const
1849 {
1850  return station->m_state->m_channelWidth;
1851 }
1852 
1853 bool
1854 WifiRemoteStationManager::GetShortGuardIntervalSupported(const WifiRemoteStation* station) const
1855 {
1856  Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1857 
1858  if (!htCapabilities)
1859  {
1860  return false;
1861  }
1862  return htCapabilities->GetShortGuardInterval20();
1863 }
1864 
1865 uint16_t
1866 WifiRemoteStationManager::GetGuardInterval(const WifiRemoteStation* station) const
1867 {
1868  return station->m_state->m_guardInterval;
1869 }
1870 
1871 bool
1872 WifiRemoteStationManager::GetAggregation(const WifiRemoteStation* station) const
1873 {
1874  return station->m_state->m_aggregation;
1875 }
1876 
1877 uint8_t
1878 WifiRemoteStationManager::GetNumberOfSupportedStreams(const WifiRemoteStation* station) const
1879 {
1880  Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1881 
1882  if (!htCapabilities)
1883  {
1884  return 1;
1885  }
1886  return htCapabilities->GetRxHighestSupportedAntennas();
1887 }
1888 
1889 uint8_t
1890 WifiRemoteStationManager::GetNess(const WifiRemoteStation* station) const
1891 {
1892  return station->m_state->m_ness;
1893 }
1894 
1896 WifiRemoteStationManager::GetPhy() const
1897 {
1898  return m_wifiPhy;
1899 }
1900 
1902 WifiRemoteStationManager::GetMac() const
1903 {
1904  return m_wifiMac;
1905 }
1906 
1907 uint8_t
1908 WifiRemoteStationManager::GetNSupported(const WifiRemoteStation* station) const
1909 {
1910  return static_cast<uint8_t>(station->m_state->m_operationalRateSet.size());
1911 }
1912 
1913 bool
1914 WifiRemoteStationManager::GetQosSupported(const WifiRemoteStation* station) const
1915 {
1916  return station->m_state->m_qosSupported;
1917 }
1918 
1919 bool
1920 WifiRemoteStationManager::GetHtSupported(const WifiRemoteStation* station) const
1921 {
1922  return bool(station->m_state->m_htCapabilities);
1923 }
1924 
1925 bool
1926 WifiRemoteStationManager::GetVhtSupported(const WifiRemoteStation* station) const
1927 {
1928  return bool(station->m_state->m_vhtCapabilities);
1929 }
1930 
1931 bool
1932 WifiRemoteStationManager::GetHeSupported(const WifiRemoteStation* station) const
1933 {
1934  return bool(station->m_state->m_heCapabilities);
1935 }
1936 
1937 bool
1938 WifiRemoteStationManager::GetEhtSupported(const WifiRemoteStation* station) const
1939 {
1940  return (bool)(station->m_state->m_ehtCapabilities);
1941 }
1942 
1943 uint8_t
1944 WifiRemoteStationManager::GetNMcsSupported(const WifiRemoteStation* station) const
1945 {
1946  return static_cast<uint8_t>(station->m_state->m_operationalMcsSet.size());
1947 }
1948 
1949 uint32_t
1950 WifiRemoteStationManager::GetNNonErpSupported(const WifiRemoteStation* station) const
1951 {
1952  uint32_t size = 0;
1953  for (WifiModeListIterator i = station->m_state->m_operationalRateSet.begin();
1954  i != station->m_state->m_operationalRateSet.end();
1955  i++)
1956  {
1957  if (i->GetModulationClass() == WIFI_MOD_CLASS_ERP_OFDM)
1958  {
1959  continue;
1960  }
1961  size++;
1962  }
1963  return size;
1964 }
1965 
1966 uint16_t
1967 WifiRemoteStationManager::GetChannelWidthSupported(Mac48Address address) const
1968 {
1969  return LookupState(address)->m_channelWidth;
1970 }
1971 
1972 bool
1973 WifiRemoteStationManager::GetShortGuardIntervalSupported(Mac48Address address) const
1974 {
1975  Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
1976 
1977  if (!htCapabilities)
1978  {
1979  return false;
1980  }
1981  return htCapabilities->GetShortGuardInterval20();
1982 }
1983 
1984 uint8_t
1985 WifiRemoteStationManager::GetNumberOfSupportedStreams(Mac48Address address) const
1986 {
1987  Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
1988 
1989  if (!htCapabilities)
1990  {
1991  return 1;
1992  }
1993  return htCapabilities->GetRxHighestSupportedAntennas();
1994 }
1995 
1996 uint8_t
1997 WifiRemoteStationManager::GetNMcsSupported(Mac48Address address) const
1998 {
1999  return static_cast<uint8_t>(LookupState(address)->m_operationalMcsSet.size());
2000 }
2001 
2002 bool
2003 WifiRemoteStationManager::GetDsssSupported(const Mac48Address& address) const
2004 {
2005  return (LookupState(address)->m_dsssSupported);
2006 }
2007 
2008 bool
2009 WifiRemoteStationManager::GetErpOfdmSupported(const Mac48Address& address) const
2010 {
2011  return (LookupState(address)->m_erpOfdmSupported);
2012 }
2013 
2014 bool
2015 WifiRemoteStationManager::GetOfdmSupported(const Mac48Address& address) const
2016 {
2017  return (LookupState(address)->m_ofdmSupported);
2018 }
2019 
2020 bool
2021 WifiRemoteStationManager::GetHtSupported(Mac48Address address) const
2022 {
2023  return bool(LookupState(address)->m_htCapabilities);
2024 }
2025 
2026 bool
2027 WifiRemoteStationManager::GetVhtSupported(Mac48Address address) const
2028 {
2029  return bool(LookupState(address)->m_vhtCapabilities);
2030 }
2031 
2032 bool
2033 WifiRemoteStationManager::GetHeSupported(Mac48Address address) const
2034 {
2035  return bool(LookupState(address)->m_heCapabilities);
2036 }
2037 
2038 bool
2039 WifiRemoteStationManager::GetEhtSupported(Mac48Address address) const
2040 {
2041  return (bool)(LookupState(address)->m_ehtCapabilities);
2042 }
2043 
2044 void
2045 WifiRemoteStationManager::SetDefaultTxPowerLevel(uint8_t txPower)
2046 {
2047  m_defaultTxPowerLevel = txPower;
2048 }
2049 
2050 uint8_t
2051 WifiRemoteStationManager::GetNumberOfAntennas() const
2052 {
2053  return m_wifiPhy->GetNumberOfAntennas();
2054 }
2055 
2056 uint8_t
2057 WifiRemoteStationManager::GetMaxNumberOfTransmitStreams() const
2058 {
2059  return m_wifiPhy->GetMaxSupportedTxSpatialStreams();
2060 }
2061 
2062 bool
2063 WifiRemoteStationManager::UseLdpcForDestination(Mac48Address dest) const
2064 {
2065  return (GetLdpcSupported() && GetLdpcSupported(dest));
2066 }
2067 
2068 } // namespace ns3
The IEEE 802.11be EHT Capabilities.
uint8_t GetHighestSupportedRxMcs(EhtMcsAndNssSet::EhtMcsMapType mapType)
Get the highest supported RX MCS for a given EHT-MCS map type.
Hold variables of type enum.
Definition: enum.h:56
The IEEE 802.11ax HE Capabilities.
uint8_t GetHighestMcsSupported() const
Get highest MCS supported.
bool GetHeSuPpdu1xHeLtf800nsGi() const
Get 1xHE-LTF and 800ns GI in HE SU PPDU reception support.
uint8_t GetChannelWidthSet() const
Get channel width set.
The HT Capabilities Information Element.
uint8_t GetSupportedChannelWidth() const
Return the supported channel width.
bool IsSupportedMcs(uint8_t mcs) const
Return the is MCS supported flag.
static WifiMode GetHtMcs(uint8_t index)
Return the HT MCS corresponding to the provided index.
Definition: ht-phy.cc:490
an EUI-48 address
Definition: mac48-address.h:46
bool IsGroup() const
A base class which provides memory management and object aggregation.
Definition: object.h:89
uint16_t GetAssociationId() const
Return the association ID.
bool IsAssociated() const
Return whether we are associated with an AP.
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
The IEEE 802.11ac VHT Capabilities.
bool IsSupportedMcs(uint8_t mcs, uint8_t nss) const
Get the is MCS supported.
uint8_t GetSupportedChannelWidthSet() const
Get the supported channel width set.
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid() const
Return the Traffic ID of a QoS header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
bool IsMgt() const
Return true if the Type is Management.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
TypeOfStation GetTypeOfStation() const
Return the type of station.
Definition: wifi-mac.cc:418
represent a single transmission mode
Definition: wifi-mode.h:50
bool IsHigherDataRate(WifiMode mode) const
Definition: wifi-mode.cc:208
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
bool IsMandatory() const
Definition: wifi-mode.cc:156
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
AttributeValue implementation for WifiMode.
Ptr< VhtConfiguration > GetVhtConfiguration() const
Ptr< EhtConfiguration > GetEhtConfiguration() const
Ptr< HtConfiguration > GetHtConfiguration() const
Ptr< HeConfiguration > GetHeConfiguration() const
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:996
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:606
std::list< WifiMode > GetMcsList() const
The WifiPhy::GetMcsList() method is used (e.g., by a WifiRemoteStationManager) to determine the set o...
Definition: wifi-phy.cc:1956
std::list< WifiMode > GetModeList() const
The WifiPhy::GetModeList() method is used (e.g., by a WifiRemoteStationManager) to determine the set ...
Definition: wifi-phy.cc:1907
TID independent remote station statistics.
void NotifyTxSuccess(uint32_t retryCounter)
Updates average frame error rate when data or RTS was transmitted successfully.
void NotifyTxFailed()
Updates average frame error rate when final data or RTS has failed.
hold a list of per-remote-station state.
bool GetQosSupported(Mac48Address address) const
Return whether the given station is QoS capable.
void SetShortSlotTimeEnabled(bool enable)
Enable or disable short slot time.
void AddBasicMode(WifiMode mode)
Invoked in a STA upon association to store the set of rates which belong to the BSSBasicRateSet of th...
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
uint16_t GetAssociationId(Mac48Address remoteAddress) const
Get the AID of a remote station.
WifiMode m_defaultTxMcs
The default transmission modulation-coding scheme (MCS)
ProtectionMode m_htProtectionMode
Protection mode for HT stations when non-HT stations are detected.
uint32_t GetFragmentationThreshold() const
Return the fragmentation threshold.
uint32_t m_maxSsrc
Maximum STA short retry count (SSRC)
void SetRtsCtsThreshold(uint32_t threshold)
Sets the RTS threshold.
void AddAllSupportedMcs(Mac48Address address)
Invoked in a STA or AP to store all of the MCS supported by a destination which is also supported loc...
TracedCallback< Mac48Address > m_macTxRtsFailed
The trace source fired when the transmission of a single RTS has failed.
void DoSetFragmentationThreshold(uint32_t threshold)
Actually sets the fragmentation threshold, it also checks the validity of the given threshold.
bool IsBrandNew(Mac48Address address) const
Return whether the station state is brand new.
bool GetShortSlotTimeEnabled() const
Return whether the device uses short slot time.
void DoDispose() override
Destructor implementation.
bool GetShortPreambleSupported(Mac48Address address) const
Return whether the station supports short PHY preamble or not.
void AddAllSupportedModes(Mac48Address address)
Invoked in a STA or AP to store all of the modes supported by a destination which is also supported l...
void AddSupportedMcs(Mac48Address address, WifiMode mcs)
Record the MCS index supported by the station.
void RemoveAllSupportedMcs(Mac48Address address)
Invoked in a STA or AP to delete all of the supported MCS by a destination.
uint32_t DoGetFragmentationThreshold() const
Return the current fragmentation threshold.
TracedCallback< Mac48Address > m_macTxFinalRtsFailed
The trace source fired when the transmission of a RTS has exceeded the maximum number of attempts.
bool m_shortPreambleEnabled
flag if short PHY preamble is enabled
bool GetShortSlotTimeSupported(Mac48Address address) const
Return whether the station supports short ERP slot time or not.
void SetShortPreambleEnabled(bool enable)
Enable or disable short PHY preambles.
Ptr< WifiPhy > m_wifiPhy
This is a pointer to the WifiPhy associated with this WifiRemoteStationManager that is set on call to...
uint8_t m_defaultTxPowerLevel
Default transmission power level.
static TypeId GetTypeId()
Get the type ID.
WifiMode m_nonUnicastMode
Transmission mode for non-unicast Data frames.
uint16_t GetGuardInterval() const
Return the supported HE guard interval duration (in nanoseconds).
bool IsAssociated(Mac48Address address) const
Return whether the station associated.
bool GetHtSupported() const
Return whether the device has HT capability support enabled.
void RecordWaitAssocTxOk(Mac48Address address)
Records that we are waiting for an ACK for the association response we sent.
void SetFragmentationThreshold(uint32_t threshold)
Sets a fragmentation threshold.
Ptr< WifiMac > m_wifiMac
This is a pointer to the WifiMac associated with this WifiRemoteStationManager that is set on call to...
void SetMldAddress(const Mac48Address &address, const Mac48Address &mldAddress)
Set the address of the MLD the given station is affiliated with.
void RecordGotAssocTxOk(Mac48Address address)
Records that we got an ACK for the association response we sent.
bool GetLdpcSupported() const
Return whether the device has LDPC support enabled.
bool GetEhtSupported() const
Return whether the device has EHT capability support enabled.
void AddSupportedMode(Mac48Address address, WifiMode mode)
Invoked in a STA or AP to store the set of modes supported by a destination which is also supported l...
std::shared_ptr< WifiRemoteStationState > LookupState(Mac48Address address) const
Return the state of the station associated with the given address.
void RecordAssocRefused(Mac48Address address)
Records that association request was refused.
StationStates m_states
States of known stations.
void SetMaxSsrc(uint32_t maxSsrc)
Sets the maximum STA short retry count (SSRC).
TracedCallback< Mac48Address > m_macTxDataFailed
The trace source fired when the transmission of a single data packet has failed.
uint16_t GetStaId(Mac48Address address, const WifiTxVector &txVector) const
If the given TXVECTOR is used for a MU transmission, return the STAID of the station with the given a...
void AddSupportedPhyPreamble(Mac48Address address, bool isShortPreambleSupported)
Record whether the short PHY preamble is supported by the station.
bool GetShortGuardIntervalSupported() const
Return whether the device has SGI support enabled.
virtual void SetupPhy(const Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
void RecordDisassociated(Mac48Address address)
Records that the STA was disassociated.
uint32_t m_maxSlrc
Maximum STA long retry count (SLRC)
void Reset()
Reset the station, invoked in a STA upon dis-association or in an AP upon reboot.
bool IsAssocRefused(Mac48Address address) const
Return whether we refused an association request from the given station.
bool GetVhtSupported() const
Return whether the device has VHT capability support enabled.
ProtectionMode m_erpProtectionMode
Protection mode for ERP stations when non-ERP stations are detected.
void AddSupportedErpSlotTime(Mac48Address address, bool isShortSlotTimeSupported)
Record whether the short ERP slot time is supported by the station.
bool GetShortPreambleEnabled() const
Return whether the device uses short PHY preambles.
bool GetHeSupported() const
Return whether the device has HE capability support enabled.
WifiMode m_defaultTxMode
The default transmission mode.
void RecordGotAssocTxFailed(Mac48Address address)
Records that we missed an ACK for the association response we sent.
virtual void SetupMac(const Ptr< WifiMac > mac)
Set up MAC associated with this device since it is the object that knows the full set of timing param...
uint32_t m_rtsCtsThreshold
Threshold for RTS/CTS.
bool m_shortSlotTimeEnabled
flag if short slot time is enabled
bool IsWaitAssocTxOk(Mac48Address address) const
Return whether we are waiting for an ACK for the association response we sent.
void SetMaxSlrc(uint32_t maxSlrc)
Sets the maximum STA long retry count (SLRC).
TracedCallback< Mac48Address > m_macTxFinalDataFailed
The trace source fired when the transmission of a data packet has exceeded the maximum number of atte...
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetNess(uint8_t ness)
Sets the Ness number.
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetLdpc(bool ldpc)
Sets if LDPC FEC coding is being used.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
void SetBssColor(uint8_t color)
Set the BSS color.
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
uint16_t GetChannelWidth() const
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: enum.h:205
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:46
void Reset()
Reset the initial value of every attribute as well as the value of every global to what they were bef...
Definition: config.cc:856
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:134
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:72
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_EHT_MU
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PREAMBLE_VHT_SU
@ WIFI_PREAMBLE_HT_MF
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_HR_DSSS
HR/DSSS (Clause 16)
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_MOD_CLASS_DSSS
DSSS (Clause 15)
@ WIFI_MOD_CLASS_ERP_OFDM
ERP-OFDM (18.4)
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ STA
Definition: wifi-mac.h:62
@ AP
Definition: wifi-mac.h:63
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octets of the IEEE 802.11 MAC FCS field.
bool IsAllowedControlAnswerModulationClass(WifiModulationClass modClassReq, WifiModulationClass modClassAnswer)
Return whether the modulation class of the selected mode for the control answer frame is allowed.
WifiModeList::const_iterator WifiModeListIterator
An iterator for WifiModeList vector.
Definition: wifi-mode.h:265
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:163
uint16_t ConvertGuardIntervalToNanoSeconds(WifiMode mode, const Ptr< WifiNetDevice > device)
Convert the guard interval to nanoseconds based on the WifiMode.
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble)
Return the preamble to be used for the transmission.
mac
Definition: third.py:85
phy
Definition: third.py:82
EhtMcsMapType
The different EHT-MCS map types as defined in 9.4.2.313.4 Supported EHT-MCS And NSS Set field.
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:70
double rssi
RSSI in dBm.
Definition: phy-entity.h:72
double snr
SNR in linear scale.
Definition: phy-entity.h:71
hold per-remote-station state.
WifiRemoteStationState * m_state
Remote station state.
std::pair< double, Time > m_rssiAndUpdateTimePair
RSSI (in dBm) of the most recent packet received from the remote station along with update time.
Mac48Address m_address
Mac48Address of the remote station.
uint16_t m_channelWidth
Channel width (in MHz) supported by the remote station.
uint8_t m_ness
Number of extended spatial streams of the remote station.
bool m_aggregation
Flag if MPDU aggregation is used by the remote station.
bool m_qosSupported
Flag if QoS is supported by the station.
WifiModeList m_operationalRateSet
This member is the list of WifiMode objects that comprise the OperationalRateSet parameter for this r...
WifiModeList m_operationalMcsSet
operational MCS set
uint16_t m_guardInterval
HE Guard interval duration (in nanoseconds) supported by the remote station.
Ptr< const EhtCapabilities > m_ehtCapabilities
remote station EHT capabilities
Ptr< const VhtCapabilities > m_vhtCapabilities
remote station VHT capabilities
WifiRemoteStationInfo m_info
remote station info
Ptr< const HtCapabilities > m_htCapabilities
remote station HT capabilities
Ptr< const HeCapabilities > m_heCapabilities
remote station HE capabilities
#define SU_STA_ID
Definition: wifi-mode.h:34