A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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",
73 MakePointerChecker<Channel>())
74 .AddAttribute(
75 "ChannelSettings",
76 "Tuple {channel number, channel width (MHz), PHY band, primary20 index} "
77 "describing the settings of the operating channel. The primary20 index is "
78 "the index of the primary 20 MHz channel within the operating channel "
79 "(0 indicates the 20 MHz subchannel with the lowest center frequency) and "
80 "is only valid if the width of the operating channel is a multiple of 20 MHz. "
81 "If the standard for this object has not been set yet, the value of this "
82 "attribute is saved and will be used to set the operating channel when the "
83 "standard is configured. If the PHY band is left unspecified, the default "
84 "band for the configured standard is used. If the channel width and the "
85 "channel number are both 0, the default channel width for the configured "
86 "standard and band are used. If the channel number is 0, the default "
87 "channel number for the configured standard, band and channel width is used."
88 "Note that the channel width can be left unspecified (0) if the channel "
89 "number uniquely identify a frequency channel for the given standard and band.",
90 StringValue("{0, 0, BAND_UNSPECIFIED, 0}"),
91 MakeTupleAccessor<UintegerValue, UintegerValue, EnumValue, UintegerValue>(
93 MakeTupleChecker<UintegerValue, UintegerValue, EnumValue, UintegerValue>(
94 MakeUintegerChecker<uint8_t>(0, 233),
95 MakeUintegerChecker<uint16_t>(0, 160),
97 "BAND_2_4GHZ",
99 "BAND_5GHZ",
101 "BAND_6GHZ",
103 "BAND_UNSPECIFIED"),
104 MakeUintegerChecker<uint8_t>(0, 7)))
105 .AddAttribute("Frequency",
106 "The center frequency (MHz) of the current operating channel.",
108 UintegerValue(0),
110 MakeUintegerChecker<uint16_t>())
111 .AddAttribute("ChannelNumber",
112 "The channel number of the current operating channel.",
114 UintegerValue(0),
116 MakeUintegerChecker<uint8_t>(0, 233))
117 .AddAttribute(
118 "ChannelWidth",
119 "The width in MHz of the current operating channel (5, 10, 20, 22, 40, 80 or 160).",
121 UintegerValue(0),
123 MakeUintegerChecker<uint16_t>(5, 160))
124 .AddAttribute(
125 "Primary20MHzIndex",
126 "The index of the primary 20 MHz channel within the current operating channel "
127 "(0 indicates the 20 MHz subchannel with the lowest center frequency).",
128 UintegerValue(0),
130 MakeUintegerChecker<uint8_t>(0, 7))
131 .AddAttribute("FixedPhyBand",
132 "If set to true, changing PHY band is prohibited after initialization.",
133 BooleanValue(false),
136 .AddAttribute(
137 "RxSensitivity",
138 "The energy of a received signal should be higher than "
139 "this threshold (dBm) for the PHY to detect the signal. "
140 "This threshold refers to a width of 20 MHz and will be "
141 "scaled to match the width of the received signal.",
142 DoubleValue(-101.0),
144 MakeDoubleChecker<double>())
145 .AddAttribute(
146 "CcaEdThreshold",
147 "The energy of all received signals should be higher than "
148 "this threshold (dBm) in the primary channel to allow the PHY layer "
149 "to declare CCA BUSY state.",
150 DoubleValue(-62.0),
152 MakeDoubleChecker<double>())
153 .AddAttribute("CcaSensitivity",
154 "The energy of a received wifi signal should be higher than "
155 "this threshold (dBm) in the primary channel to allow the PHY layer "
156 "to declare CCA BUSY state.",
157 DoubleValue(-82.0),
160 MakeDoubleChecker<double>())
161 .AddAttribute("TxGain",
162 "Transmission gain (dB).",
163 DoubleValue(0.0),
165 MakeDoubleChecker<double>())
166 .AddAttribute("RxGain",
167 "Reception gain (dB).",
168 DoubleValue(0.0),
170 MakeDoubleChecker<double>())
171 .AddAttribute("TxPowerLevels",
172 "Number of transmission power levels available between "
173 "TxPowerStart and TxPowerEnd included.",
174 UintegerValue(1),
176 MakeUintegerChecker<uint8_t>())
177 .AddAttribute("TxPowerEnd",
178 "Maximum available transmission level (dBm).",
179 DoubleValue(16.0206),
181 MakeDoubleChecker<double>())
182 .AddAttribute("TxPowerStart",
183 "Minimum available transmission level (dBm).",
184 DoubleValue(16.0206),
186 MakeDoubleChecker<double>())
187 .AddAttribute(
188 "RxNoiseFigure",
189 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
190 " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
191 "\"the difference in decibels (dB) between"
192 " the noise output of the actual receiver to the noise output of an "
193 " ideal receiver with the same overall gain and bandwidth when the receivers "
194 " are connected to sources at the standard noise temperature T0 (usually 290 K)\".",
195 DoubleValue(7),
197 MakeDoubleChecker<double>())
198 .AddAttribute("State",
199 "The state of the PHY layer.",
200 PointerValue(),
202 MakePointerChecker<WifiPhyStateHelper>())
203 .AddAttribute("ChannelSwitchDelay",
204 "Delay between two short frames transmitted on different frequencies.",
208 .AddAttribute(
209 "Antennas",
210 "The number of antennas on the device.",
211 UintegerValue(1),
213 MakeUintegerChecker<uint8_t>(1, 8))
214 .AddAttribute("MaxSupportedTxSpatialStreams",
215 "The maximum number of supported TX spatial streams."
216 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
217 UintegerValue(1),
220 MakeUintegerChecker<uint8_t>(1, 8))
221 .AddAttribute("MaxSupportedRxSpatialStreams",
222 "The maximum number of supported RX spatial streams."
223 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
224 UintegerValue(1),
227 MakeUintegerChecker<uint8_t>(1, 8))
228 .AddAttribute("ShortPlcpPreambleSupported",
229 "Whether or not short PHY preamble is supported."
230 "This parameter is only valuable for 802.11b STAs and APs."
231 "Note: 802.11g APs and STAs always support short PHY preamble.",
232 BooleanValue(false),
236 .AddAttribute("FrameCaptureModel",
237 "Ptr to an object that implements the frame capture model",
238 PointerValue(),
240 MakePointerChecker<FrameCaptureModel>())
241 .AddAttribute("PreambleDetectionModel",
242 "Ptr to an object that implements the preamble detection model",
243 PointerValue(),
245 MakePointerChecker<PreambleDetectionModel>())
246 .AddAttribute("PostReceptionErrorModel",
247 "An optional packet error model can be added to the receive "
248 "packet process after any propagation-based (SNR-based) error "
249 "models have been applied. Typically this is used to force "
250 "specific packet drops, for testing purposes.",
251 PointerValue(),
253 MakePointerChecker<ErrorModel>())
254 .AddAttribute("InterferenceHelper",
255 "Ptr to an object that implements the interference helper",
256 PointerValue(),
258 MakePointerChecker<InterferenceHelper>())
259 .AddAttribute("Sifs",
260 "The duration of the Short Interframe Space. "
261 "NOTE that the default value is overwritten by the value defined "
262 "by the standard; if you want to set this attribute, you have to "
263 "do it after that the PHY object is initialized.",
267 .AddAttribute("Slot",
268 "The duration of a slot. "
269 "NOTE that the default value is overwritten by the value defined "
270 "by the standard; if you want to set this attribute, you have to "
271 "do it after that the PHY object is initialized.",
275 .AddAttribute("Pifs",
276 "The duration of the PCF Interframe Space. "
277 "NOTE that the default value is overwritten by the value defined "
278 "by the standard; if you want to set this attribute, you have to "
279 "do it after that the PHY object is initialized.",
283 .AddAttribute("PowerDensityLimit",
284 "The mean equivalent isotropically radiated power density"
285 "limit (in dBm/MHz) set by regulators.",
286 DoubleValue(100.0), // set to a high value so as to have no effect
288 MakeDoubleChecker<double>())
289 .AddTraceSource("PhyTxBegin",
290 "Trace source indicating a packet "
291 "has begun transmitting over the channel medium",
293 "ns3::WifiPhy::PhyTxBeginTracedCallback")
294 .AddTraceSource("PhyTxPsduBegin",
295 "Trace source indicating a PSDU "
296 "has begun transmitting over the channel medium",
298 "ns3::WifiPhy::PsduTxBeginCallback")
299 .AddTraceSource("PhyTxEnd",
300 "Trace source indicating a packet "
301 "has been completely transmitted over the channel.",
303 "ns3::Packet::TracedCallback")
304 .AddTraceSource("PhyTxDrop",
305 "Trace source indicating a packet "
306 "has been dropped by the device during transmission",
308 "ns3::Packet::TracedCallback")
309 .AddTraceSource("PhyRxBegin",
310 "Trace source indicating a packet "
311 "has begun being received from the channel medium "
312 "by the device",
314 "ns3::WifiPhy::PhyRxBeginTracedCallback")
315 .AddTraceSource("PhyRxPayloadBegin",
316 "Trace source indicating the reception of the "
317 "payload of a PPDU has begun",
319 "ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
320 .AddTraceSource("PhyRxEnd",
321 "Trace source indicating a packet "
322 "has been completely received from the channel medium "
323 "by the device",
325 "ns3::Packet::TracedCallback")
326 .AddTraceSource("PhyRxDrop",
327 "Trace source indicating a packet "
328 "has been dropped by the device during reception",
330 "ns3::Packet::TracedCallback")
331 .AddTraceSource("MonitorSnifferRx",
332 "Trace source simulating a wifi device in monitor mode "
333 "sniffing all received frames",
335 "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
336 .AddTraceSource("MonitorSnifferTx",
337 "Trace source simulating the capability of a wifi device "
338 "in monitor mode to sniff all frames being transmitted",
340 "ns3::WifiPhy::MonitorSnifferTxTracedCallback");
341 return tid;
342}
343
345 : m_txMpduReferenceNumber(0xffffffff),
346 m_rxMpduReferenceNumber(0xffffffff),
347 m_endPhyRxEvent(),
348 m_endTxEvent(),
349 m_currentEvent(nullptr),
350 m_previouslyRxPpduUid(UINT64_MAX),
351 m_standard(WIFI_STANDARD_UNSPECIFIED),
353 m_sifs(Seconds(0)),
354 m_slot(Seconds(0)),
355 m_pifs(Seconds(0)),
356 m_ackTxTime(Seconds(0)),
357 m_blockAckTxTime(Seconds(0)),
358 m_powerRestricted(false),
359 m_channelAccessRequested(false),
360 m_txSpatialStreams(1),
361 m_rxSpatialStreams(1),
362 m_wifiRadioEnergyModel(nullptr),
363 m_timeLastPreambleDetected(Seconds(0))
364{
365 NS_LOG_FUNCTION(this);
366 m_random = CreateObject<UniformRandomVariable>();
367 m_state = CreateObject<WifiPhyStateHelper>();
368}
369
371{
372 NS_LOG_FUNCTION(this);
373}
374
375void
377{
378 NS_LOG_FUNCTION(this);
379
380 // This method ensures that the local mobility model pointer holds
381 // a pointer to the Node's aggregated mobility model (if one exists)
382 // in the case that the user has not directly called SetMobility()
383 // on this WifiPhy during simulation setup. If the mobility model
384 // needs to be added or changed during simulation runtime, users must
385 // call SetMobility() on this object.
386
387 if (!m_mobility)
388 {
390 "Either install a MobilityModel on this object or ensure that this "
391 "object is part of a Node and NetDevice");
393 if (!m_mobility)
394 {
395 NS_LOG_WARN("Mobility not found, propagation models might not work properly");
396 }
397 }
398}
399
400void
402{
403 NS_LOG_FUNCTION(this);
406 for (auto& phyEntity : m_phyEntities)
407 {
408 phyEntity.second->CancelAllEvents();
409 }
410 m_device = nullptr;
411 m_mobility = nullptr;
412 m_frameCaptureModel = nullptr;
413 m_preambleDetectionModel = nullptr;
414 m_wifiRadioEnergyModel = nullptr;
416 if (m_interference)
417 {
418 m_interference->Dispose();
419 }
420 m_interference = nullptr;
421 m_random = nullptr;
422 m_state = nullptr;
423 m_currentEvent = nullptr;
424 for (auto& preambleEvent : m_currentPreambleEvents)
425 {
426 preambleEvent.second = nullptr;
427 }
429
430 for (auto& phyEntity : m_phyEntities)
431 {
432 phyEntity.second = nullptr;
433 }
434 m_phyEntities.clear();
435}
436
437std::map<WifiModulationClass, Ptr<PhyEntity>>&
439{
440 static std::map<WifiModulationClass, Ptr<PhyEntity>> g_staticPhyEntities;
441 return g_staticPhyEntities;
442}
443
446{
447 return m_state;
448}
449
450void
452{
453 m_state->SetReceiveOkCallback(callback);
454}
455
456void
458{
459 m_state->SetReceiveErrorCallback(callback);
460}
461
462void
464{
465 m_state->RegisterListener(listener);
466}
467
468void
470{
471 m_state->UnregisterListener(listener);
472}
473
474void
476{
478}
479
480void
482{
483 NS_LOG_FUNCTION(this << threshold);
484 m_rxSensitivityW = DbmToW(threshold);
485}
486
487double
489{
490 return WToDbm(m_rxSensitivityW);
491}
492
493void
495{
496 NS_LOG_FUNCTION(this << threshold);
497 m_ccaEdThresholdW = DbmToW(threshold);
498}
499
500double
502{
504}
505
506void
508{
509 NS_LOG_FUNCTION(this << threshold);
511}
512
513double
515{
517}
518
519void
520WifiPhy::SetRxNoiseFigure(double noiseFigureDb)
521{
522 NS_LOG_FUNCTION(this << noiseFigureDb);
523 if (m_interference)
524 {
525 m_interference->SetNoiseFigure(DbToRatio(noiseFigureDb));
526 }
527 m_noiseFigureDb = noiseFigureDb;
528}
529
530void
532{
533 NS_LOG_FUNCTION(this << start);
534 m_txPowerBaseDbm = start;
535}
536
537double
539{
540 return m_txPowerBaseDbm;
541}
542
543void
545{
546 NS_LOG_FUNCTION(this << end);
547 m_txPowerEndDbm = end;
548}
549
550double
552{
553 return m_txPowerEndDbm;
554}
555
556void
558{
559 NS_LOG_FUNCTION(this << +n);
560 m_nTxPower = n;
561}
562
563uint8_t
565{
566 return m_nTxPower;
567}
568
569void
571{
572 NS_LOG_FUNCTION(this << gain);
573 m_txGainDb = gain;
574}
575
576double
578{
579 return m_txGainDb;
580}
581
582void
584{
585 NS_LOG_FUNCTION(this << gain);
586 m_rxGainDb = gain;
587}
588
589double
591{
592 return m_rxGainDb;
593}
594
595void
597{
598 NS_LOG_FUNCTION(this << enable);
599 m_shortPreamble = enable;
600}
601
602bool
604{
605 return m_shortPreamble;
606}
607
608void
610{
611 m_device = device;
612}
613
616{
617 return m_device;
618}
619
620void
622{
623 m_mobility = mobility;
624}
625
628{
629 return m_mobility;
630}
631
632void
634{
635 m_interference = helper;
636 m_interference->SetNoiseFigure(DbToRatio(m_noiseFigureDb));
637 m_interference->SetNumberOfReceiveAntennas(m_numberOfAntennas);
638}
639
640void
642{
644 m_interference->SetErrorRateModel(model);
645}
646
647void
649{
650 NS_LOG_FUNCTION(this << em);
652}
653
654void
656{
657 m_frameCaptureModel = model;
658}
659
660void
662{
664}
665
666void
668{
669 m_wifiRadioEnergyModel = wifiRadioEnergyModel;
670}
671
672double
673WifiPhy::GetPowerDbm(uint8_t power) const
674{
677 double dbm;
678 if (m_nTxPower > 1)
679 {
681 }
682 else
683 {
685 "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
686 dbm = m_txPowerBaseDbm;
687 }
688 return dbm;
689}
690
691Time
693{
695}
696
697double
698WifiPhy::CalculateSnr(const WifiTxVector& txVector, double ber) const
699{
700 return m_interference->GetErrorRateModel()->CalculateSnr(txVector, ber);
701}
702
705{
706 const auto it = GetStaticPhyEntities().find(modulation);
708 "Unimplemented Wi-Fi modulation class " << modulation);
709 return it->second;
710}
711
714{
715 const auto it = m_phyEntities.find(modulation);
716 NS_ABORT_MSG_IF(it == m_phyEntities.cend(),
717 "Unsupported Wi-Fi modulation class " << modulation);
718 return it->second;
719}
720
723{
725}
726
729{
730 return GetPhyEntity(m_standard);
731}
732
735{
736 NS_ABORT_IF(!ppdu);
737 const auto modulation = ppdu->GetModulation();
738 if (modulation > m_phyEntities.rbegin()->first)
739 {
740 // unsupported modulation: start reception process with latest PHY entity
741 return GetLatestPhyEntity();
742 }
743 if (modulation < WIFI_MOD_CLASS_HT)
744 {
745 // for non-HT (duplicate), call the latest PHY entity since some extra processing can be
746 // done in PHYs implemented in HT and later (e.g. channel width selection for non-HT
747 // duplicates)
748 return GetLatestPhyEntity();
749 }
750 return GetPhyEntity(modulation);
751}
752
753void
755{
756 NS_LOG_FUNCTION(modulation);
757 NS_ASSERT_MSG(GetStaticPhyEntities().find(modulation) == GetStaticPhyEntities().end(),
758 "The PHY entity has already been added. The setting should only be done once per "
759 "modulation class");
760 GetStaticPhyEntities()[modulation] = phyEntity;
761}
762
763void
765{
766 NS_LOG_FUNCTION(this << modulation);
767 NS_ABORT_MSG_IF(GetStaticPhyEntities().find(modulation) == GetStaticPhyEntities().end(),
768 "Cannot add an unimplemented PHY to supported list. Update the former first.");
769 NS_ASSERT_MSG(m_phyEntities.find(modulation) == m_phyEntities.end(),
770 "The PHY entity has already been added. The setting should only be done once per "
771 "modulation class");
772 phyEntity->SetOwner(this);
773 m_phyEntities[modulation] = phyEntity;
774}
775
776void
778{
779 m_sifs = sifs;
780}
781
782Time
784{
785 return m_sifs;
786}
787
788void
790{
791 m_slot = slot;
792}
793
794Time
796{
797 return m_slot;
798}
799
800void
802{
803 m_pifs = pifs;
804}
805
806Time
808{
809 return m_pifs;
810}
811
812Time
814{
815 return m_ackTxTime;
816}
817
818Time
820{
821 return m_blockAckTxTime;
822}
823
824void
826{
827 NS_LOG_FUNCTION(this);
828 AddPhyEntity(WIFI_MOD_CLASS_OFDM, Create<OfdmPhy>());
829
830 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
833 SetPifs(GetSifs() + GetSlot());
834 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
835 // of the PPDU causing the EIFS" of 802.11-2016
837}
838
839void
841{
842 NS_LOG_FUNCTION(this);
843 Ptr<DsssPhy> phyEntity = Create<DsssPhy>();
845 AddPhyEntity(WIFI_MOD_CLASS_DSSS, phyEntity); // when plain DSSS modes are used
846
847 // See Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2016
850 SetPifs(GetSifs() + GetSlot());
851 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
852 // of the PPDU causing the EIFS" of 802.11-2016
854}
855
856void
858{
859 NS_LOG_FUNCTION(this);
860 // See Table 18-5 "ERP characteristics" of 802.11-2016
861 // Slot time defaults to the "long slot time" of 20 us in the standard
862 // according to mixed 802.11b/g deployments. Short slot time is enabled
863 // if the user sets the ShortSlotTimeSupported flag to true and when the BSS
864 // consists of only ERP STAs capable of supporting this option.
866 AddPhyEntity(WIFI_MOD_CLASS_ERP_OFDM, Create<ErpOfdmPhy>());
867}
868
869void
871{
872 NS_LOG_FUNCTION(this);
873 if (GetChannelWidth() == 10)
874 {
876
877 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
880 SetPifs(GetSifs() + GetSlot());
882 }
883 else if (GetChannelWidth() == 5)
884 {
886
887 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
890 SetPifs(GetSifs() + GetSlot());
892 }
893 else
894 {
895 NS_FATAL_ERROR("802.11p configured with a wrong channel width!");
896 }
897}
898
899void
901{
902 NS_LOG_FUNCTION(this);
904 {
906 }
907 else
908 {
910 }
912
913 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
914 // of the PPDU causing the EIFS" of 802.11-2016
916}
917
918void
920{
921 NS_LOG_FUNCTION(this);
923 AddPhyEntity(WIFI_MOD_CLASS_VHT, Create<VhtPhy>());
924}
925
926void
928{
929 NS_LOG_FUNCTION(this);
931 {
933 }
934 else
935 {
937 }
938 AddPhyEntity(WIFI_MOD_CLASS_HE, Create<HePhy>());
939}
940
941void
943{
944 NS_LOG_FUNCTION(this);
946 AddPhyEntity(WIFI_MOD_CLASS_EHT, Create<EhtPhy>());
947}
948
949void
951{
952 NS_LOG_FUNCTION(this << standard);
953
955 "Cannot change standard");
956
957 m_standard = standard;
958
960 {
961 NS_LOG_DEBUG("Setting the operating channel first");
963 // return because we are called back by SetOperatingChannel
964 return;
965 }
966
967 // this function is called when changing PHY band, hence we have to delete
968 // the previous PHY entities
969 m_phyEntities.clear();
970
971 switch (standard)
972 {
975 break;
978 break;
981 break;
984 break;
987 break;
990 break;
993 break;
996 break;
998 default:
999 NS_ASSERT_MSG(false, "Unsupported standard");
1000 break;
1001 }
1002}
1003
1006{
1007 return m_band;
1008}
1009
1012{
1013 return m_standard;
1014}
1015
1018{
1019 return m_operatingChannel;
1020}
1021
1022uint16_t
1024{
1026}
1027
1028uint8_t
1030{
1032}
1033
1034uint16_t
1036{
1038}
1039
1040uint8_t
1042{
1044}
1045
1046void
1048{
1049 m_fixedPhyBand = enable;
1050}
1051
1052bool
1054{
1055 return m_fixedPhyBand;
1056}
1057
1058uint16_t
1059WifiPhy::GetTxBandwidth(WifiMode mode, uint16_t maxAllowedWidth) const
1060{
1061 auto modulation = mode.GetModulationClass();
1062 if (modulation == WIFI_MOD_CLASS_DSSS || modulation == WIFI_MOD_CLASS_HR_DSSS)
1063 {
1064 return 22;
1065 }
1066
1067 return std::min({GetChannelWidth(), GetMaximumChannelWidth(modulation), maxAllowedWidth});
1068}
1069
1070void
1072{
1073 NS_LOG_FUNCTION(this << channel);
1074 WifiPhy::ChannelTuple tuple(channel.GetNumber(),
1075 channel.GetWidth(),
1076 channel.GetPhyBand(),
1077 channel.GetPrimaryChannelIndex(20));
1078 SetOperatingChannel(tuple);
1079}
1080
1081void
1083{
1084 // the generic operator<< for tuples does not give a pretty result
1085 NS_LOG_FUNCTION(this << +std::get<0>(channelTuple) << std::get<1>(channelTuple)
1086 << static_cast<WifiPhyBand>(std::get<2>(channelTuple))
1087 << +std::get<3>(channelTuple));
1088
1089 m_channelSettings = channelTuple;
1090
1092 {
1093 NS_LOG_DEBUG("Channel information will be applied when a standard is configured");
1094 return;
1095 }
1096
1097 Time delay = Seconds(0);
1098
1099 if (IsInitialized())
1100 {
1102 }
1103
1104 if (delay.IsStrictlyNegative())
1105 {
1106 // switching channel is not possible now
1107 return;
1108 }
1109 if (delay.IsStrictlyPositive())
1110 {
1111 // switching channel has been postponed
1112 void (WifiPhy::*fp)(const ChannelTuple&) = &WifiPhy::SetOperatingChannel;
1113 Simulator::Schedule(delay, fp, this, channelTuple);
1114 return;
1115 }
1116
1117 // channel can be switched now.
1119}
1120
1121Time
1123{
1124 m_powerRestricted = false;
1126 m_currentEvent = nullptr;
1128 if (!IsInitialized())
1129 {
1130 // this is not channel switch, this is initialization
1131 NS_LOG_DEBUG("Before initialization, nothing to do");
1132 return Seconds(0);
1133 }
1134
1135 Time delay = Seconds(0);
1136
1138 switch (m_state->GetState())
1139 {
1140 case WifiPhyState::RX:
1141 NS_LOG_DEBUG("drop packet because of channel switching while reception");
1143 break;
1144 case WifiPhyState::TX:
1145 NS_LOG_DEBUG("channel switching postponed until end of current transmission");
1146 delay = GetDelayUntilIdle();
1147 break;
1148 case WifiPhyState::CCA_BUSY:
1149 case WifiPhyState::IDLE:
1151 for (auto& phyEntity : m_phyEntities)
1152 {
1153 phyEntity.second->CancelAllEvents();
1154 }
1155 break;
1156 case WifiPhyState::SLEEP:
1157 NS_LOG_DEBUG("channel switching ignored in sleep mode");
1158 delay = Seconds(-1); // negative value to indicate switching not possible
1159 break;
1160 default:
1161 NS_ASSERT(false);
1162 break;
1163 }
1164
1165 return delay;
1166}
1167
1168void
1170{
1171 NS_LOG_FUNCTION(this);
1172
1173 // Update unspecified parameters with default values
1174 {
1175 auto& [number, width, band, primary20] = m_channelSettings;
1176 if (band == static_cast<int>(WIFI_PHY_BAND_UNSPECIFIED))
1177 {
1178 band = static_cast<int>(GetDefaultPhyBand(m_standard));
1179 }
1180 if (width == 0 && number == 0)
1181 {
1182 width = GetDefaultChannelWidth(m_standard, static_cast<WifiPhyBand>(band));
1183 }
1184 if (number == 0)
1185 {
1186 number =
1188 m_standard,
1189 static_cast<WifiPhyBand>(band));
1190 }
1191 }
1192
1193 // We need to call SetStandard if this is the first time we set a channel or we
1194 // are changing PHY band. Checking if the new PHY band is different than the
1195 // previous one covers both cases because initially the PHY band is unspecified
1196 bool changingPhyBand = (static_cast<WifiPhyBand>(std::get<2>(m_channelSettings)) != m_band);
1197
1198 NS_ABORT_MSG_IF(IsInitialized() && m_fixedPhyBand && changingPhyBand,
1199 "Trying to change PHY band while prohibited.");
1200
1201 m_band = static_cast<WifiPhyBand>(std::get<2>(m_channelSettings));
1202
1203 // check that the channel width is supported
1204 uint16_t chWidth = std::get<1>(m_channelSettings);
1205
1206 if (m_device)
1207 {
1208 if (auto htConfig = m_device->GetHtConfiguration();
1209 htConfig && !htConfig->Get40MHzOperationSupported() && chWidth > 20)
1210 {
1211 NS_ABORT_MSG("Attempting to set a " << chWidth
1212 << " MHz channel on"
1213 "a station only supporting 20 MHz operation");
1214 }
1215
1216 if (auto vhtConfig = m_device->GetVhtConfiguration();
1217 vhtConfig && !vhtConfig->Get160MHzOperationSupported() && chWidth > 80)
1218 {
1219 NS_ABORT_MSG("Attempting to set a " << chWidth
1220 << " MHz channel on"
1221 "a station supporting up to 80 MHz operation");
1222 }
1223 }
1224
1225 NS_LOG_DEBUG("switching channel");
1226 m_operatingChannel.Set(std::get<0>(m_channelSettings), 0, chWidth, m_standard, m_band);
1228
1229 if (changingPhyBand)
1230 {
1232 }
1233
1234 if (IsInitialized())
1235 {
1236 // notify channel switching
1237 m_state->SwitchToChannelSwitching(GetChannelSwitchDelay());
1238 /*
1239 * Needed here to be able to correctly sensed the medium for the first
1240 * time after the switching. The actual switching is not performed until
1241 * after m_channelSwitchDelay. Packets received during the switching
1242 * state are added to the event list and are employed later to figure
1243 * out the state of the medium after the switching.
1244 */
1245 }
1246}
1247
1248void
1250{
1251 NS_LOG_FUNCTION(this << +antennas);
1252 NS_ASSERT_MSG(antennas > 0 && antennas <= 4, "unsupported number of antennas");
1253 m_numberOfAntennas = antennas;
1254 if (m_interference)
1255 {
1256 m_interference->SetNumberOfReceiveAntennas(antennas);
1257 }
1258}
1259
1260uint8_t
1262{
1263 return m_numberOfAntennas;
1264}
1265
1266void
1268{
1269 NS_ASSERT(streams <= GetNumberOfAntennas());
1270 bool changed = (m_txSpatialStreams != streams);
1271 m_txSpatialStreams = streams;
1272 if (changed)
1273 {
1274 auto phyEntity = m_phyEntities.find(WIFI_MOD_CLASS_HT);
1275 if (phyEntity != m_phyEntities.end())
1276 {
1277 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity->second);
1278 if (htPhy)
1279 {
1280 htPhy->SetMaxSupportedNss(
1281 m_txSpatialStreams); // this is essential to have the right MCSs configured
1282 }
1283
1285 {
1287 }
1288 }
1289 }
1290}
1291
1292uint8_t
1294{
1295 return m_txSpatialStreams;
1296}
1297
1298void
1300{
1301 NS_ASSERT(streams <= GetNumberOfAntennas());
1302 bool changed = (m_rxSpatialStreams != streams);
1303 m_rxSpatialStreams = streams;
1304 if (changed && !m_capabilitiesChangedCallback.IsNull())
1305 {
1307 }
1308}
1309
1310uint8_t
1312{
1313 return m_rxSpatialStreams;
1314}
1315
1316std::list<uint8_t>
1318{
1319 std::list<uint8_t> list;
1320 for (const auto& phyEntity : m_phyEntities)
1321 {
1322 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity.second);
1323 if (htPhy)
1324 {
1325 list.emplace_back(htPhy->GetBssMembershipSelector());
1326 }
1327 }
1328 return list;
1329}
1330
1331void
1333{
1334 NS_LOG_FUNCTION(this);
1335 m_powerRestricted = false;
1337 switch (m_state->GetState())
1338 {
1339 case WifiPhyState::TX:
1340 NS_LOG_DEBUG("setting sleep mode postponed until end of current transmission");
1342 break;
1343 case WifiPhyState::RX:
1344 NS_LOG_DEBUG("setting sleep mode postponed until end of current reception");
1346 break;
1347 case WifiPhyState::SWITCHING:
1348 NS_LOG_DEBUG("setting sleep mode postponed until end of channel switching");
1350 break;
1351 case WifiPhyState::CCA_BUSY:
1352 case WifiPhyState::IDLE:
1353 NS_LOG_DEBUG("setting sleep mode");
1354 m_state->SwitchToSleep();
1355 break;
1356 case WifiPhyState::SLEEP:
1357 NS_LOG_DEBUG("already in sleep mode");
1358 break;
1359 default:
1360 NS_ASSERT(false);
1361 break;
1362 }
1363}
1364
1365void
1367{
1368 NS_LOG_FUNCTION(this);
1369 m_powerRestricted = false;
1373 for (auto& phyEntity : m_phyEntities)
1374 {
1375 phyEntity.second->CancelAllEvents();
1376 }
1377 m_state->SwitchToOff();
1378}
1379
1380void
1382{
1383 NS_LOG_FUNCTION(this);
1385 switch (m_state->GetState())
1386 {
1387 case WifiPhyState::TX:
1388 case WifiPhyState::RX:
1389 case WifiPhyState::IDLE:
1390 case WifiPhyState::CCA_BUSY:
1391 case WifiPhyState::SWITCHING: {
1392 NS_LOG_DEBUG("not in sleep mode, there is nothing to resume");
1393 break;
1394 }
1395 case WifiPhyState::SLEEP: {
1396 NS_LOG_DEBUG("resuming from sleep mode");
1397 m_state->SwitchFromSleep();
1398 SwitchMaybeToCcaBusy(nullptr);
1399 break;
1400 }
1401 default: {
1402 NS_ASSERT(false);
1403 break;
1404 }
1405 }
1406}
1407
1408void
1410{
1411 NS_LOG_FUNCTION(this);
1412 switch (m_state->GetState())
1413 {
1414 case WifiPhyState::TX:
1415 case WifiPhyState::RX:
1416 case WifiPhyState::IDLE:
1417 case WifiPhyState::CCA_BUSY:
1418 case WifiPhyState::SWITCHING:
1419 case WifiPhyState::SLEEP: {
1420 NS_LOG_DEBUG("not in off mode, there is nothing to resume");
1421 break;
1422 }
1423 case WifiPhyState::OFF: {
1424 NS_LOG_DEBUG("resuming from off mode");
1425 m_state->SwitchFromOff();
1426 SwitchMaybeToCcaBusy(nullptr);
1427 break;
1428 }
1429 default: {
1430 NS_ASSERT(false);
1431 break;
1432 }
1433 }
1434}
1435
1436Time
1438{
1439 return MicroSeconds(4);
1440}
1441
1442Time
1444{
1445 return MicroSeconds(4);
1446}
1447
1448Time
1450 const WifiTxVector& txVector,
1451 WifiPhyBand band,
1452 MpduType mpdutype,
1453 uint16_t staId)
1454{
1455 uint32_t totalAmpduSize;
1456 double totalAmpduNumSymbols;
1457 return GetPayloadDuration(size,
1458 txVector,
1459 band,
1460 mpdutype,
1461 false,
1462 totalAmpduSize,
1463 totalAmpduNumSymbols,
1464 staId);
1465}
1466
1467Time
1469 const WifiTxVector& txVector,
1470 WifiPhyBand band,
1471 MpduType mpdutype,
1472 bool incFlag,
1473 uint32_t& totalAmpduSize,
1474 double& totalAmpduNumSymbols,
1475 uint16_t staId)
1476{
1477 return GetStaticPhyEntity(txVector.GetModulationClass())
1478 ->GetPayloadDuration(size,
1479 txVector,
1480 band,
1481 mpdutype,
1482 incFlag,
1483 totalAmpduSize,
1484 totalAmpduNumSymbols,
1485 staId);
1486}
1487
1488Time
1490{
1491 return GetStaticPhyEntity(txVector.GetModulationClass())
1492 ->CalculatePhyPreambleAndHeaderDuration(txVector);
1493}
1494
1495Time
1497 const WifiTxVector& txVector,
1498 WifiPhyBand band,
1499 uint16_t staId)
1500{
1501 Time duration = CalculatePhyPreambleAndHeaderDuration(txVector) +
1502 GetPayloadDuration(size, txVector, band, NORMAL_MPDU, staId);
1503 NS_ASSERT(duration.IsStrictlyPositive());
1504 return duration;
1505}
1506
1507Time
1509 const WifiTxVector& txVector,
1510 WifiPhyBand band)
1511{
1512 return CalculateTxDuration(GetWifiConstPsduMap(psdu, txVector), txVector, band);
1513}
1514
1515Time
1517 const WifiTxVector& txVector,
1518 WifiPhyBand band)
1519{
1520 return GetStaticPhyEntity(txVector.GetModulationClass())
1521 ->CalculateTxDuration(psduMap, txVector, band);
1522}
1523
1526{
1527 return GetStaticPhyEntity(modulation)->GetMaxPsduSize();
1528}
1529
1530void
1532{
1533 if (!m_phyTxBeginTrace.IsEmpty())
1534 {
1535 for (const auto& psdu : psdus)
1536 {
1537 for (auto& mpdu : *PeekPointer(psdu.second))
1538 {
1539 m_phyTxBeginTrace(mpdu->GetProtocolDataUnit(), txPowerW);
1540 }
1541 }
1542 }
1543}
1544
1545void
1547{
1548 if (!m_phyTxEndTrace.IsEmpty())
1549 {
1550 for (const auto& psdu : psdus)
1551 {
1552 for (auto& mpdu : *PeekPointer(psdu.second))
1553 {
1554 m_phyTxEndTrace(mpdu->GetProtocolDataUnit());
1555 }
1556 }
1557 }
1558}
1559
1560void
1562{
1564 {
1565 for (auto& mpdu : *PeekPointer(psdu))
1566 {
1567 m_phyTxDropTrace(mpdu->GetProtocolDataUnit());
1568 }
1569 }
1570}
1571
1572void
1574{
1575 if (psdu && !m_phyRxBeginTrace.IsEmpty())
1576 {
1577 for (auto& mpdu : *PeekPointer(psdu))
1578 {
1579 m_phyRxBeginTrace(mpdu->GetProtocolDataUnit(), rxPowersW);
1580 }
1581 }
1582}
1583
1584void
1586{
1587 if (psdu && !m_phyRxEndTrace.IsEmpty())
1588 {
1589 for (auto& mpdu : *PeekPointer(psdu))
1590 {
1591 m_phyRxEndTrace(mpdu->GetProtocolDataUnit());
1592 }
1593 }
1594}
1595
1596void
1598{
1599 if (psdu && !m_phyRxDropTrace.IsEmpty())
1600 {
1601 for (auto& mpdu : *PeekPointer(psdu))
1602 {
1603 m_phyRxDropTrace(mpdu->GetProtocolDataUnit(), reason);
1604 }
1605 }
1606}
1607
1608void
1610 uint16_t channelFreqMhz,
1611 WifiTxVector txVector,
1612 SignalNoiseDbm signalNoise,
1613 std::vector<bool> statusPerMpdu,
1614 uint16_t staId)
1615{
1616 MpduInfo aMpdu;
1617 if (psdu->IsAggregate())
1618 {
1619 // Expand A-MPDU
1620 NS_ASSERT_MSG(txVector.IsAggregation(),
1621 "TxVector with aggregate flag expected here according to PSDU");
1623 size_t nMpdus = psdu->GetNMpdus();
1624 NS_ASSERT_MSG(statusPerMpdu.size() == nMpdus, "Should have one reception status per MPDU");
1625 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1626 {
1627 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1628 for (size_t i = 0; i < nMpdus;)
1629 {
1630 if (statusPerMpdu.at(i)) // packet received without error, hand over to sniffer
1631 {
1632 m_phyMonitorSniffRxTrace(psdu->GetAmpduSubframe(i),
1633 channelFreqMhz,
1634 txVector,
1635 aMpdu,
1636 signalNoise,
1637 staId);
1638 }
1639 ++i;
1640 aMpdu.type =
1641 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1642 }
1643 }
1644 }
1645 else
1646 {
1647 NS_ASSERT_MSG(statusPerMpdu.size() == 1,
1648 "Should have one reception status for normal MPDU");
1649 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1650 {
1651 aMpdu.type = NORMAL_MPDU;
1652 m_phyMonitorSniffRxTrace(psdu->GetPacket(),
1653 channelFreqMhz,
1654 txVector,
1655 aMpdu,
1656 signalNoise,
1657 staId);
1658 }
1659 }
1660}
1661
1662void
1664 uint16_t channelFreqMhz,
1665 WifiTxVector txVector,
1666 uint16_t staId)
1667{
1668 MpduInfo aMpdu;
1669 if (psdu->IsAggregate())
1670 {
1671 // Expand A-MPDU
1672 NS_ASSERT_MSG(txVector.IsAggregation(),
1673 "TxVector with aggregate flag expected here according to PSDU");
1675 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1676 {
1677 size_t nMpdus = psdu->GetNMpdus();
1678 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1679 for (size_t i = 0; i < nMpdus;)
1680 {
1681 m_phyMonitorSniffTxTrace(psdu->GetAmpduSubframe(i),
1682 channelFreqMhz,
1683 txVector,
1684 aMpdu,
1685 staId);
1686 ++i;
1687 aMpdu.type =
1688 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1689 }
1690 }
1691 }
1692 else
1693 {
1694 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1695 {
1696 aMpdu.type = NORMAL_MPDU;
1697 m_phyMonitorSniffTxTrace(psdu->GetPacket(), channelFreqMhz, txVector, aMpdu, staId);
1698 }
1699 }
1700}
1701
1704{
1705 return GetStaticPhyEntity(txVector.GetModulationClass())->GetWifiConstPsduMap(psdu, txVector);
1706}
1707
1708void
1710{
1711 NS_LOG_FUNCTION(this << *psdu << txVector);
1712 Send(GetWifiConstPsduMap(psdu, txVector), txVector);
1713}
1714
1715void
1717{
1718 NS_LOG_FUNCTION(this << psdus << txVector);
1719 /* Transmission can happen if:
1720 * - we are syncing on a packet. It is the responsibility of the
1721 * MAC layer to avoid doing this but the PHY does nothing to
1722 * prevent it.
1723 * - we are idle
1724 */
1725 NS_ASSERT(!m_state->IsStateTx() && !m_state->IsStateSwitching());
1727
1728 if (txVector.GetNssMax() > GetMaxSupportedTxSpatialStreams())
1729 {
1730 NS_FATAL_ERROR("Unsupported number of spatial streams!");
1731 }
1732
1733 if (m_state->IsStateSleep())
1734 {
1735 NS_LOG_DEBUG("Dropping packet because in sleep mode");
1736 for (const auto& psdu : psdus)
1737 {
1738 NotifyTxDrop(psdu.second);
1739 }
1740 return;
1741 }
1742
1743 Time txDuration = CalculateTxDuration(psdus, txVector, GetPhyBand());
1744
1745 bool noEndPreambleDetectionEvent = true;
1746 for (const auto& it : m_phyEntities)
1747 {
1748 noEndPreambleDetectionEvent &= it.second->NoEndPreambleDetectionEvents();
1749 }
1750 if (!noEndPreambleDetectionEvent ||
1751 (m_currentEvent &&
1752 (m_currentEvent->GetEndTime() > (Simulator::Now() + m_state->GetDelayUntilIdle()))))
1753 {
1755 }
1756
1757 for (auto& it : m_phyEntities)
1758 {
1759 it.second->CancelRunningEndPreambleDetectionEvents();
1760 }
1763
1765 {
1766 NS_LOG_DEBUG("Transmitting with power restriction for " << txDuration.As(Time::NS));
1767 }
1768 else
1769 {
1770 NS_LOG_DEBUG("Transmitting without power restriction for " << txDuration.As(Time::NS));
1771 }
1772
1773 if (m_state->GetState() == WifiPhyState::OFF)
1774 {
1775 NS_LOG_DEBUG("Transmission canceled because device is OFF");
1776 return;
1777 }
1778
1779 Ptr<WifiPpdu> ppdu =
1780 GetPhyEntity(txVector.GetModulationClass())->BuildPpdu(psdus, txVector, txDuration);
1781 m_previouslyRxPpduUid = UINT64_MAX; // reset (after creation of PPDU) to use it only once
1782
1783 double txPowerW = DbmToW(GetTxPowerForTransmission(ppdu) + GetTxGain());
1784 NotifyTxBegin(psdus, txPowerW);
1785 if (!m_phyTxPsduBeginTrace.IsEmpty())
1786 {
1787 m_phyTxPsduBeginTrace(psdus, txVector, txPowerW);
1788 }
1789 for (const auto& psdu : psdus)
1790 {
1791 NotifyMonitorSniffTx(psdu.second, GetFrequency(), txVector, psdu.first);
1792 }
1793 m_state->SwitchToTx(txDuration, psdus, GetPowerDbm(txVector.GetTxPowerLevel()), txVector);
1794
1796 m_wifiRadioEnergyModel->GetMaximumTimeInState(WifiPhyState::TX) < txDuration)
1797 {
1798 ppdu->SetTruncatedTx();
1799 }
1800
1801 m_endTxEvent =
1802 Simulator::Schedule(txDuration, &WifiPhy::NotifyTxEnd, this, psdus); // TODO: fix for MU
1803
1804 StartTx(ppdu);
1805 ppdu->ResetTxVector();
1806
1808 m_powerRestricted = false;
1809
1810 Simulator::Schedule(txDuration, &WifiPhy::Reset, this);
1811}
1812
1813uint64_t
1815{
1816 return m_previouslyRxPpduUid;
1817}
1818
1819void
1821{
1822 NS_LOG_FUNCTION(this);
1824 m_currentEvent = nullptr;
1825 for (auto& phyEntity : m_phyEntities)
1826 {
1827 phyEntity.second->CancelAllEvents();
1828 }
1829 SwitchMaybeToCcaBusy(nullptr);
1830}
1831
1832void
1834 RxPowerWattPerChannelBand& rxPowersW,
1835 Time rxDuration)
1836{
1837 NS_LOG_FUNCTION(this << ppdu << rxDuration);
1838 WifiModulationClass modulation = ppdu->GetModulation();
1839 auto it = m_phyEntities.find(modulation);
1840 if (it != m_phyEntities.end())
1841 {
1842 it->second->StartReceivePreamble(ppdu, rxPowersW, rxDuration);
1843 }
1844 else
1845 {
1846 // TODO find a fallback PHY for receiving the PPDU (e.g. 11a for 11ax due to preamble
1847 // structure)
1848 NS_LOG_DEBUG("Unsupported modulation received (" << modulation << "), consider as noise");
1849 m_interference->Add(ppdu, ppdu->GetTxVector(), rxDuration, rxPowersW);
1850 SwitchMaybeToCcaBusy(nullptr);
1851 }
1852}
1853
1854void
1856{
1857 NS_LOG_FUNCTION(this);
1859 {
1860 m_powerRestricted = false;
1861 }
1862}
1863
1864void
1866{
1867 NS_LOG_FUNCTION(this);
1869}
1870
1871bool
1873{
1874 for (const auto& phyEntity : m_phyEntities)
1875 {
1876 if (phyEntity.second->IsModeSupported(mode))
1877 {
1878 return true;
1879 }
1880 }
1881 return false;
1882}
1883
1886{
1887 // Start from oldest standards and move up (guaranteed by fact that WifModulationClass is
1888 // ordered)
1889 for (const auto& phyEntity : m_phyEntities)
1890 {
1891 for (const auto& mode : *(phyEntity.second))
1892 {
1893 return mode;
1894 }
1895 }
1896 NS_ASSERT_MSG(false, "Should have found at least one default mode");
1897 return WifiMode();
1898}
1899
1900bool
1901WifiPhy::IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
1902{
1903 const auto phyEntity = m_phyEntities.find(modulation);
1904 if (phyEntity == m_phyEntities.end())
1905 {
1906 return false;
1907 }
1908 return phyEntity->second->IsMcsSupported(mcs);
1909}
1910
1911std::list<WifiMode>
1913{
1914 std::list<WifiMode> list;
1915 for (const auto& phyEntity : m_phyEntities)
1916 {
1917 if (!phyEntity.second->HandlesMcsModes()) // to exclude MCSs from search
1918 {
1919 for (const auto& mode : *(phyEntity.second))
1920 {
1921 list.emplace_back(mode);
1922 }
1923 }
1924 }
1925 return list;
1926}
1927
1928std::list<WifiMode>
1930{
1931 std::list<WifiMode> list;
1932 const auto phyEntity = m_phyEntities.find(modulation);
1933 if (phyEntity != m_phyEntities.end())
1934 {
1935 if (!phyEntity->second->HandlesMcsModes()) // to exclude MCSs from search
1936 {
1937 for (const auto& mode : *(phyEntity->second))
1938 {
1939 list.emplace_back(mode);
1940 }
1941 }
1942 }
1943 return list;
1944}
1945
1946uint16_t
1948{
1949 uint16_t numMcs = 0;
1950 for (const auto& phyEntity : m_phyEntities)
1951 {
1952 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
1953 {
1954 numMcs += phyEntity.second->GetNumModes();
1955 }
1956 }
1957 return numMcs;
1958}
1959
1960std::list<WifiMode>
1962{
1963 std::list<WifiMode> list;
1964 for (const auto& phyEntity : m_phyEntities)
1965 {
1966 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
1967 {
1968 for (const auto& mode : *(phyEntity.second))
1969 {
1970 list.emplace_back(mode);
1971 }
1972 }
1973 }
1974 return list;
1975}
1976
1977std::list<WifiMode>
1979{
1980 std::list<WifiMode> list;
1981 auto phyEntity = m_phyEntities.find(modulation);
1982 if (phyEntity != m_phyEntities.end())
1983 {
1984 if (phyEntity->second->HandlesMcsModes()) // to exclude non-MCS modes from search
1985 {
1986 for (const auto& mode : *(phyEntity->second))
1987 {
1988 list.emplace_back(mode);
1989 }
1990 }
1991 }
1992 return list;
1993}
1994
1996WifiPhy::GetMcs(WifiModulationClass modulation, uint8_t mcs) const
1997{
1998 NS_ASSERT_MSG(IsMcsSupported(modulation, mcs), "Unsupported MCS");
1999 return m_phyEntities.at(modulation)->GetMcs(mcs);
2000}
2001
2002bool
2004{
2005 return m_state->IsStateCcaBusy();
2006}
2007
2008bool
2010{
2011 return m_state->IsStateIdle();
2012}
2013
2014bool
2016{
2017 return m_state->IsStateRx();
2018}
2019
2020bool
2022{
2023 return m_state->IsStateTx();
2024}
2025
2026bool
2028{
2029 return m_state->IsStateSwitching();
2030}
2031
2032bool
2034{
2035 return m_state->IsStateSleep();
2036}
2037
2038bool
2040{
2041 return m_state->IsStateOff();
2042}
2043
2044Time
2046{
2047 return m_state->GetDelayUntilIdle();
2048}
2049
2050Time
2052{
2053 return m_state->GetLastRxStartTime();
2054}
2055
2056Time
2058{
2059 return m_state->GetLastRxEndTime();
2060}
2061
2062void
2064{
2065 NS_LOG_FUNCTION(this);
2066 GetLatestPhyEntity()->SwitchMaybeToCcaBusy(ppdu);
2067}
2068
2069void
2071{
2072 NS_LOG_FUNCTION(this << duration);
2073 GetLatestPhyEntity()->NotifyCcaBusy(ppdu, duration, WIFI_CHANLIST_PRIMARY);
2074}
2075
2076void
2078{
2079 NS_LOG_FUNCTION(this << reason);
2080 if (reason != OBSS_PD_CCA_RESET ||
2081 m_currentEvent) // Otherwise abort has already been called previously
2082 {
2083 for (auto& phyEntity : m_phyEntities)
2084 {
2085 phyEntity.second->CancelAllEvents();
2086 }
2088 {
2090 }
2092 if (!m_currentEvent)
2093 {
2094 return;
2095 }
2097 if (reason == OBSS_PD_CCA_RESET)
2098 {
2099 m_state->SwitchFromRxAbort(GetChannelWidth());
2100 }
2101 for (auto it = m_currentPreambleEvents.begin(); it != m_currentPreambleEvents.end(); ++it)
2102 {
2103 if (it->second == m_currentEvent)
2104 {
2105 it = m_currentPreambleEvents.erase(it);
2106 break;
2107 }
2108 }
2109 m_currentEvent = nullptr;
2110 }
2111}
2112
2113void
2114WifiPhy::ResetCca(bool powerRestricted, double txPowerMaxSiso, double txPowerMaxMimo)
2115{
2116 NS_LOG_FUNCTION(this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
2117 // This method might be called multiple times when receiving TB PPDUs with a BSS color
2118 // different than the one of the receiver. The first time this method is called, the call
2119 // to AbortCurrentReception sets m_currentEvent to 0. Therefore, we need to check whether
2120 // m_currentEvent is not 0 before executing the instructions below.
2121 if (m_currentEvent)
2122 {
2123 m_powerRestricted = powerRestricted;
2124 m_txPowerMaxSiso = txPowerMaxSiso;
2125 m_txPowerMaxMimo = txPowerMaxMimo;
2126 NS_ASSERT((m_currentEvent->GetEndTime() - Simulator::Now()).IsPositive());
2129 this);
2131 this,
2132 OBSS_PD_CCA_RESET); // finish processing field first
2133 }
2134}
2135
2136double
2138{
2139 NS_LOG_FUNCTION(this << m_powerRestricted << ppdu);
2140 const auto& txVector = ppdu->GetTxVector();
2141 // Get transmit power before antenna gain
2142 double txPowerDbm;
2143 if (!m_powerRestricted)
2144 {
2145 txPowerDbm = GetPowerDbm(txVector.GetTxPowerLevel());
2146 }
2147 else
2148 {
2149 if (txVector.GetNssMax() > 1)
2150 {
2151 txPowerDbm = std::min(m_txPowerMaxMimo, GetPowerDbm(txVector.GetTxPowerLevel()));
2152 }
2153 else
2154 {
2155 txPowerDbm = std::min(m_txPowerMaxSiso, GetPowerDbm(txVector.GetTxPowerLevel()));
2156 }
2157 }
2158
2159 // Apply power density constraint on EIRP
2160 uint16_t channelWidth = ppdu->GetTransmissionChannelWidth();
2161 double txPowerDbmPerMhz =
2162 (txPowerDbm + GetTxGain()) - RatioToDb(channelWidth); // account for antenna gain since EIRP
2163 NS_LOG_INFO("txPowerDbm=" << txPowerDbm << " with txPowerDbmPerMhz=" << txPowerDbmPerMhz
2164 << " over " << channelWidth << " MHz");
2165 txPowerDbm = std::min(txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb(channelWidth);
2166 txPowerDbm -= GetTxGain(); // remove antenna gain since will be added right afterwards
2167 NS_LOG_INFO("txPowerDbm=" << txPowerDbm
2168 << " after applying m_powerDensityLimit=" << m_powerDensityLimit);
2169 return txPowerDbm;
2170}
2171
2174{
2175 // TODO: wrapper. See if still needed
2176 return GetPhyEntityForPpdu(ppdu)->GetAddressedPsduInPpdu(ppdu);
2177}
2178
2179int64_t
2181{
2182 NS_LOG_FUNCTION(this << stream);
2183 int64_t currentStream = stream;
2184 m_random->SetStream(currentStream++);
2185 currentStream += m_interference->GetErrorRateModel()->AssignStreams(currentStream);
2186 return (currentStream - stream);
2187}
2188
2189std::ostream&
2190operator<<(std::ostream& os, RxSignalInfo rxSignalInfo)
2191{
2192 os << "SNR:" << RatioToDb(rxSignalInfo.snr) << " dB"
2193 << ", RSSI:" << rxSignalInfo.rssi << " dBm";
2194 return os;
2195}
2196
2197uint8_t
2198WifiPhy::GetPrimaryChannelNumber(uint16_t primaryChannelWidth) const
2199{
2200 return m_operatingChannel.GetPrimaryChannelNumber(primaryChannelWidth, m_standard);
2201}
2202
2205{
2206 uint32_t subcarrierSpacing = 0;
2207 switch (GetStandard())
2208 {
2214 subcarrierSpacing = 312500;
2215 break;
2217 if (GetChannelWidth() == 5)
2218 {
2219 subcarrierSpacing = 78125;
2220 }
2221 else
2222 {
2223 subcarrierSpacing = 156250;
2224 }
2225 break;
2228 subcarrierSpacing = 78125;
2229 break;
2230 default:
2231 NS_FATAL_ERROR("Standard unknown: " << GetStandard());
2232 break;
2233 }
2234 return subcarrierSpacing;
2235}
2236
2237} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
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
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:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
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
AttributeValue implementation for Time.
Definition: nstime.h:1423
bool IsEmpty() const
Checks if the Callbacks list is empty.
a unique identifier for an interface.
Definition: type-id.h:59
@ ATTR_GET
The attribute can be read.
Definition: type-id.h:64
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
bool Get160MHzOperationSupported() const
represent a single transmission mode
Definition: wifi-mode.h:51
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
Ptr< VhtConfiguration > GetVhtConfiguration() const
Ptr< HtConfiguration > GetHtConfiguration() const
Ptr< Node > GetNode() const override
802.11 PHY layer model
Definition: wifi-phy.h:53
static TypeId GetTypeId()
Get the type ID.
Definition: wifi-phy.cc:62
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1249
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1234
Time GetBlockAckTxTime() const
Return the estimated BlockAck TX time for this PHY.
Definition: wifi-phy.cc:819
double GetCcaEdThreshold() const
Return the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:501
double m_rxGainDb
Reception gain (dB)
Definition: wifi-phy.h:1480
bool IsStateTx() const
Definition: wifi-phy.cc:2021
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition: wifi-phy.h:1504
bool IsStateIdle() const
Definition: wifi-phy.cc:2009
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition: wifi-phy.cc:633
uint8_t m_txSpatialStreams
Number of supported TX spatial streams.
Definition: wifi-phy.h:1496
bool IsStateCcaBusy() const
Definition: wifi-phy.cc:2003
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:1709
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1233
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition: wifi-phy.h:1508
void Configure80211ax()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard.
Definition: wifi-phy.cc:927
Time m_channelSwitchDelay
Time required to switch between channel.
Definition: wifi-phy.h:1501
void SetCcaEdThreshold(double threshold)
Sets the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:494
void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration)
Notify PHY state helper to switch to CCA busy state,.
Definition: wifi-phy.cc:2070
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition: wifi-phy.h:1464
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:1372
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:641
bool m_channelAccessRequested
Flag if channels access has been requested (used for OBSS_PD SR)
Definition: wifi-phy.h:1491
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:1449
Time GetSlot() const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:795
uint32_t GetSubcarrierSpacing() const
Definition: wifi-phy.cc:2204
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1299
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:2173
void Configure80211g()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard.
Definition: wifi-phy.cc:857
uint8_t GetPrimary20Index() const
Definition: wifi-phy.cc:1041
void NotifyTxEnd(WifiConstPsduMap psdus)
Public method used to fire a PhyTxEnd trace.
Definition: wifi-phy.cc:1546
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1035
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:1246
uint8_t GetNumberOfAntennas() const
Definition: wifi-phy.cc:1261
Time m_slot
Slot duration.
Definition: wifi-phy.h:1468
double m_powerDensityLimit
the power density limit (dBm/MHz)
Definition: wifi-phy.h:1484
Time GetDelayUntilIdle()
Definition: wifi-phy.cc:2045
double GetRxSensitivity() const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:488
bool GetShortPhyPreambleSupported() const
Return whether short PHY preamble is supported.
Definition: wifi-phy.cc:603
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:777
std::list< uint8_t > GetBssMembershipSelectorList() const
The WifiPhy::BssMembershipSelector() method is used (e.g., by a WifiRemoteStationManager) to determin...
Definition: wifi-phy.cc:1317
void Configure80211n()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard.
Definition: wifi-phy.cc:900
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1241
double GetTxGain() const
Return the transmission gain (dB).
Definition: wifi-phy.cc:577
double m_txPowerBaseDbm
Minimum transmission power (dBm)
Definition: wifi-phy.h:1481
Time GetDelayUntilChannelSwitch()
Perform any actions necessary when user changes operating channel after initialization.
Definition: wifi-phy.cc:1122
void Configure80211be()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11be standard.
Definition: wifi-phy.cc:942
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1597
bool IsStateRx() const
Definition: wifi-phy.cc:2015
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:1901
Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:783
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1023
Ptr< MobilityModel > GetMobility() const
Return the mobility model this PHY is associated with.
Definition: wifi-phy.cc:627
uint16_t GetNMcs() const
Definition: wifi-phy.cc:1947
Time m_blockAckTxTime
estimated BlockAck TX time
Definition: wifi-phy.h:1471
uint8_t GetPrimaryChannelNumber(uint16_t primaryChannelWidth) const
Get channel number of the primary channel.
Definition: wifi-phy.cc:2198
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:2114
double m_txPowerMaxMimo
MIMO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:1490
void ResumeFromSleep()
Resume from sleep mode.
Definition: wifi-phy.cc:1381
static Time GetPreambleDetectionDuration()
Definition: wifi-phy.cc:1437
void Configure80211p()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11p standard.
Definition: wifi-phy.cc:870
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition: wifi-phy.cc:2077
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:1506
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: wifi-phy.h:1404
void NotifyRxBegin(Ptr< const WifiPsdu > psdu, const RxPowerWattPerChannelBand &rxPowersW)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:1573
Time GetChannelSwitchDelay() const
Definition: wifi-phy.cc:692
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1267
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: wifi-phy.h:1467
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:457
bool IsStateOff() const
Definition: wifi-phy.cc:2039
uint8_t GetMaxSupportedRxSpatialStreams() const
Definition: wifi-phy.cc:1311
double GetTxPowerEnd() const
Return the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:551
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:950
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:648
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:1996
uint8_t m_numberOfAntennas
Number of transmitters.
Definition: wifi-phy.h:1495
ChannelTuple m_channelSettings
Store operating channel settings until initialization.
Definition: wifi-phy.h:1463
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1496
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition: wifi-phy.cc:1525
Ptr< WifiPhyStateHelper > GetState() const
Return the WifiPhyStateHelper of this PHY.
Definition: wifi-phy.cc:445
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:1531
void EndReceiveInterBss()
For HE receptions only, check and possibly modify the transmit power restriction state at the end of ...
Definition: wifi-phy.cc:1855
void SetSleepMode()
Put in sleep mode.
Definition: wifi-phy.cc:1332
void SetShortPhyPreambleSupported(bool preamble)
Enable or disable short PHY preamble.
Definition: wifi-phy.cc:596
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:557
WifiPhyBand m_band
WifiPhyBand.
Definition: wifi-phy.h:1462
void SetRxSensitivity(double threshold)
Sets the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:481
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:704
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:1450
double m_txPowerMaxSiso
SISO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:1488
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1269
virtual void StartTx(Ptr< const WifiPpdu > ppdu)=0
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:764
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:1431
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: wifi-phy.h:1509
EventId m_endTxEvent
the end of transmit event
Definition: wifi-phy.h:1242
double GetRxGain() const
Return the reception gain (dB).
Definition: wifi-phy.cc:590
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:1703
static std::map< WifiModulationClass, Ptr< PhyEntity > > & GetStaticPhyEntities()
Definition: wifi-phy.cc:438
void SetSlot(Time slot)
Set the slot duration for this PHY.
Definition: wifi-phy.cc:789
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:1082
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1005
double m_ccaSensitivityThresholdW
Clear channel assessment (CCA) modulation and coding rate sensitivity threshold in watts.
Definition: wifi-phy.h:1476
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:1244
Time GetLastRxStartTime() const
Return the start time of the last received packet.
Definition: wifi-phy.cc:2051
WifiMode GetDefaultMode() const
Get the default WifiMode supported by the PHY.
Definition: wifi-phy.cc:1885
void SetCcaSensitivityThreshold(double threshold)
Sets the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:507
double m_ccaEdThresholdW
Clear channel assessment (CCA) energy detection (ED) threshold in watts.
Definition: wifi-phy.h:1474
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:1663
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:713
uint8_t GetChannelNumber() const
Return current channel number.
Definition: wifi-phy.cc:1029
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
Definition: wifi-phy.h:1364
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1249
uint32_t m_rxMpduReferenceNumber
A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU.
Definition: wifi-phy.h:1238
void SetWifiRadioEnergyModel(const Ptr< WifiRadioEnergyModel > wifiRadioEnergyModel)
Sets the wifi radio energy model.
Definition: wifi-phy.cc:667
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:1349
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:609
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:1507
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:544
Time GetPifs() const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:807
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:754
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:1585
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:1833
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:1356
double m_txGainDb
Transmission gain (dB)
Definition: wifi-phy.h:1479
bool IsStateSleep() const
Definition: wifi-phy.cc:2033
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:615
WifiStandard m_standard
WifiStandard.
Definition: wifi-phy.h:1461
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:673
uint8_t m_nTxPower
Number of available transmission power levels.
Definition: wifi-phy.h:1483
void DoDispose() override
Destructor implementation.
Definition: wifi-phy.cc:401
bool IsStateSwitching() const
Definition: wifi-phy.cc:2027
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Definition: wifi-phy.cc:1169
void SetOffMode()
Put in off mode.
Definition: wifi-phy.cc:1366
double m_noiseFigureDb
The noise figure in dB.
Definition: wifi-phy.h:1499
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:1411
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:661
void SetPifs(Time pifs)
Set the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:801
void Configure80211b()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard.
Definition: wifi-phy.cc:840
static Time GetStartOfPacketDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1443
virtual FrequencyRange GetCurrentFrequencyRange() const =0
Get the frequency range of the current RF interface.
uint16_t GetTxBandwidth(WifiMode mode, uint16_t maxAllowedBandWidth=std::numeric_limits< uint16_t >::max()) const
Get the bandwidth for a transmission occurring on the current operating channel and using the given W...
Definition: wifi-phy.cc:1059
void UnregisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:469
void SetRxGain(double gain)
Sets the reception gain (dB).
Definition: wifi-phy.cc:583
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:621
void SetTxGain(double gain)
Sets the transmission gain (dB).
Definition: wifi-phy.cc:570
uint8_t m_rxSpatialStreams
Number of supported RX spatial streams.
Definition: wifi-phy.h:1497
double m_txPowerEndDbm
Maximum transmission power (dBm)
Definition: wifi-phy.h:1482
double CalculateSnr(const WifiTxVector &txVector, double ber) const
Definition: wifi-phy.cc:698
void SetFixedPhyBand(bool enable)
Configure whether it is prohibited to change PHY band after initialization.
Definition: wifi-phy.cc:1047
~WifiPhy() override
Definition: wifi-phy.cc:370
void Configure80211ac()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard.
Definition: wifi-phy.cc:919
bool HasFixedPhyBand() const
Definition: wifi-phy.cc:1053
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:1380
void RegisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:463
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition: wifi-phy.h:1503
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition: wifi-phy.h:1231
void DoInitialize() override
Initialize() implementation.
Definition: wifi-phy.cc:376
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition: wifi-phy.h:1494
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: wifi-phy.h:1469
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:520
double GetTxPowerStart() const
Return the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:538
double GetTxPowerForTransmission(Ptr< const WifiPpdu > ppdu) const
Compute the transmit power for the next transmission.
Definition: wifi-phy.cc:2137
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1011
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition: wifi-phy.cc:475
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:451
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:655
void NotifyChannelAccessRequested()
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:1865
void ResumeFromOff()
Resume from off mode.
Definition: wifi-phy.cc:1409
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition: wifi-phy.h:1486
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition: wifi-phy.h:1512
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:1609
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition: wifi-phy.cc:734
Time GetAckTxTime() const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:813
uint64_t GetPreviouslyRxPpduUid() const
Definition: wifi-phy.cc:1814
void Reset()
Reset data upon end of TX or RX.
Definition: wifi-phy.cc:1820
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:1396
Time GetLastRxEndTime() const
Return the end time of the last received packet.
Definition: wifi-phy.cc:2057
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:872
uint8_t GetMaxSupportedTxSpatialStreams() const
Definition: wifi-phy.cc:1293
void Configure80211a()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard.
Definition: wifi-phy.cc:825
std::list< WifiMode > GetMcsList() const
The WifiPhy::GetMcsList() method is used (e.g., by a WifiRemoteStationManager) to determine the set o...
Definition: wifi-phy.cc:1961
std::list< WifiMode > GetModeList() const
The WifiPhy::GetModeList() method is used (e.g., by a WifiRemoteStationManager) to determine the set ...
Definition: wifi-phy.cc:1912
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:2063
double m_rxSensitivityW
Receive sensitivity threshold in watts.
Definition: wifi-phy.h:1473
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1017
double GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:514
bool m_fixedPhyBand
True to prohibit changing PHY band after initialization.
Definition: wifi-phy.h:1465
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
Definition: wifi-phy.cc:728
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:531
uint8_t GetNTxPower() const
Return the number of available transmission power levels.
Definition: wifi-phy.cc:564
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:2180
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1489
bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:1872
Time m_ackTxTime
estimated Ack TX time
Definition: wifi-phy.h:1470
void NotifyTxDrop(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:1561
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).
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:227
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_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:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
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
@ CHANNEL_SWITCHING
@ 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.
uint16_t GetMaximumChannelWidth(WifiModulationClass modulation)
Get the maximum channel width in MHz allowed for the given modulation class.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:46
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
std::map< WifiSpectrumBandInfo, 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
#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
Declaration of ns3::WifiPpdu class and ns3::WifiConstPsduMap.