A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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/erp-ofdm-phy.h"
34#include "ns3/he-configuration.h"
35#include "ns3/ht-configuration.h"
36#include "ns3/ht-phy.h"
37#include "ns3/log.h"
38#include "ns3/simulator.h"
39#include "ns3/uinteger.h"
40#include "ns3/vht-configuration.h"
41
42namespace ns3
43{
44
45NS_LOG_COMPONENT_DEFINE("WifiRemoteStationManager");
46
47NS_OBJECT_ENSURE_REGISTERED(WifiRemoteStationManager);
48
49TypeId
51{
52 static TypeId tid =
53 TypeId("ns3::WifiRemoteStationManager")
55 .SetGroupName("Wifi")
56 .AddAttribute("MaxSsrc",
57 "The maximum number of retransmission attempts for any packet with size "
58 "<= RtsCtsThreshold. "
59 "This value will not have any effect on some rate control algorithms.",
62 MakeUintegerChecker<uint32_t>())
63 .AddAttribute("MaxSlrc",
64 "The maximum number of retransmission attempts for any packet with size "
65 "> RtsCtsThreshold. "
66 "This value will not have any effect on some rate control algorithms.",
69 MakeUintegerChecker<uint32_t>())
70 .AddAttribute("RtsCtsThreshold",
71 "If the size of the PSDU is bigger than this value, we use an RTS/CTS "
72 "handshake before sending the data frame."
73 "This value will not have any effect on some rate control algorithms.",
74 UintegerValue(65535),
76 MakeUintegerChecker<uint32_t>())
77 .AddAttribute(
78 "FragmentationThreshold",
79 "If the size of the PSDU is bigger than this value, we fragment it such that the "
80 "size of the fragments are equal or smaller. "
81 "This value does not apply when it is carried in an A-MPDU. "
82 "This value will not have any effect on some rate control algorithms.",
83 UintegerValue(65535),
86 MakeUintegerChecker<uint32_t>())
87 .AddAttribute("NonUnicastMode",
88 "Wifi mode used for non-unicast transmissions.",
90 MakeWifiModeAccessor(&WifiRemoteStationManager::m_nonUnicastMode),
91 MakeWifiModeChecker())
92 .AddAttribute("DefaultTxPowerLevel",
93 "Default power level to be used for transmissions. "
94 "This is the power level that is used by all those WifiManagers that do "
95 "not implement TX power control.",
98 MakeUintegerChecker<uint8_t>())
99 .AddAttribute("ErpProtectionMode",
100 "Protection mode used when non-ERP STAs are connected to an ERP AP: "
101 "Rts-Cts or Cts-To-Self",
105 "Rts-Cts",
107 "Cts-To-Self"))
108 .AddAttribute("HtProtectionMode",
109 "Protection mode used when non-HT STAs are connected to a HT AP: Rts-Cts "
110 "or Cts-To-Self",
114 "Rts-Cts",
116 "Cts-To-Self"))
117 .AddTraceSource("MacTxRtsFailed",
118 "The transmission of a RTS by the MAC layer has failed",
120 "ns3::Mac48Address::TracedCallback")
121 .AddTraceSource("MacTxDataFailed",
122 "The transmission of a data packet by the MAC layer has failed",
124 "ns3::Mac48Address::TracedCallback")
125 .AddTraceSource(
126 "MacTxFinalRtsFailed",
127 "The transmission of a RTS has exceeded the maximum number of attempts",
129 "ns3::Mac48Address::TracedCallback")
130 .AddTraceSource(
131 "MacTxFinalDataFailed",
132 "The transmission of a data packet has exceeded the maximum number of attempts",
134 "ns3::Mac48Address::TracedCallback");
135 return tid;
136}
137
139 : m_useNonErpProtection(false),
140 m_useNonHtProtection(false),
141 m_shortPreambleEnabled(false),
142 m_shortSlotTimeEnabled(false)
143{
144 NS_LOG_FUNCTION(this);
145}
146
148{
149 NS_LOG_FUNCTION(this);
150}
151
152void
154{
155 NS_LOG_FUNCTION(this);
156 Reset();
157}
158
159void
161{
162 NS_LOG_FUNCTION(this << phy);
163 // We need to track our PHY because it is the object that knows the
164 // full set of transmit rates that are supported. We need to know
165 // this in order to find the relevant mandatory rates when choosing a
166 // transmit rate for automatic control responses like
167 // acknowledgments.
168 m_wifiPhy = phy;
169 m_defaultTxMode = phy->GetDefaultMode();
171 if (GetHtSupported())
172 {
174 }
175 Reset();
176}
177
178void
180{
181 NS_LOG_FUNCTION(this << mac);
182 // We need to track our MAC because it is the object that knows the
183 // full set of interframe spaces.
184 m_wifiMac = mac;
185 Reset();
186}
187
188int64_t
190{
191 NS_LOG_FUNCTION(this << stream);
192 return 0;
193}
194
195void
197{
198 NS_LOG_FUNCTION(this << maxSsrc);
199 m_maxSsrc = maxSsrc;
200}
201
202void
204{
205 NS_LOG_FUNCTION(this << maxSlrc);
206 m_maxSlrc = maxSlrc;
207}
208
209void
211{
212 NS_LOG_FUNCTION(this << threshold);
213 m_rtsCtsThreshold = threshold;
214}
215
216void
218{
219 NS_LOG_FUNCTION(this << threshold);
221}
222
223void
225{
226 NS_LOG_FUNCTION(this << enable);
227 m_shortPreambleEnabled = enable;
228}
229
230void
232{
233 NS_LOG_FUNCTION(this << enable);
234 m_shortSlotTimeEnabled = enable;
235}
236
237bool
239{
241}
242
243bool
245{
247}
248
249bool
251{
252 return bool(m_wifiPhy->GetDevice()->GetHtConfiguration());
253}
254
255bool
257{
260}
261
262bool
264{
265 return bool(m_wifiPhy->GetDevice()->GetHeConfiguration());
266}
267
268bool
270{
271 return bool(m_wifiPhy->GetDevice()->GetEhtConfiguration());
272}
273
274bool
276{
277 if (GetHtSupported())
278 {
280 NS_ASSERT(htConfiguration); // If HT is supported, we should have a HT configuration
281 // attached
282 return htConfiguration->GetLdpcSupported();
283 }
284 return false;
285}
286
287bool
289{
290 if (GetHtSupported())
291 {
293 NS_ASSERT(htConfiguration); // If HT is supported, we should have a HT configuration
294 // attached
295 if (htConfiguration->GetShortGuardIntervalSupported())
296 {
297 return true;
298 }
299 }
300 return false;
301}
302
303uint16_t
305{
306 uint16_t gi = 0;
307 if (GetHeSupported())
308 {
310 NS_ASSERT(heConfiguration); // If HE is supported, we should have a HE configuration
311 // attached
312 gi = static_cast<uint16_t>(heConfiguration->GetGuardInterval().GetNanoSeconds());
313 }
314 return gi;
315}
316
319{
321}
322
323void
325 bool isShortPreambleSupported)
326{
327 NS_LOG_FUNCTION(this << address << isShortPreambleSupported);
328 NS_ASSERT(!address.IsGroup());
329 LookupState(address)->m_shortPreamble = isShortPreambleSupported;
330}
331
332void
334 bool isShortSlotTimeSupported)
335{
336 NS_LOG_FUNCTION(this << address << isShortSlotTimeSupported);
337 NS_ASSERT(!address.IsGroup());
338 LookupState(address)->m_shortSlotTime = isShortSlotTimeSupported;
339}
340
341void
343{
344 NS_LOG_FUNCTION(this << address << mode);
345 NS_ASSERT(!address.IsGroup());
346 auto state = LookupState(address);
347 for (const auto& i : state->m_operationalRateSet)
348 {
349 if (i == mode)
350 {
351 return; // already in
352 }
353 }
354 if ((mode.GetModulationClass() == WIFI_MOD_CLASS_DSSS) ||
356 {
357 state->m_dsssSupported = true;
358 }
360 {
361 state->m_erpOfdmSupported = true;
362 }
363 else if (mode.GetModulationClass() == WIFI_MOD_CLASS_OFDM)
364 {
365 state->m_ofdmSupported = true;
366 }
367 state->m_operationalRateSet.push_back(mode);
368}
369
370void
372{
373 NS_LOG_FUNCTION(this << address);
374 NS_ASSERT(!address.IsGroup());
375 auto state = LookupState(address);
376 state->m_operationalRateSet.clear();
377 for (const auto& mode : m_wifiPhy->GetModeList())
378 {
379 state->m_operationalRateSet.push_back(mode);
380 if (mode.IsMandatory())
381 {
382 AddBasicMode(mode);
383 }
384 }
385}
386
387void
389{
390 NS_LOG_FUNCTION(this << address);
391 NS_ASSERT(!address.IsGroup());
392 auto state = LookupState(address);
393 state->m_operationalMcsSet.clear();
394 for (const auto& mcs : m_wifiPhy->GetMcsList())
395 {
396 state->m_operationalMcsSet.push_back(mcs);
397 }
398}
399
400void
402{
403 NS_LOG_FUNCTION(this << address);
404 NS_ASSERT(!address.IsGroup());
405 LookupState(address)->m_operationalMcsSet.clear();
406}
407
408void
410{
411 NS_LOG_FUNCTION(this << address << mcs);
412 NS_ASSERT(!address.IsGroup());
413 auto state = LookupState(address);
414 for (const auto& i : state->m_operationalMcsSet)
415 {
416 if (i == mcs)
417 {
418 return; // already in
419 }
420 }
421 state->m_operationalMcsSet.push_back(mcs);
422}
423
424bool
426{
427 return LookupState(address)->m_shortPreamble;
428}
429
430bool
432{
433 return LookupState(address)->m_shortSlotTime;
434}
435
436bool
438{
439 return LookupState(address)->m_qosSupported;
440}
441
442bool
444{
445 if (address.IsGroup())
446 {
447 return false;
448 }
449 return LookupState(address)->m_state == WifiRemoteStationState::BRAND_NEW;
450}
451
452bool
454{
455 if (address.IsGroup())
456 {
457 return true;
458 }
459 return LookupState(address)->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK;
460}
461
462bool
464{
465 if (address.IsGroup())
466 {
467 return false;
468 }
469 return LookupState(address)->m_state == WifiRemoteStationState::WAIT_ASSOC_TX_OK;
470}
471
472void
474{
475 NS_ASSERT(!address.IsGroup());
477}
478
479void
481{
482 NS_ASSERT(!address.IsGroup());
484}
485
486void
488{
489 NS_ASSERT(!address.IsGroup());
491}
492
493void
495{
496 NS_ASSERT(!address.IsGroup());
498}
499
500bool
502{
503 if (address.IsGroup())
504 {
505 return false;
506 }
507 return LookupState(address)->m_state == WifiRemoteStationState::ASSOC_REFUSED;
508}
509
510void
512{
513 NS_ASSERT(!address.IsGroup());
515}
516
517uint16_t
519{
520 std::shared_ptr<WifiRemoteStationState> state;
521 if (!remoteAddress.IsGroup() &&
522 (state = LookupState(remoteAddress))->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK)
523 {
524 return state->m_aid;
525 }
526 return SU_STA_ID;
527}
528
529uint16_t
531{
532 NS_LOG_FUNCTION(this << address << txVector);
533
534 uint16_t staId = SU_STA_ID;
535
536 if (txVector.IsMu())
537 {
538 if (m_wifiMac->GetTypeOfStation() == AP)
539 {
540 staId = GetAssociationId(address);
541 }
542 else if (m_wifiMac->GetTypeOfStation() == STA)
543 {
544 Ptr<StaWifiMac> staMac = StaticCast<StaWifiMac>(m_wifiMac);
545 if (staMac->IsAssociated())
546 {
547 staId = staMac->GetAssociationId();
548 }
549 }
550 }
551
552 NS_LOG_DEBUG("Returning STAID = " << staId);
553 return staId;
554}
555
556bool
558{
559 return LookupState(address)->m_isInPsMode;
560}
561
562void
563WifiRemoteStationManager::SetPsMode(const Mac48Address& address, bool isInPsMode)
564{
565 LookupState(address)->m_isInPsMode = isInPsMode;
566}
567
568void
570{
571 NS_LOG_FUNCTION(this << address << mldAddress);
572
573 auto state = LookupState(address);
574 state->m_mldAddress = mldAddress;
575 // insert another entry in m_states indexed by the MLD address and pointing to the same state
576 const_cast<WifiRemoteStationManager*>(this)->m_states.insert({mldAddress, state});
577}
578
579std::optional<Mac48Address>
580WifiRemoteStationManager::GetMldAddress(const Mac48Address& address) const
581{
582 return LookupState(address)->m_mldAddress;
583}
584
585std::optional<Mac48Address>
586WifiRemoteStationManager::GetAffiliatedStaAddress(const Mac48Address& mldAddress) const
587{
588 auto stateIt = m_states.find(mldAddress);
589
590 if (stateIt == m_states.end() || !stateIt->second->m_mldAddress)
591 {
592 // MLD address not found
593 return std::nullopt;
594 }
595
596 NS_ASSERT(*stateIt->second->m_mldAddress == mldAddress);
597 return stateIt->second->m_address;
598}
599
601WifiRemoteStationManager::GetDataTxVector(const WifiMacHeader& header, uint16_t allowedWidth)
602{
603 NS_LOG_FUNCTION(this << header << allowedWidth);
604 Mac48Address address = header.GetAddr1();
605 if (!header.IsMgt() && address.IsGroup())
606 {
607 WifiMode mode = GetNonUnicastMode();
608 WifiTxVector v;
609 v.SetMode(mode);
611 GetPreambleForTransmission(mode.GetModulationClass(), GetShortPreambleEnabled()));
612 v.SetTxPowerLevel(m_defaultTxPowerLevel);
613 v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(mode, allowedWidth));
614 v.SetGuardInterval(ConvertGuardIntervalToNanoSeconds(mode, m_wifiPhy->GetDevice()));
615 v.SetNTx(GetNumberOfAntennas());
616 v.SetNss(1);
617 v.SetNess(0);
618 return v;
619 }
620 WifiTxVector txVector;
621 if (header.IsMgt())
622 {
623 // Use the lowest basic rate for management frames
624 WifiMode mgtMode;
625 if (GetNBasicModes() > 0)
626 {
627 mgtMode = GetBasicMode(0);
628 }
629 else
630 {
631 mgtMode = GetDefaultMode();
632 }
633 txVector.SetMode(mgtMode);
634 txVector.SetPreambleType(
635 GetPreambleForTransmission(mgtMode.GetModulationClass(), GetShortPreambleEnabled()));
636 txVector.SetTxPowerLevel(m_defaultTxPowerLevel);
637 uint16_t channelWidth = allowedWidth;
638 if (!header.GetAddr1().IsGroup())
639 {
640 if (uint16_t rxWidth = GetChannelWidthSupported(header.GetAddr1());
641 rxWidth < channelWidth)
642 {
643 channelWidth = rxWidth;
644 }
645 }
646
647 txVector.SetChannelWidth(m_wifiPhy->GetTxBandwidth(mgtMode, channelWidth));
648 txVector.SetGuardInterval(
649 ConvertGuardIntervalToNanoSeconds(mgtMode, m_wifiPhy->GetDevice()));
650 }
651 else
652 {
653 txVector = DoGetDataTxVector(Lookup(address), allowedWidth);
655 ? 0
656 : UseLdpcForDestination(address));
657 }
658 Ptr<HeConfiguration> heConfiguration = m_wifiPhy->GetDevice()->GetHeConfiguration();
659 if (heConfiguration)
660 {
661 txVector.SetBssColor(heConfiguration->GetBssColor());
662 }
663 // If both the allowed width and the TXVECTOR channel width are integer multiple
664 // of 20 MHz, then the TXVECTOR channel width must not exceed the allowed width
665 NS_ASSERT_MSG((txVector.GetChannelWidth() % 20 != 0) || (allowedWidth % 20 != 0) ||
666 (txVector.GetChannelWidth() <= allowedWidth),
667 "TXVECTOR channel width (" << txVector.GetChannelWidth()
668 << " MHz) exceeds allowed width (" << allowedWidth
669 << " MHz)");
670 return txVector;
671}
672
674WifiRemoteStationManager::GetCtsToSelfTxVector()
675{
676 WifiMode defaultMode = GetDefaultMode();
677 WifiPreamble defaultPreamble;
678 if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_EHT)
679 {
680 defaultPreamble = WIFI_PREAMBLE_EHT_MU;
681 }
682 else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_HE)
683 {
684 defaultPreamble = WIFI_PREAMBLE_HE_SU;
685 }
686 else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_VHT)
687 {
688 defaultPreamble = WIFI_PREAMBLE_VHT_SU;
689 }
690 else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_HT)
691 {
692 defaultPreamble = WIFI_PREAMBLE_HT_MF;
693 }
694 else
695 {
696 defaultPreamble = WIFI_PREAMBLE_LONG;
697 }
698
699 return WifiTxVector(defaultMode,
700 GetDefaultTxPowerLevel(),
701 defaultPreamble,
702 ConvertGuardIntervalToNanoSeconds(defaultMode, m_wifiPhy->GetDevice()),
703 GetNumberOfAntennas(),
704 1,
705 0,
706 m_wifiPhy->GetTxBandwidth(defaultMode),
707 false);
708}
709
711WifiRemoteStationManager::GetRtsTxVector(Mac48Address address)
712{
713 NS_LOG_FUNCTION(this << address);
714 if (address.IsGroup())
715 {
716 WifiMode mode = GetNonUnicastMode();
717 WifiTxVector v;
718 v.SetMode(mode);
720 GetPreambleForTransmission(mode.GetModulationClass(), GetShortPreambleEnabled()));
721 v.SetTxPowerLevel(m_defaultTxPowerLevel);
722 v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(mode));
723 v.SetGuardInterval(ConvertGuardIntervalToNanoSeconds(mode, m_wifiPhy->GetDevice()));
724 v.SetNTx(GetNumberOfAntennas());
725 v.SetNss(1);
726 v.SetNess(0);
727 return v;
728 }
729 return DoGetRtsTxVector(Lookup(address));
730}
731
733WifiRemoteStationManager::GetCtsTxVector(Mac48Address to, WifiMode rtsTxMode) const
734{
735 NS_ASSERT(!to.IsGroup());
736 WifiMode ctsMode = GetControlAnswerMode(rtsTxMode);
737 WifiTxVector v;
738 v.SetMode(ctsMode);
740 GetPreambleForTransmission(ctsMode.GetModulationClass(), GetShortPreambleEnabled()));
741 v.SetTxPowerLevel(GetDefaultTxPowerLevel());
742 v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(ctsMode));
743 uint16_t ctsTxGuardInterval =
744 ConvertGuardIntervalToNanoSeconds(ctsMode, m_wifiPhy->GetDevice());
745 v.SetGuardInterval(ctsTxGuardInterval);
746 v.SetNss(1);
747 return v;
748}
749
750void
751WifiRemoteStationManager::AdjustTxVectorForIcf(WifiTxVector& txVector) const
752{
753 NS_LOG_FUNCTION(this << txVector);
754
755 auto txMode = txVector.GetMode();
756 if (txMode.GetModulationClass() >= WIFI_MOD_CLASS_HT)
757 {
758 auto rate = txMode.GetDataRate(txVector);
759 if (rate >= 24e6)
760 {
761 rate = 24e6;
762 }
763 else if (rate >= 12e6)
764 {
765 rate = 12e6;
766 }
767 else
768 {
769 rate = 6e6;
770 }
772 if (m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ)
773 {
774 txVector.SetMode(ErpOfdmPhy::GetErpOfdmRate(rate));
775 }
776 else
777 {
778 txVector.SetMode(OfdmPhy::GetOfdmRate(rate));
779 }
780 }
781}
782
784WifiRemoteStationManager::GetAckTxVector(Mac48Address to, const WifiTxVector& dataTxVector) const
785{
786 NS_ASSERT(!to.IsGroup());
787 WifiMode ackMode = GetControlAnswerMode(dataTxVector.GetMode(GetStaId(to, dataTxVector)));
788 WifiTxVector v;
789 v.SetMode(ackMode);
791 GetPreambleForTransmission(ackMode.GetModulationClass(), GetShortPreambleEnabled()));
792 v.SetTxPowerLevel(GetDefaultTxPowerLevel());
793 v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(ackMode));
794 uint16_t ackTxGuardInterval =
795 ConvertGuardIntervalToNanoSeconds(ackMode, m_wifiPhy->GetDevice());
796 v.SetGuardInterval(ackTxGuardInterval);
797 v.SetNss(1);
798 return v;
799}
800
802WifiRemoteStationManager::GetBlockAckTxVector(Mac48Address to,
803 const WifiTxVector& dataTxVector) const
804{
805 NS_ASSERT(!to.IsGroup());
806 WifiMode blockAckMode = GetControlAnswerMode(dataTxVector.GetMode(GetStaId(to, dataTxVector)));
807 WifiTxVector v;
808 v.SetMode(blockAckMode);
810 GetPreambleForTransmission(blockAckMode.GetModulationClass(), GetShortPreambleEnabled()));
811 v.SetTxPowerLevel(GetDefaultTxPowerLevel());
812 v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(blockAckMode));
813 uint16_t blockAckTxGuardInterval =
814 ConvertGuardIntervalToNanoSeconds(blockAckMode, m_wifiPhy->GetDevice());
815 v.SetGuardInterval(blockAckTxGuardInterval);
816 v.SetNss(1);
817 return v;
818}
819
821WifiRemoteStationManager::GetControlAnswerMode(WifiMode reqMode) const
822{
837 NS_LOG_FUNCTION(this << reqMode);
838 WifiMode mode = GetDefaultMode();
839 bool found = false;
840 // First, search the BSS Basic Rate set
841 for (uint8_t i = 0; i < GetNBasicModes(); i++)
842 {
843 WifiMode testMode = GetBasicMode(i);
844 if ((!found || testMode.IsHigherDataRate(mode)) && (!testMode.IsHigherDataRate(reqMode)) &&
846 testMode.GetModulationClass())))
847 {
848 mode = testMode;
849 // We've found a potentially-suitable transmit rate, but we
850 // need to continue and consider all the basic rates before
851 // we can be sure we've got the right one.
852 found = true;
853 }
854 }
855 if (GetHtSupported())
856 {
857 if (!found)
858 {
859 mode = GetDefaultMcs();
860 for (uint8_t i = 0; i != GetNBasicMcs(); i++)
861 {
862 WifiMode testMode = GetBasicMcs(i);
863 if ((!found || testMode.IsHigherDataRate(mode)) &&
864 (!testMode.IsHigherDataRate(reqMode)) &&
865 (testMode.GetModulationClass() == reqMode.GetModulationClass()))
866 {
867 mode = testMode;
868 // We've found a potentially-suitable transmit rate, but we
869 // need to continue and consider all the basic rates before
870 // we can be sure we've got the right one.
871 found = true;
872 }
873 }
874 }
875 }
876 // If we found a suitable rate in the BSSBasicRateSet, then we are
877 // done and can return that mode.
878 if (found)
879 {
880 NS_LOG_DEBUG("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
881 return mode;
882 }
883
901 for (const auto& thismode : m_wifiPhy->GetModeList())
902 {
903 /* If the rate:
904 *
905 * - is a mandatory rate for the PHY, and
906 * - is equal to or faster than our current best choice, and
907 * - is less than or equal to the rate of the received frame, and
908 * - is of the same modulation class as the received frame
909 *
910 * ...then it's our best choice so far.
911 */
912 if (thismode.IsMandatory() && (!found || thismode.IsHigherDataRate(mode)) &&
913 (!thismode.IsHigherDataRate(reqMode)) &&
915 thismode.GetModulationClass())))
916 {
917 mode = thismode;
918 // As above; we've found a potentially-suitable transmit
919 // rate, but we need to continue and consider all the
920 // mandatory rates before we can be sure we've got the right one.
921 found = true;
922 }
923 }
924 if (GetHtSupported())
925 {
926 for (const auto& thismode : m_wifiPhy->GetMcsList())
927 {
928 if (thismode.IsMandatory() && (!found || thismode.IsHigherDataRate(mode)) &&
929 (!thismode.IsHigherCodeRate(reqMode)) &&
930 (thismode.GetModulationClass() == reqMode.GetModulationClass()))
931 {
932 mode = thismode;
933 // As above; we've found a potentially-suitable transmit
934 // rate, but we need to continue and consider all the
935 // mandatory rates before we can be sure we've got the right one.
936 found = true;
937 }
938 }
939 }
940
950 if (!found)
951 {
952 NS_FATAL_ERROR("Can't find response rate for " << reqMode);
953 }
954
955 NS_LOG_DEBUG("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
956 return mode;
957}
958
959void
960WifiRemoteStationManager::ReportRtsFailed(const WifiMacHeader& header)
961{
962 NS_LOG_FUNCTION(this << header);
963 NS_ASSERT(!header.GetAddr1().IsGroup());
964 AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
965 m_ssrc[ac]++;
966 m_macTxRtsFailed(header.GetAddr1());
967 DoReportRtsFailed(Lookup(header.GetAddr1()));
968}
969
970void
971WifiRemoteStationManager::ReportDataFailed(Ptr<const WifiMpdu> mpdu)
972{
973 NS_LOG_FUNCTION(this << *mpdu);
974 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
975 AcIndex ac =
976 QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
977 bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
978 if (longMpdu)
979 {
980 m_slrc[ac]++;
981 }
982 else
983 {
984 m_ssrc[ac]++;
985 }
986 m_macTxDataFailed(mpdu->GetHeader().GetAddr1());
987 DoReportDataFailed(Lookup(mpdu->GetHeader().GetAddr1()));
988}
989
990void
991WifiRemoteStationManager::ReportRtsOk(const WifiMacHeader& header,
992 double ctsSnr,
993 WifiMode ctsMode,
994 double rtsSnr)
995{
996 NS_LOG_FUNCTION(this << header << ctsSnr << ctsMode << rtsSnr);
997 NS_ASSERT(!header.GetAddr1().IsGroup());
998 WifiRemoteStation* station = Lookup(header.GetAddr1());
999 AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
1000 station->m_state->m_info.NotifyTxSuccess(m_ssrc[ac]);
1001 m_ssrc[ac] = 0;
1002 DoReportRtsOk(station, ctsSnr, ctsMode, rtsSnr);
1003}
1004
1005void
1006WifiRemoteStationManager::ReportDataOk(Ptr<const WifiMpdu> mpdu,
1007 double ackSnr,
1008 WifiMode ackMode,
1009 double dataSnr,
1010 WifiTxVector dataTxVector)
1011{
1012 NS_LOG_FUNCTION(this << *mpdu << ackSnr << ackMode << dataSnr << dataTxVector);
1013 const WifiMacHeader& hdr = mpdu->GetHeader();
1014 NS_ASSERT(!hdr.GetAddr1().IsGroup());
1015 WifiRemoteStation* station = Lookup(hdr.GetAddr1());
1016 AcIndex ac = QosUtilsMapTidToAc((hdr.IsQosData()) ? hdr.GetQosTid() : 0);
1017 bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
1018 if (longMpdu)
1019 {
1020 station->m_state->m_info.NotifyTxSuccess(m_slrc[ac]);
1021 m_slrc[ac] = 0;
1022 }
1023 else
1024 {
1025 station->m_state->m_info.NotifyTxSuccess(m_ssrc[ac]);
1026 m_ssrc[ac] = 0;
1027 }
1028 DoReportDataOk(station,
1029 ackSnr,
1030 ackMode,
1031 dataSnr,
1032 dataTxVector.GetChannelWidth(),
1033 dataTxVector.GetNss(GetStaId(hdr.GetAddr1(), dataTxVector)));
1034}
1035
1036void
1037WifiRemoteStationManager::ReportFinalRtsFailed(const WifiMacHeader& header)
1038{
1039 NS_LOG_FUNCTION(this << header);
1040 NS_ASSERT(!header.GetAddr1().IsGroup());
1041 WifiRemoteStation* station = Lookup(header.GetAddr1());
1042 AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
1043 station->m_state->m_info.NotifyTxFailed();
1044 m_ssrc[ac] = 0;
1045 m_macTxFinalRtsFailed(header.GetAddr1());
1046 DoReportFinalRtsFailed(station);
1047}
1048
1049void
1050WifiRemoteStationManager::ReportFinalDataFailed(Ptr<const WifiMpdu> mpdu)
1051{
1052 NS_LOG_FUNCTION(this << *mpdu);
1053 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1054 WifiRemoteStation* station = Lookup(mpdu->GetHeader().GetAddr1());
1055 AcIndex ac =
1056 QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
1057 station->m_state->m_info.NotifyTxFailed();
1058 bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
1059 if (longMpdu)
1060 {
1061 m_slrc[ac] = 0;
1062 }
1063 else
1064 {
1065 m_ssrc[ac] = 0;
1066 }
1067 m_macTxFinalDataFailed(mpdu->GetHeader().GetAddr1());
1068 DoReportFinalDataFailed(station);
1069}
1070
1071void
1072WifiRemoteStationManager::ReportRxOk(Mac48Address address,
1073 RxSignalInfo rxSignalInfo,
1074 WifiTxVector txVector)
1075{
1076 NS_LOG_FUNCTION(this << address << rxSignalInfo << txVector);
1077 if (address.IsGroup())
1078 {
1079 return;
1080 }
1081 WifiRemoteStation* station = Lookup(address);
1082 DoReportRxOk(station, rxSignalInfo.snr, txVector.GetMode(GetStaId(address, txVector)));
1083 station->m_rssiAndUpdateTimePair = std::make_pair(rxSignalInfo.rssi, Simulator::Now());
1084}
1085
1086void
1087WifiRemoteStationManager::ReportAmpduTxStatus(Mac48Address address,
1088 uint16_t nSuccessfulMpdus,
1089 uint16_t nFailedMpdus,
1090 double rxSnr,
1091 double dataSnr,
1092 WifiTxVector dataTxVector)
1093{
1094 NS_LOG_FUNCTION(this << address << nSuccessfulMpdus << nFailedMpdus << rxSnr << dataSnr
1095 << dataTxVector);
1096 NS_ASSERT(!address.IsGroup());
1097 for (uint16_t i = 0; i < nFailedMpdus; i++)
1098 {
1099 m_macTxDataFailed(address);
1100 }
1101 DoReportAmpduTxStatus(Lookup(address),
1102 nSuccessfulMpdus,
1103 nFailedMpdus,
1104 rxSnr,
1105 dataSnr,
1106 dataTxVector.GetChannelWidth(),
1107 dataTxVector.GetNss(GetStaId(address, dataTxVector)));
1108}
1109
1110bool
1111WifiRemoteStationManager::NeedRts(const WifiMacHeader& header, uint32_t size)
1112{
1113 NS_LOG_FUNCTION(this << header << size);
1114 Mac48Address address = header.GetAddr1();
1115 WifiTxVector txVector = GetDataTxVector(header, m_wifiPhy->GetChannelWidth());
1116 const auto modulationClass = txVector.GetModulationClass();
1117 if (address.IsGroup())
1118 {
1119 return false;
1120 }
1121 if (m_erpProtectionMode == RTS_CTS &&
1122 ((modulationClass == WIFI_MOD_CLASS_ERP_OFDM) || (modulationClass == WIFI_MOD_CLASS_HT) ||
1123 (modulationClass == WIFI_MOD_CLASS_VHT) || (modulationClass == WIFI_MOD_CLASS_HE) ||
1124 (modulationClass == WIFI_MOD_CLASS_EHT)) &&
1125 m_useNonErpProtection)
1126 {
1128 "WifiRemoteStationManager::NeedRTS returning true to protect non-ERP stations");
1129 return true;
1130 }
1131 else if (m_htProtectionMode == RTS_CTS &&
1132 ((modulationClass == WIFI_MOD_CLASS_HT) || (modulationClass == WIFI_MOD_CLASS_VHT)) &&
1133 m_useNonHtProtection && !(m_erpProtectionMode != RTS_CTS && m_useNonErpProtection))
1134 {
1135 NS_LOG_DEBUG("WifiRemoteStationManager::NeedRTS returning true to protect non-HT stations");
1136 return true;
1137 }
1138 bool normally = (size > m_rtsCtsThreshold);
1139 return DoNeedRts(Lookup(address), size, normally);
1140}
1141
1142bool
1143WifiRemoteStationManager::NeedCtsToSelf(WifiTxVector txVector)
1144{
1145 WifiMode mode = txVector.GetMode();
1146 NS_LOG_FUNCTION(this << mode);
1147 if (m_erpProtectionMode == CTS_TO_SELF &&
1153 m_useNonErpProtection)
1154 {
1156 "WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-ERP stations");
1157 return true;
1158 }
1159 else if (m_htProtectionMode == CTS_TO_SELF &&
1162 m_useNonHtProtection && !(m_erpProtectionMode != CTS_TO_SELF && m_useNonErpProtection))
1163 {
1165 "WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-HT stations");
1166 return true;
1167 }
1168 else if (!m_useNonErpProtection)
1169 {
1170 // search for the BSS Basic Rate set, if the used mode is in the basic set then there is no
1171 // need for CTS To Self
1172 for (WifiModeListIterator i = m_bssBasicRateSet.begin(); i != m_bssBasicRateSet.end(); i++)
1173 {
1174 if (mode == *i)
1175 {
1176 NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning false");
1177 return false;
1178 }
1179 }
1180 if (GetHtSupported())
1181 {
1182 // search for the BSS Basic MCS set, if the used mode is in the basic set then there is
1183 // no need for CTS To Self
1184 for (WifiModeListIterator i = m_bssBasicMcsSet.begin(); i != m_bssBasicMcsSet.end();
1185 i++)
1186 {
1187 if (mode == *i)
1188 {
1189 NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning false");
1190 return false;
1191 }
1192 }
1193 }
1194 NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning true");
1195 return true;
1196 }
1197 return false;
1198}
1199
1200void
1201WifiRemoteStationManager::SetUseNonErpProtection(bool enable)
1202{
1203 NS_LOG_FUNCTION(this << enable);
1204 m_useNonErpProtection = enable;
1205}
1206
1207bool
1208WifiRemoteStationManager::GetUseNonErpProtection() const
1209{
1210 return m_useNonErpProtection;
1211}
1212
1213void
1214WifiRemoteStationManager::SetUseNonHtProtection(bool enable)
1215{
1216 NS_LOG_FUNCTION(this << enable);
1217 m_useNonHtProtection = enable;
1218}
1219
1220bool
1221WifiRemoteStationManager::GetUseNonHtProtection() const
1222{
1223 return m_useNonHtProtection;
1224}
1225
1226bool
1227WifiRemoteStationManager::NeedRetransmission(Ptr<const WifiMpdu> mpdu)
1228{
1229 NS_LOG_FUNCTION(this << *mpdu);
1230 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1231 AcIndex ac =
1232 QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
1233 bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
1234 uint32_t retryCount;
1235 uint32_t maxRetryCount;
1236 if (longMpdu)
1237 {
1238 retryCount = m_slrc[ac];
1239 maxRetryCount = m_maxSlrc;
1240 }
1241 else
1242 {
1243 retryCount = m_ssrc[ac];
1244 maxRetryCount = m_maxSsrc;
1245 }
1246 bool normally = retryCount < maxRetryCount;
1247 NS_LOG_DEBUG("WifiRemoteStationManager::NeedRetransmission count: "
1248 << retryCount << " result: " << std::boolalpha << normally);
1249 return DoNeedRetransmission(Lookup(mpdu->GetHeader().GetAddr1()), mpdu->GetPacket(), normally);
1250}
1251
1252bool
1253WifiRemoteStationManager::NeedFragmentation(Ptr<const WifiMpdu> mpdu)
1254{
1255 NS_LOG_FUNCTION(this << *mpdu);
1256 if (mpdu->GetHeader().GetAddr1().IsGroup())
1257 {
1258 return false;
1259 }
1260 bool normally = mpdu->GetSize() > GetFragmentationThreshold();
1261 NS_LOG_DEBUG("WifiRemoteStationManager::NeedFragmentation result: " << std::boolalpha
1262 << normally);
1263 return DoNeedFragmentation(Lookup(mpdu->GetHeader().GetAddr1()), mpdu->GetPacket(), normally);
1264}
1265
1266void
1267WifiRemoteStationManager::DoSetFragmentationThreshold(uint32_t threshold)
1268{
1269 NS_LOG_FUNCTION(this << threshold);
1270 if (threshold < 256)
1271 {
1272 /*
1273 * ASN.1 encoding of the MAC and PHY MIB (256 ... 8000)
1274 */
1275 NS_LOG_WARN("Fragmentation threshold should be larger than 256. Setting to 256.");
1276 m_fragmentationThreshold = 256;
1277 }
1278 else
1279 {
1280 /*
1281 * The length of each fragment shall be an even number of octets, except for the last
1282 * fragment if an MSDU or MMPDU, which may be either an even or an odd number of octets.
1283 */
1284 if (threshold % 2 != 0)
1285 {
1286 NS_LOG_WARN("Fragmentation threshold should be an even number. Setting to "
1287 << threshold - 1);
1288 m_fragmentationThreshold = threshold - 1;
1289 }
1290 else
1291 {
1292 m_fragmentationThreshold = threshold;
1293 }
1294 }
1295}
1296
1298WifiRemoteStationManager::DoGetFragmentationThreshold() const
1299{
1300 return m_fragmentationThreshold;
1301}
1302
1304WifiRemoteStationManager::GetNFragments(Ptr<const WifiMpdu> mpdu)
1305{
1306 NS_LOG_FUNCTION(this << *mpdu);
1307 // The number of bytes a fragment can support is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1308 uint32_t nFragments =
1309 (mpdu->GetPacket()->GetSize() /
1310 (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH));
1311
1312 // If the size of the last fragment is not 0.
1313 if ((mpdu->GetPacket()->GetSize() %
1314 (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH)) > 0)
1315 {
1316 nFragments++;
1317 }
1318 NS_LOG_DEBUG("WifiRemoteStationManager::GetNFragments returning " << nFragments);
1319 return nFragments;
1320}
1321
1323WifiRemoteStationManager::GetFragmentSize(Ptr<const WifiMpdu> mpdu, uint32_t fragmentNumber)
1324{
1325 NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1326 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1327 uint32_t nFragment = GetNFragments(mpdu);
1328 if (fragmentNumber >= nFragment)
1329 {
1330 NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning 0");
1331 return 0;
1332 }
1333 // Last fragment
1334 if (fragmentNumber == nFragment - 1)
1335 {
1336 uint32_t lastFragmentSize =
1337 mpdu->GetPacket()->GetSize() -
1338 (fragmentNumber *
1339 (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH));
1340 NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning " << lastFragmentSize);
1341 return lastFragmentSize;
1342 }
1343 // All fragments but the last, the number of bytes is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1344 else
1345 {
1346 uint32_t fragmentSize =
1347 GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH;
1348 NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning " << fragmentSize);
1349 return fragmentSize;
1350 }
1351}
1352
1354WifiRemoteStationManager::GetFragmentOffset(Ptr<const WifiMpdu> mpdu, uint32_t fragmentNumber)
1355{
1356 NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1357 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1358 NS_ASSERT(fragmentNumber < GetNFragments(mpdu));
1359 uint32_t fragmentOffset = fragmentNumber * (GetFragmentationThreshold() -
1360 mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH);
1361 NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentOffset returning " << fragmentOffset);
1362 return fragmentOffset;
1363}
1364
1365bool
1366WifiRemoteStationManager::IsLastFragment(Ptr<const WifiMpdu> mpdu, uint32_t fragmentNumber)
1367{
1368 NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1369 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1370 bool isLast = fragmentNumber == (GetNFragments(mpdu) - 1);
1371 NS_LOG_DEBUG("WifiRemoteStationManager::IsLastFragment returning " << std::boolalpha << isLast);
1372 return isLast;
1373}
1374
1375uint8_t
1376WifiRemoteStationManager::GetDefaultTxPowerLevel() const
1377{
1378 return m_defaultTxPowerLevel;
1379}
1380
1382WifiRemoteStationManager::GetInfo(Mac48Address address)
1383{
1384 return LookupState(address)->m_info;
1385}
1386
1387std::optional<double>
1388WifiRemoteStationManager::GetMostRecentRssi(Mac48Address address) const
1389{
1390 auto station = Lookup(address);
1391 auto rssi = station->m_rssiAndUpdateTimePair.first;
1392 auto ts = station->m_rssiAndUpdateTimePair.second;
1393 if (ts.IsStrictlyPositive())
1394 {
1395 return rssi;
1396 }
1397 return std::nullopt;
1398}
1399
1400std::shared_ptr<WifiRemoteStationState>
1401WifiRemoteStationManager::LookupState(Mac48Address address) const
1402{
1403 NS_LOG_FUNCTION(this << address);
1404 auto stateIt = m_states.find(address);
1405
1406 if (stateIt != m_states.end())
1407 {
1408 NS_LOG_DEBUG("WifiRemoteStationManager::LookupState returning existing state");
1409 return stateIt->second;
1410 }
1411
1412 auto state = std::make_shared<WifiRemoteStationState>();
1413 state->m_state = WifiRemoteStationState::BRAND_NEW;
1414 state->m_address = address;
1415 state->m_aid = 0;
1416 state->m_operationalRateSet.push_back(GetDefaultMode());
1417 state->m_operationalMcsSet.push_back(GetDefaultMcs());
1418 state->m_dsssSupported = false;
1419 state->m_erpOfdmSupported = false;
1420 state->m_ofdmSupported = false;
1421 state->m_htCapabilities = nullptr;
1422 state->m_vhtCapabilities = nullptr;
1423 state->m_heCapabilities = nullptr;
1424 state->m_ehtCapabilities = nullptr;
1425 state->m_emlCapabilities = nullptr;
1426 state->m_emlsrEnabled = false;
1427 state->m_channelWidth = m_wifiPhy->GetChannelWidth();
1428 state->m_guardInterval = GetGuardInterval();
1429 state->m_ness = 0;
1430 state->m_aggregation = false;
1431 state->m_qosSupported = false;
1432 state->m_isInPsMode = false;
1433 const_cast<WifiRemoteStationManager*>(this)->m_states.insert({address, state});
1434 NS_LOG_DEBUG("WifiRemoteStationManager::LookupState returning new state");
1435 return state;
1436}
1437
1438WifiRemoteStation*
1439WifiRemoteStationManager::Lookup(Mac48Address address) const
1440{
1441 NS_LOG_FUNCTION(this << address);
1442 auto stationIt = m_stations.find(address);
1443
1444 if (stationIt != m_stations.end())
1445 {
1446 return stationIt->second;
1447 }
1448
1449 WifiRemoteStation* station = DoCreateStation();
1450 station->m_state = LookupState(address).get();
1451 station->m_rssiAndUpdateTimePair = std::make_pair(0, Seconds(0));
1452 const_cast<WifiRemoteStationManager*>(this)->m_stations.insert({address, station});
1453 return station;
1454}
1455
1456void
1457WifiRemoteStationManager::SetAssociationId(Mac48Address remoteAddress, uint16_t aid)
1458{
1459 NS_LOG_FUNCTION(this << remoteAddress << aid);
1460 LookupState(remoteAddress)->m_aid = aid;
1461}
1462
1463void
1464WifiRemoteStationManager::SetQosSupport(Mac48Address from, bool qosSupported)
1465{
1466 NS_LOG_FUNCTION(this << from << qosSupported);
1467 LookupState(from)->m_qosSupported = qosSupported;
1468}
1469
1470void
1471WifiRemoteStationManager::SetEmlsrEnabled(const Mac48Address& from, bool emlsrEnabled)
1472{
1473 NS_LOG_FUNCTION(this << from << emlsrEnabled);
1474 LookupState(from)->m_emlsrEnabled = emlsrEnabled;
1475}
1476
1477void
1478WifiRemoteStationManager::AddStationHtCapabilities(Mac48Address from, HtCapabilities htCapabilities)
1479{
1480 // Used by all stations to record HT capabilities of remote stations
1481 NS_LOG_FUNCTION(this << from << htCapabilities);
1482 auto state = LookupState(from);
1483 if (htCapabilities.GetSupportedChannelWidth() == 1)
1484 {
1485 state->m_channelWidth = 40;
1486 }
1487 else
1488 {
1489 state->m_channelWidth = 20;
1490 }
1491 SetQosSupport(from, true);
1492 for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_HT))
1493 {
1494 if (htCapabilities.IsSupportedMcs(mcs.GetMcsValue()))
1495 {
1496 AddSupportedMcs(from, mcs);
1497 }
1498 }
1499 state->m_htCapabilities = Create<const HtCapabilities>(htCapabilities);
1500}
1501
1502void
1503WifiRemoteStationManager::AddStationVhtCapabilities(Mac48Address from,
1504 VhtCapabilities vhtCapabilities)
1505{
1506 // Used by all stations to record VHT capabilities of remote stations
1507 NS_LOG_FUNCTION(this << from << vhtCapabilities);
1508 auto state = LookupState(from);
1509 if (vhtCapabilities.GetSupportedChannelWidthSet() == 1)
1510 {
1511 state->m_channelWidth = 160;
1512 }
1513 else
1514 {
1515 state->m_channelWidth = 80;
1516 }
1517 for (uint8_t i = 1; i <= m_wifiPhy->GetMaxSupportedTxSpatialStreams(); i++)
1518 {
1519 for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_VHT))
1520 {
1521 if (vhtCapabilities.IsSupportedMcs(mcs.GetMcsValue(), i))
1522 {
1523 AddSupportedMcs(from, mcs);
1524 }
1525 }
1526 }
1527 state->m_vhtCapabilities = Create<const VhtCapabilities>(vhtCapabilities);
1528}
1529
1530void
1531WifiRemoteStationManager::AddStationHeCapabilities(Mac48Address from, HeCapabilities heCapabilities)
1532{
1533 // Used by all stations to record HE capabilities of remote stations
1534 NS_LOG_FUNCTION(this << from << heCapabilities);
1535 auto state = LookupState(from);
1536 if ((m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) ||
1537 (m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_6GHZ))
1538 {
1539 if (heCapabilities.GetChannelWidthSet() & 0x04)
1540 {
1541 state->m_channelWidth = 160;
1542 }
1543 else if (heCapabilities.GetChannelWidthSet() & 0x02)
1544 {
1545 state->m_channelWidth = 80;
1546 }
1547 // For other cases at 5 GHz, the supported channel width is set by the VHT capabilities
1548 }
1549 else if (m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ)
1550 {
1551 if (heCapabilities.GetChannelWidthSet() & 0x01)
1552 {
1553 state->m_channelWidth = 40;
1554 }
1555 else
1556 {
1557 state->m_channelWidth = 20;
1558 }
1559 }
1560 if (heCapabilities.GetHeSuPpdu1xHeLtf800nsGi() == 1)
1561 {
1562 state->m_guardInterval = 800;
1563 }
1564 else
1565 {
1566 // todo: Using 3200ns, default value for HeConfiguration::GuardInterval
1567 state->m_guardInterval = 3200;
1568 }
1569 for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_HE))
1570 {
1571 if (heCapabilities.GetHighestMcsSupported() >= mcs.GetMcsValue())
1572 {
1573 AddSupportedMcs(from, mcs);
1574 }
1575 }
1576 state->m_heCapabilities = Create<const HeCapabilities>(heCapabilities);
1577 SetQosSupport(from, true);
1578}
1579
1580void
1581WifiRemoteStationManager::AddStationEhtCapabilities(Mac48Address from,
1582 EhtCapabilities ehtCapabilities)
1583{
1584 // Used by all stations to record EHT capabilities of remote stations
1585 NS_LOG_FUNCTION(this << from << ehtCapabilities);
1586 auto state = LookupState(from);
1587 for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_EHT))
1588 {
1589 for (uint8_t mapType = 0; mapType < EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_MAX; ++mapType)
1590 {
1591 if (ehtCapabilities.GetHighestSupportedRxMcs(
1592 static_cast<EhtMcsAndNssSet::EhtMcsMapType>(mapType)) >= mcs.GetMcsValue())
1593 {
1594 AddSupportedMcs(from, mcs);
1595 }
1596 }
1597 }
1598 state->m_ehtCapabilities = Create<const EhtCapabilities>(ehtCapabilities);
1599 SetQosSupport(from, true);
1600}
1601
1602void
1603WifiRemoteStationManager::AddStationEmlCapabilities(
1604 Mac48Address from,
1605 const std::shared_ptr<CommonInfoBasicMle::EmlCapabilities>& emlCapabilities)
1606{
1607 NS_LOG_FUNCTION(this << from);
1608 LookupState(from)->m_emlCapabilities = emlCapabilities;
1609}
1610
1612WifiRemoteStationManager::GetStationHtCapabilities(Mac48Address from)
1613{
1614 return LookupState(from)->m_htCapabilities;
1615}
1616
1618WifiRemoteStationManager::GetStationVhtCapabilities(Mac48Address from)
1619{
1620 return LookupState(from)->m_vhtCapabilities;
1621}
1622
1624WifiRemoteStationManager::GetStationHeCapabilities(Mac48Address from)
1625{
1626 return LookupState(from)->m_heCapabilities;
1627}
1628
1630WifiRemoteStationManager::GetStationEhtCapabilities(Mac48Address from)
1631{
1632 return LookupState(from)->m_ehtCapabilities;
1633}
1634
1635std::shared_ptr<CommonInfoBasicMle::EmlCapabilities>
1636WifiRemoteStationManager::GetStationEmlCapabilities(const Mac48Address& from)
1637{
1638 return LookupState(from)->m_emlCapabilities;
1639}
1640
1641bool
1642WifiRemoteStationManager::GetLdpcSupported(Mac48Address address) const
1643{
1644 Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
1645 Ptr<const VhtCapabilities> vhtCapabilities = LookupState(address)->m_vhtCapabilities;
1646 Ptr<const HeCapabilities> heCapabilities = LookupState(address)->m_heCapabilities;
1647 bool supported = false;
1648 if (htCapabilities)
1649 {
1650 supported |= htCapabilities->GetLdpc();
1651 }
1652 if (vhtCapabilities)
1653 {
1654 supported |= vhtCapabilities->GetRxLdpc();
1655 }
1656 if (heCapabilities)
1657 {
1658 supported |= heCapabilities->GetLdpcCodingInPayload();
1659 }
1660 return supported;
1661}
1662
1664WifiRemoteStationManager::GetDefaultMode() const
1665{
1666 return m_defaultTxMode;
1667}
1668
1670WifiRemoteStationManager::GetDefaultMcs() const
1671{
1672 return m_defaultTxMcs;
1673}
1674
1676WifiRemoteStationManager::GetDefaultModeForSta(const WifiRemoteStation* st) const
1677{
1678 NS_LOG_FUNCTION(this << st);
1679
1680 if (!GetHtSupported() || !GetHtSupported(st))
1681 {
1682 return GetDefaultMode();
1683 }
1684
1685 // find the highest modulation class supported by both stations
1687 if (GetHeSupported() && GetHeSupported(st))
1688 {
1689 modClass = WIFI_MOD_CLASS_HE;
1690 }
1691 else if (GetVhtSupported() && GetVhtSupported(st))
1692 {
1693 modClass = WIFI_MOD_CLASS_VHT;
1694 }
1695
1696 // return the MCS with lowest index
1697 return *m_wifiPhy->GetPhyEntity(modClass)->begin();
1698}
1699
1700void
1701WifiRemoteStationManager::Reset()
1702{
1703 NS_LOG_FUNCTION(this);
1704 m_states.clear();
1705 for (auto& state : m_stations)
1706 {
1707 delete (state.second);
1708 }
1709 m_stations.clear();
1710 m_bssBasicRateSet.clear();
1711 m_bssBasicMcsSet.clear();
1712 m_ssrc.fill(0);
1713 m_slrc.fill(0);
1714}
1715
1716void
1717WifiRemoteStationManager::AddBasicMode(WifiMode mode)
1718{
1719 NS_LOG_FUNCTION(this << mode);
1721 {
1722 NS_FATAL_ERROR("It is not allowed to add a HT rate in the BSSBasicRateSet!");
1723 }
1724 for (uint8_t i = 0; i < GetNBasicModes(); i++)
1725 {
1726 if (GetBasicMode(i) == mode)
1727 {
1728 return;
1729 }
1730 }
1731 m_bssBasicRateSet.push_back(mode);
1732}
1733
1734uint8_t
1735WifiRemoteStationManager::GetNBasicModes() const
1736{
1737 return static_cast<uint8_t>(m_bssBasicRateSet.size());
1738}
1739
1741WifiRemoteStationManager::GetBasicMode(uint8_t i) const
1742{
1743 NS_ASSERT(i < GetNBasicModes());
1744 return m_bssBasicRateSet[i];
1745}
1746
1748WifiRemoteStationManager::GetNNonErpBasicModes() const
1749{
1750 uint32_t size = 0;
1751 for (WifiModeListIterator i = m_bssBasicRateSet.begin(); i != m_bssBasicRateSet.end(); i++)
1752 {
1753 if (i->GetModulationClass() == WIFI_MOD_CLASS_ERP_OFDM)
1754 {
1755 continue;
1756 }
1757 size++;
1758 }
1759 return size;
1760}
1761
1763WifiRemoteStationManager::GetNonErpBasicMode(uint8_t i) const
1764{
1765 NS_ASSERT(i < GetNNonErpBasicModes());
1766 uint32_t index = 0;
1767 bool found = false;
1768 for (WifiModeListIterator j = m_bssBasicRateSet.begin(); j != m_bssBasicRateSet.end();)
1769 {
1770 if (i == index)
1771 {
1772 found = true;
1773 }
1774 if (j->GetModulationClass() != WIFI_MOD_CLASS_ERP_OFDM)
1775 {
1776 if (found)
1777 {
1778 break;
1779 }
1780 }
1781 index++;
1782 j++;
1783 }
1784 return m_bssBasicRateSet[index];
1785}
1786
1787void
1788WifiRemoteStationManager::AddBasicMcs(WifiMode mcs)
1789{
1790 NS_LOG_FUNCTION(this << +mcs.GetMcsValue());
1791 for (uint8_t i = 0; i < GetNBasicMcs(); i++)
1792 {
1793 if (GetBasicMcs(i) == mcs)
1794 {
1795 return;
1796 }
1797 }
1798 m_bssBasicMcsSet.push_back(mcs);
1799}
1800
1801uint8_t
1802WifiRemoteStationManager::GetNBasicMcs() const
1803{
1804 return static_cast<uint8_t>(m_bssBasicMcsSet.size());
1805}
1806
1808WifiRemoteStationManager::GetBasicMcs(uint8_t i) const
1809{
1810 NS_ASSERT(i < GetNBasicMcs());
1811 return m_bssBasicMcsSet[i];
1812}
1813
1815WifiRemoteStationManager::GetNonUnicastMode() const
1816{
1817 if (m_nonUnicastMode == WifiMode())
1818 {
1819 if (GetNBasicModes() > 0)
1820 {
1821 return GetBasicMode(0);
1822 }
1823 else
1824 {
1825 return GetDefaultMode();
1826 }
1827 }
1828 else
1829 {
1830 return m_nonUnicastMode;
1831 }
1832}
1833
1834bool
1835WifiRemoteStationManager::DoNeedRts(WifiRemoteStation* station, uint32_t size, bool normally)
1836{
1837 return normally;
1838}
1839
1840bool
1841WifiRemoteStationManager::DoNeedRetransmission(WifiRemoteStation* station,
1842 Ptr<const Packet> packet,
1843 bool normally)
1844{
1845 return normally;
1846}
1847
1848bool
1849WifiRemoteStationManager::DoNeedFragmentation(WifiRemoteStation* station,
1850 Ptr<const Packet> packet,
1851 bool normally)
1852{
1853 return normally;
1854}
1855
1856void
1857WifiRemoteStationManager::DoReportAmpduTxStatus(WifiRemoteStation* station,
1858 uint16_t nSuccessfulMpdus,
1859 uint16_t nFailedMpdus,
1860 double rxSnr,
1861 double dataSnr,
1862 uint16_t dataChannelWidth,
1863 uint8_t dataNss)
1864{
1865 NS_LOG_DEBUG("DoReportAmpduTxStatus received but the manager does not handle A-MPDUs!");
1866}
1867
1869WifiRemoteStationManager::GetSupported(const WifiRemoteStation* station, uint8_t i) const
1870{
1871 NS_ASSERT(i < GetNSupported(station));
1872 return station->m_state->m_operationalRateSet[i];
1873}
1874
1876WifiRemoteStationManager::GetMcsSupported(const WifiRemoteStation* station, uint8_t i) const
1877{
1878 NS_ASSERT(i < GetNMcsSupported(station));
1879 return station->m_state->m_operationalMcsSet[i];
1880}
1881
1883WifiRemoteStationManager::GetNonErpSupported(const WifiRemoteStation* station, uint8_t i) const
1884{
1885 NS_ASSERT(i < GetNNonErpSupported(station));
1886 // IEEE 802.11g standard defines that if the protection mechanism is enabled, RTS, CTS and
1887 // CTS-To-Self frames should select a rate in the BSSBasicRateSet that corresponds to an 802.11b
1888 // basic rate. This is a implemented here to avoid changes in every RAA, but should maybe be
1889 // moved in case it breaks standard rules.
1890 uint32_t index = 0;
1891 bool found = false;
1892 for (WifiModeListIterator j = station->m_state->m_operationalRateSet.begin();
1893 j != station->m_state->m_operationalRateSet.end();)
1894 {
1895 if (i == index)
1896 {
1897 found = true;
1898 }
1899 if (j->GetModulationClass() != WIFI_MOD_CLASS_ERP_OFDM)
1900 {
1901 if (found)
1902 {
1903 break;
1904 }
1905 }
1906 index++;
1907 j++;
1908 }
1909 return station->m_state->m_operationalRateSet[index];
1910}
1911
1913WifiRemoteStationManager::GetAddress(const WifiRemoteStation* station) const
1914{
1915 return station->m_state->m_address;
1916}
1917
1918uint16_t
1919WifiRemoteStationManager::GetChannelWidth(const WifiRemoteStation* station) const
1920{
1921 return station->m_state->m_channelWidth;
1922}
1923
1924bool
1925WifiRemoteStationManager::GetShortGuardIntervalSupported(const WifiRemoteStation* station) const
1926{
1927 Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1928
1929 if (!htCapabilities)
1930 {
1931 return false;
1932 }
1933 return htCapabilities->GetShortGuardInterval20();
1934}
1935
1936uint16_t
1937WifiRemoteStationManager::GetGuardInterval(const WifiRemoteStation* station) const
1938{
1939 return station->m_state->m_guardInterval;
1940}
1941
1942bool
1943WifiRemoteStationManager::GetAggregation(const WifiRemoteStation* station) const
1944{
1945 return station->m_state->m_aggregation;
1946}
1947
1948uint8_t
1949WifiRemoteStationManager::GetNumberOfSupportedStreams(const WifiRemoteStation* station) const
1950{
1951 Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1952
1953 if (!htCapabilities)
1954 {
1955 return 1;
1956 }
1957 return htCapabilities->GetRxHighestSupportedAntennas();
1958}
1959
1960uint8_t
1961WifiRemoteStationManager::GetNess(const WifiRemoteStation* station) const
1962{
1963 return station->m_state->m_ness;
1964}
1965
1967WifiRemoteStationManager::GetPhy() const
1968{
1969 return m_wifiPhy;
1970}
1971
1973WifiRemoteStationManager::GetMac() const
1974{
1975 return m_wifiMac;
1976}
1977
1978uint8_t
1979WifiRemoteStationManager::GetNSupported(const WifiRemoteStation* station) const
1980{
1981 return static_cast<uint8_t>(station->m_state->m_operationalRateSet.size());
1982}
1983
1984bool
1985WifiRemoteStationManager::GetQosSupported(const WifiRemoteStation* station) const
1986{
1987 return station->m_state->m_qosSupported;
1988}
1989
1990bool
1991WifiRemoteStationManager::GetHtSupported(const WifiRemoteStation* station) const
1992{
1993 return bool(station->m_state->m_htCapabilities);
1994}
1995
1996bool
1997WifiRemoteStationManager::GetVhtSupported(const WifiRemoteStation* station) const
1998{
1999 return bool(station->m_state->m_vhtCapabilities);
2000}
2001
2002bool
2003WifiRemoteStationManager::GetHeSupported(const WifiRemoteStation* station) const
2004{
2005 return bool(station->m_state->m_heCapabilities);
2006}
2007
2008bool
2009WifiRemoteStationManager::GetEhtSupported(const WifiRemoteStation* station) const
2010{
2011 return (bool)(station->m_state->m_ehtCapabilities);
2012}
2013
2014bool
2015WifiRemoteStationManager::GetEmlsrSupported(const WifiRemoteStation* station) const
2016{
2017 auto emlCapabilities = station->m_state->m_emlCapabilities;
2018 return emlCapabilities && emlCapabilities->emlsrSupport == 1;
2019}
2020
2021bool
2022WifiRemoteStationManager::GetEmlsrEnabled(const WifiRemoteStation* station) const
2023{
2024 return station->m_state->m_emlsrEnabled;
2025}
2026
2027uint8_t
2028WifiRemoteStationManager::GetNMcsSupported(const WifiRemoteStation* station) const
2029{
2030 return static_cast<uint8_t>(station->m_state->m_operationalMcsSet.size());
2031}
2032
2034WifiRemoteStationManager::GetNNonErpSupported(const WifiRemoteStation* station) const
2035{
2036 uint32_t size = 0;
2037 for (WifiModeListIterator i = station->m_state->m_operationalRateSet.begin();
2038 i != station->m_state->m_operationalRateSet.end();
2039 i++)
2040 {
2041 if (i->GetModulationClass() == WIFI_MOD_CLASS_ERP_OFDM)
2042 {
2043 continue;
2044 }
2045 size++;
2046 }
2047 return size;
2048}
2049
2050uint16_t
2051WifiRemoteStationManager::GetChannelWidthSupported(Mac48Address address) const
2052{
2053 return LookupState(address)->m_channelWidth;
2054}
2055
2056bool
2057WifiRemoteStationManager::GetShortGuardIntervalSupported(Mac48Address address) const
2058{
2059 Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
2060
2061 if (!htCapabilities)
2062 {
2063 return false;
2064 }
2065 return htCapabilities->GetShortGuardInterval20();
2066}
2067
2068uint8_t
2069WifiRemoteStationManager::GetNumberOfSupportedStreams(Mac48Address address) const
2070{
2071 Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
2072
2073 if (!htCapabilities)
2074 {
2075 return 1;
2076 }
2077 return htCapabilities->GetRxHighestSupportedAntennas();
2078}
2079
2080uint8_t
2081WifiRemoteStationManager::GetNMcsSupported(Mac48Address address) const
2082{
2083 return static_cast<uint8_t>(LookupState(address)->m_operationalMcsSet.size());
2084}
2085
2086bool
2087WifiRemoteStationManager::GetDsssSupported(const Mac48Address& address) const
2088{
2089 return (LookupState(address)->m_dsssSupported);
2090}
2091
2092bool
2093WifiRemoteStationManager::GetErpOfdmSupported(const Mac48Address& address) const
2094{
2095 return (LookupState(address)->m_erpOfdmSupported);
2096}
2097
2098bool
2099WifiRemoteStationManager::GetOfdmSupported(const Mac48Address& address) const
2100{
2101 return (LookupState(address)->m_ofdmSupported);
2102}
2103
2104bool
2105WifiRemoteStationManager::GetHtSupported(Mac48Address address) const
2106{
2107 return bool(LookupState(address)->m_htCapabilities);
2108}
2109
2110bool
2111WifiRemoteStationManager::GetVhtSupported(Mac48Address address) const
2112{
2113 return bool(LookupState(address)->m_vhtCapabilities);
2114}
2115
2116bool
2117WifiRemoteStationManager::GetHeSupported(Mac48Address address) const
2118{
2119 return bool(LookupState(address)->m_heCapabilities);
2120}
2121
2122bool
2123WifiRemoteStationManager::GetEhtSupported(Mac48Address address) const
2124{
2125 return (bool)(LookupState(address)->m_ehtCapabilities);
2126}
2127
2128bool
2129WifiRemoteStationManager::GetEmlsrSupported(const Mac48Address& address) const
2130{
2131 auto emlCapabilities = LookupState(address)->m_emlCapabilities;
2132 return emlCapabilities && emlCapabilities->emlsrSupport == 1;
2133}
2134
2135bool
2136WifiRemoteStationManager::GetEmlsrEnabled(const Mac48Address& address) const
2137{
2138 if (auto stateIt = m_states.find(address); stateIt != m_states.cend())
2139 {
2140 return stateIt->second->m_emlsrEnabled;
2141 }
2142 return false;
2143}
2144
2145void
2146WifiRemoteStationManager::SetDefaultTxPowerLevel(uint8_t txPower)
2147{
2148 m_defaultTxPowerLevel = txPower;
2149}
2150
2151uint8_t
2152WifiRemoteStationManager::GetNumberOfAntennas() const
2153{
2154 return m_wifiPhy->GetNumberOfAntennas();
2155}
2156
2157uint8_t
2158WifiRemoteStationManager::GetMaxNumberOfTransmitStreams() const
2159{
2160 return m_wifiPhy->GetMaxSupportedTxSpatialStreams();
2161}
2162
2163bool
2164WifiRemoteStationManager::UseLdpcForDestination(Mac48Address dest) const
2165{
2166 return (GetLdpcSupported() && GetLdpcSupported(dest));
2167}
2168
2169} // 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:488
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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
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:425
represent a single transmission mode
Definition: wifi-mode.h:51
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
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
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:1005
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:615
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:1961
std::list< WifiMode > GetModeList() const
The WifiPhy::GetModeList() method is used (e.g., by a WifiRemoteStationManager) to determine the set ...
Definition: wifi-phy.cc:1912
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 SetPsMode(const Mac48Address &address, bool isInPsMode)
Register whether the STA is in Power Save mode or not.
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.
bool IsInPsMode(const Mac48Address &address) const
Return whether the STA is currently in Power Save mode.
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)
Definition: enum.h:205
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_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 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
@ STA
Definition: wifi-mac.h:63
@ AP
Definition: wifi-mac.h:64
@ 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)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:266
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.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
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
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
bool m_emlsrEnabled
whether EMLSR mode is enabled on this link
Ptr< const HtCapabilities > m_htCapabilities
remote station HT capabilities
Ptr< const HeCapabilities > m_heCapabilities
remote station HE capabilities
std::shared_ptr< CommonInfoBasicMle::EmlCapabilities > m_emlCapabilities
remote station EML capabilities