A Discrete-Event Network Simulator
API
mac-low.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  * Copyright (c) 2009 MIRKO BANCHI
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Mirko Banchi <mk.banchi@gmail.com>
21  * Stefano Avallone <stavallo@unina.it>
22  */
23 
24 #include "ns3/simulator.h"
25 #include "ns3/log.h"
26 #include "mac-low.h"
27 #include "qos-txop.h"
28 #include "snr-tag.h"
29 #include "ampdu-tag.h"
30 #include "wifi-mac-queue.h"
31 #include "wifi-psdu.h"
32 #include "wifi-utils.h"
33 #include "ctrl-headers.h"
34 #include "mgt-headers.h"
36 #include "mpdu-aggregator.h"
37 #include "msdu-aggregator.h"
38 #include "ampdu-subframe-header.h"
39 #include "wifi-phy-listener.h"
40 #include "wifi-mac-trailer.h"
41 #include "wifi-phy.h"
42 #include "wifi-net-device.h"
43 #include "wifi-mac.h"
44 #include <algorithm>
45 
46 #undef NS_LOG_APPEND_CONTEXT
47 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
48 
49 namespace ns3 {
50 
51 NS_LOG_COMPONENT_DEFINE ("MacLow");
52 
57 {
58 public:
65  : m_macLow (macLow)
66  {
67  }
68  virtual ~PhyMacLowListener ()
69  {
70  }
71  void NotifyRxStart (Time duration)
72  {
73  }
74  void NotifyRxEndOk (void)
75  {
76  }
77  void NotifyRxEndError (void)
78  {
79  }
80  void NotifyTxStart (Time duration, double txPowerDbm)
81  {
82  }
83  void NotifyMaybeCcaBusyStart (Time duration)
84  {
85  }
86  void NotifySwitchingStart (Time duration)
87  {
89  }
90  void NotifySleep (void)
91  {
93  }
94  void NotifyOff (void)
95  {
97  }
98  void NotifyWakeup (void)
99  {
100  }
101  void NotifyOn (void)
102  {
103  }
104 
105 private:
107 };
108 
109 
111  : m_msduAggregator (0),
112  m_mpduAggregator (0),
113  m_normalAckTimeoutEvent (),
114  m_blockAckTimeoutEvent (),
115  m_ctsTimeoutEvent (),
116  m_sendCtsEvent (),
117  m_sendAckEvent (),
118  m_sendDataEvent (),
119  m_waitIfsEvent (),
120  m_endTxNoAckEvent (),
121  m_currentPacket (0),
122  m_currentTxop (0),
123  m_lastNavStart (Seconds (0)),
124  m_lastNavDuration (Seconds (0)),
125  m_cfpStart (Seconds (0)),
126  m_lastBeacon (Seconds (0)),
127  m_cfpForeshortening (Seconds (0)),
128  m_promisc (false),
129  m_phyMacLowListener (0),
130  m_ctsToSelfSupported (false),
131  m_cfAckInfo ()
132 {
133  NS_LOG_FUNCTION (this);
134 }
135 
137 {
138  NS_LOG_FUNCTION (this);
139 }
140 
141 /* static */
142 TypeId
144 {
145  static TypeId tid = TypeId ("ns3::MacLow")
146  .SetParent<Object> ()
147  .SetGroupName ("Wifi")
148  .AddConstructor<MacLow> ()
149  ;
150  return tid;
151 }
152 
153 void
155 {
157  phy->RegisterListener (m_phyMacLowListener);
158 }
159 
160 void
162 {
163  if (m_phyMacLowListener != 0 )
164  {
165  phy->UnregisterListener (m_phyMacLowListener);
166  delete m_phyMacLowListener;
168  }
169 }
170 
171 void
173 {
174  NS_LOG_FUNCTION (this);
183  m_msduAggregator = 0;
184  m_mpduAggregator = 0;
185  m_phy = 0;
186  m_stationManager = 0;
187  if (m_phyMacLowListener != 0)
188  {
189  delete m_phyMacLowListener;
191  }
192 }
193 
194 void
196 {
197  NS_LOG_FUNCTION (this);
198  bool oneRunning = false;
200  {
202  oneRunning = true;
203  }
205  {
207  oneRunning = true;
208  }
210  {
212  oneRunning = true;
213  }
214  if (m_sendCtsEvent.IsRunning ())
215  {
217  oneRunning = true;
218  }
219  if (m_sendAckEvent.IsRunning ())
220  {
222  oneRunning = true;
223  }
224  if (m_sendDataEvent.IsRunning ())
225  {
227  oneRunning = true;
228  }
229  if (m_waitIfsEvent.IsRunning ())
230  {
232  oneRunning = true;
233  }
235  {
237  oneRunning = true;
238  }
239  if (oneRunning && m_currentTxop != 0)
240  {
241  m_currentTxop->Cancel ();
242  m_currentTxop = 0;
243  }
244 }
245 
246 void
248 {
249  m_phy = phy;
253 }
254 
256 MacLow::GetPhy (void) const
257 {
258  return m_phy;
259 }
260 
261 void
263 {
264  m_phy->SetReceiveOkCallback (MakeNullCallback<void, Ptr<Packet>, double, WifiTxVector, std::vector<bool>> ());
267  m_phy = 0;
268 }
269 
270 void
272 {
273  m_mac = mac;
274 }
275 
276 void
278 {
279  m_stationManager = manager;
280 }
281 
284 {
285  return m_msduAggregator;
286 }
287 
290 {
291  return m_mpduAggregator;
292 }
293 
294 void
296 {
297  NS_LOG_FUNCTION (this << aggr);
298  m_msduAggregator = aggr;
299 }
300 
301 void
303 {
304  NS_LOG_FUNCTION (this << aggr);
305  m_mpduAggregator = aggr;
306 }
307 
308 void
310 {
311  m_self = ad;
312 }
313 
314 void
316 {
317  m_ackTimeout = ackTimeout;
318 }
319 
320 void
322 {
323  m_basicBlockAckTimeout = blockAckTimeout;
324 }
325 
326 void
328 {
329  m_compressedBlockAckTimeout = blockAckTimeout;
330 }
331 
332 void
334 {
335  m_ctsToSelfSupported = enable;
336 }
337 
338 bool
340 {
341  return m_ctsToSelfSupported;
342 }
343 
344 void
346 {
347  m_ctsTimeout = ctsTimeout;
348 }
349 
350 void
352 {
353  m_sifs = sifs;
354 }
355 
356 void
358 {
359  m_slotTime = slotTime;
360 }
361 
362 void
364 {
365  m_pifs = pifs;
366 }
367 
368 void
370 {
371  m_rifs = rifs;
372 }
373 
374 void
376 {
377  m_beaconInterval = interval;
378 }
379 
380 void
382 {
383  m_cfpMaxDuration = cfpMaxDuration;
384 }
385 
386 void
388 {
389  m_bssid = bssid;
390 }
391 
392 void
394 {
395  m_promisc = true;
396 }
397 
399 MacLow::GetAddress (void) const
400 {
401  return m_self;
402 }
403 
404 Time
406 {
407  return m_ackTimeout;
408 }
409 
410 Time
412 {
413  return m_basicBlockAckTimeout;
414 }
415 
416 Time
418 {
420 }
421 
422 Time
424 {
425  return m_ctsTimeout;
426 }
427 
428 Time
429 MacLow::GetSifs (void) const
430 {
431  return m_sifs;
432 }
433 
434 Time
435 MacLow::GetRifs (void) const
436 {
437  return m_rifs;
438 }
439 
440 Time
442 {
443  return m_slotTime;
444 }
445 
446 Time
447 MacLow::GetPifs (void) const
448 {
449  return m_pifs;
450 }
451 
453 MacLow::GetBssid (void) const
454 {
455  return m_bssid;
456 }
457 
458 Time
460 {
461  return m_beaconInterval;
462 }
463 
464 Time
466 {
467  return m_cfpMaxDuration;
468 }
469 
470 bool
471 MacLow::IsPromisc (void) const
472 {
473  return m_promisc;
474 }
475 
476 void
478 {
479  m_rxCallback = callback;
480 }
481 
482 void
484 {
485  m_channelAccessManagers.push_back (dcf);
486 }
487 
488 void
491  Ptr<Txop> txop)
492 {
493  NS_LOG_FUNCTION (this << *mpdu << params << txop);
495  if (m_phy->IsStateOff ())
496  {
497  NS_LOG_DEBUG ("Cannot start TX because device is OFF");
498  return;
499  }
500  /* m_currentPacket is not NULL because someone started
501  * a transmission and was interrupted before one of:
502  * - ctsTimeout
503  * - sendDataAfterCTS
504  * expired. This means that one of these timers is still
505  * running. They are all cancelled below anyway by the
506  * call to CancelAllEvents (because of at least one
507  * of these two timers) which will trigger a call to the
508  * previous listener's cancel method.
509  *
510  * This typically happens because the high-priority
511  * QapScheduler has taken access to the channel from
512  * one of the Edca of the QAP.
513  */
514  m_currentPacket = Create<WifiPsdu> (mpdu, false);
515  const WifiMacHeader& hdr = mpdu->GetHeader ();
516  CancelAllEvents ();
517  m_currentTxop = txop;
518  m_txParams = params;
519  if (hdr.IsCtl ())
520  {
522  }
523  else
524  {
526  }
527 
528  /* The packet received by this function can be any of the following:
529  * (a) a management frame dequeued from the Txop
530  * (b) a non-QoS data frame dequeued from the Txop
531  * (c) a QoS data or DELBA Request frame dequeued from a QosTxop
532  * (d) a BlockAckReq or ADDBA Request frame
533  */
534  if (hdr.IsQosData () && !hdr.GetAddr1 ().IsBroadcast () && m_mpduAggregator != 0)
535  {
536  /* We get here if the received packet is any of the following:
537  * (a) a QoS data frame
538  * (b) a BlockAckRequest
539  */
540  uint8_t tid = GetTid (mpdu->GetPacket (), hdr);
541  Ptr<QosTxop> qosTxop = m_edca.find (QosUtilsMapTidToAc (tid))->second;
542  std::vector<Ptr<WifiMacQueueItem>> mpduList;
543 
544  // if a TXOP limit exists, compute the remaining TXOP duration
545  Time txopLimit = Seconds (0);
547  {
549  NS_ASSERT (txopLimit.IsPositive ());
550  }
551 
552  //Perform MPDU aggregation if possible
553  mpduList = m_mpduAggregator->GetNextAmpdu (mpdu, m_currentTxVector, txopLimit);
554 
555  if (mpduList.size () > 1)
556  {
557  m_currentPacket = Create<WifiPsdu> (mpduList);
558 
559  if (qosTxop->GetBaBufferSize (hdr.GetAddr1 (), tid) > 64)
560  {
562  }
563  else
564  {
566  }
567 
568  NS_LOG_DEBUG ("tx unicast A-MPDU containing " << mpduList.size () << " MPDUs");
569  qosTxop->SetAmpduExist (hdr.GetAddr1 (), true);
570  }
573  {
574  // VHT/HE single MPDU
575  m_currentPacket = Create<WifiPsdu> (mpdu, true);
576  m_currentPacket->SetAckPolicyForTid (tid, WifiMacHeader::NORMAL_ACK);
577 
578  //VHT/HE single MPDUs are followed by normal ACKs
580  NS_LOG_DEBUG ("tx unicast S-MPDU with sequence number " << hdr.GetSequenceNumber ());
581  qosTxop->SetAmpduExist (hdr.GetAddr1 (), true);
582  }
583  else if (hdr.IsQosData () && !hdr.IsQosBlockAck () && !hdr.GetAddr1 ().IsGroup ())
584  {
586  }
587  }
588 
589  NS_LOG_DEBUG ("startTx size=" << m_currentPacket->GetSize () <<
590  ", to=" << m_currentPacket->GetAddr1 () << ", txop=" << m_currentTxop);
591 
592  if (m_txParams.MustSendRts ())
593  {
594  SendRtsForPacket ();
595  }
596  else
597  {
599  {
600  SendCtsToSelf ();
601  }
602  else
603  {
604  SendDataPacket ();
605  }
606  }
607 
608  /* When this method completes, either we have taken ownership of the medium or the device switched off in the meantime. */
610 }
611 
612 bool
614 {
615  WifiTxVector dataTxVector = GetDataTxVector (*m_currentPacket->begin ());
616  return m_stationManager->NeedCtsToSelf (dataTxVector);
617 }
618 
619 bool
621  uint32_t ampduSize, Time ppduDurationLimit)
622 {
623  NS_ASSERT (mpdu != 0 && mpdu->GetHeader ().IsQosData ());
624 
625  return IsWithinSizeAndTimeLimits (mpdu->GetSize (), mpdu->GetHeader ().GetAddr1 (),
626  mpdu->GetHeader ().GetQosTid (), txVector,
627  ampduSize, ppduDurationLimit);
628 }
629 
630 bool
631 MacLow::IsWithinSizeAndTimeLimits (uint32_t mpduSize, Mac48Address receiver, uint8_t tid,
632  WifiTxVector txVector, uint32_t ampduSize, Time ppduDurationLimit)
633 {
634  NS_LOG_FUNCTION (this << mpduSize << receiver << +tid << txVector << ampduSize << ppduDurationLimit);
635 
636  WifiModulationClass modulation = txVector.GetMode ().GetModulationClass ();
637 
638  uint32_t maxAmpduSize = 0;
639  if (GetMpduAggregator ())
640  {
641  maxAmpduSize = GetMpduAggregator ()->GetMaxAmpduSize (receiver, tid, modulation);
642  }
643 
644  // If maxAmpduSize is null, then ampduSize must be null as well
645  NS_ASSERT (maxAmpduSize || ampduSize == 0);
646 
647  uint32_t ppduPayloadSize = mpduSize;
648 
649  // compute the correct size for A-MPDUs and S-MPDUs
650  if (ampduSize > 0 || modulation == WIFI_MOD_CLASS_HE || modulation == WIFI_MOD_CLASS_VHT)
651  {
652  ppduPayloadSize = GetMpduAggregator ()->GetSizeIfAggregated (mpduSize, ampduSize);
653  }
654 
655  if (maxAmpduSize > 0 && ppduPayloadSize > maxAmpduSize)
656  {
657  NS_LOG_DEBUG ("the frame does not meet the constraint on max A-MPDU size");
658  return false;
659  }
660 
661  // Get the maximum PPDU Duration based on the preamble type
662  Time maxPpduDuration = GetPpduMaxTime (txVector.GetPreambleType ());
663 
664  Time txTime = m_phy->CalculateTxDuration (ppduPayloadSize, txVector, m_phy->GetFrequency ());
665 
666  if ((ppduDurationLimit.IsStrictlyPositive () && txTime > ppduDurationLimit)
667  || (maxPpduDuration.IsStrictlyPositive () && txTime > maxPpduDuration))
668  {
669  NS_LOG_DEBUG ("the frame does not meet the constraint on max PPDU duration");
670  return false;
671  }
672 
673  return true;
674 }
675 
676 void
678 {
679  NS_LOG_FUNCTION (this << packet);
680  NS_LOG_DEBUG ("rx failed");
681  if (IsCfPeriod () && m_currentPacket->GetHeader (0).IsCfPoll ())
682  {
683  NS_ASSERT (m_currentTxop != 0);
685  }
686  else if (m_cfAckInfo.expectCfAck)
687  {
688  NS_ASSERT (m_currentTxop != 0);
689  Ptr<Txop> txop = m_currentTxop;
690  m_currentTxop = 0;
691  txop->MissedAck ();
692  }
693  m_cfAckInfo.expectCfAck = false;
694  return;
695 }
696 
697 void
699 {
700  NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events");
702  CancelAllEvents ();
704  {
706  }
709  m_currentPacket = 0;
710  m_currentTxop = 0;
711 }
712 
713 void
715 {
716  NS_LOG_DEBUG ("Device in sleep mode. Cancelling MAC pending events");
717  CancelAllEvents ();
719  {
721  }
724  m_currentPacket = 0;
725  m_currentTxop = 0;
726 }
727 
728 void
730 {
731  NS_LOG_DEBUG ("Device is switched off. Cancelling MAC pending events");
732  CancelAllEvents ();
734  {
736  }
739  m_currentPacket = 0;
740  m_currentTxop = 0;
741 }
742 
743 void
744 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, bool ampduSubframe)
745 {
746  NS_LOG_FUNCTION (this << packet << rxSnr << txVector.GetMode () << txVector.GetPreambleType ());
747  /* A packet is received from the PHY.
748  * When we have handled this packet,
749  * we handle any packet present in the
750  * packet queue.
751  */
752  WifiMacHeader hdr;
753  packet->RemoveHeader (hdr);
754 
755  bool isPrevNavZero = IsNavZero ();
756  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
757  NotifyNav (packet, hdr);
758  if (hdr.IsRts ())
759  {
760  /* see section 9.2.5.7 802.11-1999
761  * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS
762  * period if the NAV at the STA receiving the RTS frame indicates that the medium is
763  * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
764  * that STA shall not respond to the RTS frame.
765  */
766  if (ampduSubframe)
767  {
768  NS_FATAL_ERROR ("Received RTS as part of an A-MPDU");
769  }
770  else
771  {
772  if (isPrevNavZero
773  && hdr.GetAddr1 () == m_self)
774  {
775  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
777  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
778  rxSnr, txVector.GetMode ());
781  hdr.GetAddr2 (),
782  hdr.GetDuration (),
783  txVector,
784  rxSnr);
785  }
786  else
787  {
788  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
789  }
790  }
791  }
792  else if (hdr.IsCts ()
793  && hdr.GetAddr1 () == m_self
795  && m_currentPacket != 0)
796  {
797  if (ampduSubframe)
798  {
799  NS_FATAL_ERROR ("Received CTS as part of an A-MPDU");
800  }
801 
802  NS_LOG_DEBUG ("received cts from=" << m_currentPacket->GetAddr1 ());
803 
804  SnrTag tag;
805  packet->RemovePacketTag (tag);
806  m_stationManager->ReportRxOk (m_currentPacket->GetAddr1 (), &m_currentPacket->GetHeader (0),
807  rxSnr, txVector.GetMode ());
808  m_stationManager->ReportRtsOk (m_currentPacket->GetAddr1 (), &m_currentPacket->GetHeader (0),
809  rxSnr, txVector.GetMode (), tag.Get ());
810 
816  hdr.GetDuration ());
817  }
818  else if (hdr.IsAck ()
819  && hdr.GetAddr1 () == m_self
822  {
823  NS_LOG_DEBUG ("receive ack from=" << m_currentPacket->GetAddr1 ());
824  SnrTag tag;
825  packet->RemovePacketTag (tag);
826  //When fragmentation is used, only update manager when the last fragment is acknowledged
827  if (!m_txParams.HasNextPacket ())
828  {
829  m_stationManager->ReportRxOk (m_currentPacket->GetAddr1 (), &m_currentPacket->GetHeader (0),
830  rxSnr, txVector.GetMode ());
831  m_stationManager->ReportDataOk (m_currentPacket->GetAddr1 (), &m_currentPacket->GetHeader (0),
832  rxSnr, txVector.GetMode (), tag.Get (),
833  m_currentPacket->GetSize ());
834  }
835  bool gotAck = false;
838  {
841  gotAck = true;
842  }
843  if (gotAck)
844  {
845  m_currentTxop->GotAck ();
846  }
847  if (m_txParams.HasNextPacket ())
848  {
850  {
852  }
853  else
854  {
856  }
857  }
858  else if (m_currentPacket->GetHeader (0).IsQosData () && m_currentTxop->IsQosTxop () &&
860  {
862  {
864  }
865  else
866  {
868  }
869  }
870  else if (m_currentTxop->IsQosTxop ())
871  {
873  }
874  }
875  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
878  {
879  NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
880  SnrTag tag;
881  packet->RemovePacketTag (tag);
882  CtrlBAckResponseHeader blockAck;
883  packet->RemoveHeader (blockAck);
886  m_currentTxop->GotBlockAck (&blockAck, hdr.GetAddr2 (), rxSnr, txVector.GetMode (), tag.Get ());
887  // start next packet if TXOP remains, otherwise contend for accessing the channel again
890  {
892  {
894  }
895  else
896  {
898  }
899  }
900  else if (m_currentTxop->IsQosTxop ())
901  {
903  }
904  }
905  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
906  {
907  CtrlBAckRequestHeader blockAckReq;
908  packet->RemoveHeader (blockAckReq);
909  if (!blockAckReq.IsMultiTid ())
910  {
911  uint8_t tid = blockAckReq.GetTidInfo ();
912  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
913  if (it != m_bAckAgreements.end ())
914  {
915  //Update block ack cache
916  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
917  NS_ASSERT (i != m_bAckCaches.end ());
918  (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
919 
920  //NS_ASSERT (m_sendAckEvent.IsExpired ());
922  /* See section 11.5.3 in IEEE 802.11 for mean of this timer */
923  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
924  if ((*it).second.first.IsImmediateBlockAck ())
925  {
926  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
929  blockAckReq,
930  hdr.GetAddr2 (),
931  hdr.GetDuration (),
932  txVector.GetMode (),
933  rxSnr);
934  }
935  else
936  {
937  NS_FATAL_ERROR ("Delayed block ack not supported.");
938  }
939  }
940  else
941  {
942  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
943  }
944  }
945  else
946  {
947  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
948  }
949  }
950  else if (hdr.IsCtl ())
951  {
952  if (hdr.IsCfEnd ())
953  {
954  NS_LOG_DEBUG ("rx CF-END ");
955  m_cfpStart = NanoSeconds (0);
957  {
958  NS_ASSERT (m_currentTxop != 0);
959  if (hdr.IsCfAck ())
960  {
961  m_currentTxop->GotAck ();
962  }
963  else
964  {
966  }
967  }
968  if (m_currentTxop != 0)
969  {
971  }
972  m_cfAckInfo.expectCfAck = false;
973  }
974  else
975  {
976  NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
977  }
978  }
979  else if (hdr.GetAddr1 () == m_self)
980  {
981  if (hdr.IsCfPoll ())
982  {
984  if (m_cfAckInfo.expectCfAck && !hdr.IsCfAck ())
985  {
986  NS_ASSERT (m_currentTxop != 0);
987  Ptr<Txop> txop = m_currentTxop;
988  m_currentTxop = 0;
989  txop->MissedAck ();
990  m_cfAckInfo.expectCfAck = false;
991  }
992  }
993  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
994  rxSnr, txVector.GetMode ());
995  if (hdr.IsQosData () && ReceiveMpdu (packet, hdr))
996  {
997  /* From section 9.10.4 in IEEE 802.11:
998  Upon the receipt of a QoS data frame from the originator for which
999  the Block Ack agreement exists, the recipient shall buffer the MSDU
1000  regardless of the value of the Ack Policy subfield within the
1001  QoS Control field of the QoS data frame. */
1002  if (hdr.IsQosAck () && !ampduSubframe)
1003  {
1004  NS_LOG_DEBUG ("rx QoS unicast/sendAck from=" << hdr.GetAddr2 ());
1005  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1006 
1007  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequenceControl (),
1008  hdr.GetAddr2 (), hdr.GetQosTid ());
1009  RxCompleteBufferedPacketsUntilFirstLost (hdr.GetAddr2 (), hdr.GetQosTid ());
1012  &MacLow::SendAckAfterData, this,
1013  hdr.GetAddr2 (),
1014  hdr.GetDuration (),
1015  txVector.GetMode (),
1016  rxSnr);
1017  }
1018  else if (hdr.IsQosBlockAck ())
1019  {
1020  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1021  /* See section 11.5.3 in IEEE 802.11 for mean of this timer */
1022  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
1023  }
1024  return;
1025  }
1026  else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
1027  {
1028  /* This happens if a packet with ack policy Block Ack is received and a block ack
1029  agreement for that packet doesn't exist.
1030 
1031  From section 11.5.3 in IEEE 802.11e:
1032  When a recipient does not have an active Block ack for a TID, but receives
1033  data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
1034  them and shall send a DELBA frame using the normal access
1035  mechanisms. */
1036  AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
1037  m_edca[ac]->SendDelbaFrame (hdr.GetAddr2 (), hdr.GetQosTid (), false);
1038  return;
1039  }
1040  else if (hdr.IsQosData () && hdr.IsQosNoAck ())
1041  {
1042  if (ampduSubframe)
1043  {
1044  NS_LOG_DEBUG ("rx Ampdu with No Ack Policy from=" << hdr.GetAddr2 ());
1045  }
1046  else
1047  {
1048  NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
1049  }
1050  }
1051  else if (hdr.IsData () || hdr.IsMgt ())
1052  {
1053  if (hdr.IsProbeResp ())
1054  {
1055  // Apply SNR tag for probe response quality measurements
1056  SnrTag tag;
1057  tag.Set (rxSnr);
1058  packet->AddPacketTag (tag);
1059  }
1060  if (hdr.IsMgt () && ampduSubframe)
1061  {
1062  NS_FATAL_ERROR ("Received management packet as part of an A-MPDU");
1063  }
1064  else
1065  {
1066  if (IsCfPeriod ())
1067  {
1068  if (hdr.HasData ())
1069  {
1070  m_cfAckInfo.appendCfAck = true;
1071  m_cfAckInfo.address = hdr.GetAddr2 ();
1072  }
1073  }
1074  else
1075  {
1076  NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
1079  &MacLow::SendAckAfterData, this,
1080  hdr.GetAddr2 (),
1081  hdr.GetDuration (),
1082  txVector.GetMode (),
1083  rxSnr);
1084  }
1085  }
1086  }
1087  goto rxPacket;
1088  }
1089  else if (hdr.GetAddr1 ().IsGroup ())
1090  {
1091  if (ampduSubframe)
1092  {
1093  NS_FATAL_ERROR ("Received group addressed packet as part of an A-MPDU");
1094  }
1095  else
1096  {
1097  if (hdr.IsData () || hdr.IsMgt ())
1098  {
1099  NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
1100  if (hdr.IsBeacon ())
1101  {
1102  // Apply SNR tag for beacon quality measurements
1103  SnrTag tag;
1104  tag.Set (rxSnr);
1105  packet->AddPacketTag (tag);
1106  }
1107  goto rxPacket;
1108  }
1109  }
1110  }
1111  else if (m_promisc)
1112  {
1113  NS_ASSERT (hdr.GetAddr1 () != m_self);
1114  if (hdr.IsData ())
1115  {
1116  goto rxPacket;
1117  }
1118  }
1119  else
1120  {
1121  if (m_cfAckInfo.expectCfAck && hdr.IsCfAck ())
1122  {
1123  m_cfAckInfo.expectCfAck = false;
1124  NS_ASSERT (m_currentTxop != 0);
1125  m_currentTxop->GotAck ();
1126  }
1127  NS_LOG_DEBUG ("rx not for me from=" << hdr.GetAddr2 ());
1128  }
1129  return;
1130 rxPacket:
1131  if (m_cfAckInfo.expectCfAck && hdr.IsCfAck ())
1132  {
1133  m_cfAckInfo.expectCfAck = false;
1134  NS_ASSERT (m_currentTxop != 0);
1135  m_currentTxop->GotAck ();
1136  }
1137  WifiMacTrailer fcs;
1138  packet->RemoveTrailer (fcs);
1139  m_rxCallback (packet, &hdr);
1140  return;
1141 }
1142 
1143 uint32_t
1145 {
1146  WifiMacHeader cfEnd;
1148  {
1149  cfEnd.SetType (WIFI_MAC_CTL_END_ACK);
1150  }
1151  else
1152  {
1153  cfEnd.SetType (WIFI_MAC_CTL_END);
1154  }
1155  return cfEnd.GetSize () + 4;
1156 }
1157 
1158 Time
1160 {
1161  WifiTxVector ackTxVector = GetAckTxVectorForData (to, dataTxVector.GetMode ());
1162  return GetAckDuration (ackTxVector);
1163 }
1164 
1165 Time
1167 {
1168  NS_ASSERT (ackTxVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT); //ACK should always use non-HT PPDU (HT PPDU cases not supported yet)
1169  return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, m_phy->GetFrequency ());
1170 }
1171 
1172 Time
1173 MacLow::GetBlockAckDuration (WifiTxVector blockAckReqTxVector, BlockAckType type) const
1174 {
1175  /*
1176  * For immediate Basic BlockAck we should transmit the frame with the same WifiMode
1177  * as the BlockAckReq.
1178  */
1179  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, m_phy->GetFrequency ());
1180 }
1181 
1182 Time
1184 {
1185  WifiTxVector ctsTxVector = GetCtsTxVectorForRts (to, rtsTxVector.GetMode ());
1186  return GetCtsDuration (ctsTxVector);
1187 }
1188 
1189 Time
1191 {
1192  NS_ASSERT (ctsTxVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT); //CTS should always use non-HT PPDU (HT PPDU cases not supported yet)
1193  return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, m_phy->GetFrequency ());
1194 }
1195 
1198 {
1199  Mac48Address to = item->GetHeader ().GetAddr1 ();
1200  return m_stationManager->GetRtsTxVector (to, &item->GetHeader (), item->GetPacket ());
1201 }
1202 
1205 {
1206  Mac48Address to = item->GetHeader ().GetAddr1 ();
1207  return m_stationManager->GetDataTxVector (to, &item->GetHeader (), item->GetPacket ());
1208 }
1209 
1210 WifiMode
1212 {
1227  NS_LOG_FUNCTION (this << reqMode);
1229  bool found = false;
1230  //First, search the BSS Basic Rate set
1231  for (uint8_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
1232  {
1233  WifiMode testMode = m_stationManager->GetBasicMode (i);
1234  if ((!found || testMode.IsHigherDataRate (mode))
1235  && (!testMode.IsHigherDataRate (reqMode))
1237  {
1238  mode = testMode;
1239  //We've found a potentially-suitable transmit rate, but we
1240  //need to continue and consider all the basic rates before
1241  //we can be sure we've got the right one.
1242  found = true;
1243  }
1244  }
1246  {
1247  if (!found)
1248  {
1249  mode = m_stationManager->GetDefaultMcs ();
1250  for (uint8_t i = 0; i != m_stationManager->GetNBasicMcs (); i++)
1251  {
1252  WifiMode testMode = m_stationManager->GetBasicMcs (i);
1253  if ((!found || testMode.IsHigherDataRate (mode))
1254  && (!testMode.IsHigherDataRate (reqMode))
1255  && (testMode.GetModulationClass () == reqMode.GetModulationClass ()))
1256  {
1257  mode = testMode;
1258  //We've found a potentially-suitable transmit rate, but we
1259  //need to continue and consider all the basic rates before
1260  //we can be sure we've got the right one.
1261  found = true;
1262  }
1263  }
1264  }
1265  }
1266  //If we found a suitable rate in the BSSBasicRateSet, then we are
1267  //done and can return that mode.
1268  if (found)
1269  {
1270  NS_LOG_DEBUG ("MacLow::GetControlAnswerMode returning " << mode);
1271  return mode;
1272  }
1273 
1291  for (uint8_t idx = 0; idx < m_phy->GetNModes (); idx++)
1292  {
1293  WifiMode thismode = m_phy->GetMode (idx);
1294  /* If the rate:
1295  *
1296  * - is a mandatory rate for the PHY, and
1297  * - is equal to or faster than our current best choice, and
1298  * - is less than or equal to the rate of the received frame, and
1299  * - is of the same modulation class as the received frame
1300  *
1301  * ...then it's our best choice so far.
1302  */
1303  if (thismode.IsMandatory ()
1304  && (!found || thismode.IsHigherDataRate (mode))
1305  && (!thismode.IsHigherDataRate (reqMode))
1307  {
1308  mode = thismode;
1309  //As above; we've found a potentially-suitable transmit
1310  //rate, but we need to continue and consider all the
1311  //mandatory rates before we can be sure we've got the right one.
1312  found = true;
1313  }
1314  }
1316  {
1317  for (uint8_t idx = 0; idx < m_phy->GetNMcs (); idx++)
1318  {
1319  WifiMode thismode = m_phy->GetMcs (idx);
1320  if (thismode.IsMandatory ()
1321  && (!found || thismode.IsHigherDataRate (mode))
1322  && (!thismode.IsHigherCodeRate (reqMode))
1323  && (thismode.GetModulationClass () == reqMode.GetModulationClass ()))
1324  {
1325  mode = thismode;
1326  //As above; we've found a potentially-suitable transmit
1327  //rate, but we need to continue and consider all the
1328  //mandatory rates before we can be sure we've got the right one.
1329  found = true;
1330  }
1331  }
1332  }
1333 
1343  if (!found)
1344  {
1345  NS_FATAL_ERROR ("Can't find response rate for " << reqMode);
1346  }
1347 
1348  NS_LOG_DEBUG ("MacLow::GetControlAnswerMode returning " << mode);
1349  return mode;
1350 }
1351 
1354 {
1355  NS_ASSERT (!to.IsGroup ());
1356  WifiMode ctsMode = GetControlAnswerMode (rtsTxMode);
1357  WifiTxVector v;
1358  v.SetMode (ctsMode);
1362  uint16_t ctsTxGuardInterval = ConvertGuardIntervalToNanoSeconds (ctsMode, m_phy->GetShortGuardInterval (), m_phy->GetGuardInterval ());
1363  v.SetGuardInterval (ctsTxGuardInterval);
1364  v.SetNss (1);
1365  return v;
1366 }
1367 
1370 {
1371  NS_ASSERT (!to.IsGroup ());
1372  WifiMode ackMode = GetControlAnswerMode (dataTxMode);
1373  WifiTxVector v;
1374  v.SetMode (ackMode);
1378  uint16_t ackTxGuardInterval = ConvertGuardIntervalToNanoSeconds (ackMode, m_phy->GetShortGuardInterval (), m_phy->GetGuardInterval ());
1379  v.SetGuardInterval (ackTxGuardInterval);
1380  v.SetNss (1);
1381  return v;
1382 }
1383 
1386 {
1387  NS_ASSERT (!to.IsGroup ());
1388  WifiMode blockAckMode = GetControlAnswerMode (dataTxMode);
1389  WifiTxVector v;
1390  v.SetMode (blockAckMode);
1394 uint16_t blockAckTxGuardInterval = ConvertGuardIntervalToNanoSeconds (blockAckMode, m_phy->GetShortGuardInterval (), m_phy->GetGuardInterval ());
1395  v.SetGuardInterval (blockAckTxGuardInterval);
1396  v.SetNss (1);
1397  return v;
1398 }
1399 
1402 {
1403  return GetCtsTxVector (to, rtsTxMode);
1404 }
1405 
1408 {
1409  return GetAckTxVector (to, dataTxMode);
1410 }
1411 
1412 Time
1414  const WifiMacHeader* hdr,
1415  const MacLowTransmissionParameters& params,
1416  uint32_t fragmentSize) const
1417 {
1418  Ptr<const WifiMacQueueItem> item = Create<const WifiMacQueueItem> (packet, *hdr);
1419  Time txTime = CalculateOverheadTxTime (item, params);
1420  uint32_t dataSize;
1421  if (fragmentSize > 0)
1422  {
1423  Ptr<const Packet> fragment = Create<Packet> (fragmentSize);
1424  dataSize = GetSize (fragment, hdr, m_currentPacket && m_currentPacket->IsAggregate ());
1425  }
1426  else
1427  {
1428  dataSize = GetSize (packet, hdr, m_currentPacket && m_currentPacket->IsAggregate ());
1429  }
1430  txTime += m_phy->CalculateTxDuration (dataSize, GetDataTxVector (item), m_phy->GetFrequency ());
1431  return txTime;
1432 }
1433 
1434 Time
1436  const MacLowTransmissionParameters& params) const
1437 {
1438  Time txTime = Seconds (0);
1439  if (params.MustSendRts ())
1440  {
1441  WifiTxVector rtsTxVector = GetRtsTxVector (item);
1442  txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, m_phy->GetFrequency ());
1443  txTime += GetCtsDuration (item->GetHeader ().GetAddr1 (), rtsTxVector);
1444  txTime += Time (GetSifs () * 2);
1445  }
1446  if (params.MustWaitNormalAck ())
1447  {
1448  txTime += GetSifs ();
1449  txTime += GetAckDuration (item->GetHeader ().GetAddr1 (), GetDataTxVector (item));
1450  }
1451  else if (params.MustWaitBlockAck ())
1452  {
1453  txTime += GetSifs ();
1454  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (item->GetHeader ().GetAddr2 (),
1455  GetDataTxVector (item).GetMode ());
1456  txTime += GetBlockAckDuration (blockAckReqTxVector, params.GetBlockAckType ());
1457  }
1458 
1459  return txTime;
1460 }
1461 
1462 Time
1464  const WifiMacHeader* hdr,
1465  const MacLowTransmissionParameters& params) const
1466 {
1467  Time txTime = CalculateOverallTxTime (packet, hdr, params);
1468  if (params.HasNextPacket ())
1469  {
1470  WifiTxVector dataTxVector = GetDataTxVector (Create<const WifiMacQueueItem> (packet, *hdr));
1471  txTime += GetSifs ();
1472  txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, m_phy->GetFrequency ());
1473  }
1474  return txTime;
1475 }
1476 
1477 void
1479 {
1481  if (hdr.GetRawDuration () > 32767)
1482  {
1483  //All stations process Duration field values less than or equal to 32 767 from valid data frames
1484  //to update their NAV settings as appropriate under the coordination function rules.
1485  return;
1486  }
1487  if (hdr.IsCfEnd () && hdr.GetAddr2 () == m_bssid)
1488  {
1489  //see section 9.3.2.2 802.11-1999
1490  DoNavResetNow (Seconds (0));
1491  return;
1492  }
1493  else if (hdr.GetAddr1 () != m_self)
1494  {
1495  // see section 9.2.5.4 802.11-1999
1496  Time duration = hdr.GetDuration ();
1497  bool navUpdated = DoNavStartNow (duration);
1498  if (hdr.IsRts () && navUpdated)
1499  {
1508  WifiMacHeader cts;
1509  cts.SetType (WIFI_MAC_CTL_CTS);
1510  WifiTxVector txVector = GetRtsTxVector (Create<const WifiMacQueueItem> (packet, hdr));
1511  Time navCounterResetCtsMissedDelay =
1512  m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, m_phy->GetFrequency ()) +
1513  Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
1514  m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
1516  Simulator::Now ());
1517  }
1518  }
1519 }
1520 
1521 void
1523 {
1524  if (m_phy->GetLastRxStartTime () < rtsEndRxTime)
1525  {
1526  DoNavResetNow (Seconds (0));
1527  }
1528 }
1529 
1530 void
1532 {
1533  NS_LOG_FUNCTION (this << duration);
1534  for (ChannelAccessManagersCI i = m_channelAccessManagers.begin (); i != m_channelAccessManagers.end (); i++)
1535  {
1536  (*i)->NotifyNavResetNow (duration);
1537  }
1539  m_lastNavDuration = duration;
1540 }
1541 
1542 bool
1544 {
1545  for (ChannelAccessManagersCI i = m_channelAccessManagers.begin (); i != m_channelAccessManagers.end (); i++)
1546  {
1547  (*i)->NotifyNavStartNow (duration);
1548  }
1549  Time newNavEnd = Simulator::Now () + duration;
1550  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1551  if (newNavEnd > oldNavEnd)
1552  {
1554  m_lastNavDuration = duration;
1555  return true;
1556  }
1557  return false;
1558 }
1559 
1560 void
1562 {
1563  for (ChannelAccessManagersCI i = m_channelAccessManagers.begin (); i != m_channelAccessManagers.end (); i++)
1564  {
1565  (*i)->NotifyAckTimeoutStartNow (duration);
1566  }
1567 }
1568 
1569 void
1571 {
1572  for (ChannelAccessManagersCI i = m_channelAccessManagers.begin (); i != m_channelAccessManagers.end (); i++)
1573  {
1574  (*i)->NotifyAckTimeoutResetNow ();
1575  }
1576 }
1577 
1578 void
1580 {
1581  for (ChannelAccessManagersCI i = m_channelAccessManagers.begin (); i != m_channelAccessManagers.end (); i++)
1582  {
1583  (*i)->NotifyCtsTimeoutStartNow (duration);
1584  }
1585 }
1586 
1587 void
1589 {
1590  for (ChannelAccessManagersCI i = m_channelAccessManagers.begin (); i != m_channelAccessManagers.end (); i++)
1591  {
1592  (*i)->NotifyCtsTimeoutResetNow ();
1593  }
1594 }
1595 
1596 void
1598 {
1599  NS_LOG_FUNCTION (this << psdu << txVector);
1600 
1601  NS_ASSERT (psdu->GetNMpdus ());
1602  const WifiMacHeader& hdr = (*psdu->begin ())->GetHeader ();
1603 
1604  NS_LOG_DEBUG ("send " << hdr.GetTypeString () <<
1605  ", to=" << hdr.GetAddr1 () <<
1606  ", size=" << psdu->GetSize () <<
1607  ", mode=" << txVector.GetMode () <<
1608  ", preamble=" << txVector.GetPreambleType () <<
1609  ", duration=" << hdr.GetDuration () <<
1610  ", seq=0x" << std::hex << hdr.GetSequenceControl () << std::dec);
1611 
1612  if (!psdu->IsAggregate ())
1613  {
1614  if (hdr.IsCfPoll () && m_stationManager->GetPcfSupported ())
1615  {
1616  Simulator::Schedule (GetPifs () + m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ()), &MacLow::CfPollTimeout, this);
1617  }
1618  if (hdr.IsBeacon () && m_stationManager->GetPcfSupported ())
1619  {
1621  {
1623  }
1625  }
1626  else if (hdr.IsCfEnd () && m_stationManager->GetPcfSupported ())
1627  {
1628  m_cfpStart = NanoSeconds (0);
1630  m_cfAckInfo.appendCfAck = false;
1631  m_cfAckInfo.expectCfAck = false;
1632  }
1633  else if (IsCfPeriod () && hdr.HasData ())
1634  {
1635  m_cfAckInfo.expectCfAck = true;
1636  }
1637  NS_LOG_DEBUG ("Sending non aggregate MPDU");
1638  }
1639  else // S-MPDU or A-MPDU
1640  {
1641  txVector.SetAggregation (true);
1642  if (psdu->IsSingle ())
1643  {
1644  NS_LOG_DEBUG ("Sending S-MPDU");
1645  }
1646  else
1647  {
1648  NS_LOG_DEBUG ("Sending A-MPDU");
1649  }
1650 
1651  if (psdu->GetNMpdus () > 1)
1652  {
1653  for (auto& mpdu : *PeekPointer (psdu))
1654  {
1655  if (mpdu->GetHeader ().IsQosData ())
1656  {
1657  auto edcaIt = m_edca.find (QosUtilsMapTidToAc (mpdu->GetHeader ().GetQosTid ()));
1658  edcaIt->second->CompleteMpduTx (mpdu);
1659  }
1660  }
1661  }
1662  }
1663  m_phy->SendPacket (psdu->GetPacket (), txVector);
1664 }
1665 
1666 void
1668 {
1669  NS_LOG_FUNCTION (this);
1670  //to be reworked
1671  bool busy = false;
1672  for (ChannelAccessManagersCI i = m_channelAccessManagers.begin (); i != m_channelAccessManagers.end (); i++)
1673  {
1674  busy = (*i)->IsBusy ();
1675  }
1676  if (!busy)
1677  {
1678  NS_ASSERT (m_currentTxop != 0);
1680  m_cfAckInfo.expectCfAck = false;
1681  }
1682 }
1683 
1684 void
1686 {
1687  NS_LOG_FUNCTION (this);
1688  NS_LOG_DEBUG ("cts timeout");
1692  m_stationManager->ReportRtsFailed (m_currentPacket->GetAddr1 (), &m_currentPacket->GetHeader (0));
1693 
1694  Ptr<QosTxop> qosTxop = DynamicCast<QosTxop> (m_currentTxop);
1695  if (qosTxop != 0)
1696  {
1698  }
1699  else
1700  {
1702  }
1703  m_currentTxop = 0;
1704 }
1705 
1706 void
1708 {
1709  NS_LOG_FUNCTION (this);
1710  NS_LOG_DEBUG ("normal ack timeout");
1714  Ptr<Txop> txop = m_currentTxop;
1715  m_currentTxop = 0;
1716  txop->MissedAck ();
1717 }
1718 
1719 void
1721 {
1722  NS_LOG_FUNCTION (this);
1723  NS_LOG_DEBUG ("block ack timeout");
1724  Ptr<Txop> txop = m_currentTxop;
1725  m_currentTxop = 0;
1726  txop->MissedBlockAck (m_currentPacket->GetNMpdus ());
1727 }
1728 
1729 void
1731 {
1732  NS_LOG_FUNCTION (this);
1733  /* send an RTS for this packet. */
1734  WifiMacHeader rts;
1735  rts.SetType (WIFI_MAC_CTL_RTS);
1736  rts.SetDsNotFrom ();
1737  rts.SetDsNotTo ();
1738  rts.SetNoRetry ();
1739  rts.SetNoMoreFragments ();
1740  rts.SetAddr1 (m_currentPacket->GetAddr1 ());
1741  rts.SetAddr2 (m_self);
1742  WifiTxVector rtsTxVector = GetRtsTxVector (*m_currentPacket->begin ());
1743  Time duration = Seconds (0);
1744 
1745  duration += GetSifs ();
1746  duration += GetCtsDuration (m_currentPacket->GetAddr1 (), rtsTxVector);
1747  duration += GetSifs ();
1748  duration += m_phy->CalculateTxDuration (m_currentPacket->GetSize (),
1750  duration += GetSifs ();
1752  {
1753  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ());
1754  duration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ());
1755  }
1756  else if (m_txParams.MustWaitNormalAck ())
1757  {
1758  duration += GetAckDuration (m_currentPacket->GetAddr1 (), m_currentTxVector);
1759  }
1760  if (m_txParams.HasNextPacket ())
1761  {
1765  {
1766  duration += GetSifs ();
1767  duration += GetAckDuration (m_currentPacket->GetAddr1 (), m_currentTxVector);
1768  }
1769  }
1770  rts.SetDuration (duration);
1771 
1772  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, m_phy->GetFrequency ());
1773  Time timerDelay = txDuration + GetCtsTimeout ();
1774 
1776  NotifyCtsTimeoutStartNow (timerDelay);
1778 
1779  ForwardDown (Create<const WifiPsdu> (Create<Packet> (), rts), rtsTxVector);
1780 }
1781 
1782 void
1784 {
1785  Time txDuration = m_phy->CalculateTxDuration (m_currentPacket->GetSize (), dataTxVector, m_phy->GetFrequency ());
1786  if (m_txParams.MustWaitNormalAck () && !IsCfPeriod ())
1787  {
1788  Time timerDelay = txDuration + GetAckTimeout ();
1790  NotifyAckTimeoutStartNow (timerDelay);
1792  }
1794  {
1795  Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1797  NotifyAckTimeoutStartNow (timerDelay);
1799  }
1800  else if (m_txParams.MustWaitBlockAck () &&
1803  {
1804  Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1806  NotifyAckTimeoutStartNow (timerDelay);
1808  }
1809  else if (m_txParams.HasNextPacket ())
1810  {
1812  Time delay = txDuration;
1814  {
1815  delay += GetRifs ();
1816  }
1817  else
1818  {
1819  delay += GetSifs ();
1820  }
1822  }
1823  else if (m_currentPacket->GetHeader (0).IsQosData () && m_currentTxop->IsQosTxop () &&
1825  {
1826  Time delay = txDuration;
1828  {
1829  delay += GetRifs ();
1830  }
1831  else
1832  {
1833  delay += GetSifs ();
1834  }
1836  }
1837  else
1838  {
1839  // since we do not expect any timer to be triggered.
1841  }
1842 }
1843 
1844 void
1846 {
1847  NS_LOG_FUNCTION (this);
1848  /* send this packet directly. No RTS is needed. */
1850 
1851  if (!IsCfPeriod ())
1852  {
1853  Time duration = Seconds (0);
1855  {
1856  duration += GetSifs ();
1857  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (),
1859  duration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ());
1860  }
1861  else if (m_txParams.MustWaitNormalAck ())
1862  {
1863  duration += GetSifs ();
1864  duration += GetAckDuration (m_currentPacket->GetAddr1 (), m_currentTxVector);
1865  }
1866  if (m_txParams.HasNextPacket ())
1867  {
1869  {
1870  duration += GetRifs ();
1871  }
1872  else
1873  {
1874  duration += GetSifs ();
1875  }
1879  {
1880  duration += GetSifs ();
1881  duration += GetAckDuration (m_currentPacket->GetAddr1 (), m_currentTxVector);
1882  }
1883  }
1884  m_currentPacket->SetDuration (duration);
1885  }
1886  else
1887  {
1888  if (m_currentPacket->GetHeader (0).IsCfEnd ())
1889  {
1890  m_currentPacket->GetHeader (0).SetRawDuration (0);
1891  }
1892  else
1893  {
1894  m_currentPacket->GetHeader (0).SetRawDuration (32768);
1895  }
1896  }
1897 
1898  if (!m_currentPacket->IsAggregate ())
1899  {
1901  {
1902  switch (m_currentPacket->GetHeader (0).GetType ())
1903  {
1904  case WIFI_MAC_DATA:
1905  m_currentPacket->GetHeader (0).SetType (WIFI_MAC_DATA_CFACK, false);
1906  break;
1907  case WIFI_MAC_DATA_CFPOLL:
1908  m_currentPacket->GetHeader (0).SetType (WIFI_MAC_DATA_CFACK_CFPOLL, false);
1909  break;
1910  case WIFI_MAC_DATA_NULL:
1911  m_currentPacket->GetHeader (0).SetType (WIFI_MAC_DATA_NULL_CFACK, false);
1912  break;
1914  m_currentPacket->GetHeader (0).SetType (WIFI_MAC_DATA_NULL_CFACK_CFPOLL, false);
1915  break;
1916  case WIFI_MAC_CTL_END:
1917  m_currentPacket->GetHeader (0).SetType (WIFI_MAC_CTL_END_ACK, false);
1918  break;
1919  default:
1920  NS_ASSERT (false);
1921  break;
1922  }
1924  //Standard says that, for frames of type Data+CF-ACK, Data+CF-Poll+CF-ACK, and CF-Poll+CF-ACK,
1925  //the rate chosen to transmit the frame must be supported by both the addressed recipient STA and the STA to which the ACK is intended.
1926  //This ideally requires the rate manager to handle this case, but this requires to update all rate manager classes.
1927  //Instead, we simply fetch two TxVector and we select the one with the lowest datarate.
1928  //This should be later changed, at the latest once HCCA is implemented for HT/VHT/HE stations.
1929  WifiMacHeader tmpHdr = m_currentPacket->GetHeader (0);
1930  tmpHdr.SetAddr1 (m_cfAckInfo.address);
1931  WifiTxVector tmpTxVector = GetDataTxVector (Create<const WifiMacQueueItem> (m_currentPacket->GetPayload (0), tmpHdr));
1932  if (tmpTxVector.GetMode ().GetDataRate (tmpTxVector) < m_currentTxVector.GetMode ().GetDataRate (m_currentTxVector))
1933  {
1934  m_currentTxVector = tmpTxVector;
1935  }
1936  m_cfAckInfo.appendCfAck = false;
1938  }
1939  }
1941 }
1942 
1943 bool
1944 MacLow::IsNavZero (void) const
1945 {
1947 }
1948 
1949 void
1951 {
1952  WifiMacHeader cts;
1953  cts.SetType (WIFI_MAC_CTL_CTS);
1954  cts.SetDsNotFrom ();
1955  cts.SetDsNotTo ();
1956  cts.SetNoMoreFragments ();
1957  cts.SetNoRetry ();
1958  cts.SetAddr1 (m_self);
1959 
1960  WifiTxVector ctsTxVector = GetRtsTxVector (*m_currentPacket->begin ());
1961  Time duration = Seconds (0);
1962 
1963  duration += GetSifs ();
1964  duration += m_phy->CalculateTxDuration (m_currentPacket->GetSize (),
1967  {
1968  duration += GetSifs ();
1969  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (),
1971  duration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ());
1972  }
1973  else if (m_txParams.MustWaitNormalAck ())
1974  {
1975  duration += GetSifs ();
1976  duration += GetAckDuration (m_currentPacket->GetAddr1 (), m_currentTxVector);
1977  }
1978  if (m_txParams.HasNextPacket ())
1979  {
1980  duration += GetSifs ();
1984  {
1985  duration += GetSifs ();
1986  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (),
1988  duration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ());
1989  }
1990  else if (m_txParams.MustWaitNormalAck ())
1991  {
1992  duration += GetSifs ();
1993  duration += GetAckDuration (m_currentPacket->GetAddr1 (), m_currentTxVector);
1994  }
1995  }
1996 
1997  cts.SetDuration (duration);
1998 
1999  ForwardDown (Create<const WifiPsdu> (Create<Packet> (), cts), ctsTxVector);
2000 
2001  Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, m_phy->GetFrequency ());
2002  txDuration += GetSifs ();
2004 
2005  m_sendDataEvent = Simulator::Schedule (txDuration,
2006  &MacLow::SendDataAfterCts, this,
2007  duration);
2008 }
2009 
2010 void
2011 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiTxVector rtsTxVector, double rtsSnr)
2012 {
2013  NS_LOG_FUNCTION (this << source << duration << rtsTxVector.GetMode () << rtsSnr);
2014  /* send a CTS when you receive a RTS
2015  * right after SIFS.
2016  */
2017  WifiTxVector ctsTxVector = GetCtsTxVector (source, rtsTxVector.GetMode ());
2018  WifiMacHeader cts;
2019  cts.SetType (WIFI_MAC_CTL_CTS);
2020  cts.SetDsNotFrom ();
2021  cts.SetDsNotTo ();
2022  cts.SetNoMoreFragments ();
2023  cts.SetNoRetry ();
2024  cts.SetAddr1 (source);
2025  duration -= GetCtsDuration (source, rtsTxVector);
2026  duration -= GetSifs ();
2027  NS_ASSERT (duration.IsPositive ());
2028  cts.SetDuration (duration);
2029 
2030  Ptr<Packet> packet = Create<Packet> ();
2031 
2032  SnrTag tag;
2033  tag.Set (rtsSnr);
2034  packet->AddPacketTag (tag);
2035 
2036  //CTS should always use non-HT PPDU (HT PPDU cases not supported yet)
2037  ForwardDown (Create<const WifiPsdu> (packet, cts), ctsTxVector);
2038 }
2039 
2040 void
2042 {
2043  NS_LOG_FUNCTION (this);
2044  /* send the third step in a
2045  * RTS/CTS/DATA/ACK handshake
2046  */
2047  NS_ASSERT (m_currentPacket != 0);
2048 
2050  Time newDuration = Seconds (0);
2052  {
2053  newDuration += GetSifs ();
2054  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ());
2055  newDuration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ());
2056  }
2057  else if (m_txParams.MustWaitNormalAck ())
2058  {
2059  newDuration += GetSifs ();
2060  newDuration += GetAckDuration (m_currentPacket->GetAddr1 (), m_currentTxVector);
2061  }
2062  if (m_txParams.HasNextPacket ())
2063  {
2065  {
2066  newDuration += GetRifs ();
2067  }
2068  else
2069  {
2070  newDuration += GetSifs ();
2071  }
2074  {
2075  newDuration += GetSifs ();
2076  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ());
2077  newDuration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ());
2078  }
2079  else if (m_txParams.MustWaitNormalAck ())
2080  {
2081  newDuration += GetSifs ();
2082  newDuration += GetAckDuration (m_currentPacket->GetAddr1 (), m_currentTxVector);
2083  }
2084  }
2085 
2087  duration -= txDuration;
2088  duration -= GetSifs ();
2089 
2090  duration = std::max (duration, newDuration);
2091  NS_ASSERT (duration.IsPositive ());
2092  m_currentPacket->SetDuration (duration);
2094 }
2095 
2096 void
2098 {
2099  NS_LOG_FUNCTION (this);
2101 }
2102 
2103 void
2105 {
2106  NS_LOG_FUNCTION (this);
2108 }
2109 
2110 void
2112 {
2113  NS_LOG_FUNCTION (this);
2114  if (m_currentPacket->GetHeader (0).IsBeacon () && m_stationManager->GetPcfSupported ())
2115  {
2117  }
2118  if (!m_cfAckInfo.expectCfAck)
2119  {
2120  Ptr<Txop> txop = m_currentTxop;
2121  txop->EndTxNoAck ();
2122  }
2123  if (!IsCfPeriod ())
2124  {
2125  m_currentTxop = 0;
2126  }
2127 }
2128 
2129 void
2130 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
2131 {
2132  NS_LOG_FUNCTION (this);
2133  // send an ACK, after SIFS, when you receive a packet
2134  WifiTxVector ackTxVector = GetAckTxVector (source, dataTxMode);
2135  WifiMacHeader ack;
2136  ack.SetType (WIFI_MAC_CTL_ACK);
2137  ack.SetDsNotFrom ();
2138  ack.SetDsNotTo ();
2139  ack.SetNoRetry ();
2140  ack.SetNoMoreFragments ();
2141  ack.SetAddr1 (source);
2142  // 802.11-2012, Section 8.3.1.4: Duration/ID is received duration value
2143  // minus the time to transmit the ACK frame and its SIFS interval
2144  duration -= GetAckDuration (ackTxVector);
2145  duration -= GetSifs ();
2146  NS_ASSERT_MSG (duration.IsPositive (), "Please provide test case to maintainers if this assert is hit.");
2147  ack.SetDuration (duration);
2148 
2149  Ptr<Packet> packet = Create<Packet> ();
2150 
2151  SnrTag tag;
2152  tag.Set (dataSnr);
2153  packet->AddPacketTag (tag);
2154 
2155  //ACK should always use non-HT PPDU (HT PPDU cases not supported yet)
2156  ForwardDown (Create<const WifiPsdu> (packet, ack), ackTxVector);
2157 }
2158 
2159 bool
2161 {
2165  {
2166  Mac48Address originator = hdr.GetAddr2 ();
2167  uint8_t tid = 0;
2168  if (hdr.IsQosData ())
2169  {
2170  tid = hdr.GetQosTid ();
2171  }
2172  uint16_t seqNumber = hdr.GetSequenceNumber ();
2173  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2174  if (it != m_bAckAgreements.end ())
2175  {
2176  //Implement HT immediate Block Ack support for HT Delayed Block Ack is not added yet
2177  if (!QosUtilsIsOldPacket ((*it).second.first.GetStartingSequence (), seqNumber))
2178  {
2179  StoreMpduIfNeeded (packet, hdr);
2180  if (!IsInWindow (hdr.GetSequenceNumber (), (*it).second.first.GetStartingSequence (), (*it).second.first.GetBufferSize ()))
2181  {
2182  uint16_t delta = (seqNumber - (*it).second.first.GetWinEnd () + 4096) % 4096;
2183  if (delta > 1)
2184  {
2185  (*it).second.first.SetWinEnd (seqNumber);
2186  int16_t winEnd = (*it).second.first.GetWinEnd ();
2187  int16_t bufferSize = (*it).second.first.GetBufferSize ();
2188  uint16_t sum = (static_cast<uint16_t> (winEnd - bufferSize + 1 + 4096)) % 4096;
2189  (*it).second.first.SetStartingSequence (sum);
2190  RxCompleteBufferedPacketsWithSmallerSequence ((*it).second.first.GetStartingSequenceControl (), originator, tid);
2191  }
2192  }
2193  RxCompleteBufferedPacketsUntilFirstLost (originator, tid); //forwards up packets starting from winstart and set winstart to last +1
2194  (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2195  }
2196  return true;
2197  }
2198  return false;
2199  }
2200  return StoreMpduIfNeeded (packet, hdr);
2201 }
2202 
2203 bool
2205 {
2206  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
2207  if (it != m_bAckAgreements.end ())
2208  {
2209  WifiMacTrailer fcs;
2210  packet->RemoveTrailer (fcs);
2211  BufferedPacket bufferedPacket (packet, hdr);
2212 
2213  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2214  uint32_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
2215 
2216  BufferedPacketI i = (*it).second.second.begin ();
2217  for (; i != (*it).second.second.end ()
2218  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++)
2219  {
2220  }
2221  (*it).second.second.insert (i, bufferedPacket);
2222 
2223  //Update block ack cache
2224  BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
2225  NS_ASSERT (j != m_bAckCaches.end ());
2226  (*j).second.UpdateWithMpdu (&hdr);
2227  return true;
2228  }
2229  return false;
2230 }
2231 
2232 void
2234  uint16_t startingSeq)
2235 {
2236  NS_LOG_FUNCTION (this);
2237  uint8_t tid = respHdr->GetTid ();
2238  BlockAckAgreement agreement (originator, tid);
2239  if (respHdr->IsImmediateBlockAck ())
2240  {
2241  agreement.SetImmediateBlockAck ();
2242  }
2243  else
2244  {
2245  agreement.SetDelayedBlockAck ();
2246  }
2247  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
2248  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
2249  agreement.SetTimeout (respHdr->GetTimeout ());
2250  agreement.SetStartingSequence (startingSeq);
2251 
2252  std::list<BufferedPacket> buffer (0);
2253  AgreementKey key (originator, respHdr->GetTid ());
2254  AgreementValue value (agreement, buffer);
2255  m_bAckAgreements.insert (std::make_pair (key, value));
2256 
2257  BlockAckCache cache;
2258  cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
2259  m_bAckCaches.insert (std::make_pair (key, cache));
2260 
2261  if (respHdr->GetTimeout () != 0)
2262  {
2263  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
2264  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
2265 
2266  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
2267 
2268  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
2270  m_edca[ac], originator, tid, false);
2271  }
2272 }
2273 
2274 void
2276 {
2277  NS_LOG_FUNCTION (this);
2278  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2279  if (it != m_bAckAgreements.end ())
2280  {
2281  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequenceControl (), originator, tid);
2282  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2283  m_bAckAgreements.erase (it);
2284  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2285  NS_ASSERT (i != m_bAckCaches.end ());
2286  m_bAckCaches.erase (i);
2287  }
2288 }
2289 
2290 void
2292 {
2293  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2294  if (it != m_bAckAgreements.end ())
2295  {
2296  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2297  uint32_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
2298  BufferedPacketI last = (*it).second.second.begin ();
2299  uint16_t guard = 0;
2300  if (last != (*it).second.second.end ())
2301  {
2302  guard = (*it).second.second.begin ()->second.GetSequenceControl ();
2303  }
2304  BufferedPacketI i = (*it).second.second.begin ();
2305  for (; i != (*it).second.second.end ()
2306  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedStart; )
2307  {
2308  if (guard == (*i).second.GetSequenceControl ())
2309  {
2310  if (!(*i).second.IsMoreFragments ())
2311  {
2312  while (last != i)
2313  {
2314  m_rxCallback ((*last).first, &(*last).second);
2315  last++;
2316  }
2317  m_rxCallback ((*last).first, &(*last).second);
2318  last++;
2319  /* go to next packet */
2320  while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
2321  {
2322  i++;
2323  }
2324  if (i != (*it).second.second.end ())
2325  {
2326  guard = (*i).second.GetSequenceControl ();
2327  last = i;
2328  }
2329  }
2330  else
2331  {
2332  guard++;
2333  }
2334  }
2335  else
2336  {
2337  /* go to next packet */
2338  while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
2339  {
2340  i++;
2341  }
2342  if (i != (*it).second.second.end ())
2343  {
2344  guard = (*i).second.GetSequenceControl ();
2345  last = i;
2346  }
2347  }
2348  }
2349  (*it).second.second.erase ((*it).second.second.begin (), i);
2350  }
2351 }
2352 
2353 void
2355 {
2356  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2357  if (it != m_bAckAgreements.end ())
2358  {
2359  uint16_t guard = (*it).second.first.GetStartingSequenceControl ();
2360  BufferedPacketI lastComplete = (*it).second.second.begin ();
2361  BufferedPacketI i = (*it).second.second.begin ();
2362  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
2363  {
2364  if (!(*i).second.IsMoreFragments ())
2365  {
2366  while (lastComplete != i)
2367  {
2368  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2369  lastComplete++;
2370  }
2371  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2372  lastComplete++;
2373  }
2374  guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
2375  }
2376  (*it).second.first.SetStartingSequenceControl (guard);
2377  /* All packets already forwarded to WifiMac must be removed from buffer:
2378  [begin (), lastComplete) */
2379  (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
2380  }
2381 }
2382 
2383 void
2384 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
2385  Time duration, WifiMode blockAckReqTxMode, double rxSnr)
2386 {
2387  NS_LOG_FUNCTION (this);
2388  Ptr<Packet> packet = Create<Packet> ();
2389  packet->AddHeader (*blockAck);
2390 
2391  WifiMacHeader hdr;
2393  hdr.SetAddr1 (originator);
2394  hdr.SetAddr2 (GetAddress ());
2395  hdr.SetDsNotFrom ();
2396  hdr.SetDsNotTo ();
2397  hdr.SetNoRetry ();
2398  hdr.SetNoMoreFragments ();
2399 
2400  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (originator, blockAckReqTxMode);
2401 
2402  if (immediate)
2403  {
2405  duration -= GetSifs ();
2406  duration -= GetBlockAckDuration (blockAckReqTxVector, blockAck->GetType ());
2407  }
2408  else
2409  {
2410  m_txParams.EnableAck ();
2411  duration += GetSifs ();
2412  duration += GetAckDuration (originator, blockAckReqTxVector);
2413  }
2415 
2416  if (!immediate)
2417  {
2418  StartDataTxTimers (blockAckReqTxVector);
2419  }
2420 
2421  NS_ASSERT (duration.IsPositive ());
2422  hdr.SetDuration (duration);
2423  //here should be present a control about immediate or delayed block ack
2424  //for now we assume immediate
2425  SnrTag tag;
2426  tag.Set (rxSnr);
2427  packet->AddPacketTag (tag);
2428  ForwardDown (Create<const WifiPsdu> (packet, hdr), blockAckReqTxVector);
2429 }
2430 
2431 void
2432 MacLow::SendBlockAckAfterAmpdu (uint8_t tid, Mac48Address originator, Time duration, WifiTxVector blockAckReqTxVector, double rxSnr)
2433 {
2434  NS_LOG_FUNCTION (this);
2435  if (!m_phy->IsStateTx () && !m_phy->IsStateRx ())
2436  {
2437  NS_LOG_FUNCTION (this << +tid << originator << duration.As (Time::S) << blockAckReqTxVector << rxSnr);
2438  CtrlBAckResponseHeader blockAck;
2439  uint16_t seqNumber = 0;
2440  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2441  NS_ASSERT (i != m_bAckCaches.end ());
2442  seqNumber = (*i).second.GetWinStart ();
2443 
2444  bool immediate = true;
2445  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2446  blockAck.SetStartingSequence (seqNumber);
2447  blockAck.SetTidInfo (tid);
2448  immediate = (*it).second.first.IsImmediateBlockAck ();
2449  if ((*it).second.first.GetBufferSize () > 64)
2450  {
2451  blockAck.SetType (EXTENDED_COMPRESSED_BLOCK_ACK);
2452  }
2453  else
2454  {
2455  blockAck.SetType (COMPRESSED_BLOCK_ACK);
2456  }
2457  NS_LOG_DEBUG ("Got Implicit block Ack Req with seq " << seqNumber);
2458  (*i).second.FillBlockAckBitmap (&blockAck);
2459 
2460  WifiTxVector blockAckTxVector = GetBlockAckTxVector (originator, blockAckReqTxVector.GetMode ());
2461 
2462  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckTxVector.GetMode (), rxSnr);
2463  }
2464  else
2465  {
2466  NS_LOG_DEBUG ("Skip block ack response!");
2467  }
2468 }
2469 
2470 void
2472  Time duration, WifiMode blockAckReqTxMode, double rxSnr)
2473 {
2474  NS_LOG_FUNCTION (this);
2475  CtrlBAckResponseHeader blockAck;
2476  uint8_t tid = 0;
2477  bool immediate = false;
2478  if (!reqHdr.IsMultiTid ())
2479  {
2480  tid = reqHdr.GetTidInfo ();
2481  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2482  if (it != m_bAckAgreements.end ())
2483  {
2484  blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
2485  blockAck.SetTidInfo (tid);
2486  immediate = (*it).second.first.IsImmediateBlockAck ();
2487  if (reqHdr.IsBasic ())
2488  {
2489  blockAck.SetType (BASIC_BLOCK_ACK);
2490  }
2491  else if (reqHdr.IsCompressed ())
2492  {
2493  blockAck.SetType (COMPRESSED_BLOCK_ACK);
2494  }
2495  else if (reqHdr.IsExtendedCompressed ())
2496  {
2498  }
2499  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2500  NS_ASSERT (i != m_bAckCaches.end ());
2501  (*i).second.FillBlockAckBitmap (&blockAck);
2502  NS_LOG_DEBUG ("Got block Ack Req with seq " << reqHdr.GetStartingSequence ());
2503 
2507  {
2508  /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
2509  * See 9.10.3 in IEEE 802.11e standard.
2510  */
2512  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2513  }
2514  else
2515  {
2516  if (!QosUtilsIsOldPacket ((*it).second.first.GetStartingSequence (), reqHdr.GetStartingSequence ()))
2517  {
2518  (*it).second.first.SetStartingSequence (reqHdr.GetStartingSequence ());
2519  (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2521  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2522  (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2523  }
2524  }
2525  }
2526  else
2527  {
2528  NS_LOG_DEBUG ("there's not a valid block ack agreement with " << originator);
2529  }
2530  }
2531  else
2532  {
2533  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
2534  }
2535  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode, rxSnr);
2536 }
2537 
2538 void
2540 {
2541  if (agreement.GetTimeout () != 0)
2542  {
2543  NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
2544  agreement.m_inactivityEvent.Cancel ();
2545  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
2546  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
2549  m_edca[ac], agreement.GetPeer (),
2550  agreement.GetTid (), false);
2551  }
2552 }
2553 
2554 void
2556 {
2557  m_edca.insert (std::make_pair (ac, edca));
2558 }
2559 
2560 void
2561 MacLow::DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
2562 {
2563  NS_LOG_FUNCTION (this);
2564  bool normalAck = false;
2565  bool ampduSubframe = false; //flag indicating the packet belongs to an A-MPDU and is not a VHT/HE single MPDU
2566  if (txVector.IsAggregation ())
2567  {
2568  ampduSubframe = true;
2570  MpduAggregator::DeaggregatedMpdusCI n = packets.begin ();
2571  auto status = statusPerMpdu.begin ();
2572  NS_ABORT_MSG_IF (packets.size () != statusPerMpdu.size (), "Should have one receive status per MPDU");
2573 
2574  WifiMacHeader firsthdr;
2575  (*n).first->PeekHeader (firsthdr);
2576  NS_LOG_DEBUG ("duration/id=" << firsthdr.GetDuration ());
2577  NotifyNav ((*n).first, firsthdr);
2578 
2579  if (firsthdr.GetAddr1 () == m_self)
2580  {
2581  bool singleMpdu = (*n).second.GetEof ();
2582  //Iterate over all MPDUs and notify reception only if status OK
2583  for (; n != packets.end (); ++n, ++status)
2584  {
2585  (*n).first->PeekHeader (firsthdr);
2586  NS_ABORT_MSG_IF (firsthdr.GetAddr1 () != m_self, "All MPDUs of A-MPDU should have the same destination address");
2587  if (*status) //PER and thus CRC check succeeded
2588  {
2589  if (singleMpdu)
2590  {
2591  //If the MPDU is sent as a VHT/HE single MPDU (EOF=1 in A-MPDU subframe header), then the responder sends an ACK.
2592  NS_LOG_DEBUG ("Receive S-MPDU");
2593  ampduSubframe = false;
2594  }
2595  else if (!m_sendAckEvent.IsRunning ())
2596  {
2599  firsthdr.GetQosTid (),
2600  firsthdr.GetAddr2 (),
2601  firsthdr.GetDuration (),
2602  txVector, rxSnr);
2603  }
2604 
2605  if (firsthdr.IsAck () || firsthdr.IsBlockAck () || firsthdr.IsBlockAckReq ())
2606  {
2607  ReceiveOk ((*n).first, rxSnr, txVector, ampduSubframe);
2608  }
2609  else if (firsthdr.IsData () || firsthdr.IsQosData ())
2610  {
2611  NS_LOG_DEBUG ("Deaggregate packet from " << firsthdr.GetAddr2 () << " with sequence=" << firsthdr.GetSequenceNumber ());
2612  ReceiveOk ((*n).first, rxSnr, txVector, ampduSubframe);
2613  if (firsthdr.IsQosAck ())
2614  {
2615  NS_LOG_DEBUG ("Normal Ack");
2616  normalAck = true;
2617  }
2618  }
2619  else
2620  {
2621  NS_FATAL_ERROR ("Received A-MPDU with invalid first MPDU type");
2622  }
2623 
2624  if (!singleMpdu)
2625  {
2626  if (normalAck)
2627  {
2628  //send block Ack
2629  if (firsthdr.IsBlockAckReq ())
2630  {
2631  NS_FATAL_ERROR ("Sending a BlockAckReq with QosPolicy equal to Normal Ack");
2632  }
2633  uint8_t tid = firsthdr.GetQosTid ();
2634  AgreementsI it = m_bAckAgreements.find (std::make_pair (firsthdr.GetAddr2 (), tid));
2635  if (it != m_bAckAgreements.end ())
2636  {
2637  /* See section 11.5.3 in IEEE 802.11 for mean of this timer */
2638  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
2639  NS_LOG_DEBUG ("rx A-MPDU/sendImmediateBlockAck from=" << firsthdr.GetAddr2 ());
2641  }
2642  else
2643  {
2644  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
2645  }
2646  }
2647  }
2648  }
2649  }
2650  }
2651  }
2652  else
2653  {
2654  /* Simple MPDU */
2655  ReceiveOk (aggregatedPacket, rxSnr, txVector, ampduSubframe);
2656  }
2657 }
2658 
2659 Time
2661 {
2662  NS_LOG_FUNCTION (this);
2664  NS_ASSERT (remainingCfpDuration.IsPositive ());
2665  return remainingCfpDuration;
2666 }
2667 
2668 bool
2670 {
2672 }
2673 
2674 bool
2676 {
2677  NS_LOG_FUNCTION (this);
2678  if (!IsCfPeriod ())
2679  {
2680  return false;
2681  }
2682  NS_ASSERT (GetRemainingCfpDuration ().IsPositive ());
2683  WifiMacHeader hdr;
2684  hdr.SetType (WIFI_MAC_DATA);
2685  WifiMacTrailer fcs;
2686  uint32_t maxMacFrameSize = MAX_MSDU_SIZE + hdr.GetSerializedSize () + fcs.GetSerializedSize ();
2688  return ((GetRemainingCfpDuration () - nextTransmission).IsPositive ());
2689 }
2690 
2691 } //namespace ns3
void WaitIfsAfterEndTxPacket(void)
Event handler that is usually scheduled to fired at the appropriate time after sending a packet...
Definition: mac-low.cc:2104
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void Set(double snr)
Set the SNR to the given value.
Definition: snr-tag.cc:83
Time GetRifs(void) const
Return Reduced Interframe Space (RIFS) of this MacLow.
Definition: mac-low.cc:435
bool IsCfEnd(void) const
Return true if the header is a CF-END header.
void SetPifs(Time pifs)
Set PCF Interframe Space (PIFS) of this MacLow.
Definition: mac-low.cc:363
Time m_ctsTimeout
CTS timeout duration.
Definition: mac-low.h:914
bool IsStateOff(void) const
Definition: wifi-phy.cc:4132
bool GetRifsPermitted(void) const
Return whether the device can use RIFS.
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
uint16_t GetTimeout(void) const
Return the timeout.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
EventId m_navCounterResetCtsMissed
Event to reset NAV when CTS is not received.
Definition: mac-low.h:904
bool GetVhtSupported(void) const
Return whether the device has VHT capability support enabled.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
std::vector< Ptr< ChannelAccessManager > >::const_iterator ChannelAccessManagersCI
typedef for an iterator for a list of ChannelAccessManager.
Definition: mac-low.h:886
void ResetBlockAckInactivityTimerIfNeeded(BlockAckAgreement &agreement)
Every time that a block ack request or a packet with ack policy equals to block ack are received...
Definition: mac-low.cc:2539
EventId m_blockAckTimeoutEvent
Block ACK timeout event.
Definition: mac-low.h:897
Time CalculateOverallTxTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &params, uint32_t fragmentSize=0) const
Definition: mac-low.cc:1413
Callback template class.
Definition: callback.h:1176
void SendPacket(Ptr< const Packet > packet, WifiTxVector txVector)
Definition: wifi-phy.cc:2516
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void ReceiveError(Ptr< Packet > packet)
Definition: mac-low.cc:677
Ptr< MpduAggregator > GetMpduAggregator(void) const
Returns the aggregator used to construct A-MPDU subframes.
Definition: mac-low.cc:289
WifiMode GetMcs(uint8_t mcs) const
The WifiPhy::GetMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of tr...
Definition: wifi-phy.cc:4090
void SendBlockAckAfterBlockAckRequest(const CtrlBAckRequestHeader reqHdr, Mac48Address originator, Time duration, WifiMode blockAckReqTxMode, double rxSnr)
Invoked after that a block ack request has been received.
Definition: mac-low.cc:2471
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetDuration(Time duration)
Set the Duration/ID field with the given duration (Time object).
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
void SetPromisc(void)
Enable promiscuous mode.
Definition: mac-low.cc:393
#define min(a, b)
Definition: 80211b.c:42
virtual void StartNextPacket(void)
Start transmission for the next packet if allowed by the TxopLimit.
Definition: txop.cc:870
void DoNavResetNow(Time duration)
Reset NAV with the given duration.
Definition: mac-low.cc:1531
bool GetShortGuardInterval(void) const
Return whether short guard interval is supported.
Definition: wifi-phy.cc:659
Ptr< Txop > m_currentTxop
Current TXOP.
Definition: mac-low.h:907
virtual void EndTxNoAck(void)
Event handler when a transmission that does not require an ACK has completed.
Definition: txop.cc:768
void NotifyMaybeCcaBusyStart(Time duration)
Definition: mac-low.cc:83
void SetupPhyMacLowListener(const Ptr< WifiPhy > phy)
Set up WifiPhy listener for this MacLow.
Definition: mac-low.cc:154
virtual void StartNextFragment(void)
Start transmission for the next fragment.
Definition: txop.cc:739
uint32_t GetRtsSize(void)
Return the total RTS size (including FCS trailer).
Definition: wifi-utils.cc:199
Ptr< MsduAggregator > m_msduAggregator
A-MSDU aggregator.
Definition: mac-low.h:893
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: mac-low.h:917
void SetPhy(const Ptr< WifiPhy > phy)
Set up WifiPhy associated with this MacLow.
Definition: mac-low.cc:247
uint32_t GetSize(Ptr< const Packet > packet, const WifiMacHeader *hdr, bool isAmpdu)
Return the total size of the packet after WifiMacHeader and FCS trailer have been added...
Definition: wifi-utils.cc:228
bool DoNavStartNow(Time duration)
Start NAV with the given duration.
Definition: mac-low.cc:1543
uint32_t GetSize(void) const
Return the size of the WifiMacHeader in octets.
void SetSifs(Time sifs)
Set Short Interframe Space (SIFS) of this MacLow.
Definition: mac-low.cc:351
void NotifySwitchingStart(Time duration)
Definition: mac-low.cc:86
void ReportDataOk(Mac48Address address, const WifiMacHeader *header, double ackSnr, WifiMode ackMode, double dataSnr, uint32_t packetSize)
Should be invoked whenever we receive the Ack associated to a data packet we just sent...
std::pair< Mac48Address, uint8_t > AgreementKey
agreement key typedef
Definition: mac-low.h:940
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:455
virtual void MissedAck(void)
Event handler when an ACK is missed.
Definition: txop.cc:665
Time CalculateOverheadTxTime(Ptr< const WifiMacQueueItem > item, const MacLowTransmissionParameters &params) const
Definition: mac-low.cc:1435
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
bool GetHeSupported(void) const
Return whether the device has HE capability support enabled.
#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
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:564
void Init(uint16_t winStart, uint16_t winSize)
Init function.
WifiMode GetDefaultMcs(void) const
Return the default Modulation and Coding Scheme (MCS) index.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
bool IsNavZero(void) const
Check if NAV is zero.
Definition: mac-low.cc:1944
static DeaggregatedMpdus Deaggregate(Ptr< Packet > aggregatedPacket)
Deaggregates an A-MPDU by removing the A-MPDU subframe header and padding.
void NotifyOffNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
Definition: mac-low.cc:729
void NotifySleepNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
Definition: mac-low.cc:714
void NotifyNav(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Notify NAV function.
Definition: mac-low.cc:1478
WifiMode GetBasicMcs(uint8_t i) const
Return the MCS at the given list index.
Mac48Address GetBssid(void) const
Return the Basic Service Set Identification.
Definition: mac-low.cc:453
std::list< std::pair< Ptr< Packet >, AmpduSubframeHeader > >::const_iterator DeaggregatedMpdusCI
A constant iterator for a list of deaggregated packets and their A-MPDU subframe headers.
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: qos-txop.cc:1655
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet. ...
Definition: qos-utils.cc:84
bool IsStrictlyPositive(void) const
Definition: nstime.h:308
virtual void Cancel(void)
Cancel the transmission.
Definition: txop.cc:761
uint32_t GetAckSize(void)
Return the total ACK size (including FCS trailer).
Definition: wifi-utils.cc:181
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:743
uint16_t GetBufferSize(void) const
Return the buffer size.
Callback< R > MakeNullCallback(void)
Definition: callback.h:1635
VHT PHY (Clause 22)
Definition: wifi-mode.h:60
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
WifiTxVector GetRtsTxVector(Ptr< const WifiMacQueueItem > item) const
Return a TXVECTOR for the RTS frame given the destination.
Definition: mac-low.cc:1197
Mac48Address m_bssid
BSSID address (Mac48Address)
Definition: mac-low.h:910
ns3::Time timeout
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble, bool useGreenfield)
Return the preamble to be used for the transmission.
Definition: wifi-utils.cc:128
uint8_t GetNBasicMcs(void) const
Return the number of basic MCS index.
EventId m_sendCtsEvent
Event to send CTS.
Definition: mac-low.h:899
MacLowRxCallback m_rxCallback
Callback to pass packet up.
Definition: mac-low.h:871
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
bool appendCfAck
Flag used for PCF to indicate whether a CF-ACK should be appended.
Definition: mac-low.h:878
EventId m_sendAckEvent
Event to send ACK.
Definition: mac-low.h:900
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
WifiMode GetControlAnswerMode(WifiMode reqMode) const
Get control answer mode function.
Definition: mac-low.cc:1211
void NotifyAckTimeoutResetNow(void)
Notify ChannelAccessManager that ACK timer should be reset.
Definition: mac-low.cc:1570
Time m_cfpMaxDuration
CFP max duration.
Definition: mac-low.h:921
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
Time CalculateTransmissionTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &parameters) const
Definition: mac-low.cc:1463
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
control how a packet is transmitted.
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
bool IsMandatory(void) const
Definition: wifi-mode.cc:465
void SetCtsToSelfSupported(bool enable)
Enable or disable CTS-to-self capability.
Definition: mac-low.cc:333
bool expectCfAck
Flag used for PCF to indicate whether a CF-ACK should be expected.
Definition: mac-low.h:879
QueueEdcas m_edca
EDCA queues.
Definition: mac-low.h:953
void NormalAckTimeout(void)
Event handler when normal ACK timeout occurs.
Definition: mac-low.cc:1707
void SetBasicBlockAckTimeout(Time blockAckTimeout)
Set Basic Block ACK timeout of this MacLow.
Definition: mac-low.cc:321
phy
Definition: third.py:86
BlockAckCaches m_bAckCaches
block ack caches
Definition: mac-low.h:950
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1357
Ptr< WifiMac > m_mac
Pointer to WifiMac (to fetch configuration)
Definition: mac-low.h:869
WifiPreamble GetPreambleType(void) const
void RemovePhyMacLowListener(Ptr< WifiPhy > phy)
Remove current WifiPhy listener for this MacLow.
Definition: mac-low.cc:161
uint8_t GetTid(void) const
Return the Traffic ID (TID).
uint8_t GetNMcs(void) const
The WifiPhy::GetNMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of t...
Definition: wifi-phy.cc:4084
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2344
bool IsPromisc(void) const
Check if MacLow is operating in promiscuous mode.
Definition: mac-low.cc:471
void NotifyOn(void)
Notify listeners that we went to switch on.
Definition: mac-low.cc:101
WifiTxVector m_currentTxVector
TXVECTOR used for the current packet transmission.
Definition: mac-low.h:956
bool GetShortPreambleEnabled(void) const
Return whether the device uses short PLCP preambles.
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:2275
Time m_lastNavDuration
The duration of the latest NAV.
Definition: mac-low.h:924
bool IsImmediateBlockAck(void) const
Return whether the Block ACK policy is immediate Block ACK.
void SetCfpMaxDuration(Time duration)
Definition: mac-low.cc:381
Time GetCtsDuration(WifiTxVector ctsTxVector) const
Return the time required to transmit the CTS (including preamble and FCS).
Definition: mac-low.cc:1190
bool IsWithinSizeAndTimeLimits(Ptr< const WifiMacQueueItem > mpdu, WifiTxVector txVector, uint32_t ampduSize, Time ppduDurationLimit)
Check whether the given MPDU, if transmitted according to the given TX vector, meets the constraint o...
Definition: mac-low.cc:620
std::pair< Ptr< Packet >, WifiMacHeader > BufferedPacket
buffered packet typedef
Definition: mac-low.h:937
void SendCtsToSelf(void)
Send CTS for a CTS-to-self mechanism.
Definition: mac-low.cc:1950
bool m_ctsToSelfSupported
Flag whether CTS-to-self is supported.
Definition: mac-low.h:955
void SendAckAfterData(Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
Send ACK after receiving DATA.
Definition: mac-low.cc:2130
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1389
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
Definition: mac-low.cc:399
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
virtual void StartTransmission(Ptr< WifiMacQueueItem > mpdu, MacLowTransmissionParameters parameters, Ptr< Txop > txop)
Definition: mac-low.cc:489
#define max(a, b)
Definition: 80211b.c:43
void CreateBlockAckAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address originator, uint16_t startingSeq)
Definition: mac-low.cc:2233
Time m_lastBeacon
The time when the last beacon frame transmission started.
Definition: mac-low.h:927
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Time GetCompressedBlockAckTimeout(void) const
Return Compressed Block ACK timeout of this MacLow.
Definition: mac-low.cc:417
void ReportRtsFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the RtsTimeout associated to a transmission attempt expires.
bool GetPcfSupported(void) const
Return whether the device has PCF capability support enabled.
uint16_t GetTimeout(void) const
Return the timeout.
Listener for PHY events.
Definition: mac-low.cc:56
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1086
receive notifications about phy events.
void CtsTimeout(void)
Event handler when CTS timeout occurs.
Definition: mac-low.cc:1685
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
static const uint16_t MAX_MSDU_SIZE
This value conforms to the 802.11 specification.
Time GetSifs(void) const
Return Short Interframe Space (SIFS) of this MacLow.
Definition: mac-low.cc:429
void EndTxNoAck(void)
A transmission that does not require an ACK has completed.
Definition: mac-low.cc:2111
uint32_t GetSerializedSize(void) const
void SendBlockAckAfterAmpdu(uint8_t tid, Mac48Address originator, Time duration, WifiTxVector blockAckReqTxVector, double rxSnr)
Invoked after an A-MPDU has been received.
Definition: mac-low.cc:2432
std::map< AgreementKey, BlockAckCache >::iterator BlockAckCachesI
block ack caches iterator typedef
Definition: mac-low.h:947
virtual bool IsCfPeriod(void) const
This function indicates whether it is the CF period.
Definition: mac-low.cc:2669
void EnableExtendedCompressedBlockAck(void)
Wait COMPRESSEDBLOCKACKTimeout for an Extended Compressed Block Ack Response frame.
void SetAckTimeout(Time ackTimeout)
Set ACK timeout of this MacLow.
Definition: mac-low.cc:315
bool GetHtSupported(void) const
Return whether the device has HT capability support enabled.
static TypeId GetTypeId(void)
Register this type.
Definition: mac-low.cc:143
mac
Definition: third.py:92
uint16_t ConvertGuardIntervalToNanoSeconds(WifiMode mode, const Ptr< WifiNetDevice > device)
Convert the guard interval to nanoseconds based on the wifimode.
Definition: wifi-utils.cc:71
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:32
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
Time GetCtsTimeout(void) const
Return CTS timeout of this MacLow.
Definition: mac-low.cc:423
WifiMode GetMode(void) const
HT PHY (Clause 20)
Definition: wifi-mode.h:58
void NavCounterResetCtsMissed(Time rtsEndRxTime)
Reset NAV after CTS was missed when the NAV was set with RTS.
Definition: mac-low.cc:1522
Ptr< WifiRemoteStationManager > m_stationManager
Pointer to WifiRemoteStationManager (rate control)
Definition: mac-low.h:870
void SetMac(const Ptr< WifiMac > mac)
Set up WifiMac associated with this MacLow.
Definition: mac-low.cc:271
Headers for Block ack response.
Definition: ctrl-headers.h:193
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
void SendDataAfterCts(Time duration)
Send DATA after receiving CTS.
Definition: mac-low.cc:2041
void RegisterEdcaForAc(AcIndex ac, Ptr< QosTxop > edca)
Definition: mac-low.cc:2555
Agreements m_bAckAgreements
block ack agreements
Definition: mac-low.h:949
bool IsCompressed(void) const
Check if the current ACK policy is compressed ACK and not multiple TID.
bool IsExtendedCompressed(void) const
Check if the current BA policy is extended compressed block ACK.
virtual WifiTxVector GetDataTxVector(Ptr< const WifiMacQueueItem > item) const
Return a TXVECTOR for the DATA frame given the destination.
Definition: mac-low.cc:1204
virtual bool IsQosTxop() const
Check for QoS TXOP.
Definition: txop.cc:864
void NotifySwitchingStartNow(Time duration)
Definition: mac-low.cc:698
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:494
void NotifyOff(void)
Notify listeners that we went to switch off.
Definition: mac-low.cc:94
Time GetCfpMaxDuration(void) const
Definition: mac-low.cc:465
Time m_slotTime
Slot duration.
Definition: mac-low.h:916
#define list
WifiTxVector GetAckTxVector(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the ACK frame given the destination and the mode of the DATA used by the sender...
Definition: mac-low.cc:1369
WifiMode GetDefaultMode(void) const
Return the default transmission mode.
Mac48Address GetPeer(void) const
Return the peer address.
bool m_promisc
Flag if the device is operating in promiscuous mode.
Definition: mac-low.h:930
void NotifyRxStart(Time duration)
Definition: mac-low.cc:71
void SetNss(uint8_t nss)
Sets the number of Nss refer to IEEE 802.11n Table 20-28 for explanation and range.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
void CancelAllEvents(void)
Cancel all scheduled events.
Definition: mac-low.cc:195
WifiTxVector GetCtsTxVector(Mac48Address to, WifiMode rtsTxMode) const
Return a TXVECTOR for the CTS frame given the destination and the mode of the RTS used by the sender...
Definition: mac-low.cc:1353
std::list< BufferedPacket >::iterator BufferedPacketI
buffered packet iterator typedef
Definition: mac-low.h:938
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
void BlockAckTimeout(void)
Event handler when block ACK timeout occurs.
Definition: mac-low.cc:1720
void NotifyCtsTimeoutStartNow(Time duration)
Notify ChannelAccessManager that CTS timer should be started for the given duration.
Definition: mac-low.cc:1579
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
Time GetAckTimeout(void) const
Return ACK timeout of this MacLow.
Definition: mac-low.cc:405
void EnableCompressedBlockAck(void)
Wait COMPRESSEDBLOCKACKTimeout for a Compressed Block Ack Response frame.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Time GetRemainingCfpDuration(void) const
Definition: mac-low.cc:2660
void GotCfEnd(void)
Event handler when a CF-END frame is received.
Definition: txop.cc:699
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
void RegisterDcf(Ptr< ChannelAccessManager > dcf)
Definition: mac-low.cc:483
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
void SetBssid(Mac48Address ad)
Set the Basic Service Set Identification.
Definition: mac-low.cc:387
Time GetBasicBlockAckTimeout(void) const
Return Basic Block ACK timeout of this MacLow.
Definition: mac-low.cc:411
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1337
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
EventId m_waitIfsEvent
Wait for IFS event.
Definition: mac-low.h:902
void ReceiveOk(Ptr< Packet > packet, double rxSnr, WifiTxVector txVector, bool ampduSubframe)
Definition: mac-low.cc:744
void EnableAck(void)
Wait ACKTimeout for an ACK.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
Time GetDuration(void) const
Return the duration from the Duration/ID field (Time object).
virtual void MissedBlockAck(uint8_t nMpdus)
Event handler when a Block ACK timeout has occurred.
Definition: txop.cc:882
void NotifyMissedCts(std::list< Ptr< WifiMacQueueItem >> mpduList)
Event handler when a CTS timeout has occurred.
Definition: qos-txop.cc:685
EventId m_normalAckTimeoutEvent
Normal ACK timeout event.
Definition: mac-low.h:896
bool IsHigherCodeRate(WifiMode mode) const
Definition: wifi-mode.cc:589
void StartDataTxTimers(WifiTxVector dataTxVector)
Start a DATA timer by scheduling appropriate ACK timeout.
Definition: mac-low.cc:1783
void NotifyWakeup(void)
Notify listeners that we woke up.
Definition: mac-low.cc:98
void SetType(BlockAckType type)
Set the block ACK type.
Time m_beaconInterval
Expected interval between two beacon transmissions.
Definition: mac-low.h:920
uint16_t GetChannelWidthForTransmission(WifiMode mode, uint16_t maxSupportedChannelWidth)
Return the channel width that corresponds to the selected mode (instead of letting the PHY&#39;s default ...
Definition: wifi-utils.cc:109
bool UseGreenfieldForDestination(Mac48Address dest) const
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
Definition: wifi-utils.cc:215
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:318
an EUI-48 address
Definition: mac48-address.h:43
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
Time m_cfpForeshortening
The delay the current CF period should be foreshortened.
Definition: mac-low.h:928
void NotifyTxStart(Time duration, double txPowerDbm)
Definition: mac-low.cc:80
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
void SendBlockAckResponse(const CtrlBAckResponseHeader *blockAck, Mac48Address originator, bool immediate, Time duration, WifiMode blockAckReqTxMode, double rxSnr)
This method creates block ack frame with header equals to blockAck and start its transmission.
Definition: mac-low.cc:2384
Time GetAckDuration(WifiTxVector ackTxVector) const
Return the time required to transmit the ACK (including preamble and FCS).
Definition: mac-low.cc:1166
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
Time m_ackTimeout
ACK timeout duration.
Definition: mac-low.h:911
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr)
Extraction operator for TypeId.
Definition: qos-utils.cc:99
bool IsAllowedControlAnswerModulationClass(WifiModulationClass modClassReq, WifiModulationClass modClassAnswer)
Return whether the modulation class of the selected mode for the control answer frame is allowed...
Definition: wifi-utils.cc:158
bool IsGroup(void) const
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
void ReportRtsOk(Mac48Address address, const WifiMacHeader *header, double ctsSnr, WifiMode ctsMode, double rtsSnr)
Should be invoked whenever we receive the Cts associated to an RTS we just sent.
EventId m_ctsTimeoutEvent
CTS timeout event.
Definition: mac-low.h:898
void RxCompleteBufferedPacketsWithSmallerSequence(uint16_t seq, Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:2291
void SendCtsAfterRts(Mac48Address source, Time duration, WifiTxVector rtsTxVector, double rtsSnr)
Send CTS after receiving RTS.
Definition: mac-low.cc:2011
Ptr< MsduAggregator > GetMsduAggregator(void) const
Returns the aggregator used to construct A-MSDU subframes.
Definition: mac-low.cc:283
Time m_basicBlockAckTimeout
Basic block ACK timeout duration.
Definition: mac-low.h:912
bool GetCtsToSelfSupported(void) const
Return whether CTS-to-self capability is supported.
Definition: mac-low.cc:339
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: mac-low.h:915
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetBeaconInterval(Time interval)
Definition: mac-low.cc:375
void SetDelayedBlockAck(void)
Set Block ACK policy to delayed ACK.
uint8_t GetNModes(void) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:4072
void NotifySleep(void)
Notify listeners that we went to sleep.
Definition: mac-low.cc:90
uint32_t GetCtsSize(void)
Return the total CTS size (including FCS trailer).
Definition: wifi-utils.cc:207
Time m_lastNavStart
The time when the latest NAV started.
Definition: mac-low.h:923
EventId m_inactivityEvent
inactivity event
bool NeedCtsToSelf(WifiTxVector txVector)
Return if we need to do Cts-to-self before sending a DATA.
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
uint16_t GetRawDuration(void) const
Return the raw duration from the Duration/ID field.
uint8_t GetNBasicModes(void) const
Return the number of basic modes we support.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
handle RTS/CTS/DATA/ACK transactions.
Definition: mac-low.h:59
Mac48Address address
Address of the station to be acknowledged.
Definition: mac-low.h:880
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:449
WifiMode GetMode(uint8_t mode) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:4078
EventId m_sendDataEvent
Event to send DATA.
Definition: mac-low.h:901
bool IsStateTx(void) const
Definition: wifi-phy.cc:4114
bool ReceiveMpdu(Ptr< Packet > packet, WifiMacHeader hdr)
Definition: mac-low.cc:2160
void NotifyRxEndError(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
Definition: mac-low.cc:77
MacLowTransmissionParameters m_txParams
Transmission parameters of the current packet.
Definition: mac-low.h:908
void SetRifs(Time rifs)
Set Reduced Interframe Space (RIFS) of this MacLow.
Definition: mac-low.cc:369
void DoDispose(void)
Destructor implementation.
Definition: mac-low.cc:172
WifiTxVector GetDataTxVector(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
void SetMsduAggregator(const Ptr< MsduAggregator > aggr)
Set the aggregator used to construct A-MSDU subframes.
Definition: mac-low.cc:295
WifiTxVector GetAckTxVectorForData(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the Block ACK frame given the destination and the mode of the DATA used by the ...
Definition: mac-low.cc:1407
WifiModulationClass
This enumeration defines the modulation classes per (Table 9-4 "Modulation classes"; IEEE 802...
Definition: wifi-mode.h:36
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
Time GetPpduMaxTime(WifiPreamble preamble)
Get the maximum PPDU duration (see Section 10.14 of 802.11-2016) for the PHY layers defining the aPPD...
Definition: wifi-utils.cc:244
Mac48Address m_self
Address of this MacLow (Mac48Address)
Definition: mac-low.h:909
Maintains information for a block ack agreement.
WifiTxVector GetBlockAckTxVector(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the Block ACK frame given the destination and the mode of the DATA used by the ...
Definition: mac-low.cc:1385
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:863
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Next function is useful to correctly sort buffered packets under block ack.
Definition: qos-utils.cc:73
void NotifyAckTimeoutStartNow(Time duration)
Notify ChannelAccessManager that ACK timer should be started for the given duration.
Definition: mac-low.cc:1561
bool CanTransmitNextCfFrame(void) const
This function decides if a CF frame can be transmitted in the current CFP.
Definition: mac-low.cc:2675
void SetSlotTime(Time slotTime)
Set slot duration of this MacLow.
Definition: mac-low.cc:357
virtual void GotAck(void)
Event handler when an ACK is received.
Definition: txop.cc:635
bool IsAmsduSupported(void) const
Return whether A-MSDU capability is supported.
bool IsPositive(void) const
Definition: nstime.h:298
void Reset(void)
Reset the station, invoked in a STA upon dis-association or in an AP upon reboot. ...
bool GetUseNonErpProtection(void) const
Return whether the device supports protection of non-ERP stations.
virtual void MissedCts(void)
Event handler when a CTS timeout has occurred.
Definition: txop.cc:606
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:870
Implement the header for management frames of type add block ack response.
Definition: mgt-headers.h:1129
Time m_cfpStart
The time when the latest CF period started.
Definition: mac-low.h:926
ns3::MacLow * m_macLow
the MAC
Definition: mac-low.cc:106
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:272
uint32_t GetBlockAckSize(BlockAckType type)
Return the total Block ACK size (including FCS trailer).
Definition: wifi-utils.cc:189
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
std::map< AgreementKey, AgreementValue >::iterator AgreementsI
agreements iterator
Definition: mac-low.h:944
uint32_t GetSerializedSize(void) const
EventId m_endTxNoAckEvent
Event for finishing transmission that does not require ACK.
Definition: mac-low.h:903
virtual Time GetTxopRemaining(void) const
Return the remaining duration in the current TXOP.
Definition: txop.cc:888
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
void MissedCfPollResponse(bool expectedCfAck)
Event handler when a response to a CF-POLL frame is missed.
Definition: txop.cc:713
Time GetBlockAckDuration(WifiTxVector blockAckReqTxVector, BlockAckType type) const
Return the time required to transmit the Block ACK to the specified address given the TXVECTOR of the...
Definition: mac-low.cc:1173
CfAckInfo m_cfAckInfo
Info about piggyback ACKs used in PCF.
Definition: mac-low.h:958
void SetMpduAggregator(const Ptr< MpduAggregator > aggr)
Set the aggregator used to construct A-MPDU subframes.
Definition: mac-low.cc:302
void ReportRxOk(Mac48Address address, const WifiMacHeader *header, double rxSnr, WifiMode txMode)
void NotifyRxEndOk(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
Definition: mac-low.cc:74
std::list< std::pair< Ptr< Packet >, AmpduSubframeHeader > > DeaggregatedMpdus
A list of deaggregated packets and their A-MPDU subframe headers.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
void SetCtsTimeout(Time ctsTimeout)
Set CTS timeout of this MacLow.
Definition: mac-low.cc:345
void SetImmediateBlockAck(void)
Set Block ACK policy to immediate ACK.
bool IsRts(void) const
Return true if the header is a RTS header.
void DisableNextData(void)
Do not attempt to send data burst after current transmission.
BlockAckType GetType(void) const
Return the block ACK type ID.
void SendDataPacket(void)
Send DATA packet, which can be DATA-ACK or RTS-CTS-DATA-ACK transaction.
Definition: mac-low.cc:1845
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS DATA...
void DeaggregateAmpduAndReceive(Ptr< Packet > aggregatedPacket, double rxSnr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Definition: mac-low.cc:2561
void SetTimeout(uint16_t timeout)
Set timeout.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1078
Time GetPifs(void) const
Return PCF Interframe Space (PIFS) of this MacLow.
Definition: mac-low.cc:447
void SetAddress(Mac48Address ad)
Set MAC address of this MacLow.
Definition: mac-low.cc:309
uint32_t GetCfEndSize(void) const
Return the total CF-END size (including FCS trailer).
Definition: mac-low.cc:1144
void ForwardDown(Ptr< const WifiPsdu > psdu, WifiTxVector txVector)
Forward a PSDU down to WifiPhy for transmission.
Definition: mac-low.cc:1597
second
Definition: nstime.h:114
WifiTxVector GetRtsTxVector(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
A base class which provides memory management and object aggregation.
Definition: object.h:87
void WaitIfsAfterEndTxFragment(void)
Event handler that is usually scheduled to fired at the appropriate time after completing transmissio...
Definition: mac-low.cc:2097
PhyMacLowListener(ns3::MacLow *macLow)
Create a PhyMacLowListener for the given MacLow.
Definition: mac-low.cc:64
Time GetBeaconInterval(void) const
Definition: mac-low.cc:459
Time m_compressedBlockAckTimeout
Compressed block ACK timeout duration.
Definition: mac-low.h:913
void CfPollTimeout(void)
Event handler when CF-POLL timeout occurs.
Definition: mac-low.cc:1667
virtual void TerminateTxop(void)
Update backoff and restart access if needed.
Definition: txop.cc:895
void NotifyCtsTimeoutResetNow(void)
Notify ChannelAccessManager that CTS timer should be reset.
Definition: mac-low.cc:1588
Headers for Block ack request.
Definition: ctrl-headers.h:41
WifiMode GetBasicMode(uint8_t i) const
Return a basic mode from the set of basic modes.
Ptr< WifiPsdu > m_currentPacket
Current packet transmitted/to be transmitted.
Definition: mac-low.h:906
virtual ~PhyMacLowListener()
Definition: mac-low.cc:68
void ResetPhy(void)
Remove WifiPhy associated with this MacLow.
Definition: mac-low.cc:262
virtual void GotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
Event handler when a Block ACK is received.
Definition: txop.cc:876
void DisableAck(void)
Do not wait for Ack after data transmission.
std::pair< BlockAckAgreement, std::list< BufferedPacket > > AgreementValue
agreement value typedef
Definition: mac-low.h:941
Time GetSlotTime(void) const
Return slot duration of this MacLow.
Definition: mac-low.cc:441
WifiTxVector GetCtsTxVectorForRts(Mac48Address to, WifiMode rtsTxMode) const
Return a TXVECTOR for the CTS frame given the destination and the mode of the RTS used by the sender...
Definition: mac-low.cc:1401
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
a unique identifier for an interface.
Definition: type-id.h:58
void SetRxCallback(Callback< void, Ptr< Packet >, const WifiMacHeader *> callback)
Definition: mac-low.cc:477
bool IsHigherDataRate(WifiMode mode) const
Definition: wifi-mode.cc:609
BlockAckCache cache.
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
bool NeedCtsToSelf(void) const
Check if CTS-to-self mechanism should be used for the current packet.
Definition: mac-low.cc:613
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
Time GetLastRxStartTime(void) const
Return the start time of the last received packet.
Definition: wifi-phy.cc:4144
uint8_t GetTid(void) const
Return the Traffic ID (TID).
bool IsStateRx(void) const
Definition: wifi-phy.cc:4108
Time m_rifs
Reduced Interframe Space (RIFS) duration.
Definition: mac-low.h:918
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:38
Introspection did not find any typical Config paths.
Definition: snr-tag.h:34
bool StoreMpduIfNeeded(Ptr< Packet > packet, WifiMacHeader hdr)
Definition: mac-low.cc:2204
HE PHY (Clause 26)
Definition: wifi-mode.h:62
virtual ~MacLow()
Definition: mac-low.cc:136
Ptr< MpduAggregator > m_mpduAggregator
A-MPDU aggregator.
Definition: mac-low.h:894
Ptr< WifiPhy > m_phy
Pointer to WifiPhy (actually send/receives frames)
Definition: mac-low.h:868
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:150
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > manager)
Set up WifiRemoteStationManager associated with this MacLow.
Definition: mac-low.cc:277
Implements the IEEE 802.11 MAC header.
void SetCompressedBlockAckTimeout(Time blockAckTimeout)
Set Compressed Block ACK timeout of this MacLow.
Definition: mac-low.cc:327
Implements the IEEE 802.11 MAC trailer.
Ptr< WifiPhy > GetPhy(void) const
Definition: mac-low.cc:256
class PhyMacLowListener * m_phyMacLowListener
Listener needed to monitor when a channel switching occurs.
Definition: mac-low.h:932
ChannelAccessManagers m_channelAccessManagers
List of ChannelAccessManager.
Definition: mac-low.h:891
uint16_t GetSequenceControl(void) const
Return the raw Sequence Control field.
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
void SendRtsForPacket(void)
Send RTS to begin RTS-CTS-DATA-ACK transaction.
Definition: mac-low.cc:1730
BlockAckType
The different block ACK policies.
void RxCompleteBufferedPacketsUntilFirstLost(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:2354
Time GetGuardInterval(void) const
Definition: wifi-phy.cc:691
Time GetTxopLimit(void) const
Return the TXOP limit.
Definition: txop.cc:302