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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
10
11#include "ap-wifi-mac.h"
12#include "sta-wifi-mac.h"
13#include "wifi-mac-header.h"
14#include "wifi-mac-trailer.h"
15#include "wifi-mpdu.h"
16#include "wifi-net-device.h"
17#include "wifi-phy.h"
18#include "wifi-tx-parameters.h"
19
20#include "ns3/boolean.h"
21#include "ns3/eht-configuration.h"
22#include "ns3/enum.h"
23#include "ns3/erp-ofdm-phy.h"
24#include "ns3/he-configuration.h"
25#include "ns3/ht-configuration.h"
26#include "ns3/ht-phy.h"
27#include "ns3/log.h"
28#include "ns3/simulator.h"
29#include "ns3/uinteger.h"
30#include "ns3/vht-configuration.h"
31
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("WifiRemoteStationManager");
36
37NS_OBJECT_ENSURE_REGISTERED(WifiRemoteStationManager);
38
39TypeId
41{
42 static TypeId tid =
43 TypeId("ns3::WifiRemoteStationManager")
45 .SetGroupName("Wifi")
46 .AddAttribute("MaxSsrc",
47 "The maximum number of retransmission attempts for any packet with size "
48 "<= RtsCtsThreshold. "
49 "This value will not have any effect on some rate control algorithms.",
53 .AddAttribute("MaxSlrc",
54 "The maximum number of retransmission attempts for any packet with size "
55 "> RtsCtsThreshold. "
56 "This value will not have any effect on some rate control algorithms.",
60 .AddAttribute("RtsCtsThreshold",
61 "If the size of the PSDU is bigger than this value, we use an RTS/CTS "
62 "handshake before sending the data frame."
63 "This value will not have any effect on some rate control algorithms.",
64 UintegerValue(4692480),
67 .AddAttribute("RtsCtsTxDurationThresh",
68 "If this threshold is a strictly positive value and the TX duration of "
69 "the PSDU is greater than or equal to this threshold, we use an RTS/CTS "
70 "handshake before sending the data frame.",
71 TimeValue(Time{0}),
74 .AddAttribute(
75 "FragmentationThreshold",
76 "If the size of the PSDU is bigger than this value, we fragment it such that the "
77 "size of the fragments are equal or smaller. "
78 "This value does not apply when it is carried in an A-MPDU. "
79 "This value will not have any effect on some rate control algorithms.",
80 UintegerValue(65535),
84 .AddAttribute("NonUnicastMode",
85 "Wifi mode used for non-unicast transmissions.",
89 .AddAttribute("DefaultTxPowerLevel",
90 "Default power level to be used for transmissions. "
91 "This is the power level that is used by all those WifiManagers that do "
92 "not implement TX power control.",
96 .AddAttribute("ErpProtectionMode",
97 "Protection mode used when non-ERP STAs are connected to an ERP AP: "
98 "Rts-Cts or Cts-To-Self",
103 "Rts-Cts",
105 "Cts-To-Self"))
106 .AddAttribute("HtProtectionMode",
107 "Protection mode used when non-HT STAs are connected to a HT AP: Rts-Cts "
108 "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 m_ssrc.fill(0);
145 m_slrc.fill(0);
146}
147
152
153void
159
160void
162{
163 NS_LOG_FUNCTION(this << phy);
164 // We need to track our PHY because it is the object that knows the
165 // full set of transmit rates that are supported. We need to know
166 // this in order to find the relevant mandatory rates when choosing a
167 // transmit rate for automatic control responses like
168 // acknowledgments.
169 m_wifiPhy = phy;
170}
171
172void
174{
175 NS_LOG_FUNCTION(this << mac);
176 // We need to track our MAC because it is the object that knows the
177 // full set of interframe spaces.
178 m_wifiMac = mac;
179}
180
181int64_t
183{
184 NS_LOG_FUNCTION(this << stream);
185 return 0;
186}
187
188void
190{
191 NS_LOG_FUNCTION(this << maxSsrc);
192 m_maxSsrc = maxSsrc;
193}
194
195void
197{
198 NS_LOG_FUNCTION(this << maxSlrc);
199 m_maxSlrc = maxSlrc;
200}
201
202void
204{
205 NS_LOG_FUNCTION(this << threshold);
206 m_rtsCtsThreshold = threshold;
207}
208
209void
215
216void
218{
219 NS_LOG_FUNCTION(this << enable);
220 m_shortPreambleEnabled = enable;
221}
222
223void
225{
226 NS_LOG_FUNCTION(this << enable);
227 m_shortSlotTimeEnabled = enable;
228}
229
230bool
235
236bool
241
242bool
244{
245 return (m_wifiPhy->GetDevice()->GetHtConfiguration() &&
247}
248
249bool
251{
252 return (m_wifiPhy->GetDevice()->GetVhtConfiguration() &&
255}
256
257bool
259{
260 return bool(m_wifiPhy->GetDevice()->GetHeConfiguration());
261}
262
263bool
265{
266 return bool(m_wifiPhy->GetDevice()->GetEhtConfiguration());
267}
268
269bool
271{
272 if (auto htConfiguration = m_wifiPhy->GetDevice()->GetHtConfiguration())
273 {
274 return htConfiguration->GetLdpcSupported();
275 }
276 return false;
277}
278
279bool
281{
282 if (auto htConfiguration = m_wifiPhy->GetDevice()->GetHtConfiguration())
283 {
284 return htConfiguration->GetShortGuardIntervalSupported();
285 }
286 return false;
287}
288
289Time
291{
292 Time gi{};
293 if (GetHeSupported())
294 {
295 Ptr<HeConfiguration> heConfiguration = m_wifiPhy->GetDevice()->GetHeConfiguration();
296 NS_ASSERT(heConfiguration); // If HE is supported, we should have a HE configuration
297 // attached
298 gi = heConfiguration->GetGuardInterval();
299 }
300 return gi;
301}
302
308
309void
311 bool isShortPreambleSupported)
312{
313 NS_LOG_FUNCTION(this << address << isShortPreambleSupported);
314 NS_ASSERT(!address.IsGroup());
315 LookupState(address)->m_shortPreamble = isShortPreambleSupported;
316}
317
318void
320 bool isShortSlotTimeSupported)
321{
322 NS_LOG_FUNCTION(this << address << isShortSlotTimeSupported);
323 NS_ASSERT(!address.IsGroup());
324 LookupState(address)->m_shortSlotTime = isShortSlotTimeSupported;
325}
326
327void
329{
330 NS_LOG_FUNCTION(this << address << mode);
331 NS_ASSERT(!address.IsGroup());
332 auto state = LookupState(address);
333 for (const auto& i : state->m_operationalRateSet)
334 {
335 if (i == mode)
336 {
337 return; // already in
338 }
339 }
340 if ((mode.GetModulationClass() == WIFI_MOD_CLASS_DSSS) ||
342 {
343 state->m_dsssSupported = true;
344 }
346 {
347 state->m_erpOfdmSupported = true;
348 }
349 else if (mode.GetModulationClass() == WIFI_MOD_CLASS_OFDM)
350 {
351 state->m_ofdmSupported = true;
352 }
353 state->m_operationalRateSet.push_back(mode);
354}
355
356void
358{
359 NS_LOG_FUNCTION(this << address);
360 NS_ASSERT(!address.IsGroup());
361 auto state = LookupState(address);
362 state->m_operationalRateSet.clear();
363 for (const auto& mode : m_wifiPhy->GetModeList())
364 {
365 state->m_operationalRateSet.push_back(mode);
366 if (mode.IsMandatory())
367 {
368 AddBasicMode(mode);
369 }
370 }
371}
372
373void
375{
376 NS_LOG_FUNCTION(this << address);
377 NS_ASSERT(!address.IsGroup());
378 auto state = LookupState(address);
379
380 const auto& mcsList = m_wifiPhy->GetMcsList();
381 state->m_operationalMcsSet = WifiModeList(mcsList.begin(), mcsList.end());
382}
383
384void
386{
387 NS_LOG_FUNCTION(this << address);
388 NS_ASSERT(!address.IsGroup());
389 LookupState(address)->m_operationalMcsSet.clear();
390}
391
392void
394{
395 NS_LOG_FUNCTION(this << address << mcs);
396 NS_ASSERT(!address.IsGroup());
397 auto state = LookupState(address);
398 for (const auto& i : state->m_operationalMcsSet)
399 {
400 if (i == mcs)
401 {
402 return; // already in
403 }
404 }
405 state->m_operationalMcsSet.push_back(mcs);
406}
407
408bool
410{
411 return LookupState(address)->m_shortPreamble;
412}
413
414bool
416{
417 return LookupState(address)->m_shortSlotTime;
418}
419
420bool
422{
423 return LookupState(address)->m_qosSupported;
424}
425
426bool
428{
429 if (address.IsGroup())
430 {
431 return false;
432 }
433 return LookupState(address)->m_state == WifiRemoteStationState::BRAND_NEW;
434}
435
436bool
438{
439 if (address.IsGroup())
440 {
441 return true;
442 }
443 return LookupState(address)->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK;
444}
445
446bool
448{
449 if (address.IsGroup())
450 {
451 return false;
452 }
453 return LookupState(address)->m_state == WifiRemoteStationState::WAIT_ASSOC_TX_OK;
454}
455
456void
462
463void
469
470void
476
477void
483
484bool
486{
487 if (address.IsGroup())
488 {
489 return false;
490 }
491 return LookupState(address)->m_state == WifiRemoteStationState::ASSOC_REFUSED;
492}
493
494void
500
501uint16_t
503{
504 std::shared_ptr<WifiRemoteStationState> state;
505 if (!remoteAddress.IsGroup() &&
506 (state = LookupState(remoteAddress))->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK)
507 {
508 return state->m_aid;
509 }
510 return SU_STA_ID;
511}
512
513uint16_t
515{
516 NS_LOG_FUNCTION(this << address << txVector);
517
518 uint16_t staId = SU_STA_ID;
519
520 if (txVector.IsMu())
521 {
522 if (m_wifiMac->GetTypeOfStation() == AP)
523 {
524 staId = GetAssociationId(address);
525 }
526 else if (m_wifiMac->GetTypeOfStation() == STA)
527 {
529 if (staMac->IsAssociated())
530 {
531 staId = staMac->GetAssociationId();
532 }
533 }
534 }
535
536 NS_LOG_DEBUG("Returning STAID = " << staId);
537 return staId;
538}
539
540bool
542{
543 return LookupState(address)->m_isInPsMode;
544}
545
546void
547WifiRemoteStationManager::SetPsMode(const Mac48Address& address, bool isInPsMode)
548{
549 LookupState(address)->m_isInPsMode = isInPsMode;
550}
551
552std::optional<Mac48Address>
554{
555 if (auto stateIt = m_states.find(address);
556 stateIt != m_states.end() && stateIt->second->m_mleCommonInfo)
557 {
558 return stateIt->second->m_mleCommonInfo->m_mldMacAddress;
559 }
560
561 return std::nullopt;
562}
563
564std::optional<Mac48Address>
566{
567 auto stateIt = m_states.find(mldAddress);
568
569 if (stateIt == m_states.end() || !stateIt->second->m_mleCommonInfo)
570 {
571 // MLD address not found
572 return std::nullopt;
573 }
574
575 NS_ASSERT(stateIt->second->m_mleCommonInfo->m_mldMacAddress == mldAddress);
576 return stateIt->second->m_address;
577}
578
581{
582 NS_LOG_FUNCTION(this << header << allowedWidth);
583 Mac48Address address = header.GetAddr1();
584 if (!header.IsMgt() && address.IsGroup())
585 {
587 WifiTxVector v;
588 v.SetMode(mode);
592 v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(mode, allowedWidth));
595 v.SetNss(1);
596 v.SetNess(0);
597 return v;
598 }
599 WifiTxVector txVector;
600 if (header.IsMgt())
601 {
602 // Use the lowest basic rate for management frames
603 WifiMode mgtMode;
604 if (GetNBasicModes() > 0)
605 {
606 mgtMode = GetBasicMode(0);
607 }
608 else
609 {
610 mgtMode = GetDefaultMode();
611 }
612 txVector.SetMode(mgtMode);
613 txVector.SetPreambleType(
616 auto channelWidth = allowedWidth;
617 if (!header.GetAddr1().IsGroup())
618 {
619 if (const auto rxWidth = GetChannelWidthSupported(header.GetAddr1());
620 rxWidth < channelWidth)
621 {
622 channelWidth = rxWidth;
623 }
624 }
625
626 txVector.SetChannelWidth(m_wifiPhy->GetTxBandwidth(mgtMode, channelWidth));
628 }
629 else
630 {
631 txVector = DoGetDataTxVector(Lookup(address), allowedWidth);
633 ? false
634 : UseLdpcForDestination(address));
635 }
636 Ptr<HeConfiguration> heConfiguration = m_wifiPhy->GetDevice()->GetHeConfiguration();
637 if (heConfiguration)
638 {
639 txVector.SetBssColor(heConfiguration->GetBssColor());
640 }
641 // If both the allowed width and the TXVECTOR channel width are integer multiple
642 // of 20 MHz, then the TXVECTOR channel width must not exceed the allowed width
643 NS_ASSERT_MSG((static_cast<uint16_t>(txVector.GetChannelWidth()) % 20 != 0) ||
644 (static_cast<uint16_t>(allowedWidth) % 20 != 0) ||
645 (txVector.GetChannelWidth() <= allowedWidth),
646 "TXVECTOR channel width (" << txVector.GetChannelWidth()
647 << " MHz) exceeds allowed width (" << allowedWidth
648 << " MHz)");
649 return txVector;
650}
651
654{
655 WifiMode defaultMode = GetDefaultMode();
656 WifiPreamble defaultPreamble;
657 if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_EHT)
658 {
659 defaultPreamble = WIFI_PREAMBLE_EHT_MU;
660 }
661 else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_HE)
662 {
663 defaultPreamble = WIFI_PREAMBLE_HE_SU;
664 }
665 else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_VHT)
666 {
667 defaultPreamble = WIFI_PREAMBLE_VHT_SU;
668 }
669 else if (defaultMode.GetModulationClass() == WIFI_MOD_CLASS_HT)
670 {
671 defaultPreamble = WIFI_PREAMBLE_HT_MF;
672 }
673 else
674 {
675 defaultPreamble = WIFI_PREAMBLE_LONG;
676 }
677
678 return WifiTxVector(defaultMode,
680 defaultPreamble,
683 1,
684 0,
685 m_wifiPhy->GetTxBandwidth(defaultMode),
686 false);
687}
688
691{
692 NS_LOG_FUNCTION(this << address << allowedWidth);
693 WifiTxVector v;
694 if (address.IsGroup())
695 {
697 v.SetMode(mode);
704 v.SetNss(1);
705 v.SetNess(0);
706 }
707 else
708 {
709 v = DoGetRtsTxVector(Lookup(address));
710 }
711 auto modulation = v.GetModulationClass();
712
713 if (allowedWidth >= 40 &&
714 (modulation == WIFI_MOD_CLASS_DSSS || modulation == WIFI_MOD_CLASS_HR_DSSS))
715 {
716 // RTS must be sent in a non-HT duplicate PPDU because it must protect a frame being
717 // transmitted on at least 40 MHz. Change the modulation class to ERP-OFDM and the rate
718 // to 6 Mbps
720 modulation = v.GetModulationClass();
721 }
722 // do not set allowedWidth as the TX width if the modulation class is (HR-)DSSS (allowedWidth
723 // may be >= 40 MHz) or allowedWidth is 22 MHz (the selected modulation class may be OFDM)
724 if (modulation != WIFI_MOD_CLASS_DSSS && modulation != WIFI_MOD_CLASS_HR_DSSS &&
725 allowedWidth != 22)
726 {
727 v.SetChannelWidth(allowedWidth);
728 }
729
730 return v;
731}
732
748
749void
751{
752 NS_LOG_FUNCTION(this << txVector);
753
754 auto txMode = txVector.GetMode();
755 if (txMode.GetModulationClass() >= WIFI_MOD_CLASS_HT)
756 {
757 auto rate = txMode.GetDataRate(txVector);
758 if (rate >= 24e6)
759 {
760 rate = 24e6;
761 }
762 else if (rate >= 12e6)
763 {
764 rate = 12e6;
765 }
766 else
767 {
768 rate = 6e6;
769 }
772 {
773 txVector.SetMode(ErpOfdmPhy::GetErpOfdmRate(rate));
774 }
775 else
776 {
777 txVector.SetMode(OfdmPhy::GetOfdmRate(rate));
778 }
779 }
780}
781
784{
785 NS_ASSERT(!to.IsGroup());
786 WifiMode ackMode = GetControlAnswerMode(dataTxVector.GetMode(GetStaId(to, dataTxVector)));
787 WifiTxVector v;
788 v.SetMode(ackMode);
794 v.SetNss(1);
795 return v;
796}
797
800 const WifiTxVector& dataTxVector) const
801{
802 NS_ASSERT(!to.IsGroup());
803 WifiMode blockAckMode = GetControlAnswerMode(dataTxVector.GetMode(GetStaId(to, dataTxVector)));
804 WifiTxVector v;
805 v.SetMode(blockAckMode);
809 v.SetChannelWidth(m_wifiPhy->GetTxBandwidth(blockAckMode));
811 v.SetNss(1);
812 return v;
813}
814
817{
818 /**
819 * The standard has relatively unambiguous rules for selecting a
820 * control response rate (the below is quoted from IEEE 802.11-2012,
821 * Section 9.7):
822 *
823 * To allow the transmitting STA to calculate the contents of the
824 * Duration/ID field, a STA responding to a received frame shall
825 * transmit its Control Response frame (either CTS or Ack), other
826 * than the BlockAck control frame, at the highest rate in the
827 * BSSBasicRateSet parameter that is less than or equal to the
828 * rate of the immediately previous frame in the frame exchange
829 * sequence (as defined in Annex G) and that is of the same
830 * modulation class (see Section 9.7.8) as the received frame...
831 */
832 NS_LOG_FUNCTION(this << reqMode);
833 WifiMode mode = GetDefaultMode();
834 bool found = false;
835 // First, search the BSS Basic Rate set
836 for (uint8_t i = 0; i < GetNBasicModes(); i++)
837 {
838 WifiMode testMode = GetBasicMode(i);
839 if ((!found || testMode.IsHigherDataRate(mode)) && (!testMode.IsHigherDataRate(reqMode)) &&
841 testMode.GetModulationClass())))
842 {
843 mode = testMode;
844 // We've found a potentially-suitable transmit rate, but we
845 // need to continue and consider all the basic rates before
846 // we can be sure we've got the right one.
847 found = true;
848 }
849 }
850 if (m_wifiPhy->GetDevice()->GetHtConfiguration())
851 {
852 if (!found)
853 {
854 mode = GetDefaultMcs();
855 for (uint8_t i = 0; i != GetNBasicMcs(); i++)
856 {
857 WifiMode testMode = GetBasicMcs(i);
858 if ((!found || testMode.IsHigherDataRate(mode)) &&
859 (!testMode.IsHigherDataRate(reqMode)) &&
860 (testMode.GetModulationClass() == reqMode.GetModulationClass()))
861 {
862 mode = testMode;
863 // We've found a potentially-suitable transmit rate, but we
864 // need to continue and consider all the basic rates before
865 // we can be sure we've got the right one.
866 found = true;
867 }
868 }
869 }
870 }
871 // If we found a suitable rate in the BSSBasicRateSet, then we are
872 // done and can return that mode.
873 if (found)
874 {
875 NS_LOG_DEBUG("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
876 return mode;
877 }
878
879 /**
880 * If no suitable basic rate was found, we search the mandatory
881 * rates. The standard (IEEE 802.11-2007, Section 9.6) says:
882 *
883 * ...If no rate contained in the BSSBasicRateSet parameter meets
884 * these conditions, then the control frame sent in response to a
885 * received frame shall be transmitted at the highest mandatory
886 * rate of the PHY that is less than or equal to the rate of the
887 * received frame, and that is of the same modulation class as the
888 * received frame. In addition, the Control Response frame shall
889 * be sent using the same PHY options as the received frame,
890 * unless they conflict with the requirement to use the
891 * BSSBasicRateSet parameter.
892 *
893 * \todo Note that we're ignoring the last sentence for now, because
894 * there is not yet any manipulation here of PHY options.
895 */
896 for (const auto& thismode : m_wifiPhy->GetModeList())
897 {
898 /* If the rate:
899 *
900 * - is a mandatory rate for the PHY, and
901 * - is equal to or faster than our current best choice, and
902 * - is less than or equal to the rate of the received frame, and
903 * - is of the same modulation class as the received frame
904 *
905 * ...then it's our best choice so far.
906 */
907 if (thismode.IsMandatory() && (!found || thismode.IsHigherDataRate(mode)) &&
908 (!thismode.IsHigherDataRate(reqMode)) &&
910 thismode.GetModulationClass())))
911 {
912 mode = thismode;
913 // As above; we've found a potentially-suitable transmit
914 // rate, but we need to continue and consider all the
915 // mandatory rates before we can be sure we've got the right one.
916 found = true;
917 }
918 }
919 if (m_wifiPhy->GetDevice()->GetHtConfiguration())
920 {
921 for (const auto& thismode : m_wifiPhy->GetMcsList())
922 {
923 if (thismode.IsMandatory() && (!found || thismode.IsHigherDataRate(mode)) &&
924 (!thismode.IsHigherCodeRate(reqMode)) &&
925 (thismode.GetModulationClass() == reqMode.GetModulationClass()))
926 {
927 mode = thismode;
928 // As above; we've found a potentially-suitable transmit
929 // rate, but we need to continue and consider all the
930 // mandatory rates before we can be sure we've got the right one.
931 found = true;
932 }
933 }
934 }
935
936 /**
937 * If we still haven't found a suitable rate for the response then
938 * someone has messed up the simulation configuration. This probably means
939 * that the WifiPhyStandard is not set correctly, or that a rate that
940 * is not supported by the PHY has been explicitly requested.
941 *
942 * Either way, it is serious - we can either disobey the standard or
943 * fail, and I have chosen to do the latter...
944 */
945 if (!found)
946 {
947 NS_FATAL_ERROR("Can't find response rate for " << reqMode);
948 }
949
950 NS_LOG_DEBUG("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
951 return mode;
952}
953
954void
956{
957 NS_LOG_FUNCTION(this << header);
958 NS_ASSERT(!header.GetAddr1().IsGroup());
959 AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
960 m_ssrc[ac]++;
961 m_macTxRtsFailed(header.GetAddr1());
963}
964
965void
967{
968 NS_LOG_FUNCTION(this << *mpdu);
969 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
970 AcIndex ac =
971 QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
972 bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
973 if (longMpdu)
974 {
975 m_slrc[ac]++;
976 }
977 else
978 {
979 m_ssrc[ac]++;
980 }
981 m_macTxDataFailed(mpdu->GetHeader().GetAddr1());
982 DoReportDataFailed(Lookup(mpdu->GetHeader().GetAddr1()));
983}
984
985void
987 double ctsSnr,
988 WifiMode ctsMode,
989 double rtsSnr)
990{
991 NS_LOG_FUNCTION(this << header << ctsSnr << ctsMode << rtsSnr);
992 NS_ASSERT(!header.GetAddr1().IsGroup());
993 WifiRemoteStation* station = Lookup(header.GetAddr1());
994 AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
995 station->m_state->m_info.NotifyTxSuccess(m_ssrc[ac]);
996 m_ssrc[ac] = 0;
997 DoReportRtsOk(station, ctsSnr, ctsMode, rtsSnr);
998}
999
1000void
1002 double ackSnr,
1003 WifiMode ackMode,
1004 double dataSnr,
1005 WifiTxVector dataTxVector)
1006{
1007 NS_LOG_FUNCTION(this << *mpdu << ackSnr << ackMode << dataSnr << dataTxVector);
1008 const WifiMacHeader& hdr = mpdu->GetHeader();
1009 NS_ASSERT(!hdr.GetAddr1().IsGroup());
1010 WifiRemoteStation* station = Lookup(hdr.GetAddr1());
1011 AcIndex ac = QosUtilsMapTidToAc((hdr.IsQosData()) ? hdr.GetQosTid() : 0);
1012 bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
1013 if (longMpdu)
1014 {
1015 station->m_state->m_info.NotifyTxSuccess(m_slrc[ac]);
1016 m_slrc[ac] = 0;
1017 }
1018 else
1019 {
1020 station->m_state->m_info.NotifyTxSuccess(m_ssrc[ac]);
1021 m_ssrc[ac] = 0;
1022 }
1023 DoReportDataOk(station,
1024 ackSnr,
1025 ackMode,
1026 dataSnr,
1027 dataTxVector.GetChannelWidth(),
1028 dataTxVector.GetNss(GetStaId(hdr.GetAddr1(), dataTxVector)));
1029}
1030
1031void
1033{
1034 NS_LOG_FUNCTION(this << header);
1035 NS_ASSERT(!header.GetAddr1().IsGroup());
1036 WifiRemoteStation* station = Lookup(header.GetAddr1());
1037 AcIndex ac = QosUtilsMapTidToAc((header.IsQosData()) ? header.GetQosTid() : 0);
1038 station->m_state->m_info.NotifyTxFailed();
1039 m_ssrc[ac] = 0;
1041 DoReportFinalRtsFailed(station);
1042}
1043
1044void
1046{
1047 NS_LOG_FUNCTION(this << *mpdu);
1048 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1049 WifiRemoteStation* station = Lookup(mpdu->GetHeader().GetAddr1());
1050 AcIndex ac =
1051 QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
1052 station->m_state->m_info.NotifyTxFailed();
1053 bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
1054 if (longMpdu)
1055 {
1056 m_slrc[ac] = 0;
1057 }
1058 else
1059 {
1060 m_ssrc[ac] = 0;
1061 }
1062 m_macTxFinalDataFailed(mpdu->GetHeader().GetAddr1());
1063 DoReportFinalDataFailed(station);
1064}
1065
1066void
1068 RxSignalInfo rxSignalInfo,
1069 WifiTxVector txVector)
1070{
1071 NS_LOG_FUNCTION(this << address << rxSignalInfo << txVector);
1072 if (address.IsGroup())
1073 {
1074 return;
1075 }
1076 WifiRemoteStation* station = Lookup(address);
1077 DoReportRxOk(station, rxSignalInfo.snr, txVector.GetMode(GetStaId(address, txVector)));
1078 station->m_rssiAndUpdateTimePair = std::make_pair(rxSignalInfo.rssi, Simulator::Now());
1079}
1080
1081void
1083 uint16_t nSuccessfulMpdus,
1084 uint16_t nFailedMpdus,
1085 double rxSnr,
1086 double dataSnr,
1087 WifiTxVector dataTxVector)
1088{
1089 NS_LOG_FUNCTION(this << address << nSuccessfulMpdus << nFailedMpdus << rxSnr << dataSnr
1090 << dataTxVector);
1091 NS_ASSERT(!address.IsGroup());
1092 for (uint16_t i = 0; i < nFailedMpdus; i++)
1093 {
1094 m_macTxDataFailed(address);
1095 }
1097 nSuccessfulMpdus,
1098 nFailedMpdus,
1099 rxSnr,
1100 dataSnr,
1101 dataTxVector.GetChannelWidth(),
1102 dataTxVector.GetNss(GetStaId(address, dataTxVector)));
1103}
1104
1105bool
1107{
1108 NS_LOG_FUNCTION(this << header << &txParams);
1109 auto address = header.GetAddr1();
1110 const auto modulationClass = txParams.m_txVector.GetModulationClass();
1111 if (address.IsGroup())
1112 {
1113 return false;
1114 }
1116 ((modulationClass == WIFI_MOD_CLASS_ERP_OFDM) || (modulationClass == WIFI_MOD_CLASS_HT) ||
1117 (modulationClass == WIFI_MOD_CLASS_VHT) || (modulationClass == WIFI_MOD_CLASS_HE) ||
1118 (modulationClass == WIFI_MOD_CLASS_EHT)) &&
1120 {
1122 "WifiRemoteStationManager::NeedRTS returning true to protect non-ERP stations");
1123 return true;
1124 }
1125 else if (m_htProtectionMode == RTS_CTS &&
1126 ((modulationClass == WIFI_MOD_CLASS_HT) || (modulationClass == WIFI_MOD_CLASS_VHT)) &&
1128 {
1129 NS_LOG_DEBUG("WifiRemoteStationManager::NeedRTS returning true to protect non-HT stations");
1130 return true;
1131 }
1132 NS_ASSERT(txParams.m_txDuration.has_value());
1133 auto size = txParams.GetSize(header.GetAddr1());
1134 bool normally =
1137 return DoNeedRts(Lookup(address), size, normally);
1138}
1139
1140bool
1142{
1143 WifiMode mode = txVector.GetMode();
1144 NS_LOG_FUNCTION(this << mode);
1152 {
1154 "WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-ERP stations");
1155 return true;
1156 }
1157 else if (m_htProtectionMode == CTS_TO_SELF &&
1161 {
1163 "WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-HT stations");
1164 return true;
1165 }
1166 else if (!m_useNonErpProtection)
1167 {
1168 // search for the BSS Basic Rate set, if the used mode is in the basic set then there is no
1169 // need for CTS To Self
1170 for (auto i = m_bssBasicRateSet.begin(); i != m_bssBasicRateSet.end(); i++)
1171 {
1172 if (mode == *i)
1173 {
1174 NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning false");
1175 return false;
1176 }
1177 }
1178 if (m_wifiPhy->GetDevice()->GetHtConfiguration())
1179 {
1180 // search for the BSS Basic MCS set, if the used mode is in the basic set then there is
1181 // no need for CTS To Self
1182 for (auto i = m_bssBasicMcsSet.begin(); i != m_bssBasicMcsSet.end(); i++)
1183 {
1184 if (mode == *i)
1185 {
1186 NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning false");
1187 return false;
1188 }
1189 }
1190 }
1191 NS_LOG_DEBUG("WifiRemoteStationManager::NeedCtsToSelf returning true");
1192 return true;
1193 }
1194 return false;
1195}
1196
1197void
1199{
1200 NS_LOG_FUNCTION(this << enable);
1201 m_useNonErpProtection = enable;
1202}
1203
1204bool
1209
1210void
1212{
1213 NS_LOG_FUNCTION(this << enable);
1214 m_useNonHtProtection = enable;
1215}
1216
1217bool
1222
1223bool
1225{
1226 NS_LOG_FUNCTION(this << *mpdu);
1227 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1228 AcIndex ac =
1229 QosUtilsMapTidToAc((mpdu->GetHeader().IsQosData()) ? mpdu->GetHeader().GetQosTid() : 0);
1230 bool longMpdu = (mpdu->GetSize() > m_rtsCtsThreshold);
1231 uint32_t retryCount;
1232 uint32_t maxRetryCount;
1233 if (longMpdu)
1234 {
1235 retryCount = m_slrc[ac];
1236 maxRetryCount = m_maxSlrc;
1237 }
1238 else
1239 {
1240 retryCount = m_ssrc[ac];
1241 maxRetryCount = m_maxSsrc;
1242 }
1243 bool normally = retryCount < maxRetryCount;
1244 NS_LOG_DEBUG("WifiRemoteStationManager::NeedRetransmission count: "
1245 << retryCount << " result: " << std::boolalpha << normally);
1246 return DoNeedRetransmission(Lookup(mpdu->GetHeader().GetAddr1()), mpdu->GetPacket(), normally);
1247}
1248
1249bool
1251{
1252 NS_LOG_FUNCTION(this << *mpdu);
1253 if (mpdu->GetHeader().GetAddr1().IsGroup())
1254 {
1255 return false;
1256 }
1257 bool normally = mpdu->GetSize() > GetFragmentationThreshold();
1258 NS_LOG_DEBUG("WifiRemoteStationManager::NeedFragmentation result: " << std::boolalpha
1259 << normally);
1260 return DoNeedFragmentation(Lookup(mpdu->GetHeader().GetAddr1()), mpdu->GetPacket(), normally);
1261}
1262
1263void
1265{
1266 NS_LOG_FUNCTION(this << threshold);
1267 if (threshold < 256)
1268 {
1269 /*
1270 * ASN.1 encoding of the MAC and PHY MIB (256 ... 8000)
1271 */
1272 NS_LOG_WARN("Fragmentation threshold should be larger than 256. Setting to 256.");
1274 }
1275 else
1276 {
1277 /*
1278 * The length of each fragment shall be an even number of octets, except for the last
1279 * fragment if an MSDU or MMPDU, which may be either an even or an odd number of octets.
1280 */
1281 if (threshold % 2 != 0)
1282 {
1283 NS_LOG_WARN("Fragmentation threshold should be an even number. Setting to "
1284 << threshold - 1);
1285 m_fragmentationThreshold = threshold - 1;
1286 }
1287 else
1288 {
1289 m_fragmentationThreshold = threshold;
1290 }
1291 }
1292}
1293
1299
1302{
1303 NS_LOG_FUNCTION(this << *mpdu);
1304 // The number of bytes a fragment can support is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1305 uint32_t nFragments =
1306 (mpdu->GetPacket()->GetSize() /
1307 (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH));
1308
1309 // If the size of the last fragment is not 0.
1310 if ((mpdu->GetPacket()->GetSize() %
1311 (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH)) > 0)
1312 {
1313 nFragments++;
1314 }
1315 NS_LOG_DEBUG("WifiRemoteStationManager::GetNFragments returning " << nFragments);
1316 return nFragments;
1317}
1318
1321{
1322 NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1323 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1324 uint32_t nFragment = GetNFragments(mpdu);
1325 if (fragmentNumber >= nFragment)
1326 {
1327 NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning 0");
1328 return 0;
1329 }
1330 // Last fragment
1331 if (fragmentNumber == nFragment - 1)
1332 {
1333 uint32_t lastFragmentSize =
1334 mpdu->GetPacket()->GetSize() -
1335 (fragmentNumber *
1336 (GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH));
1337 NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning " << lastFragmentSize);
1338 return lastFragmentSize;
1339 }
1340 // All fragments but the last, the number of bytes is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1341 else
1342 {
1343 uint32_t fragmentSize =
1344 GetFragmentationThreshold() - mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH;
1345 NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentSize returning " << fragmentSize);
1346 return fragmentSize;
1347 }
1348}
1349
1352{
1353 NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1354 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1355 NS_ASSERT(fragmentNumber < GetNFragments(mpdu));
1356 uint32_t fragmentOffset = fragmentNumber * (GetFragmentationThreshold() -
1357 mpdu->GetHeader().GetSize() - WIFI_MAC_FCS_LENGTH);
1358 NS_LOG_DEBUG("WifiRemoteStationManager::GetFragmentOffset returning " << fragmentOffset);
1359 return fragmentOffset;
1360}
1361
1362bool
1364{
1365 NS_LOG_FUNCTION(this << *mpdu << fragmentNumber);
1366 NS_ASSERT(!mpdu->GetHeader().GetAddr1().IsGroup());
1367 bool isLast = fragmentNumber == (GetNFragments(mpdu) - 1);
1368 NS_LOG_DEBUG("WifiRemoteStationManager::IsLastFragment returning " << std::boolalpha << isLast);
1369 return isLast;
1370}
1371
1372uint8_t
1377
1380{
1381 return LookupState(address)->m_info;
1382}
1383
1384std::optional<dBm_u>
1386{
1387 auto station = Lookup(address);
1388 auto rssi = station->m_rssiAndUpdateTimePair.first;
1389 auto ts = station->m_rssiAndUpdateTimePair.second;
1390 if (ts.IsStrictlyPositive())
1391 {
1392 return rssi;
1393 }
1394 return std::nullopt;
1395}
1396
1397std::shared_ptr<WifiRemoteStationState>
1399{
1400 NS_LOG_FUNCTION(this << address);
1401 auto stateIt = m_states.find(address);
1402
1403 if (stateIt != m_states.end())
1404 {
1405 NS_LOG_DEBUG("WifiRemoteStationManager::LookupState returning existing state");
1406 return stateIt->second;
1407 }
1408
1409 auto state = std::make_shared<WifiRemoteStationState>();
1410 state->m_state = WifiRemoteStationState::BRAND_NEW;
1411 state->m_address = address;
1412 state->m_aid = 0;
1413 state->m_operationalRateSet.push_back(GetDefaultMode());
1414 state->m_operationalMcsSet.push_back(GetDefaultMcs());
1415 state->m_dsssSupported = false;
1416 state->m_erpOfdmSupported = false;
1417 state->m_ofdmSupported = false;
1418 state->m_htCapabilities = nullptr;
1419 state->m_vhtCapabilities = nullptr;
1420 state->m_heCapabilities = nullptr;
1421 state->m_ehtCapabilities = nullptr;
1422 state->m_mleCommonInfo = nullptr;
1423 state->m_emlsrEnabled = false;
1424 state->m_channelWidth = m_wifiPhy->GetChannelWidth();
1425 state->m_guardInterval = GetGuardInterval();
1426 state->m_ness = 0;
1427 state->m_aggregation = false;
1428 state->m_qosSupported = false;
1429 state->m_isInPsMode = false;
1430 const_cast<WifiRemoteStationManager*>(this)->m_states.insert({address, state});
1431 NS_LOG_DEBUG("WifiRemoteStationManager::LookupState returning new state");
1432 return state;
1433}
1434
1435WifiRemoteStation*
1436WifiRemoteStationManager::Lookup(Mac48Address address) const
1437{
1438 NS_LOG_FUNCTION(this << address);
1439 NS_ASSERT(!address.IsGroup());
1440 NS_ASSERT(address != m_wifiMac->GetAddress());
1441 auto stationIt = m_stations.find(address);
1442
1443 if (stationIt != m_stations.end())
1444 {
1445 return stationIt->second;
1446 }
1447
1448 WifiRemoteStation* station = DoCreateStation();
1449 station->m_state = LookupState(address).get();
1450 station->m_rssiAndUpdateTimePair = std::make_pair(0, Seconds(0));
1451 const_cast<WifiRemoteStationManager*>(this)->m_stations.insert({address, station});
1452 return station;
1453}
1454
1455void
1456WifiRemoteStationManager::SetAssociationId(Mac48Address remoteAddress, uint16_t aid)
1457{
1458 NS_LOG_FUNCTION(this << remoteAddress << aid);
1459 LookupState(remoteAddress)->m_aid = aid;
1460}
1461
1462void
1463WifiRemoteStationManager::SetQosSupport(Mac48Address from, bool qosSupported)
1464{
1465 NS_LOG_FUNCTION(this << from << qosSupported);
1466 LookupState(from)->m_qosSupported = qosSupported;
1467}
1468
1469void
1470WifiRemoteStationManager::SetEmlsrEnabled(const Mac48Address& from, bool emlsrEnabled)
1471{
1472 NS_LOG_FUNCTION(this << from << emlsrEnabled);
1473 LookupState(from)->m_emlsrEnabled = emlsrEnabled;
1474}
1475
1476void
1477WifiRemoteStationManager::AddStationHtCapabilities(Mac48Address from, HtCapabilities htCapabilities)
1478{
1479 // Used by all stations to record HT capabilities of remote stations
1480 NS_LOG_FUNCTION(this << from << htCapabilities);
1481 auto state = LookupState(from);
1482 if (htCapabilities.GetSupportedChannelWidth() == 1)
1483 {
1484 state->m_channelWidth = 40;
1485 }
1486 else
1487 {
1488 state->m_channelWidth = 20;
1489 }
1490 SetQosSupport(from, true);
1491 for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_HT))
1492 {
1493 if (htCapabilities.IsSupportedMcs(mcs.GetMcsValue()))
1494 {
1495 AddSupportedMcs(from, mcs);
1496 }
1497 }
1498 state->m_htCapabilities = Create<const HtCapabilities>(htCapabilities);
1499}
1500
1501void
1502WifiRemoteStationManager::AddStationVhtCapabilities(Mac48Address from,
1503 VhtCapabilities vhtCapabilities)
1504{
1505 // Used by all stations to record VHT capabilities of remote stations
1506 NS_LOG_FUNCTION(this << from << vhtCapabilities);
1507 auto state = LookupState(from);
1508 if (vhtCapabilities.GetSupportedChannelWidthSet() == 1)
1509 {
1510 state->m_channelWidth = 160;
1511 }
1512 else
1513 {
1514 state->m_channelWidth = 80;
1515 }
1516 for (uint8_t i = 1; i <= m_wifiPhy->GetMaxSupportedTxSpatialStreams(); i++)
1517 {
1518 for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_VHT))
1519 {
1520 if (vhtCapabilities.IsSupportedMcs(mcs.GetMcsValue(), i))
1521 {
1522 AddSupportedMcs(from, mcs);
1523 }
1524 }
1525 }
1526 state->m_vhtCapabilities = Create<const VhtCapabilities>(vhtCapabilities);
1527}
1528
1529void
1530WifiRemoteStationManager::AddStationHeCapabilities(Mac48Address from, HeCapabilities heCapabilities)
1531{
1532 // Used by all stations to record HE capabilities of remote stations
1533 NS_LOG_FUNCTION(this << from << heCapabilities);
1534 auto state = LookupState(from);
1535 if ((m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) ||
1536 (m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_6GHZ))
1537 {
1538 if (heCapabilities.GetChannelWidthSet() & 0x04)
1539 {
1540 state->m_channelWidth = 160;
1541 }
1542 else if (heCapabilities.GetChannelWidthSet() & 0x02)
1543 {
1544 state->m_channelWidth = 80;
1545 }
1546 // For other cases at 5 GHz, the supported channel width is set by the VHT capabilities
1547 }
1548 else if (m_wifiPhy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ)
1549 {
1550 if (heCapabilities.GetChannelWidthSet() & 0x01)
1551 {
1552 state->m_channelWidth = 40;
1553 }
1554 else
1555 {
1556 state->m_channelWidth = 20;
1557 }
1558 }
1559 if (heCapabilities.GetHeSuPpdu1xHeLtf800nsGi())
1560 {
1561 state->m_guardInterval = NanoSeconds(800);
1562 }
1563 else
1564 {
1565 // todo: Using 3200ns, default value for HeConfiguration::GuardInterval
1566 state->m_guardInterval = NanoSeconds(3200);
1567 }
1568 for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_HE))
1569 {
1570 if (heCapabilities.GetHighestMcsSupported() >= mcs.GetMcsValue())
1571 {
1572 AddSupportedMcs(from, mcs);
1573 }
1574 }
1575 state->m_heCapabilities = Create<const HeCapabilities>(heCapabilities);
1576 SetQosSupport(from, true);
1577}
1578
1579void
1580WifiRemoteStationManager::AddStationHe6GhzCapabilities(
1581 const Mac48Address& from,
1582 const He6GhzBandCapabilities& he6GhzCapabilities)
1583{
1584 // Used by all stations to record HE 6GHz band capabilities of remote stations
1585 NS_LOG_FUNCTION(this << from << he6GhzCapabilities);
1586 auto state = LookupState(from);
1587 state->m_he6GhzBandCapabilities = Create<const He6GhzBandCapabilities>(he6GhzCapabilities);
1588 SetQosSupport(from, true);
1589}
1590
1591void
1592WifiRemoteStationManager::AddStationEhtCapabilities(Mac48Address from,
1593 EhtCapabilities ehtCapabilities)
1594{
1595 // Used by all stations to record EHT capabilities of remote stations
1596 NS_LOG_FUNCTION(this << from << ehtCapabilities);
1597 auto state = LookupState(from);
1598 for (const auto& mcs : m_wifiPhy->GetMcsList(WIFI_MOD_CLASS_EHT))
1599 {
1600 for (uint8_t mapType = 0; mapType < EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_MAX; ++mapType)
1601 {
1602 if (ehtCapabilities.GetHighestSupportedRxMcs(
1603 static_cast<EhtMcsAndNssSet::EhtMcsMapType>(mapType)) >= mcs.GetMcsValue())
1604 {
1605 AddSupportedMcs(from, mcs);
1606 }
1607 }
1608 }
1609 state->m_ehtCapabilities = Create<const EhtCapabilities>(ehtCapabilities);
1610 SetQosSupport(from, true);
1611}
1612
1613void
1614WifiRemoteStationManager::AddStationMleCommonInfo(
1615 Mac48Address from,
1616 const std::shared_ptr<CommonInfoBasicMle>& mleCommonInfo)
1617{
1618 NS_LOG_FUNCTION(this << from);
1619 auto state = LookupState(from);
1620 state->m_mleCommonInfo = mleCommonInfo;
1621 // insert another entry in m_states indexed by the MLD address and pointing to the same state
1622 const_cast<WifiRemoteStationManager*>(this)->m_states.insert(
1623 {mleCommonInfo->m_mldMacAddress, state});
1624}
1625
1626Ptr<const HtCapabilities>
1627WifiRemoteStationManager::GetStationHtCapabilities(Mac48Address from)
1628{
1629 return LookupState(from)->m_htCapabilities;
1630}
1631
1633WifiRemoteStationManager::GetStationVhtCapabilities(Mac48Address from)
1634{
1635 return LookupState(from)->m_vhtCapabilities;
1636}
1637
1639WifiRemoteStationManager::GetStationHeCapabilities(Mac48Address from)
1640{
1641 return LookupState(from)->m_heCapabilities;
1642}
1643
1645WifiRemoteStationManager::GetStationHe6GhzCapabilities(const Mac48Address& from) const
1646{
1647 return LookupState(from)->m_he6GhzBandCapabilities;
1648}
1649
1651WifiRemoteStationManager::GetStationEhtCapabilities(Mac48Address from)
1652{
1653 return LookupState(from)->m_ehtCapabilities;
1654}
1655
1656std::optional<std::reference_wrapper<CommonInfoBasicMle::EmlCapabilities>>
1657WifiRemoteStationManager::GetStationEmlCapabilities(const Mac48Address& from)
1658{
1659 if (auto state = LookupState(from);
1660 state->m_mleCommonInfo && state->m_mleCommonInfo->m_emlCapabilities)
1661 {
1662 return state->m_mleCommonInfo->m_emlCapabilities.value();
1663 }
1664 return std::nullopt;
1665}
1666
1667std::optional<std::reference_wrapper<CommonInfoBasicMle::MldCapabilities>>
1668WifiRemoteStationManager::GetStationMldCapabilities(const Mac48Address& from)
1669{
1670 if (auto state = LookupState(from);
1671 state->m_mleCommonInfo && state->m_mleCommonInfo->m_mldCapabilities)
1672 {
1673 return state->m_mleCommonInfo->m_mldCapabilities.value();
1674 }
1675 return std::nullopt;
1676}
1677
1678bool
1679WifiRemoteStationManager::GetLdpcSupported(Mac48Address address) const
1680{
1681 Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
1682 Ptr<const VhtCapabilities> vhtCapabilities = LookupState(address)->m_vhtCapabilities;
1683 Ptr<const HeCapabilities> heCapabilities = LookupState(address)->m_heCapabilities;
1684 bool supported = false;
1685 if (htCapabilities)
1686 {
1687 supported |= htCapabilities->GetLdpc();
1688 }
1689 if (vhtCapabilities)
1690 {
1691 supported |= vhtCapabilities->GetRxLdpc();
1692 }
1693 if (heCapabilities)
1694 {
1695 supported |= heCapabilities->GetLdpcCodingInPayload();
1696 }
1697 return supported;
1698}
1699
1701WifiRemoteStationManager::GetDefaultMode() const
1702{
1703 NS_ASSERT(m_wifiPhy);
1704 auto defaultTxMode = m_wifiPhy->GetDefaultMode();
1705 NS_ASSERT(defaultTxMode.IsMandatory());
1706 return defaultTxMode;
1707}
1708
1710WifiRemoteStationManager::GetDefaultMcs() const
1711{
1712 return HtPhy::GetHtMcs0();
1713}
1714
1716WifiRemoteStationManager::GetDefaultModeForSta(const WifiRemoteStation* st) const
1717{
1718 NS_LOG_FUNCTION(this << st);
1719
1720 if ((!m_wifiPhy->GetDevice()->GetHtConfiguration()) ||
1721 (!GetHtSupported(st) && !GetStationHe6GhzCapabilities(st->m_state->m_address)))
1722 {
1723 return GetDefaultMode();
1724 }
1725
1726 // find the highest modulation class supported by both stations
1728 if (GetHeSupported() && GetHeSupported(st))
1729 {
1730 modClass = WIFI_MOD_CLASS_HE;
1731 }
1732 else if (GetVhtSupported() && GetVhtSupported(st))
1733 {
1734 modClass = WIFI_MOD_CLASS_VHT;
1735 }
1736
1737 // return the MCS with lowest index
1738 return *m_wifiPhy->GetPhyEntity(modClass)->begin();
1739}
1740
1741void
1742WifiRemoteStationManager::Reset()
1743{
1744 NS_LOG_FUNCTION(this);
1745 m_states.clear();
1746 for (auto& state : m_stations)
1747 {
1748 delete (state.second);
1749 }
1750 m_stations.clear();
1751 m_bssBasicRateSet.clear();
1752 m_bssBasicMcsSet.clear();
1753 m_ssrc.fill(0);
1754 m_slrc.fill(0);
1755}
1756
1757void
1758WifiRemoteStationManager::AddBasicMode(WifiMode mode)
1759{
1760 NS_LOG_FUNCTION(this << mode);
1762 {
1763 NS_FATAL_ERROR("It is not allowed to add a HT rate in the BSSBasicRateSet!");
1764 }
1765 for (uint8_t i = 0; i < GetNBasicModes(); i++)
1766 {
1767 if (GetBasicMode(i) == mode)
1768 {
1769 return;
1770 }
1771 }
1772 m_bssBasicRateSet.push_back(mode);
1773}
1774
1775uint8_t
1776WifiRemoteStationManager::GetNBasicModes() const
1777{
1778 return static_cast<uint8_t>(m_bssBasicRateSet.size());
1779}
1780
1782WifiRemoteStationManager::GetBasicMode(uint8_t i) const
1783{
1784 NS_ASSERT(i < GetNBasicModes());
1785 return m_bssBasicRateSet[i];
1786}
1787
1789WifiRemoteStationManager::GetNNonErpBasicModes() const
1790{
1791 uint32_t size = 0;
1792 for (auto i = m_bssBasicRateSet.begin(); i != m_bssBasicRateSet.end(); i++)
1793 {
1794 if (i->GetModulationClass() == WIFI_MOD_CLASS_ERP_OFDM)
1795 {
1796 continue;
1797 }
1798 size++;
1799 }
1800 return size;
1801}
1802
1804WifiRemoteStationManager::GetNonErpBasicMode(uint8_t i) const
1805{
1806 NS_ASSERT(i < GetNNonErpBasicModes());
1807 uint32_t index = 0;
1808 bool found = false;
1809 for (auto j = m_bssBasicRateSet.begin(); j != m_bssBasicRateSet.end();)
1810 {
1811 if (i == index)
1812 {
1813 found = true;
1814 }
1815 if (j->GetModulationClass() != WIFI_MOD_CLASS_ERP_OFDM)
1816 {
1817 if (found)
1818 {
1819 break;
1820 }
1821 }
1822 index++;
1823 j++;
1824 }
1825 return m_bssBasicRateSet[index];
1826}
1827
1828void
1829WifiRemoteStationManager::AddBasicMcs(WifiMode mcs)
1830{
1831 NS_LOG_FUNCTION(this << +mcs.GetMcsValue());
1832 for (uint8_t i = 0; i < GetNBasicMcs(); i++)
1833 {
1834 if (GetBasicMcs(i) == mcs)
1835 {
1836 return;
1837 }
1838 }
1839 m_bssBasicMcsSet.push_back(mcs);
1840}
1841
1842uint8_t
1843WifiRemoteStationManager::GetNBasicMcs() const
1844{
1845 return static_cast<uint8_t>(m_bssBasicMcsSet.size());
1846}
1847
1849WifiRemoteStationManager::GetBasicMcs(uint8_t i) const
1850{
1851 NS_ASSERT(i < GetNBasicMcs());
1852 return m_bssBasicMcsSet[i];
1853}
1854
1856WifiRemoteStationManager::GetNonUnicastMode() const
1857{
1858 if (m_nonUnicastMode == WifiMode())
1859 {
1860 if (GetNBasicModes() > 0)
1861 {
1862 return GetBasicMode(0);
1863 }
1864 else
1865 {
1866 return GetDefaultMode();
1867 }
1868 }
1869 else
1870 {
1871 return m_nonUnicastMode;
1872 }
1873}
1874
1875bool
1876WifiRemoteStationManager::DoNeedRts(WifiRemoteStation* station, uint32_t size, bool normally)
1877{
1878 return normally;
1879}
1880
1881bool
1882WifiRemoteStationManager::DoNeedRetransmission(WifiRemoteStation* station,
1883 Ptr<const Packet> packet,
1884 bool normally)
1885{
1886 return normally;
1887}
1888
1889bool
1890WifiRemoteStationManager::DoNeedFragmentation(WifiRemoteStation* station,
1891 Ptr<const Packet> packet,
1892 bool normally)
1893{
1894 return normally;
1895}
1896
1897void
1898WifiRemoteStationManager::DoReportAmpduTxStatus(WifiRemoteStation* station,
1899 uint16_t nSuccessfulMpdus,
1900 uint16_t nFailedMpdus,
1901 double rxSnr,
1902 double dataSnr,
1903 MHz_u dataChannelWidth,
1904 uint8_t dataNss)
1905{
1906 NS_LOG_DEBUG("DoReportAmpduTxStatus received but the manager does not handle A-MPDUs!");
1907}
1908
1910WifiRemoteStationManager::GetSupported(const WifiRemoteStation* station, uint8_t i) const
1911{
1912 NS_ASSERT(i < GetNSupported(station));
1913 return station->m_state->m_operationalRateSet[i];
1914}
1915
1917WifiRemoteStationManager::GetMcsSupported(const WifiRemoteStation* station, uint8_t i) const
1918{
1919 NS_ASSERT(i < GetNMcsSupported(station));
1920 return station->m_state->m_operationalMcsSet[i];
1921}
1922
1924WifiRemoteStationManager::GetNonErpSupported(const WifiRemoteStation* station, uint8_t i) const
1925{
1926 NS_ASSERT(i < GetNNonErpSupported(station));
1927 // IEEE 802.11g standard defines that if the protection mechanism is enabled, RTS, CTS and
1928 // CTS-To-Self frames should select a rate in the BSSBasicRateSet that corresponds to an 802.11b
1929 // basic rate. This is a implemented here to avoid changes in every RAA, but should maybe be
1930 // moved in case it breaks standard rules.
1931 uint32_t index = 0;
1932 bool found = false;
1933 for (auto j = station->m_state->m_operationalRateSet.begin();
1934 j != station->m_state->m_operationalRateSet.end();)
1935 {
1936 if (i == index)
1937 {
1938 found = true;
1939 }
1940 if (j->GetModulationClass() != WIFI_MOD_CLASS_ERP_OFDM)
1941 {
1942 if (found)
1943 {
1944 break;
1945 }
1946 }
1947 index++;
1948 j++;
1949 }
1950 return station->m_state->m_operationalRateSet[index];
1951}
1952
1954WifiRemoteStationManager::GetAddress(const WifiRemoteStation* station) const
1955{
1956 return station->m_state->m_address;
1957}
1958
1959MHz_u
1960WifiRemoteStationManager::GetChannelWidth(const WifiRemoteStation* station) const
1961{
1962 return station->m_state->m_channelWidth;
1963}
1964
1965bool
1966WifiRemoteStationManager::GetShortGuardIntervalSupported(const WifiRemoteStation* station) const
1967{
1968 Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1969
1970 if (!htCapabilities)
1971 {
1972 return false;
1973 }
1974 return htCapabilities->GetShortGuardInterval20();
1975}
1976
1977Time
1978WifiRemoteStationManager::GetGuardInterval(const WifiRemoteStation* station) const
1979{
1980 return station->m_state->m_guardInterval;
1981}
1982
1983bool
1984WifiRemoteStationManager::GetAggregation(const WifiRemoteStation* station) const
1985{
1986 return station->m_state->m_aggregation;
1987}
1988
1989uint8_t
1990WifiRemoteStationManager::GetNumberOfSupportedStreams(const WifiRemoteStation* station) const
1991{
1992 const auto htCapabilities = station->m_state->m_htCapabilities;
1993
1994 if (!htCapabilities)
1995 {
1996 if (const auto heCapabilities = station->m_state->m_heCapabilities)
1997 {
1998 return heCapabilities->GetHighestNssSupported();
1999 }
2000 return 1;
2001 }
2002 return htCapabilities->GetRxHighestSupportedAntennas();
2003}
2004
2005uint8_t
2006WifiRemoteStationManager::GetNess(const WifiRemoteStation* station) const
2007{
2008 return station->m_state->m_ness;
2009}
2010
2012WifiRemoteStationManager::GetPhy() const
2013{
2014 return m_wifiPhy;
2015}
2016
2018WifiRemoteStationManager::GetMac() const
2019{
2020 return m_wifiMac;
2021}
2022
2023uint8_t
2024WifiRemoteStationManager::GetNSupported(const WifiRemoteStation* station) const
2025{
2026 return static_cast<uint8_t>(station->m_state->m_operationalRateSet.size());
2027}
2028
2029bool
2030WifiRemoteStationManager::GetQosSupported(const WifiRemoteStation* station) const
2031{
2032 return station->m_state->m_qosSupported;
2033}
2034
2035bool
2036WifiRemoteStationManager::GetHtSupported(const WifiRemoteStation* station) const
2037{
2038 return bool(station->m_state->m_htCapabilities);
2039}
2040
2041bool
2042WifiRemoteStationManager::GetVhtSupported(const WifiRemoteStation* station) const
2043{
2044 return bool(station->m_state->m_vhtCapabilities);
2045}
2046
2047bool
2048WifiRemoteStationManager::GetHeSupported(const WifiRemoteStation* station) const
2049{
2050 return bool(station->m_state->m_heCapabilities);
2051}
2052
2053bool
2054WifiRemoteStationManager::GetEhtSupported(const WifiRemoteStation* station) const
2055{
2056 return (bool)(station->m_state->m_ehtCapabilities);
2057}
2058
2059bool
2060WifiRemoteStationManager::GetEmlsrSupported(const WifiRemoteStation* station) const
2061{
2062 auto mleCommonInfo = station->m_state->m_mleCommonInfo;
2063 return mleCommonInfo && mleCommonInfo->m_emlCapabilities &&
2064 mleCommonInfo->m_emlCapabilities->emlsrSupport == 1;
2065}
2066
2067bool
2068WifiRemoteStationManager::GetEmlsrEnabled(const WifiRemoteStation* station) const
2069{
2070 return station->m_state->m_emlsrEnabled;
2071}
2072
2073uint8_t
2074WifiRemoteStationManager::GetNMcsSupported(const WifiRemoteStation* station) const
2075{
2076 return static_cast<uint8_t>(station->m_state->m_operationalMcsSet.size());
2077}
2078
2080WifiRemoteStationManager::GetNNonErpSupported(const WifiRemoteStation* station) const
2081{
2082 uint32_t size = 0;
2083 for (auto i = station->m_state->m_operationalRateSet.begin();
2084 i != station->m_state->m_operationalRateSet.end();
2085 i++)
2086 {
2087 if (i->GetModulationClass() == WIFI_MOD_CLASS_ERP_OFDM)
2088 {
2089 continue;
2090 }
2091 size++;
2092 }
2093 return size;
2094}
2095
2096MHz_u
2097WifiRemoteStationManager::GetChannelWidthSupported(Mac48Address address) const
2098{
2099 return LookupState(address)->m_channelWidth;
2100}
2101
2102bool
2103WifiRemoteStationManager::GetShortGuardIntervalSupported(Mac48Address address) const
2104{
2105 Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
2106
2107 if (!htCapabilities)
2108 {
2109 return false;
2110 }
2111 return htCapabilities->GetShortGuardInterval20();
2112}
2113
2114uint8_t
2115WifiRemoteStationManager::GetNumberOfSupportedStreams(Mac48Address address) const
2116{
2117 Ptr<const HtCapabilities> htCapabilities = LookupState(address)->m_htCapabilities;
2118
2119 if (!htCapabilities)
2120 {
2121 return 1;
2122 }
2123 return htCapabilities->GetRxHighestSupportedAntennas();
2124}
2125
2126uint8_t
2127WifiRemoteStationManager::GetNMcsSupported(Mac48Address address) const
2128{
2129 return static_cast<uint8_t>(LookupState(address)->m_operationalMcsSet.size());
2130}
2131
2132bool
2133WifiRemoteStationManager::GetDsssSupported(const Mac48Address& address) const
2134{
2135 return (LookupState(address)->m_dsssSupported);
2136}
2137
2138bool
2139WifiRemoteStationManager::GetErpOfdmSupported(const Mac48Address& address) const
2140{
2141 return (LookupState(address)->m_erpOfdmSupported);
2142}
2143
2144bool
2145WifiRemoteStationManager::GetOfdmSupported(const Mac48Address& address) const
2146{
2147 return (LookupState(address)->m_ofdmSupported);
2148}
2149
2150bool
2151WifiRemoteStationManager::GetHtSupported(Mac48Address address) const
2152{
2153 return bool(LookupState(address)->m_htCapabilities);
2154}
2155
2156bool
2157WifiRemoteStationManager::GetVhtSupported(Mac48Address address) const
2158{
2159 return bool(LookupState(address)->m_vhtCapabilities);
2160}
2161
2162bool
2163WifiRemoteStationManager::GetHeSupported(Mac48Address address) const
2164{
2165 return bool(LookupState(address)->m_heCapabilities);
2166}
2167
2168bool
2169WifiRemoteStationManager::GetEhtSupported(Mac48Address address) const
2170{
2171 return (bool)(LookupState(address)->m_ehtCapabilities);
2172}
2173
2174bool
2175WifiRemoteStationManager::GetEmlsrSupported(const Mac48Address& address) const
2176{
2177 auto mleCommonInfo = LookupState(address)->m_mleCommonInfo;
2178 return mleCommonInfo && mleCommonInfo->m_emlCapabilities &&
2179 mleCommonInfo->m_emlCapabilities->emlsrSupport == 1;
2180}
2181
2182bool
2183WifiRemoteStationManager::GetEmlsrEnabled(const Mac48Address& address) const
2184{
2185 if (auto stateIt = m_states.find(address); stateIt != m_states.cend())
2186 {
2187 return stateIt->second->m_emlsrEnabled;
2188 }
2189 return false;
2190}
2191
2192void
2193WifiRemoteStationManager::SetDefaultTxPowerLevel(uint8_t txPower)
2194{
2195 m_defaultTxPowerLevel = txPower;
2196}
2197
2198uint8_t
2199WifiRemoteStationManager::GetNumberOfAntennas() const
2200{
2201 return m_wifiPhy->GetNumberOfAntennas();
2202}
2203
2204uint8_t
2205WifiRemoteStationManager::GetMaxNumberOfTransmitStreams() const
2206{
2207 return m_wifiPhy->GetMaxSupportedTxSpatialStreams();
2208}
2209
2210bool
2211WifiRemoteStationManager::UseLdpcForDestination(Mac48Address dest) const
2212{
2213 return (GetLdpcSupported() && GetLdpcSupported(dest));
2214}
2215
2216} // 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:52
static WifiMode GetErpOfdmRate(uint64_t rate)
Return a WifiMode for ERP-OFDM corresponding to the provided rate.
static WifiMode GetErpOfdmRate6Mbps()
Return a WifiMode for ERP-OFDM at 6 Mbps.
The HE 6 GHz Band Capabilities (IEEE 802.11ax-2021 9.4.2.263)
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.
an EUI-48 address
bool IsGroup() const
A base class which provides memory management and object aggregation.
Definition object.h:78
static WifiMode GetOfdmRate(uint64_t rate, MHz_u bw=20)
Return a WifiMode for OFDM corresponding to the provided rate and the channel bandwidth (20,...
Definition ofdm-phy.cc:404
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition nstime.h:340
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
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.
represent a single transmission mode
Definition wifi-mode.h:40
bool IsHigherDataRate(WifiMode mode) const
Definition wifi-mode.cc:197
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:174
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:111
uint8_t GetMcsValue() const
Definition wifi-mode.cc:152
MHz_u GetTxBandwidth(WifiMode mode, MHz_u maxAllowedBandWidth=std::numeric_limits< MHz_u >::max()) const
Get the bandwidth for a transmission occurring on the current operating channel and using the given W...
Definition wifi-phy.cc:1117
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition wifi-phy.cc:1063
MHz_u GetChannelWidth() const
Definition wifi-phy.cc:1093
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition wifi-phy.cc:641
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:2098
std::list< WifiMode > GetModeList() const
The WifiPhy::GetModeList() method is used (e.g., by a WifiRemoteStationManager) to determine the set ...
Definition wifi-phy.cc:2049
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.
void ReportDataFailed(Ptr< const WifiMpdu > mpdu)
Should be invoked whenever the AckTimeout associated to a transmission attempt expires.
bool GetQosSupported(Mac48Address address) const
Return whether the given station is QoS capable.
virtual WifiTxVector DoGetDataTxVector(WifiRemoteStation *station, MHz_u allowedWidth)=0
WifiTxVector GetAckTxVector(Mac48Address to, const WifiTxVector &dataTxVector) const
Return a TXVECTOR for the Ack frame given the destination and the mode of the Data used by the sender...
virtual bool DoNeedFragmentation(WifiRemoteStation *station, Ptr< const Packet > packet, bool normally)
uint32_t m_fragmentationThreshold
Current threshold for fragmentation.
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.
uint32_t GetNFragments(Ptr< const WifiMpdu > mpdu)
Return the number of fragments needed for the given packet.
uint16_t GetAssociationId(Mac48Address remoteAddress) const
Get the AID of a remote station.
ProtectionMode m_htProtectionMode
Protection mode for HT stations when non-HT stations are detected.
void AdjustTxVectorForIcf(WifiTxVector &txVector) const
Adjust the TXVECTOR for an initial Control frame to ensure that the modulation class is non-HT and th...
std::array< uint32_t, AC_BE_NQOS > m_slrc
long retry count per AC
WifiRemoteStation * Lookup(Mac48Address address) const
Return the station associated with the given address.
uint32_t GetFragmentationThreshold() const
Return the fragmentation threshold.
bool NeedRetransmission(Ptr< const WifiMpdu > mpdu)
uint8_t GetNBasicModes() const
Return the number of basic modes we support.
bool UseLdpcForDestination(Mac48Address dest) const
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.
virtual bool DoNeedRts(WifiRemoteStation *station, uint32_t size, bool normally)
Time GetGuardInterval() const
Return the supported HE guard interval duration.
WifiTxVector GetRtsTxVector(Mac48Address address, MHz_u allowedWidth)
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.
virtual void DoReportFinalDataFailed(WifiRemoteStation *station)=0
This method is a pure virtual method that must be implemented by the sub-class.
virtual void DoReportRtsOk(WifiRemoteStation *station, double ctsSnr, WifiMode ctsMode, double rtsSnr)=0
This method is a pure virtual method that must be implemented by the sub-class.
Time m_rtsCtsTxDurationThresh
TX duration threshold for RTS/CTS.
bool GetShortSlotTimeEnabled() const
Return whether the device uses short slot time.
void DoDispose() override
Destructor implementation.
virtual void DoReportDataFailed(WifiRemoteStation *station)=0
This method is a pure virtual method that must be implemented by the sub-class.
bool IsLastFragment(Ptr< const WifiMpdu > mpdu, uint32_t fragmentNumber)
void ReportFinalDataFailed(Ptr< const WifiMpdu > mpdu)
Should be invoked after calling ReportDataFailed if NeedRetransmission returns false.
void SetUseNonErpProtection(bool enable)
Enable or disable protection for non-ERP stations.
bool m_useNonHtProtection
flag if protection for non-HT stations against HT transmissions is enabled
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...
virtual void DoReportAmpduTxStatus(WifiRemoteStation *station, uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus, double rxSnr, double dataSnr, MHz_u dataChannelWidth, uint8_t dataNss)
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
std::optional< Mac48Address > GetAffiliatedStaAddress(const Mac48Address &mldAddress) const
Get the address of the remote station operating on this link and affiliated with the MLD having the g...
WifiTxVector GetDataTxVector(const WifiMacHeader &header, MHz_u allowedWidth)
std::optional< dBm_u > GetMostRecentRssi(Mac48Address address) const
void ReportRtsOk(const WifiMacHeader &header, double ctsSnr, WifiMode ctsMode, double rtsSnr)
Should be invoked whenever we receive the CTS associated to an RTS we just sent.
void AddSupportedMcs(Mac48Address address, WifiMode mcs)
Record the MCS index supported by the station.
WifiTxVector GetBlockAckTxVector(Mac48Address to, const WifiTxVector &dataTxVector) const
Return a TXVECTOR for the BlockAck frame given the destination and the mode of the Data used by the s...
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.
WifiMode GetNonUnicastMode() const
Return a mode for non-unicast packets.
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.
WifiMode GetDefaultMcs() const
Return the default Modulation and Coding Scheme (MCS) index.
Ptr< WifiPhy > m_wifiPhy
This is a pointer to the WifiPhy associated with this WifiRemoteStationManager that is set on call to...
void ReportRxOk(Mac48Address address, RxSignalInfo rxSignalInfo, WifiTxVector txVector)
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.
void SetUseNonHtProtection(bool enable)
Enable or disable protection for non-HT stations.
MHz_u GetChannelWidthSupported(Mac48Address address) const
Return the channel width supported by the station.
bool IsAssociated(Mac48Address address) const
Return whether the station associated.
bool NeedFragmentation(Ptr< const WifiMpdu > mpdu)
void ReportAmpduTxStatus(Mac48Address address, uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus, double rxSnr, double dataSnr, WifiTxVector dataTxVector)
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
uint32_t GetFragmentOffset(Ptr< const WifiMpdu > mpdu, uint32_t fragmentNumber)
WifiRemoteStationInfo GetInfo(Mac48Address address)
uint32_t GetFragmentSize(Ptr< const WifiMpdu > mpdu, uint32_t fragmentNumber)
WifiTxVector GetCtsToSelfTxVector()
Since CTS-to-self parameters are not dependent on the station, it is implemented in wifi remote stati...
uint8_t GetNBasicMcs() const
Return the number of basic MCS index.
bool GetHtSupported() const
Return whether the device has HT capability support enabled on the link this manager is associated wi...
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 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.
std::array< uint32_t, AC_BE_NQOS > m_ssrc
short retry count per AC
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.
void ReportFinalRtsFailed(const WifiMacHeader &header)
Should be invoked after calling ReportRtsFailed if NeedRetransmission returns false.
StationStates m_states
States of known stations.
bool NeedCtsToSelf(WifiTxVector txVector)
Return if we need to do CTS-to-self before sending a DATA.
WifiTxVector GetCtsTxVector(Mac48Address to, WifiMode rtsTxMode) const
Return a TXVECTOR for the CTS frame given the destination and the mode of the RTS used by the sender.
void SetMaxSsrc(uint32_t maxSsrc)
Sets the maximum STA short retry count (SSRC).
WifiMode GetBasicMcs(uint8_t i) const
Return the MCS at the given list index.
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...
virtual void DoReportDataOk(WifiRemoteStation *station, double ackSnr, WifiMode ackMode, double dataSnr, MHz_u dataChannelWidth, uint8_t dataNss)=0
This method is a pure virtual method that must be implemented by the sub-class.
WifiMode GetBasicMode(uint8_t i) const
Return a basic mode from the set of basic modes.
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...
virtual void DoReportRtsFailed(WifiRemoteStation *station)=0
This method is a pure virtual method that must be implemented by the sub-class.
void RecordDisassociated(Mac48Address address)
Records that the STA was disassociated.
virtual WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station)=0
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 GetUseNonErpProtection() const
Return whether the device supports protection of non-ERP stations.
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 on the link this manager is associated w...
ProtectionMode m_erpProtectionMode
Protection mode for ERP stations when non-ERP stations are detected.
WifiModeList m_bssBasicRateSet
This member is the list of WifiMode objects that comprise the BSSBasicRateSet parameter.
void ReportDataOk(Ptr< const WifiMpdu > mpdu, double ackSnr, WifiMode ackMode, double dataSnr, WifiTxVector dataTxVector)
Should be invoked whenever we receive the ACK associated to a data packet we just sent.
void ReportRtsFailed(const WifiMacHeader &header)
Should be invoked whenever the RtsTimeout associated to a transmission attempt expires.
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.
virtual void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode)=0
This method is a pure virtual method that must be implemented by the sub-class.
virtual bool DoNeedRetransmission(WifiRemoteStation *station, Ptr< const Packet > packet, bool normally)
WifiMode GetDefaultMode() const
Return the default transmission mode.
void RecordGotAssocTxFailed(Mac48Address address)
Records that we missed an ACK for the association response we sent.
std::optional< Mac48Address > GetMldAddress(const Mac48Address &address) const
Get the address of the MLD the given station is affiliated with, if any.
virtual void DoReportFinalRtsFailed(WifiRemoteStation *station)=0
This method is a pure virtual method that must be implemented by the sub-class.
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...
bool NeedRts(const WifiMacHeader &header, const WifiTxParameters &txParams)
uint32_t m_rtsCtsThreshold
Threshold for RTS/CTS.
bool m_useNonErpProtection
flag if protection for non-ERP stations against ERP transmissions is enabled
WifiMode GetControlAnswerMode(WifiMode reqMode) const
Get control answer mode function.
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...
bool GetUseNonHtProtection() const
Return whether the device supports protection of non-HT stations.
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
std::optional< Time > m_txDuration
TX duration of the frame.
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
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 SetGuardInterval(Time 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.
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
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.
MHz_u GetChannelWidth() const
void SetBssColor(uint8_t color)
Set the BSS color.
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
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:55
#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:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition qos-utils.cc:123
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:62
@ STA
Definition wifi-mac.h:58
@ AP
Definition wifi-mac.h:59
@ 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.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ 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.
Ptr< const AttributeAccessor > MakeWifiModeAccessor(T1 a1)
Definition wifi-mode.h:243
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1396
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octets of the IEEE 802.11 MAC FCS field.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Time GetGuardIntervalForMode(WifiMode mode, const Ptr< WifiNetDevice > device)
Get the guard interval for a given WifiMode.
bool IsAllowedControlAnswerModulationClass(WifiModulationClass modClassReq, WifiModulationClass modClassAnswer)
Return whether the modulation class of the selected mode for the control answer frame is allowed.
double MHz_u
MHz weak type.
Definition wifi-units.h:31
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:179
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble)
Return the preamble to be used for the transmission.
Ptr< const AttributeChecker > MakeWifiModeChecker()
Definition wifi-mode.cc:252
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:587
std::vector< WifiMode > WifiModeList
In various parts of the code, folk are interested in maintaining a list of transmission modes.
Definition wifi-mode.h:251
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition wifi-mode.h:24
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition enum.h:221
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416
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 wifi-types.h:72
double snr
SNR in linear scale.
Definition wifi-types.h:73
dBm_u rssi
RSSI.
Definition wifi-types.h:74
hold per-remote-station state.
WifiRemoteStationState * m_state
Remote station state.
std::pair< dBm_u, Time > m_rssiAndUpdateTimePair
RSSI of the most recent packet received from the remote station along with update time.
std::shared_ptr< CommonInfoBasicMle > m_mleCommonInfo
remote station Multi-Link Element Common Info
Mac48Address m_address
Mac48Address of the remote station.
MHz_u m_channelWidth
Channel width 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
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
Time m_guardInterval
HE Guard interval durationsupported by the remote station.
Ptr< const HeCapabilities > m_heCapabilities
remote station HE capabilities