A Discrete-Event Network Simulator
API
wifi-phy.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 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 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 * Sébastien Deronne <sebastien.deronne@gmail.com>
19 */
20
21#include "wifi-phy.h"
22
23#include "error-rate-model.h"
24#include "frame-capture-model.h"
25#include "interference-helper.h"
27#include "wifi-net-device.h"
28#include "wifi-ppdu.h"
29#include "wifi-psdu.h"
31#include "wifi-utils.h"
32
33#include "ns3/channel.h"
34#include "ns3/dsss-phy.h"
35#include "ns3/eht-phy.h" //also includes OFDM, HT, VHT and HE
36#include "ns3/erp-ofdm-phy.h"
37#include "ns3/error-model.h"
38#include "ns3/ht-configuration.h"
39#include "ns3/log.h"
40#include "ns3/mobility-model.h"
41#include "ns3/pointer.h"
42#include "ns3/random-variable-stream.h"
43#include "ns3/simulator.h"
44#include "ns3/string.h"
45#include "ns3/tuple.h"
46#include "ns3/vht-configuration.h"
47
48#include <algorithm>
49
50namespace ns3
51{
52
54
55/****************************************************************
56 * The actual WifiPhy class
57 ****************************************************************/
58
60
61TypeId
63{
64 static TypeId tid =
65 TypeId("ns3::WifiPhy")
67 .SetGroupName("Wifi")
68 .AddAttribute("Channel",
69 "The channel attached to this PHY",
72 MakePointerChecker<Channel>())
73 .AddAttribute(
74 "ChannelSettings",
75 "Tuple {channel number, channel width (MHz), PHY band, primary20 index} "
76 "describing the settings of the operating channel. The primary20 index is "
77 "the index of the primary 20 MHz channel within the operating channel "
78 "(0 indicates the 20 MHz subchannel with the lowest center frequency) and "
79 "is only valid if the width of the operating channel is a multiple of 20 MHz. "
80 "If the standard for this object has not been set yet, the value of this "
81 "attribute is saved and will be used to set the operating channel when the "
82 "standard is configured. If the PHY band is left unspecified, the default "
83 "band for the configured standard is used. If the channel width and the "
84 "channel number are both 0, the default channel width for the configured "
85 "standard and band are used. If the channel number is 0, the default "
86 "channel number for the configured standard, band and channel width is used."
87 "Note that the channel width can be left unspecified (0) if the channel "
88 "number uniquely identify a frequency channel for the given standard and band.",
89 StringValue("{0, 0, BAND_UNSPECIFIED, 0}"),
90 MakeTupleAccessor<UintegerValue, UintegerValue, EnumValue, UintegerValue>(
92 MakeTupleChecker<UintegerValue, UintegerValue, EnumValue, UintegerValue>(
93 MakeUintegerChecker<uint8_t>(0, 233),
94 MakeUintegerChecker<uint16_t>(0, 160),
96 "BAND_2_4GHZ",
98 "BAND_5GHZ",
100 "BAND_6GHZ",
102 "BAND_UNSPECIFIED"),
103 MakeUintegerChecker<uint8_t>(0, 7)))
104 .AddAttribute("Frequency",
105 "The center frequency (MHz) of the current operating channel.",
106 UintegerValue(0),
108 MakeUintegerChecker<uint16_t>())
109 .AddAttribute("ChannelNumber",
110 "The channel number of the current operating channel.",
111 UintegerValue(0),
113 MakeUintegerChecker<uint8_t>(0, 233))
114 .AddAttribute(
115 "ChannelWidth",
116 "The width in MHz of the current operating channel (5, 10, 20, 22, 40, 80 or 160).",
117 UintegerValue(0),
119 MakeUintegerChecker<uint16_t>(5, 160))
120 .AddAttribute(
121 "Primary20MHzIndex",
122 "The index of the primary 20 MHz channel within the current operating channel "
123 "(0 indicates the 20 MHz subchannel with the lowest center frequency).",
124 UintegerValue(0),
126 MakeUintegerChecker<uint8_t>(0, 7))
127 .AddAttribute("FixedPhyBand",
128 "If set to true, changing PHY band is prohibited after initialization.",
129 BooleanValue(false),
132 .AddAttribute(
133 "RxSensitivity",
134 "The energy of a received signal should be higher than "
135 "this threshold (dBm) for the PHY to detect the signal. "
136 "This threshold refers to a width of 20 MHz and will be "
137 "scaled to match the width of the received signal.",
138 DoubleValue(-101.0),
140 MakeDoubleChecker<double>())
141 .AddAttribute(
142 "CcaEdThreshold",
143 "The energy of all received signals should be higher than "
144 "this threshold (dBm) in the primary channel to allow the PHY layer "
145 "to declare CCA BUSY state.",
146 DoubleValue(-62.0),
148 MakeDoubleChecker<double>())
149 .AddAttribute("CcaSensitivity",
150 "The energy of a received wifi signal should be higher than "
151 "this threshold (dBm) in the primary channel to allow the PHY layer "
152 "to declare CCA BUSY state.",
153 DoubleValue(-82.0),
156 MakeDoubleChecker<double>())
157 .AddAttribute("TxGain",
158 "Transmission gain (dB).",
159 DoubleValue(0.0),
161 MakeDoubleChecker<double>())
162 .AddAttribute("RxGain",
163 "Reception gain (dB).",
164 DoubleValue(0.0),
166 MakeDoubleChecker<double>())
167 .AddAttribute("TxPowerLevels",
168 "Number of transmission power levels available between "
169 "TxPowerStart and TxPowerEnd included.",
170 UintegerValue(1),
172 MakeUintegerChecker<uint8_t>())
173 .AddAttribute("TxPowerEnd",
174 "Maximum available transmission level (dBm).",
175 DoubleValue(16.0206),
177 MakeDoubleChecker<double>())
178 .AddAttribute("TxPowerStart",
179 "Minimum available transmission level (dBm).",
180 DoubleValue(16.0206),
182 MakeDoubleChecker<double>())
183 .AddAttribute(
184 "RxNoiseFigure",
185 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
186 " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
187 "\"the difference in decibels (dB) between"
188 " the noise output of the actual receiver to the noise output of an "
189 " ideal receiver with the same overall gain and bandwidth when the receivers "
190 " are connected to sources at the standard noise temperature T0 (usually 290 K)\".",
191 DoubleValue(7),
193 MakeDoubleChecker<double>())
194 .AddAttribute("State",
195 "The state of the PHY layer.",
196 PointerValue(),
198 MakePointerChecker<WifiPhyStateHelper>())
199 .AddAttribute("ChannelSwitchDelay",
200 "Delay between two short frames transmitted on different frequencies.",
204 .AddAttribute(
205 "Antennas",
206 "The number of antennas on the device.",
207 UintegerValue(1),
209 MakeUintegerChecker<uint8_t>(1, 8))
210 .AddAttribute("MaxSupportedTxSpatialStreams",
211 "The maximum number of supported TX spatial streams."
212 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
213 UintegerValue(1),
216 MakeUintegerChecker<uint8_t>(1, 8))
217 .AddAttribute("MaxSupportedRxSpatialStreams",
218 "The maximum number of supported RX spatial streams."
219 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
220 UintegerValue(1),
223 MakeUintegerChecker<uint8_t>(1, 8))
224 .AddAttribute("ShortPlcpPreambleSupported",
225 "Whether or not short PHY preamble is supported."
226 "This parameter is only valuable for 802.11b STAs and APs."
227 "Note: 802.11g APs and STAs always support short PHY preamble.",
228 BooleanValue(false),
232 .AddAttribute("FrameCaptureModel",
233 "Ptr to an object that implements the frame capture model",
234 PointerValue(),
236 MakePointerChecker<FrameCaptureModel>())
237 .AddAttribute("PreambleDetectionModel",
238 "Ptr to an object that implements the preamble detection model",
239 PointerValue(),
241 MakePointerChecker<PreambleDetectionModel>())
242 .AddAttribute("PostReceptionErrorModel",
243 "An optional packet error model can be added to the receive "
244 "packet process after any propagation-based (SNR-based) error "
245 "models have been applied. Typically this is used to force "
246 "specific packet drops, for testing purposes.",
247 PointerValue(),
249 MakePointerChecker<ErrorModel>())
250 .AddAttribute("Sifs",
251 "The duration of the Short Interframe Space. "
252 "NOTE that the default value is overwritten by the value defined "
253 "by the standard; if you want to set this attribute, you have to "
254 "do it after that the PHY object is initialized.",
258 .AddAttribute("Slot",
259 "The duration of a slot. "
260 "NOTE that the default value is overwritten by the value defined "
261 "by the standard; if you want to set this attribute, you have to "
262 "do it after that the PHY object is initialized.",
266 .AddAttribute("Pifs",
267 "The duration of the PCF Interframe Space. "
268 "NOTE that the default value is overwritten by the value defined "
269 "by the standard; if you want to set this attribute, you have to "
270 "do it after that the PHY object is initialized.",
274 .AddAttribute("PowerDensityLimit",
275 "The mean equivalent isotropically radiated power density"
276 "limit (in dBm/MHz) set by regulators.",
277 DoubleValue(100.0), // set to a high value so as to have no effect
279 MakeDoubleChecker<double>())
280 .AddTraceSource("PhyTxBegin",
281 "Trace source indicating a packet "
282 "has begun transmitting over the channel medium",
284 "ns3::WifiPhy::PhyTxBeginTracedCallback")
285 .AddTraceSource("PhyTxPsduBegin",
286 "Trace source indicating a PSDU "
287 "has begun transmitting over the channel medium",
289 "ns3::WifiPhy::PsduTxBeginCallback")
290 .AddTraceSource("PhyTxEnd",
291 "Trace source indicating a packet "
292 "has been completely transmitted over the channel.",
294 "ns3::Packet::TracedCallback")
295 .AddTraceSource("PhyTxDrop",
296 "Trace source indicating a packet "
297 "has been dropped by the device during transmission",
299 "ns3::Packet::TracedCallback")
300 .AddTraceSource("PhyRxBegin",
301 "Trace source indicating a packet "
302 "has begun being received from the channel medium "
303 "by the device",
305 "ns3::WifiPhy::PhyRxBeginTracedCallback")
306 .AddTraceSource("PhyRxPayloadBegin",
307 "Trace source indicating the reception of the "
308 "payload of a PPDU has begun",
310 "ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
311 .AddTraceSource("PhyRxEnd",
312 "Trace source indicating a packet "
313 "has been completely received from the channel medium "
314 "by the device",
316 "ns3::Packet::TracedCallback")
317 .AddTraceSource("PhyRxDrop",
318 "Trace source indicating a packet "
319 "has been dropped by the device during reception",
321 "ns3::Packet::TracedCallback")
322 .AddTraceSource("MonitorSnifferRx",
323 "Trace source simulating a wifi device in monitor mode "
324 "sniffing all received frames",
326 "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
327 .AddTraceSource("MonitorSnifferTx",
328 "Trace source simulating the capability of a wifi device "
329 "in monitor mode to sniff all frames being transmitted",
331 "ns3::WifiPhy::MonitorSnifferTxTracedCallback");
332 return tid;
333}
334
336 : m_txMpduReferenceNumber(0xffffffff),
337 m_rxMpduReferenceNumber(0xffffffff),
338 m_endPhyRxEvent(),
339 m_endTxEvent(),
340 m_currentEvent(nullptr),
341 m_previouslyRxPpduUid(UINT64_MAX),
342 m_standard(WIFI_STANDARD_UNSPECIFIED),
344 m_sifs(Seconds(0)),
345 m_slot(Seconds(0)),
346 m_pifs(Seconds(0)),
347 m_ackTxTime(Seconds(0)),
348 m_blockAckTxTime(Seconds(0)),
349 m_powerRestricted(false),
350 m_channelAccessRequested(false),
351 m_txSpatialStreams(1),
352 m_rxSpatialStreams(1),
353 m_wifiRadioEnergyModel(nullptr),
354 m_timeLastPreambleDetected(Seconds(0))
355{
356 NS_LOG_FUNCTION(this);
357 m_random = CreateObject<UniformRandomVariable>();
358 m_state = CreateObject<WifiPhyStateHelper>();
359}
360
362{
363 NS_LOG_FUNCTION(this);
364}
365
366void
368{
369 NS_LOG_FUNCTION(this);
372 for (auto& phyEntity : m_phyEntities)
373 {
374 phyEntity.second->CancelAllEvents();
375 }
376 m_device = nullptr;
377 m_mobility = nullptr;
378 m_frameCaptureModel = nullptr;
379 m_preambleDetectionModel = nullptr;
380 m_wifiRadioEnergyModel = nullptr;
382 if (m_interference)
383 {
384 m_interference->Dispose();
385 }
386 m_interference = nullptr;
387 m_random = nullptr;
388 m_state = nullptr;
389 m_currentEvent = nullptr;
390 for (auto& preambleEvent : m_currentPreambleEvents)
391 {
392 preambleEvent.second = nullptr;
393 }
395
396 for (auto& phyEntity : m_phyEntities)
397 {
398 phyEntity.second = nullptr;
399 }
400 m_phyEntities.clear();
401}
402
403std::map<WifiModulationClass, Ptr<PhyEntity>>&
405{
406 static std::map<WifiModulationClass, Ptr<PhyEntity>> g_staticPhyEntities;
407 return g_staticPhyEntities;
408}
409
412{
413 return m_state;
414}
415
416void
418{
419 m_state->SetReceiveOkCallback(callback);
420}
421
422void
424{
425 m_state->SetReceiveErrorCallback(callback);
426}
427
428void
430{
431 m_state->RegisterListener(listener);
432}
433
434void
436{
437 m_state->UnregisterListener(listener);
438}
439
440void
442{
444}
445
446void
448{
449 NS_LOG_FUNCTION(this << threshold);
450 m_rxSensitivityW = DbmToW(threshold);
451}
452
453double
455{
456 return WToDbm(m_rxSensitivityW);
457}
458
459void
461{
462 NS_LOG_FUNCTION(this << threshold);
463 m_ccaEdThresholdW = DbmToW(threshold);
464}
465
466double
468{
470}
471
472void
474{
475 NS_LOG_FUNCTION(this << threshold);
477}
478
479double
481{
483}
484
485void
486WifiPhy::SetRxNoiseFigure(double noiseFigureDb)
487{
488 NS_LOG_FUNCTION(this << noiseFigureDb);
489 if (m_interference)
490 {
491 m_interference->SetNoiseFigure(DbToRatio(noiseFigureDb));
492 }
493 m_noiseFigureDb = noiseFigureDb;
494}
495
496void
498{
499 NS_LOG_FUNCTION(this << start);
501}
502
503double
505{
506 return m_txPowerBaseDbm;
507}
508
509void
511{
512 NS_LOG_FUNCTION(this << end);
513 m_txPowerEndDbm = end;
514}
515
516double
518{
519 return m_txPowerEndDbm;
520}
521
522void
524{
525 NS_LOG_FUNCTION(this << +n);
526 m_nTxPower = n;
527}
528
529uint8_t
531{
532 return m_nTxPower;
533}
534
535void
537{
538 NS_LOG_FUNCTION(this << gain);
539 m_txGainDb = gain;
540}
541
542double
544{
545 return m_txGainDb;
546}
547
548void
550{
551 NS_LOG_FUNCTION(this << gain);
552 m_rxGainDb = gain;
553}
554
555double
557{
558 return m_rxGainDb;
559}
560
561void
563{
564 NS_LOG_FUNCTION(this << enable);
565 m_shortPreamble = enable;
566}
567
568bool
570{
571 return m_shortPreamble;
572}
573
574void
576{
577 m_device = device;
578}
579
582{
583 return m_device;
584}
585
586void
588{
590}
591
594{
595 if (m_mobility)
596 {
597 return m_mobility;
598 }
599 else
600 {
602 }
603}
604
605void
607{
608 m_interference = helper;
609 m_interference->SetNoiseFigure(DbToRatio(m_noiseFigureDb));
610 m_interference->SetNumberOfReceiveAntennas(m_numberOfAntennas);
611}
612
613void
615{
617 m_interference->SetErrorRateModel(model);
618}
619
620void
622{
623 NS_LOG_FUNCTION(this << em);
625}
626
627void
629{
630 m_frameCaptureModel = model;
631}
632
633void
635{
637}
638
639void
641{
642 m_wifiRadioEnergyModel = wifiRadioEnergyModel;
643}
644
645double
646WifiPhy::GetPowerDbm(uint8_t power) const
647{
650 double dbm;
651 if (m_nTxPower > 1)
652 {
654 }
655 else
656 {
658 "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
659 dbm = m_txPowerBaseDbm;
660 }
661 return dbm;
662}
663
664Time
666{
668}
669
670double
671WifiPhy::CalculateSnr(const WifiTxVector& txVector, double ber) const
672{
673 return m_interference->GetErrorRateModel()->CalculateSnr(txVector, ber);
674}
675
678{
679 const auto it = GetStaticPhyEntities().find(modulation);
680 NS_ABORT_MSG_IF(it == GetStaticPhyEntities().end(), "Unimplemented Wi-Fi modulation class");
681 return it->second;
682}
683
686{
687 const auto it = m_phyEntities.find(modulation);
688 NS_ABORT_MSG_IF(it == m_phyEntities.end(), "Unsupported Wi-Fi modulation class " << modulation);
689 return it->second;
690}
691
694{
696}
697
698void
700{
701 NS_LOG_FUNCTION(modulation);
702 NS_ASSERT_MSG(GetStaticPhyEntities().find(modulation) == GetStaticPhyEntities().end(),
703 "The PHY entity has already been added. The setting should only be done once per "
704 "modulation class");
705 GetStaticPhyEntities()[modulation] = phyEntity;
706}
707
708void
710{
711 NS_LOG_FUNCTION(this << modulation);
712 NS_ABORT_MSG_IF(GetStaticPhyEntities().find(modulation) == GetStaticPhyEntities().end(),
713 "Cannot add an unimplemented PHY to supported list. Update the former first.");
714 NS_ASSERT_MSG(m_phyEntities.find(modulation) == m_phyEntities.end(),
715 "The PHY entity has already been added. The setting should only be done once per "
716 "modulation class");
717 phyEntity->SetOwner(this);
718 m_phyEntities[modulation] = phyEntity;
719}
720
721void
723{
724 m_sifs = sifs;
725}
726
727Time
729{
730 return m_sifs;
731}
732
733void
735{
736 m_slot = slot;
737}
738
739Time
741{
742 return m_slot;
743}
744
745void
747{
748 m_pifs = pifs;
749}
750
751Time
753{
754 return m_pifs;
755}
756
757Time
759{
760 return m_ackTxTime;
761}
762
763Time
765{
766 return m_blockAckTxTime;
767}
768
769void
771{
772 NS_LOG_FUNCTION(this);
773 AddPhyEntity(WIFI_MOD_CLASS_OFDM, Create<OfdmPhy>());
774
775 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
778 SetPifs(GetSifs() + GetSlot());
779 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
780 // of the PPDU causing the EIFS" of 802.11-2016
782}
783
784void
786{
787 NS_LOG_FUNCTION(this);
788 Ptr<DsssPhy> phyEntity = Create<DsssPhy>();
790 AddPhyEntity(WIFI_MOD_CLASS_DSSS, phyEntity); // when plain DSSS modes are used
791
792 // See Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2016
795 SetPifs(GetSifs() + GetSlot());
796 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
797 // of the PPDU causing the EIFS" of 802.11-2016
799}
800
801void
803{
804 NS_LOG_FUNCTION(this);
805 // See Table 18-5 "ERP characteristics" of 802.11-2016
806 // Slot time defaults to the "long slot time" of 20 us in the standard
807 // according to mixed 802.11b/g deployments. Short slot time is enabled
808 // if the user sets the ShortSlotTimeSupported flag to true and when the BSS
809 // consists of only ERP STAs capable of supporting this option.
811 AddPhyEntity(WIFI_MOD_CLASS_ERP_OFDM, Create<ErpOfdmPhy>());
812}
813
814void
816{
817 NS_LOG_FUNCTION(this);
818 if (GetChannelWidth() == 10)
819 {
821
822 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
825 SetPifs(GetSifs() + GetSlot());
827 }
828 else if (GetChannelWidth() == 5)
829 {
831
832 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
835 SetPifs(GetSifs() + GetSlot());
837 }
838 else
839 {
840 NS_FATAL_ERROR("802.11p configured with a wrong channel width!");
841 }
842}
843
844void
846{
847 NS_LOG_FUNCTION(this);
849 {
851 }
852 else
853 {
855 }
857
858 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
859 // of the PPDU causing the EIFS" of 802.11-2016
861}
862
863void
865{
866 NS_LOG_FUNCTION(this);
868 AddPhyEntity(WIFI_MOD_CLASS_VHT, Create<VhtPhy>());
869}
870
871void
873{
874 NS_LOG_FUNCTION(this);
876 {
878 }
879 else
880 {
882 }
883 AddPhyEntity(WIFI_MOD_CLASS_HE, Create<HePhy>());
884}
885
886void
888{
889 NS_LOG_FUNCTION(this);
891 AddPhyEntity(WIFI_MOD_CLASS_EHT, Create<EhtPhy>());
892}
893
894void
896{
897 NS_LOG_FUNCTION(this << standard);
898
900 "Cannot change standard");
901
902 m_standard = standard;
903
905 {
906 NS_LOG_DEBUG("Setting the operating channel first");
908 // return because we are called back by SetOperatingChannel
909 return;
910 }
911
912 // this function is called when changing PHY band, hence we have to delete
913 // the previous PHY entities
914 m_phyEntities.clear();
915
916 switch (standard)
917 {
920 break;
923 break;
926 break;
929 break;
932 break;
935 break;
938 break;
941 break;
943 default:
944 NS_ASSERT_MSG(false, "Unsupported standard");
945 break;
946 }
947}
948
951{
952 return m_band;
953}
954
957{
958 return m_standard;
959}
960
963{
964 return m_operatingChannel;
965}
966
967uint16_t
969{
971}
972
973uint8_t
975{
977}
978
979uint16_t
981{
983}
984
985uint8_t
987{
989}
990
991void
993{
994 m_fixedPhyBand = enable;
995}
996
997bool
999{
1000 return m_fixedPhyBand;
1001}
1002
1003void
1005{
1006 // the generic operator<< for tuples does not give a pretty result
1007 NS_LOG_FUNCTION(this << +std::get<0>(channelTuple) << std::get<1>(channelTuple)
1008 << static_cast<WifiPhyBand>(std::get<2>(channelTuple))
1009 << +std::get<3>(channelTuple));
1010
1011 m_channelSettings = channelTuple;
1012
1014 {
1015 NS_LOG_DEBUG("Channel information will be applied when a standard is configured");
1016 return;
1017 }
1018
1019 Time delay = Seconds(0);
1020
1021 if (IsInitialized())
1022 {
1024 }
1025
1026 if (delay.IsStrictlyNegative())
1027 {
1028 // switching channel is not possible now
1029 return;
1030 }
1031 if (delay.IsStrictlyPositive())
1032 {
1033 // switching channel has been postponed
1034 Simulator::Schedule(delay, &WifiPhy::SetOperatingChannel, this, channelTuple);
1035 return;
1036 }
1037
1038 // channel can be switched now.
1040}
1041
1042Time
1044{
1045 m_powerRestricted = false;
1047 m_currentEvent = nullptr;
1049 if (!IsInitialized())
1050 {
1051 // this is not channel switch, this is initialization
1052 NS_LOG_DEBUG("Before initialization, nothing to do");
1053 return Seconds(0);
1054 }
1055
1056 Time delay = Seconds(0);
1057
1059 switch (m_state->GetState())
1060 {
1061 case WifiPhyState::RX:
1062 NS_LOG_DEBUG("drop packet because of channel switching while reception");
1064 for (auto& phyEntity : m_phyEntities)
1065 {
1066 phyEntity.second->CancelAllEvents();
1067 }
1068 break;
1069 case WifiPhyState::TX:
1070 NS_LOG_DEBUG("channel switching postponed until end of current transmission");
1071 delay = GetDelayUntilIdle();
1072 break;
1074 case WifiPhyState::IDLE:
1076 for (auto& phyEntity : m_phyEntities)
1077 {
1078 phyEntity.second->CancelAllEvents();
1079 }
1080 break;
1082 NS_LOG_DEBUG("channel switching ignored in sleep mode");
1083 delay = Seconds(-1); // negative value to indicate switching not possible
1084 break;
1085 default:
1086 NS_ASSERT(false);
1087 break;
1088 }
1089
1090 return delay;
1091}
1092
1093void
1095{
1096 NS_LOG_FUNCTION(this);
1097
1098 // Update unspecified parameters with default values
1099 if (auto& [number, width, band, primary20] = m_channelSettings; true)
1100 {
1101 if (band == static_cast<int>(WIFI_PHY_BAND_UNSPECIFIED))
1102 {
1103 band = static_cast<int>(GetDefaultPhyBand(m_standard));
1104 }
1105 if (width == 0 && number == 0)
1106 {
1107 width = GetDefaultChannelWidth(m_standard, static_cast<WifiPhyBand>(band));
1108 }
1109 if (number == 0)
1110 {
1111 number =
1113 m_standard,
1114 static_cast<WifiPhyBand>(band));
1115 }
1116 }
1117
1118 // We need to call SetStandard if this is the first time we set a channel or we
1119 // are changing PHY band. Checking if the new PHY band is different than the
1120 // previous one covers both cases because initially the PHY band is unspecified
1121 bool changingPhyBand = (static_cast<WifiPhyBand>(std::get<2>(m_channelSettings)) != m_band);
1122
1123 NS_ABORT_MSG_IF(IsInitialized() && m_fixedPhyBand && changingPhyBand,
1124 "Trying to change PHY band while prohibited.");
1125
1126 m_band = static_cast<WifiPhyBand>(std::get<2>(m_channelSettings));
1127
1128 // check that the channel width is supported
1129 uint16_t chWidth = std::get<1>(m_channelSettings);
1130
1131 if (m_device)
1132 {
1133 if (auto htConfig = m_device->GetHtConfiguration();
1134 htConfig && !htConfig->Get40MHzOperationSupported() && chWidth > 20)
1135 {
1136 NS_ABORT_MSG("Attempting to set a " << chWidth
1137 << " MHz channel on"
1138 "a station only supporting 20 MHz operation");
1139 }
1140
1141 if (auto vhtConfig = m_device->GetVhtConfiguration();
1142 vhtConfig && !vhtConfig->Get160MHzOperationSupported() && chWidth > 80)
1143 {
1144 NS_ABORT_MSG("Attempting to set a " << chWidth
1145 << " MHz channel on"
1146 "a station supporting up to 80 MHz operation");
1147 }
1148 }
1149
1150 NS_LOG_DEBUG("switching channel");
1151 m_operatingChannel.Set(std::get<0>(m_channelSettings), 0, chWidth, m_standard, m_band);
1153
1154 if (changingPhyBand)
1155 {
1157 }
1158
1159 if (IsInitialized())
1160 {
1161 // notify channel switching
1162 m_state->SwitchToChannelSwitching(GetChannelSwitchDelay());
1163 m_interference->EraseEvents();
1164 /*
1165 * Needed here to be able to correctly sensed the medium for the first
1166 * time after the switching. The actual switching is not performed until
1167 * after m_channelSwitchDelay. Packets received during the switching
1168 * state are added to the event list and are employed later to figure
1169 * out the state of the medium after the switching.
1170 */
1171 }
1172}
1173
1174void
1176{
1177 NS_LOG_FUNCTION(this << +antennas);
1178 NS_ASSERT_MSG(antennas > 0 && antennas <= 4, "unsupported number of antennas");
1179 m_numberOfAntennas = antennas;
1180 if (m_interference)
1181 {
1182 m_interference->SetNumberOfReceiveAntennas(antennas);
1183 }
1184}
1185
1186uint8_t
1188{
1189 return m_numberOfAntennas;
1190}
1191
1192void
1194{
1195 NS_ASSERT(streams <= GetNumberOfAntennas());
1196 bool changed = (m_txSpatialStreams != streams);
1197 m_txSpatialStreams = streams;
1198 if (changed)
1199 {
1200 auto phyEntity = m_phyEntities.find(WIFI_MOD_CLASS_HT);
1201 if (phyEntity != m_phyEntities.end())
1202 {
1203 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity->second);
1204 if (htPhy)
1205 {
1206 htPhy->SetMaxSupportedNss(
1207 m_txSpatialStreams); // this is essential to have the right MCSs configured
1208 }
1209
1211 {
1213 }
1214 }
1215 }
1216}
1217
1218uint8_t
1220{
1221 return m_txSpatialStreams;
1222}
1223
1224void
1226{
1227 NS_ASSERT(streams <= GetNumberOfAntennas());
1228 bool changed = (m_rxSpatialStreams != streams);
1229 m_rxSpatialStreams = streams;
1230 if (changed && !m_capabilitiesChangedCallback.IsNull())
1231 {
1233 }
1234}
1235
1236uint8_t
1238{
1239 return m_rxSpatialStreams;
1240}
1241
1242std::list<uint8_t>
1244{
1245 std::list<uint8_t> list;
1246 for (const auto& phyEntity : m_phyEntities)
1247 {
1248 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity.second);
1249 if (htPhy)
1250 {
1251 list.emplace_back(htPhy->GetBssMembershipSelector());
1252 }
1253 }
1254 return list;
1255}
1256
1257void
1259{
1260 NS_LOG_FUNCTION(this);
1261 m_powerRestricted = false;
1263 switch (m_state->GetState())
1264 {
1265 case WifiPhyState::TX:
1266 NS_LOG_DEBUG("setting sleep mode postponed until end of current transmission");
1268 break;
1269 case WifiPhyState::RX:
1270 NS_LOG_DEBUG("setting sleep mode postponed until end of current reception");
1272 break;
1274 NS_LOG_DEBUG("setting sleep mode postponed until end of channel switching");
1276 break;
1278 case WifiPhyState::IDLE:
1279 NS_LOG_DEBUG("setting sleep mode");
1280 m_state->SwitchToSleep();
1281 break;
1283 NS_LOG_DEBUG("already in sleep mode");
1284 break;
1285 default:
1286 NS_ASSERT(false);
1287 break;
1288 }
1289}
1290
1291void
1293{
1294 NS_LOG_FUNCTION(this);
1295 m_powerRestricted = false;
1299 for (auto& phyEntity : m_phyEntities)
1300 {
1301 phyEntity.second->CancelAllEvents();
1302 }
1303 m_state->SwitchToOff();
1304}
1305
1306void
1308{
1309 NS_LOG_FUNCTION(this);
1311 switch (m_state->GetState())
1312 {
1313 case WifiPhyState::TX:
1314 case WifiPhyState::RX:
1315 case WifiPhyState::IDLE:
1318 NS_LOG_DEBUG("not in sleep mode, there is nothing to resume");
1319 break;
1320 }
1321 case WifiPhyState::SLEEP: {
1322 NS_LOG_DEBUG("resuming from sleep mode");
1323 m_state->SwitchFromSleep();
1324 SwitchMaybeToCcaBusy(nullptr);
1325 break;
1326 }
1327 default: {
1328 NS_ASSERT(false);
1329 break;
1330 }
1331 }
1332}
1333
1334void
1336{
1337 NS_LOG_FUNCTION(this);
1338 switch (m_state->GetState())
1339 {
1340 case WifiPhyState::TX:
1341 case WifiPhyState::RX:
1342 case WifiPhyState::IDLE:
1345 case WifiPhyState::SLEEP: {
1346 NS_LOG_DEBUG("not in off mode, there is nothing to resume");
1347 break;
1348 }
1349 case WifiPhyState::OFF: {
1350 NS_LOG_DEBUG("resuming from off mode");
1351 m_state->SwitchFromOff();
1352 SwitchMaybeToCcaBusy(nullptr);
1353 break;
1354 }
1355 default: {
1356 NS_ASSERT(false);
1357 break;
1358 }
1359 }
1360}
1361
1362Time
1364{
1365 return MicroSeconds(4);
1366}
1367
1368Time
1370{
1371 return MicroSeconds(4);
1372}
1373
1374Time
1376 const WifiTxVector& txVector,
1377 WifiPhyBand band,
1378 MpduType mpdutype,
1379 uint16_t staId)
1380{
1381 uint32_t totalAmpduSize;
1382 double totalAmpduNumSymbols;
1383 return GetPayloadDuration(size,
1384 txVector,
1385 band,
1386 mpdutype,
1387 false,
1388 totalAmpduSize,
1389 totalAmpduNumSymbols,
1390 staId);
1391}
1392
1393Time
1395 const WifiTxVector& txVector,
1396 WifiPhyBand band,
1397 MpduType mpdutype,
1398 bool incFlag,
1399 uint32_t& totalAmpduSize,
1400 double& totalAmpduNumSymbols,
1401 uint16_t staId)
1402{
1403 return GetStaticPhyEntity(txVector.GetModulationClass())
1404 ->GetPayloadDuration(size,
1405 txVector,
1406 band,
1407 mpdutype,
1408 incFlag,
1409 totalAmpduSize,
1410 totalAmpduNumSymbols,
1411 staId);
1412}
1413
1414Time
1416{
1417 return GetStaticPhyEntity(txVector.GetModulationClass())
1418 ->CalculatePhyPreambleAndHeaderDuration(txVector);
1419}
1420
1421Time
1423 const WifiTxVector& txVector,
1424 WifiPhyBand band,
1425 uint16_t staId)
1426{
1427 Time duration = CalculatePhyPreambleAndHeaderDuration(txVector) +
1428 GetPayloadDuration(size, txVector, band, NORMAL_MPDU, staId);
1429 NS_ASSERT(duration.IsStrictlyPositive());
1430 return duration;
1431}
1432
1433Time
1435 const WifiTxVector& txVector,
1436 WifiPhyBand band)
1437{
1438 return CalculateTxDuration(GetWifiConstPsduMap(psdu, txVector), txVector, band);
1439}
1440
1441Time
1443 const WifiTxVector& txVector,
1444 WifiPhyBand band)
1445{
1446 return GetStaticPhyEntity(txVector.GetModulationClass())
1447 ->CalculateTxDuration(psduMap, txVector, band);
1448}
1449
1452{
1453 return GetStaticPhyEntity(modulation)->GetMaxPsduSize();
1454}
1455
1456void
1458{
1459 if (!m_phyTxBeginTrace.IsEmpty())
1460 {
1461 for (const auto& psdu : psdus)
1462 {
1463 for (auto& mpdu : *PeekPointer(psdu.second))
1464 {
1465 m_phyTxBeginTrace(mpdu->GetProtocolDataUnit(), txPowerW);
1466 }
1467 }
1468 }
1469}
1470
1471void
1473{
1474 if (!m_phyTxEndTrace.IsEmpty())
1475 {
1476 for (const auto& psdu : psdus)
1477 {
1478 for (auto& mpdu : *PeekPointer(psdu.second))
1479 {
1480 m_phyTxEndTrace(mpdu->GetProtocolDataUnit());
1481 }
1482 }
1483 }
1484}
1485
1486void
1488{
1490 {
1491 for (auto& mpdu : *PeekPointer(psdu))
1492 {
1493 m_phyTxDropTrace(mpdu->GetProtocolDataUnit());
1494 }
1495 }
1496}
1497
1498void
1500{
1501 if (psdu && !m_phyRxBeginTrace.IsEmpty())
1502 {
1503 for (auto& mpdu : *PeekPointer(psdu))
1504 {
1505 m_phyRxBeginTrace(mpdu->GetProtocolDataUnit(), rxPowersW);
1506 }
1507 }
1508}
1509
1510void
1512{
1513 if (psdu && !m_phyRxEndTrace.IsEmpty())
1514 {
1515 for (auto& mpdu : *PeekPointer(psdu))
1516 {
1517 m_phyRxEndTrace(mpdu->GetProtocolDataUnit());
1518 }
1519 }
1520}
1521
1522void
1524{
1525 if (psdu && !m_phyRxDropTrace.IsEmpty())
1526 {
1527 for (auto& mpdu : *PeekPointer(psdu))
1528 {
1529 m_phyRxDropTrace(mpdu->GetProtocolDataUnit(), reason);
1530 }
1531 }
1532}
1533
1534void
1536 uint16_t channelFreqMhz,
1537 WifiTxVector txVector,
1538 SignalNoiseDbm signalNoise,
1539 std::vector<bool> statusPerMpdu,
1540 uint16_t staId)
1541{
1542 MpduInfo aMpdu;
1543 if (psdu->IsAggregate())
1544 {
1545 // Expand A-MPDU
1546 NS_ASSERT_MSG(txVector.IsAggregation(),
1547 "TxVector with aggregate flag expected here according to PSDU");
1549 size_t nMpdus = psdu->GetNMpdus();
1550 NS_ASSERT_MSG(statusPerMpdu.size() == nMpdus, "Should have one reception status per MPDU");
1551 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1552 {
1553 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1554 for (size_t i = 0; i < nMpdus;)
1555 {
1556 if (statusPerMpdu.at(i)) // packet received without error, hand over to sniffer
1557 {
1559 channelFreqMhz,
1560 txVector,
1561 aMpdu,
1562 signalNoise,
1563 staId);
1564 }
1565 ++i;
1566 aMpdu.type =
1567 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1568 }
1569 }
1570 }
1571 else
1572 {
1573 NS_ASSERT_MSG(statusPerMpdu.size() == 1,
1574 "Should have one reception status for normal MPDU");
1575 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1576 {
1577 aMpdu.type = NORMAL_MPDU;
1579 channelFreqMhz,
1580 txVector,
1581 aMpdu,
1582 signalNoise,
1583 staId);
1584 }
1585 }
1586}
1587
1588void
1590 uint16_t channelFreqMhz,
1591 WifiTxVector txVector,
1592 uint16_t staId)
1593{
1594 MpduInfo aMpdu;
1595 if (psdu->IsAggregate())
1596 {
1597 // Expand A-MPDU
1598 NS_ASSERT_MSG(txVector.IsAggregation(),
1599 "TxVector with aggregate flag expected here according to PSDU");
1601 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1602 {
1603 size_t nMpdus = psdu->GetNMpdus();
1604 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1605 for (size_t i = 0; i < nMpdus;)
1606 {
1608 channelFreqMhz,
1609 txVector,
1610 aMpdu,
1611 staId);
1612 ++i;
1613 aMpdu.type =
1614 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1615 }
1616 }
1617 }
1618 else
1619 {
1620 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1621 {
1622 aMpdu.type = NORMAL_MPDU;
1623 m_phyMonitorSniffTxTrace(psdu->GetPacket(), channelFreqMhz, txVector, aMpdu, staId);
1624 }
1625 }
1626}
1627
1630{
1631 return GetStaticPhyEntity(txVector.GetModulationClass())->GetWifiConstPsduMap(psdu, txVector);
1632}
1633
1634void
1636{
1637 NS_LOG_FUNCTION(this << *psdu << txVector);
1638 Send(GetWifiConstPsduMap(psdu, txVector), txVector);
1639}
1640
1641void
1643{
1644 NS_LOG_FUNCTION(this << psdus << txVector);
1645 /* Transmission can happen if:
1646 * - we are syncing on a packet. It is the responsibility of the
1647 * MAC layer to avoid doing this but the PHY does nothing to
1648 * prevent it.
1649 * - we are idle
1650 */
1651 NS_ASSERT(!m_state->IsStateTx() && !m_state->IsStateSwitching());
1653
1654 if (txVector.GetNssMax() > GetMaxSupportedTxSpatialStreams())
1655 {
1656 NS_FATAL_ERROR("Unsupported number of spatial streams!");
1657 }
1658
1659 if (m_state->IsStateSleep())
1660 {
1661 NS_LOG_DEBUG("Dropping packet because in sleep mode");
1662 for (const auto& psdu : psdus)
1663 {
1664 NotifyTxDrop(psdu.second);
1665 }
1666 return;
1667 }
1668
1669 Time txDuration = CalculateTxDuration(psdus, txVector, GetPhyBand());
1670
1671 bool noEndPreambleDetectionEvent = true;
1672 for (const auto& it : m_phyEntities)
1673 {
1674 noEndPreambleDetectionEvent &= it.second->NoEndPreambleDetectionEvents();
1675 }
1676 if (!noEndPreambleDetectionEvent ||
1677 (m_currentEvent &&
1678 (m_currentEvent->GetEndTime() > (Simulator::Now() + m_state->GetDelayUntilIdle()))))
1679 {
1681 }
1682
1683 for (auto& it : m_phyEntities)
1684 {
1685 it.second->CancelRunningEndPreambleDetectionEvents();
1686 }
1689
1691 {
1692 NS_LOG_DEBUG("Transmitting with power restriction for " << txDuration.As(Time::NS));
1693 }
1694 else
1695 {
1696 NS_LOG_DEBUG("Transmitting without power restriction for " << txDuration.As(Time::NS));
1697 }
1698
1699 if (m_state->GetState() == WifiPhyState::OFF)
1700 {
1701 NS_LOG_DEBUG("Transmission canceled because device is OFF");
1702 return;
1703 }
1704
1705 Ptr<WifiPpdu> ppdu =
1706 GetPhyEntity(txVector.GetModulationClass())->BuildPpdu(psdus, txVector, txDuration);
1707 m_previouslyRxPpduUid = UINT64_MAX; // reset (after creation of PPDU) to use it only once
1708
1709 double txPowerW = DbmToW(GetTxPowerForTransmission(ppdu) + GetTxGain());
1710 NotifyTxBegin(psdus, txPowerW);
1711 if (!m_phyTxPsduBeginTrace.IsEmpty())
1712 {
1713 m_phyTxPsduBeginTrace(psdus, txVector, txPowerW);
1714 }
1715 for (const auto& psdu : psdus)
1716 {
1717 NotifyMonitorSniffTx(psdu.second, GetFrequency(), txVector, psdu.first);
1718 }
1719 m_state->SwitchToTx(txDuration, psdus, GetPowerDbm(txVector.GetTxPowerLevel()), txVector);
1720
1722 m_wifiRadioEnergyModel->GetMaximumTimeInState(WifiPhyState::TX) < txDuration)
1723 {
1724 ppdu->SetTruncatedTx();
1725 }
1726
1727 m_endTxEvent =
1728 Simulator::Schedule(txDuration, &WifiPhy::NotifyTxEnd, this, psdus); // TODO: fix for MU
1729
1730 StartTx(ppdu, txVector);
1731
1733 m_powerRestricted = false;
1734
1735 Simulator::Schedule(txDuration, &WifiPhy::Reset, this);
1736}
1737
1738uint64_t
1740{
1741 return m_previouslyRxPpduUid;
1742}
1743
1744void
1746{
1747 NS_LOG_FUNCTION(this);
1749 m_currentEvent = nullptr;
1750 for (auto& phyEntity : m_phyEntities)
1751 {
1752 phyEntity.second->CancelAllEvents();
1753 }
1754 SwitchMaybeToCcaBusy(nullptr);
1755}
1756
1757void
1759 RxPowerWattPerChannelBand& rxPowersW,
1760 Time rxDuration)
1761{
1762 WifiModulationClass modulation = ppdu->GetTxVector().GetModulationClass();
1763 auto it = m_phyEntities.find(modulation);
1764 if (it != m_phyEntities.end())
1765 {
1766 it->second->StartReceivePreamble(ppdu, rxPowersW, rxDuration);
1767 }
1768 else
1769 {
1770 // TODO find a fallback PHY for receiving the PPDU (e.g. 11a for 11ax due to preamble
1771 // structure)
1772 NS_LOG_DEBUG("Unsupported modulation received (" << modulation << "), consider as noise");
1773 m_interference->Add(ppdu, ppdu->GetTxVector(), rxDuration, rxPowersW);
1774 SwitchMaybeToCcaBusy(nullptr);
1775 }
1776}
1777
1780 uint16_t guardBandwidth,
1782 uint8_t bandIndex) const
1783{
1784 NS_ASSERT_MSG(false, "802.11ax can only be used with SpectrumWifiPhy");
1785 WifiSpectrumBand convertedSubcarriers;
1786 return convertedSubcarriers;
1787}
1788
1789void
1791{
1792 NS_LOG_FUNCTION(this);
1794 {
1795 m_powerRestricted = false;
1796 }
1797}
1798
1799void
1801{
1802 NS_LOG_FUNCTION(this);
1804}
1805
1806bool
1808{
1809 for (const auto& phyEntity : m_phyEntities)
1810 {
1811 if (phyEntity.second->IsModeSupported(mode))
1812 {
1813 return true;
1814 }
1815 }
1816 return false;
1817}
1818
1821{
1822 // Start from oldest standards and move up (guaranteed by fact that WifModulationClass is
1823 // ordered)
1824 for (const auto& phyEntity : m_phyEntities)
1825 {
1826 for (const auto& mode : *(phyEntity.second))
1827 {
1828 return mode;
1829 }
1830 }
1831 NS_ASSERT_MSG(false, "Should have found at least one default mode");
1832 return WifiMode();
1833}
1834
1835bool
1836WifiPhy::IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
1837{
1838 const auto phyEntity = m_phyEntities.find(modulation);
1839 if (phyEntity == m_phyEntities.end())
1840 {
1841 return false;
1842 }
1843 return phyEntity->second->IsMcsSupported(mcs);
1844}
1845
1846std::list<WifiMode>
1848{
1849 std::list<WifiMode> list;
1850 for (const auto& phyEntity : m_phyEntities)
1851 {
1852 if (!phyEntity.second->HandlesMcsModes()) // to exclude MCSs from search
1853 {
1854 for (const auto& mode : *(phyEntity.second))
1855 {
1856 list.emplace_back(mode);
1857 }
1858 }
1859 }
1860 return list;
1861}
1862
1863std::list<WifiMode>
1865{
1866 std::list<WifiMode> list;
1867 const auto phyEntity = m_phyEntities.find(modulation);
1868 if (phyEntity != m_phyEntities.end())
1869 {
1870 if (!phyEntity->second->HandlesMcsModes()) // to exclude MCSs from search
1871 {
1872 for (const auto& mode : *(phyEntity->second))
1873 {
1874 list.emplace_back(mode);
1875 }
1876 }
1877 }
1878 return list;
1879}
1880
1881uint16_t
1883{
1884 uint16_t numMcs = 0;
1885 for (const auto& phyEntity : m_phyEntities)
1886 {
1887 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
1888 {
1889 numMcs += phyEntity.second->GetNumModes();
1890 }
1891 }
1892 return numMcs;
1893}
1894
1895std::list<WifiMode>
1897{
1898 std::list<WifiMode> list;
1899 for (const auto& phyEntity : m_phyEntities)
1900 {
1901 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
1902 {
1903 for (const auto& mode : *(phyEntity.second))
1904 {
1905 list.emplace_back(mode);
1906 }
1907 }
1908 }
1909 return list;
1910}
1911
1912std::list<WifiMode>
1914{
1915 std::list<WifiMode> list;
1916 auto phyEntity = m_phyEntities.find(modulation);
1917 if (phyEntity != m_phyEntities.end())
1918 {
1919 if (phyEntity->second->HandlesMcsModes()) // to exclude non-MCS modes from search
1920 {
1921 for (const auto& mode : *(phyEntity->second))
1922 {
1923 list.emplace_back(mode);
1924 }
1925 }
1926 }
1927 return list;
1928}
1929
1931WifiPhy::GetMcs(WifiModulationClass modulation, uint8_t mcs) const
1932{
1933 NS_ASSERT_MSG(IsMcsSupported(modulation, mcs), "Unsupported MCS");
1934 return m_phyEntities.at(modulation)->GetMcs(mcs);
1935}
1936
1937bool
1939{
1940 return m_state->IsStateCcaBusy();
1941}
1942
1943bool
1945{
1946 return m_state->IsStateIdle();
1947}
1948
1949bool
1951{
1952 return m_state->IsStateRx();
1953}
1954
1955bool
1957{
1958 return m_state->IsStateTx();
1959}
1960
1961bool
1963{
1964 return m_state->IsStateSwitching();
1965}
1966
1967bool
1969{
1970 return m_state->IsStateSleep();
1971}
1972
1973bool
1975{
1976 return m_state->IsStateOff();
1977}
1978
1979Time
1981{
1982 return m_state->GetDelayUntilIdle();
1983}
1984
1985Time
1987{
1988 return m_state->GetLastRxStartTime();
1989}
1990
1991Time
1993{
1994 return m_state->GetLastRxEndTime();
1995}
1996
1997void
1999{
2000 NS_LOG_FUNCTION(this);
2001 GetPhyEntity(m_standard)->SwitchMaybeToCcaBusy(ppdu);
2002}
2003
2004void
2006{
2007 NS_LOG_FUNCTION(this << duration);
2008 GetPhyEntity(m_standard)->NotifyCcaBusy(ppdu, duration, WIFI_CHANLIST_PRIMARY);
2009}
2010
2011void
2013{
2014 NS_LOG_FUNCTION(this << reason);
2015 if (reason != OBSS_PD_CCA_RESET ||
2016 m_currentEvent) // Otherwise abort has already been called previously
2017 {
2018 for (auto& phyEntity : m_phyEntities)
2019 {
2020 phyEntity.second->CancelAllEvents();
2021 }
2023 {
2025 }
2026 m_interference->NotifyRxEnd(Simulator::Now());
2027 if (!m_currentEvent)
2028 {
2029 return;
2030 }
2032 if (reason == OBSS_PD_CCA_RESET)
2033 {
2034 m_state->SwitchFromRxAbort(GetChannelWidth());
2035 }
2036 for (auto it = m_currentPreambleEvents.begin(); it != m_currentPreambleEvents.end(); ++it)
2037 {
2038 if (it->second == m_currentEvent)
2039 {
2040 it = m_currentPreambleEvents.erase(it);
2041 break;
2042 }
2043 }
2044 m_currentEvent = nullptr;
2045 }
2046}
2047
2048void
2049WifiPhy::ResetCca(bool powerRestricted, double txPowerMaxSiso, double txPowerMaxMimo)
2050{
2051 NS_LOG_FUNCTION(this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
2052 // This method might be called multiple times when receiving TB PPDUs with a BSS color
2053 // different than the one of the receiver. The first time this method is called, the call
2054 // to AbortCurrentReception sets m_currentEvent to 0. Therefore, we need to check whether
2055 // m_currentEvent is not 0 before executing the instructions below.
2056 if (m_currentEvent)
2057 {
2058 m_powerRestricted = powerRestricted;
2059 m_txPowerMaxSiso = txPowerMaxSiso;
2060 m_txPowerMaxMimo = txPowerMaxMimo;
2061 NS_ASSERT((m_currentEvent->GetEndTime() - Simulator::Now()).IsPositive());
2064 this);
2066 this,
2067 OBSS_PD_CCA_RESET); // finish processing field first
2068 }
2069}
2070
2071double
2073{
2074 NS_LOG_FUNCTION(this << m_powerRestricted << ppdu);
2075 const WifiTxVector& txVector = ppdu->GetTxVector();
2076 // Get transmit power before antenna gain
2077 double txPowerDbm;
2078 if (!m_powerRestricted)
2079 {
2080 txPowerDbm = GetPowerDbm(txVector.GetTxPowerLevel());
2081 }
2082 else
2083 {
2084 if (txVector.GetNssMax() > 1)
2085 {
2086 txPowerDbm = std::min(m_txPowerMaxMimo, GetPowerDbm(txVector.GetTxPowerLevel()));
2087 }
2088 else
2089 {
2090 txPowerDbm = std::min(m_txPowerMaxSiso, GetPowerDbm(txVector.GetTxPowerLevel()));
2091 }
2092 }
2093
2094 // Apply power density constraint on EIRP
2095 uint16_t channelWidth = ppdu->GetTransmissionChannelWidth();
2096 double txPowerDbmPerMhz =
2097 (txPowerDbm + GetTxGain()) - RatioToDb(channelWidth); // account for antenna gain since EIRP
2098 NS_LOG_INFO("txPowerDbm=" << txPowerDbm << " with txPowerDbmPerMhz=" << txPowerDbmPerMhz
2099 << " over " << channelWidth << " MHz");
2100 txPowerDbm = std::min(txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb(channelWidth);
2101 txPowerDbm -= GetTxGain(); // remove antenna gain since will be added right afterwards
2102 NS_LOG_INFO("txPowerDbm=" << txPowerDbm
2103 << " after applying m_powerDensityLimit=" << m_powerDensityLimit);
2104 return txPowerDbm;
2105}
2106
2109{
2110 // TODO: wrapper. See if still needed
2111 return GetPhyEntity(ppdu->GetModulation())->GetAddressedPsduInPpdu(ppdu);
2112}
2113
2115WifiPhy::GetBand(uint16_t /*bandWidth*/, uint8_t /*bandIndex*/)
2116{
2117 WifiSpectrumBand band;
2118 band.first = 0;
2119 band.second = 0;
2120 return band;
2121}
2122
2123int64_t
2125{
2126 NS_LOG_FUNCTION(this << stream);
2127 int64_t currentStream = stream;
2128 m_random->SetStream(currentStream++);
2129 currentStream += m_interference->GetErrorRateModel()->AssignStreams(currentStream);
2130 return (currentStream - stream);
2131}
2132
2133std::ostream&
2134operator<<(std::ostream& os, RxSignalInfo rxSignalInfo)
2135{
2136 os << "SNR:" << RatioToDb(rxSignalInfo.snr) << " dB"
2137 << ", RSSI:" << rxSignalInfo.rssi << " dBm";
2138 return os;
2139}
2140
2141uint8_t
2142WifiPhy::GetPrimaryChannelNumber(uint16_t primaryChannelWidth) const
2143{
2144 return m_operatingChannel.GetPrimaryChannelNumber(primaryChannelWidth, m_standard);
2145}
2146
2147} // namespace ns3
#define min(a, b)
Definition: 80211b.c:42
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:556
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
std::pair< int16_t, int16_t > SubcarrierRange
(lowest index, highest index) pair defining a subcarrier range
Definition: he-ru.h:52
Keep track of the current position and velocity of an object.
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
bool IsInitialized() const
Check if the object has been initialized.
Definition: object.cc:212
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
Hold variables of type string.
Definition: string.h:42
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:350
@ NS
nanosecond
Definition: nstime.h:119
bool IsStrictlyNegative() const
Exactly equivalent to t < 0.
Definition: nstime.h:341
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
AttributeValue implementation for Time.
Definition: nstime.h:1425
bool IsEmpty() const
Checks if the Callbacks list is empty.
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
bool Get160MHzOperationSupported() const
represent a single transmission mode
Definition: wifi-mode.h:50
Ptr< VhtConfiguration > GetVhtConfiguration() const
Ptr< HtConfiguration > GetHtConfiguration() const
Ptr< Node > GetNode() const override
static TypeId GetTypeId()
Get the type ID.
Definition: wifi-phy.cc:62
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1175
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1176
Time GetBlockAckTxTime() const
Return the estimated BlockAck TX time for this PHY.
Definition: wifi-phy.cc:764
double GetCcaEdThreshold() const
Return the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:467
double m_rxGainDb
Reception gain (dB)
Definition: wifi-phy.h:1422
bool IsStateTx() const
Definition: wifi-phy.cc:1956
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition: wifi-phy.h:1446
bool IsStateIdle() const
Definition: wifi-phy.cc:1944
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition: wifi-phy.cc:606
uint8_t m_txSpatialStreams
Number of supported TX spatial streams.
Definition: wifi-phy.h:1438
bool IsStateCcaBusy() const
Definition: wifi-phy.cc:1938
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
Definition: wifi-phy.cc:1635
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1175
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition: wifi-phy.h:1450
void Configure80211ax()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard.
Definition: wifi-phy.cc:872
Time m_channelSwitchDelay
Time required to switch between channel.
Definition: wifi-phy.h:1443
void SetCcaEdThreshold(double threshold)
Sets the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:460
void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration)
Notify PHY state helper to switch to CCA busy state,.
Definition: wifi-phy.cc:2005
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition: wifi-phy.h:1406
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the PHY layer drops a packet as it tries to transmit it.
Definition: wifi-phy.h:1314
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:614
bool m_channelAccessRequested
Flag if channels access has been requested (used for OBSS_PD SR)
Definition: wifi-phy.h:1433
static Time GetPayloadDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, MpduType mpdutype=NORMAL_MPDU, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1375
Time GetSlot() const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:740
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1225
Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
Definition: wifi-phy.cc:2108
void Configure80211g()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard.
Definition: wifi-phy.cc:802
uint8_t GetPrimary20Index() const
Definition: wifi-phy.cc:986
void NotifyTxEnd(WifiConstPsduMap psdus)
Public method used to fire a PhyTxEnd trace.
Definition: wifi-phy.cc:1472
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:980
std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > m_currentPreambleEvents
store event associated to a PPDU (that has a unique ID and preamble combination) whose preamble is be...
Definition: wifi-phy.h:1188
uint8_t GetNumberOfAntennas() const
Definition: wifi-phy.cc:1187
Time m_slot
Slot duration.
Definition: wifi-phy.h:1410
double m_powerDensityLimit
the power density limit (dBm/MHz)
Definition: wifi-phy.h:1426
Time GetDelayUntilIdle()
Definition: wifi-phy.cc:1980
double GetRxSensitivity() const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:454
bool GetShortPhyPreambleSupported() const
Return whether short PHY preamble is supported.
Definition: wifi-phy.cc:569
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:722
std::list< uint8_t > GetBssMembershipSelectorList() const
The WifiPhy::BssMembershipSelector() method is used (e.g., by a WifiRemoteStationManager) to determin...
Definition: wifi-phy.cc:1243
void Configure80211n()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard.
Definition: wifi-phy.cc:845
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1183
double GetTxGain() const
Return the transmission gain (dB).
Definition: wifi-phy.cc:543
double m_txPowerBaseDbm
Minimum transmission power (dBm)
Definition: wifi-phy.h:1423
Time GetDelayUntilChannelSwitch()
Perform any actions necessary when user changes operating channel after initialization.
Definition: wifi-phy.cc:1043
void Configure80211be()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11be standard.
Definition: wifi-phy.cc:887
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1523
bool IsStateRx() const
Definition: wifi-phy.cc:1950
bool IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
Check if the given MCS of the given modulation class is supported by the PHY.
Definition: wifi-phy.cc:1836
Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:728
uint16_t GetFrequency() const
Definition: wifi-phy.cc:968
Ptr< MobilityModel > GetMobility() const
Return the mobility model this PHY is associated with.
Definition: wifi-phy.cc:593
uint16_t GetNMcs() const
Definition: wifi-phy.cc:1882
Time m_blockAckTxTime
estimated BlockAck TX time
Definition: wifi-phy.h:1413
uint8_t GetPrimaryChannelNumber(uint16_t primaryChannelWidth) const
Get channel number of the primary channel.
Definition: wifi-phy.cc:2142
void ResetCca(bool powerRestricted, double txPowerMaxSiso=0, double txPowerMaxMimo=0)
Reset PHY to IDLE, with some potential TX power restrictions for the next transmission.
Definition: wifi-phy.cc:2049
double m_txPowerMaxMimo
MIMO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:1432
void ResumeFromSleep()
Resume from sleep mode.
Definition: wifi-phy.cc:1307
static Time GetPreambleDetectionDuration()
Definition: wifi-phy.cc:1363
void Configure80211p()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11p standard.
Definition: wifi-phy.cc:815
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition: wifi-phy.cc:2012
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:1448
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: wifi-phy.h:1346
void NotifyRxBegin(Ptr< const WifiPsdu > psdu, const RxPowerWattPerChannelBand &rxPowersW)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:1499
Time GetChannelSwitchDelay() const
Definition: wifi-phy.cc:665
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1193
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: wifi-phy.h:1409
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:423
bool IsStateOff() const
Definition: wifi-phy.cc:1974
uint8_t GetMaxSupportedRxSpatialStreams() const
Definition: wifi-phy.cc:1237
double GetTxPowerEnd() const
Return the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:517
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:895
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:621
WifiMode GetMcs(WifiModulationClass modulation, uint8_t mcs) const
Get the WifiMode object corresponding to the given MCS of the given modulation class.
Definition: wifi-phy.cc:1931
uint8_t m_numberOfAntennas
Number of transmitters.
Definition: wifi-phy.h:1437
ChannelTuple m_channelSettings
Store operating channel settings until initialization.
Definition: wifi-phy.h:1405
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1422
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition: wifi-phy.cc:1451
Ptr< WifiPhyStateHelper > GetState() const
Return the WifiPhyStateHelper of this PHY.
Definition: wifi-phy.cc:411
virtual Ptr< Channel > GetChannel() const =0
Return the Channel this WifiPhy is connected to.
void NotifyTxBegin(WifiConstPsduMap psdus, double txPowerW)
Public method used to fire a PhyTxBegin trace.
Definition: wifi-phy.cc:1457
void EndReceiveInterBss()
For HE receptions only, check and possibly modify the transmit power restriction state at the end of ...
Definition: wifi-phy.cc:1790
void SetSleepMode()
Put in sleep mode.
Definition: wifi-phy.cc:1258
void SetShortPhyPreambleSupported(bool preamble)
Enable or disable short PHY preamble.
Definition: wifi-phy.cc:562
void SetNTxPower(uint8_t n)
Sets the number of transmission power levels available between the minimum level and the maximum leve...
Definition: wifi-phy.cc:523
WifiPhyBand m_band
WifiPhyBand.
Definition: wifi-phy.h:1404
void SetRxSensitivity(double threshold)
Sets the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:447
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:677
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, uint16_t > m_phyMonitorSniffTxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being transmitted.
Definition: wifi-phy.h:1392
virtual WifiSpectrumBand ConvertHeRuSubcarriers(uint16_t bandWidth, uint16_t guardBandwidth, HeRu::SubcarrierRange range, uint8_t bandIndex=0) const
Definition: wifi-phy.cc:1779
double m_txPowerMaxSiso
SISO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:1430
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1211
void AddPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of supported PHY entities for the given modulation class for the WifiPh...
Definition: wifi-phy.cc:709
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, SignalNoiseDbm, uint16_t > m_phyMonitorSniffRxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being received.
Definition: wifi-phy.h:1373
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: wifi-phy.h:1451
EventId m_endTxEvent
the end of transmit event
Definition: wifi-phy.h:1184
double GetRxGain() const
Return the reception gain (dB).
Definition: wifi-phy.cc:556
static WifiConstPsduMap GetWifiConstPsduMap(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Get a WifiConstPsduMap from a PSDU and the TXVECTOR to use to send the PSDU.
Definition: wifi-phy.cc:1629
static std::map< WifiModulationClass, Ptr< PhyEntity > > & GetStaticPhyEntities()
Definition: wifi-phy.cc:404
void SetSlot(Time slot)
Set the slot duration for this PHY.
Definition: wifi-phy.cc:734
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1004
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:950
double m_ccaSensitivityThresholdW
Clear channel assessment (CCA) modulation and coding rate sensitivity threshold in watts.
Definition: wifi-phy.h:1418
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:1186
Time GetLastRxStartTime() const
Return the start time of the last received packet.
Definition: wifi-phy.cc:1986
WifiMode GetDefaultMode() const
Get the default WifiMode supported by the PHY.
Definition: wifi-phy.cc:1820
void SetCcaSensitivityThreshold(double threshold)
Sets the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:473
double m_ccaEdThresholdW
Clear channel assessment (CCA) energy detection (ED) threshold in watts.
Definition: wifi-phy.h:1416
void NotifyMonitorSniffTx(Ptr< const WifiPsdu > psdu, uint16_t channelFreqMhz, WifiTxVector txVector, uint16_t staId=SU_STA_ID)
Public method used to fire a MonitorSniffer trace for a wifi PSDU being transmitted.
Definition: wifi-phy.cc:1589
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:685
virtual WifiSpectrumBand GetBand(uint16_t bandWidth, uint8_t bandIndex=0)
Get the start band index and the stop band index for a given band.
Definition: wifi-phy.cc:2115
uint8_t GetChannelNumber() const
Return current channel number.
Definition: wifi-phy.cc:974
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
Definition: wifi-phy.h:1306
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1191
uint32_t m_rxMpduReferenceNumber
A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU.
Definition: wifi-phy.h:1180
void SetWifiRadioEnergyModel(const Ptr< WifiRadioEnergyModel > wifiRadioEnergyModel)
Sets the wifi radio energy model.
Definition: wifi-phy.cc:640
TracedCallback< Ptr< const Packet >, double > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
Definition: wifi-phy.h:1291
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:575
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:1449
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:510
Time GetPifs() const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:752
static void AddStaticPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of implemented PHY entities for the given modulation class.
Definition: wifi-phy.cc:699
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:1511
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:1758
TracedCallback< WifiConstPsduMap, WifiTxVector, double > m_phyTxPsduBeginTrace
The trace source fired when a PSDU map begins the transmission process on the medium.
Definition: wifi-phy.h:1298
double m_txGainDb
Transmission gain (dB)
Definition: wifi-phy.h:1421
bool IsStateSleep() const
Definition: wifi-phy.cc:1968
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:581
WifiStandard m_standard
WifiStandard.
Definition: wifi-phy.h:1403
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:646
uint8_t m_nTxPower
Number of available transmission power levels.
Definition: wifi-phy.h:1425
void DoDispose() override
Destructor implementation.
Definition: wifi-phy.cc:367
bool IsStateSwitching() const
Definition: wifi-phy.cc:1962
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Definition: wifi-phy.cc:1094
void SetOffMode()
Put in off mode.
Definition: wifi-phy.cc:1292
double m_noiseFigureDb
The noise figure in dB.
Definition: wifi-phy.h:1441
TracedCallback< Ptr< const Packet >, WifiPhyRxfailureReason > m_phyRxDropTrace
The trace source fired when the PHY layer drops a packet it has received.
Definition: wifi-phy.h:1353
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:634
void SetPifs(Time pifs)
Set the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:746
void Configure80211b()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard.
Definition: wifi-phy.cc:785
static Time GetStartOfPacketDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1369
void UnregisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:435
void SetRxGain(double gain)
Sets the reception gain (dB).
Definition: wifi-phy.cc:549
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:587
void SetTxGain(double gain)
Sets the transmission gain (dB).
Definition: wifi-phy.cc:536
uint8_t m_rxSpatialStreams
Number of supported RX spatial streams.
Definition: wifi-phy.h:1439
double m_txPowerEndDbm
Maximum transmission power (dBm)
Definition: wifi-phy.h:1424
double CalculateSnr(const WifiTxVector &txVector, double ber) const
Definition: wifi-phy.cc:671
void SetFixedPhyBand(bool enable)
Configure whether it is prohibited to change PHY band after initialization.
Definition: wifi-phy.cc:992
~WifiPhy() override
Definition: wifi-phy.cc:361
void Configure80211ac()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard.
Definition: wifi-phy.cc:864
bool HasFixedPhyBand() const
Definition: wifi-phy.cc:998
TracedCallback< Ptr< const Packet >, RxPowerWattPerChannelBand > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition: wifi-phy.h:1322
void RegisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:429
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition: wifi-phy.h:1445
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition: wifi-phy.h:1173
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition: wifi-phy.h:1436
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: wifi-phy.h:1411
void SetRxNoiseFigure(double noiseFigureDb)
Sets the RX loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver.
Definition: wifi-phy.cc:486
double GetTxPowerStart() const
Return the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:504
double GetTxPowerForTransmission(Ptr< const WifiPpdu > ppdu) const
Compute the transmit power for the next transmission.
Definition: wifi-phy.cc:2072
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:956
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition: wifi-phy.cc:441
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:417
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:628
void NotifyChannelAccessRequested()
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:1800
void ResumeFromOff()
Resume from off mode.
Definition: wifi-phy.cc:1335
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition: wifi-phy.h:1428
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition: wifi-phy.h:1454
void NotifyMonitorSniffRx(Ptr< const WifiPsdu > psdu, uint16_t channelFreqMhz, WifiTxVector txVector, SignalNoiseDbm signalNoise, std::vector< bool > statusPerMpdu, uint16_t staId=SU_STA_ID)
Public method used to fire a MonitorSniffer trace for a wifi PSDU being received.
Definition: wifi-phy.cc:1535
Time GetAckTxTime() const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:758
uint64_t GetPreviouslyRxPpduUid() const
Definition: wifi-phy.cc:1739
void Reset()
Reset data upon end of TX or RX.
Definition: wifi-phy.cc:1745
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:1338
Time GetLastRxEndTime() const
Return the end time of the last received packet.
Definition: wifi-phy.cc:1992
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:869
uint8_t GetMaxSupportedTxSpatialStreams() const
Definition: wifi-phy.cc:1219
void Configure80211a()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard.
Definition: wifi-phy.cc:770
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:1896
std::list< WifiMode > GetModeList() const
The WifiPhy::GetModeList() method is used (e.g., by a WifiRemoteStationManager) to determine the set ...
Definition: wifi-phy.cc:1847
void SwitchMaybeToCcaBusy(const Ptr< const WifiPpdu > ppdu)
Check if PHY state should move to CCA busy state based on current state of interference tracker.
Definition: wifi-phy.cc:1998
virtual void StartTx(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector)=0
double m_rxSensitivityW
Receive sensitivity threshold in watts.
Definition: wifi-phy.h:1415
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:962
double GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:480
bool m_fixedPhyBand
True to prohibit changing PHY band after initialization.
Definition: wifi-phy.h:1407
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:497
uint8_t GetNTxPower() const
Return the number of available transmission power levels.
Definition: wifi-phy.cc:530
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: wifi-phy.cc:2124
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1415
bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:1807
Time m_ackTxTime
estimated Ack TX time
Definition: wifi-phy.h:1412
void NotifyTxDrop(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:1487
receive notifications about PHY events.
Class that keeps track of all information about the current PHY operating channel.
bool IsSet() const
Return true if a valid channel has been set, false otherwise.
uint8_t GetPrimaryChannelIndex(uint16_t primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
void Set(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band)
Set the channel according to the specified parameters if a unique frequency channel matches the speci...
uint8_t GetPrimaryChannelNumber(uint16_t primaryChannelWidth, WifiStandard standard) const
Get channel number of the primary channel.
uint16_t GetWidth() const
Return the width of the whole operating channel (in MHz).
static uint8_t GetDefaultChannelNumber(uint16_t width, WifiStandard standard, WifiPhyBand band)
Get the default channel number of the given width and for the given standard and band.
uint8_t GetNumber() const
Return the channel number identifying the whole operating channel.
uint16_t GetFrequency() const
Return the center frequency of the operating channel (in MHz).
Ptr< const Packet > GetPacket() const
Get the PSDU as a single packet.
Definition: wifi-psdu.cc:89
Ptr< Packet > GetAmpduSubframe(std::size_t i) const
Get a copy of the i-th A-MPDU subframe (includes subframe header, MPDU, and possibly padding)
Definition: wifi-psdu.cc:287
bool IsAggregate() const
Return true if the PSDU is an S-MPDU or A-MPDU.
Definition: wifi-psdu.cc:83
bool IsSingle() const
Return true if the PSDU is an S-MPDU.
Definition: wifi-psdu.cc:77
std::size_t GetNMpdus() const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:317
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
uint8_t GetNssMax() const
uint8_t GetTxPowerLevel() const
bool IsAggregation() const
Checks whether the PSDU contains A-MPDU.
#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 > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:230
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1426
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:160
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#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_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1362
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
MpduType
The type of an MPDU.
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ OBSS_PD_CCA_RESET
@ RECEPTION_ABORTED_BY_TX
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
Definition: wifi-phy-band.h:43
@ 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)
@ OFDM_PHY_10_MHZ
Definition: ofdm-phy.h:46
@ OFDM_PHY_5_MHZ
Definition: ofdm-phy.h:47
@ WIFI_CHANLIST_PRIMARY
@ LAST_MPDU_IN_AGGREGATE
The MPDU is the last aggregate in an A-MPDU with multiple MPDUs.
@ NORMAL_MPDU
The MPDU is not part of an A-MPDU.
@ FIRST_MPDU_IN_AGGREGATE
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate.
@ SINGLE_MPDU
The MPDU is a single MPDU.
@ MIDDLE_MPDU_IN_AGGREGATE
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:52
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:46
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:40
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:78
WifiPhyBand GetDefaultPhyBand(WifiStandard standard)
Get the default PHY band for the given standard.
WifiModulationClass GetModulationClassForStandard(WifiStandard standard)
Return the modulation class corresponding to a given standard.
uint16_t GetDefaultChannelWidth(WifiStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
double DbToRatio(double dB)
Convert from dB to ratio.
Definition: wifi-utils.cc:34
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
mobility
Definition: third.py:96
def start()
Definition: core.py:1861
#define list
MpduInfo structure.
Definition: phy-entity.h:63
MpduType type
type of MPDU
Definition: phy-entity.h:64
uint32_t mpduRefNumber
MPDU ref number.
Definition: phy-entity.h:65
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
SignalNoiseDbm structure.
Definition: phy-entity.h:56
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ SWITCHING
The PHY layer is switching to other channel.
@ RX
The PHY layer is receiving a packet.
@ TX
The PHY layer is sending a packet.
@ OFF
The PHY layer is switched off.
@ SLEEP
The PHY layer is sleeping.
@ IDLE
The PHY layer is IDLE.
Declaration of ns3::WifiPpdu class and ns3::WifiConstPsduMap.