A Discrete-Event Network Simulator
API
frame-exchange-manager.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/abort.h"
23 #include "frame-exchange-manager.h"
24 #include "channel-access-manager.h"
25 #include "wifi-utils.h"
26 #include "snr-tag.h"
27 #include "wifi-mac-queue.h"
30 #include "wifi-mac-trailer.h"
31 
32 #undef NS_LOG_APPEND_CONTEXT
33 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
34 
35 // Time (in nanoseconds) to be added to the PSDU duration to yield the duration
36 // of the timer that is started when the PHY indicates the start of the reception
37 // of a frame and we are waiting for a response.
38 #define PSDU_DURATION_SAFEGUARD 400
39 
40 namespace ns3 {
41 
42 NS_LOG_COMPONENT_DEFINE ("FrameExchangeManager");
43 
44 NS_OBJECT_ENSURE_REGISTERED (FrameExchangeManager);
45 
46 TypeId
48 {
49  static TypeId tid = TypeId ("ns3::FrameExchangeManager")
50  .SetParent<Object> ()
51  .AddConstructor<FrameExchangeManager> ()
52  .SetGroupName ("Wifi")
53  ;
54  return tid;
55 }
56 
58  : m_navEnd (Seconds (0)),
59  m_promisc (false),
60  m_moreFragments (false)
61 {
62  NS_LOG_FUNCTION (this);
63 }
64 
66 {
68 }
69 
70 void
72 {
73  NS_LOG_FUNCTION (this);
74  m_txTimer.Cancel ();
76  {
78  }
80  m_mpdu = 0;
81  m_txParams.Clear ();
82  m_dcf = 0;
83 }
84 
85 void
87 {
88  NS_LOG_FUNCTION (this);
89  Reset ();
91  m_mac = 0;
92  m_txMiddle = 0;
93  m_rxMiddle = 0;
96  m_ackManager = 0;
97  if (m_phy != 0)
98  {
99  m_phy->TraceDisconnectWithoutContext ("PhyRxPayloadBegin",
101  }
102  m_phy = 0;
104 }
105 
106 void
108 {
109  NS_LOG_FUNCTION (this << protectionManager);
110  m_protectionManager = protectionManager;
111 }
112 
115 {
116  return m_protectionManager;
117 }
118 
119 void
121 {
122  NS_LOG_FUNCTION (this << ackManager);
123  m_ackManager = ackManager;
124 }
125 
128 {
129  return m_ackManager;
130 }
131 
132 void
134 {
135  NS_LOG_FUNCTION (this << mac);
136  m_mac = mac;
137 }
138 
139 void
141 {
142  NS_LOG_FUNCTION (this << txMiddle);
143  m_txMiddle = txMiddle;
144 }
145 
146 void
148 {
149  NS_LOG_FUNCTION (this << rxMiddle);
150  m_rxMiddle = rxMiddle;
151 }
152 
153 void
155 {
156  NS_LOG_FUNCTION (this << channelAccessManager);
157  m_channelAccessManager = channelAccessManager;
158 }
159 
160 void
162 {
163  NS_LOG_FUNCTION (this << phy);
164  m_phy = phy;
165  m_phy->TraceConnectWithoutContext ("PhyRxPayloadBegin",
168 }
169 
170 void
172 {
173  m_phy->TraceDisconnectWithoutContext ("PhyRxPayloadBegin",
176  m_phy = 0;
177 }
178 
179 void
181 {
182  NS_LOG_FUNCTION (this << address);
183  m_self = address;
184 }
185 
186 void
188 {
189  NS_LOG_FUNCTION (this << bssid);
190  m_bssid = bssid;
191 }
192 
193 void
195 {
196  m_promisc = true;
197 }
198 
199 bool
201 {
202  return m_promisc;
203 }
204 
205 void
207 {
208  m_mac->NotifyTxDrop (mpdu->GetPacket ());
209 }
210 
211 void
213 {
214  NS_LOG_FUNCTION (this << "PSDU reception started for " << psduDuration.As (Time::US)
215  << " (txVector: " << txVector << ")");
216 
217  if (psduDuration.IsZero ())
218  {
219  // PHY-RXEND immediately follows PHY-RXSTART (e.g. when PPDU has been filtered),
220  // no need to reschedule timeouts (CCA will take over)
221  return;
222  }
223 
224  NS_ASSERT (psduDuration.IsStrictlyPositive ());
226  "The TX timer and the NAV reset event cannot be both running");
227 
228  if (m_txTimer.IsRunning ())
229  {
230  // we are waiting for a response and something arrived
231  NS_LOG_DEBUG ("Rescheduling timeout event");
233  // PHY has switched to RX, so we can reset the ack timeout
234  m_channelAccessManager->NotifyAckTimeoutResetNow ();
235  }
236  else if (m_navResetEvent.IsRunning ())
237  {
239  }
240 }
241 
242 bool
244 {
245  NS_LOG_FUNCTION (this << dcf);
246 
247  NS_ASSERT (m_mpdu == 0);
248  if (m_txTimer.IsRunning ())
249  {
250  m_txTimer.Cancel ();
251  }
252  m_dcf = dcf;
253 
254  Ptr<WifiMacQueue> queue = dcf->GetWifiMacQueue ();
255 
256  // Even though channel access is requested when the queue is not empty, at
257  // the time channel access is granted the lifetime of the packet might be
258  // expired and the queue might be empty.
259  if (queue->IsEmpty ())
260  {
261  NS_LOG_DEBUG ("Queue empty");
263  m_dcf = 0;
264  return false;
265  }
266 
268  Ptr<WifiMacQueueItem> mpdu = *queue->Peek ()->GetQueueIteratorPairs ().front ().it;
269  NS_ASSERT (mpdu != 0);
270  NS_ASSERT (mpdu->GetHeader ().IsData () || mpdu->GetHeader ().IsMgt ());
271 
272  // assign a sequence number if this is not a fragment nor a retransmission
273  if (!mpdu->IsFragment () && !mpdu->GetHeader ().IsRetry ())
274  {
275  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&mpdu->GetHeader ());
276  mpdu->GetHeader ().SetSequenceNumber (sequence);
277  }
278 
279  NS_LOG_DEBUG ("MPDU payload size=" << mpdu->GetPacketSize () <<
280  ", to=" << mpdu->GetHeader ().GetAddr1 () <<
281  ", seq=" << mpdu->GetHeader ().GetSequenceControl ());
282 
283  // check if the MSDU needs to be fragmented
284  mpdu = GetFirstFragmentIfNeeded (mpdu);
285 
287  NS_ASSERT (m_ackManager != 0);
288  WifiTxParameters txParams;
289  txParams.m_txVector = m_mac->GetWifiRemoteStationManager ()->GetDataTxVector (mpdu->GetHeader ());
290  txParams.m_protection = m_protectionManager->TryAddMpdu (mpdu, txParams);
291  txParams.m_acknowledgment = m_ackManager->TryAddMpdu (mpdu, txParams);
292  txParams.AddMpdu (mpdu);
293  UpdateTxDuration (mpdu->GetHeader ().GetAddr1 (), txParams);
294 
295  SendMpduWithProtection (mpdu, txParams);
296 
297  return true;
298 }
299 
302 {
303  NS_LOG_FUNCTION (this << *mpdu);
304 
305  if (mpdu->IsFragment ())
306  {
307  // a fragment cannot be further fragmented
309  }
310  else if (m_mac->GetWifiRemoteStationManager ()->NeedFragmentation (mpdu))
311  {
312  NS_LOG_DEBUG ("Fragmenting the MSDU");
313  m_fragmentedPacket = mpdu->GetPacket ()->Copy ();
314  // dequeue the MSDU
316  queueIt.queue->Dequeue (queueIt.it);
317  // create the first fragment
318  mpdu->GetHeader ().SetMoreFragments ();
319  Ptr<Packet> fragment = m_fragmentedPacket->CreateFragment (0, m_mac->GetWifiRemoteStationManager ()->GetFragmentSize (mpdu, 0));
320  // enqueue the first fragment
321  Ptr<WifiMacQueueItem> item = Create<WifiMacQueueItem> (fragment, mpdu->GetHeader (), mpdu->GetTimeStamp ());
322  queueIt.queue->PushFront (item);
323  return item;
324  }
325  return mpdu;
326 }
327 
328 void
330 {
331  NS_LOG_FUNCTION (this << *mpdu << &txParams);
332 
333  m_mpdu = mpdu;
334  m_txParams = std::move (txParams);
335 
336  // If protection is required, the MPDU must be stored in some queue because
337  // it is not put back in a queue if the RTS/CTS exchange fails
339  || m_mpdu->GetHeader ().IsCtl ()
340  || m_mpdu->IsQueued ());
341 
342  // Make sure that the acknowledgment time has been computed, so that SendRts()
343  // and SendCtsToSelf() can reuse this value.
345 
346  if (m_txParams.m_acknowledgment->acknowledgmentTime == Time::Min ())
347  {
349  }
350 
351  // Set QoS Ack policy if this is a QoS data frame
353 
354  switch (m_txParams.m_protection->method)
355  {
358  break;
361  break;
363  SendMpdu ();
364  break;
365  default:
366  NS_ABORT_MSG ("Unknown protection type");
367  }
368 }
369 
370 void
372 {
373  NS_LOG_FUNCTION (this);
374 
376 
378 
380  {
382  }
384  {
387 
388  // the timeout duration is "aSIFSTime + aSlotTime + aRxPHYStartDelay, starting
389  // at the PHY-TXEND.confirm primitive" (section 10.3.2.9 or 10.22.2.2 of 802.11-2016).
390  // aRxPHYStartDelay equals the time to transmit the PHY header.
391  WifiNormalAck* normalAcknowledgment = static_cast<WifiNormalAck*> (m_txParams.m_acknowledgment.get ());
392 
393  Time timeout = txDuration
394  + m_phy->GetSifs ()
395  + m_phy->GetSlot ()
396  + m_phy->CalculatePhyPreambleAndHeaderDuration (normalAcknowledgment->ackTxVector);
399  this, m_mpdu);
400  m_channelAccessManager->NotifyAckTimeoutStartNow (timeout);
401  }
402  else
403  {
404  NS_ABORT_MSG ("Unable to handle the selected acknowledgment method ("
405  << m_txParams.m_acknowledgment.get () << ")");
406  }
407 
408  // transmit the MPDU
410 
412  {
413  // we are done with frames that do not require acknowledgment
414  m_mpdu = 0;
415  }
416 }
417 
418 void
420 {
421  NS_LOG_FUNCTION (this << *mpdu << txVector);
422 
423  // The MPDU is about to be transmitted, we can now dequeue it if it is stored in a queue
424  DequeueMpdu (mpdu);
425 
426  m_phy->Send (Create<WifiPsdu> (mpdu, false), txVector);
427 }
428 
429 void
431 {
432  NS_LOG_DEBUG (this << *mpdu);
433 
434  if (mpdu->IsQueued ())
435  {
437  NS_ASSERT (*queueIt.it == mpdu);
438  queueIt.queue->Dequeue (queueIt.it);
439  }
440 }
441 
442 void
444 {
445  NS_LOG_FUNCTION (this << protection);
446  NS_ASSERT (protection != nullptr);
447 
448  if (protection->method == WifiProtection::NONE)
449  {
450  protection->protectionTime = Seconds (0);
451  }
452  else if (protection->method == WifiProtection::RTS_CTS)
453  {
454  WifiRtsCtsProtection* rtsCtsProtection = static_cast<WifiRtsCtsProtection*> (protection);
455  rtsCtsProtection->protectionTime = m_phy->CalculateTxDuration (GetRtsSize (), rtsCtsProtection->rtsTxVector,
456  m_phy->GetPhyBand ())
457  + m_phy->CalculateTxDuration (GetCtsSize (), rtsCtsProtection->ctsTxVector,
458  m_phy->GetPhyBand ())
459  + 2 * m_phy->GetSifs ();
460  }
461  else if (protection->method == WifiProtection::CTS_TO_SELF)
462  {
463  WifiCtsToSelfProtection* ctsToSelfProtection = static_cast<WifiCtsToSelfProtection*> (protection);
464  ctsToSelfProtection->protectionTime = m_phy->CalculateTxDuration (GetCtsSize (),
465  ctsToSelfProtection->ctsTxVector,
466  m_phy->GetPhyBand ())
467  + m_phy->GetSifs ();
468  }
469 }
470 
471 void
473 {
474  NS_LOG_FUNCTION (this << acknowledgment);
475  NS_ASSERT (acknowledgment != nullptr);
476 
477  if (acknowledgment->method == WifiAcknowledgment::NONE)
478  {
479  acknowledgment->acknowledgmentTime = Seconds (0);
480  }
481  else if (acknowledgment->method == WifiAcknowledgment::NORMAL_ACK)
482  {
483  WifiNormalAck* normalAcknowledgment = static_cast<WifiNormalAck*> (acknowledgment);
484  normalAcknowledgment->acknowledgmentTime = m_phy->GetSifs ()
486  normalAcknowledgment->ackTxVector,
487  m_phy->GetPhyBand ());
488  }
489 }
490 
491 Time
492 FrameExchangeManager::GetTxDuration (uint32_t ppduPayloadSize, Mac48Address receiver,
493  const WifiTxParameters& txParams) const
494 {
495  return m_phy->CalculateTxDuration (ppduPayloadSize, txParams.m_txVector, m_phy->GetPhyBand ());
496 }
497 
498 void
500 {
501  txParams.m_txDuration = GetTxDuration (txParams.GetSize (receiver), receiver, txParams);
502 }
503 
504 Time
506  const WifiTxParameters& txParams,
507  Ptr<Packet> fragmentedPacket) const
508 {
509  NS_LOG_FUNCTION (this << header << size << &txParams << fragmentedPacket);
510 
511  NS_ASSERT (txParams.m_acknowledgment && txParams.m_acknowledgment->acknowledgmentTime != Time::Min ());
512  Time durationId = txParams.m_acknowledgment->acknowledgmentTime;
513 
514  // if the current frame is a fragment followed by another fragment, we have to
515  // update the Duration/ID to cover the next fragment and the corresponding Ack
516  if (header.IsMoreFragments ())
517  {
518  uint32_t payloadSize = size - header.GetSize () - WIFI_MAC_FCS_LENGTH;
519  uint32_t nextFragmentOffset = (header.GetFragmentNumber () + 1) * payloadSize;
520  uint32_t nextFragmentSize = std::min (fragmentedPacket->GetSize () - nextFragmentOffset,
521  payloadSize);
522  WifiTxVector ackTxVector = m_mac->GetWifiRemoteStationManager ()->GetAckTxVector (header.GetAddr1 (),
523  txParams.m_txVector.GetMode ());
524 
525  durationId += 2 * m_phy->GetSifs ()
526  + m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, m_phy->GetPhyBand ())
527  + m_phy->CalculateTxDuration (nextFragmentSize, txParams.m_txVector, m_phy->GetPhyBand ());
528  }
529  return durationId;
530 }
531 
532 Time
533 FrameExchangeManager::GetRtsDurationId (const WifiTxVector& rtsTxVector, Time txDuration, Time response) const
534 {
535  NS_LOG_FUNCTION (this << rtsTxVector << txDuration << response);
536 
537  WifiTxVector ctsTxVector;
538  ctsTxVector = m_mac->GetWifiRemoteStationManager ()->GetCtsTxVector (m_self, rtsTxVector.GetMode ());
539 
540  return m_phy->GetSifs ()
541  + m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, m_phy->GetPhyBand ()) /* CTS */
542  + m_phy->GetSifs () + txDuration + response;
543 }
544 
545 void
547 {
548  NS_LOG_FUNCTION (this << &txParams);
549 
550  NS_ASSERT (txParams.GetPsduInfoMap ().size () == 1);
551  Mac48Address receiver = txParams.GetPsduInfoMap ().begin ()->first;
552 
553  WifiMacHeader rts;
555  rts.SetDsNotFrom ();
556  rts.SetDsNotTo ();
557  rts.SetNoRetry ();
558  rts.SetNoMoreFragments ();
559  rts.SetAddr1 (receiver);
560  rts.SetAddr2 (m_self);
561 
562  NS_ASSERT (txParams.m_protection && txParams.m_protection->method == WifiProtection::RTS_CTS);
563  WifiRtsCtsProtection* rtsCtsProtection = static_cast<WifiRtsCtsProtection*> (txParams.m_protection.get ());
564 
565  NS_ASSERT (txParams.m_txDuration != Time::Min ());
566  rts.SetDuration (GetRtsDurationId (rtsCtsProtection->rtsTxVector, txParams.m_txDuration,
567  txParams.m_acknowledgment->acknowledgmentTime));
568  Ptr<WifiMacQueueItem> mpdu = Create<WifiMacQueueItem> (Create<Packet> (), rts);
569 
570  // After transmitting an RTS frame, the STA shall wait for a CTSTimeout interval with
571  // a value of aSIFSTime + aSlotTime + aRxPHYStartDelay (IEEE 802.11-2016 sec. 10.3.2.7).
572  // aRxPHYStartDelay equals the time to transmit the PHY header.
574  + m_phy->GetSifs ()
575  + m_phy->GetSlot ()
579  m_channelAccessManager->NotifyCtsTimeoutStartNow (timeout);
580 
581  ForwardMpduDown (mpdu, rtsCtsProtection->rtsTxVector);
582 }
583 
584 void
586  double rtsSnr)
587 {
588  NS_LOG_FUNCTION (this << rtsHdr << ctsTxVector << rtsSnr);
589 
590  WifiMacHeader cts;
592  cts.SetDsNotFrom ();
593  cts.SetDsNotTo ();
594  cts.SetNoMoreFragments ();
595  cts.SetNoRetry ();
596  cts.SetAddr1 (rtsHdr.GetAddr2 ());
597  Time duration = rtsHdr.GetDuration () - m_phy->GetSifs ()
598  - m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, m_phy->GetPhyBand ());
599  // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8 of 802.11-2016)
600  if (duration.IsStrictlyNegative ())
601  {
602  duration = Seconds (0);
603  }
604  cts.SetDuration (duration);
605 
606  Ptr<Packet> packet = Create<Packet> ();
607 
608  SnrTag tag;
609  tag.Set (rtsSnr);
610  packet->AddPacketTag (tag);
611 
612  // CTS should always use non-HT PPDU (HT PPDU cases not supported yet)
613  ForwardMpduDown (Create<WifiMacQueueItem> (packet, cts), ctsTxVector);
614 }
615 
616 void
617 FrameExchangeManager::SendCtsAfterRts (const WifiMacHeader& rtsHdr, WifiMode rtsTxMode, double rtsSnr)
618 {
619  NS_LOG_FUNCTION (this << rtsHdr << rtsTxMode << rtsSnr);
620 
621  WifiTxVector ctsTxVector = m_mac->GetWifiRemoteStationManager ()->GetCtsTxVector (rtsHdr.GetAddr2 (), rtsTxMode);
622  DoSendCtsAfterRts (rtsHdr, ctsTxVector, rtsSnr);
623 }
624 
625 Time
627  Time txDuration, Time response) const
628 {
629  NS_LOG_FUNCTION (this << ctsTxVector << txDuration << response);
630 
631  return m_phy->GetSifs () + txDuration + response;
632 }
633 
634 void
636 {
637  NS_LOG_FUNCTION (this << &txParams);
638 
639  WifiMacHeader cts;
641  cts.SetDsNotFrom ();
642  cts.SetDsNotTo ();
643  cts.SetNoMoreFragments ();
644  cts.SetNoRetry ();
645  cts.SetAddr1 (m_self);
646 
647  NS_ASSERT (txParams.m_protection && txParams.m_protection->method == WifiProtection::CTS_TO_SELF);
648  WifiCtsToSelfProtection* ctsToSelfProtection = static_cast<WifiCtsToSelfProtection*> (txParams.m_protection.get ());
649 
650  NS_ASSERT (txParams.m_txDuration != Time::Min ());
651  cts.SetDuration (GetCtsToSelfDurationId (ctsToSelfProtection->ctsTxVector, txParams.m_txDuration,
652  txParams.m_acknowledgment->acknowledgmentTime));
653 
654  ForwardMpduDown (Create<WifiMacQueueItem> (Create<Packet> (), cts), ctsToSelfProtection->ctsTxVector);
655 
656  Time ctsDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsToSelfProtection->ctsTxVector,
657  m_phy->GetPhyBand ());
659 }
660 
661 void
663  double dataSnr)
664 {
665  NS_LOG_FUNCTION (this << hdr << dataTxVector << dataSnr);
666 
667  WifiTxVector ackTxVector = m_mac->GetWifiRemoteStationManager ()->GetAckTxVector (hdr.GetAddr2 (), dataTxVector.GetMode ());
668  WifiMacHeader ack;
670  ack.SetDsNotFrom ();
671  ack.SetDsNotTo ();
672  ack.SetNoRetry ();
673  ack.SetNoMoreFragments ();
674  ack.SetAddr1 (hdr.GetAddr2 ());
675  // 802.11-2016, Section 9.2.5.7: Duration/ID is received duration value
676  // minus the time to transmit the Ack frame and its SIFS interval
677  Time duration = hdr.GetDuration () - m_phy->GetSifs ()
678  - m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, m_phy->GetPhyBand ());
679  // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8 of 802.11-2016)
680  if (duration.IsStrictlyNegative ())
681  {
682  duration = Seconds (0);
683  }
684  ack.SetDuration (duration);
685 
686  Ptr<Packet> packet = Create<Packet> ();
687 
688  SnrTag tag;
689  tag.Set (dataSnr);
690  packet->AddPacketTag (tag);
691 
692  ForwardMpduDown (Create<WifiMacQueueItem> (packet, ack), ackTxVector);
693 }
694 
697 {
698  NS_LOG_FUNCTION (this);
700 
701  WifiMacHeader& hdr = m_mpdu->GetHeader ();
702  hdr.SetFragmentNumber (hdr.GetFragmentNumber () + 1);
703 
704  uint32_t startOffset = hdr.GetFragmentNumber () * m_mpdu->GetPacketSize ();
705  uint32_t size = m_fragmentedPacket->GetSize () - startOffset;
706 
707  if (size > m_mpdu->GetPacketSize ())
708  {
709  // this is not the last fragment
710  size = m_mpdu->GetPacketSize ();
711  hdr.SetMoreFragments ();
712  }
713  else
714  {
715  hdr.SetNoMoreFragments ();
716  }
717 
718  return Create<WifiMacQueueItem> (m_fragmentedPacket->CreateFragment (startOffset, size), hdr);
719 }
720 
721 void
723 {
724  NS_LOG_FUNCTION (this);
725 
726  // Upon a transmission success, a non-QoS station transmits the next fragment,
727  // if any, or releases the channel, otherwise
728  if (m_moreFragments)
729  {
730  NS_LOG_DEBUG ("Schedule transmission of next fragment in a SIFS");
732  m_moreFragments = false;
733  }
734  else
735  {
737  m_dcf = 0;
738  }
739 }
740 
741 void
743 {
744  NS_LOG_FUNCTION (this);
745  // A non-QoS station always releases the channel upon a transmission failure
747  m_dcf = 0;
748 }
749 
750 void
752 {
753  NS_LOG_FUNCTION (this << *mpdu);
754 
755  m_mac->GetWifiRemoteStationManager ()->ReportDataFailed (mpdu);
756 
757  if (!m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (mpdu))
758  {
759  NS_LOG_DEBUG ("Missed Ack, discard MPDU");
760  NotifyPacketDiscarded (mpdu);
761  m_mac->GetWifiRemoteStationManager ()->ReportFinalDataFailed (mpdu);
762  m_mac->TxFailed (mpdu->GetHeader ());
763  m_dcf->ResetCw ();
764  }
765  else
766  {
767  NS_LOG_DEBUG ("Missed Ack, retransmit MPDU");
768  mpdu->GetHeader ().SetRetry ();
770  m_dcf->UpdateFailedCw ();
771  }
772 
773  m_mpdu = 0;
775 }
776 
777 void
779 {
780  NS_LOG_FUNCTION (this << *mpdu);
781 
782  // insert the MPDU in the DCF queue again
783  m_dcf->GetWifiMacQueue ()->PushFront (mpdu);
784 }
785 
786 void
788 {
789  NS_LOG_FUNCTION (this);
790 
791  m_mac->GetWifiRemoteStationManager ()->ReportRtsFailed (m_mpdu->GetHeader ());
792 
793  if (!m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (m_mpdu))
794  {
795  NS_LOG_DEBUG ("Missed CTS, discard MPDU");
796  // Dequeue the MPDU if it is stored in a queue
799  m_mac->GetWifiRemoteStationManager ()->ReportFinalRtsFailed (m_mpdu->GetHeader ());
800  m_dcf->ResetCw ();
801  }
802  else
803  {
804  NS_LOG_DEBUG ("Missed CTS, retransmit RTS");
806  m_dcf->UpdateFailedCw ();
807  }
808  m_mpdu = 0;
810 }
811 
812 void
814 {
815  NS_LOG_FUNCTION (this << *mpdu);
816 
817  // the MPDU should be still in the DCF queue, unless it expired.
818  // If the MPDU has never been transmitted, it will be assigned a sequence
819  // number again the next time we try to transmit it. Therefore, we need to
820  // make its sequence number available again
821  if (!mpdu->GetHeader ().IsRetry ())
822  {
823  m_txMiddle->SetSequenceNumberFor (&mpdu->GetHeader ());
824  }
825 }
826 
827 void
829 {
830  NS_LOG_DEBUG ("Switching channel. Cancelling MAC pending events");
831  m_mac->GetWifiRemoteStationManager ()->Reset ();
832  Reset ();
833 }
834 
835 void
837 {
838  NS_LOG_DEBUG ("Device in sleep mode. Cancelling MAC pending events");
839  Reset ();
840 }
841 
842 void
844 {
845  NS_LOG_DEBUG ("Device is switched off. Cancelling MAC pending events");
846  Reset ();
847 }
848 
849 void
851  WifiTxVector txVector, std::vector<bool> perMpduStatus)
852 {
853  NS_LOG_FUNCTION (this << psdu << rxSignalInfo << txVector << perMpduStatus.size ()
854  << std::all_of (perMpduStatus.begin(), perMpduStatus.end(), [](bool v) { return v; }));
855 
856  if (!perMpduStatus.empty ())
857  {
858  // for A-MPDUs, we get here only once
859  PreProcessFrame (psdu, txVector);
860  }
861 
862  // ignore unicast frames that are not addressed to us
863  Mac48Address addr1 = psdu->GetAddr1 ();
864  if (!addr1.IsGroup () && addr1 != m_self)
865  {
866  if (m_promisc && psdu->GetNMpdus () == 1 && psdu->GetHeader (0).IsData ())
867  {
868  m_rxMiddle->Receive (*psdu->begin ());
869  }
870  return;
871  }
872 
873  if (psdu->GetNMpdus () == 1)
874  {
875  // if perMpduStatus is not empty (i.e., this MPDU is not included in an A-MPDU)
876  // then it must contain a single value which must be true (i.e., the MPDU
877  // has been correctly received)
878  NS_ASSERT (perMpduStatus.empty () || (perMpduStatus.size () == 1 && perMpduStatus[0]));
879  // Ack and CTS do not carry Addr2
880  if (!psdu->GetHeader (0).IsAck () && !psdu->GetHeader (0).IsCts ())
881  {
882  m_mac->GetWifiRemoteStationManager ()->ReportRxOk (psdu->GetHeader (0).GetAddr2 (),
883  rxSignalInfo, txVector.GetMode ());
884  }
885  ReceiveMpdu (*(psdu->begin ()), rxSignalInfo, txVector, perMpduStatus.empty ());
886  }
887  else
888  {
889  EndReceiveAmpdu (psdu, rxSignalInfo.snr, txVector, perMpduStatus);
890  }
891 }
892 
893 void
895 {
896  NS_LOG_FUNCTION (this << psdu << txVector);
897 
898  UpdateNav (psdu, txVector);
899 }
900 
901 void
903 {
904  NS_LOG_FUNCTION (this << psdu << txVector);
905 
906  if (psdu->GetHeader (0).GetRawDuration () > 32767)
907  {
908  // When the contents of a received Duration/ID field, treated as an unsigned
909  // integer, are greater than 32 768, the contents are interpreted as appropriate
910  // for the frame type and subtype or ignored if the receiving MAC entity does
911  // not have a defined interpretation for that type and subtype (IEEE 802.11-2016
912  // sec. 10.27.3)
913  return;
914  }
915 
916  Time duration = psdu->GetDuration ();
917  NS_LOG_DEBUG ("Duration/ID=" << duration);
918 
919  if (psdu->GetAddr1 () == m_self)
920  {
921  // When the received frame’s RA is equal to the STA’s own MAC address, the STA
922  // shall not update its NAV (IEEE 802.11-2016, sec. 10.3.2.4)
923  return;
924  }
925 
926  // For all other received frames the STA shall update its NAV when the received
927  // Duration is greater than the STA’s current NAV value (IEEE 802.11-2016 sec. 10.3.2.4)
928  Time navEnd = Simulator::Now () + duration;
929  if (navEnd > m_navEnd)
930  {
931  m_navEnd = navEnd;
932  NS_LOG_DEBUG ("Updated NAV=" << m_navEnd);
933 
934  // A STA that used information from an RTS frame as the most recent basis to update
935  // its NAV setting is permitted to reset its NAV if no PHY-RXSTART.indication
936  // primitive is received from the PHY during a NAVTimeout period starting when the
937  // MAC receives a PHY-RXEND.indication primitive corresponding to the detection of
938  // the RTS frame. NAVTimeout period is equal to:
939  // (2 x aSIFSTime) + (CTS_Time) + aRxPHYStartDelay + (2 x aSlotTime)
940  // The “CTS_Time” shall be calculated using the length of the CTS frame and the data
941  // rate at which the RTS frame used for the most recent NAV update was received
942  // (IEEE 802.11-2016 sec. 10.3.2.4)
943  if (psdu->GetHeader (0).IsRts ())
944  {
945  Time navResetDelay = 2 * m_phy->GetSifs ()
947  m_phy->GetPhyBand ())
949  + 2 * m_phy->GetSlot ();
951  }
952  }
953 
954  m_channelAccessManager->NotifyNavStartNow (duration);
955 }
956 
957 void
959 {
961  m_channelAccessManager->NotifyNavResetNow (Seconds (0));
962 }
963 
964 void
966  const WifiTxVector& txVector, bool inAmpdu)
967 {
968  NS_LOG_FUNCTION (this << *mpdu << rxSignalInfo << txVector << inAmpdu);
969  // The received MPDU is either broadcast or addressed to this station
970  NS_ASSERT (mpdu->GetHeader ().GetAddr1 ().IsGroup ()
971  || mpdu->GetHeader ().GetAddr1 () == m_self);
972 
973  const WifiMacHeader& hdr = mpdu->GetHeader ();
974  double rxSnr = rxSignalInfo.snr;
975 
976  if (hdr.IsCtl ())
977  {
978  if (hdr.IsRts ())
979  {
980  NS_ABORT_MSG_IF (inAmpdu, "Received RTS as part of an A-MPDU");
981 
982  // A non-VHT STA that is addressed by an RTS frame behaves as follows:
983  // - If the NAV indicates idle, the STA shall respond with a CTS frame after a SIFS
984  // - Otherwise, the STA shall not respond with a CTS frame
985  // (IEEE 802.11-2016 sec. 10.3.2.7)
986  if (m_navEnd <= Simulator::Now ())
987  {
988  NS_LOG_DEBUG ("Received RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
990  this, hdr, txVector.GetMode (), rxSnr);
991  }
992  else
993  {
994  NS_LOG_DEBUG ("Received RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
995  }
996  }
997  else if (hdr.IsCts () && m_txTimer.IsRunning () && m_txTimer.GetReason () == WifiTxTimer::WAIT_CTS
998  && m_mpdu != 0)
999  {
1000  NS_ABORT_MSG_IF (inAmpdu, "Received CTS as part of an A-MPDU");
1001  NS_ASSERT (hdr.GetAddr1 () == m_self);
1002 
1003  Mac48Address sender = m_mpdu->GetHeader ().GetAddr1 ();
1004  NS_LOG_DEBUG ("Received CTS from=" << sender);
1005 
1006  SnrTag tag;
1007  mpdu->GetPacket ()->PeekPacketTag (tag);
1008  m_mac->GetWifiRemoteStationManager ()->ReportRxOk (sender, rxSignalInfo, txVector.GetMode ());
1009  m_mac->GetWifiRemoteStationManager ()->ReportRtsOk (m_mpdu->GetHeader (),
1010  rxSnr, txVector.GetMode (), tag.Get ());
1011 
1012  m_txTimer.Cancel ();
1013  m_channelAccessManager->NotifyCtsTimeoutResetNow ();
1015  }
1016  else if (hdr.IsAck () && m_mpdu != 0 && m_txTimer.IsRunning ()
1018  {
1019  NS_ASSERT (hdr.GetAddr1 () == m_self);
1020  SnrTag tag;
1021  mpdu->GetPacket ()->PeekPacketTag (tag);
1022  ReceivedNormalAck (m_mpdu, m_txParams.m_txVector, txVector, rxSignalInfo, tag.Get ());
1023  m_mpdu = 0;
1024  }
1025  }
1026  else if (hdr.IsMgt ())
1027  {
1028  NS_ABORT_MSG_IF (inAmpdu, "Received management frame as part of an A-MPDU");
1029 
1030  if (hdr.IsBeacon () || hdr.IsProbeResp ())
1031  {
1032  // Apply SNR tag for beacon quality measurements
1033  SnrTag tag;
1034  tag.Set (rxSnr);
1035  Ptr<Packet> packet = mpdu->GetPacket ()->Copy ();
1036  packet->AddPacketTag (tag);
1037  mpdu = Create<WifiMacQueueItem> (packet, hdr);
1038  }
1039 
1040  if (hdr.GetAddr1 () == m_self)
1041  {
1042  NS_LOG_DEBUG ("Received " << hdr.GetTypeString () << " from=" << hdr.GetAddr2 () << ", schedule ACK");
1044  this, hdr, txVector, rxSnr);
1045  }
1046 
1047  m_rxMiddle->Receive (mpdu);
1048  }
1049  else if (hdr.IsData () && !hdr.IsQosData ())
1050  {
1051  if (hdr.GetAddr1 () == m_self)
1052  {
1053  NS_LOG_DEBUG ("Received " << hdr.GetTypeString () << " from=" << hdr.GetAddr2 () << ", schedule ACK");
1055  this, hdr, txVector, rxSnr);
1056  }
1057 
1058  m_rxMiddle->Receive (mpdu);
1059  }
1060 }
1061 
1062 void
1064  const WifiTxVector& ackTxVector, RxSignalInfo rxSignalInfo,
1065  double snr)
1066 {
1067  Mac48Address sender = mpdu->GetHeader ().GetAddr1 ();
1068  NS_LOG_DEBUG ("Received ACK from=" << sender);
1069 
1070  NotifyReceivedNormalAck (mpdu);
1071 
1072  // When fragmentation is used, only update manager when the last fragment is acknowledged
1073  if (!mpdu->GetHeader ().IsMoreFragments ())
1074  {
1075  m_mac->GetWifiRemoteStationManager ()->ReportRxOk (sender, rxSignalInfo, ackTxVector.GetMode ());
1076  m_mac->GetWifiRemoteStationManager ()->ReportDataOk (mpdu, rxSignalInfo.snr, ackTxVector.GetMode (), snr, txVector);
1077  }
1078  // cancel the timer
1079  m_txTimer.Cancel ();
1080  m_channelAccessManager->NotifyAckTimeoutResetNow ();
1081 
1082  // The CW shall be reset to aCWmin after every successful attempt to transmit
1083  // a frame containing all or part of an MSDU or MMPDU (sec. 10.3.3 of 802.11-2016)
1084  m_dcf->ResetCw ();
1085 
1086  if (mpdu->GetHeader ().IsMoreFragments ())
1087  {
1088  // enqueue the next fragment
1090  m_dcf->GetWifiMacQueue ()->PushFront (next);
1091  m_moreFragments = true;
1092  }
1093 
1095 }
1096 
1097 void
1099 {
1100  NS_LOG_FUNCTION (this << *mpdu);
1101 
1102  // inform the MAC that the transmission was successful
1103  m_mac->TxOk (mpdu->GetHeader ());
1104 }
1105 
1106 void
1108  const WifiTxVector& txVector, const std::vector<bool>& perMpduStatus)
1109 {
1110  NS_ASSERT_MSG (false, "A non-QoS station should not receive an A-MPDU");
1111 }
1112 
1113 } //namespace ns3
void NormalAckTimeout(Ptr< WifiMacQueueItem > mpdu)
Called when the Ack timeout expires.
void Set(double snr)
Set the SNR to the given value.
Definition: snr-tag.cc:83
bool IsRetry(void) const
Return if the Retry bit is set.
void SetRetry(void)
Set the Retry bit in the Frame Control field.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:429
void SetMoreFragments(void)
Set the More Fragment bit in the Frame Control field.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
virtual void ReceivedNormalAck(Ptr< WifiMacQueueItem > mpdu, const WifiTxVector &txVector, const WifiTxVector &ackTxVector, RxSignalInfo rxSignalInfo, double snr)
Perform the actions needed when a Normal Ack is received.
bool m_moreFragments
true if a fragment has to be sent after a SIFS
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
microsecond
Definition: nstime.h:117
#define PSDU_DURATION_SAFEGUARD
virtual void DequeueMpdu(Ptr< WifiMacQueueItem > mpdu)
Dequeue the given MPDU from the queue in which it is stored.
void SendCtsToSelf(const WifiTxParameters &txParams)
Send CTS for a CTS-to-self mechanism.
WifiTxTimer m_txTimer
the timer set upon frame transmission
virtual void SetProtectionManager(Ptr< WifiProtectionManager > protectionManager)
Set the Protection Manager to use.
bool IsPromisc(void) const
Check if the device is operating in promiscuous mode.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SendMpduWithProtection(Ptr< WifiMacQueueItem > mpdu, WifiTxParameters &txParams)
Send an MPDU with the given TX parameters (with the specified protection).
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
virtual void SetAddress(Mac48Address address)
Set the MAC address.
Ptr< WifiProtectionManager > GetProtectionManager(void) const
Get the Protection Manager used by this node.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
Ptr< WifiPhy > m_phy
the PHY layer on this station
void SetDuration(Time duration)
Set the Duration/ID field with the given duration (Time object).
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:274
bool IsCtl(void) const
Return true if the Type is Control.
#define min(a, b)
Definition: 80211b.c:42
Ptr< Packet > m_fragmentedPacket
the MSDU being fragmented
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1305
std::unique_ptr< WifiProtection > m_protection
protection method
uint32_t GetRtsSize(void)
Return the total RTS size (including FCS trailer).
Definition: wifi-utils.cc:192
void SetPromisc(void)
Enable promiscuous mode.
uint32_t GetSize(void) const
Return the size of the packet stored by this item, including header size and trailer size...
uint32_t GetSize(void) const
Return the size of the WifiMacHeader in octets.
void Clear(void)
Reset the TX parameters.
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
Time acknowledgmentTime
time required by the acknowledgment method
WifiAcknowledgment is an abstract base struct.
Ptr< WifiMacQueueItem > m_mpdu
the MPDU being transmitted
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:227
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
virtual void PreProcessFrame(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Perform actions that are possibly needed when receiving any frame, independently of whether the frame...
Time GetTimeStamp(void) const
Get the timestamp included in this item.
Information needed to remove an MSDU from the queue.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ConstIterator it
iterator pointing to the MSDU in the queue
virtual void ForwardMpduDown(Ptr< WifiMacQueueItem > mpdu, WifiTxVector &txVector)
Forward an MPDU down to the PHY layer.
WifiTxVector ackTxVector
Ack TXVECTOR.
WifiTxVector ctsTxVector
CTS TXVECTOR.
virtual void CalculateProtectionTime(WifiProtection *protection) const
Calculate the time required to protect a frame according to the given protection method.
bool m_promisc
Flag if the device is operating in promiscuous mode.
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
uint32_t GetAckSize(void)
Return the total Ack size (including FCS trailer).
Definition: wifi-utils.cc:164
virtual void CtsTimeout(void)
Called when the CTS timeout expires.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Time m_txDuration
TX duration of the frame.
ns3::Time timeout
void NotifySwitchingStartNow(Time duration)
Ptr< ChannelAccessManager > m_channelAccessManager
the channel access manager
Callback< R, Ts... > MakeNullCallback(void)
Definition: callback.h:1682
virtual void DoDispose()
Destructor implementation.
Ptr< WifiMacQueueItem > Dequeue(void)
Dequeue the packet in the front of the queue.
virtual void TransmissionFailed(void)
Take necessary actions upon a transmission failure.
WifiTxVector rtsTxVector
RTS TXVECTOR.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:68
const Method method
acknowledgment method
virtual void CalculateAcknowledgmentTime(WifiAcknowledgment *acknowledgment) const
Calculate the time required to acknowledge a frame according to the given acknowledgment method...
virtual void ResetPhy(void)
Remove WifiPhy associated with this MacLow.
Ptr< WifiAckManager > GetAckManager(void) const
Get the Acknowledgment Manager used by this node.
double Get(void) const
Return the SNR value.
Definition: snr-tag.cc:89
Ptr< RegularWifiMac > m_mac
the MAC layer on this station
virtual void SetMacRxMiddle(const Ptr< MacRxMiddle > rxMiddle)
Set the MAC RX Middle to use.
phy
Definition: third.py:93
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode...
Ptr< WifiMacQueueItem > GetFirstFragmentIfNeeded(Ptr< WifiMacQueueItem > mpdu)
Fragment the given MPDU if needed.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1846
const PsduInfoMap & GetPsduInfoMap(void) const
Get a const reference to the map containing information about PSDUs.
void UpdateFailedCw(void)
Update the value of the CW variable to take into account a transmission failure.
Definition: txop.cc:215
virtual void SetAckManager(Ptr< WifiAckManager > ackManager)
Set the Acknowledgment Manager to use.
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:66
Mac48Address m_bssid
BSSID address (Mac48Address)
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
virtual Time GetFrameDurationId(const WifiMacHeader &header, uint32_t size, const WifiTxParameters &txParams, Ptr< Packet > fragmentedPacket) const
Compute how to set the Duration/ID field of a frame being transmitted with the given TX parameters...
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void Receive(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > perMpduStatus)
This method is intended to be called by the PHY layer every time an MPDU is received and also when th...
void Set(Reason reason, const Time &delay, MEM mem_ptr, OBJ obj, Args... args)
This method is called when a frame soliciting a response is transmitted.
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
Reason GetReason(void) const
Get the reason why the timer was started.
virtual void UpdateNav(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Update the NAV, if needed, based on the Duration/ID of the given psdu.
virtual void SetMacTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set the MAC TX Middle to use.
void NotifyOffNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
EventId m_navResetEvent
the event to reset the NAV after an RTS
mac
Definition: third.py:99
virtual void SetChannelAccessManager(const Ptr< ChannelAccessManager > channelAccessManager)
Set the channel access manager to use.
virtual void NotifyChannelReleased(void)
Called by the FrameExchangeManager to notify the completion of the transmissions. ...
Definition: txop.cc:369
virtual bool StartTransmission(Ptr< Txop > dcf)
Request the FrameExchangeManager to start a frame exchange sequence.
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
Definition: object-base.cc:319
virtual Time GetRtsDurationId(const WifiTxVector &rtsTxVector, Time txDuration, Time response) const
Compute how to set the Duration/ID field of an RTS frame to send to protect a frame transmitted with ...
Time GetDuration(void) const
Get the duration from the Duration/ID field, which is common to all the MPDUs.
Definition: wifi-psdu.cc:141
Ptr< WifiAckManager > m_ackManager
Acknowledgment manager.
Time protectionTime
time required by the protection method
const WifiMacHeader & GetHeader(std::size_t i) const
Get the header of the i-th MPDU.
Definition: wifi-psdu.cc:266
virtual void NotifyPacketDiscarded(Ptr< const WifiMacQueueItem > mpdu)
Pass the packet included in the given MPDU to the packet dropped callback.
Mac48Address m_self
the MAC address of this device
WifiProtection is an abstract base struct.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
Ptr< const Packet > GetPacket(void) const
Get the packet stored in this item.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
bool IsFragment(void) const
Return true if this item contains an MSDU fragment, false otherwise.
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SendRts(const WifiTxParameters &txParams)
Send RTS to begin RTS-CTS-Data-Ack transaction.
bool IsData(void) const
Return true if the Type is DATA.
address
Definition: first.py:44
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).
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
void Cancel(void)
Cancel the timer.
an EUI-48 address
Definition: mac48-address.h:43
bool IsRunning(void) const
Return true if the timer is running.
static void SetQosAckPolicy(Ptr< WifiMacQueueItem > item, const WifiAcknowledgment *acknowledgment)
Set the QoS Ack policy for the given MPDU, which must be a QoS data frame.
WifiRtsCtsProtection specifies that RTS/CTS protection method is used.
void SendCtsAfterRts(const WifiMacHeader &rtsHdr, WifiMode rtsTxMode, double rtsSnr)
Send CTS after receiving RTS.
bool IsGroup(void) const
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
virtual void SetWifiMac(const Ptr< RegularWifiMac > mac)
Set the MAC layer to use.
WifiTxParameters m_txParams
the TX parameters for the current frame
static TypeId GetTypeId(void)
Get the type ID.
void SendNormalAck(const WifiMacHeader &hdr, const WifiTxVector &dataTxVector, double dataSnr)
Send Normal Ack.
virtual Time GetTxDuration(uint32_t ppduPayloadSize, Mac48Address receiver, const WifiTxParameters &txParams) const
Get the updated TX duration of the frame associated with the given TX parameters if the size of the P...
void AddMpdu(Ptr< const WifiMacQueueItem > mpdu)
Record that an MPDU is being added to the current frame.
bool IsMoreFragments(void) const
Return if the More Fragment bit is set.
virtual void NotifyChannelAccessed(Time txopDuration=Seconds(0))
Called by the FrameExchangeManager to notify that channel access has been granted for the given amoun...
Definition: txop.cc:362
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
uint32_t GetCtsSize(void)
Return the total CTS size (including FCS trailer).
Definition: wifi-utils.cc:200
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
uint16_t GetRawDuration(void) const
Return the raw duration from the Duration/ID field.
Ptr< WifiProtectionManager > m_protectionManager
Protection manager.
void Reschedule(const Time &delay)
Reschedule the timer to time out the given amount of time from the moment this function is called...
void NotifySleepNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:606
WifiMacQueue * queue
pointer to the queue where the MSDU is enqueued
bool IsMgt(void) const
Return true if the Type is Management.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:1001
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
virtual void Reset(void)
Reset this frame exchange manager.
bool IsQueued(void) const
Return true if this item is stored in some queue, false otherwise.
double snr
SNR in linear scale.
Definition: phy-entity.h:68
bool PushFront(Ptr< WifiMacQueueItem > item)
Enqueue the given Wifi MAC queue item at the front of the queue.
virtual void SetBssid(Mac48Address bssid)
Set the Basic Service Set Identification.
bool IsStrictlyNegative(void) const
Exactly equivalent to t < 0.
Definition: nstime.h:325
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
WifiTxVector ctsTxVector
CTS TXVECTOR.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
Definition: txop.cc:170
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism...
Ptr< Txop > m_dcf
the DCF/EDCAF that gained channel access
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
Time GetSlot(void) const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:1013
WifiCtsToSelfProtection specifies that CTS-to-self protection method is used.
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1834
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Definition: wifi-phy.cc:1986
virtual Time GetCtsToSelfDurationId(const WifiTxVector &ctsTxVector, Time txDuration, Time response) const
Compute how to set the Duration/ID field of a CTS-to-self frame to send to protect a frame transmitte...
const Method method
protection method
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
bool IsRts(void) const
Return true if the header is a RTS header.
Time m_navEnd
NAV expiration time.
virtual void ReceiveMpdu(Ptr< WifiMacQueueItem > mpdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, bool inAmpdu)
This method handles the reception of an MPDU (possibly included in an A-MPDU)
virtual void RetransmitMpduAfterMissedAck(Ptr< WifiMacQueueItem > mpdu) const
Retransmit an MPDU that was not acknowledged.
virtual void TransmissionSucceeded(void)
Take necessary actions upon a transmission success.
void RxStartIndication(WifiTxVector txVector, Time psduDuration)
void DoSendCtsAfterRts(const WifiMacHeader &rtsHdr, WifiTxVector &ctsTxVector, double rtsSnr)
Send CTS after receiving RTS.
Ptr< WifiMacQueueItem > GetNextFragment(void)
Get the next fragment of the current MSDU.
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
virtual void NotifyReceivedNormalAck(Ptr< WifiMacQueueItem > mpdu)
Notify other components that an MPDU was acknowledged.
A base class which provides memory management and object aggregation.
Definition: object.h:87
void UpdateTxDuration(Mac48Address receiver, WifiTxParameters &txParams) const
Update the TX duration field of the given TX parameters after that the PSDU addressed to the given re...
Mac48Address GetAddr1(void) const
Get the Receiver Address (RA), which is common to all the MPDUs.
Definition: wifi-psdu.cc:111
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:978
uint32_t GetPacketSize(void) const
Return the size in bytes of the packet or control header or management header stored by this item...
Ptr< MacRxMiddle > m_rxMiddle
the MAC RX Middle on this station
WifiNormalAck specifies that acknowledgment via Normal Ack is required.
uint8_t GetFragmentNumber(void) const
Return the fragment number of the header.
virtual void SetWifiPhy(const Ptr< WifiPhy > phy)
Set the PHY layer to use.
void SetFragmentNumber(uint8_t frag)
Set the fragment number of the header.
virtual void EndReceiveAmpdu(Ptr< const WifiPsdu > psdu, double rxSnr, const WifiTxVector &txVector, const std::vector< bool > &perMpduStatus)
This method is called when the reception of an A-MPDU including multiple MPDUs is completed...
Ptr< MacTxMiddle > m_txMiddle
the MAC TX Middle on this station
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
Definition: txop.cc:207
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
const std::list< QueueIteratorPair > & GetQueueIteratorPairs(void) const
Get a const reference to the list of iterators pointing to the positions of the items in the queue...
void SendMpdu(void)
Send the current MPDU, which can be acknowledged by a Normal Ack.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
Introspection did not find any typical Config paths.
Definition: snr-tag.h:34
Implements the IEEE 802.11 MAC header.
virtual void NavResetTimeout(void)
Reset the NAV upon expiration of the NAV reset timer.
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.
virtual void RetransmitMpduAfterMissedCts(Ptr< WifiMacQueueItem > mpdu) const
Retransmit an MPDU that was not sent because a CTS was not received.