A Discrete-Event Network Simulator
API
channel-access-manager.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 "ns3/log.h"
22#include "ns3/simulator.h"
24#include "txop.h"
25#include "wifi-phy-listener.h"
26#include "wifi-phy.h"
28
29namespace ns3 {
30
31NS_LOG_COMPONENT_DEFINE ("ChannelAccessManager");
32
37{
38public:
45 : m_cam (cam)
46 {
47 }
48 virtual ~PhyListener ()
49 {
50 }
51 void NotifyRxStart (Time duration)
52 {
53 m_cam->NotifyRxStartNow (duration);
54 }
55 void NotifyRxEndOk (void)
56 {
58 }
59 void NotifyRxEndError (void)
60 {
62 }
63 void NotifyTxStart (Time duration, double txPowerDbm)
64 {
65 m_cam->NotifyTxStartNow (duration);
66 }
68 {
70 }
71 void NotifySwitchingStart (Time duration)
72 {
74 }
75 void NotifySleep (void)
76 {
78 }
79 void NotifyOff (void)
80 {
82 }
83 void NotifyWakeup (void)
84 {
86 }
87 void NotifyOn (void)
88 {
90 }
91
92private:
94};
95
96
97/****************************************************************
98 * Implement the channel access manager of all Txop holders
99 ****************************************************************/
100
102 : m_lastAckTimeoutEnd (MicroSeconds (0)),
103 m_lastCtsTimeoutEnd (MicroSeconds (0)),
104 m_lastNavStart (MicroSeconds (0)),
105 m_lastNavDuration (MicroSeconds (0)),
106 m_lastRxStart (MicroSeconds (0)),
107 m_lastRxDuration (MicroSeconds (0)),
108 m_lastRxReceivedOk (true),
109 m_lastTxStart (MicroSeconds (0)),
110 m_lastTxDuration (MicroSeconds (0)),
111 m_lastBusyStart (MicroSeconds (0)),
112 m_lastBusyDuration (MicroSeconds (0)),
113 m_lastSwitchingStart (MicroSeconds (0)),
114 m_lastSwitchingDuration (MicroSeconds (0)),
115 m_sleeping (false),
116 m_off (false),
117 m_phyListener (0)
118{
119 NS_LOG_FUNCTION (this);
120}
121
123{
124 NS_LOG_FUNCTION (this);
125 delete m_phyListener;
126 m_phyListener = 0;
127}
128
129void
131{
132 NS_LOG_FUNCTION (this);
133 for (Ptr<Txop> i : m_txops)
134 {
135 i->Dispose ();
136 i = 0;
137 }
138 m_phy = 0;
139 m_feManager = 0;
140}
141
142void
144{
145 NS_LOG_FUNCTION (this << phy);
147 m_phyListener = new PhyListener (this);
148 phy->RegisterListener (m_phyListener);
149 m_phy = phy;
150}
151
152void
154{
155 NS_LOG_FUNCTION (this << phy);
156 if (m_phyListener != 0)
157 {
158 phy->UnregisterListener (m_phyListener);
159 delete m_phyListener;
160 m_phyListener = 0;
161 m_phy = 0;
162 }
163}
164
165void
167{
168 NS_LOG_FUNCTION (this << feManager);
169 m_feManager = feManager;
170 m_feManager->SetChannelAccessManager (this);
171}
172
173Time
175{
176 return m_phy->GetSlot ();
177}
178
179Time
181{
182 return m_phy->GetSifs ();
183}
184
185Time
187{
188 return m_phy->GetSifs () + m_phy->GetAckTxTime ();
189}
190
191void
193{
194 NS_LOG_FUNCTION (this << txop);
195 m_txops.push_back (txop);
196}
197
198Time
199ChannelAccessManager::MostRecent (std::initializer_list<Time> list) const
200{
201 NS_ASSERT (list.size () > 0);
202 return *std::max_element (list.begin (), list.end ());
203}
204
205bool
207{
208 NS_LOG_FUNCTION (this);
209 // PHY busy
210 Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
211 if (lastRxEnd > Simulator::Now ())
212 {
213 return true;
214 }
215 Time lastTxEnd = m_lastTxStart + m_lastTxDuration;
216 if (lastTxEnd > Simulator::Now ())
217 {
218 return true;
219 }
220 // NAV busy
222 if (lastNavEnd > Simulator::Now ())
223 {
224 return true;
225 }
226 // CCA busy
227 Time lastCCABusyEnd = m_lastBusyStart + m_lastBusyDuration;
228 if (lastCCABusyEnd > Simulator::Now ())
229 {
230 return true;
231 }
232 return false;
233}
234
235bool
237{
238 NS_LOG_FUNCTION (this << txop);
239
240 // No backoff needed if in sleep mode or off
241 if (m_sleeping || m_off)
242 {
243 return false;
244 }
245
246 // the Txop might have a stale value of remaining backoff slots
247 UpdateBackoff ();
248
249 /*
250 * From section 10.3.4.2 "Basic access" of IEEE 802.11-2016:
251 *
252 * A STA may transmit an MPDU when it is operating under the DCF access
253 * method, either in the absence of a PC, or in the CP of the PCF access
254 * method, when the STA determines that the medium is idle when a frame is
255 * queued for transmission, and remains idle for a period of a DIFS, or an
256 * EIFS (10.3.2.3.7) from the end of the immediately preceding medium-busy
257 * event, whichever is the greater, and the backoff timer is zero. Otherwise
258 * the random backoff procedure described in 10.3.4.3 shall be followed.
259 *
260 * From section 10.22.2.2 "EDCA backoff procedure" of IEEE 802.11-2016:
261 *
262 * The backoff procedure shall be invoked by an EDCAF when any of the following
263 * events occurs:
264 * a) An MA-UNITDATA.request primitive is received that causes a frame with that AC
265 * to be queued for transmission such that one of the transmit queues associated
266 * with that AC has now become non-empty and any other transmit queues
267 * associated with that AC are empty; the medium is busy on the primary channel
268 */
269 if (!txop->HasFramesToTransmit () && txop->GetAccessStatus () != Txop::GRANTED
270 && txop->GetBackoffSlots () == 0)
271 {
272 if (!IsBusy ())
273 {
274 // medium idle. If this is a DCF, use immediate access (we can transmit
275 // in a DIFS if the medium remains idle). If this is an EDCAF, update
276 // the backoff start time kept by the EDCAF to the current time in order
277 // to correctly align the backoff start time at the next slot boundary
278 // (performed by the next call to ChannelAccessManager::RequestAccess())
279 Time delay = (txop->IsQosTxop () ? Seconds (0)
280 : GetSifs () + txop->GetAifsn () * GetSlot ());
281 txop->UpdateBackoffSlotsNow (0, Simulator::Now () + delay);
282 }
283 else
284 {
285 // medium busy, backoff is needed
286 return true;
287 }
288 }
289 return false;
290}
291
292void
294{
295 NS_LOG_FUNCTION (this << txop);
296 if (m_phy)
297 {
299 }
300 //Deny access if in sleep mode or off
301 if (m_sleeping || m_off)
302 {
303 return;
304 }
305 /*
306 * EDCAF operations shall be performed at slot boundaries (Sec. 10.22.2.4 of 802.11-2016)
307 */
308 Time accessGrantStart = GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ());
309
310 if (txop->IsQosTxop () && txop->GetBackoffStart () > accessGrantStart)
311 {
312 // The backoff start time reported by the EDCAF is more recent than the last
313 // time the medium was busy plus an AIFS, hence we need to align it to the
314 // next slot boundary.
315 Time diff = txop->GetBackoffStart () - accessGrantStart;
316 uint32_t nIntSlots = (diff / GetSlot ()).GetHigh () + 1;
317 txop->UpdateBackoffSlotsNow (0, accessGrantStart + (nIntSlots * GetSlot ()));
318 }
319
320 UpdateBackoff ();
322 txop->NotifyAccessRequested ();
325}
326
327void
329{
330 NS_LOG_FUNCTION (this);
331 uint32_t k = 0;
332 for (Txops::iterator i = m_txops.begin (); i != m_txops.end (); k++)
333 {
334 Ptr<Txop> txop = *i;
335 if (txop->GetAccessStatus () == Txop::REQUESTED
336 && (!txop->IsQosTxop () || !StaticCast<QosTxop> (txop)->EdcaDisabled ())
337 && GetBackoffEndFor (txop) <= Simulator::Now () )
338 {
343 NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << txop->GetBackoffSlots ());
344 i++; //go to the next item in the list.
345 k++;
346 std::vector<Ptr<Txop> > internalCollisionTxops;
347 for (Txops::iterator j = i; j != m_txops.end (); j++, k++)
348 {
349 Ptr<Txop> otherTxop = *j;
350 if (otherTxop->GetAccessStatus () == Txop::REQUESTED
351 && GetBackoffEndFor (otherTxop) <= Simulator::Now ())
352 {
353 NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
354 otherTxop->GetBackoffSlots ());
360 internalCollisionTxops.push_back (otherTxop);
361 }
362 }
363
372 NS_ASSERT (m_feManager != 0);
373
374 if (m_feManager->StartTransmission (txop))
375 {
376 for (auto& collidingTxop : internalCollisionTxops)
377 {
378 m_feManager->NotifyInternalCollision (collidingTxop);
379 }
380 break;
381 }
382 else
383 {
384 // reset the current state to the EDCAF that won the contention
385 // but did not transmit anything
386 i--;
387 k = std::distance (m_txops.begin (), i);
388 }
389 }
390 i++;
391 }
392}
393
394void
396{
397 NS_LOG_FUNCTION (this);
398 UpdateBackoff ();
401}
402
403Time
405{
406 NS_LOG_FUNCTION (this);
407 Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
408 const Time& sifs = GetSifs();
409 Time rxAccessStart = lastRxEnd + sifs;
410 if ((lastRxEnd <= Simulator::Now ()) && !m_lastRxReceivedOk)
411 {
412 rxAccessStart += GetEifsNoDifs ();
413 }
414 Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + sifs;
415 Time txAccessStart = m_lastTxStart + m_lastTxDuration + sifs;
416 Time navAccessStart = m_lastNavStart + m_lastNavDuration + sifs;
417 Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + sifs;
418 Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + sifs;
419 Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + sifs;
420 Time accessGrantedStart;
421 if (ignoreNav)
422 {
423 accessGrantedStart = MostRecent ({rxAccessStart,
424 busyAccessStart,
425 txAccessStart,
426 ackTimeoutAccessStart,
427 ctsTimeoutAccessStart,
428 switchingAccessStart}
429 );
430 }
431 else
432 {
433 accessGrantedStart = MostRecent ({rxAccessStart,
434 busyAccessStart,
435 txAccessStart,
436 navAccessStart,
437 ackTimeoutAccessStart,
438 ctsTimeoutAccessStart,
439 switchingAccessStart}
440 );
441 }
442 NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
443 ", rx access start=" << rxAccessStart <<
444 ", busy access start=" << busyAccessStart <<
445 ", tx access start=" << txAccessStart <<
446 ", nav access start=" << navAccessStart);
447 return accessGrantedStart;
448}
449
450Time
452{
453 NS_LOG_FUNCTION (this << txop);
454 Time mostRecentEvent = MostRecent ({txop->GetBackoffStart (),
455 GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ())});
456 NS_LOG_DEBUG ("Backoff start: " << mostRecentEvent.As (Time::US));
457
458 return mostRecentEvent;
459}
460
461Time
463{
464 NS_LOG_FUNCTION (this << txop);
465 Time backoffEnd = GetBackoffStartFor (txop) + (txop->GetBackoffSlots () * GetSlot ());
466 NS_LOG_DEBUG ("Backoff end: " << backoffEnd.As (Time::US));
467
468 return backoffEnd;
469}
470
471void
473{
474 NS_LOG_FUNCTION (this);
475 uint32_t k = 0;
476 for (auto txop : m_txops)
477 {
478 Time backoffStart = GetBackoffStartFor (txop);
479 if (backoffStart <= Simulator::Now ())
480 {
481 uint32_t nIntSlots = ((Simulator::Now () - backoffStart) / GetSlot ()).GetHigh ();
482 /*
483 * EDCA behaves slightly different to DCA. For EDCA we
484 * decrement once at the slot boundary at the end of AIFS as
485 * well as once at the end of each clear slot
486 * thereafter. For DCA we only decrement at the end of each
487 * clear slot after DIFS. We account for the extra backoff
488 * by incrementing the slot count here in the case of
489 * EDCA. The if statement whose body we are in has confirmed
490 * that a minimum of AIFS has elapsed since last busy
491 * medium.
492 */
493 if (txop->IsQosTxop ())
494 {
495 nIntSlots++;
496 }
497 uint32_t n = std::min (nIntSlots, txop->GetBackoffSlots ());
498 NS_LOG_DEBUG ("dcf " << k << " dec backoff slots=" << n);
499 Time backoffUpdateBound = backoffStart + (n * GetSlot ());
500 txop->UpdateBackoffSlotsNow (n, backoffUpdateBound);
501 }
502 ++k;
503 }
504}
505
506void
508{
509 NS_LOG_FUNCTION (this);
514 bool accessTimeoutNeeded = false;
515 Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
516 for (auto txop : m_txops)
517 {
518 if (txop->GetAccessStatus () == Txop::REQUESTED)
519 {
520 Time tmp = GetBackoffEndFor (txop);
521 if (tmp > Simulator::Now ())
522 {
523 accessTimeoutNeeded = true;
524 expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
525 }
526 }
527 }
528 NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded);
529 if (accessTimeoutNeeded)
530 {
531 NS_LOG_DEBUG ("expected backoff end=" << expectedBackoffEnd);
532 Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now ();
534 && Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay)
535 {
537 }
539 {
540 m_accessTimeout = Simulator::Schedule (expectedBackoffDelay,
542 }
543 }
544}
545
546void
548{
549 NS_LOG_FUNCTION (this << qosTxop << duration);
550 NS_ASSERT (qosTxop->IsQosTxop ());
551 UpdateBackoff ();
552 Time resume = Simulator::Now () + duration;
553 NS_LOG_DEBUG ("Backoff will resume at time " << resume << " with "
554 << qosTxop->GetBackoffSlots () << " remaining slot(s)");
555 qosTxop->UpdateBackoffSlotsNow (0, resume);
557}
558
559void
561{
562 NS_LOG_FUNCTION (this << duration);
563 NS_LOG_DEBUG ("rx start for=" << duration);
564 UpdateBackoff ();
566 m_lastRxDuration = duration;
567 m_lastRxReceivedOk = true;
568}
569
570void
572{
573 NS_LOG_FUNCTION (this);
574 NS_LOG_DEBUG ("rx end ok");
576 m_lastRxReceivedOk = true;
577}
578
579void
581{
582 NS_LOG_FUNCTION (this);
583 NS_LOG_DEBUG ("rx end error");
584 Time now = Simulator::Now ();
585 Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
586 if (lastRxEnd > now)
587 {
588 m_lastBusyStart = now;
590 }
592 m_lastRxReceivedOk = false;
593}
594
595void
597{
598 NS_LOG_FUNCTION (this << duration);
599 m_lastRxReceivedOk = true;
600 Time now = Simulator::Now ();
601 Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
602 if (lastRxEnd > now)
603 {
604 //this may be caused only if PHY has started to receive a packet
605 //inside SIFS, so, we check that lastRxStart was maximum a SIFS ago
606 NS_ASSERT (now - m_lastRxStart <= GetSifs ());
608 }
609 NS_LOG_DEBUG ("tx start for " << duration);
610 UpdateBackoff ();
611 m_lastTxStart = now;
612 m_lastTxDuration = duration;
613}
614
615void
617{
618 NS_LOG_FUNCTION (this << duration);
619 NS_LOG_DEBUG ("busy start for " << duration);
620 UpdateBackoff ();
622 m_lastBusyDuration = duration;
623}
624
625void
627{
628 NS_LOG_FUNCTION (this << duration);
629 Time now = Simulator::Now ();
632
633 m_lastRxReceivedOk = true;
634
636 {
637 //channel switching during packet reception
639 }
641 {
643 }
645 {
647 }
648 if (m_lastAckTimeoutEnd > now)
649 {
651 }
652 if (m_lastCtsTimeoutEnd > now)
653 {
655 }
656
657 //Cancel timeout
659 {
661 }
662
663 // Notify the FEM, which will in turn notify the MAC
664 m_feManager->NotifySwitchingStartNow (duration);
665
666 //Reset backoffs
667 for (auto txop : m_txops)
668 {
669 uint32_t remainingSlots = txop->GetBackoffSlots ();
670 if (remainingSlots > 0)
671 {
672 txop->UpdateBackoffSlotsNow (remainingSlots, now);
673 NS_ASSERT (txop->GetBackoffSlots () == 0);
674 }
675 txop->ResetCw ();
676 txop->m_access = Txop::NOT_REQUESTED;
677 }
678
679 NS_LOG_DEBUG ("switching start for " << duration);
681 m_lastSwitchingDuration = duration;
682}
683
684void
686{
687 NS_LOG_FUNCTION (this);
688 m_sleeping = true;
689 //Cancel timeout
691 {
693 }
694
695 //Reset backoffs
696 for (auto txop : m_txops)
697 {
698 txop->NotifySleep ();
699 }
700}
701
702void
704{
705 NS_LOG_FUNCTION (this);
706 m_off = true;
707 //Cancel timeout
709 {
711 }
712
713 //Reset backoffs
714 for (auto txop : m_txops)
715 {
716 txop->NotifyOff ();
717 }
718}
719
720void
722{
723 NS_LOG_FUNCTION (this);
724 m_sleeping = false;
725 for (auto txop : m_txops)
726 {
727 uint32_t remainingSlots = txop->GetBackoffSlots ();
728 if (remainingSlots > 0)
729 {
730 txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
731 NS_ASSERT (txop->GetBackoffSlots () == 0);
732 }
733 txop->ResetCw ();
734 txop->m_access = Txop::NOT_REQUESTED;
735 txop->NotifyWakeUp ();
736 }
737}
738
739void
741{
742 NS_LOG_FUNCTION (this);
743 m_off = false;
744 for (auto txop : m_txops)
745 {
746 uint32_t remainingSlots = txop->GetBackoffSlots ();
747 if (remainingSlots > 0)
748 {
749 txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
750 NS_ASSERT (txop->GetBackoffSlots () == 0);
751 }
752 txop->ResetCw ();
753 txop->m_access = Txop::NOT_REQUESTED;
754 txop->NotifyOn ();
755 }
756}
757
758void
760{
761 NS_LOG_FUNCTION (this << duration);
762 NS_LOG_DEBUG ("nav reset for=" << duration);
763 UpdateBackoff ();
765 m_lastNavDuration = duration;
773}
774
775void
777{
778 NS_LOG_FUNCTION (this << duration);
780 NS_LOG_DEBUG ("nav start for=" << duration);
781 UpdateBackoff ();
782 Time newNavEnd = Simulator::Now () + duration;
784 if (newNavEnd > lastNavEnd)
785 {
787 m_lastNavDuration = duration;
788 }
789}
790
791void
793{
794 NS_LOG_FUNCTION (this << duration);
796 m_lastAckTimeoutEnd = Simulator::Now () + duration;
797}
798
799void
801{
802 NS_LOG_FUNCTION (this);
805}
806
807void
809{
810 NS_LOG_FUNCTION (this << duration);
811 m_lastCtsTimeoutEnd = Simulator::Now () + duration;
812}
813
814void
816{
817 NS_LOG_FUNCTION (this);
820}
821
822} //namespace ns3
#define min(a, b)
Definition: 80211b.c:42
Manage a set of ns3::Txop.
Time MostRecent(std::initializer_list< Time > list) const
Return the most recent time.
void AccessTimeout(void)
Called when access timeout should occur (e.g.
bool m_off
flag whether it is in off state
void NotifyRxStartNow(Time duration)
void UpdateBackoff(void)
Update backoff slots for all Txops.
Time m_lastRxStart
the last receive start time
Time GetBackoffEndFor(Ptr< Txop > txop)
Return the time when the backoff procedure ended (or will ended) for the given Txop.
void DoDispose(void) override
Destructor implementation.
bool m_lastRxReceivedOk
the last receive OK
void NotifyCtsTimeoutResetNow(void)
Notify that CTS timer has reset.
void NotifyOnNow(void)
Notify the Txop that the device has been resumed from off mode.
Ptr< WifiPhy > m_phy
pointer to the PHY
void NotifyTxStartNow(Time duration)
Time m_lastRxDuration
the last receive duration time
Time m_lastSwitchingDuration
the last switching duration time
Time m_lastSwitchingStart
the last switching start time
Time m_lastAckTimeoutEnd
the last Ack timeout end time
void NotifyAckTimeoutStartNow(Time duration)
Notify that ack timer has started for the given duration.
bool m_sleeping
flag whether it is in sleeping state
void NotifyRxEndOkNow(void)
Notify the Txop that a packet reception was just completed successfully.
void SetupFrameExchangeManager(Ptr< FrameExchangeManager > feManager)
Set up the Frame Exchange Manager.
void NotifyCtsTimeoutStartNow(Time duration)
Notify that CTS timer has started for the given duration.
void RequestAccess(Ptr< Txop > txop)
Time m_lastTxStart
the last transmit start time
bool IsBusy(void) const
Check if the device is busy sending or receiving, or NAV or CCA busy.
void NotifyMaybeCcaBusyStartNow(Time duration)
void RemovePhyListener(Ptr< WifiPhy > phy)
Remove current registered listener for PHY events.
void NotifySleepNow(void)
Notify the Txop that the device has been put in sleep mode.
void SetupPhyListener(Ptr< WifiPhy > phy)
Set up listener for PHY events.
Time m_lastCtsTimeoutEnd
the last CTS timeout end time
void NotifyWakeupNow(void)
Notify the Txop that the device has been resumed from sleep mode.
Ptr< FrameExchangeManager > m_feManager
pointer to the Frame Exchange Manager
void NotifyOffNow(void)
Notify the Txop that the device has been put in off mode.
Time m_lastBusyStart
the last busy start time
Time m_lastNavDuration
the last NAV duration time
PhyListener * m_phyListener
the PHY listener
virtual Time GetSlot(void) const
Return the slot duration for this PHY.
void NotifySwitchingStartNow(Time duration)
void DisableEdcaFor(Ptr< Txop > qosTxop, Time duration)
void DoGrantDcfAccess(void)
Grant access to Txop using DCF/EDCF contention rules.
Txops m_txops
the vector of managed Txops
Time m_lastTxDuration
the last transmit duration time
virtual Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Time m_lastBusyDuration
the last busy duration time
void NotifyAckTimeoutResetNow(void)
Notify that ack timer has reset.
void NotifyNavResetNow(Time duration)
Time GetAccessGrantStart(bool ignoreNav=false) const
Access will never be granted to the medium before the time returned by this method.
bool NeedBackoffUponAccess(Ptr< Txop > txop)
Determine if a new backoff needs to be generated when a packet is queued for transmission.
virtual Time GetEifsNoDifs(void) const
Return the EIFS duration minus a DIFS.
Time GetBackoffStartFor(Ptr< Txop > txop)
Return the time when the backoff procedure started for the given Txop.
Time m_lastNavStart
the last NAV start time
void NotifyNavStartNow(Time duration)
EventId m_accessTimeout
the access timeout ID
void NotifyRxEndErrorNow(void)
Notify the Txop that a packet reception was just completed unsuccessfully.
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
Listener for PHY events.
void NotifySwitchingStart(Time duration)
void NotifyRxEndError(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void NotifyOn(void)
Notify listeners that we went to switch on.
PhyListener(ns3::ChannelAccessManager *cam)
Create a PhyListener for the given ChannelAccessManager.
ns3::ChannelAccessManager * m_cam
ChannelAccessManager to forward events to.
void NotifyRxEndOk(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void NotifyWakeup(void)
Notify listeners that we woke up.
void NotifyMaybeCcaBusyStart(Time duration)
void NotifyOff(void)
Notify listeners that we went to switch off.
void NotifyTxStart(Time duration, double txPowerDbm)
void NotifySleep(void)
Notify listeners that we went to sleep.
void NotifyRxStart(Time duration)
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:293
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:204
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ US
microsecond
Definition: nstime.h:116
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:432
virtual ChannelAccessStatus GetAccessStatus(void) const
Definition: txop.cc:335
@ GRANTED
Definition: txop.h:96
@ NOT_REQUESTED
Definition: txop.h:94
@ REQUESTED
Definition: txop.h:95
virtual void NotifyAccessRequested(void)
Notify that access request has been received.
Definition: txop.cc:341
virtual bool IsQosTxop() const
Check for QoS TXOP.
Definition: txop.cc:412
void UpdateBackoffSlotsNow(uint32_t nSlots, Time backoffUpdateBound)
Update backoff slots that nSlots has passed.
Definition: txop.cc:222
Time GetBackoffStart(void) const
Return the time when the backoff procedure started.
Definition: txop.cc:216
uint32_t GetBackoffSlots(void) const
Return the current number of backoff slots.
Definition: txop.cc:210
virtual bool HasFramesToTransmit(void)
Check if the Txop has frames to transmit.
Definition: txop.cc:286
virtual uint8_t GetAifsn(void) const
Return the number of slots that make up an AIFS.
Definition: txop.cc:274
Time GetSlot(void) const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:671
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:1655
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:659
Time GetAckTxTime(void) const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:689
receive notifications about PHY events.
#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
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#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:281
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Every class exported by the ns3 library is enclosed in the ns3 namespace.
phy
Definition: third.py:93
#define list