A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
phy-entity.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Orange Labs
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: Rediet <getachew.redieteab@orange.com>
18 * Sébastien Deronne <sebastien.deronne@gmail.com> (for logic ported from wifi-phy and
19 * spectrum-wifi-phy) Mathieu Lacage <mathieu.lacage@sophia.inria.fr> (for logic ported from
20 * wifi-phy)
21 */
22
23#include "phy-entity.h"
24
25#include "frame-capture-model.h"
26#include "interference-helper.h"
28#include "spectrum-wifi-phy.h"
29#include "wifi-psdu.h"
31#include "wifi-utils.h"
32
33#include "ns3/assert.h"
34#include "ns3/log.h"
35#include "ns3/packet.h"
36#include "ns3/simulator.h"
37
38#include <algorithm>
39
40#undef NS_LOG_APPEND_CONTEXT
41#define NS_LOG_APPEND_CONTEXT WIFI_PHY_NS_LOG_APPEND_CONTEXT(m_wifiPhy)
42
43namespace ns3
44{
45
46NS_LOG_COMPONENT_DEFINE("PhyEntity");
47
48std::ostream&
49operator<<(std::ostream& os, const PhyEntity::PhyRxFailureAction& action)
50{
51 switch (action)
52 {
53 case PhyEntity::DROP:
54 return (os << "DROP");
56 return (os << "ABORT");
58 return (os << "IGNORE");
59 default:
60 NS_FATAL_ERROR("Unknown action");
61 return (os << "unknown");
62 }
63}
64
65std::ostream&
66operator<<(std::ostream& os, const PhyEntity::PhyFieldRxStatus& status)
67{
68 if (status.isSuccess)
69 {
70 return os << "success";
71 }
72 else
73 {
74 return os << "failure (" << status.reason << "/" << status.actionIfFailure << ")";
75 }
76}
77
78/*******************************************************
79 * Abstract base class for PHY entities
80 *******************************************************/
81
83
85{
86 NS_LOG_FUNCTION(this);
87 m_modeList.clear();
89}
90
91void
93{
94 NS_LOG_FUNCTION(this << wifiPhy);
95 m_wifiPhy = wifiPhy;
97}
98
99bool
101{
102 for (const auto& m : m_modeList)
103 {
104 if (m == mode)
105 {
106 return true;
107 }
108 }
109 return false;
110}
111
112uint8_t
114{
115 return m_modeList.size();
116}
117
119PhyEntity::GetMcs(uint8_t /* index */) const
120{
122 "This method should be used only for HtPhy and child classes. Use GetMode instead.");
123 return WifiMode();
124}
125
126bool
127PhyEntity::IsMcsSupported(uint8_t /* index */) const
128{
129 NS_ABORT_MSG("This method should be used only for HtPhy and child classes. Use IsModeSupported "
130 "instead.");
131 return false;
132}
133
134bool
136{
137 return false;
138}
139
140std::list<WifiMode>::const_iterator
142{
143 return m_modeList.begin();
144}
145
146std::list<WifiMode>::const_iterator
148{
149 return m_modeList.end();
150}
151
154{
155 NS_FATAL_ERROR("PPDU field is not a SIG field (no sense in retrieving the signaled mode) or is "
156 "unsupported: "
157 << field);
158 return WifiMode(); // should be overloaded
159}
160
163{
164 const auto& ppduFormats = GetPpduFormats();
165 const auto itPpdu = ppduFormats.find(preamble);
166 if (itPpdu != ppduFormats.end())
167 {
168 const auto itField = std::find(itPpdu->second.begin(), itPpdu->second.end(), currentField);
169 if (itField != itPpdu->second.end())
170 {
171 const auto itNextField = std::next(itField, 1);
172 if (itNextField != itPpdu->second.end())
173 {
174 return *(itNextField);
175 }
176 NS_FATAL_ERROR("No field after " << currentField << " for " << preamble
177 << " for the provided PPDU formats");
178 }
179 else
180 {
181 NS_FATAL_ERROR("Unsupported PPDU field " << currentField << " for " << preamble
182 << " for the provided PPDU formats");
183 }
184 }
185 else
186 {
187 NS_FATAL_ERROR("Unsupported preamble " << preamble << " for the provided PPDU formats");
188 }
189 return WifiPpduField::WIFI_PPDU_FIELD_PREAMBLE; // Silence compiler warning
190}
191
192Time
194{
195 if (field > WIFI_PPDU_FIELD_EHT_SIG)
196 {
197 NS_FATAL_ERROR("Unsupported PPDU field");
198 }
199 return MicroSeconds(0); // should be overloaded
200}
201
202Time
204{
205 Time duration = MicroSeconds(0);
206 for (uint8_t field = WIFI_PPDU_FIELD_PREAMBLE; field < WIFI_PPDU_FIELD_DATA; ++field)
207 {
208 duration += GetDuration(static_cast<WifiPpduField>(field), txVector);
209 }
210 return duration;
211}
212
215{
216 return WifiConstPsduMap({{SU_STA_ID, psdu}});
217}
218
221{
222 return ppdu->GetPsdu();
223}
224
226PhyEntity::GetPhyHeaderSections(const WifiTxVector& txVector, Time ppduStart) const
227{
229 WifiPpduField field = WIFI_PPDU_FIELD_PREAMBLE; // preamble always present
230 Time start = ppduStart;
231
232 while (field != WIFI_PPDU_FIELD_DATA)
233 {
234 Time duration = GetDuration(field, txVector);
235 map[field] = {{start, start + duration}, GetSigMode(field, txVector)};
236 // Move to next field
237 start += duration;
238 field = GetNextField(field, txVector.GetPreambleType());
239 }
240 return map;
241}
242
244PhyEntity::BuildPpdu(const WifiConstPsduMap& psdus, const WifiTxVector& txVector, Time ppduDuration)
245{
246 NS_LOG_FUNCTION(this << psdus << txVector << ppduDuration);
247 NS_FATAL_ERROR("This method is unsupported for the base PhyEntity class. Use the overloaded "
248 "version in the amendment-specific subclasses instead!");
249 return Create<WifiPpdu>(psdus.begin()->second,
250 txVector,
251 m_wifiPhy->GetOperatingChannel()); // should be overloaded
252}
253
254Time
256{
257 if (field ==
258 WIFI_PPDU_FIELD_DATA) // this field is not in the map returned by GetPhyHeaderSections
259 {
261 }
262 const auto& sections = GetPhyHeaderSections(txVector, NanoSeconds(0));
263 auto it = sections.find(field);
264 NS_ASSERT(it != sections.end());
265 const auto& startStopTimes = it->second.first;
266 return startStopTimes
267 .first; // return the start time of field relatively to the beginning of the PPDU
268}
269
272{
273 uint16_t measurementChannelWidth = GetMeasurementChannelWidth(event->GetPpdu());
274 return m_wifiPhy->m_interference->CalculatePhyHeaderSnrPer(
275 event,
276 measurementChannelWidth,
277 GetPrimaryBand(measurementChannelWidth),
278 field);
279}
280
281void
283{
284 NS_LOG_FUNCTION(this << field << *event);
285 NS_ASSERT(m_wifiPhy); // no sense if no owner WifiPhy instance
288 "Use the StartReceivePreamble method for preamble reception");
289 // Handle special cases of data reception
290 if (field == WIFI_PPDU_FIELD_DATA)
291 {
292 StartReceivePayload(event);
293 return;
294 }
295
296 bool supported = DoStartReceiveField(field, event);
297 NS_ABORT_MSG_IF(!supported,
298 "Unknown field "
299 << field << " for this PHY entity"); // TODO see what to do if not supported
300 Time duration = GetDuration(field, event->GetPpdu()->GetTxVector());
302 Simulator::Schedule(duration, &PhyEntity::EndReceiveField, this, field, event);
304 event->GetPpdu(),
305 duration); // keep in CCA busy state up to reception of Data (will then switch to RX)
306}
307
308void
310{
311 NS_LOG_FUNCTION(this << field << *event);
312 NS_ASSERT(m_wifiPhy); // no sense if no owner WifiPhy instance
314 PhyFieldRxStatus status = DoEndReceiveField(field, event);
315 const auto& txVector = event->GetPpdu()->GetTxVector();
316 if (status.isSuccess) // move to next field if reception succeeded
317 {
318 StartReceiveField(GetNextField(field, txVector.GetPreambleType()), event);
319 }
320 else
321 {
322 Ptr<const WifiPpdu> ppdu = event->GetPpdu();
323 switch (status.actionIfFailure)
324 {
325 case ABORT:
326 // Abort reception, but consider medium as busy
328 if (event->GetEndTime() > (Simulator::Now() + m_state->GetDelayUntilIdle()))
329 {
331 }
332 break;
333 case DROP:
334 // Notify drop, keep in CCA busy, and perform same processing as IGNORE case
335 if (status.reason == FILTERED)
336 {
337 // PHY-RXSTART is immediately followed by PHY-RXEND (Filtered)
339 txVector,
340 NanoSeconds(0)); // this callback (equivalent to PHY-RXSTART primitive) is also
341 // triggered for filtered PPDUs
342 }
343 m_wifiPhy->NotifyRxPpduDrop(ppdu, status.reason);
345 // no break
346 case IGNORE:
347 // Keep in Rx state and reset at end
348 m_endRxPayloadEvents.push_back(
351 this,
352 event));
353 break;
354 default:
355 NS_FATAL_ERROR("Unknown action in case of failure");
356 }
357 }
358}
359
360Time
362{
363 const auto& txVector = ppdu->GetTxVector();
364 return ppdu->GetTxDuration() -
365 (GetDurationUpToField(field, txVector) + GetDuration(field, txVector));
366}
367
368bool
370{
371 NS_LOG_FUNCTION(this << field << *event);
373 field != WIFI_PPDU_FIELD_DATA); // handled apart for the time being
374 const auto& ppduFormats = GetPpduFormats();
375 auto itFormat = ppduFormats.find(event->GetPpdu()->GetPreamble());
376 if (itFormat != ppduFormats.end())
377 {
378 auto itField = std::find(itFormat->second.begin(), itFormat->second.end(), field);
379 if (itField != itFormat->second.end())
380 {
381 return true; // supported field so we can start receiving
382 }
383 }
384 return false; // unsupported otherwise
385}
386
389{
390 NS_LOG_FUNCTION(this << field << *event);
391 NS_ASSERT(field != WIFI_PPDU_FIELD_DATA); // handled apart for the time being
392 if (field == WIFI_PPDU_FIELD_PREAMBLE)
393 {
394 return DoEndReceivePreamble(event);
395 }
396 return PhyFieldRxStatus(false); // failed reception by default
397}
398
399void
401 RxPowerWattPerChannelBand& rxPowersW,
402 Time rxDuration)
403{
404 // The total RX power corresponds to the maximum over all the bands
405 auto it =
406 std::max_element(rxPowersW.begin(), rxPowersW.end(), [](const auto& p1, const auto& p2) {
407 return p1.second < p2.second;
408 });
409 NS_LOG_FUNCTION(this << ppdu << it->second);
410
411 auto event = DoGetEvent(ppdu, rxPowersW);
412 if (!event)
413 {
414 // PPDU should be simply considered as interference (once it has been accounted for in
415 // InterferenceHelper)
416 return;
417 }
418
419 Time endRx = Simulator::Now() + rxDuration;
420 if (ppdu->IsTruncatedTx())
421 {
422 NS_LOG_DEBUG("Packet reception stopped because transmitter has been switched off");
423 if (endRx > (Simulator::Now() + m_state->GetDelayUntilIdle()))
424 {
426 }
428 return;
429 }
430
431 switch (m_state->GetState())
432 {
434 NS_LOG_DEBUG("Drop packet because of channel switching");
435 /*
436 * Packets received on the upcoming channel are added to the event list
437 * during the switching state. This way the medium can be correctly sensed
438 * when the device listens to the channel for the first time after the
439 * switching e.g. after channel switching, the channel may be sensed as
440 * busy due to other devices' transmissions started before the end of
441 * the switching.
442 */
444 break;
445 case WifiPhyState::RX:
447 m_wifiPhy->m_frameCaptureModel->IsInCaptureWindow(
449 m_wifiPhy->m_frameCaptureModel->CaptureNewFrame(m_wifiPhy->m_currentEvent, event))
450 {
452 NS_LOG_DEBUG("Switch to new packet");
454 }
455 else
456 {
457 NS_LOG_DEBUG("Drop packet because already in Rx");
458 DropPreambleEvent(ppdu, RXING, endRx);
460 {
461 /*
462 * We are here because the non-legacy PHY header has not been successfully received.
463 * The PHY is kept in RX state for the duration of the PPDU, but EndReceive function
464 * is not called when the reception of the PPDU is finished, which is responsible to
465 * clear m_currentPreambleEvents. As a result, m_currentPreambleEvents should be
466 * cleared here.
467 */
469 }
470 }
471 break;
472 case WifiPhyState::TX:
473 NS_LOG_DEBUG("Drop packet because already in Tx");
474 DropPreambleEvent(ppdu, TXING, endRx);
475 break;
478 {
480 m_wifiPhy->m_frameCaptureModel->IsInCaptureWindow(
482 m_wifiPhy->m_frameCaptureModel->CaptureNewFrame(m_wifiPhy->m_currentEvent, event))
483 {
485 NS_LOG_DEBUG("Switch to new packet");
487 }
488 else
489 {
490 NS_LOG_DEBUG("Drop packet because already decoding preamble");
492 }
493 }
494 else
495 {
497 }
498 break;
502 break;
504 NS_LOG_DEBUG("Drop packet because in sleep mode");
505 DropPreambleEvent(ppdu, SLEEPING, endRx);
506 break;
508 NS_LOG_DEBUG("Drop packet because in switched off");
510 break;
511 default:
512 NS_FATAL_ERROR("Invalid WifiPhy state.");
513 break;
514 }
515}
516
517void
519{
520 NS_LOG_FUNCTION(this << ppdu << reason << endRx);
521 m_wifiPhy->NotifyRxPpduDrop(ppdu, reason);
522 auto it = m_wifiPhy->m_currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
523 if (it != m_wifiPhy->m_currentPreambleEvents.end())
524 {
526 }
528 (endRx > (Simulator::Now() + m_state->GetDelayUntilIdle())))
529 {
530 // that PPDU will be noise _after_ the end of the current event.
532 }
533}
534
535void
537{
538 NS_LOG_FUNCTION(this << ppdu << rxDuration);
539 auto it = m_wifiPhy->m_currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
540 if (it != m_wifiPhy->m_currentPreambleEvents.end())
541 {
543 }
545 {
546 m_wifiPhy->Reset();
547 }
548
549 if (rxDuration > m_state->GetDelayUntilIdle())
550 {
551 // this PPDU will be noise _after_ the completion of the current event
553 }
554}
555
556uint16_t
558{
559 return SU_STA_ID;
560}
561
562void
564{
565 NS_LOG_FUNCTION(this << *event);
567
568 Time payloadDuration = DoStartReceivePayload(event);
569 m_state->SwitchToRx(payloadDuration);
570}
571
572Time
574{
575 NS_LOG_FUNCTION(this << *event);
576 Ptr<const WifiPpdu> ppdu = event->GetPpdu();
577 NS_LOG_DEBUG("Receiving PSDU");
578 uint16_t staId = GetStaId(ppdu);
579 m_signalNoiseMap.insert({{ppdu->GetUid(), staId}, SignalNoiseDbm()});
580 m_statusPerMpduMap.insert({{ppdu->GetUid(), staId}, std::vector<bool>()});
581 ScheduleEndOfMpdus(event);
582 const auto& txVector = event->GetPpdu()->GetTxVector();
583 Time payloadDuration = ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector);
585 txVector,
586 payloadDuration); // this callback (equivalent to PHY-RXSTART primitive) is triggered only
587 // if headers have been correctly decoded and that the mode within is
588 // supported
589 m_endRxPayloadEvents.push_back(
590 Simulator::Schedule(payloadDuration, &PhyEntity::EndReceivePayload, this, event));
591 return payloadDuration;
592}
593
594void
596{
597 NS_LOG_FUNCTION(this << *event);
598 Ptr<const WifiPpdu> ppdu = event->GetPpdu();
600 const auto& txVector = event->GetPpdu()->GetTxVector();
601 uint16_t staId = GetStaId(ppdu);
602 Time endOfMpduDuration = NanoSeconds(0);
603 Time relativeStart = NanoSeconds(0);
604 Time psduDuration = ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector);
605 Time remainingAmpduDuration = psduDuration;
606 size_t nMpdus = psdu->GetNMpdus();
607 MpduType mpduType =
608 (nMpdus > 1) ? FIRST_MPDU_IN_AGGREGATE : (psdu->IsSingle() ? SINGLE_MPDU : NORMAL_MPDU);
609 uint32_t totalAmpduSize = 0;
610 double totalAmpduNumSymbols = 0.0;
611 auto mpdu = psdu->begin();
612 for (size_t i = 0; i < nMpdus && mpdu != psdu->end(); ++mpdu)
613 {
614 uint32_t size = (mpduType == NORMAL_MPDU) ? psdu->GetSize() : psdu->GetAmpduSubframeSize(i);
615 Time mpduDuration = m_wifiPhy->GetPayloadDuration(size,
616 txVector,
618 mpduType,
619 true,
620 totalAmpduSize,
621 totalAmpduNumSymbols,
622 staId);
623
624 remainingAmpduDuration -= mpduDuration;
625 if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero()) // no more MPDUs coming
626 {
627 if (remainingAmpduDuration <
628 NanoSeconds(txVector.GetGuardInterval())) // enables to ignore padding
629 {
630 mpduDuration += remainingAmpduDuration; // apply a correction just in case rounding
631 // had induced slight shift
632 }
633 }
634
635 endOfMpduDuration += mpduDuration;
636 NS_LOG_INFO("Schedule end of MPDU #"
637 << i << " in " << endOfMpduDuration.As(Time::NS) << " (relativeStart="
638 << relativeStart.As(Time::NS) << ", mpduDuration=" << mpduDuration.As(Time::NS)
639 << ", remainingAmdpuDuration=" << remainingAmpduDuration.As(Time::NS) << ")");
640 m_endOfMpduEvents.push_back(Simulator::Schedule(endOfMpduDuration,
642 this,
643 event,
644 Create<WifiPsdu>(*mpdu, false),
645 i,
646 relativeStart,
647 mpduDuration));
648
649 // Prepare next iteration
650 ++i;
651 relativeStart += mpduDuration;
652 mpduType = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
653 }
654}
655
656void
659 size_t mpduIndex,
660 Time relativeStart,
661 Time mpduDuration)
662{
663 NS_LOG_FUNCTION(this << *event << mpduIndex << relativeStart << mpduDuration);
664 const auto ppdu = event->GetPpdu();
665 const auto& txVector = ppdu->GetTxVector();
666 uint16_t staId = GetStaId(ppdu);
667
668 std::pair<bool, SignalNoiseDbm> rxInfo =
669 GetReceptionStatus(psdu, event, staId, relativeStart, mpduDuration);
670 NS_LOG_DEBUG("Extracted MPDU #" << mpduIndex << ": duration: " << mpduDuration.As(Time::NS)
671 << ", correct reception: " << rxInfo.first << ", Signal/Noise: "
672 << rxInfo.second.signal << "/" << rxInfo.second.noise << "dBm");
673
674 auto signalNoiseIt = m_signalNoiseMap.find({ppdu->GetUid(), staId});
675 NS_ASSERT(signalNoiseIt != m_signalNoiseMap.end());
676 signalNoiseIt->second = rxInfo.second;
677
678 RxSignalInfo rxSignalInfo;
679 rxSignalInfo.snr = rxInfo.second.signal / rxInfo.second.noise;
680 rxSignalInfo.rssi = rxInfo.second.signal;
681
682 auto statusPerMpduIt = m_statusPerMpduMap.find({ppdu->GetUid(), staId});
683 NS_ASSERT(statusPerMpduIt != m_statusPerMpduMap.end());
684 statusPerMpduIt->second.push_back(rxInfo.first);
685
686 if (rxInfo.first && GetAddressedPsduInPpdu(ppdu)->GetNMpdus() > 1)
687 {
688 // only done for correct MPDU that is part of an A-MPDU
689 m_state->NotifyRxMpdu(psdu, rxSignalInfo, txVector);
690 }
691}
692
693void
695{
696 const auto ppdu = event->GetPpdu();
697 const auto& txVector = ppdu->GetTxVector();
699 this << *event << ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector));
700 NS_ASSERT(event->GetEndTime() == Simulator::Now());
701 const auto staId = GetStaId(ppdu);
702 const auto channelWidthAndBand = GetChannelWidthAndBand(txVector, staId);
703 double snr = m_wifiPhy->m_interference->CalculateSnr(event,
704 channelWidthAndBand.first,
705 txVector.GetNss(staId),
706 channelWidthAndBand.second);
707
709 m_wifiPhy->NotifyRxEnd(psdu);
710
711 auto signalNoiseIt = m_signalNoiseMap.find({ppdu->GetUid(), staId});
712 NS_ASSERT(signalNoiseIt != m_signalNoiseMap.end());
713 auto statusPerMpduIt = m_statusPerMpduMap.find({ppdu->GetUid(), staId});
714 NS_ASSERT(statusPerMpduIt != m_statusPerMpduMap.end());
715 // store per-MPDU status, which is cleared by the call to DoEndReceivePayload below
716 auto statusPerMpdu = statusPerMpduIt->second;
717
718 RxSignalInfo rxSignalInfo;
719 bool success;
720
721 if (std::count(statusPerMpdu.cbegin(), statusPerMpdu.cend(), true))
722 {
723 // At least one MPDU has been successfully received
726 txVector,
727 signalNoiseIt->second,
728 statusPerMpdu,
729 staId);
730 rxSignalInfo.snr = snr;
731 rxSignalInfo.rssi = signalNoiseIt->second.signal; // same information for all MPDUs
732 RxPayloadSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu);
734 ppdu->GetUid(); // store UID only if reception is successful (because otherwise trigger
735 // won't be read by MAC layer)
736 success = true;
737 }
738 else
739 {
740 RxPayloadFailed(psdu, snr, txVector);
741 success = false;
742 }
743
744 m_state->NotifyRxPpduOutcome(ppdu, rxSignalInfo, txVector, staId, statusPerMpduIt->second);
747
748 // notify the MAC through the PHY state helper as the last action. Indeed, the notification
749 // of the RX end may lead the MAC to request a PHY state change (e.g., channel switch, sleep).
750 // Hence, all actions the PHY has to perform when RX ends should be completed before
751 // notifying the MAC.
752 success ? m_state->NotifyRxPsduSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu)
753 : m_state->NotifyRxPsduFailed(psdu, snr);
754}
755
756void
758 RxSignalInfo rxSignalInfo,
759 const WifiTxVector& txVector,
760 uint16_t staId,
761 const std::vector<bool>& statusPerMpdu)
762{
763 NS_LOG_FUNCTION(this << *psdu << txVector);
764 m_state->SwitchFromRxEndOk();
765}
766
767void
769{
770 NS_LOG_FUNCTION(this << *psdu << txVector << snr);
771 m_state->SwitchFromRxEndError();
772}
773
774void
776{
777 NS_LOG_FUNCTION(this << ppdu);
779 NotifyInterferenceRxEndAndClear(false); // don't reset WifiPhy
780
781 m_wifiPhy->m_currentEvent = nullptr;
783 m_endRxPayloadEvents.clear();
784}
785
786std::pair<bool, SignalNoiseDbm>
788 Ptr<Event> event,
789 uint16_t staId,
790 Time relativeMpduStart,
791 Time mpduDuration)
792{
793 NS_LOG_FUNCTION(this << *psdu << *event << staId << relativeMpduStart << mpduDuration);
794 const auto channelWidthAndBand = GetChannelWidthAndBand(event->GetPpdu()->GetTxVector(), staId);
795 SnrPer snrPer = m_wifiPhy->m_interference->CalculatePayloadSnrPer(
796 event,
797 channelWidthAndBand.first,
798 channelWidthAndBand.second,
799 staId,
800 {relativeMpduStart, relativeMpduStart + mpduDuration});
801
802 WifiMode mode = event->GetPpdu()->GetTxVector().GetMode(staId);
803 NS_LOG_DEBUG("rate=" << (mode.GetDataRate(event->GetPpdu()->GetTxVector(), staId))
804 << ", SNR(dB)=" << RatioToDb(snrPer.snr) << ", PER=" << snrPer.per
805 << ", size=" << psdu->GetSize()
806 << ", relativeStart = " << relativeMpduStart.As(Time::NS)
807 << ", duration = " << mpduDuration.As(Time::NS));
808
809 // There are two error checks: PER and receive error model check.
810 // PER check models is typical for Wi-Fi and is based on signal modulation;
811 // Receive error model is optional, if we have an error model and
812 // it indicates that the packet is corrupt, drop the packet.
813 SignalNoiseDbm signalNoise;
814 signalNoise.signal = WToDbm(event->GetRxPowerW(channelWidthAndBand.second));
815 signalNoise.noise = WToDbm(event->GetRxPowerW(channelWidthAndBand.second) / snrPer.snr);
816 if (GetRandomValue() > snrPer.per &&
818 m_wifiPhy->m_postReceptionErrorModel->IsCorrupt(psdu->GetPacket()->Copy())))
819 {
820 NS_LOG_DEBUG("Reception succeeded: " << psdu);
821 return {true, signalNoise};
822 }
823 else
824 {
825 NS_LOG_DEBUG("Reception failed: " << psdu);
826 return {false, signalNoise};
827 }
828}
829
830std::pair<uint16_t, WifiSpectrumBandInfo>
831PhyEntity::GetChannelWidthAndBand(const WifiTxVector& txVector, uint16_t /* staId */) const
832{
833 uint16_t channelWidth = GetRxChannelWidth(txVector);
834 return {channelWidth, GetPrimaryBand(channelWidth)};
835}
836
837const std::map<std::pair<uint64_t, WifiPreamble>, Ptr<Event>>&
839{
841}
842
843void
845{
846 NS_LOG_FUNCTION(this << *event);
847 Ptr<const WifiPpdu> ppdu = event->GetPpdu();
848 m_wifiPhy->m_currentPreambleEvents.insert({{ppdu->GetUid(), ppdu->GetPreamble()}, event});
849}
850
853{
854 // We store all incoming preamble events, and a decision is made at the end of the preamble
855 // detection window.
856 const auto& currentPreambleEvents = GetCurrentPreambleEvents();
857 const auto it = currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
858 if (it != currentPreambleEvents.cend())
859 {
860 // received another signal with the same content
861 NS_LOG_DEBUG("Received another PPDU for UID " << ppdu->GetUid());
862 const auto foundEvent = it->second;
863 HandleRxPpduWithSameContent(foundEvent, ppdu, rxPowersW);
864 return nullptr;
865 }
866
867 auto event = CreateInterferenceEvent(ppdu, ppdu->GetTxDuration(), rxPowersW);
868 AddPreambleEvent(event);
869 return event;
870}
871
874 Time duration,
876 bool isStartHePortionRxing /* = false */)
877{
878 return m_wifiPhy->m_interference->Add(ppdu,
879 duration,
880 rxPower,
882 isStartHePortionRxing);
883}
884
885void
889{
890 if (const auto maxDelay =
891 m_wifiPhy->GetPhyEntityForPpdu(ppdu)->GetMaxDelayPpduSameUid(ppdu->GetTxVector());
892 Simulator::Now() - event->GetStartTime() > maxDelay)
893 {
894 // This PPDU arrived too late to be decoded properly. The PPDU is dropped and added as
895 // interference
896 event = CreateInterferenceEvent(ppdu, ppdu->GetTxDuration(), rxPower);
897 NS_LOG_DEBUG("Drop PPDU that arrived too late");
899 return;
900 }
901
902 // Update received power and TXVECTOR of the event associated to that transmission upon
903 // reception of a signal adding up constructively (in case of a UL MU PPDU or non-HT duplicate
904 // PPDU)
905 m_wifiPhy->m_interference->UpdateEvent(event, rxPower);
906 const auto& txVector = ppdu->GetTxVector();
907 const auto& eventTxVector = event->GetPpdu()->GetTxVector();
908 auto updatedTxVector{eventTxVector};
909 updatedTxVector.SetChannelWidth(
910 std::max(eventTxVector.GetChannelWidth(), txVector.GetChannelWidth()));
911 if (updatedTxVector.GetChannelWidth() != eventTxVector.GetChannelWidth())
912 {
913 event->UpdatePpdu(ppdu);
914 }
915}
916
917void
919{
921 m_signalNoiseMap.clear();
922 m_statusPerMpduMap.clear();
923 for (const auto& endOfMpduEvent : m_endOfMpduEvents)
924 {
925 NS_ASSERT(endOfMpduEvent.IsExpired());
926 }
927 m_endOfMpduEvents.clear();
928 if (reset)
929 {
930 m_wifiPhy->Reset();
931 }
932}
933
936{
937 NS_LOG_FUNCTION(this << *event);
939 1); // Synched on one after detection period
940 return PhyFieldRxStatus(true); // always consider that preamble has been correctly received if
941 // preamble detection was OK
942}
943
944void
946{
947 NS_LOG_FUNCTION(this << *event);
948 NS_LOG_DEBUG("Sync to signal (power=" << WToDbm(GetRxPowerWForPpdu(event)) << "dBm)");
949 m_wifiPhy->m_interference->NotifyRxStart(
950 m_wifiPhy->GetCurrentFrequencyRange()); // We need to notify it now so that it starts
951 // recording events
955 this,
956 event));
957}
958
959void
961{
962 NS_LOG_FUNCTION(this << *event);
964 NS_ASSERT(m_wifiPhy->m_endPhyRxEvent.IsExpired()); // since end of preamble reception is
965 // scheduled by this method upon success
966
967 // calculate PER on the measurement channel for PHY headers
968 uint16_t measurementChannelWidth = GetMeasurementChannelWidth(event->GetPpdu());
969 auto measurementBand = GetPrimaryBand(measurementChannelWidth);
970 double maxRxPowerW = -1; // in case current event may not be sent on measurement channel
971 // (rxPowerW would be equal to 0)
972 Ptr<Event> maxEvent;
974 for (auto preambleEvent : m_wifiPhy->m_currentPreambleEvents)
975 {
976 double rxPowerW = preambleEvent.second->GetRxPowerW(measurementBand);
977 if (rxPowerW > maxRxPowerW)
978 {
979 maxRxPowerW = rxPowerW;
980 maxEvent = preambleEvent.second;
981 }
982 }
983
984 NS_ASSERT(maxEvent);
985 if (maxEvent != event)
986 {
987 NS_LOG_DEBUG("Receiver got a stronger packet with UID "
988 << maxEvent->GetPpdu()->GetUid()
989 << " during preamble detection: drop packet with UID "
990 << event->GetPpdu()->GetUid());
992
993 auto it = m_wifiPhy->m_currentPreambleEvents.find(
994 {event->GetPpdu()->GetUid(), event->GetPpdu()->GetPreamble()});
996 // This is needed to cleanup the m_firstPowerPerBand so that the first power corresponds to
997 // the power at the start of the PPDU
998 m_wifiPhy->m_interference->NotifyRxEnd(maxEvent->GetStartTime(),
1000 // Make sure InterferenceHelper keeps recording events
1002 return;
1003 }
1004
1005 m_wifiPhy->m_currentEvent = event;
1006
1007 double snr = m_wifiPhy->m_interference->CalculateSnr(m_wifiPhy->m_currentEvent,
1008 measurementChannelWidth,
1009 1,
1010 measurementBand);
1011 NS_LOG_DEBUG("SNR(dB)=" << RatioToDb(snr) << " at end of preamble detection period");
1012
1013 if ((!m_wifiPhy->m_preambleDetectionModel && maxRxPowerW > 0.0) ||
1015 m_wifiPhy->m_preambleDetectionModel->IsPreambleDetected(
1016 m_wifiPhy->m_currentEvent->GetRxPowerW(measurementBand),
1017 snr,
1018 measurementChannelWidth)))
1019 {
1020 // A bit convoluted but it enables to sync all PHYs
1021 for (auto& it : m_wifiPhy->m_phyEntities)
1022 {
1023 it.second->CancelRunningEndPreambleDetectionEvents();
1024 }
1025
1026 for (auto it = m_wifiPhy->m_currentPreambleEvents.begin();
1027 it != m_wifiPhy->m_currentPreambleEvents.end();)
1028 {
1029 if (it->second != m_wifiPhy->m_currentEvent)
1030 {
1031 NS_LOG_DEBUG("Drop packet with UID " << it->first.first << " and preamble "
1032 << it->first.second << " arrived at time "
1033 << it->second->GetStartTime());
1035 if (m_wifiPhy->m_currentEvent->GetPpdu()->GetUid() > it->first.first)
1036 {
1038 // This is needed to cleanup the m_firstPowerPerBand so that the first power
1039 // corresponds to the power at the start of the PPDU
1040 m_wifiPhy->m_interference->NotifyRxEnd(
1041 m_wifiPhy->m_currentEvent->GetStartTime(),
1043 }
1044 else
1045 {
1046 reason = BUSY_DECODING_PREAMBLE;
1047 }
1048 m_wifiPhy->NotifyRxPpduDrop(it->second->GetPpdu(), reason);
1049
1050 it = m_wifiPhy->m_currentPreambleEvents.erase(it);
1051 }
1052 else
1053 {
1054 ++it;
1055 }
1056 }
1057
1058 // Make sure InterferenceHelper keeps recording events
1060
1062 m_wifiPhy->m_currentEvent->GetRxPowerWPerBand());
1064
1065 // Continue receiving preamble
1066 Time durationTillEnd =
1067 GetDuration(WIFI_PPDU_FIELD_PREAMBLE, event->GetPpdu()->GetTxVector()) -
1069 m_wifiPhy->NotifyCcaBusy(event->GetPpdu(),
1070 durationTillEnd); // will be prolonged by next field
1073 this,
1075 event);
1076 }
1077 else
1078 {
1079 NS_LOG_DEBUG("Drop packet because PHY preamble detection failed");
1080 // Like CCA-SD, CCA-ED is governed by the 4 us CCA window to flag CCA-BUSY
1081 // for any received signal greater than the CCA-ED threshold.
1084 m_wifiPhy->m_currentEvent->GetEndTime());
1086 {
1087 // Do not erase events if there are still pending preamble events to be processed
1088 m_wifiPhy->m_interference->NotifyRxEnd(Simulator::Now(),
1090 }
1091 m_wifiPhy->m_currentEvent = nullptr;
1092 // Cancel preamble reception
1094 }
1095}
1096
1097bool
1099{
1100 WifiMode txMode = ppdu->GetTxVector().GetMode();
1101 if (!IsModeSupported(txMode))
1102 {
1103 NS_LOG_DEBUG("Drop packet because it was sent using an unsupported mode (" << txMode
1104 << ")");
1105 return false;
1106 }
1107 return true;
1108}
1109
1110void
1112{
1113 NS_LOG_FUNCTION(this);
1115 for (auto& endRxPayloadEvent : m_endRxPayloadEvents)
1116 {
1117 endRxPayloadEvent.Cancel();
1118 }
1119 m_endRxPayloadEvents.clear();
1120 for (auto& endMpduEvent : m_endOfMpduEvents)
1121 {
1122 endMpduEvent.Cancel();
1123 }
1124 m_endOfMpduEvents.clear();
1125}
1126
1127bool
1129{
1130 return m_endPreambleDetectionEvents.empty();
1131}
1132
1133void
1135{
1136 NS_LOG_FUNCTION(this);
1137 for (auto& endPreambleDetectionEvent : m_endPreambleDetectionEvents)
1138 {
1139 endPreambleDetectionEvent.Cancel();
1140 }
1142}
1143
1144void
1146{
1147 NS_LOG_FUNCTION(this << reason);
1150}
1151
1152void
1154{
1155 NS_LOG_FUNCTION(this << reason);
1156 if (m_wifiPhy->m_currentEvent) // Otherwise abort has already been called just before
1157 {
1158 for (auto& endMpduEvent : m_endOfMpduEvents)
1159 {
1160 endMpduEvent.Cancel();
1161 }
1162 m_endOfMpduEvents.clear();
1163 }
1164}
1165
1166void
1168{
1169 NS_LOG_FUNCTION(this << *event);
1170 DoResetReceive(event);
1173 NS_ASSERT(m_endRxPayloadEvents.size() == 1 && m_endRxPayloadEvents.front().IsExpired());
1174 m_endRxPayloadEvents.clear();
1175 m_wifiPhy->m_currentEvent = nullptr;
1177 m_wifiPhy->SwitchMaybeToCcaBusy(event->GetPpdu());
1178}
1179
1180void
1182{
1183 NS_LOG_FUNCTION(this << *event);
1184 NS_ASSERT(event->GetEndTime() == Simulator::Now());
1185}
1186
1187double
1189{
1190 return m_wifiPhy->m_random->GetValue();
1191}
1192
1193double
1195{
1196 return event->GetRxPowerW(GetPrimaryBand(GetMeasurementChannelWidth(event->GetPpdu())));
1197}
1198
1201{
1202 return m_wifiPhy->m_currentEvent;
1203}
1204
1206PhyEntity::GetPrimaryBand(uint16_t bandWidth) const
1207{
1208 if (m_wifiPhy->GetChannelWidth() % 20 != 0)
1209 {
1210 return m_wifiPhy->GetBand(bandWidth);
1211 }
1212 return m_wifiPhy->GetBand(bandWidth,
1214}
1215
1217PhyEntity::GetSecondaryBand(uint16_t bandWidth) const
1218{
1220 return m_wifiPhy->GetBand(bandWidth,
1222}
1223
1224uint16_t
1226{
1227 return std::min(m_wifiPhy->GetChannelWidth(), txVector.GetChannelWidth());
1228}
1229
1230double
1232 WifiChannelListType /*channelType*/) const
1233{
1235}
1236
1237Time
1239{
1240 return m_wifiPhy->m_interference->GetEnergyDuration(DbmToW(thresholdDbm), band);
1241}
1242
1243void
1245{
1246 // We are here because we have received the first bit of a packet and we are
1247 // not going to be able to synchronize on it
1248 // In this model, CCA becomes busy when the aggregation of all signals as
1249 // tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
1250 const auto ccaIndication = GetCcaIndication(ppdu);
1251 if (ccaIndication.has_value())
1252 {
1253 NS_LOG_DEBUG("CCA busy for " << ccaIndication.value().second << " during "
1254 << ccaIndication.value().first.As(Time::S));
1255 m_state->SwitchMaybeToCcaBusy(ccaIndication.value().first,
1256 ccaIndication.value().second,
1257 {});
1258 return;
1259 }
1260 if (ppdu)
1261 {
1262 SwitchMaybeToCcaBusy(nullptr);
1263 }
1264}
1265
1268{
1269 const uint16_t channelWidth = GetMeasurementChannelWidth(ppdu);
1270 NS_LOG_FUNCTION(this << channelWidth);
1271 const double ccaThresholdDbm = GetCcaThreshold(ppdu, WIFI_CHANLIST_PRIMARY);
1272 const Time delayUntilCcaEnd =
1273 GetDelayUntilCcaEnd(ccaThresholdDbm, GetPrimaryBand(channelWidth));
1274 if (delayUntilCcaEnd.IsStrictlyPositive())
1275 {
1276 return std::make_pair(delayUntilCcaEnd, WIFI_CHANLIST_PRIMARY);
1277 }
1278 return std::nullopt;
1279}
1280
1281void
1283 Time duration,
1284 WifiChannelListType channelType)
1285{
1286 NS_LOG_FUNCTION(this << duration << channelType);
1287 NS_LOG_DEBUG("CCA busy for " << channelType << " during " << duration.As(Time::S));
1288 m_state->SwitchMaybeToCcaBusy(duration, channelType, {});
1289}
1290
1291uint64_t
1293{
1294 NS_LOG_FUNCTION(this);
1295 return m_globalPpduUid++;
1296}
1297
1298Time
1300{
1301 return Seconds(0);
1302}
1303
1304uint16_t
1306{
1307 NS_LOG_FUNCTION(this << txVector);
1308
1310 txVector.GetChannelWidth());
1311}
1312
1313void
1314PhyEntity::NotifyPayloadBegin(const WifiTxVector& txVector, const Time& payloadDuration)
1315{
1316 m_wifiPhy->m_phyRxPayloadBeginTrace(txVector, payloadDuration);
1317}
1318
1319void
1321{
1322 NS_LOG_FUNCTION(this << ppdu);
1323 auto txPowerDbm = m_wifiPhy->GetTxPowerForTransmission(ppdu) + m_wifiPhy->GetTxGain();
1324 auto txVector = ppdu->GetTxVector();
1325 auto txPowerSpectrum = GetTxPowerSpectralDensity(DbmToW(txPowerDbm), ppdu);
1326 Transmit(ppdu->GetTxDuration(), ppdu, txPowerDbm, txPowerSpectrum, "transmission");
1327}
1328
1329void
1332 double txPowerDbm,
1333 Ptr<SpectrumValue> txPowerSpectrum,
1334 const std::string& type)
1335{
1336 NS_LOG_FUNCTION(this << txDuration << ppdu << txPowerDbm << type);
1337 NS_LOG_DEBUG("Start " << type << ": signal power before antenna gain=" << txPowerDbm << "dBm");
1338 auto txParams = Create<WifiSpectrumSignalParameters>();
1339 txParams->duration = txDuration;
1340 txParams->psd = txPowerSpectrum;
1341 txParams->ppdu = ppdu;
1342 NS_LOG_DEBUG("Starting " << type << " with power " << txPowerDbm << " dBm on channel "
1343 << +m_wifiPhy->GetChannelNumber() << " for "
1344 << txParams->duration.As(Time::MS));
1345 NS_LOG_DEBUG("Starting " << type << " with integrated spectrum power "
1346 << WToDbm(Integral(*txPowerSpectrum)) << " dBm; spectrum model Uid: "
1347 << txPowerSpectrum->GetSpectrumModel()->GetUid());
1348 auto spectrumWifiPhy = DynamicCast<SpectrumWifiPhy>(m_wifiPhy);
1349 NS_ASSERT(spectrumWifiPhy);
1350 spectrumWifiPhy->Transmit(txParams);
1351}
1352
1353uint16_t
1354PhyEntity::GetGuardBandwidth(uint16_t currentChannelWidth) const
1355{
1356 return m_wifiPhy->GetGuardBandwidth(currentChannelWidth);
1357}
1358
1359std::tuple<double, double, double>
1361{
1363}
1364
1365Time
1367 const WifiTxVector& txVector,
1368 WifiPhyBand band) const
1369{
1370 NS_ASSERT(psduMap.size() == 1);
1371 const auto& it = psduMap.begin();
1372 return WifiPhy::CalculateTxDuration(it->second->GetSize(), txVector, band, it->first);
1373}
1374
1375bool
1377{
1378 // The PHY shall not issue a PHY-RXSTART.indication primitive in response to a PPDU that does
1379 // not overlap the primary channel
1380 const auto channelWidth = m_wifiPhy->GetChannelWidth();
1381 const auto primaryWidth =
1382 ((channelWidth % 20 == 0) ? 20
1383 : channelWidth); // if the channel width is a multiple of 20 MHz,
1384 // then we consider the primary20 channel
1385 const auto p20CenterFreq =
1387 const auto p20MinFreq = p20CenterFreq - (primaryWidth / 2);
1388 const auto p20MaxFreq = p20CenterFreq + (primaryWidth / 2);
1389 const auto txCenterFreq = ppdu->GetTxCenterFreq();
1390 const auto txChannelWidth = ppdu->GetTxChannelWidth();
1391 const auto minTxFreq = txCenterFreq - txChannelWidth / 2;
1392 const auto maxTxFreq = txCenterFreq + txChannelWidth / 2;
1393 return p20MinFreq >= minTxFreq && p20MaxFreq <= maxTxFreq;
1394}
1395
1398{
1399 return ppdu;
1400}
1401
1402} // namespace ns3
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
void NotifyPayloadBegin(const WifiTxVector &txVector, const Time &payloadDuration)
Fire the trace indicating that the PHY is starting to receive the payload of a PPDU.
Definition: phy-entity.cc:1314
virtual void HandleRxPpduWithSameContent(Ptr< Event > event, Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPower)
Handle reception of a PPDU that carries the same content of another PPDU.
Definition: phy-entity.cc:886
void DropPreambleEvent(Ptr< const WifiPpdu > ppdu, WifiPhyRxfailureReason reason, Time endRx)
Drop the PPDU and the corresponding preamble detection event, but keep CCA busy state after the compl...
Definition: phy-entity.cc:518
std::list< WifiMode >::const_iterator end() const
Return a const iterator to past-the-last WifiMode.
Definition: phy-entity.cc:147
virtual void RxPayloadSucceeded(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, uint16_t staId, const std::vector< bool > &statusPerMpdu)
Perform amendment-specific actions when the payload is successfully received.
Definition: phy-entity.cc:757
virtual PhyFieldRxStatus DoEndReceivePreamble(Ptr< Event > event)
End receiving the preamble, perform amendment-specific actions, and provide the status of the recepti...
Definition: phy-entity.cc:935
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper of the WifiPhy (to make it reachable for child classes)
Definition: phy-entity.h:982
virtual void RxPayloadFailed(Ptr< const WifiPsdu > psdu, double snr, const WifiTxVector &txVector)
Perform amendment-specific actions when the payload is unsuccessfuly received.
Definition: phy-entity.cc:768
void EndPreambleDetectionPeriod(Ptr< Event > event)
End the preamble detection period.
Definition: phy-entity.cc:960
virtual void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration, WifiChannelListType channelType)
Notify PHY state helper to switch to CCA busy state,.
Definition: phy-entity.cc:1282
virtual Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration)
Build amendment-specific PPDU.
Definition: phy-entity.cc:244
virtual Time GetDuration(WifiPpduField field, const WifiTxVector &txVector) const
Get the duration of the PPDU field (or group of fields) used by this entity for the given transmissio...
Definition: phy-entity.cc:193
std::tuple< double, double, double > GetTxMaskRejectionParams() const
Definition: phy-entity.cc:1360
virtual uint64_t ObtainNextUid(const WifiTxVector &txVector)
Obtain the next UID for the PPDU to transmit.
Definition: phy-entity.cc:1292
virtual Time DoStartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: phy-entity.cc:573
Time GetDelayUntilCcaEnd(double thresholdDbm, const WifiSpectrumBandInfo &band)
Return the delay until CCA busy is ended for a given sensitivity threshold (in dBm) and a given band.
Definition: phy-entity.cc:1238
virtual void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: phy-entity.cc:400
bool NoEndPreambleDetectionEvents() const
Definition: phy-entity.cc:1128
virtual bool HandlesMcsModes() const
Check if the WifiModes handled by this PHY are MCSs.
Definition: phy-entity.cc:135
const std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > & GetCurrentPreambleEvents() const
Get the map of current preamble events (stored in WifiPhy).
Definition: phy-entity.cc:838
std::map< UidStaIdPair, SignalNoiseDbm > m_signalNoiseMap
Map of the latest signal power and noise power in dBm (noise power includes the noise figure)
Definition: phy-entity.h:1002
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition: phy-entity.h:981
void Transmit(Time txDuration, Ptr< const WifiPpdu > ppdu, double txPowerDbm, Ptr< SpectrumValue > txPowerSpectrum, const std::string &type)
This function prepares most of the WifiSpectrumSignalParameters parameters and invokes SpectrumWifiPh...
Definition: phy-entity.cc:1330
virtual Ptr< SpectrumValue > GetTxPowerSpectralDensity(double txPowerW, Ptr< const WifiPpdu > ppdu) const =0
WifiSpectrumBandInfo GetSecondaryBand(uint16_t bandWidth) const
If the channel bonding is used, return the info corresponding to the secondary channel of the given b...
Definition: phy-entity.cc:1217
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
Definition: phy-entity.h:988
virtual uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const =0
Return the channel width used to measure the RSSI.
virtual ~PhyEntity()
Destructor for PHY entity.
Definition: phy-entity.cc:84
virtual double GetCcaThreshold(const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType) const
Return the CCA threshold in dBm for a given channel type.
Definition: phy-entity.cc:1231
virtual const PpduFormats & GetPpduFormats() const =0
Return the PPDU formats of the PHY.
virtual uint8_t GetNumModes() const
Definition: phy-entity.cc:113
virtual bool DoStartReceiveField(WifiPpduField field, Ptr< Event > event)
Start receiving a given field, perform amendment-specific actions, and signify if it is supported.
Definition: phy-entity.cc:369
void SetOwner(Ptr< WifiPhy > wifiPhy)
Set the WifiPhy owning this PHY entity.
Definition: phy-entity.cc:92
std::list< WifiMode >::const_iterator begin() const
Return a const iterator to the first WifiMode.
Definition: phy-entity.cc:141
virtual void CancelAllEvents()
Cancel and clear all running events.
Definition: phy-entity.cc:1111
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
Definition: phy-entity.cc:1153
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Abort the current reception.
Definition: phy-entity.cc:1145
void EndReceivePayload(Ptr< Event > event)
The last symbol of the PPDU has arrived.
Definition: phy-entity.cc:694
static uint64_t m_globalPpduUid
Global counter of the PPDU UID.
Definition: phy-entity.h:1005
PhyHeaderSections GetPhyHeaderSections(const WifiTxVector &txVector, Time ppduStart) const
Return a map of PHY header chunk information per PPDU field.
Definition: phy-entity.cc:226
virtual bool IsMcsSupported(uint8_t index) const
Check if the WifiMode corresponding to the given MCS index is supported.
Definition: phy-entity.cc:127
void StartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: phy-entity.cc:563
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
Definition: phy-entity.h:991
virtual void DoResetReceive(Ptr< Event > event)
Perform amendment-specific actions before resetting PHY at the end of the PPDU under reception after ...
Definition: phy-entity.cc:1181
void EndReceiveField(WifiPpduField field, Ptr< Event > event)
End receiving a given field.
Definition: phy-entity.cc:309
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW)
Get the event corresponding to the incoming PPDU.
Definition: phy-entity.cc:852
virtual WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const
Get the WifiMode for the SIG field specified by the PPDU field.
Definition: phy-entity.cc:153
WifiPpduField GetNextField(WifiPpduField currentField, WifiPreamble preamble) const
Return the field following the provided one.
Definition: phy-entity.cc:162
void CancelRunningEndPreambleDetectionEvents()
Cancel all end preamble detection events.
Definition: phy-entity.cc:1134
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition: phy-entity.h:326
double GetRxPowerWForPpdu(Ptr< Event > event) const
Obtain the received power (W) for a given band.
Definition: phy-entity.cc:1194
virtual 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: phy-entity.cc:1244
Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector) const
Definition: phy-entity.cc:203
void NotifyInterferenceRxEndAndClear(bool reset)
Notify WifiPhy's InterferenceHelper of the end of the reception, clear maps and end of MPDU event,...
Definition: phy-entity.cc:918
void StartPreambleDetectionPeriod(Ptr< Event > event)
Start the preamble detection period.
Definition: phy-entity.cc:945
Time GetDurationUpToField(WifiPpduField field, const WifiTxVector &txVector) const
Get the duration of the PPDU up to (but excluding) the given field.
Definition: phy-entity.cc:255
std::map< UidStaIdPair, std::vector< bool > > m_statusPerMpduMap
Map of the current reception status per MPDU that is filled in as long as MPDUs are being processed b...
Definition: phy-entity.h:999
virtual bool CanStartRx(Ptr< const WifiPpdu > ppdu) const
Determine whether the PHY shall issue a PHY-RXSTART.indication primitive in response to a given PPDU.
Definition: phy-entity.cc:1376
virtual void StartTx(Ptr< const WifiPpdu > ppdu)
This function is called by SpectrumWifiPhy to send the PPDU while performing amendment-specific actio...
Definition: phy-entity.cc:1320
virtual uint16_t GetRxChannelWidth(const WifiTxVector &txVector) const
Return the channel width used in the reception spectrum model.
Definition: phy-entity.cc:1225
Time GetRemainingDurationAfterField(Ptr< const WifiPpdu > ppdu, WifiPpduField field) const
Get the remaining duration of the PPDU after the end of the given field.
Definition: phy-entity.cc:361
virtual uint16_t GetStaId(const Ptr< const WifiPpdu > ppdu) const
Return the STA ID that has been assigned to the station this PHY belongs to.
Definition: phy-entity.cc:557
virtual Time CalculateTxDuration(WifiConstPsduMap psduMap, const WifiTxVector &txVector, WifiPhyBand band) const
Definition: phy-entity.cc:1366
void StartReceiveField(WifiPpduField field, Ptr< Event > event)
Start receiving a given field.
Definition: phy-entity.cc:282
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const
Definition: phy-entity.cc:1354
virtual bool IsModeSupported(WifiMode mode) const
Check if the WifiMode is supported.
Definition: phy-entity.cc:100
void ResetReceive(Ptr< Event > event)
Reset PHY at the end of the PPDU under reception after it has failed the PHY header.
Definition: phy-entity.cc:1167
std::optional< std::pair< Time, WifiChannelListType > > CcaIndication
CCA end time and its corresponding channel list type (can be std::nullopt if IDLE)
Definition: phy-entity.h:969
virtual CcaIndication GetCcaIndication(const Ptr< const WifiPpdu > ppdu)
Get CCA end time and its corresponding channel list type when a new signal has been received by the P...
Definition: phy-entity.cc:1267
std::list< WifiMode > m_modeList
the list of supported modes
Definition: phy-entity.h:985
virtual Time GetMaxDelayPpduSameUid(const WifiTxVector &txVector)
Obtain the maximum time between two PPDUs with the same UID to consider they are identical and their ...
Definition: phy-entity.cc:1299
Ptr< const Event > GetCurrentEvent() const
Get the pointer to the current event (stored in WifiPhy).
Definition: phy-entity.cc:1200
double GetRandomValue() const
Obtain a random value from the WifiPhy's generator.
Definition: phy-entity.cc:1188
std::vector< EventId > m_endPreambleDetectionEvents
the end of preamble detection events
Definition: phy-entity.h:987
virtual Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
Definition: phy-entity.cc:220
SnrPer GetPhyHeaderSnrPer(WifiPpduField field, Ptr< Event > event) const
Obtain the SNR and PER of the PPDU field from the WifiPhy's InterferenceHelper class.
Definition: phy-entity.cc:271
void ErasePreambleEvent(Ptr< const WifiPpdu > ppdu, Time rxDuration)
Erase the event corresponding to the PPDU from the list of preamble events, but consider it as noise ...
Definition: phy-entity.cc:536
virtual Ptr< const WifiPpdu > GetRxPpduFromTxPpdu(Ptr< const WifiPpdu > ppdu)
The WifiPpdu from the TX PHY is received by each RX PHY attached to the same channel.
Definition: phy-entity.cc:1397
virtual WifiMode GetMcs(uint8_t index) const
Get the WifiMode corresponding to the given MCS index.
Definition: phy-entity.cc:119
void AddPreambleEvent(Ptr< Event > event)
Add an entry to the map of current preamble events (stored in WifiPhy).
Definition: phy-entity.cc:844
virtual void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu)
Perform amendment-specific actions at the end of the reception of the payload.
Definition: phy-entity.cc:775
uint16_t GetCenterFrequencyForChannelWidth(const WifiTxVector &txVector) const
Get the center frequency of the channel corresponding the current TxVector rather than that of the su...
Definition: phy-entity.cc:1305
virtual WifiConstPsduMap GetWifiConstPsduMap(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector) const
Get a WifiConstPsduMap from a PSDU and the TXVECTOR to use to send the PSDU.
Definition: phy-entity.cc:214
virtual std::pair< uint16_t, WifiSpectrumBandInfo > GetChannelWidthAndBand(const WifiTxVector &txVector, uint16_t staId) const
Get the channel width and band to use (will be overloaded by child classes).
Definition: phy-entity.cc:831
virtual bool IsConfigSupported(Ptr< const WifiPpdu > ppdu) const
Checks if the signaled configuration (excluding bandwidth) is supported by the PHY.
Definition: phy-entity.cc:1098
Ptr< Event > CreateInterferenceEvent(Ptr< const WifiPpdu > ppdu, Time duration, RxPowerWattPerChannelBand &rxPower, bool isStartHePortionRxing=false)
Create an event using WifiPhy's InterferenceHelper class.
Definition: phy-entity.cc:873
PhyRxFailureAction
Action to perform in case of RX failure.
Definition: phy-entity.h:102
@ DROP
drop PPDU and set CCA_BUSY
Definition: phy-entity.h:103
@ IGNORE
ignore the reception
Definition: phy-entity.h:105
@ ABORT
abort reception of PPDU
Definition: phy-entity.h:104
std::pair< bool, SignalNoiseDbm > GetReceptionStatus(Ptr< const WifiPsdu > psdu, Ptr< Event > event, uint16_t staId, Time relativeMpduStart, Time mpduDuration)
Get the reception status for the provided MPDU and notify.
Definition: phy-entity.cc:787
WifiSpectrumBandInfo GetPrimaryBand(uint16_t bandWidth) const
If the operating channel width is a multiple of 20 MHz, return the info corresponding to the primary ...
Definition: phy-entity.cc:1206
void EndOfMpdu(Ptr< Event > event, Ptr< const WifiPsdu > psdu, size_t mpduIndex, Time relativeStart, Time mpduDuration)
The last symbol of an MPDU in an A-MPDU has arrived.
Definition: phy-entity.cc:657
virtual PhyFieldRxStatus DoEndReceiveField(WifiPpduField field, Ptr< Event > event)
End receiving a given field, perform amendment-specific actions, and provide the status of the recept...
Definition: phy-entity.cc:388
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Definition: phy-entity.cc:595
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
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:415
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:351
@ MS
millisecond
Definition: nstime.h:117
@ S
second
Definition: nstime.h:116
@ NS
nanosecond
Definition: nstime.h:119
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:315
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
represent a single transmission mode
Definition: wifi-mode.h:51
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1323
double GetCcaEdThreshold() const
Return the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:517
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1322
void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration)
Notify PHY state helper to switch to CCA busy state,.
Definition: wifi-phy.cc:2175
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition: wifi-phy.h:1568
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:1492
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1083
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:1335
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1330
double GetTxGain() const
Return the transmission gain (dB).
Definition: wifi-phy.cc:593
bool IsStateRx() const
Definition: wifi-phy.cc:2120
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1071
static Time GetPreambleDetectionDuration()
Definition: wifi-phy.cc:1480
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition: wifi-phy.cc:2182
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:1610
void NotifyRxBegin(Ptr< const WifiPsdu > psdu, const RxPowerWattPerChannelBand &rxPowersW)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:1616
virtual uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const =0
bool IsStateOff() const
Definition: wifi-phy.cc:2144
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1539
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1358
void NotifyRxPpduDrop(Ptr< const WifiPpdu > ppdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxPpduDrop trace.
Definition: wifi-phy.cc:1652
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: wifi-phy.h:1613
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1053
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:1333
uint8_t GetChannelNumber() const
Return current channel number.
Definition: wifi-phy.cc:1077
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1338
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:1611
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:1628
bool IsStateSleep() const
Definition: wifi-phy.cc:2138
virtual FrequencyRange GetCurrentFrequencyRange() const =0
Get the frequency range of the current RF interface.
virtual WifiSpectrumBandInfo GetBand(uint16_t bandWidth, uint8_t bandIndex=0)=0
Get the info of a given band.
void SwitchMaybeToCcaBusy(const Ptr< const WifiPpdu > ppdu=nullptr)
Check if PHY state should move to CCA busy state based on current state of interference tracker.
Definition: wifi-phy.cc:2168
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition: wifi-phy.h:1320
double GetTxPowerForTransmission(Ptr< const WifiPpdu > ppdu) const
Compute the transmit power for the next transmission.
Definition: wifi-phy.cc:2255
virtual std::tuple< double, double, double > GetTxMaskRejectionParams() const =0
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:1659
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition: wifi-phy.cc:765
void Reset()
Reset data upon end of TX or RX.
Definition: wifi-phy.cc:1907
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:1494
Time GetLastRxEndTime() const
Return the end time of the last received packet.
Definition: wifi-phy.cc:2162
Time m_timeLastPreambleDetected
Record the time the last preamble was detected.
Definition: wifi-phy.h:1614
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1065
double GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:530
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...
uint8_t GetSecondaryChannelIndex(uint16_t secondaryChannelWidth) const
If the operating channel width is made of a multiple of 20 MHz, return the index of the secondary cha...
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiPreamble GetPreambleType() const
uint16_t GetChannelWidth() const
#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_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_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
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1343
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1355
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
WifiPpduField
The type of PPDU field (grouped for convenience)
MpduType
The type of an MPDU.
@ PREAMBLE_DETECT_FAILURE
@ TRUNCATED_TX
@ FRAME_CAPTURE_PACKET_SWITCH
@ POWERED_OFF
@ CHANNEL_SWITCHING
@ BUSY_DECODING_PREAMBLE
@ PPDU_TOO_LATE
@ PREAMBLE_DETECTION_PACKET_SWITCH
@ WIFI_CHANLIST_PRIMARY
@ WIFI_PPDU_FIELD_EHT_SIG
EHT-SIG field.
@ WIFI_PPDU_FIELD_PREAMBLE
SYNC + SFD fields for DSSS or ERP, shortSYNC + shortSFD fields for HR/DSSS or ERP,...
@ WIFI_PPDU_FIELD_DATA
data field
@ 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.
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:54
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
@ SWITCHING
The PHY layer is switching to other channel.
@ TX
The PHY layer is sending a packet.
@ OFF
The PHY layer is switched off.
@ IDLE
The PHY layer is IDLE.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ SLEEP
The PHY layer is sleeping.
@ RX
The PHY layer is receiving a packet.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:48
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
double Integral(const SpectrumValue &arg)
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:42
std::map< WifiSpectrumBandInfo, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:77
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
Declaration of:
Status of the reception of the PPDU field.
Definition: phy-entity.h:112
WifiPhyRxfailureReason reason
failure reason
Definition: phy-entity.h:114
PhyRxFailureAction actionIfFailure
action to perform in case of failure
Definition: phy-entity.h:115
bool isSuccess
outcome (true if success) of the reception
Definition: phy-entity.h:113
A struct for both SNR and PER.
Definition: phy-entity.h:147
double snr
SNR in linear scale.
Definition: phy-entity.h:148
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:69
double rssi
RSSI in dBm.
Definition: phy-entity.h:71
double snr
SNR in linear scale.
Definition: phy-entity.h:70
SignalNoiseDbm structure.
Definition: phy-entity.h:55
double noise
noise power in dBm
Definition: phy-entity.h:57
double signal
signal strength in dBm
Definition: phy-entity.h:56
WifiSpectrumBandInfo structure containing info about a spectrum band.