A Discrete-Event Network Simulator
API
wifi-phy-state-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include <algorithm>
22 #include "ns3/log.h"
23 #include "ns3/simulator.h"
24 #include "ns3/packet.h"
25 #include "wifi-phy-state-helper.h"
26 #include "wifi-tx-vector.h"
27 #include "wifi-phy-listener.h"
28 #include "wifi-psdu.h"
29 #include "wifi-phy.h"
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("WifiPhyStateHelper");
34 
35 NS_OBJECT_ENSURE_REGISTERED (WifiPhyStateHelper);
36 
37 TypeId
39 {
40  static TypeId tid = TypeId ("ns3::WifiPhyStateHelper")
41  .SetParent<Object> ()
42  .SetGroupName ("Wifi")
43  .AddConstructor<WifiPhyStateHelper> ()
44  .AddTraceSource ("State",
45  "The state of the PHY layer",
47  "ns3::WifiPhyStateHelper::StateTracedCallback")
48  .AddTraceSource ("RxOk",
49  "A packet has been received successfully.",
51  "ns3::WifiPhyStateHelper::RxOkTracedCallback")
52  .AddTraceSource ("RxError",
53  "A packet has been received unsuccessfully.",
55  "ns3::WifiPhyStateHelper::RxEndErrorTracedCallback")
56  .AddTraceSource ("Tx", "Packet transmission is starting.",
58  "ns3::WifiPhyStateHelper::TxTracedCallback")
59  ;
60  return tid;
61 }
62 
64  : m_sleeping (false),
65  m_isOff (false),
66  m_endTx (Seconds (0)),
67  m_endRx (Seconds (0)),
68  m_endCcaBusy (Seconds (0)),
69  m_endSwitching (Seconds (0)),
70  m_startTx (Seconds (0)),
71  m_startRx (Seconds (0)),
72  m_startCcaBusy (Seconds (0)),
73  m_startSwitching (Seconds (0)),
74  m_startSleep (Seconds (0)),
75  m_previousStateChangeTime (Seconds (0))
76 {
77  NS_LOG_FUNCTION (this);
78 }
79 
80 void
82 {
83  m_rxOkCallback = callback;
84 }
85 
86 void
88 {
89  m_rxErrorCallback = callback;
90 }
91 
92 void
94 {
95  m_listeners.push_back (listener);
96 }
97 
98 void
100 {
101  ListenersI i = find (m_listeners.begin (), m_listeners.end (), listener);
102  if (i != m_listeners.end ())
103  {
104  m_listeners.erase (i);
105  }
106 }
107 
108 bool
110 {
111  return (GetState () == WifiPhyState::IDLE);
112 }
113 
114 bool
116 {
117  return (GetState () == WifiPhyState::CCA_BUSY);
118 }
119 
120 bool
122 {
123  return (GetState () == WifiPhyState::RX);
124 }
125 
126 bool
128 {
129  return (GetState () == WifiPhyState::TX);
130 }
131 
132 bool
134 {
135  return (GetState () == WifiPhyState::SWITCHING);
136 }
137 
138 bool
140 {
141  return (GetState () == WifiPhyState::SLEEP);
142 }
143 
144 bool
146 {
147  return (GetState () == WifiPhyState::OFF);
148 }
149 
150 Time
152 {
153  Time retval;
154 
155  switch (GetState ())
156  {
157  case WifiPhyState::RX:
158  retval = m_endRx - Simulator::Now ();
159  break;
160  case WifiPhyState::TX:
161  retval = m_endTx - Simulator::Now ();
162  break;
164  retval = m_endCcaBusy - Simulator::Now ();
165  break;
167  retval = m_endSwitching - Simulator::Now ();
168  break;
169  case WifiPhyState::IDLE:
170  case WifiPhyState::SLEEP:
171  case WifiPhyState::OFF:
172  retval = Seconds (0);
173  break;
174  default:
175  NS_FATAL_ERROR ("Invalid WifiPhy state.");
176  retval = Seconds (0);
177  break;
178  }
179  retval = Max (retval, Seconds (0));
180  return retval;
181 }
182 
183 Time
185 {
186  return m_startRx;
187 }
188 
189 Time
191 {
192  return m_endRx;
193 }
194 
197 {
198  if (m_isOff)
199  {
200  return WifiPhyState::OFF;
201  }
202  if (m_sleeping)
203  {
204  return WifiPhyState::SLEEP;
205  }
206  else if (m_endTx > Simulator::Now ())
207  {
208  return WifiPhyState::TX;
209  }
210  else if (m_endRx > Simulator::Now ())
211  {
212  return WifiPhyState::RX;
213  }
214  else if (m_endSwitching > Simulator::Now ())
215  {
217  }
218  else if (m_endCcaBusy > Simulator::Now ())
219  {
220  return WifiPhyState::CCA_BUSY;
221  }
222  else
223  {
224  return WifiPhyState::IDLE;
225  }
226 }
227 
228 void
229 WifiPhyStateHelper::NotifyTxStart (Time duration, double txPowerDbm)
230 {
231  NS_LOG_FUNCTION (this);
232  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
233  {
234  (*i)->NotifyTxStart (duration, txPowerDbm);
235  }
236 }
237 
238 void
240 {
241  NS_LOG_FUNCTION (this);
242  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
243  {
244  (*i)->NotifyRxStart (duration);
245  }
246 }
247 
248 void
250 {
251  NS_LOG_FUNCTION (this);
252  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
253  {
254  (*i)->NotifyRxEndOk ();
255  }
256 }
257 
258 void
260 {
261  NS_LOG_FUNCTION (this);
262  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
263  {
264  (*i)->NotifyRxEndError ();
265  }
266 }
267 
268 void
270 {
271  NS_LOG_FUNCTION (this);
272  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
273  {
274  (*i)->NotifyMaybeCcaBusyStart (duration);
275  }
276 }
277 
278 void
280 {
281  NS_LOG_FUNCTION (this);
282  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
283  {
284  (*i)->NotifySwitchingStart (duration);
285  }
286 }
287 
288 void
290 {
291  NS_LOG_FUNCTION (this);
292  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
293  {
294  (*i)->NotifySleep ();
295  }
296 }
297 
298 void
300 {
301  NS_LOG_FUNCTION (this);
302  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
303  {
304  (*i)->NotifyOff ();
305  }
306 }
307 
308 void
310 {
311  NS_LOG_FUNCTION (this);
312  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
313  {
314  (*i)->NotifyWakeup ();
315  }
316 }
317 
318 void
320 {
321  NS_LOG_FUNCTION (this);
322  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
323  {
324  (*i)->NotifyOn ();
325  }
326 }
327 
328 void
330 {
331  NS_LOG_FUNCTION (this);
332  Time now = Simulator::Now ();
333  Time idleStart = Max (m_endCcaBusy, m_endRx);
334  idleStart = Max (idleStart, m_endTx);
335  idleStart = Max (idleStart, m_endSwitching);
336  NS_ASSERT (idleStart <= now);
337  if (m_endCcaBusy > m_endRx
339  && m_endCcaBusy > m_endTx)
340  {
341  Time ccaBusyStart = Max (m_endTx, m_endRx);
342  ccaBusyStart = Max (ccaBusyStart, m_startCcaBusy);
343  ccaBusyStart = Max (ccaBusyStart, m_endSwitching);
344  Time ccaBusyDuration = idleStart - ccaBusyStart;
345  if (ccaBusyDuration.IsStrictlyPositive ())
346  {
347  m_stateLogger (ccaBusyStart, ccaBusyDuration, WifiPhyState::CCA_BUSY);
348  }
349  }
350  Time idleDuration = now - idleStart;
351  if (idleDuration.IsStrictlyPositive ())
352  {
353  m_stateLogger (idleStart, idleDuration, WifiPhyState::IDLE);
354  }
355 }
356 
357 void
358 WifiPhyStateHelper::SwitchToTx (Time txDuration, WifiConstPsduMap psdus, double txPowerDbm, WifiTxVector txVector)
359 {
360  NS_LOG_FUNCTION (this << txDuration << psdus << txPowerDbm << txVector);
361  for (auto const& psdu : psdus)
362  {
363  m_txTrace (psdu.second->GetPacket (), txVector.GetMode (psdu.first), txVector.GetPreambleType (), txVector.GetTxPowerLevel ());
364  }
365  Time now = Simulator::Now ();
366  switch (GetState ())
367  {
368  case WifiPhyState::RX:
369  /* The packet which is being received as well
370  * as its endRx event are cancelled by the caller.
371  */
373  m_endRx = now;
374  break;
376  {
377  Time ccaStart = Max (m_endRx, m_endTx);
378  ccaStart = Max (ccaStart, m_startCcaBusy);
379  ccaStart = Max (ccaStart, m_endSwitching);
380  m_stateLogger (ccaStart, now - ccaStart, WifiPhyState::CCA_BUSY);
381  } break;
382  case WifiPhyState::IDLE:
384  break;
385  default:
386  NS_FATAL_ERROR ("Invalid WifiPhy state.");
387  break;
388  }
389  m_stateLogger (now, txDuration, WifiPhyState::TX);
391  m_endTx = now + txDuration;
392  m_startTx = now;
393  NotifyTxStart (txDuration, txPowerDbm);
394 }
395 
396 void
398 {
399  NS_LOG_FUNCTION (this << rxDuration);
401  Time now = Simulator::Now ();
402  switch (GetState ())
403  {
404  case WifiPhyState::IDLE:
406  break;
408  {
409  Time ccaStart = Max (m_endRx, m_endTx);
410  ccaStart = Max (ccaStart, m_startCcaBusy);
411  ccaStart = Max (ccaStart, m_endSwitching);
412  m_stateLogger (ccaStart, now - ccaStart, WifiPhyState::CCA_BUSY);
413  } break;
414  default:
415  NS_FATAL_ERROR ("Invalid WifiPhy state " << GetState ());
416  break;
417  }
419  m_startRx = now;
420  m_endRx = now + rxDuration;
421  NotifyRxStart (rxDuration);
422  NS_ASSERT (IsStateRx ());
423 }
424 
425 void
427 {
428  NS_LOG_FUNCTION (this << switchingDuration);
429  Time now = Simulator::Now ();
430  switch (GetState ())
431  {
432  case WifiPhyState::RX:
433  /* The packet which is being received as well
434  * as its endRx event are cancelled by the caller.
435  */
437  m_endRx = now;
438  break;
440  {
441  Time ccaStart = Max (m_endRx, m_endTx);
442  ccaStart = Max (ccaStart, m_startCcaBusy);
443  ccaStart = Max (ccaStart, m_endSwitching);
444  m_stateLogger (ccaStart, now - ccaStart, WifiPhyState::CCA_BUSY);
445  } break;
446  case WifiPhyState::IDLE:
448  break;
449  default:
450  NS_FATAL_ERROR ("Invalid WifiPhy state.");
451  break;
452  }
453 
454  if (now < m_endCcaBusy)
455  {
456  m_endCcaBusy = now;
457  }
458 
459  m_stateLogger (now, switchingDuration, WifiPhyState::SWITCHING);
461  m_startSwitching = now;
462  m_endSwitching = now + switchingDuration;
463  NotifySwitchingStart (switchingDuration);
465 }
466 
467 void
469 {
470  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
471  std::vector<bool> statusPerMpdu;
472  if (!m_rxOkCallback.IsNull ())
473  {
474  m_rxOkCallback (psdu, rxSignalInfo, txVector, statusPerMpdu);
475  }
476 }
477 
478 void
479 WifiPhyStateHelper::SwitchFromRxEndOk (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, uint16_t staId, std::vector<bool> statusPerMpdu)
480 {
481  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector << staId << statusPerMpdu.size () <<
482  std::all_of(statusPerMpdu.begin(), statusPerMpdu.end(), [](bool v) { return v; })); //returns true if all true
483  NS_ASSERT (statusPerMpdu.size () != 0);
484  NS_ASSERT (Abs (m_endRx - Simulator::Now ()) < MicroSeconds (1)); //1us corresponds to the maximum propagation delay (delay spread)
485  //TODO: a better fix would be to call the function once all HE TB PPDUs are received
486  m_rxOkTrace (psdu->GetPacket (), rxSignalInfo.snr, txVector.GetMode (staId), txVector.GetPreambleType ());
487  NotifyRxEndOk ();
488  DoSwitchFromRx ();
489  if (!m_rxOkCallback.IsNull ())
490  {
491  m_rxOkCallback (psdu, rxSignalInfo, txVector, statusPerMpdu);
492  }
493 }
494 
495 void
497 {
498  NS_LOG_FUNCTION (this << *psdu << snr);
499  NS_ASSERT (Abs (m_endRx - Simulator::Now ()) < MicroSeconds (1)); //1us corresponds to the maximum propagation delay (delay spread)
500  //TODO: a better fix would be to call the function once all HE TB PPDUs are received
501  m_rxErrorTrace (psdu->GetPacket (), snr);
502  NotifyRxEndError ();
503  DoSwitchFromRx ();
504  if (!m_rxErrorCallback.IsNull ())
505  {
506  m_rxErrorCallback (psdu);
507  }
508 }
509 
510 void
512 {
513  NS_LOG_FUNCTION (this);
514  Time now = Simulator::Now ();
517  m_endRx = Simulator::Now ();
519 }
520 
521 void
523 {
524  NS_LOG_FUNCTION (this << duration);
525  if (GetState () != WifiPhyState::RX)
526  {
527  NotifyMaybeCcaBusyStart (duration);
528  }
529  Time now = Simulator::Now ();
530  switch (GetState ())
531  {
532  case WifiPhyState::IDLE:
534  break;
535  case WifiPhyState::RX:
536  return;
537  default:
538  break;
539  }
541  {
542  m_startCcaBusy = now;
543  }
544  m_endCcaBusy = std::max (m_endCcaBusy, now + duration);
545 }
546 
547 void
549 {
550  NS_LOG_FUNCTION (this);
551  Time now = Simulator::Now ();
552  switch (GetState ())
553  {
554  case WifiPhyState::IDLE:
556  break;
558  {
559  Time ccaStart = Max (m_endRx, m_endTx);
560  ccaStart = Max (ccaStart, m_startCcaBusy);
561  ccaStart = Max (ccaStart, m_endSwitching);
562  m_stateLogger (ccaStart, now - ccaStart, WifiPhyState::CCA_BUSY);
563  } break;
564  default:
565  NS_FATAL_ERROR ("Invalid WifiPhy state.");
566  break;
567  }
569  m_sleeping = true;
570  m_startSleep = now;
571  NotifySleep ();
572  NS_ASSERT (IsStateSleep ());
573 }
574 
575 void
577 {
578  NS_LOG_FUNCTION (this << duration);
579  NS_ASSERT (IsStateSleep ());
580  Time now = Simulator::Now ();
583  m_sleeping = false;
584  NotifyWakeup ();
585  //update m_endCcaBusy after the sleep period
586  m_endCcaBusy = std::max (m_endCcaBusy, now + duration);
587  if (m_endCcaBusy > now)
588  {
590  }
591 }
592 
593 void
595 {
596  NS_LOG_FUNCTION (this);
597  NS_ASSERT (IsStateCcaBusy ()); //abort is called (with OBSS_PD_CCA_RESET reason) before RX is set by payload start
598  NotifyRxEndOk ();
599  DoSwitchFromRx ();
602  NS_ASSERT (IsStateIdle ());
603 }
604 
605 void
607 {
608  NS_LOG_FUNCTION (this);
609  Time now = Simulator::Now ();
610  switch (GetState ())
611  {
612  case WifiPhyState::RX:
613  /* The packet which is being received as well
614  * as its endRx event are cancelled by the caller.
615  */
617  m_endRx = now;
618  break;
619  case WifiPhyState::TX:
620  /* The packet which is being transmitted as well
621  * as its endTx event are cancelled by the caller.
622  */
624  m_endTx = now;
625  break;
626  case WifiPhyState::IDLE:
628  break;
630  {
631  Time ccaStart = Max (m_endRx, m_endTx);
632  ccaStart = Max (ccaStart, m_startCcaBusy);
633  ccaStart = Max (ccaStart, m_endSwitching);
634  m_stateLogger (ccaStart, now - ccaStart, WifiPhyState::CCA_BUSY);
635  } break;
636  default:
637  NS_FATAL_ERROR ("Invalid WifiPhy state.");
638  break;
639  }
641  m_isOff = true;
642  NotifyOff ();
643  NS_ASSERT (IsStateOff ());
644 }
645 
646 void
648 {
649  NS_LOG_FUNCTION (this << duration);
650  NS_ASSERT (IsStateOff ());
651  Time now = Simulator::Now ();
653  m_isOff = false;
654  NotifyOn ();
655  //update m_endCcaBusy after the off period
656  m_endCcaBusy = std::max (m_endCcaBusy, now + duration);
657  if (m_endCcaBusy > now)
658  {
660  }
661 }
662 
663 } //namespace ns3
bool IsStateIdle(void) const
Check whether the current state is IDLE.
Time GetLastRxStartTime(void) const
Return the time the last RX start.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
void DoSwitchFromRx(void)
Switch the state from RX.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
TracedCallback< Time, Time, WifiPhyState > m_stateLogger
The trace source fired when state is changed.
void SwitchFromRxEndOk(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, uint16_t staId, std::vector< bool > statusPerMpdu)
Switch from RX after the reception was successful.
void NotifyWakeup(void)
Notify all WifiPhyListener that we woke up.
void ContinueRxNextMpdu(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector)
Continue RX after the reception of an MPDU in an A-MPDU was successful.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition: wifi-ppdu.h:38
The PHY layer is sleeping.
Time m_startCcaBusy
start CCA busy
void SwitchToOff(void)
Switch to off mode.
void SwitchToChannelSwitching(Time switchingDuration)
Switch state to channel switching for the given duration.
void UnregisterListener(WifiPhyListener *listener)
Remove WifiPhyListener from this WifiPhyStateHelper.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
void NotifyRxEndError(void)
Notify all WifiPhyListener that the reception was not successful.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void SwitchFromRxAbort(void)
Abort current reception.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
std::vector< WifiPhyListener * >::iterator ListenersI
typedef for a list of WifiPhyListeners iterator
bool IsStateRx(void) const
Check whether the current state is RX.
bool IsStateSwitching(void) const
Check whether the current state is SWITCHING.
void SwitchFromSleep(Time duration)
Switch from sleep mode.
Time GetDelayUntilIdle(void) const
Return the time before the state is back to IDLE.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode...
WifiPreamble GetPreambleType(void) const
Ptr< const Packet > GetPacket(void) const
Get the PSDU as a single packet.
Definition: wifi-psdu.cc:87
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:66
void NotifySleep(void)
Notify all WifiPhyListener that we are going to sleep.
Time m_endSwitching
end switching
#define max(a, b)
Definition: 80211b.c:43
bool IsStateSleep(void) const
Check whether the current state is SLEEP.
void NotifyOn(void)
Notify all WifiPhyListener that we are going to switch on.
receive notifications about PHY events.
void NotifySwitchingStart(Time duration)
Notify all WifiPhyListener that we are switching channel with the given channel switching delay...
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:230
The PHY layer has sense the medium busy through the CCA mechanism.
Time m_previousStateChangeTime
previous state change time
TracedCallback< Ptr< const Packet >, double, WifiMode, WifiPreamble > m_rxOkTrace
receive OK trace callback
void NotifyMaybeCcaBusyStart(Time duration)
Notify all WifiPhyListener that the CCA has started for the given duration.
Time GetLastRxEndTime(void) const
Return the time the last RX end.
RxErrorCallback m_rxErrorCallback
receive error callback
bool IsStateTx(void) const
Check whether the current state is TX.
int64x64_t Abs(const int64x64_t &value)
Absolute value.
Definition: int64x64.h:205
void SwitchToSleep(void)
Switch to sleep mode.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
The PHY layer is IDLE.
WifiPhyState
The state of the PHY layer.
Time m_startSwitching
start switching
void SetReceiveOkCallback(RxOkCallback callback)
Set a callback for a successful reception.
Time m_startTx
start transmit
void NotifyTxStart(Time duration, double txPowerDbm)
Notify all WifiPhyListener that the transmission has started for the given duration.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
void NotifyRxEndOk(void)
Notify all WifiPhyListener that the reception was successful.
void SwitchFromRxEndError(Ptr< WifiPsdu > psdu, double snr)
Switch from RX after the reception failed.
TracedCallback< Ptr< const Packet >, WifiMode, WifiPreamble, uint8_t > m_txTrace
transmit trace callback
static TypeId GetTypeId(void)
Get the type ID.
This objects implements the PHY state machine of the Wifi device.
WifiPhyState GetState(void) const
Return the current state of WifiPhy.
The PHY layer is sending a packet.
void SwitchFromOff(Time duration)
Switch from off mode.
void SwitchToTx(Time txDuration, WifiConstPsduMap psdus, double txPowerDbm, WifiTxVector txVector)
Switch state to TX for the given duration.
Listeners m_listeners
listeners
double snr
SNR in linear scale.
Definition: phy-entity.h:68
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
The PHY layer is receiving a packet.
bool IsStateOff(void) const
Check whether the current state is OFF.
void SetReceiveErrorCallback(RxErrorCallback callback)
Set a callback for a failed reception.
The PHY layer is switched off.
uint8_t GetTxPowerLevel(void) const
TracedCallback< Ptr< const Packet >, double > m_rxErrorTrace
receive error trace callback
The PHY layer is switching to other channel.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
A base class which provides memory management and object aggregation.
Definition: object.h:87
void SwitchToRx(Time rxDuration)
Switch state to RX for the given duration.
void LogPreviousIdleAndCcaBusyStates(void)
Log the ideal and CCA states.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
void NotifyRxStart(Time duration)
Notify all WifiPhyListener that the reception has started for the given duration. ...
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
void RegisterListener(WifiPhyListener *listener)
Register WifiPhyListener to this WifiPhyStateHelper.
void SwitchMaybeToCcaBusy(Time duration)
Switch to CCA busy.
RxOkCallback m_rxOkCallback
receive OK callback
void NotifyOff(void)
Notify all WifiPhyListener that we are going to switch off.
bool IsStateCcaBusy(void) const
Check whether the current state is CCA busy.