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