A Discrete-Event Network Simulator
API
phy-entity.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Orange Labs
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Rediet <getachew.redieteab@orange.com>
18  * Sébastien Deronne <sebastien.deronne@gmail.com> (for logic ported from wifi-phy and
19  * spectrum-wifi-phy) Mathieu Lacage <mathieu.lacage@sophia.inria.fr> (for logic ported from
20  * wifi-phy)
21  */
22 
23 #include "phy-entity.h"
24 
25 #include "frame-capture-model.h"
26 #include "interference-helper.h"
28 #include "spectrum-wifi-phy.h"
29 #include "wifi-psdu.h"
31 #include "wifi-utils.h"
32 
33 #include "ns3/assert.h"
34 #include "ns3/log.h"
35 #include "ns3/packet.h"
36 #include "ns3/simulator.h"
37 
38 #include <algorithm>
39 
40 namespace ns3
41 {
42 
43 NS_LOG_COMPONENT_DEFINE("PhyEntity");
44 
45 std::ostream&
46 operator<<(std::ostream& os, const PhyEntity::PhyRxFailureAction& action)
47 {
48  switch (action)
49  {
50  case PhyEntity::DROP:
51  return (os << "DROP");
52  case PhyEntity::ABORT:
53  return (os << "ABORT");
54  case PhyEntity::IGNORE:
55  return (os << "IGNORE");
56  default:
57  NS_FATAL_ERROR("Unknown action");
58  return (os << "unknown");
59  }
60 }
61 
62 std::ostream&
63 operator<<(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 
79 uint64_t PhyEntity::m_globalPpduUid = 0;
80 
82 {
83  NS_LOG_FUNCTION(this);
84  m_modeList.clear();
86 }
87 
88 void
90 {
91  NS_LOG_FUNCTION(this << wifiPhy);
92  m_wifiPhy = wifiPhy;
94 }
95 
96 bool
98 {
99  for (const auto& m : m_modeList)
100  {
101  if (m == mode)
102  {
103  return true;
104  }
105  }
106  return false;
107 }
108 
109 uint8_t
111 {
112  return m_modeList.size();
113 }
114 
115 WifiMode
116 PhyEntity::GetMcs(uint8_t /* index */) const
117 {
118  NS_ABORT_MSG(
119  "This method should be used only for HtPhy and child classes. Use GetMode instead.");
120  return WifiMode();
121 }
122 
123 bool
124 PhyEntity::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 
131 bool
133 {
134  return false;
135 }
136 
137 std::list<WifiMode>::const_iterator
139 {
140  return m_modeList.begin();
141 }
142 
143 std::list<WifiMode>::const_iterator
145 {
146  return m_modeList.end();
147 }
148 
149 WifiMode
150 PhyEntity::GetSigMode(WifiPpduField field, const WifiTxVector& txVector) const
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 
189 Time
190 PhyEntity::GetDuration(WifiPpduField field, const WifiTxVector& txVector) const
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 
199 Time
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({{SU_STA_ID, psdu}});
214 }
215 
218 {
219  return ppdu->GetPsdu();
220 }
221 
223 PhyEntity::GetPhyHeaderSections(const WifiTxVector& txVector, Time ppduStart) const
224 {
225  PhyHeaderSections map;
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] = {{start, start + duration}, GetSigMode(field, txVector)};
233  // Move to next field
234  start += duration;
235  field = GetNextField(field, txVector.GetPreambleType());
236  }
237  return map;
238 }
239 
241 PhyEntity::BuildPpdu(const WifiConstPsduMap& psdus, const WifiTxVector& txVector, Time ppduDuration)
242 {
243  NS_LOG_FUNCTION(this << psdus << txVector << ppduDuration);
244  NS_FATAL_ERROR("This method is unsupported for the base PhyEntity class. Use the overloaded "
245  "version in the amendment-specific subclasses instead!");
246  return Create<WifiPpdu>(psdus.begin()->second,
247  txVector,
248  m_wifiPhy->GetOperatingChannel()); // should be overloaded
249 }
250 
251 Time
253 {
254  if (field ==
255  WIFI_PPDU_FIELD_DATA) // this field is not in the map returned by GetPhyHeaderSections
256  {
257  return CalculatePhyPreambleAndHeaderDuration(txVector);
258  }
259  const auto& sections = GetPhyHeaderSections(txVector, NanoSeconds(0));
260  auto it = sections.find(field);
261  NS_ASSERT(it != sections.end());
262  const auto& startStopTimes = it->second.first;
263  return startStopTimes
264  .first; // return the start time of field relatively to the beginning of the PPDU
265 }
266 
269 {
270  uint16_t measurementChannelWidth = GetMeasurementChannelWidth(event->GetPpdu());
271  return m_wifiPhy->m_interference->CalculatePhyHeaderSnrPer(
272  event,
273  measurementChannelWidth,
274  GetPrimaryBand(measurementChannelWidth),
275  field);
276 }
277 
278 void
280 {
281  NS_LOG_FUNCTION(this << field << *event);
282  NS_ASSERT(m_wifiPhy); // no sense if no owner WifiPhy instance
285  "Use the StartReceivePreamble method for preamble reception");
286  // Handle special cases of data reception
287  if (field == WIFI_PPDU_FIELD_DATA)
288  {
289  StartReceivePayload(event);
290  return;
291  }
292 
293  bool supported = DoStartReceiveField(field, event);
294  NS_ABORT_MSG_IF(!supported,
295  "Unknown field "
296  << field << " for this PHY entity"); // TODO see what to do if not supported
297  Time duration = GetDuration(field, event->GetPpdu()->GetTxVector());
299  Simulator::Schedule(duration, &PhyEntity::EndReceiveField, this, field, event);
301  event->GetPpdu(),
302  duration); // keep in CCA busy state up to reception of Data (will then switch to RX)
303 }
304 
305 void
307 {
308  NS_LOG_FUNCTION(this << field << *event);
309  NS_ASSERT(m_wifiPhy); // no sense if no owner WifiPhy instance
311  PhyFieldRxStatus status = DoEndReceiveField(field, event);
312  const auto& txVector = event->GetPpdu()->GetTxVector();
313  if (status.isSuccess) // move to next field if reception succeeded
314  {
315  StartReceiveField(GetNextField(field, txVector.GetPreambleType()), event);
316  }
317  else
318  {
319  Ptr<const WifiPpdu> ppdu = event->GetPpdu();
320  switch (status.actionIfFailure)
321  {
322  case ABORT:
323  // Abort reception, but consider medium as busy
325  if (event->GetEndTime() > (Simulator::Now() + m_state->GetDelayUntilIdle()))
326  {
328  }
329  break;
330  case DROP:
331  // Notify drop, keep in CCA busy, and perform same processing as IGNORE case
332  if (status.reason == FILTERED)
333  {
334  // PHY-RXSTART is immediately followed by PHY-RXEND (Filtered)
336  txVector,
337  NanoSeconds(0)); // this callback (equivalent to PHY-RXSTART primitive) is also
338  // triggered for filtered PPDUs
339  }
342  // no break
343  case IGNORE:
344  // Keep in Rx state and reset at end
345  m_endRxPayloadEvents.push_back(
348  this,
349  event));
350  break;
351  default:
352  NS_FATAL_ERROR("Unknown action in case of failure");
353  }
354  }
355 }
356 
357 Time
359 {
360  const auto& txVector = ppdu->GetTxVector();
361  return ppdu->GetTxDuration() -
362  (GetDurationUpToField(field, txVector) + GetDuration(field, txVector));
363 }
364 
365 bool
367 {
368  NS_LOG_FUNCTION(this << field << *event);
370  field != WIFI_PPDU_FIELD_DATA); // handled apart for the time being
371  auto ppduFormats = GetPpduFormats();
372  auto itFormat = ppduFormats.find(event->GetPpdu()->GetPreamble());
373  if (itFormat != ppduFormats.end())
374  {
375  auto itField = std::find(itFormat->second.begin(), itFormat->second.end(), field);
376  if (itField != itFormat->second.end())
377  {
378  return true; // supported field so we can start receiving
379  }
380  }
381  return false; // unsupported otherwise
382 }
383 
386 {
387  NS_LOG_FUNCTION(this << field << *event);
388  NS_ASSERT(field != WIFI_PPDU_FIELD_DATA); // handled apart for the time being
389  if (field == WIFI_PPDU_FIELD_PREAMBLE)
390  {
391  return DoEndReceivePreamble(event);
392  }
393  return PhyFieldRxStatus(false); // failed reception by default
394 }
395 
396 void
398  RxPowerWattPerChannelBand& rxPowersW,
399  Time rxDuration)
400 {
401  // The total RX power corresponds to the maximum over all the bands
402  auto it =
403  std::max_element(rxPowersW.begin(), rxPowersW.end(), [](const auto& p1, const auto& p2) {
404  return p1.second < p2.second;
405  });
406  NS_LOG_FUNCTION(this << ppdu << it->second);
407 
408  auto event = DoGetEvent(ppdu, rxPowersW);
409  if (!event)
410  {
411  // PPDU should be simply considered as interference (once it has been accounted for in
412  // InterferenceHelper)
413  return;
414  }
415 
416  Time endRx = Simulator::Now() + rxDuration;
417  if (ppdu->IsTruncatedTx())
418  {
419  NS_LOG_DEBUG("Packet reception stopped because transmitter has been switched off");
420  if (endRx > (Simulator::Now() + m_state->GetDelayUntilIdle()))
421  {
423  }
425  return;
426  }
427 
428  switch (m_state->GetState())
429  {
431  NS_LOG_DEBUG("Drop packet because of channel switching");
432  /*
433  * Packets received on the upcoming channel are added to the event list
434  * during the switching state. This way the medium can be correctly sensed
435  * when the device listens to the channel for the first time after the
436  * switching e.g. after channel switching, the channel may be sensed as
437  * busy due to other devices' transmissions started before the end of
438  * the switching.
439  */
440  DropPreambleEvent(ppdu, CHANNEL_SWITCHING, endRx);
441  break;
442  case WifiPhyState::RX:
444  m_wifiPhy->m_frameCaptureModel->IsInCaptureWindow(
446  m_wifiPhy->m_frameCaptureModel->CaptureNewFrame(m_wifiPhy->m_currentEvent, event))
447  {
449  NS_LOG_DEBUG("Switch to new packet");
451  }
452  else
453  {
454  NS_LOG_DEBUG("Drop packet because already in Rx");
455  DropPreambleEvent(ppdu, RXING, endRx);
457  {
458  /*
459  * We are here because the non-legacy PHY header has not been successfully received.
460  * The PHY is kept in RX state for the duration of the PPDU, but EndReceive function
461  * is not called when the reception of the PPDU is finished, which is responsible to
462  * clear m_currentPreambleEvents. As a result, m_currentPreambleEvents should be
463  * cleared here.
464  */
466  }
467  }
468  break;
469  case WifiPhyState::TX:
470  NS_LOG_DEBUG("Drop packet because already in Tx");
471  DropPreambleEvent(ppdu, TXING, endRx);
472  break;
475  {
477  m_wifiPhy->m_frameCaptureModel->IsInCaptureWindow(
479  m_wifiPhy->m_frameCaptureModel->CaptureNewFrame(m_wifiPhy->m_currentEvent, event))
480  {
482  NS_LOG_DEBUG("Switch to new packet");
484  }
485  else
486  {
487  NS_LOG_DEBUG("Drop packet because already decoding preamble");
489  }
490  }
491  else
492  {
494  }
495  break;
496  case WifiPhyState::IDLE:
499  break;
500  case WifiPhyState::SLEEP:
501  NS_LOG_DEBUG("Drop packet because in sleep mode");
502  DropPreambleEvent(ppdu, SLEEPING, endRx);
503  break;
504  case WifiPhyState::OFF:
505  NS_LOG_DEBUG("Drop packet because in switched off");
507  break;
508  default:
509  NS_FATAL_ERROR("Invalid WifiPhy state.");
510  break;
511  }
512 }
513 
514 void
516 {
517  NS_LOG_FUNCTION(this << ppdu << reason << endRx);
519  auto it = m_wifiPhy->m_currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
520  if (it != m_wifiPhy->m_currentPreambleEvents.end())
521  {
523  }
524  if (!m_wifiPhy->IsStateSleep() && !m_wifiPhy->IsStateOff() &&
525  (endRx > (Simulator::Now() + m_state->GetDelayUntilIdle())))
526  {
527  // that PPDU will be noise _after_ the end of the current event.
529  }
530 }
531 
532 void
534 {
535  NS_LOG_FUNCTION(this << ppdu << rxDuration);
536  auto it = m_wifiPhy->m_currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
537  if (it != m_wifiPhy->m_currentPreambleEvents.end())
538  {
540  }
541  if (m_wifiPhy->m_currentPreambleEvents.empty())
542  {
543  m_wifiPhy->Reset();
544  }
545 
546  if (rxDuration > m_state->GetDelayUntilIdle())
547  {
548  // this PPDU will be noise _after_ the completion of the current event
550  }
551 }
552 
553 uint16_t
555 {
556  return SU_STA_ID;
557 }
558 
559 void
561 {
562  NS_LOG_FUNCTION(this << *event);
564 
565  Time payloadDuration = DoStartReceivePayload(event);
566  m_state->SwitchToRx(payloadDuration);
567 }
568 
569 Time
571 {
572  NS_LOG_FUNCTION(this << *event);
573  Ptr<const WifiPpdu> ppdu = event->GetPpdu();
574  NS_LOG_DEBUG("Receiving PSDU");
575  uint16_t staId = GetStaId(ppdu);
576  m_signalNoiseMap.insert({{ppdu->GetUid(), staId}, SignalNoiseDbm()});
577  m_statusPerMpduMap.insert({{ppdu->GetUid(), staId}, std::vector<bool>()});
578  ScheduleEndOfMpdus(event);
579  const auto& txVector = event->GetPpdu()->GetTxVector();
580  Time payloadDuration = ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector);
582  txVector,
583  payloadDuration); // this callback (equivalent to PHY-RXSTART primitive) is triggered only
584  // if headers have been correctly decoded and that the mode within is
585  // supported
586  m_endRxPayloadEvents.push_back(
587  Simulator::Schedule(payloadDuration, &PhyEntity::EndReceivePayload, this, event));
588  return payloadDuration;
589 }
590 
591 void
593 {
594  NS_LOG_FUNCTION(this << *event);
595  Ptr<const WifiPpdu> ppdu = event->GetPpdu();
597  const auto& txVector = event->GetPpdu()->GetTxVector();
598  uint16_t staId = GetStaId(ppdu);
599  Time endOfMpduDuration = NanoSeconds(0);
600  Time relativeStart = NanoSeconds(0);
601  Time psduDuration = ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector);
602  Time remainingAmpduDuration = psduDuration;
603  size_t nMpdus = psdu->GetNMpdus();
604  MpduType mpduType =
605  (nMpdus > 1) ? FIRST_MPDU_IN_AGGREGATE : (psdu->IsSingle() ? SINGLE_MPDU : NORMAL_MPDU);
606  uint32_t totalAmpduSize = 0;
607  double totalAmpduNumSymbols = 0.0;
608  auto mpdu = psdu->begin();
609  for (size_t i = 0; i < nMpdus && mpdu != psdu->end(); ++mpdu)
610  {
611  uint32_t size = (mpduType == NORMAL_MPDU) ? psdu->GetSize() : psdu->GetAmpduSubframeSize(i);
612  Time mpduDuration = m_wifiPhy->GetPayloadDuration(size,
613  txVector,
615  mpduType,
616  true,
617  totalAmpduSize,
618  totalAmpduNumSymbols,
619  staId);
620 
621  remainingAmpduDuration -= mpduDuration;
622  if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero()) // no more MPDUs coming
623  {
624  if (remainingAmpduDuration <
625  NanoSeconds(txVector.GetGuardInterval())) // enables to ignore padding
626  {
627  mpduDuration += remainingAmpduDuration; // apply a correction just in case rounding
628  // had induced slight shift
629  }
630  }
631 
632  endOfMpduDuration += mpduDuration;
633  NS_LOG_INFO("Schedule end of MPDU #"
634  << i << " in " << endOfMpduDuration.As(Time::NS) << " (relativeStart="
635  << relativeStart.As(Time::NS) << ", mpduDuration=" << mpduDuration.As(Time::NS)
636  << ", remainingAmdpuDuration=" << remainingAmpduDuration.As(Time::NS) << ")");
637  m_endOfMpduEvents.push_back(Simulator::Schedule(endOfMpduDuration,
639  this,
640  event,
641  Create<WifiPsdu>(*mpdu, false),
642  i,
643  relativeStart,
644  mpduDuration));
645 
646  // Prepare next iteration
647  ++i;
648  relativeStart += mpduDuration;
649  mpduType = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
650  }
651 }
652 
653 void
655  Ptr<const WifiPsdu> psdu,
656  size_t mpduIndex,
657  Time relativeStart,
658  Time mpduDuration)
659 {
660  NS_LOG_FUNCTION(this << *event << mpduIndex << relativeStart << mpduDuration);
661  const auto ppdu = event->GetPpdu();
662  const auto& txVector = ppdu->GetTxVector();
663  uint16_t staId = GetStaId(ppdu);
664 
665  std::pair<bool, SignalNoiseDbm> rxInfo =
666  GetReceptionStatus(psdu, event, staId, relativeStart, mpduDuration);
667  NS_LOG_DEBUG("Extracted MPDU #" << mpduIndex << ": duration: " << mpduDuration.As(Time::NS)
668  << ", correct reception: " << rxInfo.first << ", Signal/Noise: "
669  << rxInfo.second.signal << "/" << rxInfo.second.noise << "dBm");
670 
671  auto signalNoiseIt = m_signalNoiseMap.find({ppdu->GetUid(), staId});
672  NS_ASSERT(signalNoiseIt != m_signalNoiseMap.end());
673  signalNoiseIt->second = rxInfo.second;
674 
675  RxSignalInfo rxSignalInfo;
676  rxSignalInfo.snr = rxInfo.second.signal / rxInfo.second.noise;
677  rxSignalInfo.rssi = rxInfo.second.signal;
678 
679  auto statusPerMpduIt = m_statusPerMpduMap.find({ppdu->GetUid(), staId});
680  NS_ASSERT(statusPerMpduIt != m_statusPerMpduMap.end());
681  statusPerMpduIt->second.push_back(rxInfo.first);
682 
683  if (rxInfo.first && GetAddressedPsduInPpdu(ppdu)->GetNMpdus() > 1)
684  {
685  // only done for correct MPDU that is part of an A-MPDU
686  m_state->NotifyRxMpdu(psdu, rxSignalInfo, txVector);
687  }
688 }
689 
690 void
692 {
693  const auto ppdu = event->GetPpdu();
694  const auto& txVector = ppdu->GetTxVector();
696  this << *event << ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(txVector));
697  NS_ASSERT(event->GetEndTime() == Simulator::Now());
698  const auto staId = GetStaId(ppdu);
699  const auto channelWidthAndBand = GetChannelWidthAndBand(txVector, staId);
700  double snr = m_wifiPhy->m_interference->CalculateSnr(event,
701  channelWidthAndBand.first,
702  txVector.GetNss(staId),
703  channelWidthAndBand.second);
704 
706  m_wifiPhy->NotifyRxEnd(psdu);
707 
708  auto signalNoiseIt = m_signalNoiseMap.find({ppdu->GetUid(), staId});
709  NS_ASSERT(signalNoiseIt != m_signalNoiseMap.end());
710  auto statusPerMpduIt = m_statusPerMpduMap.find({ppdu->GetUid(), staId});
711  NS_ASSERT(statusPerMpduIt != m_statusPerMpduMap.end());
712  // store per-MPDU status, which is cleared by the call to DoEndReceivePayload below
713  auto statusPerMpdu = statusPerMpduIt->second;
714 
715  RxSignalInfo rxSignalInfo;
716  bool success;
717 
718  if (std::count(statusPerMpdu.cbegin(), statusPerMpdu.cend(), true))
719  {
720  // At least one MPDU has been successfully received
723  txVector,
724  signalNoiseIt->second,
725  statusPerMpdu,
726  staId);
727  rxSignalInfo.snr = snr;
728  rxSignalInfo.rssi = signalNoiseIt->second.signal; // same information for all MPDUs
729  RxPayloadSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu);
731  ppdu->GetUid(); // store UID only if reception is successful (because otherwise trigger
732  // won't be read by MAC layer)
733  success = true;
734  }
735  else
736  {
737  RxPayloadFailed(psdu, snr, txVector);
738  success = false;
739  }
740 
741  DoEndReceivePayload(ppdu);
743 
744  // notify the MAC through the PHY state helper as the last action. Indeed, the notification
745  // of the RX end may lead the MAC to request a PHY state change (e.g., channel switch, sleep).
746  // Hence, all actions the PHY has to perform when RX ends should be completed before
747  // notifying the MAC.
748  success ? m_state->NotifyRxPsduSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu)
749  : m_state->NotifyRxPsduFailed(psdu, snr);
750 }
751 
752 void
754  RxSignalInfo rxSignalInfo,
755  const WifiTxVector& txVector,
756  uint16_t staId,
757  const std::vector<bool>& statusPerMpdu)
758 {
759  NS_LOG_FUNCTION(this << *psdu << txVector);
760  m_state->SwitchFromRxEndOk();
761 }
762 
763 void
765 {
766  NS_LOG_FUNCTION(this << *psdu << txVector << snr);
767  m_state->SwitchFromRxEndError();
768 }
769 
770 void
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 
782 std::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  {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 {true, signalNoise};
818  }
819  else
820  {
821  NS_LOG_DEBUG("Reception failed: " << psdu);
822  return {false, signalNoise};
823  }
824 }
825 
826 std::pair<uint16_t, WifiSpectrumBandInfo>
827 PhyEntity::GetChannelWidthAndBand(const WifiTxVector& txVector, uint16_t /* staId */) const
828 {
829  uint16_t channelWidth = GetRxChannelWidth(txVector);
830  return {channelWidth, GetPrimaryBand(channelWidth)};
831 }
832 
833 const std::map<std::pair<uint64_t, WifiPreamble>, Ptr<Event>>&
835 {
837 }
838 
839 void
841 {
842  NS_LOG_FUNCTION(this << *event);
843  Ptr<const WifiPpdu> ppdu = event->GetPpdu();
844  m_wifiPhy->m_currentPreambleEvents.insert({{ppdu->GetUid(), ppdu->GetPreamble()}, event});
845 }
846 
849 {
850  // We store all incoming preamble events, and a decision is made at the end of the preamble
851  // detection window.
852  const auto& currentPreambleEvents = GetCurrentPreambleEvents();
853  const auto it = currentPreambleEvents.find({ppdu->GetUid(), ppdu->GetPreamble()});
854  if (it != currentPreambleEvents.cend())
855  {
856  // received another signal with the same content
857  NS_LOG_DEBUG("Received another PPDU for UID " << ppdu->GetUid());
858  const auto foundEvent = it->second;
859  HandleRxPpduWithSameContent(foundEvent, ppdu, rxPowersW);
860  return nullptr;
861  }
862 
863  auto event = CreateInterferenceEvent(ppdu, ppdu->GetTxDuration(), rxPowersW);
864  AddPreambleEvent(event);
865  return event;
866 }
867 
870  Time duration,
871  RxPowerWattPerChannelBand& rxPower,
872  bool isStartHePortionRxing /* = false */)
873 {
874  return m_wifiPhy->m_interference->Add(ppdu, duration, rxPower, isStartHePortionRxing);
875 }
876 
877 void
879  Ptr<const WifiPpdu> ppdu,
880  RxPowerWattPerChannelBand& rxPower)
881 {
882  if (const auto maxDelay =
883  m_wifiPhy->GetPhyEntityForPpdu(ppdu)->GetMaxDelayPpduSameUid(ppdu->GetTxVector());
884  Simulator::Now() - event->GetStartTime() > maxDelay)
885  {
886  // This PPDU arrived too late to be decoded properly. The PPDU is dropped and added as
887  // interference
888  event = CreateInterferenceEvent(ppdu, ppdu->GetTxDuration(), rxPower);
889  NS_LOG_DEBUG("Drop PPDU that arrived too late");
891  return;
892  }
893 
894  // Update received power and TXVECTOR of the event associated to that transmission upon
895  // reception of a signal adding up constructively (in case of a UL MU PPDU or non-HT duplicate
896  // PPDU)
897  m_wifiPhy->m_interference->UpdateEvent(event, rxPower);
898  const auto& txVector = ppdu->GetTxVector();
899  const auto& eventTxVector = event->GetPpdu()->GetTxVector();
900  auto updatedTxVector{eventTxVector};
901  updatedTxVector.SetChannelWidth(
902  std::max(eventTxVector.GetChannelWidth(), txVector.GetChannelWidth()));
903  if (updatedTxVector.GetChannelWidth() != eventTxVector.GetChannelWidth())
904  {
905  event->UpdatePpdu(ppdu);
906  }
907 }
908 
909 void
911 {
913  m_signalNoiseMap.clear();
914  m_statusPerMpduMap.clear();
915  for (const auto& endOfMpduEvent : m_endOfMpduEvents)
916  {
917  NS_ASSERT(endOfMpduEvent.IsExpired());
918  }
919  m_endOfMpduEvents.clear();
920  if (reset)
921  {
922  m_wifiPhy->Reset();
923  }
924 }
925 
928 {
929  NS_LOG_FUNCTION(this << *event);
931  1); // Synched on one after detection period
932  return PhyFieldRxStatus(true); // always consider that preamble has been correctly received if
933  // preamble detection was OK
934 }
935 
936 void
938 {
939  NS_LOG_FUNCTION(this << *event);
940  NS_LOG_DEBUG("Sync to signal (power=" << WToDbm(GetRxPowerWForPpdu(event)) << "dBm)");
942  ->NotifyRxStart(); // We need to notify it now so that it starts recording events
946  this,
947  event));
948 }
949 
950 void
952 {
953  NS_LOG_FUNCTION(this << *event);
955  NS_ASSERT(m_wifiPhy->m_endPhyRxEvent.IsExpired()); // since end of preamble reception is
956  // scheduled by this method upon success
957 
958  // calculate PER on the measurement channel for PHY headers
959  uint16_t measurementChannelWidth = GetMeasurementChannelWidth(event->GetPpdu());
960  auto measurementBand = GetPrimaryBand(measurementChannelWidth);
961  double maxRxPowerW = -1; // in case current event may not be sent on measurement channel
962  // (rxPowerW would be equal to 0)
963  Ptr<Event> maxEvent;
965  for (auto preambleEvent : m_wifiPhy->m_currentPreambleEvents)
966  {
967  double rxPowerW = preambleEvent.second->GetRxPowerW(measurementBand);
968  if (rxPowerW > maxRxPowerW)
969  {
970  maxRxPowerW = rxPowerW;
971  maxEvent = preambleEvent.second;
972  }
973  }
974 
975  NS_ASSERT(maxEvent);
976  if (maxEvent != event)
977  {
978  NS_LOG_DEBUG("Receiver got a stronger packet with UID "
979  << maxEvent->GetPpdu()->GetUid()
980  << " during preamble detection: drop packet with UID "
981  << event->GetPpdu()->GetUid());
983  auto it = m_wifiPhy->m_currentPreambleEvents.find(
984  {event->GetPpdu()->GetUid(), event->GetPpdu()->GetPreamble()});
986  // This is needed to cleanup the m_firstPowerPerBand so that the first power corresponds to
987  // the power at the start of the PPDU
988  m_wifiPhy->m_interference->NotifyRxEnd(maxEvent->GetStartTime(),
990  // Make sure InterferenceHelper keeps recording events
991  m_wifiPhy->m_interference->NotifyRxStart();
992  return;
993  }
994 
995  m_wifiPhy->m_currentEvent = event;
996 
997  double snr = m_wifiPhy->m_interference->CalculateSnr(m_wifiPhy->m_currentEvent,
998  measurementChannelWidth,
999  1,
1000  measurementBand);
1001  NS_LOG_DEBUG("SNR(dB)=" << RatioToDb(snr) << " at end of preamble detection period");
1002 
1003  if ((!m_wifiPhy->m_preambleDetectionModel && maxRxPowerW > 0.0) ||
1005  m_wifiPhy->m_preambleDetectionModel->IsPreambleDetected(
1006  m_wifiPhy->m_currentEvent->GetRxPowerW(measurementBand),
1007  snr,
1008  measurementChannelWidth)))
1009  {
1010  // A bit convoluted but it enables to sync all PHYs
1011  for (auto& it : m_wifiPhy->m_phyEntities)
1012  {
1013  it.second->CancelRunningEndPreambleDetectionEvents();
1014  }
1015 
1016  for (auto it = m_wifiPhy->m_currentPreambleEvents.begin();
1017  it != m_wifiPhy->m_currentPreambleEvents.end();)
1018  {
1019  if (it->second != m_wifiPhy->m_currentEvent)
1020  {
1021  NS_LOG_DEBUG("Drop packet with UID " << it->first.first << " and preamble "
1022  << it->first.second << " arrived at time "
1023  << it->second->GetStartTime());
1024  WifiPhyRxfailureReason reason;
1025  if (m_wifiPhy->m_currentEvent->GetPpdu()->GetUid() > it->first.first)
1026  {
1028  // This is needed to cleanup the m_firstPowerPerBand so that the first power
1029  // corresponds to the power at the start of the PPDU
1030  m_wifiPhy->m_interference->NotifyRxEnd(
1031  m_wifiPhy->m_currentEvent->GetStartTime(),
1033  }
1034  else
1035  {
1036  reason = BUSY_DECODING_PREAMBLE;
1037  }
1038  m_wifiPhy->NotifyRxDrop(GetAddressedPsduInPpdu(it->second->GetPpdu()), reason);
1039  it = m_wifiPhy->m_currentPreambleEvents.erase(it);
1040  }
1041  else
1042  {
1043  ++it;
1044  }
1045  }
1046 
1047  // Make sure InterferenceHelper keeps recording events
1048  m_wifiPhy->m_interference->NotifyRxStart();
1049 
1051  m_wifiPhy->m_currentEvent->GetRxPowerWPerBand());
1053 
1054  // Continue receiving preamble
1055  Time durationTillEnd =
1056  GetDuration(WIFI_PPDU_FIELD_PREAMBLE, event->GetPpdu()->GetTxVector()) -
1058  m_wifiPhy->NotifyCcaBusy(event->GetPpdu(),
1059  durationTillEnd); // will be prolonged by next field
1060  m_wifiPhy->m_endPhyRxEvent = Simulator::Schedule(durationTillEnd,
1062  this,
1064  event);
1065  }
1066  else
1067  {
1068  NS_LOG_DEBUG("Drop packet because PHY preamble detection failed");
1069  // Like CCA-SD, CCA-ED is governed by the 4 us CCA window to flag CCA-BUSY
1070  // for any received signal greater than the CCA-ED threshold.
1073  m_wifiPhy->m_currentEvent->GetEndTime());
1074  if (m_wifiPhy->m_currentPreambleEvents.empty())
1075  {
1076  // Do not erase events if there are still pending preamble events to be processed
1077  m_wifiPhy->m_interference->NotifyRxEnd(Simulator::Now(),
1079  }
1080  m_wifiPhy->m_currentEvent = nullptr;
1081  // Cancel preamble reception
1083  }
1084 }
1085 
1086 bool
1088 {
1089  WifiMode txMode = ppdu->GetTxVector().GetMode();
1090  if (!IsModeSupported(txMode))
1091  {
1092  NS_LOG_DEBUG("Drop packet because it was sent using an unsupported mode (" << txMode
1093  << ")");
1094  return false;
1095  }
1096  return true;
1097 }
1098 
1099 void
1101 {
1102  NS_LOG_FUNCTION(this);
1104  for (auto& endRxPayloadEvent : m_endRxPayloadEvents)
1105  {
1106  endRxPayloadEvent.Cancel();
1107  }
1108  m_endRxPayloadEvents.clear();
1109  for (auto& endMpduEvent : m_endOfMpduEvents)
1110  {
1111  endMpduEvent.Cancel();
1112  }
1113  m_endOfMpduEvents.clear();
1114 }
1115 
1116 bool
1118 {
1119  return m_endPreambleDetectionEvents.empty();
1120 }
1121 
1122 void
1124 {
1125  NS_LOG_FUNCTION(this);
1126  for (auto& endPreambleDetectionEvent : m_endPreambleDetectionEvents)
1127  {
1128  endPreambleDetectionEvent.Cancel();
1129  }
1131 }
1132 
1133 void
1135 {
1136  NS_LOG_FUNCTION(this << reason);
1137  DoAbortCurrentReception(reason);
1139 }
1140 
1141 void
1143 {
1144  NS_LOG_FUNCTION(this << reason);
1145  if (m_wifiPhy->m_currentEvent) // Otherwise abort has already been called just before
1146  {
1147  for (auto& endMpduEvent : m_endOfMpduEvents)
1148  {
1149  endMpduEvent.Cancel();
1150  }
1151  m_endOfMpduEvents.clear();
1152  }
1153 }
1154 
1155 void
1157 {
1158  NS_LOG_FUNCTION(this << *event);
1159  DoResetReceive(event);
1162  NS_ASSERT(m_endRxPayloadEvents.size() == 1 && m_endRxPayloadEvents.front().IsExpired());
1163  m_endRxPayloadEvents.clear();
1164  m_wifiPhy->m_currentEvent = nullptr;
1166  m_wifiPhy->SwitchMaybeToCcaBusy(event->GetPpdu());
1167 }
1168 
1169 void
1171 {
1172  NS_LOG_FUNCTION(this << *event);
1173  NS_ASSERT(event->GetEndTime() == Simulator::Now());
1174 }
1175 
1176 double
1178 {
1179  return m_wifiPhy->m_random->GetValue();
1180 }
1181 
1182 double
1184 {
1185  return event->GetRxPowerW(GetPrimaryBand(GetMeasurementChannelWidth(event->GetPpdu())));
1186 }
1187 
1190 {
1191  return m_wifiPhy->m_currentEvent;
1192 }
1193 
1195 PhyEntity::GetPrimaryBand(uint16_t bandWidth) const
1196 {
1197  if (m_wifiPhy->GetChannelWidth() % 20 != 0)
1198  {
1199  return m_wifiPhy->GetBand(bandWidth);
1200  }
1201  return m_wifiPhy->GetBand(bandWidth,
1203 }
1204 
1206 PhyEntity::GetSecondaryBand(uint16_t bandWidth) const
1207 {
1209  return m_wifiPhy->GetBand(bandWidth,
1211 }
1212 
1213 uint16_t
1215 {
1216  return std::min(m_wifiPhy->GetChannelWidth(), txVector.GetChannelWidth());
1217 }
1218 
1219 double
1221  WifiChannelListType /*channelType*/) const
1222 {
1224 }
1225 
1226 Time
1227 PhyEntity::GetDelayUntilCcaEnd(double thresholdDbm, const WifiSpectrumBandInfo& band)
1228 {
1229  return m_wifiPhy->m_interference->GetEnergyDuration(DbmToW(thresholdDbm), band);
1230 }
1231 
1232 void
1234 {
1235  // We are here because we have received the first bit of a packet and we are
1236  // not going to be able to synchronize on it
1237  // In this model, CCA becomes busy when the aggregation of all signals as
1238  // tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
1239  const auto ccaIndication = GetCcaIndication(ppdu);
1240  if (ccaIndication.has_value())
1241  {
1242  NS_LOG_DEBUG("CCA busy for " << ccaIndication.value().second << " during "
1243  << ccaIndication.value().first.As(Time::S));
1244  m_state->SwitchMaybeToCcaBusy(ccaIndication.value().first,
1245  ccaIndication.value().second,
1246  {});
1247  return;
1248  }
1249  if (ppdu)
1250  {
1251  SwitchMaybeToCcaBusy(nullptr);
1252  }
1253 }
1254 
1257 {
1258  const uint16_t channelWidth = GetMeasurementChannelWidth(ppdu);
1259  NS_LOG_FUNCTION(this << channelWidth);
1260  const double ccaThresholdDbm = GetCcaThreshold(ppdu, WIFI_CHANLIST_PRIMARY);
1261  const Time delayUntilCcaEnd =
1262  GetDelayUntilCcaEnd(ccaThresholdDbm, GetPrimaryBand(channelWidth));
1263  if (delayUntilCcaEnd.IsStrictlyPositive())
1264  {
1265  return std::make_pair(delayUntilCcaEnd, WIFI_CHANLIST_PRIMARY);
1266  }
1267  return std::nullopt;
1268 }
1269 
1270 void
1272  Time duration,
1273  WifiChannelListType channelType)
1274 {
1275  NS_LOG_FUNCTION(this << duration << channelType);
1276  NS_LOG_DEBUG("CCA busy for " << channelType << " during " << duration.As(Time::S));
1277  m_state->SwitchMaybeToCcaBusy(duration, channelType, {});
1278 }
1279 
1280 uint64_t
1282 {
1283  NS_LOG_FUNCTION(this);
1284  return m_globalPpduUid++;
1285 }
1286 
1287 Time
1289 {
1290  return Seconds(0);
1291 }
1292 
1293 uint16_t
1295 {
1296  NS_LOG_FUNCTION(this << txVector);
1297 
1299  txVector.GetChannelWidth());
1300 }
1301 
1302 void
1303 PhyEntity::NotifyPayloadBegin(const WifiTxVector& txVector, const Time& payloadDuration)
1304 {
1305  m_wifiPhy->m_phyRxPayloadBeginTrace(txVector, payloadDuration);
1306 }
1307 
1308 void
1310 {
1311  NS_LOG_FUNCTION(this << ppdu);
1312  auto txPowerDbm = m_wifiPhy->GetTxPowerForTransmission(ppdu) + m_wifiPhy->GetTxGain();
1313  auto txVector = ppdu->GetTxVector();
1314  auto txPowerSpectrum = GetTxPowerSpectralDensity(DbmToW(txPowerDbm), ppdu);
1315  Transmit(ppdu->GetTxDuration(), ppdu, txPowerDbm, txPowerSpectrum, "transmission");
1316 }
1317 
1318 void
1320  Ptr<const WifiPpdu> ppdu,
1321  double txPowerDbm,
1322  Ptr<SpectrumValue> txPowerSpectrum,
1323  const std::string& type)
1324 {
1325  NS_LOG_FUNCTION(this << txDuration << ppdu << txPowerDbm << type);
1326  NS_LOG_DEBUG("Start " << type << ": signal power before antenna gain=" << txPowerDbm << "dBm");
1327  auto txParams = Create<WifiSpectrumSignalParameters>();
1328  txParams->duration = txDuration;
1329  txParams->psd = txPowerSpectrum;
1330  txParams->ppdu = ppdu;
1331  NS_LOG_DEBUG("Starting " << type << " with power " << txPowerDbm << " dBm on channel "
1332  << +m_wifiPhy->GetChannelNumber() << " for "
1333  << txParams->duration.As(Time::MS));
1334  NS_LOG_DEBUG("Starting " << type << " with integrated spectrum power "
1335  << WToDbm(Integral(*txPowerSpectrum)) << " dBm; spectrum model Uid: "
1336  << txPowerSpectrum->GetSpectrumModel()->GetUid());
1337  auto spectrumWifiPhy = DynamicCast<SpectrumWifiPhy>(m_wifiPhy);
1338  NS_ASSERT(spectrumWifiPhy);
1339  spectrumWifiPhy->Transmit(txParams);
1340 }
1341 
1342 uint16_t
1343 PhyEntity::GetGuardBandwidth(uint16_t currentChannelWidth) const
1344 {
1345  return m_wifiPhy->GetGuardBandwidth(currentChannelWidth);
1346 }
1347 
1348 std::tuple<double, double, double>
1350 {
1352 }
1353 
1354 Time
1356  const WifiTxVector& txVector,
1357  WifiPhyBand band) const
1358 {
1359  NS_ASSERT(psduMap.size() == 1);
1360  const auto& it = psduMap.begin();
1361  return WifiPhy::CalculateTxDuration(it->second->GetSize(), txVector, band, it->first);
1362 }
1363 
1364 bool
1366 {
1367  // The PHY shall not issue a PHY-RXSTART.indication primitive in response to a PPDU that does
1368  // not overlap the primary channel
1369  const auto channelWidth = m_wifiPhy->GetChannelWidth();
1370  const auto primaryWidth =
1371  ((channelWidth % 20 == 0) ? 20
1372  : channelWidth); // if the channel width is a multiple of 20 MHz,
1373  // then we consider the primary20 channel
1374  const auto p20CenterFreq =
1376  const auto p20MinFreq = p20CenterFreq - (primaryWidth / 2);
1377  const auto p20MaxFreq = p20CenterFreq + (primaryWidth / 2);
1378  const auto txCenterFreq = ppdu->GetTxCenterFreq();
1379  const auto txChannelWidth = ppdu->GetTxChannelWidth();
1380  const auto minTxFreq = txCenterFreq - txChannelWidth / 2;
1381  const auto maxTxFreq = txCenterFreq + txChannelWidth / 2;
1382  return p20MinFreq >= minTxFreq && p20MaxFreq <= maxTxFreq;
1383 }
1384 
1387 {
1388  return ppdu;
1389 }
1390 
1391 } // namespace ns3
#define min(a, b)
Definition: 80211b.c:41
#define max(a, b)
Definition: 80211b.c:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
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:1303
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:878
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:515
std::list< WifiMode >::const_iterator end() const
Return a const iterator to past-the-last WifiMode.
Definition: phy-entity.cc:144
virtual const PpduFormats & GetPpduFormats() const =0
Return the PPDU formats of the PHY.
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:753
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:927
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper of the WifiPhy (to make it reachable for child classes)
Definition: phy-entity.h:982
virtual void RxPayloadFailed(Ptr< const WifiPsdu > psdu, double snr, const WifiTxVector &txVector)
Perform amendment-specific actions when the payload is unsuccessfuly received.
Definition: phy-entity.cc:764
void EndPreambleDetectionPeriod(Ptr< Event > event)
End the preamble detection period.
Definition: phy-entity.cc:951
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:1271
virtual Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration)
Build amendment-specific PPDU.
Definition: phy-entity.cc:241
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:1349
virtual uint64_t ObtainNextUid(const WifiTxVector &txVector)
Obtain the next UID for the PPDU to transmit.
Definition: phy-entity.cc:1281
virtual Time DoStartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: phy-entity.cc:570
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:1227
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:397
bool NoEndPreambleDetectionEvents() const
Definition: phy-entity.cc:1117
virtual Ptr< SpectrumValue > GetTxPowerSpectralDensity(double txPowerW, Ptr< const WifiPpdu > ppdu) const =0
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:1002
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition: phy-entity.h:981
void Transmit(Time txDuration, Ptr< const WifiPpdu > ppdu, double txPowerDbm, Ptr< SpectrumValue > txPowerSpectrum, const std::string &type)
This function prepares most of the WifiSpectrumSignalParameters parameters and invokes SpectrumWifiPh...
Definition: phy-entity.cc:1319
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:1206
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
Definition: phy-entity.h:988
virtual uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const =0
Return the channel width used to measure the RSSI.
virtual ~PhyEntity()
Destructor for PHY entity.
Definition: phy-entity.cc: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:1220
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:366
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:1100
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
Definition: phy-entity.cc:1142
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Abort the current reception.
Definition: phy-entity.cc:1134
void EndReceivePayload(Ptr< Event > event)
The last symbol of the PPDU has arrived.
Definition: phy-entity.cc:691
static uint64_t m_globalPpduUid
Global counter of the PPDU UID.
Definition: phy-entity.h:1005
PhyHeaderSections GetPhyHeaderSections(const WifiTxVector &txVector, Time ppduStart) const
Return a map of PHY header chunk information per PPDU field.
Definition: phy-entity.cc: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:560
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
Definition: phy-entity.h:991
virtual void DoResetReceive(Ptr< Event > event)
Perform amendment-specific actions before resetting PHY at the end of the PPDU under reception after ...
Definition: phy-entity.cc:1170
void EndReceiveField(WifiPpduField field, Ptr< Event > event)
End receiving a given field.
Definition: phy-entity.cc:306
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW)
Get the event corresponding to the incoming PPDU.
Definition: phy-entity.cc:848
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
void CancelRunningEndPreambleDetectionEvents()
Cancel all end preamble detection events.
Definition: phy-entity.cc:1123
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:1183
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:1233
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:910
void StartPreambleDetectionPeriod(Ptr< Event > event)
Start the preamble detection period.
Definition: phy-entity.cc:937
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:252
std::map< UidStaIdPair, std::vector< bool > > m_statusPerMpduMap
Map of the current reception status per MPDU that is filled in as long as MPDUs are being processed b...
Definition: phy-entity.h:999
virtual bool CanStartRx(Ptr< const WifiPpdu > ppdu) const
Determine whether the PHY shall issue a PHY-RXSTART.indication primitive in response to a given PPDU.
Definition: phy-entity.cc:1365
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:1309
virtual uint16_t GetRxChannelWidth(const WifiTxVector &txVector) const
Return the channel width used in the reception spectrum model.
Definition: phy-entity.cc:1214
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:358
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:554
virtual Time CalculateTxDuration(WifiConstPsduMap psduMap, const WifiTxVector &txVector, WifiPhyBand band) const
Definition: phy-entity.cc:1355
void StartReceiveField(WifiPpduField field, Ptr< Event > event)
Start receiving a given field.
Definition: phy-entity.cc:279
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const
Definition: phy-entity.cc:1343
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:1156
std::optional< std::pair< Time, WifiChannelListType > > CcaIndication
CCA end time and its corresponding channel list type (can be std::nullopt if IDLE)
Definition: phy-entity.h:969
virtual CcaIndication GetCcaIndication(const Ptr< const WifiPpdu > ppdu)
Get CCA end time and its corresponding channel list type when a new signal has been received by the P...
Definition: phy-entity.cc:1256
std::list< WifiMode > m_modeList
the list of supported modes
Definition: phy-entity.h:985
virtual Time GetMaxDelayPpduSameUid(const WifiTxVector &txVector)
Obtain the maximum time between two PPDUs with the same UID to consider they are identical and their ...
Definition: phy-entity.cc:1288
Ptr< const Event > GetCurrentEvent() const
Get the pointer to the current event (stored in WifiPhy).
Definition: phy-entity.cc:1189
double GetRandomValue() const
Obtain a random value from the WifiPhy's generator.
Definition: phy-entity.cc:1177
std::vector< EventId > m_endPreambleDetectionEvents
the end of preamble detection events
Definition: phy-entity.h:987
virtual Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
Definition: phy-entity.cc: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:268
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:533
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:1386
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:1294
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:1087
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:869
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:1195
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:654
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:385
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Definition: phy-entity.cc:592
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
SpectrumModelUid_t GetUid() const
Ptr< const SpectrumModel > GetSpectrumModel() const
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:351
@ MS
millisecond
Definition: nstime.h:117
@ S
second
Definition: nstime.h:116
@ NS
nanosecond
Definition: nstime.h:119
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:315
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
represent a single transmission mode
Definition: wifi-mode.h:51
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1263
double GetCcaEdThreshold() const
Return the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:499
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1262
void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration)
Notify PHY state helper to switch to CCA busy state,.
Definition: wifi-phy.cc:2112
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition: wifi-phy.h:1494
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:1460
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1051
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:1275
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1270
double GetTxGain() const
Return the transmission gain (dB).
Definition: wifi-phy.cc:575
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1608
bool IsStateRx() const
Definition: wifi-phy.cc:2057
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1039
static Time GetPreambleDetectionDuration()
Definition: wifi-phy.cc:1448
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition: wifi-phy.cc:2119
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:1536
void NotifyRxBegin(Ptr< const WifiPsdu > psdu, const RxPowerWattPerChannelBand &rxPowersW)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:1584
virtual std::tuple< double, double, double > GetTxMaskRejectionParams() const =0
virtual uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const =0
bool IsStateOff() const
Definition: wifi-phy.cc:2081
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1507
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1298
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: wifi-phy.h:1539
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1021
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:1273
uint8_t GetChannelNumber() const
Return current channel number.
Definition: wifi-phy.cc:1045
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1278
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:1537
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:1596
bool IsStateSleep() const
Definition: wifi-phy.cc:2075
virtual FrequencyRange GetCurrentFrequencyRange() const =0
Get the frequency range of the current RF interface.
virtual WifiSpectrumBandInfo GetBand(uint16_t bandWidth, uint8_t bandIndex=0)=0
Get the info of a given band.
void SwitchMaybeToCcaBusy(const Ptr< const WifiPpdu > ppdu=nullptr)
Check if PHY state should move to CCA busy state based on current state of interference tracker.
Definition: wifi-phy.cc:2105
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition: wifi-phy.h:1260
double GetTxPowerForTransmission(Ptr< const WifiPpdu > ppdu) const
Compute the transmit power for the next transmission.
Definition: wifi-phy.cc:2184
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:1620
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition: wifi-phy.cc:732
void Reset()
Reset data upon end of TX or RX.
Definition: wifi-phy.cc:1854
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:1425
Time GetLastRxEndTime() const
Return the end time of the last received packet.
Definition: wifi-phy.cc:2099
Time m_timeLastPreambleDetected
Record the time the last preamble was detected.
Definition: wifi-phy.h:1540
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1033
double GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:512
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.
Ptr< const Packet > GetPacket() const
Get the PSDU as a single packet.
Definition: wifi-psdu.cc:89
std::vector< Ptr< WifiMpdu > >::const_iterator end() const
Return a const iterator to past-the-last MPDU.
Definition: wifi-psdu.cc:345
std::vector< Ptr< WifiMpdu > >::const_iterator begin() const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:333
uint32_t GetSize() const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:273
std::size_t GetAmpduSubframeSize(std::size_t i) const
Return the size of the i-th A-MPDU subframe.
Definition: wifi-psdu.cc:314
bool IsSingle() const
Return true if the PSDU is an S-MPDU.
Definition: wifi-psdu.cc:77
std::size_t GetNMpdus() const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:327
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:1350
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1362
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
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
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
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.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ SWITCHING
The PHY layer is switching to other channel.
@ RX
The PHY layer is receiving a packet.
@ TX
The PHY layer is sending a packet.
@ OFF
The PHY layer is switched off.
@ SLEEP
The PHY layer is sleeping.
@ IDLE
The PHY layer is IDLE.