A Discrete-Event Network Simulator
API
ht-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 "ns3/wifi-mac-queue.h"
25 #include "ns3/mgt-headers.h"
26 #include "ns3/recipient-block-ack-agreement.h"
27 #include "ns3/wifi-utils.h"
28 #include "ns3/snr-tag.h"
29 #include "ns3/ctrl-headers.h"
30 #include <array>
31 #include <optional>
32 
33 #undef NS_LOG_APPEND_CONTEXT
34 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
35 
36 namespace ns3 {
37 
38 NS_LOG_COMPONENT_DEFINE ("HtFrameExchangeManager");
39 
40 NS_OBJECT_ENSURE_REGISTERED (HtFrameExchangeManager);
41 
42 TypeId
44 {
45  static TypeId tid = TypeId ("ns3::HtFrameExchangeManager")
47  .AddConstructor<HtFrameExchangeManager> ()
48  .SetGroupName ("Wifi")
49  ;
50  return tid;
51 }
52 
54 {
55  NS_LOG_FUNCTION (this);
56  m_msduAggregator = CreateObject<MsduAggregator> ();
57  m_mpduAggregator = CreateObject<MpduAggregator> ();
58 }
59 
61 {
63 }
64 
65 void
67 {
68  NS_LOG_FUNCTION (this);
69  m_agreements.clear ();
70  m_msduAggregator = 0;
71  m_mpduAggregator = 0;
72  m_psdu = 0;
73  m_txParams.Clear ();
75 }
76 
77 void
79 {
80  m_msduAggregator->SetWifiMac (mac);
81  m_mpduAggregator->SetWifiMac (mac);
83 }
84 
87 {
88  return m_msduAggregator;
89 }
90 
93 {
94  return m_mpduAggregator;
95 }
96 
99 {
100  return m_mac->GetQosTxop (tid)->GetBaManager ();
101 }
102 
103 bool
105 {
106  Ptr<QosTxop> qosTxop = m_mac->GetQosTxop (tid);
107  bool establish;
108 
109  if (!m_mac->GetWifiRemoteStationManager ()->GetHtSupported (recipient))
110  {
111  establish = false;
112  }
113  else if (qosTxop->GetBaManager ()->ExistsAgreement (recipient, tid)
114  && !qosTxop->GetBaManager ()->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::RESET))
115  {
116  establish = false;
117  }
118  else
119  {
120  uint32_t packets = qosTxop->GetWifiMacQueue ()->GetNPacketsByTidAndAddress (tid, recipient);
121  establish = ((qosTxop->GetBlockAckThreshold () > 0 && packets >= qosTxop->GetBlockAckThreshold ())
122  || (m_mpduAggregator->GetMaxAmpduSize (recipient, tid, WIFI_MOD_CLASS_HT) > 0 && packets > 1)
123  || m_mac->GetWifiRemoteStationManager ()->GetVhtSupported ());
124  }
125 
126  NS_LOG_FUNCTION (this << recipient << +tid << establish);
127  return establish;
128 }
129 
130 void
131 HtFrameExchangeManager::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startingSeq,
132  uint16_t timeout, bool immediateBAck)
133 {
134  NS_LOG_FUNCTION (this << dest << +tid << startingSeq << timeout << immediateBAck);
135  NS_LOG_DEBUG ("Send ADDBA request to " << dest);
136 
137  WifiMacHeader hdr;
139  hdr.SetAddr1 (dest);
140  hdr.SetAddr2 (m_self);
141  hdr.SetAddr3 (m_bssid);
142  hdr.SetDsNotTo ();
143  hdr.SetDsNotFrom ();
144 
145  WifiActionHeader actionHdr;
148  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
149 
150  Ptr<Packet> packet = Create<Packet> ();
151  // Setting ADDBARequest header
152  MgtAddBaRequestHeader reqHdr;
153  reqHdr.SetAmsduSupport (true);
154  if (immediateBAck)
155  {
156  reqHdr.SetImmediateBlockAck ();
157  }
158  else
159  {
160  reqHdr.SetDelayedBlockAck ();
161  }
162  reqHdr.SetTid (tid);
163  /* For now we don't use buffer size field in the ADDBA request frame. The recipient
164  * will choose how many packets it can receive under block ack.
165  */
166  reqHdr.SetBufferSize (0);
167  reqHdr.SetTimeout (timeout);
168  // set the starting sequence number for the BA agreement
169  reqHdr.SetStartingSequence (startingSeq);
170 
171  GetBaManager (tid)->CreateAgreement (&reqHdr, dest);
172 
173  packet->AddHeader (reqHdr);
174  packet->AddHeader (actionHdr);
175 
176  Ptr<WifiMacQueueItem> mpdu = Create<WifiMacQueueItem> (packet, hdr);
177 
178  // get the sequence number for the ADDBA Request management frame
179  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&mpdu->GetHeader ());
180  mpdu->GetHeader ().SetSequenceNumber (sequence);
181 
182  WifiTxParameters txParams;
183  txParams.m_txVector = m_mac->GetWifiRemoteStationManager ()->GetDataTxVector (mpdu->GetHeader ());
184  txParams.m_protection = std::unique_ptr<WifiProtection> (new WifiNoProtection);
185  txParams.m_acknowledgment = GetAckManager ()->TryAddMpdu (mpdu, txParams);
186 
187  SendMpduWithProtection (mpdu, txParams);
188 }
189 
190 void
192  Mac48Address originator)
193 {
194  NS_LOG_FUNCTION (this << originator);
195  WifiMacHeader hdr;
197  hdr.SetAddr1 (originator);
198  hdr.SetAddr2 (m_self);
199  hdr.SetAddr3 (m_bssid);
200  hdr.SetDsNotFrom ();
201  hdr.SetDsNotTo ();
202 
203  MgtAddBaResponseHeader respHdr;
204  StatusCode code;
205  code.SetSuccess ();
206  respHdr.SetStatusCode (code);
207  //Here a control about queues type?
208  respHdr.SetAmsduSupport (reqHdr->IsAmsduSupported ());
209 
210  if (reqHdr->IsImmediateBlockAck ())
211  {
212  respHdr.SetImmediateBlockAck ();
213  }
214  else
215  {
216  respHdr.SetDelayedBlockAck ();
217  }
218  respHdr.SetTid (reqHdr->GetTid ());
219 
220  respHdr.SetBufferSize (GetSupportedBaBufferSize () - 1);
221  respHdr.SetTimeout (reqHdr->GetTimeout ());
222 
223  WifiActionHeader actionHdr;
226  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
227 
228  Ptr<Packet> packet = Create<Packet> ();
229  packet->AddHeader (respHdr);
230  packet->AddHeader (actionHdr);
231 
232  CreateBlockAckAgreement (&respHdr, originator, reqHdr->GetStartingSequence ());
233 
234  //It is unclear which queue this frame should go into. For now we
235  //bung it into the queue corresponding to the TID for which we are
236  //establishing an agreement, and push it to the head.
237  m_mac->GetQosTxop (reqHdr->GetTid ())->PushFront (packet, hdr);
238 }
239 
240 uint16_t
242 {
243  return 64;
244 }
245 
246 void
247 HtFrameExchangeManager::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator)
248 {
249  NS_LOG_FUNCTION (this << addr << +tid << byOriginator);
250  WifiMacHeader hdr;
252  hdr.SetAddr1 (addr);
253  hdr.SetAddr2 (m_self);
254  hdr.SetAddr3 (m_bssid);
255  hdr.SetDsNotTo ();
256  hdr.SetDsNotFrom ();
257 
258  MgtDelBaHeader delbaHdr;
259  delbaHdr.SetTid (tid);
260  if (byOriginator)
261  {
262  delbaHdr.SetByOriginator ();
263  GetBaManager (tid)->DestroyAgreement (addr, tid);
264  }
265  else
266  {
267  delbaHdr.SetByRecipient ();
268  DestroyBlockAckAgreement (addr, tid);
269  }
270 
271  WifiActionHeader actionHdr;
274  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
275 
276  Ptr<Packet> packet = Create<Packet> ();
277  packet->AddHeader (delbaHdr);
278  packet->AddHeader (actionHdr);
279 
280  m_mac->GetQosTxop (tid)->GetWifiMacQueue ()->PushFront (Create<WifiMacQueueItem> (packet, hdr));
281 }
282 
283 void
285  uint16_t startingSeq)
286 {
287  NS_LOG_FUNCTION (this << *respHdr << originator << startingSeq);
288  uint8_t tid = respHdr->GetTid ();
289 
290  RecipientBlockAckAgreement agreement (originator, respHdr->IsAmsduSupported (), tid,
291  respHdr->GetBufferSize () + 1, respHdr->GetTimeout (),
292  startingSeq,
293  m_mac->GetWifiRemoteStationManager ()->GetHtSupported ()
294  && m_mac->GetWifiRemoteStationManager ()->GetHtSupported (originator));
295  agreement.SetMacRxMiddle (m_rxMiddle);
296  if (respHdr->IsImmediateBlockAck ())
297  {
298  agreement.SetImmediateBlockAck ();
299  }
300  else
301  {
302  agreement.SetDelayedBlockAck ();
303  }
304 
305  if (respHdr->GetTimeout () != 0)
306  {
307  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
308 
310  this, originator, tid, false);
311  }
312 
313  m_agreements.insert ({{originator, tid}, agreement});
314  GetBaManager (tid)->SetBlockAckInactivityCallback (MakeCallback (&HtFrameExchangeManager::SendDelbaFrame, this));
315 }
316 
317 void
319 {
320  NS_LOG_FUNCTION (this << originator << +tid);
321 
322  auto agreementIt = m_agreements.find ({originator, tid});
323  if (agreementIt != m_agreements.end ())
324  {
325  // forward up the buffered MPDUs before destroying the agreement
326  agreementIt->second.Flush ();
327  m_agreements.erase (agreementIt);
328  }
329 }
330 
331 bool
332 HtFrameExchangeManager::StartFrameExchange (Ptr<QosTxop> edca, Time availableTime, bool initialFrame)
333 {
334  NS_LOG_FUNCTION (this << edca << availableTime << initialFrame);
335 
336  // First, check if there is a BAR to be transmitted
337  if (SendMpduFromBaManager (edca, availableTime, initialFrame))
338  {
339  return true;
340  }
341 
342  Ptr<const WifiMacQueueItem> peekedItem = edca->PeekNextMpdu ();
343 
344  // Even though channel access is requested when the queue is not empty, at
345  // the time channel access is granted the lifetime of the packet might be
346  // expired and the queue might be empty.
347  if (peekedItem == 0)
348  {
349  NS_LOG_DEBUG ("No frames available for transmission");
350  return false;
351  }
352 
353  const WifiMacHeader& hdr = peekedItem->GetHeader ();
354  // setup a Block Ack agreement if needed
355  if (hdr.IsQosData () && !hdr.GetAddr1 ().IsGroup ()
356  && NeedSetupBlockAck (hdr.GetAddr1 (), hdr.GetQosTid ()))
357  {
358  // if the peeked MPDU has been already transmitted, use its sequence number
359  // as the starting sequence number for the BA agreement, otherwise use the
360  // next available sequence number
361  uint16_t startingSeq = (hdr.IsRetry () ? hdr.GetSequenceNumber ()
362  : m_txMiddle->GetNextSeqNumberByTidAndAddress (hdr.GetQosTid (),
363  hdr.GetAddr1 ()));
364  SendAddBaRequest (hdr.GetAddr1 (), hdr.GetQosTid (), startingSeq,
365  edca->GetBlockAckInactivityTimeout (), true);
366  return true;
367  }
368 
369  // Use SendDataFrame if we can try aggregation
370  if (hdr.IsQosData () && !hdr.GetAddr1 ().IsGroup () && !peekedItem->IsFragment ()
371  && !m_mac->GetWifiRemoteStationManager ()->NeedFragmentation (peekedItem))
372  {
373  return SendDataFrame (peekedItem, availableTime, initialFrame);
374  }
375 
376  // Use the QoS FEM to transmit the frame in all the other cases, i.e.:
377  // - the frame is not a QoS data frame
378  // - the frame is a broadcast QoS data frame
379  // - the frame is a fragment
380  // - the frame must be fragmented
381  return QosFrameExchangeManager::StartFrameExchange (edca, availableTime, initialFrame);
382 }
383 
384 bool
385 HtFrameExchangeManager::SendMpduFromBaManager (Ptr<QosTxop> edca, Time availableTime, bool initialFrame)
386 {
387  NS_LOG_FUNCTION (this << edca << availableTime << initialFrame);
388 
389  // First, check if there is a BAR to be transmitted
390  Ptr<const WifiMacQueueItem> peekedItem = edca->GetBaManager ()->GetBar (false);
391 
392  if (peekedItem == 0)
393  {
394  NS_LOG_DEBUG ("Block Ack Manager returned no frame to send");
395  return false;
396  }
397 
398  NS_ASSERT (peekedItem->GetHeader ().IsBlockAckReq ());
399 
400  // Prepare the TX parameters. Note that the default ack manager expects the
401  // data TxVector in the m_txVector field to compute the BlockAck TxVector.
402  // The m_txVector field of the TX parameters is set to the BlockAckReq TxVector
403  // a few lines below.
404  WifiTxParameters txParams;
405  txParams.m_txVector = m_mac->GetWifiRemoteStationManager ()->GetDataTxVector (peekedItem->GetHeader ());
406  txParams.m_protection = std::unique_ptr<WifiProtection> (new WifiNoProtection);
407  txParams.m_acknowledgment = GetAckManager ()->TryAddMpdu (peekedItem, txParams);
408 
410 
411  WifiBlockAck* blockAcknowledgment = static_cast<WifiBlockAck*> (txParams.m_acknowledgment.get ());
412  CalculateAcknowledgmentTime (blockAcknowledgment);
413  // the BlockAckReq frame is sent using the same TXVECTOR as the BlockAck frame
414  txParams.m_txVector = blockAcknowledgment->blockAckTxVector;
415 
416  Time barTxDuration = m_phy->CalculateTxDuration (peekedItem->GetSize (),
417  blockAcknowledgment->blockAckTxVector,
418  m_phy->GetPhyBand ());
419 
420  // if the available time is limited and we are not transmitting the initial
421  // frame of the TXOP, we have to check that this frame and its response fit
422  // within the given time limits
423  if (availableTime != Time::Min () && !initialFrame
424  && barTxDuration + m_phy->GetSifs () + blockAcknowledgment->acknowledgmentTime > availableTime)
425  {
426  NS_LOG_DEBUG ("Not enough time to send the BAR frame returned by the Block Ack Manager");
427  return false;
428  }
429 
430  // we can transmit the BlockAckReq frame
431  Ptr<const WifiMacQueueItem> mpdu = edca->GetBaManager ()->GetBar ();
432  SendPsduWithProtection (Create<WifiPsdu> (mpdu, false), txParams);
433  return true;
434 }
435 
436 bool
438  Time availableTime, bool initialFrame)
439 {
440  NS_ASSERT (peekedItem != 0 && peekedItem->GetHeader ().IsQosData ()
441  && !peekedItem->GetHeader ().GetAddr1 ().IsBroadcast ()
442  && !peekedItem->IsFragment ());
443  NS_LOG_FUNCTION (this << *peekedItem << availableTime << initialFrame);
444 
445  Ptr<QosTxop> edca = m_mac->GetQosTxop (peekedItem->GetHeader ().GetQosTid ());
446  WifiTxParameters txParams;
447  txParams.m_txVector = m_mac->GetWifiRemoteStationManager ()->GetDataTxVector (peekedItem->GetHeader ());
449  Ptr<WifiMacQueueItem> mpdu = edca->GetNextMpdu (peekedItem, txParams, availableTime, initialFrame, queueIt);
450 
451  if (mpdu == nullptr)
452  {
453  NS_LOG_DEBUG ("Not enough time to transmit a frame");
454  return false;
455  }
456 
457  // try A-MPDU aggregation
458  std::vector<Ptr<WifiMacQueueItem>> mpduList = m_mpduAggregator->GetNextAmpdu (mpdu, txParams,
459  availableTime, queueIt);
460  NS_ASSERT (txParams.m_acknowledgment);
461 
462  if (mpduList.size () > 1)
463  {
464  // A-MPDU aggregation succeeded
465  SendPsduWithProtection (Create<WifiPsdu> (std::move (mpduList)), txParams);
466  }
467  else if (txParams.m_acknowledgment->method == WifiAcknowledgment::BAR_BLOCK_ACK)
468  {
469  // a QoS data frame using the Block Ack policy can be followed by a BlockAckReq
470  // frame and a BlockAck frame. Such a sequence is handled by the HT FEM
471  SendPsduWithProtection (Create<WifiPsdu> (mpdu, false), txParams);
472  }
473  else
474  {
475  // transmission can be handled by the base FEM
476  SendMpduWithProtection (mpdu, txParams);
477  }
478 
479  return true;
480 }
481 
482 void
484 {
485  NS_LOG_FUNCTION (this << acknowledgment);
486  NS_ASSERT (acknowledgment != nullptr);
487 
488  if (acknowledgment->method == WifiAcknowledgment::BLOCK_ACK)
489  {
490  WifiBlockAck* blockAcknowledgment = static_cast<WifiBlockAck*> (acknowledgment);
491  Time baTxDuration = m_phy->CalculateTxDuration (GetBlockAckSize (blockAcknowledgment->baType),
492  blockAcknowledgment->blockAckTxVector,
493  m_phy->GetPhyBand ());
494  blockAcknowledgment->acknowledgmentTime = m_phy->GetSifs () + baTxDuration;
495  }
496  else if (acknowledgment->method == WifiAcknowledgment::BAR_BLOCK_ACK)
497  {
498  WifiBarBlockAck* barBlockAcknowledgment = static_cast<WifiBarBlockAck*> (acknowledgment);
499  Time barTxDuration = m_phy->CalculateTxDuration (GetBlockAckRequestSize (barBlockAcknowledgment->barType),
500  barBlockAcknowledgment->blockAckReqTxVector,
501  m_phy->GetPhyBand ());
502  Time baTxDuration = m_phy->CalculateTxDuration (GetBlockAckSize (barBlockAcknowledgment->baType),
503  barBlockAcknowledgment->blockAckTxVector,
504  m_phy->GetPhyBand ());
505  barBlockAcknowledgment->acknowledgmentTime = 2 * m_phy->GetSifs () + barTxDuration + baTxDuration;
506  }
507  else
508  {
510  }
511 }
512 
513 void
515 {
516  ForwardPsduDown (GetWifiPsdu (mpdu, txVector), txVector);
517 }
518 
521 {
522  return Create<WifiPsdu> (mpdu, false);
523 }
524 
525 void
527 {
528  NS_LOG_FUNCTION (this << *mpdu);
529 
530  if (mpdu->GetHeader ().IsQosData ())
531  {
532  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
533  Ptr<QosTxop> edca = m_mac->GetQosTxop (tid);
534 
535  if (edca->GetBaAgreementEstablished (mpdu->GetHeader ().GetAddr1 (), tid))
536  {
537  // notify the BA manager that the MPDU was acknowledged
538  edca->GetBaManager ()->NotifyGotAck (mpdu);
539  }
540  }
541  else if (mpdu->GetHeader ().IsAction ())
542  {
543  WifiActionHeader actionHdr;
544  Ptr<Packet> p = mpdu->GetPacket ()->Copy ();
545  p->RemoveHeader (actionHdr);
546  if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK)
547  {
549  {
550  MgtDelBaHeader delBa;
551  p->PeekHeader (delBa);
552  if (delBa.IsByOriginator ())
553  {
554  GetBaManager (delBa.GetTid ())->DestroyAgreement (mpdu->GetHeader ().GetAddr1 (),
555  delBa.GetTid ());
556  }
557  else
558  {
559  DestroyBlockAckAgreement (mpdu->GetHeader ().GetAddr1 (), delBa.GetTid ());
560  }
561  }
563  {
564  // Setup ADDBA response timeout
565  MgtAddBaRequestHeader addBa;
566  p->PeekHeader (addBa);
567  Ptr<QosTxop> edca = m_mac->GetQosTxop (addBa.GetTid ());
570  mpdu->GetHeader ().GetAddr1 (), addBa.GetTid ());
571  }
572  }
573  }
575 }
576 
577 void
579 {
580  NS_LOG_DEBUG (this);
581 
582  if (m_edca != 0 && m_edca->GetTxopLimit ().IsZero () && m_edca->GetBaManager ()->GetBar (false) != 0)
583  {
584  // A TXOP limit of 0 indicates that the TXOP holder may transmit or cause to
585  // be transmitted (as responses) the following within the current TXOP:
586  // f) Any number of BlockAckReq frames
587  // (Sec. 10.22.2.8 of 802.11-2016)
588  NS_LOG_DEBUG ("Schedule a transmission from Block Ack Manager in a SIFS");
590 
591  // TXOP limit is null, hence the txopDuration parameter is unused
592  Simulator::Schedule (m_phy->GetSifs (), fp, this, m_edca, Seconds (0));
593  }
594  else
595  {
597  }
598 }
599 
600 void
602 {
603  NS_LOG_FUNCTION (this << *mpdu);
604 
605  if (mpdu->GetHeader ().IsQosData ())
606  {
607  GetBaManager (mpdu->GetHeader ().GetQosTid ())->NotifyDiscardedMpdu (mpdu);
608  }
609  else if (mpdu->GetHeader ().IsAction ())
610  {
611  WifiActionHeader actionHdr;
612  mpdu->GetPacket ()->PeekHeader (actionHdr);
613  if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK)
614  {
615  uint8_t tid = GetTid (mpdu->GetPacket (), mpdu->GetHeader ());
616  if (GetBaManager (tid)->ExistsAgreementInState (mpdu->GetHeader ().GetAddr1 (), tid,
618  {
619  NS_LOG_DEBUG ("No ACK after ADDBA request");
620  GetBaManager (tid)->NotifyAgreementNoReply (mpdu->GetHeader ().GetAddr1 (), tid);
621  Ptr<QosTxop> qosTxop = m_mac->GetQosTxop (tid);
623  mpdu->GetHeader ().GetAddr1 (), tid);
624  }
625  }
626  }
628 }
629 
630 void
632 {
633  NS_LOG_FUNCTION (this << *mpdu);
634 
635  if (mpdu->GetHeader ().IsQosData ())
636  {
637  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
638  Ptr<QosTxop> edca = m_mac->GetQosTxop (tid);
639 
640  if (edca->GetBaAgreementEstablished (mpdu->GetHeader ().GetAddr1 (), tid))
641  {
642  // notify the BA manager that the MPDU was not acknowledged
643  edca->GetBaManager ()->NotifyMissedAck (mpdu);
644  return;
645  }
646  }
648 }
649 
650 void
652 {
653  NS_LOG_FUNCTION (this << *mpdu);
654 
655  // the MPDU should be still in the queue, unless it expired.
656  const WifiMacHeader& hdr = mpdu->GetHeader ();
657  if (hdr.IsQosData ())
658  {
659  uint8_t tid = hdr.GetQosTid ();
660  Ptr<QosTxop> edca = m_mac->GetQosTxop (tid);
661 
662  if (edca->GetBaAgreementEstablished (hdr.GetAddr1 (), tid)
663  && !hdr.IsRetry ())
664  {
665  // The MPDU has never been transmitted, so we can make its sequence
666  // number available again if it is lower than the sequence number
667  // maintained by the MAC TX middle
668  uint16_t currentNextSeq = m_txMiddle->PeekNextSequenceNumberFor (&hdr);
669  uint16_t startingSeq = edca->GetBaStartingSequence (hdr.GetAddr1 (), tid);
670 
671  if (BlockAckAgreement::GetDistance (hdr.GetSequenceNumber (), startingSeq)
672  < BlockAckAgreement::GetDistance (currentNextSeq, startingSeq))
673  {
674  m_txMiddle->SetSequenceNumberFor (&hdr);
675  }
676 
677  return;
678  }
679  }
681 }
682 
683 Time
685 {
686  NS_LOG_FUNCTION (this << txDuration << &txParams);
687 
688  NS_ASSERT (m_edca != 0);
689 
690  if (m_edca->GetTxopLimit ().IsZero ())
691  {
692  NS_ASSERT (txParams.m_acknowledgment && txParams.m_acknowledgment->acknowledgmentTime != Time::Min ());
693  return txParams.m_acknowledgment->acknowledgmentTime;
694  }
695 
696  // under multiple protection settings, if the TXOP limit is not null, Duration/ID
697  // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
698  // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
699  // of 802.11-2016)
700  return std::max (m_edca->GetRemainingTxop () - txDuration, Seconds (0));
701 }
702 
703 void
705 {
706  NS_LOG_FUNCTION (this << psdu << &txParams);
707 
708  m_psdu = psdu;
709  m_txParams = std::move (txParams);
710 
711 #ifdef NS3_BUILD_PROFILE_DEBUG
712  // If protection is required, the MPDUs must be stored in some queue because
713  // they are not put back in a queue if the RTS/CTS exchange fails
715  {
716  for (const auto& mpdu : *PeekPointer (m_psdu))
717  {
718  NS_ASSERT (mpdu->GetHeader ().IsCtl () || mpdu->IsQueued ());
719  }
720  }
721 #endif
722 
723  // Make sure that the acknowledgment time has been computed, so that SendRts()
724  // and SendCtsToSelf() can reuse this value.
726 
727  if (m_txParams.m_acknowledgment->acknowledgmentTime == Time::Min ())
728  {
730  }
731 
732  // Set QoS Ack policy
734 
736  {
738  }
740  {
742  }
743  else if (m_txParams.m_protection->method == WifiProtection::NONE)
744  {
745  SendPsdu ();
746  }
747  else
748  {
749  NS_ABORT_MSG ("Unknown protection type");
750  }
751 }
752 
753 void
755 {
756  NS_LOG_FUNCTION (this << *rts << txVector);
757 
758  if (m_psdu == 0)
759  {
760  // A CTS Timeout occurred when protecting a single MPDU is handled by the
761  // parent classes
762  QosFrameExchangeManager::CtsTimeout (rts, txVector);
763  return;
764  }
765 
766  NS_ASSERT (m_psdu->GetNMpdus () > 1);
767  m_mac->GetWifiRemoteStationManager ()->ReportRtsFailed (m_psdu->GetHeader (0));
768 
769  if (!m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (*m_psdu->begin ()))
770  {
771  NS_LOG_DEBUG ("Missed CTS, discard MPDUs");
772  m_mac->GetWifiRemoteStationManager ()->ReportFinalRtsFailed (m_psdu->GetHeader (0));
773  // Dequeue the MPDUs if they are stored in a queue
775  for (const auto& mpdu : *PeekPointer (m_psdu))
776  {
777  NotifyPacketDiscarded (mpdu);
778  }
779  m_edca->ResetCw ();
780  }
781  else
782  {
783  NS_LOG_DEBUG ("Missed CTS, retransmit MPDUs");
784  for (const auto& mpdu : *PeekPointer (m_psdu))
785  {
787  }
789  }
790  m_psdu = 0;
792 }
793 
794 void
796 {
797  NS_LOG_FUNCTION (this);
798 
800 
802 
804  {
806  }
808  {
810 
811  // the timeout duration is "aSIFSTime + aSlotTime + aRxPHYStartDelay, starting
812  // at the PHY-TXEND.confirm primitive" (section 10.3.2.9 or 10.22.2.2 of 802.11-2016).
813  // aRxPHYStartDelay equals the time to transmit the PHY header.
814  WifiBlockAck* blockAcknowledgment = static_cast<WifiBlockAck*> (m_txParams.m_acknowledgment.get ());
815 
816  Time timeout = txDuration
817  + m_phy->GetSifs ()
818  + m_phy->GetSlot ()
822  this, m_psdu, m_txParams.m_txVector);
823  m_channelAccessManager->NotifyAckTimeoutStartNow (timeout);
824  }
826  {
828 
829  // schedule the transmission of a BAR in a SIFS
830  std::set<uint8_t> tids = m_psdu->GetTids ();
831  NS_ABORT_MSG_IF (tids.size () > 1, "Acknowledgment method incompatible with a Multi-TID A-MPDU");
832  uint8_t tid = *tids.begin ();
833 
834  Ptr<QosTxop> edca = m_mac->GetQosTxop (tid);
835  edca->ScheduleBar (edca->PrepareBlockAckRequest (m_psdu->GetAddr1 (), tid));
836 
838  }
839  else
840  {
841  NS_ABORT_MSG ("Unable to handle the selected acknowledgment method ("
842  << m_txParams.m_acknowledgment.get () << ")");
843  }
844 
845  // transmit the PSDU
846  if (m_psdu->GetNMpdus () > 1)
847  {
849  }
850  else
851  {
853  }
854 
856  {
857  // we are done in case the A-MPDU does not require acknowledgment
858  m_psdu = 0;
859  }
860 }
861 
862 void
864 {
865  NS_LOG_FUNCTION (this << psdu);
866 
867  // use an array to avoid computing the queue size for every MPDU in the PSDU
868  std::array<std::optional<uint8_t>, 8> queueSizeForTid;
869 
870  for (const auto& mpdu : *PeekPointer (psdu))
871  {
872  WifiMacHeader& hdr = mpdu->GetHeader ();
873 
874  if (hdr.IsQosData ())
875  {
876  uint8_t tid = hdr.GetQosTid ();
877  Ptr<QosTxop> edca = m_mac->GetQosTxop (tid);
878 
879  if (m_mac->GetTypeOfStation () == STA
880  && (m_setQosQueueSize || hdr.IsQosEosp ()))
881  {
882  // set the Queue Size subfield of the QoS Control field
883  if (!queueSizeForTid[tid].has_value ())
884  {
885  queueSizeForTid[tid] = edca->GetQosQueueSize (tid, hdr.GetAddr1 ());
886  }
887 
888  hdr.SetQosEosp ();
889  hdr.SetQosQueueSize (queueSizeForTid[tid].value ());
890  }
891 
892  if (hdr.HasData ())
893  {
894  edca->CompleteMpduTx (mpdu);
895  }
896  }
897  }
898 }
899 
900 void
902 {
903  DequeuePsdu (Create<const WifiPsdu> (mpdu, true));
904 }
905 
906 void
908 {
909  NS_LOG_DEBUG (this << psdu);
910 
911  for (const auto& mpdu : *PeekPointer (psdu))
912  {
913  if (mpdu->GetQueueIteratorPairs ().size () > 1)
914  {
915  // this MPDU contains an A-MSDU
916  for (const auto& queueIt : mpdu->GetQueueIteratorPairs ())
917  {
918  NS_ASSERT (*queueIt.it != mpdu);
919  queueIt.queue->Dequeue (queueIt.it);
920  }
921  }
922  else if (mpdu->IsQueued ())
923  {
924  WifiMacQueueItem::QueueIteratorPair queueIt = mpdu->GetQueueIteratorPairs ().front ();
925  NS_ASSERT (*queueIt.it == mpdu);
926  queueIt.queue->Dequeue (queueIt.it);
927  }
928  }
929 }
930 
931 void
933 {
934  NS_LOG_FUNCTION (this << psdu << txVector);
935 
936  NS_LOG_DEBUG ("Transmitting a PSDU: " << *psdu << " TXVECTOR: " << txVector);
937  NotifyTxToEdca (psdu);
938 
939  if (psdu->IsAggregate ())
940  {
941  txVector.SetAggregation (true);
942  }
943 
944  // The PSDU is about to be transmitted, we can now dequeue the MPDUs
945  DequeuePsdu (psdu);
946 
947  m_phy->Send (psdu, txVector);
948 }
949 
950 bool
952  const WifiTxParameters& txParams,
953  Time ppduDurationLimit) const
954 {
955  NS_ASSERT (mpdu != 0);
956  NS_LOG_FUNCTION (this << *mpdu << &txParams << ppduDurationLimit);
957 
958  Mac48Address receiver = mpdu->GetHeader ().GetAddr1 ();
959  uint32_t ampduSize = txParams.GetSizeIfAddMpdu (mpdu);
960 
961  if (txParams.GetSize (receiver) > 0)
962  {
963  // we are attempting to perform A-MPDU aggregation, hence we have to check
964  // that we meet the limit on the max A-MPDU size
965  uint8_t tid;
966  const WifiTxParameters::PsduInfo* info;
967 
968  if (mpdu->GetHeader ().IsQosData ())
969  {
970  tid = mpdu->GetHeader ().GetQosTid ();
971  }
972  else if ((info = txParams.GetPsduInfo (receiver)) && !info->seqNumbers.empty ())
973  {
974  tid = info->seqNumbers.begin ()->first;
975  }
976  else
977  {
978  NS_ABORT_MSG ("Cannot aggregate a non-QoS data frame to an A-MPDU that does"
979  " not contain any QoS data frame");
980  }
981 
982  WifiModulationClass modulation = txParams.m_txVector.GetModulationClass ();
983 
984  if (!IsWithinAmpduSizeLimit (ampduSize, receiver, tid, modulation))
985  {
986  return false;
987  }
988  }
989 
990  return IsWithinSizeAndTimeLimits (ampduSize, receiver, txParams, ppduDurationLimit);
991 }
992 
993 bool
994 HtFrameExchangeManager::IsWithinAmpduSizeLimit (uint32_t ampduSize, Mac48Address receiver, uint8_t tid,
995  WifiModulationClass modulation) const
996 {
997  NS_LOG_FUNCTION (this << ampduSize << receiver << +tid << modulation);
998 
999  uint32_t maxAmpduSize = m_mpduAggregator->GetMaxAmpduSize (receiver, tid, modulation);
1000 
1001  if (maxAmpduSize == 0)
1002  {
1003  NS_LOG_DEBUG ("A-MPDU aggregation disabled");
1004  return false;
1005  }
1006 
1007  if (ampduSize > maxAmpduSize)
1008  {
1009  NS_LOG_DEBUG ("the frame does not meet the constraint on max A-MPDU size ("
1010  << maxAmpduSize << ")");
1011  return false;
1012  }
1013  return true;
1014 }
1015 
1016 bool
1018  Time availableTime) const
1019 {
1020  NS_ASSERT (msdu != 0 && msdu->GetHeader ().IsQosData ());
1021  NS_LOG_FUNCTION (this << *msdu << &txParams << availableTime);
1022 
1023  // check if aggregating the given MSDU requires a different protection method
1024  NS_ASSERT (txParams.m_protection);
1025  Time protectionTime = txParams.m_protection->protectionTime;
1026 
1027  std::unique_ptr<WifiProtection> protection;
1028  protection = GetProtectionManager ()->TryAggregateMsdu (msdu, txParams);
1029  bool protectionSwapped = false;
1030 
1031  if (protection)
1032  {
1033  // the protection method has changed, calculate the new protection time
1034  CalculateProtectionTime (protection.get ());
1035  protectionTime = protection->protectionTime;
1036  // swap unique pointers, so that the txParams that is passed to the next
1037  // call to IsWithinLimitsIfAggregateMsdu is the most updated one
1038  txParams.m_protection.swap (protection);
1039  protectionSwapped = true;
1040  }
1041  NS_ASSERT (protectionTime != Time::Min ());
1042 
1043  // check if aggregating the given MSDU requires a different acknowledgment method
1044  NS_ASSERT (txParams.m_acknowledgment);
1045  Time acknowledgmentTime = txParams.m_acknowledgment->acknowledgmentTime;
1046 
1047  std::unique_ptr<WifiAcknowledgment> acknowledgment;
1048  acknowledgment = GetAckManager ()->TryAggregateMsdu (msdu, txParams);
1049  bool acknowledgmentSwapped = false;
1050 
1051  if (acknowledgment)
1052  {
1053  // the acknowledgment method has changed, calculate the new acknowledgment time
1054  CalculateAcknowledgmentTime (acknowledgment.get ());
1055  acknowledgmentTime = acknowledgment->acknowledgmentTime;
1056  // swap unique pointers, so that the txParams that is passed to the next
1057  // call to IsWithinLimitsIfAggregateMsdu is the most updated one
1058  txParams.m_acknowledgment.swap (acknowledgment);
1059  acknowledgmentSwapped = true;
1060  }
1061  NS_ASSERT (acknowledgmentTime != Time::Min ());
1062 
1063  Time ppduDurationLimit = Time::Min ();
1064  if (availableTime != Time::Min ())
1065  {
1066  ppduDurationLimit = availableTime - protectionTime - acknowledgmentTime;
1067  }
1068 
1069  if (!IsWithinLimitsIfAggregateMsdu (msdu, txParams, ppduDurationLimit))
1070  {
1071  // adding MPDU failed, restore protection and acknowledgment methods
1072  // if they were swapped
1073  if (protectionSwapped)
1074  {
1075  txParams.m_protection.swap (protection);
1076  }
1077  if (acknowledgmentSwapped)
1078  {
1079  txParams.m_acknowledgment.swap (acknowledgment);
1080  }
1081  return false;
1082  }
1083 
1084  // the given MPDU can be added, hence update the txParams
1085  txParams.AggregateMsdu (msdu);
1086  UpdateTxDuration (msdu->GetHeader ().GetAddr1 (), txParams);
1087 
1088  return true;
1089 }
1090 
1091 bool
1093  const WifiTxParameters& txParams,
1094  Time ppduDurationLimit) const
1095 {
1096  NS_ASSERT (msdu != 0 && msdu->GetHeader ().IsQosData ());
1097  NS_LOG_FUNCTION (this << *msdu << &txParams << ppduDurationLimit);
1098 
1099  std::pair<uint16_t, uint32_t> ret = txParams.GetSizeIfAggregateMsdu (msdu);
1100  Mac48Address receiver = msdu->GetHeader ().GetAddr1 ();
1101  uint8_t tid = msdu->GetHeader ().GetQosTid ();
1102  WifiModulationClass modulation = txParams.m_txVector.GetModulationClass ();
1103 
1104  // Check that the limit on A-MSDU size is met
1105  uint16_t maxAmsduSize = m_msduAggregator->GetMaxAmsduSize (receiver, tid, modulation);
1106 
1107  if (maxAmsduSize == 0)
1108  {
1109  NS_LOG_DEBUG ("A-MSDU aggregation disabled");
1110  return false;
1111  }
1112 
1113  if (ret.first > maxAmsduSize)
1114  {
1115  NS_LOG_DEBUG ("No other MSDU can be aggregated: maximum A-MSDU size ("
1116  << maxAmsduSize << ") reached ");
1117  return false;
1118  }
1119 
1120  const WifiTxParameters::PsduInfo* info = txParams.GetPsduInfo (msdu->GetHeader ().GetAddr1 ());
1121  NS_ASSERT (info != nullptr);
1122 
1123  if (info->ampduSize > 0)
1124  {
1125  // the A-MSDU being built is aggregated to other MPDUs in an A-MPDU.
1126  // Check that the limit on A-MPDU size is met.
1127  if (!IsWithinAmpduSizeLimit (ret.second, receiver, tid, modulation))
1128  {
1129  return false;
1130  }
1131  }
1132 
1133  return IsWithinSizeAndTimeLimits (ret.second, receiver, txParams, ppduDurationLimit);
1134 }
1135 
1136 void
1138 {
1139  NS_LOG_FUNCTION (this << *psdu << txVector);
1140 
1141  m_mac->GetWifiRemoteStationManager ()->ReportDataFailed (*psdu->begin ());
1142 
1143  bool resetCw;
1144  MissedBlockAck (psdu, txVector, resetCw);
1145 
1146  NS_ASSERT (m_edca != 0);
1147 
1148  if (resetCw)
1149  {
1150  m_edca->ResetCw ();
1151  }
1152  else
1153  {
1154  m_edca->UpdateFailedCw ();
1155  }
1156 
1157  m_psdu = 0;
1158  TransmissionFailed ();
1159 }
1160 
1161 void
1163 {
1164  NS_LOG_FUNCTION (this << psdu << txVector << resetCw);
1165 
1166  Mac48Address recipient = psdu->GetAddr1 ();
1167  bool isBar;
1168  uint8_t tid;
1169 
1170  if (psdu->GetNMpdus () == 1 && psdu->GetHeader (0).IsBlockAckReq ())
1171  {
1172  isBar = true;
1173  CtrlBAckRequestHeader baReqHdr;
1174  psdu->GetPayload (0)->PeekHeader (baReqHdr);
1175  tid = baReqHdr.GetTidInfo ();
1176  }
1177  else
1178  {
1179  isBar = false;
1180  m_mac->GetWifiRemoteStationManager ()->ReportAmpduTxStatus (recipient, 0, psdu->GetNMpdus (),
1181  0, 0, txVector);
1182  std::set<uint8_t> tids = psdu->GetTids ();
1183  NS_ABORT_MSG_IF (tids.size () > 1, "Multi-TID A-MPDUs not handled here");
1184  NS_ASSERT (!tids.empty ());
1185  tid = *tids.begin ();
1186  }
1187 
1188  Ptr<QosTxop> edca = m_mac->GetQosTxop (tid);
1189 
1190  if (edca->UseExplicitBarAfterMissedBlockAck () || isBar)
1191  {
1192  // we have to send a BlockAckReq, if needed
1193  if (GetBaManager (tid)->NeedBarRetransmission (tid, recipient))
1194  {
1195  NS_LOG_DEBUG ("Missed Block Ack, transmit a BlockAckReq");
1196  if (isBar)
1197  {
1198  psdu->GetHeader (0).SetRetry ();
1199  edca->ScheduleBar (*psdu->begin ());
1200  }
1201  else
1202  {
1203  // missed block ack after data frame with Implicit BAR Ack policy
1204  edca->ScheduleBar (edca->PrepareBlockAckRequest (recipient, tid));
1205  }
1206  resetCw = false;
1207  }
1208  else
1209  {
1210  NS_LOG_DEBUG ("Missed Block Ack, do not transmit a BlockAckReq");
1211  // if a BA agreement exists, we can get here if there is no outstanding
1212  // MPDU whose lifetime has not expired yet.
1213  m_mac->GetWifiRemoteStationManager ()->ReportFinalDataFailed (*psdu->begin ());
1214  if (GetBaManager (tid)->ExistsAgreementInState (recipient, tid,
1216  {
1217  // If there is any (expired) outstanding MPDU, request the BA manager to discard
1218  // it, which involves the scheduling of a BAR to advance the recipient's window
1219  if (GetBaManager (tid)->GetNBufferedPackets (recipient, tid) > 0)
1220  {
1221  GetBaManager (tid)->DiscardOutstandingMpdus (recipient, tid);
1222  }
1223  // otherwise, it means that we have not received a Block Ack in response to a
1224  // BlockAckRequest sent while no frame was outstanding, whose purpose was therefore
1225  // to advance the recipient's window. Schedule a BlockAckRequest with
1226  // skipIfNoDataQueued set to true, so that the BlockAckRequest is only sent
1227  // if there are data frames queued for this recipient.
1228  else
1229  {
1230  edca->ScheduleBar (edca->PrepareBlockAckRequest (recipient, tid), true);
1231  }
1232  }
1233  resetCw = true;
1234  }
1235  }
1236  else
1237  {
1238  // we have to retransmit the data frames, if needed
1239  if (!m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (*psdu->begin ()))
1240  {
1241  NS_LOG_DEBUG ("Missed Block Ack, do not retransmit the data frames");
1242  m_mac->GetWifiRemoteStationManager ()->ReportFinalDataFailed (*psdu->begin ());
1243  for (const auto& mpdu : *PeekPointer (psdu))
1244  {
1246  }
1247  GetBaManager (tid)->DiscardOutstandingMpdus (recipient, tid);
1248  resetCw = true;
1249  }
1250  else
1251  {
1252  NS_LOG_DEBUG ("Missed Block Ack, retransmit data frames");
1253  GetBaManager (tid)->NotifyMissedBlockAck (recipient, tid);
1254  resetCw = false;
1255  }
1256  }
1257 }
1258 
1259 void
1261  WifiTxVector& blockAckTxVector, double rxSnr)
1262 {
1263  NS_LOG_FUNCTION (this << durationId << blockAckTxVector << rxSnr);
1264 
1265  WifiMacHeader hdr;
1267  hdr.SetAddr1 (agreement.GetPeer ());
1268  hdr.SetAddr2 (m_self);
1269  hdr.SetDsNotFrom ();
1270  hdr.SetDsNotTo ();
1271 
1272  CtrlBAckResponseHeader blockAck;
1273  blockAck.SetType (agreement.GetBlockAckType ());
1274  blockAck.SetTidInfo (agreement.GetTid ());
1275  agreement.FillBlockAckBitmap (&blockAck);
1276 
1277  Ptr<Packet> packet = Create<Packet> ();
1278  packet->AddHeader (blockAck);
1279  Ptr<WifiPsdu> psdu = GetWifiPsdu (Create<WifiMacQueueItem> (packet, hdr), blockAckTxVector);
1280 
1281  // 802.11-2016, Section 9.2.5.7: In a BlockAck frame transmitted in response
1282  // to a BlockAckReq frame or transmitted in response to a frame containing an
1283  // implicit block ack request, the Duration/ID field is set to the value obtained
1284  // from the Duration/ ID field of the frame that elicited the response minus the
1285  // time, in microseconds between the end of the PPDU carrying the frame that
1286  // elicited the response and the end of the PPDU carrying the BlockAck frame.
1287  Time baDurationId = durationId - m_phy->GetSifs ()
1288  - m_phy->CalculateTxDuration (psdu, blockAckTxVector, m_phy->GetPhyBand ());
1289  // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8 of 802.11-2016)
1290  if (baDurationId.IsStrictlyNegative ())
1291  {
1292  baDurationId = Seconds (0);
1293  }
1294  psdu->GetHeader (0).SetDuration (baDurationId);
1295 
1296  SnrTag tag;
1297  tag.Set (rxSnr);
1298  psdu->GetPayload (0)->AddPacketTag (tag);
1299 
1300  ForwardPsduDown (psdu, blockAckTxVector);
1301 }
1302 
1303 bool
1305 {
1306  return (m_agreements.find ({originator, tid}) != m_agreements.end ());
1307 }
1308 
1311 {
1312  auto it = m_agreements.find ({originator, tid});
1313  NS_ABORT_MSG_IF (it == m_agreements.end (), "No established Block Ack agreement");
1314  return it->second.GetBlockAckType ();
1315 }
1316 
1317 void
1319  const WifiTxVector& txVector, bool inAmpdu)
1320 {
1321  // The received MPDU is either broadcast or addressed to this station
1322  NS_ASSERT (mpdu->GetHeader ().GetAddr1 ().IsGroup ()
1323  || mpdu->GetHeader ().GetAddr1 () == m_self);
1324 
1325  double rxSnr = rxSignalInfo.snr;
1326  const WifiMacHeader& hdr = mpdu->GetHeader ();
1327 
1328  if (hdr.IsCtl ())
1329  {
1331  && m_psdu != 0)
1332  {
1333  NS_ABORT_MSG_IF (inAmpdu, "Received CTS as part of an A-MPDU");
1334  NS_ASSERT (hdr.GetAddr1 () == m_self);
1335 
1336  Mac48Address sender = m_psdu->GetAddr1 ();
1337  NS_LOG_DEBUG ("Received CTS from=" << sender);
1338 
1339  SnrTag tag;
1340  mpdu->GetPacket ()->PeekPacketTag (tag);
1341  m_mac->GetWifiRemoteStationManager ()->ReportRxOk (sender, rxSignalInfo, txVector);
1342  m_mac->GetWifiRemoteStationManager ()->ReportRtsOk (m_psdu->GetHeader (0),
1343  rxSnr, txVector.GetMode (), tag.Get ());
1344 
1345  m_txTimer.Cancel ();
1346  m_channelAccessManager->NotifyCtsTimeoutResetNow ();
1348  }
1349  else if (hdr.IsBlockAck () && m_txTimer.IsRunning ()
1351  && hdr.GetAddr1 () == m_self)
1352  {
1353  Mac48Address sender = hdr.GetAddr2 ();
1354  NS_LOG_DEBUG ("Received BlockAck from=" << sender);
1355 
1356  SnrTag tag;
1357  mpdu->GetPacket ()->PeekPacketTag (tag);
1358 
1359  // notify the Block Ack Manager
1360  CtrlBAckResponseHeader blockAck;
1361  mpdu->GetPacket ()->PeekHeader (blockAck);
1362  uint8_t tid = blockAck.GetTidInfo ();
1363  std::pair<uint16_t,uint16_t> ret = GetBaManager (tid)->NotifyGotBlockAck (blockAck, hdr.GetAddr2 (), {tid});
1364  m_mac->GetWifiRemoteStationManager ()->ReportAmpduTxStatus (hdr.GetAddr2 (), ret.first, ret.second,
1365  rxSnr, tag.Get (), m_txParams.m_txVector);
1366 
1367  // cancel the timer
1368  m_txTimer.Cancel ();
1369  m_channelAccessManager->NotifyAckTimeoutResetNow ();
1370 
1371  // Reset the CW
1372  m_edca->ResetCw ();
1373 
1374  m_psdu = 0;
1376  }
1377  else if (hdr.IsBlockAckReq ())
1378  {
1379  NS_ASSERT (hdr.GetAddr1 () == m_self);
1380  NS_ABORT_MSG_IF (inAmpdu, "BlockAckReq in A-MPDU is not supported");
1381 
1382  Mac48Address sender = hdr.GetAddr2 ();
1383  NS_LOG_DEBUG ("Received BlockAckReq from=" << sender);
1384 
1385  CtrlBAckRequestHeader blockAckReq;
1386  mpdu->GetPacket ()->PeekHeader (blockAckReq);
1387  NS_ABORT_MSG_IF (blockAckReq.IsMultiTid (), "Multi-TID BlockAckReq not supported");
1388  uint8_t tid = blockAckReq.GetTidInfo ();
1389 
1390  auto agreementIt = m_agreements.find ({sender, tid});
1391 
1392  if (agreementIt == m_agreements.end ())
1393  {
1394  NS_LOG_DEBUG ("There's not a valid agreement for this BlockAckReq");
1395  return;
1396  }
1397 
1398  agreementIt->second.NotifyReceivedBar (blockAckReq.GetStartingSequence ());
1399 
1400  NS_LOG_DEBUG ("Schedule Block Ack");
1402  agreementIt->second, hdr.GetDuration (),
1403  m_mac->GetWifiRemoteStationManager ()->GetBlockAckTxVector (sender, txVector),
1404  rxSnr);
1405  }
1406  else
1407  {
1408  // the received control frame cannot be handled here
1409  QosFrameExchangeManager::ReceiveMpdu (mpdu, rxSignalInfo, txVector, inAmpdu);
1410  }
1411  return;
1412  }
1413 
1414  if (hdr.IsQosData () && hdr.HasData () && hdr.GetAddr1 () == m_self)
1415  {
1416  uint8_t tid = hdr.GetQosTid ();
1417 
1418  auto agreementIt = m_agreements.find ({hdr.GetAddr2 (), tid});
1419  if (agreementIt != m_agreements.end ())
1420  {
1421  // a Block Ack agreement has been established
1422  NS_LOG_DEBUG ("Received from=" << hdr.GetAddr2 ()
1423  << " (" << *mpdu << ")");
1424 
1425  agreementIt->second.NotifyReceivedMpdu (mpdu);
1426 
1427  if (!inAmpdu && hdr.GetQosAckPolicy () == WifiMacHeader::NORMAL_ACK)
1428  {
1429  NS_LOG_DEBUG ("Schedule Normal Ack");
1431  this, hdr, txVector, rxSnr);
1432  }
1433  return;
1434  }
1435  // We let the QosFrameExchangeManager handle QoS data frame not belonging
1436  // to a Block Ack agreement
1437  }
1438 
1439  QosFrameExchangeManager::ReceiveMpdu (mpdu, rxSignalInfo, txVector, inAmpdu);
1440 }
1441 
1442 void
1444  const WifiTxVector& txVector, const std::vector<bool>& perMpduStatus)
1445 {
1446  std::set<uint8_t> tids = psdu->GetTids ();
1447 
1448  // Multi-TID A-MPDUs are not supported yet
1449  if (tids.size () == 1)
1450  {
1451  uint8_t tid = *tids.begin ();
1452  WifiMacHeader::QosAckPolicy ackPolicy = psdu->GetAckPolicyForTid (tid);
1453  NS_ASSERT (psdu->GetNMpdus () > 1);
1454 
1455  if (ackPolicy == WifiMacHeader::NORMAL_ACK)
1456  {
1457  // Normal Ack or Implicit Block Ack Request
1458  NS_LOG_DEBUG ("Schedule Block Ack");
1459  auto agreementIt = m_agreements.find ({psdu->GetAddr2 (), tid});
1460  NS_ASSERT (agreementIt != m_agreements.end ());
1461 
1463  agreementIt->second, psdu->GetDuration (),
1464  m_mac->GetWifiRemoteStationManager ()->GetBlockAckTxVector (psdu->GetAddr2 (), txVector),
1465  rxSignalInfo.snr);
1466  }
1467  }
1468 }
1469 
1470 } //namespace ns3
ns3::FrameExchangeManager::CalculateAcknowledgmentTime
virtual void CalculateAcknowledgmentTime(WifiAcknowledgment *acknowledgment) const
Calculate the time required to acknowledge a frame according to the given acknowledgment method.
Definition: frame-exchange-manager.cc:488
ns3::GetBlockAckSize
uint32_t GetBlockAckSize(BlockAckType type)
Return the total BlockAck size (including FCS trailer).
Definition: wifi-utils.cc:172
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
ns3::FrameExchangeManager::RetransmitMpduAfterMissedAck
virtual void RetransmitMpduAfterMissedAck(Ptr< WifiMacQueueItem > mpdu) const
Retransmit an MPDU that was not acknowledged.
Definition: frame-exchange-manager.cc:794
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::BlockAckAgreement::GetTid
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Definition: block-ack-agreement.cc:100
ns3::WifiTxParameters::PsduInfo::ampduSize
uint32_t ampduSize
the size in bytes of the A-MPDU if multiple MPDUs have been added, and zero otherwise
Definition: wifi-tx-parameters.h:119
ns3::RecipientBlockAckAgreement::SetMacRxMiddle
void SetMacRxMiddle(const Ptr< MacRxMiddle > rxMiddle)
Set the MAC RX Middle to use.
Definition: recipient-block-ack-agreement.cc:68
ns3::QosFrameExchangeManager::m_setQosQueueSize
bool m_setQosQueueSize
whether to set the Queue Size subfield of the QoS Control field of QoS data frames
Definition: qos-frame-exchange-manager.h:161
ns3::WifiAcknowledgment::acknowledgmentTime
Time acknowledgmentTime
time required by the acknowledgment method
Definition: wifi-acknowledgment.h:104
ns3::FrameExchangeManager::m_txTimer
WifiTxTimer m_txTimer
the timer set upon frame transmission
Definition: frame-exchange-manager.h:379
ns3::MgtAddBaResponseHeader::IsImmediateBlockAck
bool IsImmediateBlockAck(void) const
Return whether the Block Ack policy is immediate Block Ack.
Definition: mgt-headers.cc:1762
NS_OBJECT_ENSURE_REGISTERED
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
NS_ASSERT
#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
ns3::HtFrameExchangeManager::CtsTimeout
void CtsTimeout(Ptr< WifiMacQueueItem > rts, const WifiTxVector &txVector) override
Called when the CTS timeout expires.
Definition: ht-frame-exchange-manager.cc:754
ns3::WifiNoProtection
WifiNoProtection specifies that no protection method is used.
Definition: wifi-protection.h:82
ns3::WifiMacQueueItem::GetPacket
Ptr< const Packet > GetPacket(void) const
Get the packet stored in this item.
Definition: wifi-mac-queue-item.cc:57
ns3::FrameExchangeManager::m_phy
Ptr< WifiPhy > m_phy
the PHY layer on this station
Definition: frame-exchange-manager.h:385
ns3::WifiMacHeader::SetDuration
void SetDuration(Time duration)
Set the Duration/ID field with the given duration (Time object).
Definition: wifi-mac-header.cc:300
ns3::Packet::PeekHeader
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
ns3::HtFrameExchangeManager::RetransmitMpduAfterMissedCts
void RetransmitMpduAfterMissedCts(Ptr< WifiMacQueueItem > mpdu) const override
Retransmit an MPDU that was not sent because a CTS was not received.
Definition: ht-frame-exchange-manager.cc:651
ns3::WifiPsdu::GetAddr1
Mac48Address GetAddr1(void) const
Get the Receiver Address (RA), which is common to all the MPDUs.
Definition: wifi-psdu.cc:111
ns3::FrameExchangeManager::SendNormalAck
void SendNormalAck(const WifiMacHeader &hdr, const WifiTxVector &dataTxVector, double dataSnr)
Send Normal Ack.
Definition: frame-exchange-manager.cc:679
ns3::MgtAddBaResponseHeader::GetBufferSize
uint16_t GetBufferSize(void) const
Return the buffer size.
Definition: mgt-headers.cc:1774
ns3::WifiTxParameters::GetPsduInfo
const PsduInfo * GetPsduInfo(Mac48Address receiver) const
Get a pointer to the information about the PSDU addressed to the given receiver, if present,...
Definition: wifi-tx-parameters.cc:80
ns3::WifiMacHeader::IsQosEosp
bool IsQosEosp(void) const
Return if the end of service period (EOSP) is set.
Definition: wifi-mac-header.cc:822
ns3::WifiAcknowledgment::NONE
@ NONE
Definition: wifi-acknowledgment.h:52
ns3::WifiPsdu::GetDuration
Time GetDuration(void) const
Get the duration from the Duration/ID field, which is common to all the MPDUs.
Definition: wifi-psdu.cc:141
ns3::Mac48Address::IsGroup
bool IsGroup(void) const
Definition: mac48-address.cc:164
ns3::MgtAddBaRequestHeader::SetImmediateBlockAck
void SetImmediateBlockAck()
Enable immediate BlockAck.
Definition: mgt-headers.cc:1533
ns3::WifiPsdu::GetPayload
Ptr< const Packet > GetPayload(std::size_t i) const
Get the payload of the i-th MPDU.
Definition: wifi-psdu.cc:278
ns3::WifiPhy::GetSlot
Time GetSlot(void) const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:922
ns3::HtFrameExchangeManager::MissedBlockAck
virtual void MissedBlockAck(Ptr< WifiPsdu > psdu, const WifiTxVector &txVector, bool &resetCw)
Take necessary actions when a BlockAck is missed, such as scheduling a BlockAckReq frame or the retra...
Definition: ht-frame-exchange-manager.cc:1162
ns3::Packet::AddHeader
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
ns3::HtFrameExchangeManager::GetBlockAckType
BlockAckType GetBlockAckType(Mac48Address originator, uint8_t tid) const
Get the type of BlockAck frames sent to the given originator.
Definition: ht-frame-exchange-manager.cc:1310
ns3::WifiMacHeader::IsRetry
bool IsRetry(void) const
Return if the Retry bit is set.
Definition: wifi-mac-header.cc:789
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::WifiMacHeader::SetRetry
void SetRetry(void)
Set the Retry bit in the Frame Control field.
Definition: wifi-mac-header.cc:342
ns3::HtFrameExchangeManager::StartFrameExchange
bool StartFrameExchange(Ptr< QosTxop > edca, Time availableTime, bool initialFrame) override
Start a frame exchange (including protection frames and acknowledgment frames as needed) that fits wi...
Definition: ht-frame-exchange-manager.cc:332
ns3::HtFrameExchangeManager::SendMpduFromBaManager
virtual bool SendMpduFromBaManager(Ptr< QosTxop > edca, Time availableTime, bool initialFrame)
If the Block Ack Manager associated with the given EDCA has a BlockAckReq frame to transmit (the dura...
Definition: ht-frame-exchange-manager.cc:385
ns3::WifiPhy::CalculateTxDuration
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1610
ns3::WifiBlockAck
WifiBlockAck specifies that acknowledgment via Block Ack is required.
Definition: wifi-acknowledgment.h:162
ns3::WifiMacHeader::SetSequenceNumber
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
Definition: wifi-mac-header.cc:312
ns3::WIFI_MOD_CLASS_HT
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
Definition: wifi-phy-common.h:125
ns3::WifiProtection::CTS_TO_SELF
@ CTS_TO_SELF
Definition: wifi-protection.h:49
ns3::QosTxop::GetBlockAckThreshold
uint8_t GetBlockAckThreshold(void) const
Return the current threshold for block ack mechanism.
Definition: qos-txop.cc:694
ns3::QosFrameExchangeManager::TransmissionFailed
void TransmissionFailed(void) override
Take necessary actions upon a transmission failure.
Definition: qos-frame-exchange-manager.cc:566
ns3::MgtAddBaRequestHeader::SetBufferSize
void SetBufferSize(uint16_t size)
Set buffer size.
Definition: mgt-headers.cc:1552
ns3::QosTxop::GetBaAgreementEstablished
bool GetBaAgreementEstablished(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:245
ns3::CtrlBAckRequestHeader
Headers for BlockAckRequest.
Definition: ctrl-headers.h:49
ns3::MicroSeconds
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
ns3::MgtDelBaHeader::GetTid
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Definition: mgt-headers.cc:1872
ns3::WifiPsdu::GetAckPolicyForTid
WifiMacHeader::QosAckPolicy GetAckPolicyForTid(uint8_t tid) const
Get the QoS Ack Policy of the QoS Data frames included in the PSDU that have the given TID.
Definition: wifi-psdu.cc:180
ns3::WifiTxTimer::IsRunning
bool IsRunning(void) const
Return true if the timer is running.
Definition: wifi-tx-timer.cc:94
ns3::QosFrameExchangeManager::IsWithinSizeAndTimeLimits
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...
Definition: qos-frame-exchange-manager.cc:407
ns3::HtFrameExchangeManager::DoDispose
void DoDispose() override
Destructor implementation.
Definition: ht-frame-exchange-manager.cc:66
ns3::FrameExchangeManager::CalculateProtectionTime
virtual void CalculateProtectionTime(WifiProtection *protection) const
Calculate the time required to protect a frame according to the given protection method.
Definition: frame-exchange-manager.cc:459
ns3::QosFrameExchangeManager::TransmissionSucceeded
void TransmissionSucceeded(void) override
Take necessary actions upon a transmission success.
Definition: qos-frame-exchange-manager.cc:537
ns3::HtFrameExchangeManager::NeedSetupBlockAck
virtual bool NeedSetupBlockAck(Mac48Address recipient, uint8_t tid)
A Block Ack agreement needs to be established with the given recipient for the given TID if it does n...
Definition: ht-frame-exchange-manager.cc:104
ns3::FrameExchangeManager::SendCtsToSelf
void SendCtsToSelf(const WifiTxParameters &txParams)
Send CTS for a CTS-to-self mechanism.
Definition: frame-exchange-manager.cc:652
ns3::WifiMacHeader::SetDsNotFrom
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
Definition: wifi-mac-header.cc:90
ns3::HtFrameExchangeManager::IsWithinLimitsIfAggregateMsdu
virtual bool IsWithinLimitsIfAggregateMsdu(Ptr< const WifiMacQueueItem > msdu, const WifiTxParameters &txParams, Time ppduDurationLimit) const
Check if the PSDU obtained by aggregating the given MSDU to the PSDU specified by the given TX parame...
Definition: ht-frame-exchange-manager.cc:1092
ns3::WifiPhy::CalculatePhyPreambleAndHeaderDuration
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1604
ns3::WifiTxParameters::GetSize
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
Definition: wifi-tx-parameters.cc:227
ns3::HtFrameExchangeManager::SendAddBaRequest
void SendAddBaRequest(Mac48Address recipient, uint8_t tid, uint16_t startingSeq, uint16_t timeout, bool immediateBAck)
Sends an ADDBA Request to establish a block ack agreement with STA addressed by recipient for TID tid...
Definition: ht-frame-exchange-manager.cc:131
ns3::QosTxop::GetBaManager
Ptr< BlockAckManager > GetBaManager(void)
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:239
ns3::WifiMacQueueItem::QueueIteratorPair::queue
WifiMacQueue * queue
pointer to the queue where the MSDU is enqueued
Definition: wifi-mac-queue-item.h:148
ns3::MgtDelBaHeader::SetByOriginator
void SetByOriginator(void)
Set the initiator bit in the DELBA.
Definition: mgt-headers.cc:1880
ns3::QosFrameExchangeManager::ReceiveMpdu
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)
Definition: qos-frame-exchange-manager.cc:659
ns3::HtFrameExchangeManager::SendBlockAck
void SendBlockAck(const RecipientBlockAckAgreement &agreement, Time durationId, WifiTxVector &blockAckTxVector, double rxSnr)
Create a BlockAck frame with header equal to blockAck and start its transmission.
Definition: ht-frame-exchange-manager.cc:1260
ns3::HtFrameExchangeManager::SendPsduWithProtection
void SendPsduWithProtection(Ptr< WifiPsdu > psdu, WifiTxParameters &txParams)
Send a PSDU (A-MPDU or BlockAckReq frame) requesting a BlockAck frame or a BlockAckReq frame followed...
Definition: ht-frame-exchange-manager.cc:704
ns3::FrameExchangeManager::m_channelAccessManager
Ptr< ChannelAccessManager > m_channelAccessManager
the channel access manager
Definition: frame-exchange-manager.h:384
ns3::WifiTxVector::SetAggregation
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
Definition: wifi-tx-vector.cc:291
ns3::Txop::ResetCw
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
Definition: txop.cc:186
ns3::QosFrameExchangeManager::StartFrameExchange
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...
Definition: qos-frame-exchange-manager.cc:262
ns3::QosTxop::UseExplicitBarAfterMissedBlockAck
bool UseExplicitBarAfterMissedBlockAck(void) const
Return true if an explicit BlockAckRequest is sent after a missed BlockAck.
Definition: qos-txop.cc:291
ns3::MgtAddBaRequestHeader
Implement the header for management frames of type Add Block Ack request.
Definition: mgt-headers.h:1018
ns3::WifiActionHeader::ActionValue
typedef for union of different ActionValues
Definition: mgt-headers.h:956
ns3::HtFrameExchangeManager::SetWifiMac
void SetWifiMac(const Ptr< RegularWifiMac > mac) override
Set the MAC layer to use.
Definition: ht-frame-exchange-manager.cc:78
ns3::WifiMacHeader::IsCts
bool IsCts(void) const
Return true if the header is a CTS header.
Definition: wifi-mac-header.cc:657
ns3::HtFrameExchangeManager::CreateBlockAckAgreement
void CreateBlockAckAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address originator, uint16_t startingSeq)
Definition: ht-frame-exchange-manager.cc:284
ns3::QosTxop::GetNextMpdu
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:435
ns3::Mac48Address
an EUI-48 address
Definition: mac48-address.h:44
ns3::HtFrameExchangeManager::ForwardPsduDown
virtual void ForwardPsduDown(Ptr< const WifiPsdu > psdu, WifiTxVector &txVector)
Forward a PSDU down to the PHY layer.
Definition: ht-frame-exchange-manager.cc:932
ns3::QosFrameExchangeManager::StartTransmission
bool StartTransmission(Ptr< Txop > edca) override
Request the FrameExchangeManager to start a frame exchange sequence.
Definition: qos-frame-exchange-manager.cc:151
ns3::HtFrameExchangeManager::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: ht-frame-exchange-manager.cc:43
ns3::QosTxop::PeekNextMpdu
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:353
ns3::WifiTxVector
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Definition: wifi-tx-vector.h:71
ns3::HtFrameExchangeManager::SendDataFrame
virtual bool SendDataFrame(Ptr< const WifiMacQueueItem > peekedItem, Time availableTime, bool initialFrame)
Given a non-broadcast QoS data frame, prepare the PSDU to transmit by attempting A-MSDU and A-MPDU ag...
Definition: ht-frame-exchange-manager.cc:437
ns3::FrameExchangeManager::CtsTimeout
virtual void CtsTimeout(Ptr< WifiMacQueueItem > rts, const WifiTxVector &txVector)
Called when the CTS timeout expires.
Definition: frame-exchange-manager.cc:803
ns3::CtrlBAckRequestHeader::IsMultiTid
bool IsMultiTid(void) const
Check if the current Ack Policy has Multi-TID Block Ack.
Definition: ctrl-headers.cc:263
ns3::WifiMacHeader::GetAddr1
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
Definition: wifi-mac-header.cc:424
third.mac
mac
Definition: third.py:99
ns3::WifiMacHeader::SetQosQueueSize
void SetQosQueueSize(uint8_t size)
Set the Queue Size subfield in the QoS control field.
Definition: wifi-mac-header.cc:402
ns3::WifiMacHeader::SetAddr3
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
Definition: wifi-mac-header.cc:120
ns3::OriginatorBlockAckAgreement::PENDING
@ PENDING
Definition: originator-block-ack-agreement.h:103
ns3::FrameExchangeManager::m_self
Mac48Address m_self
the MAC address of this device
Definition: frame-exchange-manager.h:386
ns3::Packet::PeekPacketTag
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:978
ns3::QosTxop::GetQosQueueSize
uint8_t GetQosQueueSize(uint8_t tid, Mac48Address receiver) const
Get the value for the Queue Size subfield of the QoS Control field of a QoS data frame of the given T...
Definition: qos-txop.cc:126
ns3::WifiTxParameters
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
Definition: wifi-tx-parameters.h:45
ns3::Simulator::Schedule
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
ns3::WifiMacQueueItem::GetHeader
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
Definition: wifi-mac-queue-item.cc:63
ns3::WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST
@ BLOCK_ACK_ADDBA_REQUEST
Definition: mgt-headers.h:946
ns3::CtrlBAckResponseHeader::SetTidInfo
void SetTidInfo(uint8_t tid, std::size_t index=0)
For Block Ack variants other than Multi-STA Block Ack, set the TID_INFO subfield of the BA Control fi...
Definition: ctrl-headers.cc:477
ns3::QosTxop::AddBaResponseTimeout
void AddBaResponseTimeout(Mac48Address recipient, uint8_t tid)
Callback when ADDBA response is not received after timeout.
Definition: qos-txop.cc:715
ns3::MgtDelBaHeader::SetByRecipient
void SetByRecipient(void)
Un-set the initiator bit in the DELBA.
Definition: mgt-headers.cc:1886
ns3::Txop::GetTxopLimit
Time GetTxopLimit(void) const
Return the TXOP limit.
Definition: txop.cc:275
ns3::HtFrameExchangeManager::RetransmitMpduAfterMissedAck
void RetransmitMpduAfterMissedAck(Ptr< WifiMacQueueItem > mpdu) const override
Retransmit an MPDU that was not acknowledged.
Definition: ht-frame-exchange-manager.cc:631
ns3::PeekPointer
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:415
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
ns3::Txop::UpdateFailedCw
void UpdateFailedCw(void)
Update the value of the CW variable to take into account a transmission failure.
Definition: txop.cc:194
ns3::WifiBarBlockAck::barType
BlockAckReqType barType
BlockAckReq type.
Definition: wifi-acknowledgment.h:189
ns3::QosTxop::GetBlockAckInactivityTimeout
uint16_t GetBlockAckInactivityTimeout(void) const
Get the BlockAck inactivity timeout.
Definition: qos-txop.cc:701
ns3::MgtAddBaRequestHeader::SetDelayedBlockAck
void SetDelayedBlockAck()
Enable delayed BlockAck.
Definition: mgt-headers.cc:1527
ns3::WifiTxParameters::m_protection
std::unique_ptr< WifiProtection > m_protection
protection method
Definition: wifi-tx-parameters.h:63
ns3::GetTid
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr)
This function is useful to get traffic id of different packet types.
Definition: qos-utils.cc:187
ns3::BlockAckAgreement::SetImmediateBlockAck
void SetImmediateBlockAck(void)
Set block ack policy to immediate Ack.
Definition: block-ack-agreement.cc:79
ns3::QosTxop::GetBaStartingSequence
uint16_t GetBaStartingSequence(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:257
ns3::MgtAddBaResponseHeader::SetTid
void SetTid(uint8_t tid)
Set Traffic ID (TID).
Definition: mgt-headers.cc:1719
ns3::FrameExchangeManager::NotifyPacketDiscarded
virtual void NotifyPacketDiscarded(Ptr< const WifiMacQueueItem > mpdu)
Pass the given MPDU, discarded because of the max retry limit was reached, to the MPDU dropped callba...
Definition: frame-exchange-manager.cc:223
ns3::QosFrameExchangeManager::DoDispose
void DoDispose() override
Destructor implementation.
Definition: qos-frame-exchange-manager.cc:72
ns3::WifiMacHeader::SetAddr1
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
Definition: wifi-mac-header.cc:108
ns3::HtFrameExchangeManager::DestroyBlockAckAgreement
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
Destroy a Block Ack agreement.
Definition: ht-frame-exchange-manager.cc:318
ns3::BlockAckAgreement::GetTimeout
uint16_t GetTimeout(void) const
Return the timeout.
Definition: block-ack-agreement.cc:119
ns3::HtFrameExchangeManager::GetBaManager
Ptr< BlockAckManager > GetBaManager(uint8_t tid) const
Get the Block Ack Manager handling the given TID.
Definition: ht-frame-exchange-manager.cc:98
ns3::WifiMacQueueItem::QueueIteratorPair::it
ConstIterator it
iterator pointing to the MSDU in the queue
Definition: wifi-mac-queue-item.h:149
ns3::FrameExchangeManager::GetProtectionManager
Ptr< WifiProtectionManager > GetProtectionManager(void) const
Get the Protection Manager used by this node.
Definition: frame-exchange-manager.cc:111
ns3::MgtAddBaRequestHeader::IsAmsduSupported
bool IsAmsduSupported(void) const
Return whether A-MSDU capability is supported.
Definition: mgt-headers.cc:1600
ns3::MgtAddBaResponseHeader::SetTimeout
void SetTimeout(uint16_t timeout)
Set timeout.
Definition: mgt-headers.cc:1726
ns3::WifiMacHeader
Implements the IEEE 802.11 MAC header.
Definition: wifi-mac-header.h:85
ns3::HtFrameExchangeManager
HtFrameExchangeManager handles the frame exchange sequences for HT stations.
Definition: ht-frame-exchange-manager.h:45
ns3::GetBlockAckRequestSize
uint32_t GetBlockAckRequestSize(BlockAckReqType type)
Return the total BlockAckRequest size (including FCS trailer).
Definition: wifi-utils.cc:182
ns3::WifiBarBlockAck
WifiBarBlockAck specifies that a BlockAckReq is sent to solicit a Block Ack response.
Definition: wifi-acknowledgment.h:180
ns3::FrameExchangeManager::SendRts
void SendRts(const WifiTxParameters &txParams)
Send RTS to begin RTS-CTS-Data-Ack transaction.
Definition: frame-exchange-manager.cc:562
ns3::Ptr
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
ns3::WifiActionHeader
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:885
ns3::WifiActionHeader::GetAction
ActionValue GetAction()
Return the action value.
Definition: mgt-headers.cc:1247
ns3::HtFrameExchangeManager::m_msduAggregator
Ptr< MsduAggregator > m_msduAggregator
A-MSDU aggregator.
Definition: ht-frame-exchange-manager.h:381
ns3::MgtAddBaResponseHeader::GetTid
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Definition: mgt-headers.cc:1756
ns3::QosFrameExchangeManager
QosFrameExchangeManager handles the frame exchange sequences for QoS stations.
Definition: qos-frame-exchange-manager.h:37
ns3::WifiMacHeader::IsBlockAckReq
bool IsBlockAckReq(void) const
Return true if the header is a BlockAckRequest header.
Definition: wifi-mac-header.cc:741
ns3::WifiTxVector::GetModulationClass
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
Definition: wifi-tx-vector.cc:127
ns3::MgtAddBaResponseHeader::SetStatusCode
void SetStatusCode(StatusCode code)
Set the status code.
Definition: mgt-headers.cc:1738
ns3::WifiMacQueue::Dequeue
Ptr< WifiMacQueueItem > Dequeue(void) override
Dequeue the packet in the front of the queue.
Definition: wifi-mac-queue.cc:175
ns3::QosFrameExchangeManager::m_edca
Ptr< QosTxop > m_edca
the EDCAF that gained channel access
Definition: qos-frame-exchange-manager.h:159
ns3::WifiTxParameters::GetSizeIfAddMpdu
uint32_t GetSizeIfAddMpdu(Ptr< const WifiMacQueueItem > mpdu) const
Get the size in bytes of the frame in case the given MPDU is added.
Definition: wifi-tx-parameters.cc:147
ns3::QosTxop::ResetBa
void ResetBa(Mac48Address recipient, uint8_t tid)
Reset BA agreement after BA negotiation failed.
Definition: qos-txop.cc:732
ns3::HtFrameExchangeManager::TryAggregateMsdu
virtual bool TryAggregateMsdu(Ptr< const WifiMacQueueItem > msdu, WifiTxParameters &txParams, Time availableTime) const
Check if aggregating an MSDU to the current MPDU (as specified by the given TX parameters) does not v...
Definition: ht-frame-exchange-manager.cc:1017
max
#define max(a, b)
Definition: 80211b.c:43
ns3::MgtAddBaRequestHeader::GetStartingSequence
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
Definition: mgt-headers.cc:1606
ns3::FrameExchangeManager::SetWifiMac
virtual void SetWifiMac(const Ptr< RegularWifiMac > mac)
Set the MAC layer to use.
Definition: frame-exchange-manager.cc:130
ns3::Time::IsZero
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
ns3::HtFrameExchangeManager::m_mpduAggregator
Ptr< MpduAggregator > m_mpduAggregator
A-MPDU aggregator.
Definition: ht-frame-exchange-manager.h:382
ns3::WifiProtection::NONE
@ NONE
Definition: wifi-protection.h:47
ns3::WifiMacHeader::QosAckPolicy
QosAckPolicy
Ack policy for QoS frames.
Definition: wifi-mac-header.h:91
ns3::FrameExchangeManager::m_rxMiddle
Ptr< MacRxMiddle > m_rxMiddle
the MAC RX Middle on this station
Definition: frame-exchange-manager.h:383
ns3::WifiTxParameters::PsduInfo::seqNumbers
std::map< uint8_t, std::set< uint16_t > > seqNumbers
set of the sequence numbers of the MPDUs added for each TID
Definition: wifi-tx-parameters.h:121
ns3::BlockAckAgreement::GetPeer
Mac48Address GetPeer(void) const
Return the peer address.
Definition: block-ack-agreement.cc:106
ns3::WifiPsdu::GetHeader
const WifiMacHeader & GetHeader(std::size_t i) const
Get the header of the i-th MPDU.
Definition: wifi-psdu.cc:266
ns3::MgtDelBaHeader::SetTid
void SetTid(uint8_t tid)
Set Traffic ID (TID).
Definition: mgt-headers.cc:1892
ns3::MgtAddBaResponseHeader::SetDelayedBlockAck
void SetDelayedBlockAck()
Enable delayed BlockAck.
Definition: mgt-headers.cc:1707
ns3::StatusCode::SetSuccess
void SetSuccess(void)
Set success bit to 0 (success).
Definition: status-code.cc:30
ns3::WifiTxParameters::GetSizeIfAggregateMsdu
std::pair< uint32_t, uint32_t > GetSizeIfAggregateMsdu(Ptr< const WifiMacQueueItem > msdu) const
Get the size in bytes of the frame in case the given MSDU is aggregated.
Definition: wifi-tx-parameters.cc:187
ns3::HtFrameExchangeManager::ReceiveMpdu
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)
Definition: ht-frame-exchange-manager.cc:1318
ns3::BlockAckType
The different BlockAck variants.
Definition: block-ack-type.h:34
ns3::Packet::RemoveHeader
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
ns3::Txop::GetWifiMacQueue
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
Definition: txop.cc:149
ns3::MgtAddBaRequestHeader::SetTid
void SetTid(uint8_t tid)
Set Traffic ID (TID).
Definition: mgt-headers.cc:1539
ns3::OriginatorBlockAckAgreement::ESTABLISHED
@ ESTABLISHED
Definition: originator-block-ack-agreement.h:104
ns3::HtFrameExchangeManager::NotifyPacketDiscarded
void NotifyPacketDiscarded(Ptr< const WifiMacQueueItem > mpdu) override
Pass the given MPDU, discarded because of the max retry limit was reached, to the MPDU dropped callba...
Definition: ht-frame-exchange-manager.cc:601
ns3::WifiMacHeader::HasData
bool HasData(void) const
Return true if the header type is DATA and is not DATA_NULL.
Definition: wifi-mac-header.cc:632
ns3::HtFrameExchangeManager::m_txParams
WifiTxParameters m_txParams
the TX parameters for the current frame
Definition: ht-frame-exchange-manager.h:392
ns3::WifiActionHeader::ActionValue::blockAck
BlockAckActionValue blockAck
block ack
Definition: mgt-headers.h:960
ns3::WifiPsdu::GetSize
uint32_t GetSize(void) const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:260
ns3::WifiMacHeader::IsBlockAck
bool IsBlockAck(void) const
Return true if the header is a BlockAck header.
Definition: wifi-mac-header.cc:747
ns3::MgtAddBaRequestHeader::IsImmediateBlockAck
bool IsImmediateBlockAck(void) const
Return whether the Block Ack policy is immediate Block Ack.
Definition: mgt-headers.cc:1582
ns3::WifiMacHeader::NORMAL_ACK
@ NORMAL_ACK
Definition: wifi-mac-header.h:92
ns3::HtFrameExchangeManager::IsWithinLimitsIfAddMpdu
bool IsWithinLimitsIfAddMpdu(Ptr< const WifiMacQueueItem > mpdu, const WifiTxParameters &txParams, Time ppduDurationLimit) const override
Check if the PSDU obtained by aggregating the given MPDU to the PSDU specified by the given TX parame...
Definition: ht-frame-exchange-manager.cc:951
ns3::WifiTxParameters::Clear
void Clear(void)
Reset the TX parameters.
Definition: wifi-tx-parameters.cc:67
ns3::MgtAddBaRequestHeader::SetStartingSequence
void SetStartingSequence(uint16_t seq)
Set the starting sequence number.
Definition: mgt-headers.cc:1558
ns3::RecipientBlockAckAgreement
Maintains the scoreboard and the receive reordering buffer used by a recipient of a Block Ack agreeme...
Definition: recipient-block-ack-agreement.h:40
ns3::WifiPsdu::GetNMpdus
std::size_t GetNMpdus(void) const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:319
ns3::WifiMacHeader::IsQosData
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
Definition: wifi-mac-header.cc:565
ns3::MgtAddBaResponseHeader::GetTimeout
uint16_t GetTimeout(void) const
Return the timeout.
Definition: mgt-headers.cc:1768
ns3::WifiPhy::GetPhyBand
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1124
ns3::MgtAddBaResponseHeader::IsAmsduSupported
bool IsAmsduSupported(void) const
Return whether A-MSDU capability is supported.
Definition: mgt-headers.cc:1780
ns3::WifiPsdu::GetTids
std::set< uint8_t > GetTids(void) const
Get the set of TIDs of the QoS Data frames included in the PSDU.
Definition: wifi-psdu.cc:166
ns3::MgtAddBaRequestHeader::GetTid
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Definition: mgt-headers.cc:1576
ns3::HtFrameExchangeManager::~HtFrameExchangeManager
virtual ~HtFrameExchangeManager()
Definition: ht-frame-exchange-manager.cc:60
ns3::Time
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
ns3::WifiMacHeader::GetSequenceNumber
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
Definition: wifi-mac-header.cc:777
ns3::WifiTxTimer::WAIT_BLOCK_ACK
@ WAIT_BLOCK_ACK
Definition: wifi-tx-timer.h:59
NS_ABORT_MSG_IF
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
ns3::WifiPsdu::SetDuration
void SetDuration(Time duration)
Set the Duration/ID field on all the MPDUs.
Definition: wifi-psdu.cc:156
ns3::MgtAddBaRequestHeader::SetTimeout
void SetTimeout(uint16_t timeout)
Set timeout.
Definition: mgt-headers.cc:1546
ns3::SnrTag::Set
void Set(double snr)
Set the SNR to the given value.
Definition: snr-tag.cc:83
ns3::HtFrameExchangeManager::CalculateAcknowledgmentTime
void CalculateAcknowledgmentTime(WifiAcknowledgment *acknowledgment) const override
Calculate the time required to acknowledge a frame according to the given acknowledgment method.
Definition: ht-frame-exchange-manager.cc:483
ns3::MgtAddBaRequestHeader::GetTimeout
uint16_t GetTimeout(void) const
Return the timeout.
Definition: mgt-headers.cc:1588
ns3::WifiMacHeader::GetQosAckPolicy
QosAckPolicy GetQosAckPolicy(void) const
Return the QoS Ack policy in the QoS control field.
Definition: wifi-mac-header.cc:829
ns3::FrameExchangeManager::GetAckManager
Ptr< WifiAckManager > GetAckManager(void) const
Get the Acknowledgment Manager used by this node.
Definition: frame-exchange-manager.cc:124
ns3::StatusCode
Status code for association response.
Definition: status-code.h:32
ns3::QosTxop::GetAddBaResponseTimeout
Time GetAddBaResponseTimeout(void) const
Get the timeout for ADDBA response.
Definition: qos-txop.cc:754
ns3::WifiTxParameters::m_acknowledgment
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
Definition: wifi-tx-parameters.h:64
ns3::SnrTag
Introspection did not find any typical Config paths.
Definition: snr-tag.h:35
ns3::MgtAddBaResponseHeader
Implement the header for management frames of type Add Block Ack response.
Definition: mgt-headers.h:1150
ns3::WifiMacQueueItem::QueueIteratorPair
Information needed to remove an MSDU from the queue.
Definition: wifi-mac-queue-item.h:147
ns3::MakeCallback
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
ns3::QosTxop::PrepareBlockAckRequest
Ptr< const WifiMacQueueItem > PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:263
ns3::HtFrameExchangeManager::GetSupportedBaBufferSize
virtual uint16_t GetSupportedBaBufferSize(void) const
Get the maximum supported buffer size for a Block Ack agreement.
Definition: ht-frame-exchange-manager.cc:241
ns3::WifiBarBlockAck::blockAckReqTxVector
WifiTxVector blockAckReqTxVector
BlockAckReq TXVECTOR.
Definition: wifi-acknowledgment.h:187
NS_ABORT_IF
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:77
ns3::HtFrameExchangeManager::IsWithinAmpduSizeLimit
virtual bool IsWithinAmpduSizeLimit(uint32_t ampduSize, Mac48Address receiver, uint8_t tid, WifiModulationClass modulation) const
Check whether an A-MPDU of the given size meets the constraint on the maximum size for A-MPDUs sent t...
Definition: ht-frame-exchange-manager.cc:994
ns3::MgtAddBaRequestHeader::SetAmsduSupport
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
Definition: mgt-headers.cc:1570
ns3::HtFrameExchangeManager::GetMpduAggregator
Ptr< MpduAggregator > GetMpduAggregator(void) const
Returns the aggregator used to construct A-MPDU subframes.
Definition: ht-frame-exchange-manager.cc:92
ns3::WIFI_MAC_MGT_ACTION
@ WIFI_MAC_MGT_ACTION
Definition: wifi-mac-header.h:58
ns3::CtrlBAckResponseHeader::SetType
void SetType(BlockAckType type)
Set the block ack type.
Definition: ctrl-headers.cc:456
ns3::WifiAckManager::SetQosAckPolicy
static void SetQosAckPolicy(Ptr< WifiMacQueueItem > item, const WifiAcknowledgment *acknowledgment)
Set the QoS Ack policy for the given MPDU, which must be a QoS data frame.
Definition: wifi-ack-manager.cc:64
ns3::Packet::AddPacketTag
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
ns3::WifiMacHeader::SetAddr2
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
Definition: wifi-mac-header.cc:114
ns3::WifiMacHeader::GetQosTid
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
Definition: wifi-mac-header.cc:862
ns3::RecipientBlockAckAgreement::FillBlockAckBitmap
void FillBlockAckBitmap(CtrlBAckResponseHeader *blockAckHeader, std::size_t index=0) const
Set the Starting Sequence Number subfield of the Block Ack Starting Sequence Control subfield of the ...
Definition: recipient-block-ack-agreement.cc:224
NS_LOG_FUNCTION_NOARGS
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log-macros-enabled.h:209
ht-frame-exchange-manager.h
ns3::STA
@ STA
Definition: wifi-mac.h:42
ns3::MgtDelBaHeader
Implement the header for management frames of type Delete Block Ack.
Definition: mgt-headers.h:1271
ns3::HtFrameExchangeManager::TransmissionSucceeded
void TransmissionSucceeded(void) override
Take necessary actions upon a transmission success.
Definition: ht-frame-exchange-manager.cc:578
ns3::Time::Min
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:274
ns3::CtrlBAckResponseHeader::GetTidInfo
uint8_t GetTidInfo(std::size_t index=0) const
For Block Ack variants other than Multi-STA Block Ack, get the TID_INFO subfield of the BA Control fi...
Definition: ctrl-headers.cc:510
ns3::WifiPsdu::IsAggregate
bool IsAggregate(void) const
Return true if the PSDU is an S-MPDU or A-MPDU.
Definition: wifi-psdu.cc:81
ns3::Time::IsStrictlyNegative
bool IsStrictlyNegative(void) const
Exactly equivalent to t < 0.
Definition: nstime.h:325
timeout
ns3::Time timeout
Definition: openflow-switch.cc:52
ns3::FrameExchangeManager::UpdateTxDuration
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...
Definition: frame-exchange-manager.cc:515
ns3::WifiPsdu::GetAddr2
Mac48Address GetAddr2(void) const
Get the Transmitter Address (TA), which is common to all the MPDUs.
Definition: wifi-psdu.cc:126
ns3::HtFrameExchangeManager::m_agreements
std::map< AgreementKey, RecipientBlockAckAgreement > m_agreements
agreements
Definition: ht-frame-exchange-manager.h:380
ns3::FrameExchangeManager::m_txMiddle
Ptr< MacTxMiddle > m_txMiddle
the MAC TX Middle on this station
Definition: frame-exchange-manager.h:382
ns3::RxSignalInfo::snr
double snr
SNR in linear scale.
Definition: phy-entity.h:68
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::WifiTxParameters::m_txVector
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
Definition: wifi-tx-parameters.h:62
ns3::WifiBlockAck::blockAckTxVector
WifiTxVector blockAckTxVector
BlockAck TXVECTOR.
Definition: wifi-acknowledgment.h:169
ns3::RxSignalInfo
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:67
ns3::Seconds
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
ns3::WifiActionHeader::GetCategory
CategoryValue GetCategory()
Return the category value.
Definition: mgt-headers.cc:1226
ns3::WifiAcknowledgment
WifiAcknowledgment is an abstract base struct.
Definition: wifi-acknowledgment.h:45
ns3::Packet::Copy
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
ns3::WifiActionHeader::SetAction
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
Definition: mgt-headers.cc:1192
ns3::BlockAckAgreement::SetDelayedBlockAck
void SetDelayedBlockAck(void)
Set block ack policy to delayed Ack.
Definition: block-ack-agreement.cc:86
ns3::FrameExchangeManager::NotifyReceivedNormalAck
virtual void NotifyReceivedNormalAck(Ptr< WifiMacQueueItem > mpdu)
Notify other components that an MPDU was acknowledged.
Definition: frame-exchange-manager.cc:1194
ns3::BlockAckAgreement::m_inactivityEvent
EventId m_inactivityEvent
inactivity event
Definition: block-ack-agreement.h:188
ns3::FrameExchangeManager::SendMpduWithProtection
void SendMpduWithProtection(Ptr< WifiMacQueueItem > mpdu, WifiTxParameters &txParams)
Send an MPDU with the given TX parameters (with the specified protection).
Definition: frame-exchange-manager.cc:345
ns3::HtFrameExchangeManager::NotifyTxToEdca
virtual void NotifyTxToEdca(Ptr< const WifiPsdu > psdu) const
Notify the transmission of the given PSDU to the EDCAF associated with the AC the PSDU belongs to.
Definition: ht-frame-exchange-manager.cc:863
ns3::FrameExchangeManager::m_mac
Ptr< RegularWifiMac > m_mac
the MAC layer on this station
Definition: frame-exchange-manager.h:381
ns3::HtFrameExchangeManager::ForwardMpduDown
void ForwardMpduDown(Ptr< WifiMacQueueItem > mpdu, WifiTxVector &txVector) override
Forward an MPDU down to the PHY layer.
Definition: ht-frame-exchange-manager.cc:514
ns3::FrameExchangeManager::m_bssid
Mac48Address m_bssid
BSSID address (Mac48Address)
Definition: frame-exchange-manager.h:387
ns3::SnrTag::Get
double Get(void) const
Return the SNR value.
Definition: snr-tag.cc:89
ns3::WifiTxTimer::WAIT_CTS
@ WAIT_CTS
Definition: wifi-tx-timer.h:57
ns3::HtFrameExchangeManager::m_psdu
Ptr< WifiPsdu > m_psdu
the A-MPDU being transmitted
Definition: ht-frame-exchange-manager.h:391
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::WifiMacHeader::GetDuration
Time GetDuration(void) const
Return the duration from the Duration/ID field (Time object).
Definition: wifi-mac-header.cc:765
ns3::QosTxop::ScheduleBar
void ScheduleBar(Ptr< const WifiMacQueueItem > bar, bool skipIfNoDataQueued=false)
Definition: qos-txop.cc:285
ns3::WifiTxParameters::PsduInfo
information about the frame being prepared for a specific receiver
Definition: wifi-tx-parameters.h:115
ns3::WifiMacHeader::SetQosEosp
void SetQosEosp()
Set the end of service period (EOSP) bit in the QoS control field.
Definition: wifi-mac-header.cc:357
ns3::WifiTxTimer::GetReason
Reason GetReason(void) const
Get the reason why the timer was started.
Definition: wifi-tx-timer.cc:60
ns3::WifiMacHeader::IsCtl
bool IsCtl(void) const
Return true if the Type is Control.
Definition: wifi-mac-header.cc:571
ns3::WifiTxParameters::AggregateMsdu
void AggregateMsdu(Ptr< const WifiMacQueueItem > msdu)
Record that an MSDU is being aggregated to the last MPDU added to the frame that hase the same receiv...
Definition: wifi-tx-parameters.cc:174
ns3::WifiMacHeader::SetType
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
Definition: wifi-mac-header.cc:132
ns3::BlockAckAgreement::GetBlockAckType
BlockAckType GetBlockAckType(void) const
Get the type of the Block Acks sent by the recipient of this agreement.
Definition: block-ack-agreement.cc:169
ns3::WifiAcknowledgment::BAR_BLOCK_ACK
@ BAR_BLOCK_ACK
Definition: wifi-acknowledgment.h:55
ns3::FrameExchangeManager::RetransmitMpduAfterMissedCts
virtual void RetransmitMpduAfterMissedCts(Ptr< WifiMacQueueItem > mpdu) const
Retransmit an MPDU that was not sent because a CTS was not received.
Definition: frame-exchange-manager.cc:829
ns3::BlockAckAgreement::GetDistance
static std::size_t GetDistance(uint16_t seqNumber, uint16_t startingSeqNumber)
Get the distance between the given starting sequence number and the given sequence number.
Definition: block-ack-agreement.cc:195
ns3::TracedValueCallback::Time
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:813
ns3::WifiMacHeader::SetDsNotTo
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Definition: wifi-mac-header.cc:102
ns3::HtFrameExchangeManager::GetMsduAggregator
Ptr< MsduAggregator > GetMsduAggregator(void) const
Returns the aggregator used to construct A-MSDU subframes.
Definition: ht-frame-exchange-manager.cc:86
ns3::WifiActionHeader::BLOCK_ACK_DELBA
@ BLOCK_ACK_DELBA
Definition: mgt-headers.h:948
ns3::HtFrameExchangeManager::HtFrameExchangeManager
HtFrameExchangeManager()
Definition: ht-frame-exchange-manager.cc:53
ns3::HtFrameExchangeManager::DequeuePsdu
void DequeuePsdu(Ptr< const WifiPsdu > psdu)
Dequeue the MPDUs of the given PSDU from the queue in which they are stored.
Definition: ht-frame-exchange-manager.cc:907
ns3::WifiProtection::RTS_CTS
@ RTS_CTS
Definition: wifi-protection.h:48
ns3::WIFI_MAC_CTL_BACKRESP
@ WIFI_MAC_CTL_BACKRESP
Definition: wifi-mac-header.h:44
ns3::WifiPsdu::begin
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
ns3::CtrlBAckRequestHeader::GetStartingSequence
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
Definition: ctrl-headers.cc:239
ns3::HtFrameExchangeManager::GetWifiPsdu
virtual Ptr< WifiPsdu > GetWifiPsdu(Ptr< WifiMacQueueItem > mpdu, const WifiTxVector &txVector) const
Get a PSDU containing the given MPDU.
Definition: ht-frame-exchange-manager.cc:520
ns3::HtFrameExchangeManager::DequeueMpdu
void DequeueMpdu(Ptr< WifiMacQueueItem > mpdu) override
Dequeue the given MPDU from the queue in which it is stored.
Definition: ht-frame-exchange-manager.cc:901
ns3::WifiAcknowledgment::method
const Method method
acknowledgment method
Definition: wifi-acknowledgment.h:103
ns3::HtFrameExchangeManager::SendPsdu
void SendPsdu(void)
Send the current PSDU, which can be acknowledged by a BlockAck frame or followed by a BlockAckReq fra...
Definition: ht-frame-exchange-manager.cc:795
ns3::WifiBarBlockAck::baType
BlockAckType baType
BlockAck type.
Definition: wifi-acknowledgment.h:190
ns3::OriginatorBlockAckAgreement::RESET
@ RESET
Definition: originator-block-ack-agreement.h:106
ns3::WifiBlockAck::baType
BlockAckType baType
BlockAck type.
Definition: wifi-acknowledgment.h:170
ns3::WifiAcknowledgment::BLOCK_ACK
@ BLOCK_ACK
Definition: wifi-acknowledgment.h:54
ns3::WifiMacHeader::GetAddr2
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
Definition: wifi-mac-header.cc:430
ns3::QosTxop::CompleteMpduTx
void CompleteMpduTx(Ptr< WifiMacQueueItem > mpdu)
Stores an MPDU (part of an A-MPDU) in block ack agreement (i.e.
Definition: qos-txop.cc:668
ns3::HtFrameExchangeManager::EndReceiveAmpdu
void EndReceiveAmpdu(Ptr< const WifiPsdu > psdu, const RxSignalInfo &rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &perMpduStatus) override
This method is called when the reception of an A-MPDU including multiple MPDUs is completed.
Definition: ht-frame-exchange-manager.cc:1443
ns3::WifiPhy::GetSifs
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:910
ns3::WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE
@ BLOCK_ACK_ADDBA_RESPONSE
Definition: mgt-headers.h:947
ns3::HtFrameExchangeManager::SendAddBaResponse
void SendAddBaResponse(const MgtAddBaRequestHeader *reqHdr, Mac48Address originator)
This method can be called to accept a received ADDBA Request.
Definition: ht-frame-exchange-manager.cc:191
ns3::WifiTxTimer::Set
void Set(Reason reason, const Time &delay, MEM mem_ptr, OBJ obj, Args... args)
This method is called when a frame soliciting a response is transmitted.
Definition: wifi-tx-timer.h:241
ns3::WifiBarBlockAck::blockAckTxVector
WifiTxVector blockAckTxVector
BlockAck TXVECTOR.
Definition: wifi-acknowledgment.h:188
ns3::WifiTxTimer::Cancel
void Cancel(void)
Cancel the timer.
Definition: wifi-tx-timer.cc:100
ns3::HtFrameExchangeManager::NotifyReceivedNormalAck
void NotifyReceivedNormalAck(Ptr< WifiMacQueueItem > mpdu) override
Notify other components that an MPDU was acknowledged.
Definition: ht-frame-exchange-manager.cc:526
ns3::HtFrameExchangeManager::GetPsduDurationId
virtual Time GetPsduDurationId(Time txDuration, const WifiTxParameters &txParams) const
Compute how to set the Duration/ID field of PSDUs that do not include fragments.
Definition: ht-frame-exchange-manager.cc:684
ns3::MgtAddBaResponseHeader::SetBufferSize
void SetBufferSize(uint16_t size)
Set buffer size.
Definition: mgt-headers.cc:1732
ns3::WifiPhy::Send
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:1789
ns3::WifiTxVector::GetMode
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.
Definition: wifi-tx-vector.cc:111
ns3::CtrlBAckRequestHeader::GetTidInfo
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
Definition: ctrl-headers.cc:232
ns3::QosTxop::GetFailedAddBaTimeout
Time GetFailedAddBaTimeout(void) const
Get the timeout for failed BA agreement.
Definition: qos-txop.cc:767
ns3::WifiModulationClass
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
Definition: wifi-phy-common.h:117
ns3::WifiMacHeader::IsAction
bool IsAction(void) const
Return true if the header is an Action header.
Definition: wifi-mac-header.cc:729
ns3::WifiActionHeader::BLOCK_ACK
@ BLOCK_ACK
Definition: mgt-headers.h:898
ns3::CtrlBAckResponseHeader
Headers for BlockAck response.
Definition: ctrl-headers.h:202
ns3::MgtDelBaHeader::IsByOriginator
bool IsByOriginator(void) const
Check if the initiator bit in the DELBA is set.
Definition: mgt-headers.cc:1866
ns3::HtFrameExchangeManager::BlockAckTimeout
virtual void BlockAckTimeout(Ptr< WifiPsdu > psdu, const WifiTxVector &txVector)
Called when the BlockAck timeout expires.
Definition: ht-frame-exchange-manager.cc:1137
ns3::HtFrameExchangeManager::SendDelbaFrame
void SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOriginator)
Sends DELBA frame to cancel a block ack agreement with STA addressed by addr for TID tid.
Definition: ht-frame-exchange-manager.cc:247
ns3::HtFrameExchangeManager::GetBaAgreementEstablished
bool GetBaAgreementEstablished(Mac48Address originator, uint8_t tid) const
Return true if a Block Ack agreement has been established with the given originator for the given TID...
Definition: ht-frame-exchange-manager.cc:1304
ns3::MgtAddBaResponseHeader::SetImmediateBlockAck
void SetImmediateBlockAck()
Enable immediate BlockAck.
Definition: mgt-headers.cc:1713
NS_ABORT_MSG
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
ns3::QosTxop::GetRemainingTxop
virtual Time GetRemainingTxop(void) const
Return the remaining duration in the current TXOP.
Definition: qos-txop.cc:592
ns3::MgtAddBaResponseHeader::SetAmsduSupport
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
Definition: mgt-headers.cc:1744