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