20 #include "wifi-phy-state-helper.h"
22 #include "ns3/simulator.h"
23 #include "ns3/trace-source-accessor.h"
29 NS_OBJECT_ENSURE_REGISTERED (WifiPhyStateHelper);
32 WifiPhyStateHelper::GetTypeId (
void)
34 static TypeId tid = TypeId (
"ns3::WifiPhyStateHelper")
36 .AddConstructor<WifiPhyStateHelper> ()
37 .AddTraceSource (
"State",
38 "The state of the PHY layer",
40 .AddTraceSource (
"RxOk",
41 "A packet has been received successfully.",
43 .AddTraceSource (
"RxError",
44 "A packet has been received unsuccessfully.",
46 .AddTraceSource (
"Tx",
"Packet transmission is starting.",
52 WifiPhyStateHelper::WifiPhyStateHelper ()
64 m_previousStateChangeTime (
Seconds (0))
70 WifiPhyStateHelper::SetReceiveOkCallback (WifiPhy::RxOkCallback callback)
72 m_rxOkCallback = callback;
75 WifiPhyStateHelper::SetReceiveErrorCallback (WifiPhy::RxErrorCallback callback)
77 m_rxErrorCallback = callback;
80 WifiPhyStateHelper::RegisterListener (WifiPhyListener *listener)
82 m_listeners.push_back (listener);
86 WifiPhyStateHelper::IsStateIdle (
void)
88 return (GetState () == WifiPhy::IDLE);
91 WifiPhyStateHelper::IsStateBusy (
void)
93 return (GetState () != WifiPhy::IDLE);
96 WifiPhyStateHelper::IsStateCcaBusy (
void)
98 return (GetState () == WifiPhy::CCA_BUSY);
101 WifiPhyStateHelper::IsStateRx (
void)
103 return (GetState () == WifiPhy::RX);
106 WifiPhyStateHelper::IsStateTx (
void)
108 return (GetState () == WifiPhy::TX);
111 WifiPhyStateHelper::IsStateSwitching (
void)
113 return (GetState () == WifiPhy::SWITCHING);
116 WifiPhyStateHelper::IsStateSensing (
void)
118 return (GetState () == WifiPhy::SENSING);
123 WifiPhyStateHelper::GetStateDuration (
void)
125 return Simulator::Now () - m_previousStateChangeTime;
129 WifiPhyStateHelper::GetDelayUntilIdle (
void)
136 retval = m_endRx - Simulator::Now ();
139 retval = m_endTx - Simulator::Now ();
141 case WifiPhy::CCA_BUSY:
142 retval = m_endCcaBusy - Simulator::Now ();
144 case WifiPhy::SWITCHING:
145 retval = m_endSwitching - Simulator::Now ();
147 case WifiPhy::SENSING:
148 retval = m_endSensing - Simulator::Now ();
158 retval = Max (retval, Seconds (0));
163 WifiPhyStateHelper::GetLastRxStartTime (
void)
const
169 WifiPhyStateHelper::GetState (
void)
171 if (m_endTx > Simulator::Now ())
179 else if (m_endSwitching > Simulator::Now ())
181 return WifiPhy::SWITCHING;
183 else if (m_endSensing > Simulator::Now ())
185 return WifiPhy::SENSING;
187 else if (m_endCcaBusy > Simulator::Now ())
189 return WifiPhy::CCA_BUSY;
193 return WifiPhy::IDLE;
199 WifiPhyStateHelper::NotifyTxStart (Time duration)
201 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
203 (*i)->NotifyTxStart (duration);
207 WifiPhyStateHelper::NotifyRxStart (Time duration)
209 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
211 (*i)->NotifyRxStart (duration);
215 WifiPhyStateHelper::NotifyRxEndOk (
void)
217 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
219 (*i)->NotifyRxEndOk ();
223 WifiPhyStateHelper::NotifyRxEndError (
void)
225 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
227 (*i)->NotifyRxEndError ();
231 WifiPhyStateHelper::NotifyMaybeCcaBusyStart (Time duration)
233 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
235 (*i)->NotifyMaybeCcaBusyStart (duration);
239 WifiPhyStateHelper::NotifySwitchingStart (Time duration, uint16_t toChannel)
241 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
243 (*i)->NotifySwitchingStart (duration, toChannel);
247 WifiPhyStateHelper::NotifySensingStart (Time duration)
249 for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
251 (*i)->NotifySensingStart (duration);
256 WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates (
void)
258 Time now = Simulator::Now ();
259 Time idleStart = Max (m_endCcaBusy, m_endRx);
260 idleStart = Max (idleStart, m_endTx);
261 idleStart = Max (idleStart, m_endSwitching);
262 idleStart = Max (idleStart, m_endSensing);
264 if (m_endCcaBusy > m_endRx
265 && m_endCcaBusy > m_endSwitching
266 && m_endCcaBusy > m_endTx
267 && m_endCcaBusy > m_endSensing)
269 Time ccaBusyStart = Max (m_endTx, m_endRx);
270 ccaBusyStart = Max (ccaBusyStart, m_startCcaBusy);
271 ccaBusyStart = Max (ccaBusyStart, m_endSwitching);
272 ccaBusyStart = Max (ccaBusyStart, m_endSensing);
273 m_stateLogger (ccaBusyStart, idleStart - ccaBusyStart, WifiPhy::CCA_BUSY);
275 m_stateLogger (idleStart, now - idleStart, WifiPhy::IDLE);
279 WifiPhyStateHelper::SwitchToTx (Time txDuration, Ptr<const Packet> packet, WifiMode txMode,
282 m_txTrace (packet, txMode, preamble, txPower);
283 NotifyTxStart (txDuration);
284 Time now = Simulator::Now ();
292 m_stateLogger (m_startRx, now - m_startRx, WifiPhy::RX);
295 case WifiPhy::CCA_BUSY:
297 Time ccaStart = Max (m_endRx, m_endTx);
298 ccaStart = Max (ccaStart, m_startCcaBusy);
299 ccaStart = Max (ccaStart, m_endSwitching);
300 ccaStart = Max (ccaStart, m_endSensing);
301 m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
304 LogPreviousIdleAndCcaBusyStates ();
306 case WifiPhy::SWITCHING:
311 m_stateLogger (now, txDuration, WifiPhy::TX);
312 m_previousStateChangeTime = now;
313 m_endTx = now + txDuration;
317 WifiPhyStateHelper::SwitchToRx (Time rxDuration)
319 NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
321 NotifyRxStart (rxDuration);
322 Time now = Simulator::Now ();
326 LogPreviousIdleAndCcaBusyStates ();
328 case WifiPhy::CCA_BUSY:
330 Time ccaStart = Max (m_endRx, m_endTx);
331 ccaStart = Max (ccaStart, m_startCcaBusy);
332 ccaStart = Max (ccaStart, m_endSwitching);
333 ccaStart = Max (ccaStart, m_endSensing);
334 m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
336 case WifiPhy::SWITCHING:
337 case WifiPhy::SENSING:
343 m_previousStateChangeTime = now;
346 m_endRx = now + rxDuration;
351 WifiPhyStateHelper::SwitchToChannelSwitching (Time switchingDuration, uint16_t toChannel)
353 NotifySwitchingStart (switchingDuration, toChannel);
354 Time now = Simulator::Now ();
362 m_stateLogger (m_startRx, now - m_startRx, WifiPhy::RX);
365 case WifiPhy::CCA_BUSY:
367 Time ccaStart = Max (m_endRx, m_endTx);
368 ccaStart = Max (ccaStart, m_startCcaBusy);
369 ccaStart = Max (ccaStart, m_endSwitching);
370 ccaStart = Max (ccaStart, m_endSensing);
371 m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
374 LogPreviousIdleAndCcaBusyStates ();
377 case WifiPhy::SWITCHING:
383 if (now < m_endCcaBusy)
388 m_stateLogger (now, switchingDuration, WifiPhy::SWITCHING);
389 m_previousStateChangeTime = now;
390 m_startSwitching = now;
391 m_endSwitching = now + switchingDuration;
396 WifiPhyStateHelper::SwitchToChannelSensing (Time sensingDuration)
398 NotifySensingStart (sensingDuration);
399 Time now = Simulator::Now ();
407 m_stateLogger (m_startRx, now - m_startRx, WifiPhy::RX);
410 case WifiPhy::CCA_BUSY:
412 Time ccaStart = Max (m_endRx, m_endTx);
413 ccaStart = Max (ccaStart, m_startCcaBusy);
414 ccaStart = Max (ccaStart, m_endSwitching);
415 ccaStart = Max (ccaStart, m_endSensing);
416 m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
419 LogPreviousIdleAndCcaBusyStates ();
422 case WifiPhy::SWITCHING:
423 case WifiPhy::SENSING:
429 if (now < m_endCcaBusy)
434 m_stateLogger (now, sensingDuration, WifiPhy::SENSING);
435 m_previousStateChangeTime = now;
436 m_startSensing = now;
437 m_endSensing = now + sensingDuration;
442 WifiPhyStateHelper::SwitchFromRxEndOk (Ptr<Packet> packet,
double snr, WifiMode mode,
enum WifiPreamble preamble)
444 m_rxOkTrace (packet, snr, mode, preamble);
447 if (!m_rxOkCallback.IsNull ())
449 m_rxOkCallback (packet, snr, mode, preamble);
454 WifiPhyStateHelper::SwitchFromRxEndError (Ptr<const Packet> packet,
double snr)
456 m_rxErrorTrace (packet, snr);
459 if (!m_rxErrorCallback.IsNull ())
461 m_rxErrorCallback (packet, snr);
466 WifiPhyStateHelper::DoSwitchFromRx (
void)
471 Time now = Simulator::Now ();
472 m_stateLogger (m_startRx, now - m_startRx, WifiPhy::RX);
473 m_previousStateChangeTime = now;
476 NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
479 WifiPhyStateHelper::SwitchMaybeToCcaBusy (Time duration)
481 NotifyMaybeCcaBusyStart (duration);
482 Time now = Simulator::Now ();
485 case WifiPhy::SWITCHING:
486 case WifiPhy::SENSING:
489 LogPreviousIdleAndCcaBusyStates ();
491 case WifiPhy::CCA_BUSY:
498 m_startCcaBusy = now;
499 m_endCcaBusy = std::max (m_endCcaBusy, now + duration);
#define NS_LOG_FUNCTION(parameters)
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
#define NS_FATAL_ERROR(msg)
fatal error handling
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.