A Discrete-Event Network Simulator
API
qos-frame-exchange-manager.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
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: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/abort.h"
24 #include "wifi-mac-queue.h"
25 #include "channel-access-manager.h"
26 #include "wifi-mac-trailer.h"
27 #include "ap-wifi-mac.h"
29 #include "wifi-ack-manager.h"
30 
31 #undef NS_LOG_APPEND_CONTEXT
32 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
33 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("QosFrameExchangeManager");
37 
38 NS_OBJECT_ENSURE_REGISTERED (QosFrameExchangeManager);
39 
40 TypeId
42 {
43  static TypeId tid = TypeId ("ns3::QosFrameExchangeManager")
45  .AddConstructor<QosFrameExchangeManager> ()
46  .SetGroupName ("Wifi")
47  .AddAttribute ("PifsRecovery",
48  "Perform a PIFS recovery as a response to transmission failure "
49  "within a TXOP",
50  BooleanValue (true),
53  ;
54  return tid;
55 }
56 
58  : m_initialFrame (false)
59 {
60  NS_LOG_FUNCTION (this);
61 }
62 
64 {
66 }
67 
68 void
70 {
71  NS_LOG_FUNCTION (this);
72  m_edca = 0;
73  m_edcaBackingOff = 0;
76 }
77 
78 bool
80 {
81  NS_LOG_FUNCTION (this);
82  NS_ASSERT (m_edca != 0);
84 
85  WifiMacHeader cfEnd;
86  cfEnd.SetType (WIFI_MAC_CTL_END);
87  cfEnd.SetDsNotFrom ();
88  cfEnd.SetDsNotTo ();
89  cfEnd.SetNoRetry ();
90  cfEnd.SetNoMoreFragments ();
91  cfEnd.SetDuration (Seconds (0));
92  cfEnd.SetAddr1 (Mac48Address::GetBroadcast ());
93  cfEnd.SetAddr2 (m_self);
94 
95  WifiTxVector cfEndTxVector = m_mac->GetWifiRemoteStationManager ()->GetRtsTxVector (cfEnd.GetAddr1 ());
96 
97  Time txDuration = m_phy->CalculateTxDuration (cfEnd.GetSize () + WIFI_MAC_FCS_LENGTH,
98  cfEndTxVector, m_phy->GetPhyBand ());
99 
100  // Send the CF-End frame if the remaining duration is long enough to transmit this frame
101  if (m_edca->GetRemainingTxop () > txDuration)
102  {
103  NS_LOG_DEBUG ("Send CF-End frame");
104  m_phy->Send (Create<WifiPsdu> (Create<Packet> (), cfEnd), cfEndTxVector);
106  return true;
107  }
108 
110  m_edca = 0;
111  return false;
112 }
113 
114 void
116 {
117  NS_LOG_FUNCTION (this);
118  NS_ASSERT (m_edca != 0);
120 
121  // Release the channel if it has not been idle for the last PIFS interval
122  if (m_channelAccessManager->GetAccessGrantStart () - m_phy->GetSifs ()
123  > Simulator::Now () - m_phy->GetPifs ())
124  {
126  m_edca = 0;
127  }
128  else
129  {
130  // the txopDuration parameter is unused because we are not starting a new TXOP
132  }
133 }
134 
135 void
137 {
138  NS_LOG_FUNCTION (this);
140  NS_ASSERT (m_edca != 0);
141 
142  NS_LOG_DEBUG ("Cancel PIFS recovery being attempted by EDCAF " << m_edca);
145 }
146 
147 bool
149 {
150  NS_LOG_FUNCTION (this << edca);
151 
153  {
154  // Another AC (having AIFS=1 or lower, if the user changed the default settings)
155  // gained channel access while performing PIFS recovery. Abort PIFS recovery
157  }
158 
159  // TODO This will become an assert once no Txop is installed on a QoS station
160  if (!edca->IsQosTxop ())
161  {
162  m_edca = 0;
164  }
165 
166  Ptr<QosTxop> qosTxop = StaticCast<QosTxop> (edca);
167  return StartTransmission (qosTxop, qosTxop->GetTxopLimit ());
168 }
169 
170 bool
172 {
173  NS_LOG_FUNCTION (this << edca << txopDuration);
174 
176  {
177  // Another AC (having AIFS=1 or lower, if the user changed the default settings)
178  // gained channel access while performing PIFS recovery. Abort PIFS recovery
180  }
181 
182  if (m_txTimer.IsRunning ())
183  {
184  m_txTimer.Cancel ();
185  }
186  m_dcf = edca;
187  m_edca = edca;
188 
189  // We check if this EDCAF invoked the backoff procedure (without terminating
190  // the TXOP) because the transmission of a non-initial frame of a TXOP failed
191  bool backingOff = (m_edcaBackingOff == m_edca);
192 
193  if (backingOff)
194  {
199 
200  // clear the member variable
201  m_edcaBackingOff = 0;
202  }
203 
205  {
206  // TXOP limit is not null. We have to check if this EDCAF is starting a
207  // new TXOP. This includes the case when the transmission of a non-initial
208  // frame of a TXOP failed and backoff was invoked without terminating the
209  // TXOP. In such a case, we assume that a new TXOP is being started if it
210  // elapsed more than TXOPlimit since the start of the paused TXOP. Note
211  // that GetRemainingTxop returns 0 iff Now - TXOPstart >= TXOPlimit
212  if (!m_edca->IsTxopStarted ()
213  || (backingOff && m_edca->GetRemainingTxop ().IsZero ()))
214  {
215  // starting a new TXOP
216  m_edca->NotifyChannelAccessed (txopDuration);
217 
218  if (StartFrameExchange (m_edca, txopDuration, true))
219  {
220  m_initialFrame = true;
221  return true;
222  }
223 
224  // TXOP not even started, return false
225  NS_LOG_DEBUG ("No frame transmitted");
227  m_edca = 0;
228  return false;
229  }
230 
231  // We are continuing a TXOP, check if we can transmit another frame
233 
235  {
236  NS_LOG_DEBUG ("Not enough remaining TXOP time");
237  return SendCfEndIfNeeded ();
238  }
239 
240  return true;
241  }
242 
243  // we get here if TXOP limit is null
244  m_initialFrame = true;
245 
246  if (StartFrameExchange (m_edca, Time::Min (), true))
247  {
249  return true;
250  }
251 
252  NS_LOG_DEBUG ("No frame transmitted");
254  m_edca = 0;
255  return false;
256 }
257 
258 bool
259 QosFrameExchangeManager::StartFrameExchange (Ptr<QosTxop> edca, Time availableTime, bool initialFrame)
260 {
261  NS_LOG_FUNCTION (this << edca << availableTime << initialFrame);
262 
264 
265  // Even though channel access is requested when the queue is not empty, at
266  // the time channel access is granted the lifetime of the packet might be
267  // expired and the queue might be empty.
268  if (mpdu == 0)
269  {
270  NS_LOG_DEBUG ("Queue empty");
271  return false;
272  }
273 
274  WifiTxParameters txParams;
275  txParams.m_txVector = m_mac->GetWifiRemoteStationManager ()->GetDataTxVector (mpdu->GetHeader ());
276 
278  Ptr<WifiMacQueueItem> item = edca->GetNextMpdu (mpdu, txParams, availableTime, initialFrame, queueIt);
279 
280  if (item == nullptr)
281  {
282  NS_LOG_DEBUG ("Not enough time to transmit a frame");
283  return false;
284  }
285 
286  NS_ASSERT_MSG (!item->GetHeader ().IsQosData () || !item->GetHeader ().IsQosAmsdu (),
287  "We should not get an A-MSDU here");
288 
289  // check if the MSDU needs to be fragmented
290  item = GetFirstFragmentIfNeeded (item);
291 
292  // update the protection method if the frame was fragmented
293  if (item->IsFragment () && item->GetSize () != mpdu->GetSize ())
294  {
295  WifiTxParameters fragmentTxParams;
296  fragmentTxParams.m_txVector = txParams.m_txVector;
297  txParams.m_protection = GetProtectionManager ()->TryAddMpdu (item, fragmentTxParams);
298  NS_ASSERT (txParams.m_protection != nullptr);
299  }
300 
301  SendMpduWithProtection (item, txParams);
302 
303  return true;
304 }
305 
306 bool
308  Time availableTime) const
309 {
310  NS_ASSERT (mpdu != 0);
311  NS_LOG_FUNCTION (this << *mpdu << &txParams << availableTime);
312 
313  // check if adding the given MPDU requires a different protection method
314  Time protectionTime = Time::Min (); // uninitialized
315  if (txParams.m_protection)
316  {
317  protectionTime = txParams.m_protection->protectionTime;
318  }
319 
320  std::unique_ptr<WifiProtection> protection;
321  protection = GetProtectionManager ()->TryAddMpdu (mpdu, txParams);
322  bool protectionSwapped = false;
323 
324  if (protection)
325  {
326  // the protection method has changed, calculate the new protection time
327  CalculateProtectionTime (protection.get ());
328  protectionTime = protection->protectionTime;
329  // swap unique pointers, so that the txParams that is passed to the next
330  // call to IsWithinLimitsIfAddMpdu is the most updated one
331  txParams.m_protection.swap (protection);
332  protectionSwapped = true;
333  }
334  NS_ASSERT (protectionTime != Time::Min ());
335  NS_LOG_DEBUG ("protection time=" << protectionTime);
336 
337  // check if adding the given MPDU requires a different acknowledgment method
338  Time acknowledgmentTime = Time::Min (); // uninitialized
339  if (txParams.m_acknowledgment)
340  {
341  acknowledgmentTime = txParams.m_acknowledgment->acknowledgmentTime;
342  }
343 
344  std::unique_ptr<WifiAcknowledgment> acknowledgment;
345  acknowledgment = GetAckManager ()->TryAddMpdu (mpdu, txParams);
346  bool acknowledgmentSwapped = false;
347 
348  if (acknowledgment)
349  {
350  // the acknowledgment method has changed, calculate the new acknowledgment time
351  CalculateAcknowledgmentTime (acknowledgment.get ());
352  acknowledgmentTime = acknowledgment->acknowledgmentTime;
353  // swap unique pointers, so that the txParams that is passed to the next
354  // call to IsWithinLimitsIfAddMpdu is the most updated one
355  txParams.m_acknowledgment.swap (acknowledgment);
356  acknowledgmentSwapped = true;
357  }
358  NS_ASSERT (acknowledgmentTime != Time::Min ());
359  NS_LOG_DEBUG ("acknowledgment time=" << acknowledgmentTime);
360 
361  Time ppduDurationLimit = Time::Min ();
362  if (availableTime != Time::Min ())
363  {
364  ppduDurationLimit = availableTime - protectionTime - acknowledgmentTime;
365  }
366 
367  if (!IsWithinLimitsIfAddMpdu (mpdu, txParams, ppduDurationLimit))
368  {
369  // adding MPDU failed, restore protection and acknowledgment methods
370  // if they were swapped
371  if (protectionSwapped)
372  {
373  txParams.m_protection.swap (protection);
374  }
375  if (acknowledgmentSwapped)
376  {
377  txParams.m_acknowledgment.swap (acknowledgment);
378  }
379  return false;
380  }
381 
382  // the given MPDU can be added, hence update the txParams
383  txParams.AddMpdu (mpdu);
384  UpdateTxDuration (mpdu->GetHeader ().GetAddr1 (), txParams);
385 
386  return true;
387 }
388 
389 bool
391  const WifiTxParameters& txParams,
392  Time ppduDurationLimit) const
393 {
394  NS_ASSERT (mpdu != 0);
395  NS_LOG_FUNCTION (this << *mpdu << &txParams << ppduDurationLimit);
396 
397  // A QoS station only has to check that the MPDU transmission time does not
398  // exceed the given limit
399  return IsWithinSizeAndTimeLimits (mpdu->GetSize (), mpdu->GetHeader ().GetAddr1 (),
400  txParams, ppduDurationLimit);
401 }
402 
403 bool
405  const WifiTxParameters& txParams,
406  Time ppduDurationLimit) const
407 {
408  NS_LOG_FUNCTION (this << ppduPayloadSize << receiver << &txParams << ppduDurationLimit);
409 
410  if (ppduDurationLimit != Time::Min () && ppduDurationLimit.IsNegative ())
411  {
412  NS_LOG_DEBUG ("ppduDurationLimit is null or negative, time limit is trivially exceeded");
413  return false;
414  }
415 
416  if (ppduPayloadSize > WifiPhy::GetMaxPsduSize (txParams.m_txVector.GetModulationClass ()))
417  {
418  NS_LOG_DEBUG ("the frame exceeds the max PSDU size");
419  return false;
420  }
421 
422  // Get the maximum PPDU Duration based on the preamble type
423  Time maxPpduDuration = GetPpduMaxTime (txParams.m_txVector.GetPreambleType ());
424 
425  Time txTime = GetTxDuration (ppduPayloadSize, receiver, txParams);
426  NS_LOG_DEBUG ("PPDU duration: " << txTime.As (Time::MS));
427 
428  if ((ppduDurationLimit.IsStrictlyPositive () && txTime > ppduDurationLimit)
429  || (maxPpduDuration.IsStrictlyPositive () && txTime > maxPpduDuration))
430  {
431  NS_LOG_DEBUG ("the frame does not meet the constraint on max PPDU duration or PPDU duration limit");
432  return false;
433  }
434 
435  return true;
436 }
437 
438 Time
440  const WifiTxParameters& txParams,
441  Ptr<Packet> fragmentedPacket) const
442 {
443  NS_LOG_FUNCTION (this << header << size << &txParams << fragmentedPacket);
444 
445  // TODO This will be removed once no Txop is installed on a QoS station
446  if (m_edca == 0)
447  {
448  return FrameExchangeManager::GetFrameDurationId (header, size, txParams, fragmentedPacket);
449  }
450 
451  if (m_edca->GetTxopLimit ().IsZero ())
452  {
453  return FrameExchangeManager::GetFrameDurationId (header, size, txParams, fragmentedPacket);
454  }
455 
456  // under multiple protection settings, if the TXOP limit is not null, Duration/ID
457  // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
458  // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
459  // of 802.11-2016)
460  return std::max (m_edca->GetRemainingTxop ()
461  - m_phy->CalculateTxDuration (size, txParams.m_txVector, m_phy->GetPhyBand ()),
462  Seconds (0));
463 }
464 
465 Time
466 QosFrameExchangeManager::GetRtsDurationId (const WifiTxVector& rtsTxVector, Time txDuration, Time response) const
467 {
468  NS_LOG_FUNCTION (this << rtsTxVector << txDuration << response);
469 
470  // TODO This will be removed once no Txop is installed on a QoS station
471  if (m_edca == 0)
472  {
473  return FrameExchangeManager::GetRtsDurationId (rtsTxVector, txDuration, response);
474  }
475 
476  if (m_edca->GetTxopLimit ().IsZero ())
477  {
478  return FrameExchangeManager::GetRtsDurationId (rtsTxVector, txDuration, response);
479  }
480 
481  // under multiple protection settings, if the TXOP limit is not null, Duration/ID
482  // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
483  // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
484  // of 802.11-2016)
485  return std::max (m_edca->GetRemainingTxop ()
486  - m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, m_phy->GetPhyBand ()),
487  Seconds (0));
488 }
489 
490 Time
492  Time txDuration, Time response) const
493 {
494  NS_LOG_FUNCTION (this << ctsTxVector << txDuration << response);
495 
496  // TODO This will be removed once no Txop is installed on a QoS station
497  if (m_edca == 0)
498  {
499  return FrameExchangeManager::GetCtsToSelfDurationId (ctsTxVector, txDuration, response);
500  }
501 
502  if (m_edca->GetTxopLimit ().IsZero ())
503  {
504  return FrameExchangeManager::GetCtsToSelfDurationId (ctsTxVector, txDuration, response);
505  }
506 
507  // under multiple protection settings, if the TXOP limit is not null, Duration/ID
508  // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
509  // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
510  // of 802.11-2016)
511  return std::max (m_edca->GetRemainingTxop ()
512  - m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, m_phy->GetPhyBand ()),
513  Seconds (0));
514 }
515 
516 void
518 {
519  NS_LOG_DEBUG (this);
520 
521  // TODO This will be removed once no Txop is installed on a QoS station
522  if (m_edca == 0)
523  {
525  return;
526  }
527 
529  && m_edca->GetRemainingTxop () > m_phy->GetSifs ())
530  {
531  NS_LOG_DEBUG ("Schedule another transmission in a SIFS");
533 
534  // we are continuing a TXOP, hence the txopDuration parameter is unused
535  Simulator::Schedule (m_phy->GetSifs (), fp, this, m_edca, Seconds (0));
536  }
537  else
538  {
540  m_edca = 0;
541  }
542  m_initialFrame = false;
543 }
544 
545 void
547 {
548  NS_LOG_FUNCTION (this);
549 
550  // TODO This will be removed once no Txop is installed on a QoS station
551  if (m_edca == 0)
552  {
554  return;
555  }
556 
557  if (m_initialFrame)
558  {
559  // The backoff procedure shall be invoked by an EDCAF when the transmission
560  // of an MPDU in the initial PPDU of a TXOP fails (Sec. 10.22.2.2 of 802.11-2016)
561  NS_LOG_DEBUG ("TX of the initial frame of a TXOP failed: terminate TXOP");
563  m_edca = 0;
564  }
565  else
566  {
568  "Cannot transmit more than one frame if TXOP Limit is zero");
569 
570  // A STA can perform a PIFS recovery or perform a backoff as a response to
571  // transmission failure within a TXOP. How it chooses between these two is
572  // implementation dependent. (Sec. 10.22.2.2 of 802.11-2016)
573  if (m_pifsRecovery)
574  {
575  // we can continue the TXOP if the carrier sense mechanism indicates that
576  // the medium is idle in a PIFS
577  NS_LOG_DEBUG ("TX of a non-initial frame of a TXOP failed: perform PIFS recovery");
580  }
581  else
582  {
583  // In order not to terminate (yet) the TXOP, we call the NotifyChannelReleased
584  // method of the Txop class, which only generates a new backoff value and
585  // requests channel access if needed,
586  NS_LOG_DEBUG ("TX of a non-initial frame of a TXOP failed: invoke backoff");
587  m_edca->Txop::NotifyChannelReleased ();
589  m_edca = 0;
590  }
591  }
592  m_initialFrame = false;
593 }
594 
595 void
597 {
598  NS_LOG_FUNCTION (this << psdu << txVector);
599 
600  SetTxopHolder (psdu, txVector);
601 
602  // APs store buffer size report of associated stations
603  if (m_mac->GetTypeOfStation () == AP && psdu->GetAddr1 () == m_self)
604  {
605  for (const auto& mpdu : *PeekPointer (psdu))
606  {
607  const WifiMacHeader& hdr = mpdu->GetHeader ();
608 
609  if (hdr.IsQosData () && hdr.IsQosEosp ())
610  {
611  NS_LOG_DEBUG ("Station " << hdr.GetAddr2 () << " reported a buffer status of "
612  << +hdr.GetQosQueueSize () << " for tid=" << +hdr.GetQosTid ());
613  StaticCast<ApWifiMac> (m_mac)->SetBufferStatus (hdr.GetQosTid (), hdr.GetAddr2 (), hdr.GetQosQueueSize ());
614  }
615  }
616  }
617 
618  FrameExchangeManager::PreProcessFrame (psdu, txVector);
619 }
620 
621 void
623 {
624  NS_LOG_FUNCTION (this << psdu << txVector);
625 
626  const WifiMacHeader& hdr = psdu->GetHeader (0);
627 
628  if (hdr.IsQosData () || hdr.IsMgt () || hdr.IsRts ())
629  {
630  m_txopHolder = psdu->GetAddr2 ();
631  }
632  else if (hdr.IsCts () || hdr.IsAck ())
633  {
634  m_txopHolder = psdu->GetAddr1 ();
635  }
636 }
637 
638 void
640  const WifiTxVector& txVector, bool inAmpdu)
641 {
642  // The received MPDU is either broadcast or addressed to this station
643  NS_ASSERT (mpdu->GetHeader ().GetAddr1 ().IsGroup ()
644  || mpdu->GetHeader ().GetAddr1 () == m_self);
645 
646  double rxSnr = rxSignalInfo.snr;
647  const WifiMacHeader& hdr = mpdu->GetHeader ();
648 
649  if (hdr.IsCfEnd ())
650  {
651  // reset NAV
652  NavResetTimeout ();
653  return;
654  }
655 
656  if (hdr.IsRts ())
657  {
658  NS_ABORT_MSG_IF (inAmpdu, "Received RTS as part of an A-MPDU");
659 
660  // If a non-VHT STA receives an RTS frame with the RA address matching the
661  // MAC address of the STA and the MAC address in the TA field in the RTS
662  // frame matches the saved TXOP holder address, then the STA shall send the
663  // CTS frame after SIFS, without regard for, and without resetting, its NAV.
664  // (sec. 10.22.2.4 of 802.11-2016)
665  if (hdr.GetAddr2 () == m_txopHolder || m_navEnd <= Simulator::Now ())
666  {
667  NS_LOG_DEBUG ("Received RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
669  this, hdr, txVector.GetMode (), rxSnr);
670  }
671  else
672  {
673  NS_LOG_DEBUG ("Received RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
674  }
675  return;
676  }
677 
678  if (hdr.IsQosData ())
679  {
680  if (hdr.GetAddr1 () == m_self && hdr.GetQosAckPolicy () == WifiMacHeader::NORMAL_ACK)
681  {
682  NS_LOG_DEBUG ("Received " << hdr.GetTypeString () << " from=" << hdr.GetAddr2 () << ", schedule ACK");
684  this, hdr, txVector, rxSnr);
685  }
686 
687  // Forward up the frame if it is not a QoS Null frame
688  if (hdr.HasData ())
689  {
690  m_rxMiddle->Receive (mpdu);
691  }
692 
693  // the received data frame has been processed
694  return;
695  }
696 
697  return FrameExchangeManager::ReceiveMpdu (mpdu, rxSignalInfo, txVector, inAmpdu);
698 }
699 
700 } //namespace ns3
EventId m_pifsRecoveryEvent
event associated with an attempt of PIFS recovery
bool IsCfEnd(void) const
Return true if the header is a CF-End header.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
Ptr< const WifiMacQueueItem > PeekNextMpdu(uint8_t tid=8, Mac48Address recipient=Mac48Address::GetBroadcast())
Peek the next frame to transmit to the given receiver and of the given TID from the block ack manager...
Definition: qos-txop.cc:277
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
WifiTxTimer m_txTimer
the timer set upon frame transmission
AttributeValue implementation for Boolean.
Definition: boolean.h:36
virtual void NotifyChannelAccessed(Time txopDuration)
Called by the FrameExchangeManager to notify that channel access has been granted for the given amoun...
Definition: qos-txop.cc:566
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SendMpduWithProtection(Ptr< WifiMacQueueItem > mpdu, WifiTxParameters &txParams)
Send an MPDU with the given TX parameters (with the specified protection).
void NotifyChannelReleased(void)
Called by the FrameExchangeManager to notify the completion of the transmissions. ...
Definition: qos-txop.cc:584
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< WifiProtectionManager > GetProtectionManager(void) const
Get the Protection Manager used by this node.
Ptr< WifiPhy > m_phy
the PHY layer on this station
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:274
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1124
std::unique_ptr< WifiProtection > m_protection
protection method
uint32_t GetRtsSize(void)
Return the total RTS size (including FCS trailer).
Definition: wifi-utils.cc:209
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:85
virtual Time GetRtsDurationId(const WifiTxVector &rtsTxVector, Time txDuration, Time response) const override
Compute how to set the Duration/ID field of an RTS frame to send to protect a frame transmitted with ...
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
#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
virtual void PreProcessFrame(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Perform actions that are possibly needed when receiving any frame, independently of whether the frame...
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:411
bool IsQosEosp(void) const
Return if the end of service period (EOSP) is set.
Information needed to remove an MSDU from the queue.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
virtual void CalculateProtectionTime(WifiProtection *protection) const
Calculate the time required to protect a frame according to the given protection method.
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:813
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual Time GetRemainingTxop(void) const
Return the remaining duration in the current TXOP.
Definition: qos-txop.cc:598
void PifsRecovery(void)
Perform a PIFS recovery as a response to transmission failure within a TXOP.
const char * GetTypeString(void) const
Return a string corresponds to the header type.
Ptr< ChannelAccessManager > m_channelAccessManager
the channel access manager
virtual void DoDispose()
Destructor implementation.
virtual void TransmissionFailed(void)
Take necessary actions upon a transmission failure.
virtual void CalculateAcknowledgmentTime(WifiAcknowledgment *acknowledgment) const
Calculate the time required to acknowledge a frame according to the given acknowledgment method...
Ptr< WifiAckManager > GetAckManager(void) const
Get the Acknowledgment Manager used by this node.
Ptr< RegularWifiMac > m_mac
the MAC layer on this station
virtual bool StartTransmission(Ptr< Txop > edca) override
Request the FrameExchangeManager to start a frame exchange sequence.
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...
Ptr< WifiMacQueueItem > GetFirstFragmentIfNeeded(Ptr< WifiMacQueueItem > mpdu)
Fragment the given MPDU if needed.
virtual void DoDispose() override
Destructor implementation.
WifiPreamble GetPreambleType(void) const
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1616
virtual void TransmissionSucceeded(void) override
Take necessary actions upon a transmission success.
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:66
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
virtual Time GetFrameDurationId(const WifiMacHeader &header, uint32_t size, const WifiTxParameters &txParams, Ptr< Packet > fragmentedPacket) const
Compute how to set the Duration/ID field of a frame being transmitted with the given TX parameters...
#define max(a, b)
Definition: 80211b.c:43
virtual void PreProcessFrame(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector) override
Perform actions that are possibly needed when receiving any frame, independently of whether the frame...
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
QosFrameExchangeManager handles the frame exchange sequences for QoS stations.
uint8_t GetQosQueueSize(void) const
Get the Queue Size subfield in the QoS control field.
bool IsQosAmsdu(void) const
Check if the A-MSDU present bit is set in the QoS control field.
virtual bool IsWithinSizeAndTimeLimits(uint32_t ppduPayloadSize, Mac48Address receiver, const WifiTxParameters &txParams, Time ppduDurationLimit) const
Check whether the transmission time of the frame being built (as described by the given TX parameters...
static TypeId GetTypeId(void)
Get the type ID.
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
virtual void NotifyChannelReleased(void)
Called by the FrameExchangeManager to notify the completion of the transmissions. ...
Definition: txop.cc:349
bool IsCts(void) const
Return true if the header is a CTS header.
virtual bool StartTransmission(Ptr< Txop > dcf)
Request the FrameExchangeManager to start a frame exchange sequence.
Ptr< Txop > m_edcaBackingOff
channel access function that invoked backoff during TXOP
static Mac48Address GetBroadcast(void)
virtual Time GetRtsDurationId(const WifiTxVector &rtsTxVector, Time txDuration, Time response) const
Compute how to set the Duration/ID field of an RTS frame to send to protect a frame transmitted with ...
Mac48Address GetAddr2(void) const
Get the Transmitter Address (TA), which is common to all the MPDUs.
Definition: wifi-psdu.cc:126
virtual void SetTxopHolder(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Set the TXOP holder, if needed, based on the received frame.
virtual bool IsQosTxop() const
Check for QoS TXOP.
Definition: txop.cc:421
virtual bool SendCfEndIfNeeded(void)
Send a CF-End frame to indicate the completion of the TXOP, provided that the remaining duration is l...
bool m_initialFrame
true if transmitting the initial frame of a TXOP
const WifiMacHeader & GetHeader(std::size_t i) const
Get the header of the i-th MPDU.
Definition: wifi-psdu.cc:266
Mac48Address m_self
the MAC address of this device
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
void CancelPifsRecovery(void)
Cancel the PIFS recovery event and have the EDCAF attempting PIFS recovery release the channel...
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition: wifi-phy.cc:1637
bool m_pifsRecovery
true if performing a PIFS recovery after failure
void Cancel(void)
Cancel the timer.
an EUI-48 address
Definition: mac48-address.h:43
bool IsRunning(void) const
Return true if the timer is running.
Mac48Address m_txopHolder
MAC address of the TXOP holder.
Time GetPifs(void) const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:934
Ptr< QosTxop > m_edca
the EDCAF that gained channel access
void SendCtsAfterRts(const WifiMacHeader &rtsHdr, WifiMode rtsTxMode, double rtsSnr)
Send CTS after receiving RTS.
bool IsGroup(void) const
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
virtual Time GetFrameDurationId(const WifiMacHeader &header, uint32_t size, const WifiTxParameters &txParams, Ptr< Packet > fragmentedPacket) const override
Compute how to set the Duration/ID field of a frame being transmitted with the given TX parameters...
void SendNormalAck(const WifiMacHeader &hdr, const WifiTxVector &dataTxVector, double dataSnr)
Send Normal Ack.
FrameExchangeManager is a base class handling the basic frame exchange sequences for non-QoS stations...
virtual Time GetTxDuration(uint32_t ppduPayloadSize, Mac48Address receiver, const WifiTxParameters &txParams) const
Get the updated TX duration of the frame associated with the given TX parameters if the size of the P...
void AddMpdu(Ptr< const WifiMacQueueItem > mpdu)
Record that an MPDU is being added to the current frame.
uint32_t GetCtsSize(void)
Return the total CTS size (including FCS trailer).
Definition: wifi-utils.cc:217
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
bool IsMgt(void) const
Return true if the Type is Management.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
Time GetPpduMaxTime(WifiPreamble preamble)
Get the maximum PPDU duration (see Section 10.14 of 802.11-2016) for the PHY layers defining the aPPD...
Definition: wifi-utils.cc:254
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:910
double snr
SNR in linear scale.
Definition: phy-entity.h:68
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism...
Ptr< Txop > m_dcf
the DCF/EDCAF that gained channel access
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument...
Definition: wifi-phy.cc:1774
virtual Time GetCtsToSelfDurationId(const WifiTxVector &ctsTxVector, Time txDuration, Time response) const
Compute how to set the Duration/ID field of a CTS-to-self frame to send to protect a frame transmitte...
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
bool IsRts(void) const
Return true if the header is a RTS header.
Time m_navEnd
NAV expiration time.
virtual void ReceiveMpdu(Ptr< WifiMacQueueItem > mpdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, bool inAmpdu)
This method handles the reception of an MPDU (possibly included in an A-MPDU)
virtual void ReceiveMpdu(Ptr< WifiMacQueueItem > mpdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, bool inAmpdu) override
This method handles the reception of an MPDU (possibly included in an A-MPDU)
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data...
virtual void TransmissionFailed(void) override
Take necessary actions upon a transmission failure.
virtual void TransmissionSucceeded(void)
Take necessary actions upon a transmission success.
bool IsAck(void) const
Return true if the header is an Ack header.
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
void UpdateTxDuration(Mac48Address receiver, WifiTxParameters &txParams) const
Update the TX duration field of the given TX parameters after that the PSDU addressed to the given re...
Mac48Address GetAddr1(void) const
Get the Receiver Address (RA), which is common to all the MPDUs.
Definition: wifi-psdu.cc:111
Ptr< WifiMacQueueItem > GetNextMpdu(Ptr< const WifiMacQueueItem > peekedItem, WifiTxParameters &txParams, Time availableTime, bool initialFrame, WifiMacQueueItem::QueueIteratorPair &queueIt)
Prepare the frame to transmit starting from the MPDU that has been previously peeked by calling PeekN...
Definition: qos-txop.cc:359
bool TryAddMpdu(Ptr< const WifiMacQueueItem > mpdu, WifiTxParameters &txParams, Time availableTime) const
Recompute the protection and acknowledgment methods to use if the given MPDU is added to the frame be...
Ptr< MacRxMiddle > m_rxMiddle
the MAC RX Middle on this station
millisecond
Definition: nstime.h:116
virtual bool StartFrameExchange(Ptr< QosTxop > edca, Time availableTime, bool initialFrame)
Start a frame exchange (including protection frames and acknowledgment frames as needed) that fits wi...
a unique identifier for an interface.
Definition: type-id.h:58
virtual Time GetCtsToSelfDurationId(const WifiTxVector &ctsTxVector, Time txDuration, Time response) const override
Compute how to set the Duration/ID field of a CTS-to-self frame to send to protect a frame transmitte...
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
virtual bool IsWithinLimitsIfAddMpdu(Ptr< const WifiMacQueueItem > mpdu, const WifiTxParameters &txParams, Time ppduDurationLimit) const
Check whether the given MPDU can be added to the frame being built (as described by the given TX para...
Implements the IEEE 802.11 MAC header.
bool IsNegative(void) const
Exactly equivalent to t <= 0.
Definition: nstime.h:309
virtual bool IsTxopStarted(void) const
Return true if a TXOP has started.
Definition: qos-txop.cc:577
bool HasData(void) const
Return true if the header type is DATA and is not DATA_NULL.
virtual void NavResetTimeout(void)
Reset the NAV upon expiration of the NAV reset timer.
QosAckPolicy GetQosAckPolicy(void) const
Return the QoS Ack policy in the QoS control field.
Time GetTxopLimit(void) const
Return the TXOP limit.
Definition: txop.cc:274