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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Rediet <getachew.redieteab@orange.com>
7 * Sébastien Deronne <sebastien.deronne@gmail.com> (for logic ported from wifi-phy and
8 * spectrum-wifi-phy)
9 * Mathieu Lacage <mathieu.lacage@sophia.inria.fr> (for logic ported from wifi-phy)
10 */
11
12#include "phy-entity.h"
13
14#include "frame-capture-model.h"
15#include "interference-helper.h"
17#include "spectrum-wifi-phy.h"
18#include "wifi-psdu.h"
20#include "wifi-utils.h"
21
22#include "ns3/assert.h"
23#include "ns3/data-rate.h"
24#include "ns3/log.h"
25#include "ns3/packet.h"
26#include "ns3/simulator.h"
27
28#include <algorithm>
29
30#undef NS_LOG_APPEND_CONTEXT
31#define NS_LOG_APPEND_CONTEXT WIFI_PHY_NS_LOG_APPEND_CONTEXT(m_wifiPhy)
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("PhyEntity");
37
38std::ostream&
39operator<<(std::ostream& os, const PhyEntity::PhyRxFailureAction& action)
40{
41 switch (action)
42 {
43 case PhyEntity::DROP:
44 return (os << "DROP");
46 return (os << "ABORT");
48 return (os << "IGNORE");
49 default:
50 NS_FATAL_ERROR("Unknown action");
51 return (os << "unknown");
52 }
53}
54
55std::ostream&
56operator<<(std::ostream& os, const PhyEntity::PhyFieldRxStatus& status)
57{
58 if (status.isSuccess)
59 {
60 return os << "success";
61 }
62 else
63 {
64 return os << "failure (" << status.reason << "/" << status.actionIfFailure << ")";
65 }
66}
67
68/*******************************************************
69 * Abstract base class for PHY entities
70 *******************************************************/
71
73
80
81void
83{
84 NS_LOG_FUNCTION(this << wifiPhy);
85 m_wifiPhy = wifiPhy;
87}
88
89bool
91{
92 for (const auto& m : m_modeList)
93 {
94 if (m == mode)
95 {
96 return true;
97 }
98 }
99 return false;
100}
101
102uint8_t
104{
105 return m_modeList.size();
106}
107
109PhyEntity::GetMcs(uint8_t /* index */) const
110{
112 "This method should be used only for HtPhy and child classes. Use GetMode instead.");
113 return WifiMode();
114}
115
116bool
117PhyEntity::IsMcsSupported(uint8_t /* index */) const
118{
119 NS_ABORT_MSG("This method should be used only for HtPhy and child classes. Use IsModeSupported "
120 "instead.");
121 return false;
122}
123
124bool
126{
127 return false;
128}
129
130std::list<WifiMode>::const_iterator
132{
133 return m_modeList.begin();
134}
135
136std::list<WifiMode>::const_iterator
138{
139 return m_modeList.end();
140}
141
144{
145 NS_FATAL_ERROR("PPDU field is not a SIG field (no sense in retrieving the signaled mode) or is "
146 "unsupported: "
147 << field);
148 return WifiMode(); // should be overloaded
149}
150
153{
154 const auto& ppduFormats = GetPpduFormats();
155 const auto itPpdu = ppduFormats.find(preamble);
156 if (itPpdu != ppduFormats.end())
157 {
158 const auto itField = std::find(itPpdu->second.begin(), itPpdu->second.end(), currentField);
159 if (itField != itPpdu->second.end())
160 {
161 const auto itNextField = std::next(itField, 1);
162 if (itNextField != itPpdu->second.end())
163 {
164 return *(itNextField);
165 }
166 NS_FATAL_ERROR("No field after " << currentField << " for " << preamble
167 << " for the provided PPDU formats");
168 }
169 else
170 {
171 NS_FATAL_ERROR("Unsupported PPDU field " << currentField << " for " << preamble
172 << " for the provided PPDU formats");
173 }
174 }
175 else
176 {
177 NS_FATAL_ERROR("Unsupported preamble " << preamble << " for the provided PPDU formats");
178 }
179 return WifiPpduField::WIFI_PPDU_FIELD_PREAMBLE; // Silence compiler warning
180}
181
182Time
184{
185 if (field > WIFI_PPDU_FIELD_EHT_SIG)
186 {
187 NS_FATAL_ERROR("Unsupported PPDU field");
188 }
189 return Time(); // should be overloaded
190}
191
192Time
194{
195 Time duration;
196 for (uint8_t field = WIFI_PPDU_FIELD_PREAMBLE; field < WIFI_PPDU_FIELD_DATA; ++field)
197 {
198 duration += GetDuration(static_cast<WifiPpduField>(field), txVector);
199 }
200 return duration;
201}
202
205{
206 return WifiConstPsduMap({{SU_STA_ID, psdu}});
207}
208
211{
212 return ppdu->GetPsdu();
213}
214
216PhyEntity::GetPhyHeaderSections(const WifiTxVector& txVector, Time ppduStart) const
217{
219 WifiPpduField field = WIFI_PPDU_FIELD_PREAMBLE; // preamble always present
220 Time start = ppduStart;
221
222 while (field != WIFI_PPDU_FIELD_DATA)
223 {
224 Time duration = GetDuration(field, txVector);
225 map[field] = {{start, start + duration}, GetSigMode(field, txVector)};
226 // Move to next field
227 start += duration;
228 field = GetNextField(field, txVector.GetPreambleType());
229 }
230 return map;
231}
232
234PhyEntity::BuildPpdu(const WifiConstPsduMap& psdus, const WifiTxVector& txVector, Time ppduDuration)
235{
236 NS_LOG_FUNCTION(this << psdus << txVector << ppduDuration);
237 NS_FATAL_ERROR("This method is unsupported for the base PhyEntity class. Use the overloaded "
238 "version in the amendment-specific subclasses instead!");
239 return Create<WifiPpdu>(psdus.begin()->second,
240 txVector,
241 m_wifiPhy->GetOperatingChannel()); // should be overloaded
242}
243
244Time
246{
247 if (field ==
248 WIFI_PPDU_FIELD_DATA) // this field is not in the map returned by GetPhyHeaderSections
249 {
251 }
252 const auto& sections = GetPhyHeaderSections(txVector, Time());
253 auto it = sections.find(field);
254 NS_ASSERT(it != sections.end());
255 const auto& startStopTimes = it->second.first;
256 return startStopTimes
257 .first; // return the start time of field relatively to the beginning of the PPDU
258}
259
262{
263 const auto measurementChannelWidth = GetMeasurementChannelWidth(event->GetPpdu());
264 return m_wifiPhy->m_interference->CalculatePhyHeaderSnrPer(
265 event,
266 measurementChannelWidth,
267 GetPrimaryBand(measurementChannelWidth),
268 field);
269}
270
271void
273{
274 NS_LOG_FUNCTION(this << field << *event);
275 NS_ASSERT(m_wifiPhy); // no sense if no owner WifiPhy instance
278 "Use the StartReceivePreamble method for preamble reception");
279 // Handle special cases of data reception
280 if (field == WIFI_PPDU_FIELD_DATA)
281 {
282 StartReceivePayload(event);
283 return;
284 }
285
286 bool supported = DoStartReceiveField(field, event);
287 NS_ABORT_MSG_IF(!supported,
288 "Unknown field "
289 << field << " for this PHY entity"); // TODO see what to do if not supported
290 Time duration = GetDuration(field, event->GetPpdu()->GetTxVector());
292 Simulator::Schedule(duration, &PhyEntity::EndReceiveField, this, field, event);
294 event->GetPpdu(),
295 duration); // keep in CCA busy state up to reception of Data (will then switch to RX)
296}
297
298void
300{
301 NS_LOG_FUNCTION(this << field << *event);
302 NS_ASSERT(m_wifiPhy); // no sense if no owner WifiPhy instance
304 PhyFieldRxStatus status = DoEndReceiveField(field, event);
305 const auto& txVector = event->GetPpdu()->GetTxVector();
306 if (status.isSuccess) // move to next field if reception succeeded
307 {
308 StartReceiveField(GetNextField(field, txVector.GetPreambleType()), event);
309 }
310 else
311 {
312 Ptr<const WifiPpdu> ppdu = event->GetPpdu();
313 switch (status.actionIfFailure)
314 {
315 case ABORT:
316 // Abort reception, but consider medium as busy
318 if (event->GetEndTime() > (Simulator::Now() + m_state->GetDelayUntilIdle()))
319 {
321 }
322 break;
323 case DROP:
324 // Notify drop, keep in CCA busy, and perform same processing as IGNORE case
325 if (status.reason == FILTERED)
326 {
327 // PHY-RXSTART is immediately followed by PHY-RXEND (Filtered)
329 txVector,
330 NanoSeconds(0)); // this callback (equivalent to PHY-RXSTART primitive) is also
331 // triggered for filtered PPDUs
332 }
333 m_wifiPhy->NotifyRxPpduDrop(ppdu, status.reason);
335 // no break
336 case IGNORE:
337 // Keep in Rx state and reset at end
338 m_endRxPayloadEvents.push_back(
341 this,
342 event));
343 break;
344 default:
345 NS_FATAL_ERROR("Unknown action in case of failure");
346 }
347 }
348}
349
350Time
352{
353 const auto& txVector = ppdu->GetTxVector();
354 return ppdu->GetTxDuration() -
355 (GetDurationUpToField(field, txVector) + GetDuration(field, txVector));
356}
357
358bool
360{
361 NS_LOG_FUNCTION(this << field << *event);
363 field != WIFI_PPDU_FIELD_DATA); // handled apart for the time being
364 const auto& ppduFormats = GetPpduFormats();
365 auto itFormat = ppduFormats.find(event->GetPpdu()->GetPreamble());
366 if (itFormat != ppduFormats.end())
367 {
368 auto itField = std::find(itFormat->second.begin(), itFormat->second.end(), field);
369 if (itField != itFormat->second.end())
370 {
371 return true; // supported field so we can start receiving
372 }
373 }
374 return false; // unsupported otherwise
375}
376
379{
380 NS_LOG_FUNCTION(this << field << *event);
381 NS_ASSERT(field != WIFI_PPDU_FIELD_DATA); // handled apart for the time being
382 if (field == WIFI_PPDU_FIELD_PREAMBLE)
383 {
384 return DoEndReceivePreamble(event);
385 }
386 return PhyFieldRxStatus(false); // failed reception by default
387}
388
389void
391 RxPowerWattPerChannelBand& rxPowersW,
392 Time rxDuration)
393{
394 // The total RX power corresponds to the maximum over all the bands
395 auto it =
396 std::max_element(rxPowersW.begin(), rxPowersW.end(), [](const auto& p1, const auto& p2) {
397 return p1.second < p2.second;
398 });
399 NS_LOG_FUNCTION(this << ppdu << it->second);
400
401 auto event = DoGetEvent(ppdu, rxPowersW);
402 if (!event)
403 {
404 // PPDU should be simply considered as interference (once it has been accounted for in
405 // InterferenceHelper)
406 return;
407 }
408
409 Time endRx = Simulator::Now() + rxDuration;
410 if (ppdu->IsTruncatedTx())
411 {
412 NS_LOG_DEBUG("Packet reception stopped because transmitter has been switched off");
413 if (endRx > (Simulator::Now() + m_state->GetDelayUntilIdle()))
414 {
416 }
418 return;
419 }
420
421 switch (m_state->GetState())
422 {
424 NS_LOG_DEBUG("Drop packet because of channel switching");
425 /*
426 * Packets received on the upcoming channel are added to the event list
427 * during the switching state. This way the medium can be correctly sensed
428 * when the device listens to the channel for the first time after the
429 * switching e.g. after channel switching, the channel may be sensed as
430 * busy due to other devices' transmissions started before the end of
431 * the switching.
432 */
434 break;
435 case WifiPhyState::RX:
437 m_wifiPhy->m_frameCaptureModel->IsInCaptureWindow(
439 m_wifiPhy->m_frameCaptureModel->CaptureNewFrame(m_wifiPhy->m_currentEvent, event))
440 {
442 NS_LOG_DEBUG("Switch to new packet");
444 }
445 else
446 {
447 NS_LOG_DEBUG("Drop packet because already in Rx");
448 DropPreambleEvent(ppdu, RXING, endRx);
450 {
451 /*
452 * We are here because the non-legacy PHY header has not been successfully received.
453 * The PHY is kept in RX state for the duration of the PPDU, but EndReceive function
454 * is not called when the reception of the PPDU is finished, which is responsible to
455 * clear m_currentPreambleEvents. As a result, m_currentPreambleEvents should be
456 * cleared here.
457 */
459 }
460 }
461 break;
462 case WifiPhyState::TX:
463 NS_LOG_DEBUG("Drop packet because already in Tx");
464 DropPreambleEvent(ppdu, TXING, endRx);
465 break;
468 {
470 m_wifiPhy->m_frameCaptureModel->IsInCaptureWindow(
472 m_wifiPhy->m_frameCaptureModel->CaptureNewFrame(m_wifiPhy->m_currentEvent, event))
473 {
475 NS_LOG_DEBUG("Switch to new packet");
477 }
478 else
479 {
480 NS_LOG_DEBUG("Drop packet because already decoding preamble");
482 }
483 }
484 else
485 {
487 }
488 break;
492 break;
494 NS_LOG_DEBUG("Drop packet because in sleep mode");
495 DropPreambleEvent(ppdu, SLEEPING, endRx);
496 break;
498 NS_LOG_DEBUG("Drop packet because in switched off");
500 break;
501 default:
502 NS_FATAL_ERROR("Invalid WifiPhy state.");
503 break;
504 }
505}
506
507void
509{
510 NS_LOG_FUNCTION(this << ppdu << reason << endRx);
511 m_wifiPhy->NotifyRxPpduDrop(ppdu, reason);
512 auto it = m_wifiPhy->m_currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
513 if (it != m_wifiPhy->m_currentPreambleEvents.end())
514 {
516 }
518 (endRx > (Simulator::Now() + m_state->GetDelayUntilIdle())))
519 {
520 // that PPDU will be noise _after_ the end of the current event.
522 }
523}
524
525void
527{
528 NS_LOG_FUNCTION(this << ppdu << rxDuration);
529 auto it = m_wifiPhy->m_currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
530 if (it != m_wifiPhy->m_currentPreambleEvents.end())
531 {
533 }
535 {
536 m_wifiPhy->Reset();
537 }
538
539 if (rxDuration > m_state->GetDelayUntilIdle())
540 {
541 // this PPDU will be noise _after_ the completion of the current event
543 }
544}
545
546uint16_t
548{
549 return SU_STA_ID;
550}
551
552void
554{
555 NS_LOG_FUNCTION(this << *event);
557
558 Time payloadDuration = DoStartReceivePayload(event);
559 m_state->SwitchToRx(payloadDuration);
560}
561
562Time
564{
565 NS_LOG_FUNCTION(this << *event);
566 Ptr<const WifiPpdu> ppdu = event->GetPpdu();
567 NS_LOG_DEBUG("Receiving PSDU");
568 uint16_t staId = GetStaId(ppdu);
569 m_signalNoiseMap.insert({{ppdu->GetUid(), staId}, SignalNoiseDbm()});
570 m_statusPerMpduMap.insert({{ppdu->GetUid(), staId}, std::vector<bool>()});
571 ScheduleEndOfMpdus(event);
572 const auto& txVector = event->GetPpdu()->GetTxVector();
573 Time payloadDuration = ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector);
575 txVector,
576 payloadDuration); // this callback (equivalent to PHY-RXSTART primitive) is triggered only
577 // if headers have been correctly decoded and that the mode within is
578 // supported
579 m_endRxPayloadEvents.push_back(
580 Simulator::Schedule(payloadDuration, &PhyEntity::EndReceivePayload, this, event));
581 return payloadDuration;
582}
583
584void
586{
587 NS_LOG_FUNCTION(this << *event);
588 Ptr<const WifiPpdu> ppdu = event->GetPpdu();
590 const auto& txVector = event->GetPpdu()->GetTxVector();
591 uint16_t staId = GetStaId(ppdu);
592 Time endOfMpduDuration;
593 Time relativeStart;
594 Time psduDuration = ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector);
595 Time remainingAmpduDuration = psduDuration;
596 size_t nMpdus = psdu->GetNMpdus();
597 MpduType mpduType =
598 (nMpdus > 1) ? FIRST_MPDU_IN_AGGREGATE : (psdu->IsSingle() ? SINGLE_MPDU : NORMAL_MPDU);
599 uint32_t totalAmpduSize = 0;
600 double totalAmpduNumSymbols = 0.0;
601 auto mpdu = psdu->begin();
602 for (size_t i = 0; i < nMpdus && mpdu != psdu->end(); ++mpdu)
603 {
605 {
606 // calculate MAC header size (including A-MPDU subframe header, if present)
607 auto macHdrSize =
608 (*mpdu)->GetHeader().GetSerializedSize() + (mpduType == NORMAL_MPDU ? 0 : 4);
609 // calculate the (approximate) duration of the MAC header TX
610 auto macHdrDuration = DataRate(txVector.GetMode(staId).GetDataRate(txVector, staId))
611 .CalculateBytesTxTime(macHdrSize);
612 const auto widthBand = GetChannelWidthAndBand(txVector, staId);
613 const auto snrPer = m_wifiPhy->m_interference->CalculatePayloadSnrPer(
614 event,
615 widthBand.first,
616 widthBand.second,
617 staId,
618 {relativeStart, relativeStart + macHdrDuration});
619 if (GetRandomValue() > snrPer.per)
620 {
621 // interference level should permit to correctly decode the MAC header
622 m_endOfMacHdrEvents[staId].push_back(
623 Simulator::Schedule(endOfMpduDuration + macHdrDuration, [=, this]() {
624 m_wifiPhy->m_phyRxMacHeaderEndTrace((*mpdu)->GetHeader(),
625 txVector,
626 remainingAmpduDuration -
627 macHdrDuration);
628 }));
629 }
630 }
631
632 uint32_t size = (mpduType == NORMAL_MPDU) ? psdu->GetSize() : psdu->GetAmpduSubframeSize(i);
633 Time mpduDuration = WifiPhy::GetPayloadDuration(size,
634 txVector,
636 mpduType,
637 true,
638 totalAmpduSize,
639 totalAmpduNumSymbols,
640 staId);
641
642 remainingAmpduDuration -= mpduDuration;
643 if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero()) // no more MPDUs coming
644 {
645 if (remainingAmpduDuration < txVector.GetGuardInterval()) // enables to ignore padding
646 {
647 mpduDuration += remainingAmpduDuration; // apply a correction just in case rounding
648 // had induced slight shift
649 }
650 }
651
652 endOfMpduDuration += mpduDuration;
653 NS_LOG_INFO("Schedule end of MPDU #"
654 << i << " in " << endOfMpduDuration.As(Time::NS) << " (relativeStart="
655 << relativeStart.As(Time::NS) << ", mpduDuration=" << mpduDuration.As(Time::NS)
656 << ", remainingAmdpuDuration=" << remainingAmpduDuration.As(Time::NS) << ")");
657 m_endOfMpduEvents.push_back(Simulator::Schedule(endOfMpduDuration,
659 this,
660 event,
661 *mpdu,
662 i,
663 relativeStart,
664 mpduDuration));
665
666 // Prepare next iteration
667 ++i;
668 relativeStart += mpduDuration;
669 mpduType = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
670 }
671}
672
673void
675 Ptr<WifiMpdu> mpdu,
676 size_t mpduIndex,
677 Time relativeStart,
678 Time mpduDuration)
679{
680 NS_LOG_FUNCTION(this << *event << mpduIndex << relativeStart << mpduDuration);
681 const auto ppdu = event->GetPpdu();
682 const auto& txVector = ppdu->GetTxVector();
683 uint16_t staId = GetStaId(ppdu);
684
685 std::pair<bool, SignalNoiseDbm> rxInfo =
686 GetReceptionStatus(mpdu, event, staId, relativeStart, mpduDuration);
687 NS_LOG_DEBUG("Extracted MPDU #" << mpduIndex << ": duration: " << mpduDuration.As(Time::NS)
688 << ", correct reception: " << rxInfo.first << ", Signal/Noise: "
689 << rxInfo.second.signal << "/" << rxInfo.second.noise << "dBm");
690
691 auto signalNoiseIt = m_signalNoiseMap.find({ppdu->GetUid(), staId});
692 NS_ASSERT(signalNoiseIt != m_signalNoiseMap.end());
693 signalNoiseIt->second = rxInfo.second;
694
695 RxSignalInfo rxSignalInfo;
696 rxSignalInfo.snr = DbToRatio(dB_u{rxInfo.second.signal - rxInfo.second.noise});
697 rxSignalInfo.rssi = rxInfo.second.signal;
698
699 auto statusPerMpduIt = m_statusPerMpduMap.find({ppdu->GetUid(), staId});
700 NS_ASSERT(statusPerMpduIt != m_statusPerMpduMap.end());
701 statusPerMpduIt->second.push_back(rxInfo.first);
702
703 if (rxInfo.first && GetAddressedPsduInPpdu(ppdu)->GetNMpdus() > 1)
704 {
705 // only done for correct MPDU that is part of an A-MPDU
706 m_state->NotifyRxMpdu(Create<const WifiPsdu>(mpdu, false), rxSignalInfo, txVector);
707 }
708}
709
710void
712{
713 const auto ppdu = event->GetPpdu();
714 const auto& txVector = ppdu->GetTxVector();
716 this << *event << ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector));
717 NS_ASSERT(event->GetEndTime() == Simulator::Now());
718 const auto staId = GetStaId(ppdu);
719 const auto channelWidthAndBand = GetChannelWidthAndBand(txVector, staId);
720 const auto snr = m_wifiPhy->m_interference->CalculateSnr(event,
721 channelWidthAndBand.first,
722 txVector.GetNss(staId),
723 channelWidthAndBand.second);
724
726 m_wifiPhy->NotifyRxEnd(psdu);
727
728 auto signalNoiseIt = m_signalNoiseMap.find({ppdu->GetUid(), staId});
729 NS_ASSERT(signalNoiseIt != m_signalNoiseMap.end());
730 auto statusPerMpduIt = m_statusPerMpduMap.find({ppdu->GetUid(), staId});
731 NS_ASSERT(statusPerMpduIt != m_statusPerMpduMap.end());
732 // store per-MPDU status, which is cleared by the call to DoEndReceivePayload below
733 auto statusPerMpdu = statusPerMpduIt->second;
734
735 RxSignalInfo rxSignalInfo;
736 bool success;
737
738 if (std::count(statusPerMpdu.cbegin(), statusPerMpdu.cend(), true))
739 {
740 // At least one MPDU has been successfully received
743 txVector,
744 signalNoiseIt->second,
745 statusPerMpdu,
746 staId);
747 rxSignalInfo.snr = snr;
748 rxSignalInfo.rssi = signalNoiseIt->second.signal; // same information for all MPDUs
749 RxPayloadSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu);
751 ppdu->GetUid(); // store UID only if reception is successful (because otherwise trigger
752 // won't be read by MAC layer)
753 success = true;
754 }
755 else
756 {
757 RxPayloadFailed(psdu, snr, txVector);
758 success = false;
759 }
760
761 m_state->NotifyRxPpduOutcome(ppdu, rxSignalInfo, txVector, staId, statusPerMpduIt->second);
764
765 // notify the MAC through the PHY state helper as the last action. Indeed, the notification
766 // of the RX end may lead the MAC to request a PHY state change (e.g., channel switch, sleep).
767 // Hence, all actions the PHY has to perform when RX ends should be completed before
768 // notifying the MAC.
769 success ? m_state->NotifyRxPsduSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu)
770 : m_state->NotifyRxPsduFailed(psdu, snr);
771}
772
773void
775 RxSignalInfo rxSignalInfo,
776 const WifiTxVector& txVector,
777 uint16_t staId,
778 const std::vector<bool>& statusPerMpdu)
779{
780 NS_LOG_FUNCTION(this << *psdu << txVector);
781 m_state->SwitchFromRxEndOk();
782}
783
784void
786{
787 NS_LOG_FUNCTION(this << *psdu << txVector << snr);
788 m_state->SwitchFromRxEndError();
789}
790
791void
802
803std::pair<bool, SignalNoiseDbm>
805 Ptr<Event> event,
806 uint16_t staId,
807 Time relativeMpduStart,
808 Time mpduDuration)
809{
810 NS_LOG_FUNCTION(this << *mpdu << *event << staId << relativeMpduStart << mpduDuration);
811 const auto channelWidthAndBand = GetChannelWidthAndBand(event->GetPpdu()->GetTxVector(), staId);
812 SnrPer snrPer = m_wifiPhy->m_interference->CalculatePayloadSnrPer(
813 event,
814 channelWidthAndBand.first,
815 channelWidthAndBand.second,
816 staId,
817 {relativeMpduStart, relativeMpduStart + mpduDuration});
818
819 WifiMode mode = event->GetPpdu()->GetTxVector().GetMode(staId);
820 NS_LOG_DEBUG("rate=" << (mode.GetDataRate(event->GetPpdu()->GetTxVector(), staId))
821 << ", SNR(dB)=" << RatioToDb(snrPer.snr) << ", PER=" << snrPer.per
822 << ", size=" << mpdu->GetSize()
823 << ", relativeStart = " << relativeMpduStart.As(Time::NS)
824 << ", duration = " << mpduDuration.As(Time::NS));
825
826 // There are two error checks: PER and receive error model check.
827 // PER check models is typical for Wi-Fi and is based on signal modulation;
828 // Receive error model is optional, if we have an error model and
829 // it indicates that the packet is corrupt, drop the packet.
830 SignalNoiseDbm signalNoise;
831 signalNoise.signal = WToDbm(event->GetRxPower(channelWidthAndBand.second));
832 signalNoise.noise = WToDbm(event->GetRxPower(channelWidthAndBand.second) / snrPer.snr);
833 if (GetRandomValue() > snrPer.per &&
835 m_wifiPhy->m_postReceptionErrorModel->IsCorrupt(mpdu->GetPacket()->Copy())))
836 {
837 NS_LOG_DEBUG("Reception succeeded: " << *mpdu);
838 return {true, signalNoise};
839 }
840 else
841 {
842 NS_LOG_DEBUG("Reception failed: " << *mpdu);
843 return {false, signalNoise};
844 }
845}
846
847std::optional<Time>
848PhyEntity::GetTimeToMacHdrEnd(uint16_t staId) const
849{
850 const auto it = m_endOfMacHdrEvents.find(staId);
851
852 if (it == m_endOfMacHdrEvents.cend())
853 {
854 return std::nullopt;
855 }
856
857 for (const auto& endOfMacHdrEvent : it->second)
858 {
859 if (endOfMacHdrEvent.IsPending())
860 {
861 return Simulator::GetDelayLeft(endOfMacHdrEvent);
862 }
863 }
864
865 return std::nullopt;
866}
867
868std::pair<MHz_u, WifiSpectrumBandInfo>
869PhyEntity::GetChannelWidthAndBand(const WifiTxVector& txVector, uint16_t /* staId */) const
870{
871 const auto channelWidth = GetRxChannelWidth(txVector);
872 return {channelWidth, GetPrimaryBand(channelWidth)};
873}
874
875const std::map<std::pair<uint64_t, WifiPreamble>, Ptr<Event>>&
880
881void
883{
884 NS_LOG_FUNCTION(this << *event);
885 Ptr<const WifiPpdu> ppdu = event->GetPpdu();
886 m_wifiPhy->m_currentPreambleEvents.insert({{ppdu->GetUid(), ppdu->GetPreamble()}, event});
887}
888
891{
892 // We store all incoming preamble events, and a decision is made at the end of the preamble
893 // detection window.
894 const auto& currentPreambleEvents = GetCurrentPreambleEvents();
895 const auto it = currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
896 if (it != currentPreambleEvents.cend())
897 {
898 // received another signal with the same content
899 NS_LOG_DEBUG("Received another PPDU for UID " << ppdu->GetUid());
900 const auto foundEvent = it->second;
901 HandleRxPpduWithSameContent(foundEvent, ppdu, rxPowersW);
902 return nullptr;
903 }
904
905 auto event = CreateInterferenceEvent(ppdu, ppdu->GetTxDuration(), rxPowersW);
906 AddPreambleEvent(event);
907 return event;
908}
909
912 Time duration,
914 bool isStartHePortionRxing /* = false */)
915{
916 return m_wifiPhy->m_interference->Add(ppdu,
917 duration,
918 rxPower,
920 isStartHePortionRxing);
921}
922
923void
927{
928 if (const auto maxDelay =
929 m_wifiPhy->GetPhyEntityForPpdu(ppdu)->GetMaxDelayPpduSameUid(ppdu->GetTxVector());
930 Simulator::Now() - event->GetStartTime() > maxDelay)
931 {
932 // This PPDU arrived too late to be decoded properly. The PPDU is dropped and added as
933 // interference
934 event = CreateInterferenceEvent(ppdu, ppdu->GetTxDuration(), rxPower);
935 NS_LOG_DEBUG("Drop PPDU that arrived too late");
937 return;
938 }
939
940 // Update received power and TXVECTOR of the event associated to that transmission upon
941 // reception of a signal adding up constructively (in case of a UL MU PPDU or non-HT duplicate
942 // PPDU)
943 m_wifiPhy->m_interference->UpdateEvent(event, rxPower);
944 const auto& txVector = ppdu->GetTxVector();
945 const auto& eventTxVector = event->GetPpdu()->GetTxVector();
946 auto updatedTxVector{eventTxVector};
947 updatedTxVector.SetChannelWidth(
948 std::max(eventTxVector.GetChannelWidth(), txVector.GetChannelWidth()));
949 if (updatedTxVector.GetChannelWidth() != eventTxVector.GetChannelWidth())
950 {
951 event->UpdatePpdu(ppdu);
952 }
953}
954
955void
957{
959 m_signalNoiseMap.clear();
960 m_statusPerMpduMap.clear();
961 for (const auto& endOfMpduEvent : m_endOfMpduEvents)
962 {
963 NS_ASSERT(endOfMpduEvent.IsExpired());
964 }
965 m_endOfMpduEvents.clear();
966 for (const auto& [staId, endOfMacHdrEvents] : m_endOfMacHdrEvents)
967 {
968 for (const auto& endOfMacHdrEvent : endOfMacHdrEvents)
969 {
970 NS_ASSERT(endOfMacHdrEvent.IsExpired());
971 }
972 }
973 m_endOfMacHdrEvents.clear();
974 if (reset)
975 {
976 m_wifiPhy->Reset();
977 }
978}
979
982{
983 NS_LOG_FUNCTION(this << *event);
985 1); // Synched on one after detection period
986 return PhyFieldRxStatus(true); // always consider that preamble has been correctly received if
987 // preamble detection was OK
988}
989
990void
992{
993 NS_LOG_FUNCTION(this << *event);
994 const auto rxPower = GetRxPowerForPpdu(event);
995 NS_LOG_DEBUG("Sync to signal (power=" << (rxPower > Watt_u{0.0}
996 ? std::to_string(WToDbm(rxPower)) + "dBm)"
997 : std::to_string(rxPower) + "W)"));
998 m_wifiPhy->m_interference->NotifyRxStart(
999 m_wifiPhy->GetCurrentFrequencyRange()); // We need to notify it now so that it starts
1000 // recording events
1004 this,
1005 event));
1006}
1007
1008void
1010{
1011 NS_LOG_FUNCTION(this << *event);
1013 NS_ASSERT(m_wifiPhy->m_endPhyRxEvent.IsExpired()); // since end of preamble reception is
1014 // scheduled by this method upon success
1015
1016 // calculate PER on the measurement channel for PHY headers
1017 const auto measurementChannelWidth = GetMeasurementChannelWidth(event->GetPpdu());
1018 auto measurementBand = GetPrimaryBand(measurementChannelWidth);
1019 std::optional<Watt_u>
1020 maxRxPower; // in case current event may not be sent on measurement channel
1021 Ptr<Event> maxEvent;
1023 for (auto preambleEvent : m_wifiPhy->m_currentPreambleEvents)
1024 {
1025 const auto rxPower = preambleEvent.second->GetRxPower(measurementBand);
1026 if (!maxRxPower || (rxPower > *maxRxPower))
1027 {
1028 maxRxPower = rxPower;
1029 maxEvent = preambleEvent.second;
1030 }
1031 }
1032
1033 NS_ASSERT(maxEvent);
1034 if (maxEvent != event)
1035 {
1036 NS_LOG_DEBUG("Receiver got a stronger packet with UID "
1037 << maxEvent->GetPpdu()->GetUid()
1038 << " during preamble detection: drop packet with UID "
1039 << event->GetPpdu()->GetUid());
1041
1042 auto it = m_wifiPhy->m_currentPreambleEvents.find(
1043 {event->GetPpdu()->GetUid(), event->GetPpdu()->GetPreamble()});
1045 // This is needed to cleanup the m_firstPowerPerBand so that the first power corresponds to
1046 // the power at the start of the PPDU
1047 m_wifiPhy->m_interference->NotifyRxEnd(maxEvent->GetStartTime(),
1049 // Make sure InterferenceHelper keeps recording events
1051 return;
1052 }
1053
1054 m_wifiPhy->m_currentEvent = event;
1055
1056 const auto snr = m_wifiPhy->m_interference->CalculateSnr(m_wifiPhy->m_currentEvent,
1057 measurementChannelWidth,
1058 1,
1059 measurementBand);
1060 NS_LOG_DEBUG("SNR(dB)=" << RatioToDb(snr) << " at end of preamble detection period");
1061
1062 if (const auto power = m_wifiPhy->m_currentEvent->GetRxPower(measurementBand);
1063 (!m_wifiPhy->m_preambleDetectionModel && maxRxPower && (*maxRxPower > Watt_u{0.0})) ||
1064 (m_wifiPhy->m_preambleDetectionModel && power > Watt_u{0.0} &&
1065 m_wifiPhy->m_preambleDetectionModel->IsPreambleDetected(WToDbm(power),
1066 snr,
1067 measurementChannelWidth)))
1068 {
1069 // A bit convoluted but it enables to sync all PHYs
1070 for (auto& it : m_wifiPhy->m_phyEntities)
1071 {
1072 it.second->CancelRunningEndPreambleDetectionEvents();
1073 }
1074
1075 for (auto it = m_wifiPhy->m_currentPreambleEvents.begin();
1076 it != m_wifiPhy->m_currentPreambleEvents.end();)
1077 {
1078 if (it->second != m_wifiPhy->m_currentEvent)
1079 {
1080 NS_LOG_DEBUG("Drop packet with UID " << it->first.first << " and preamble "
1081 << it->first.second << " arrived at time "
1082 << it->second->GetStartTime());
1084 if (m_wifiPhy->m_currentEvent->GetPpdu()->GetUid() > it->first.first)
1085 {
1087 // This is needed to cleanup the m_firstPowerPerBand so that the first power
1088 // corresponds to the power at the start of the PPDU
1089 m_wifiPhy->m_interference->NotifyRxEnd(
1090 m_wifiPhy->m_currentEvent->GetStartTime(),
1092 }
1093 else
1094 {
1095 reason = BUSY_DECODING_PREAMBLE;
1096 }
1097 m_wifiPhy->NotifyRxPpduDrop(it->second->GetPpdu(), reason);
1098
1099 it = m_wifiPhy->m_currentPreambleEvents.erase(it);
1100 }
1101 else
1102 {
1103 ++it;
1104 }
1105 }
1106
1107 // Make sure InterferenceHelper keeps recording events
1109
1111 m_wifiPhy->m_currentEvent->GetRxPowerPerBand());
1113
1114 // Continue receiving preamble
1115 const auto durationTillEnd =
1116 GetDuration(WIFI_PPDU_FIELD_PREAMBLE, event->GetPpdu()->GetTxVector()) -
1118 m_wifiPhy->NotifyCcaBusy(event->GetPpdu(),
1119 durationTillEnd); // will be prolonged by next field
1122 this,
1124 event);
1125 }
1126 else
1127 {
1128 NS_LOG_DEBUG("Drop packet because PHY preamble detection failed");
1129 // Like CCA-SD, CCA-ED is governed by the 4 us CCA window to flag CCA-BUSY
1130 // for any received signal greater than the CCA-ED threshold.
1133 m_wifiPhy->m_currentEvent->GetEndTime());
1135 {
1136 // Do not erase events if there are still pending preamble events to be processed
1137 m_wifiPhy->m_interference->NotifyRxEnd(Simulator::Now(),
1139 }
1140 m_wifiPhy->m_currentEvent = nullptr;
1141 // Cancel preamble reception
1143 }
1144}
1145
1146bool
1148{
1149 WifiMode txMode = ppdu->GetTxVector().GetMode();
1150 if (!IsModeSupported(txMode))
1151 {
1152 NS_LOG_DEBUG("Drop packet because it was sent using an unsupported mode (" << txMode
1153 << ")");
1154 return false;
1155 }
1156 return true;
1157}
1158
1159void
1161{
1162 NS_LOG_FUNCTION(this);
1164 for (auto& endRxPayloadEvent : m_endRxPayloadEvents)
1165 {
1166 endRxPayloadEvent.Cancel();
1167 }
1168 m_endRxPayloadEvents.clear();
1169 for (auto& endMpduEvent : m_endOfMpduEvents)
1170 {
1171 endMpduEvent.Cancel();
1172 }
1173 m_endOfMpduEvents.clear();
1174 for (auto& [staId, endOfMacHdrEvents] : m_endOfMacHdrEvents)
1175 {
1176 for (auto& endMacHdrEvent : endOfMacHdrEvents)
1177 {
1178 endMacHdrEvent.Cancel();
1179 }
1180 }
1181 m_endOfMacHdrEvents.clear();
1182}
1183
1184bool
1189
1190void
1192{
1193 NS_LOG_FUNCTION(this);
1194 for (auto& endPreambleDetectionEvent : m_endPreambleDetectionEvents)
1195 {
1196 endPreambleDetectionEvent.Cancel();
1197 }
1199}
1200
1201void
1208
1209void
1211{
1212 NS_LOG_FUNCTION(this << reason);
1213 if (m_wifiPhy->m_currentEvent) // Otherwise abort has already been called just before
1214 {
1215 for (auto& endMpduEvent : m_endOfMpduEvents)
1216 {
1217 endMpduEvent.Cancel();
1218 }
1219 m_endOfMpduEvents.clear();
1220 for (auto& [staId, endOfMacHdrEvents] : m_endOfMacHdrEvents)
1221 {
1222 for (auto& endMacHdrEvent : endOfMacHdrEvents)
1223 {
1224 endMacHdrEvent.Cancel();
1225 }
1226 }
1227 m_endOfMacHdrEvents.clear();
1228 }
1229}
1230
1231void
1233{
1234 NS_LOG_FUNCTION(this << *event);
1235 DoResetReceive(event);
1238 NS_ASSERT(m_endRxPayloadEvents.size() == 1 && m_endRxPayloadEvents.front().IsExpired());
1239 m_endRxPayloadEvents.clear();
1240 m_wifiPhy->m_currentEvent = nullptr;
1242 m_wifiPhy->SwitchMaybeToCcaBusy(event->GetPpdu());
1243}
1244
1245void
1247{
1248 NS_LOG_FUNCTION(this << *event);
1249 NS_ASSERT(event->GetEndTime() == Simulator::Now());
1250}
1251
1252double
1254{
1255 return m_wifiPhy->m_random->GetValue();
1256}
1257
1258Watt_u
1260{
1261 return event->GetRxPower(GetPrimaryBand(GetMeasurementChannelWidth(event->GetPpdu())));
1262}
1263
1266{
1267 return m_wifiPhy->m_currentEvent;
1268}
1269
1272{
1273 if (static_cast<uint16_t>(m_wifiPhy->GetChannelWidth()) % 20 != 0)
1274 {
1275 return m_wifiPhy->GetBand(bandWidth);
1276 }
1277 return m_wifiPhy->GetBand(bandWidth,
1279}
1280
1283{
1285 return m_wifiPhy->GetBand(bandWidth,
1287}
1288
1289MHz_u
1291{
1292 return std::min(m_wifiPhy->GetChannelWidth(), txVector.GetChannelWidth());
1293}
1294
1295dBm_u
1297 WifiChannelListType /*channelType*/) const
1298{
1300}
1301
1302Time
1304{
1305 return m_wifiPhy->m_interference->GetEnergyDuration(DbmToW(threshold), band);
1306}
1307
1308void
1310{
1311 // We are here because we have received the first bit of a packet and we are
1312 // not going to be able to synchronize on it
1313 // In this model, CCA becomes busy when the aggregation of all signals as
1314 // tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
1315 const auto ccaIndication = GetCcaIndication(ppdu);
1316 if (ccaIndication.has_value())
1317 {
1318 NS_LOG_DEBUG("CCA busy for " << ccaIndication.value().second << " during "
1319 << ccaIndication.value().first.As(Time::S));
1320 m_state->SwitchMaybeToCcaBusy(ccaIndication.value().first,
1321 ccaIndication.value().second,
1322 {});
1323 return;
1324 }
1325 if (ppdu)
1326 {
1327 SwitchMaybeToCcaBusy(nullptr);
1328 }
1329}
1330
1333{
1334 const auto channelWidth = GetMeasurementChannelWidth(ppdu);
1335 NS_LOG_FUNCTION(this << channelWidth);
1336 const auto ccaThreshold = GetCcaThreshold(ppdu, WIFI_CHANLIST_PRIMARY);
1337 const Time delayUntilCcaEnd = GetDelayUntilCcaEnd(ccaThreshold, GetPrimaryBand(channelWidth));
1338 if (delayUntilCcaEnd.IsStrictlyPositive())
1339 {
1340 return std::make_pair(delayUntilCcaEnd, WIFI_CHANLIST_PRIMARY);
1341 }
1342 return std::nullopt;
1343}
1344
1345void
1347 Time duration,
1348 WifiChannelListType channelType)
1349{
1350 NS_LOG_FUNCTION(this << duration << channelType);
1351 NS_LOG_DEBUG("CCA busy for " << channelType << " during " << duration.As(Time::S));
1352 m_state->SwitchMaybeToCcaBusy(duration, channelType, {});
1353}
1354
1355uint64_t
1357{
1358 NS_LOG_FUNCTION(this);
1359 return m_globalPpduUid++;
1360}
1361
1362Time
1364{
1365 return Seconds(0);
1366}
1367
1368void
1369PhyEntity::NotifyPayloadBegin(const WifiTxVector& txVector, const Time& payloadDuration)
1370{
1371 m_wifiPhy->m_phyRxPayloadBeginTrace(txVector, payloadDuration);
1372}
1373
1374void
1376{
1377 NS_LOG_FUNCTION(this << ppdu);
1378 auto txPower = m_wifiPhy->GetTxPowerForTransmission(ppdu) + m_wifiPhy->GetTxGain();
1379 auto txVector = ppdu->GetTxVector();
1380 auto txPowerSpectrum = GetTxPowerSpectralDensity(DbmToW(txPower), ppdu);
1381 Transmit(ppdu->GetTxDuration(), ppdu, txPower, txPowerSpectrum, "transmission");
1382}
1383
1384void
1387 dBm_u txPower,
1388 Ptr<SpectrumValue> txPowerSpectrum,
1389 const std::string& type)
1390{
1391 NS_LOG_FUNCTION(this << txDuration << ppdu << txPower << type);
1392 NS_LOG_DEBUG("Start " << type << ": signal power before antenna gain=" << txPower << "dBm");
1393 auto txParams = Create<WifiSpectrumSignalParameters>();
1394 txParams->duration = txDuration;
1395 txParams->psd = txPowerSpectrum;
1396 txParams->ppdu = ppdu;
1397 NS_LOG_DEBUG("Starting " << type << " with power " << txPower << " dBm on channel "
1398 << +m_wifiPhy->GetChannelNumber() << " for "
1399 << txParams->duration.As(Time::MS));
1400 NS_LOG_DEBUG("Starting " << type << " with integrated spectrum power "
1401 << WToDbm(Integral(*txPowerSpectrum)) << " dBm; spectrum model Uid: "
1402 << txPowerSpectrum->GetSpectrumModel()->GetUid());
1403 auto spectrumWifiPhy = DynamicCast<SpectrumWifiPhy>(m_wifiPhy);
1404 NS_ASSERT(spectrumWifiPhy);
1405 spectrumWifiPhy->Transmit(txParams);
1406}
1407
1408MHz_u
1409PhyEntity::GetGuardBandwidth(MHz_u currentChannelWidth) const
1410{
1411 return m_wifiPhy->GetGuardBandwidth(currentChannelWidth);
1412}
1413
1414std::tuple<dBr_u, dBr_u, dBr_u>
1419
1420Time
1422 const WifiTxVector& txVector,
1423 WifiPhyBand band) const
1424{
1425 NS_ASSERT(psduMap.size() == 1);
1426 const auto& it = psduMap.begin();
1427 return WifiPhy::CalculateTxDuration(it->second->GetSize(), txVector, band, it->first);
1428}
1429
1430bool
1432{
1433 // The PHY shall not issue a PHY-RXSTART.indication primitive in response to a PPDU that does
1434 // not overlap the primary channel
1435 const auto channelWidth = m_wifiPhy->GetChannelWidth();
1436 const auto primaryWidth = ((static_cast<uint16_t>(channelWidth) % 20 == 0)
1437 ? MHz_u{20}
1438 : channelWidth); // if the channel width is a multiple of 20 MHz,
1439 // then we consider the primary20 channel
1440 const auto p20CenterFreq =
1442 const auto p20MinFreq = p20CenterFreq - (primaryWidth / 2);
1443 const auto p20MaxFreq = p20CenterFreq + (primaryWidth / 2);
1444 const auto txChannelWidth = (ppdu->GetTxChannelWidth() / ppdu->GetTxCenterFreqs().size());
1445 for (auto txCenterFreq : ppdu->GetTxCenterFreqs())
1446 {
1447 const auto minTxFreq = txCenterFreq - txChannelWidth / 2;
1448 const auto maxTxFreq = txCenterFreq + txChannelWidth / 2;
1449 if ((p20MinFreq >= minTxFreq) && (p20MaxFreq <= maxTxFreq))
1450 {
1451 return true;
1452 }
1453 }
1454 return false;
1455}
1456
1459{
1460 return ppdu;
1461}
1462
1463} // namespace ns3
Class for representing data rates.
Definition data-rate.h:78
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition data-rate.cc:220
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition event-id.cc:58
void NotifyPayloadBegin(const WifiTxVector &txVector, const Time &payloadDuration)
Fire the trace indicating that the PHY is starting to receive the payload of a PPDU.
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.
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...
std::list< WifiMode >::const_iterator end() const
Return a const iterator to past-the-last WifiMode.
void EndOfMpdu(Ptr< Event > event, Ptr< WifiMpdu > mpdu, size_t mpduIndex, Time relativeStart, Time mpduDuration)
The last symbol of an MPDU in an A-MPDU has arrived.
MHz_u GetGuardBandwidth(MHz_u currentChannelWidth) const
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.
virtual PhyFieldRxStatus DoEndReceivePreamble(Ptr< Event > event)
End receiving the preamble, perform amendment-specific actions, and provide the status of the recepti...
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper of the WifiPhy (to make it reachable for child classes)
Definition phy-entity.h:949
virtual void RxPayloadFailed(Ptr< const WifiPsdu > psdu, double snr, const WifiTxVector &txVector)
Perform amendment-specific actions when the payload is unsuccessfuly received.
void EndPreambleDetectionPeriod(Ptr< Event > event)
End the preamble detection period.
virtual void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration, WifiChannelListType channelType)
Notify PHY state helper to switch to CCA busy state,.
virtual Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration)
Build amendment-specific PPDU.
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...
virtual uint64_t ObtainNextUid(const WifiTxVector &txVector)
Obtain the next UID for the PPDU to transmit.
virtual Time DoStartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
virtual void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
bool NoEndPreambleDetectionEvents() const
virtual bool HandlesMcsModes() const
Check if the WifiModes handled by this PHY are MCSs.
void Transmit(Time txDuration, Ptr< const WifiPpdu > ppdu, dBm_u txPower, Ptr< SpectrumValue > txPowerSpectrum, const std::string &type)
This function prepares most of the WifiSpectrumSignalParameters parameters and invokes SpectrumWifiPh...
const std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > & GetCurrentPreambleEvents() const
Get the map of current preamble events (stored in WifiPhy).
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:971
Watt_u GetRxPowerForPpdu(Ptr< Event > event) const
Obtain the received power for a given band.
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition phy-entity.h:948
std::pair< bool, SignalNoiseDbm > GetReceptionStatus(Ptr< WifiMpdu > mpdu, Ptr< Event > event, uint16_t staId, Time relativeMpduStart, Time mpduDuration)
Get the reception status for the provided MPDU and notify.
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:933
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
Definition phy-entity.h:955
virtual MHz_u GetRxChannelWidth(const WifiTxVector &txVector) const
Return the channel width used in the reception spectrum model.
virtual ~PhyEntity()
Destructor for PHY entity.
Definition phy-entity.cc:74
virtual const PpduFormats & GetPpduFormats() const =0
Return the PPDU formats of the PHY.
virtual uint8_t GetNumModes() const
virtual bool DoStartReceiveField(WifiPpduField field, Ptr< Event > event)
Start receiving a given field, perform amendment-specific actions, and signify if it is supported.
void SetOwner(Ptr< WifiPhy > wifiPhy)
Set the WifiPhy owning this PHY entity.
Definition phy-entity.cc:82
std::list< WifiMode >::const_iterator begin() const
Return a const iterator to the first WifiMode.
virtual void CancelAllEvents()
Cancel and clear all running events.
virtual Time CalculateTxDuration(const WifiConstPsduMap &psduMap, const WifiTxVector &txVector, WifiPhyBand band) const
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Abort the current reception.
void EndReceivePayload(Ptr< Event > event)
The last symbol of the PPDU has arrived.
virtual std::pair< MHz_u, WifiSpectrumBandInfo > GetChannelWidthAndBand(const WifiTxVector &txVector, uint16_t staId) const
Get the channel width and band to use (will be overloaded by child classes).
static uint64_t m_globalPpduUid
Global counter of the PPDU UID.
Definition phy-entity.h:974
PhyHeaderSections GetPhyHeaderSections(const WifiTxVector &txVector, Time ppduStart) const
Return a map of PHY header chunk information per PPDU field.
virtual Ptr< SpectrumValue > GetTxPowerSpectralDensity(Watt_u txPower, Ptr< const WifiPpdu > ppdu) const =0
virtual bool IsMcsSupported(uint8_t index) const
Check if the WifiMode corresponding to the given MCS index is supported.
void StartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
Definition phy-entity.h:960
virtual void DoResetReceive(Ptr< Event > event)
Perform amendment-specific actions before resetting PHY at the end of the PPDU under reception after ...
void EndReceiveField(WifiPpduField field, Ptr< Event > event)
End receiving a given field.
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW)
Get the event corresponding to the incoming PPDU.
virtual WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const
Get the WifiMode for the SIG field specified by the PPDU field.
WifiSpectrumBandInfo GetPrimaryBand(MHz_u bandWidth) const
If the operating channel width is a multiple of 20 MHz, return the info corresponding to the primary ...
WifiPpduField GetNextField(WifiPpduField currentField, WifiPreamble preamble) const
Return the field following the provided one.
void CancelRunningEndPreambleDetectionEvents()
Cancel all end preamble detection events.
Time GetDelayUntilCcaEnd(dBm_u threshold, const WifiSpectrumBandInfo &band)
Return the delay until CCA busy is ended for a given sensitivity threshold and a given band.
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition phy-entity.h:294
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.
Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector) const
void NotifyInterferenceRxEndAndClear(bool reset)
Notify WifiPhy's InterferenceHelper of the end of the reception, clear maps and end of MPDU event,...
void StartPreambleDetectionPeriod(Ptr< Event > event)
Start the preamble detection period.
Time GetDurationUpToField(WifiPpduField field, const WifiTxVector &txVector) const
Get the duration of the PPDU up to (but excluding) the given field.
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:968
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.
virtual void StartTx(Ptr< const WifiPpdu > ppdu)
This function is called by SpectrumWifiPhy to send the PPDU while performing amendment-specific actio...
virtual dBm_u GetCcaThreshold(const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType) const
Return the CCA threshold for a given channel type.
Time GetRemainingDurationAfterField(Ptr< const WifiPpdu > ppdu, WifiPpduField field) const
Get the remaining duration of the PPDU after the end of the given field.
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.
void StartReceiveField(WifiPpduField field, Ptr< Event > event)
Start receiving a given field.
virtual bool IsModeSupported(WifiMode mode) const
Check if the WifiMode is supported.
Definition phy-entity.cc:90
void ResetReceive(Ptr< Event > event)
Reset PHY at the end of the PPDU under reception after it has failed the PHY header.
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...
std::list< WifiMode > m_modeList
the list of supported modes
Definition phy-entity.h:952
virtual Time GetMaxDelayPpduSameUid(const WifiTxVector &txVector)
Obtain the maximum time between two PPDUs with the same UID to consider they are identical and their ...
Ptr< const Event > GetCurrentEvent() const
Get the pointer to the current event (stored in WifiPhy).
double GetRandomValue() const
Obtain a random value from the WifiPhy's generator.
std::vector< EventId > m_endPreambleDetectionEvents
the end of preamble detection events
Definition phy-entity.h:954
virtual std::optional< Time > GetTimeToMacHdrEnd(uint16_t staId) const
Get the remaining time to the end of the MAC header reception of the next MPDU being received from th...
virtual Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
SnrPer GetPhyHeaderSnrPer(WifiPpduField field, Ptr< Event > event) const
Obtain the SNR and PER of the PPDU field from the WifiPhy's InterferenceHelper class.
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 ...
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.
virtual WifiMode GetMcs(uint8_t index) const
Get the WifiMode corresponding to the given MCS index.
void AddPreambleEvent(Ptr< Event > event)
Add an entry to the map of current preamble events (stored in WifiPhy).
virtual void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu)
Perform amendment-specific actions at the end of the reception of the payload.
std::tuple< dBr_u, dBr_u, dBr_u > GetTxMaskRejectionParams() const
virtual MHz_u GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const =0
Return the channel width used to measure the RSSI.
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.
virtual bool IsConfigSupported(Ptr< const WifiPpdu > ppdu) const
Checks if the signaled configuration (excluding bandwidth) is supported by the PHY.
Ptr< Event > CreateInterferenceEvent(Ptr< const WifiPpdu > ppdu, Time duration, RxPowerWattPerChannelBand &rxPower, bool isStartHePortionRxing=false)
Create an event using WifiPhy's InterferenceHelper class.
PhyRxFailureAction
Action to perform in case of RX failure.
Definition phy-entity.h:70
@ DROP
drop PPDU and set CCA_BUSY
Definition phy-entity.h:71
@ IGNORE
ignore the reception
Definition phy-entity.h:73
@ ABORT
abort reception of PPDU
Definition phy-entity.h:72
WifiSpectrumBandInfo GetSecondaryBand(MHz_u bandWidth) const
If the channel bonding is used, return the info corresponding to the secondary channel of the given b...
virtual PhyFieldRxStatus DoEndReceiveField(WifiPpduField field, Ptr< Event > event)
End receiving a given field, perform amendment-specific actions, and provide the status of the recept...
std::map< uint16_t, std::vector< EventId > > m_endOfMacHdrEvents
STA_ID-indexed map of the RX end of MAC header events.
Definition phy-entity.h:957
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition simulator.cc:206
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition nstime.h:340
@ MS
millisecond
Definition nstime.h:106
@ S
second
Definition nstime.h:105
@ NS
nanosecond
Definition nstime.h:108
bool IsZero() const
Exactly equivalent to t == 0.
Definition nstime.h:304
represent a single transmission mode
Definition wifi-mode.h:40
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:111
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition wifi-phy.h:1349
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition wifi-phy.h:1348
dB_u GetTxGain() const
Return the transmission gain.
Definition wifi-phy.cc:609
void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration)
Notify PHY state helper to switch to CCA busy state,.
Definition wifi-phy.cc:2240
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:1540
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:1361
EventId m_endPhyRxEvent
the end of PHY receive event
Definition wifi-phy.h:1356
bool IsStateRx() const
Definition wifi-phy.cc:2185
bool m_notifyRxMacHeaderEnd
whether the PHY is capable of notifying MAC header RX end
Definition wifi-phy.h:1655
MHz_u GetFrequency() const
Definition wifi-phy.cc:1087
static Time GetPreambleDetectionDuration()
Definition wifi-phy.cc:1528
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition wifi-phy.cc:2247
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition wifi-phy.h:1650
void NotifyRxBegin(Ptr< const WifiPsdu > psdu, const RxPowerWattPerChannelBand &rxPowersW)
Public method used to fire a PhyRxBegin trace.
Definition wifi-phy.cc:1664
void NotifyMonitorSniffRx(Ptr< const WifiPsdu > psdu, MHz_u channelFreq, const WifiTxVector &txVector, SignalNoiseDbm signalNoise, const 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:1707
bool IsStateOff() const
Definition wifi-phy.cc:2209
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition wifi-phy.cc:1587
dBm_u GetCcaEdThreshold() const
Return the CCA energy detection threshold.
Definition wifi-phy.cc:533
virtual MHz_u GetGuardBandwidth(MHz_u currentChannelWidth) const =0
virtual std::tuple< dBr_u, dBr_u, dBr_u > GetTxMaskRejectionParams() const =0
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition wifi-phy.h:1384
void NotifyRxPpduDrop(Ptr< const WifiPpdu > ppdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxPpduDrop trace.
Definition wifi-phy.cc:1700
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition wifi-phy.h:1653
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition wifi-phy.cc:1069
Ptr< Event > m_currentEvent
Hold the current event.
Definition wifi-phy.h:1359
uint8_t GetChannelNumber() const
Return current channel number.
Definition wifi-phy.cc:1093
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition wifi-phy.h:1364
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition wifi-phy.h:1651
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition wifi-phy.cc:1676
MHz_u GetChannelWidth() const
Definition wifi-phy.cc:1099
bool IsStateSleep() const
Definition wifi-phy.cc:2203
virtual FrequencyRange GetCurrentFrequencyRange() const =0
Get the frequency range of the current RF interface.
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:2233
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition wifi-phy.h:1346
dBm_u GetTxPowerForTransmission(Ptr< const WifiPpdu > ppdu) const
Compute the transmit power for the next transmission.
Definition wifi-phy.cc:2320
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition wifi-phy.cc:781
void Reset()
Reset data upon end of TX or RX.
Definition wifi-phy.cc:1967
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition wifi-phy.h:1526
Time GetLastRxEndTime() const
Return the end time of the last received packet.
Definition wifi-phy.cc:2227
TracedCallback< const WifiMacHeader &, const WifiTxVector &, Time > m_phyRxMacHeaderEndTrace
The trace source fired when the reception of a MAC header ends.
Definition wifi-phy.h:1537
Time m_timeLastPreambleDetected
Record the time the last preamble was detected.
Definition wifi-phy.h:1654
virtual WifiSpectrumBandInfo GetBand(MHz_u bandWidth, uint8_t bandIndex=0)=0
Get the info of a given band.
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition wifi-phy.cc:1081
dBm_u GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold.
Definition wifi-phy.cc:546
uint8_t GetSecondaryChannelIndex(MHz_u secondaryChannelWidth) const
If the operating channel width is made of a multiple of 20 MHz, return the index of the secondary cha...
uint8_t GetPrimaryChannelIndex(MHz_u primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
MHz_u GetPrimaryChannelCenterFrequency(MHz_u 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
MHz_u 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:55
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1380
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
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.
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.
Definition wifi-types.h:41
@ PREAMBLE_DETECT_FAILURE
@ FRAME_CAPTURE_PACKET_SWITCH
@ 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.
Definition wifi-types.h:53
@ NORMAL_MPDU
The MPDU is not part of an A-MPDU.
Definition wifi-types.h:43
@ FIRST_MPDU_IN_AGGREGATE
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate.
Definition wifi-types.h:48
@ SINGLE_MPDU
The MPDU is a single MPDU.
Definition wifi-types.h:45
@ MIDDLE_MPDU_IN_AGGREGATE
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate.
Definition wifi-types.h:51
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ 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.
dB_u RatioToDb(double ratio)
Convert from ratio to dB.
Definition wifi-utils.cc:46
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
double Integral(const SpectrumValue &arg)
dBm_u WToDbm(Watt_u val)
Convert from Watts to dBm.
Definition wifi-utils.cc:39
double MHz_u
MHz weak type.
Definition wifi-units.h:31
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
Definition phy-entity.h:45
double dBm_u
dBm weak type
Definition wifi-units.h:27
double DbToRatio(dB_u val)
Convert from dB to ratio.
Definition wifi-utils.cc:27
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:33
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition wifi-mode.h:24
double Watt_u
Watt weak type.
Definition wifi-units.h:25
Declaration of:
Status of the reception of the PPDU field.
Definition phy-entity.h:80
WifiPhyRxfailureReason reason
failure reason
Definition phy-entity.h:82
PhyRxFailureAction actionIfFailure
action to perform in case of failure
Definition phy-entity.h:83
bool isSuccess
outcome (true if success) of the reception
Definition phy-entity.h:81
A struct for both SNR and PER.
Definition phy-entity.h:115
double snr
SNR in linear scale.
Definition phy-entity.h:116
RxSignalInfo structure containing info on the received signal.
Definition wifi-types.h:72
double snr
SNR in linear scale.
Definition wifi-types.h:73
dBm_u rssi
RSSI.
Definition wifi-types.h:74
SignalNoiseDbm structure.
Definition wifi-types.h:58
dBm_u noise
noise power
Definition wifi-types.h:60
dBm_u signal
signal strength
Definition wifi-types.h:59
WifiSpectrumBandInfo structure containing info about a spectrum band.