A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
qos-frame-exchange-manager.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
10
11#include "ap-wifi-mac.h"
12#include "wifi-mac-queue.h"
13#include "wifi-mac-trailer.h"
14
15#include "ns3/abort.h"
16#include "ns3/log.h"
17
18#undef NS_LOG_APPEND_CONTEXT
19#define NS_LOG_APPEND_CONTEXT WIFI_FEM_NS_LOG_APPEND_CONTEXT
20
21namespace ns3
22{
23
24NS_LOG_COMPONENT_DEFINE("QosFrameExchangeManager");
25
26NS_OBJECT_ENSURE_REGISTERED(QosFrameExchangeManager);
27
28TypeId
30{
31 static TypeId tid =
32 TypeId("ns3::QosFrameExchangeManager")
34 .AddConstructor<QosFrameExchangeManager>()
35 .SetGroupName("Wifi")
36 .AddAttribute("PifsRecovery",
37 "Perform a PIFS recovery as a response to transmission failure "
38 "within a TXOP",
39 BooleanValue(true),
42 .AddAttribute("SetQueueSize",
43 "Whether to set the Queue Size subfield of the QoS Control field "
44 "of QoS data frames sent by non-AP stations",
45 BooleanValue(false),
48 return tid;
49}
50
52 : m_initialFrame(false)
53{
54 NS_LOG_FUNCTION(this);
55}
56
61
62void
71
72bool
74{
75 NS_LOG_FUNCTION(this);
77
78 WifiMacHeader cfEnd;
80 cfEnd.SetDsNotFrom();
81 cfEnd.SetDsNotTo();
82 cfEnd.SetNoRetry();
83 cfEnd.SetNoMoreFragments();
84 cfEnd.SetDuration(Seconds(0));
86 cfEnd.SetAddr2(m_self);
87
88 WifiTxVector cfEndTxVector =
89 GetWifiRemoteStationManager()->GetRtsTxVector(cfEnd.GetAddr1(), m_allowedWidth);
90
91 auto mpdu = Create<WifiMpdu>(Create<Packet>(), cfEnd);
92 auto txDuration =
93 WifiPhy::CalculateTxDuration(mpdu->GetSize(), cfEndTxVector, m_phy->GetPhyBand());
94
95 // Send the CF-End frame if the remaining TXNAV is long enough to transmit this frame
96 if (m_txNav > Simulator::Now() + txDuration)
97 {
98 NS_LOG_DEBUG("Send CF-End frame");
99 ForwardMpduDown(mpdu, cfEndTxVector);
100 Simulator::Schedule(txDuration,
102 this,
103 m_edca);
104 return true;
105 }
106
108 m_edca = nullptr;
109 return false;
110}
111
112void
114{
115 NS_LOG_FUNCTION(this << forceCurrentCw);
118
119 // Release the channel if it has not been idle for the last PIFS interval
120 m_allowedWidth = std::min(
122 m_channelAccessManager->GetLargestIdlePrimaryChannel(m_phy->GetPifs(), Simulator::Now()));
123
124 if (m_allowedWidth == MHz_u{0})
125 {
126 // PIFS recovery failed, TXOP is terminated
128 if (!forceCurrentCw)
129 {
131 }
132 m_edca = nullptr;
133 }
134 else
135 {
136 // the txopDuration parameter is unused because we are not starting a new TXOP
138 }
139}
140
141void
143{
144 NS_LOG_FUNCTION(this);
147
148 NS_LOG_DEBUG("Cancel PIFS recovery being attempted by EDCAF " << m_edca);
151}
152
153bool
155{
156 NS_LOG_FUNCTION(this << edca << allowedWidth);
157
159 {
160 // Another AC (having AIFS=1 or lower, if the user changed the default settings)
161 // gained channel access while performing PIFS recovery. Abort PIFS recovery
163 }
164
165 // TODO This will become an assert once no Txop is installed on a QoS station
166 if (!edca->IsQosTxop())
167 {
168 m_edca = nullptr;
169 return FrameExchangeManager::StartTransmission(edca, allowedWidth);
170 }
171
172 m_allowedWidth = allowedWidth;
173 auto qosTxop = StaticCast<QosTxop>(edca);
174 return StartTransmission(qosTxop, qosTxop->GetTxopLimit(m_linkId));
175}
176
177bool
179{
180 NS_LOG_FUNCTION(this << edca << txopDuration);
181
183 {
184 // Another AC (having AIFS=1 or lower, if the user changed the default settings)
185 // gained channel access while performing PIFS recovery. Abort PIFS recovery
187 }
188
189 if (m_txTimer.IsRunning())
190 {
192 }
193 m_dcf = edca;
194 m_edca = edca;
195
196 // We check if this EDCAF invoked the backoff procedure (without terminating
197 // the TXOP) because the transmission of a non-initial frame of a TXOP failed
198 bool backingOff = (m_edcaBackingOff == m_edca);
199
200 if (backingOff)
201 {
206
207 // clear the member variable
208 m_edcaBackingOff = nullptr;
209 }
210
212 {
213 // TXOP limit is not null. We have to check if this EDCAF is starting a
214 // new TXOP. This includes the case when the transmission of a non-initial
215 // frame of a TXOP failed and backoff was invoked without terminating the
216 // TXOP. In such a case, we assume that a new TXOP is being started if it
217 // elapsed more than TXOPlimit since the start of the paused TXOP. Note
218 // that GetRemainingTxop returns 0 iff Now - TXOPstart >= TXOPlimit
220 (backingOff && m_edca->GetRemainingTxop(m_linkId).IsZero()))
221 {
222 // starting a new TXOP
223 m_edca->NotifyChannelAccessed(m_linkId, txopDuration);
224
225 if (StartFrameExchange(m_edca, txopDuration, true))
226 {
227 m_initialFrame = true;
228 return true;
229 }
230
231 // TXOP not even started, return false
232 NS_LOG_DEBUG("No frame transmitted");
234 m_edca = nullptr;
235 return false;
236 }
237
238 // We are continuing a TXOP, check if we can transmit another frame
240
242 {
243 NS_LOG_DEBUG("Not enough remaining TXOP time");
244 return SendCfEndIfNeeded();
245 }
246
247 return true;
248 }
249
250 // we get here if TXOP limit is null
251 m_initialFrame = true;
252
253 if (StartFrameExchange(m_edca, Time::Min(), true))
254 {
256 return true;
257 }
258
259 NS_LOG_DEBUG("No frame transmitted");
261 m_edca = nullptr;
262 return false;
263}
264
265bool
267 Time availableTime,
268 bool initialFrame)
269{
270 NS_LOG_FUNCTION(this << edca << availableTime << initialFrame);
271
272 Ptr<WifiMpdu> mpdu = edca->PeekNextMpdu(m_linkId);
273
274 // Even though channel access is requested when the queue is not empty, at
275 // the time channel access is granted the lifetime of the packet might be
276 // expired and the queue might be empty.
277 if (!mpdu)
278 {
279 NS_LOG_DEBUG("Queue empty");
280 return false;
281 }
282
283 mpdu = CreateAliasIfNeeded(mpdu);
284 WifiTxParameters txParams;
285 txParams.m_txVector =
286 GetWifiRemoteStationManager()->GetDataTxVector(mpdu->GetHeader(), m_allowedWidth);
287
288 Ptr<WifiMpdu> item = edca->GetNextMpdu(m_linkId, mpdu, txParams, availableTime, initialFrame);
289
290 if (!item)
291 {
292 NS_LOG_DEBUG("Not enough time to transmit a frame");
293 return false;
294 }
295
296 NS_ASSERT_MSG(!item->GetHeader().IsQosData() || !item->GetHeader().IsQosAmsdu(),
297 "We should not get an A-MSDU here");
298
299 // check if the MSDU needs to be fragmented
300 item = GetFirstFragmentIfNeeded(item);
301
302 // update the protection method if the frame was fragmented
303 if (item->IsFragment() && item->GetSize() != mpdu->GetSize())
304 {
305 WifiTxParameters fragmentTxParams;
306 fragmentTxParams.m_txVector = txParams.m_txVector;
307 fragmentTxParams.AddMpdu(item);
308 UpdateTxDuration(item->GetHeader().GetAddr1(), fragmentTxParams);
309 txParams.m_protection = GetProtectionManager()->TryAddMpdu(item, fragmentTxParams);
310 NS_ASSERT(txParams.m_protection);
311 }
312
313 SendMpduWithProtection(item, txParams);
314
315 return true;
316}
317
320{
321 return mpdu;
322}
323
324bool
326 WifiTxParameters& txParams,
327 Time availableTime) const
328{
329 NS_ASSERT(mpdu);
330 NS_LOG_FUNCTION(this << *mpdu << &txParams << availableTime);
331
332 // tentatively add the given MPDU
333 auto prevTxDuration = txParams.m_txDuration;
334 txParams.AddMpdu(mpdu);
335 UpdateTxDuration(mpdu->GetHeader().GetAddr1(), txParams);
336
337 // check if adding the given MPDU requires a different protection method
338 std::optional<Time> protectionTime; // uninitialized
339 if (txParams.m_protection)
340 {
341 protectionTime = txParams.m_protection->protectionTime;
342 }
343
344 std::unique_ptr<WifiProtection> protection;
345 protection = GetProtectionManager()->TryAddMpdu(mpdu, txParams);
346 bool protectionSwapped = false;
347
348 if (protection)
349 {
350 // the protection method has changed, calculate the new protection time
351 CalculateProtectionTime(protection.get());
352 protectionTime = protection->protectionTime;
353 // swap unique pointers, so that the txParams that is passed to the next
354 // call to IsWithinLimitsIfAddMpdu is the most updated one
355 txParams.m_protection.swap(protection);
356 protectionSwapped = true;
357 }
358 NS_ASSERT(protectionTime.has_value());
359 NS_LOG_DEBUG("protection time=" << *protectionTime);
360
361 // check if adding the given MPDU requires a different acknowledgment method
362 std::optional<Time> acknowledgmentTime; // uninitialized
363 if (txParams.m_acknowledgment)
364 {
365 acknowledgmentTime = txParams.m_acknowledgment->acknowledgmentTime;
366 }
367
368 std::unique_ptr<WifiAcknowledgment> acknowledgment;
369 acknowledgment = GetAckManager()->TryAddMpdu(mpdu, txParams);
370 bool acknowledgmentSwapped = false;
371
372 if (acknowledgment)
373 {
374 // the acknowledgment method has changed, calculate the new acknowledgment time
375 CalculateAcknowledgmentTime(acknowledgment.get());
376 acknowledgmentTime = acknowledgment->acknowledgmentTime;
377 // swap unique pointers, so that the txParams that is passed to the next
378 // call to IsWithinLimitsIfAddMpdu is the most updated one
379 txParams.m_acknowledgment.swap(acknowledgment);
380 acknowledgmentSwapped = true;
381 }
382 NS_ASSERT(acknowledgmentTime.has_value());
383 NS_LOG_DEBUG("acknowledgment time=" << *acknowledgmentTime);
384
385 Time ppduDurationLimit = Time::Min();
386 if (availableTime != Time::Min())
387 {
388 ppduDurationLimit = availableTime - *protectionTime - *acknowledgmentTime;
389 }
390
391 if (!IsWithinLimitsIfAddMpdu(mpdu, txParams, ppduDurationLimit))
392 {
393 // adding MPDU failed, undo the addition of the MPDU and restore protection and
394 // acknowledgment methods if they were swapped
395 txParams.UndoAddMpdu();
396 txParams.m_txDuration = prevTxDuration;
397 if (protectionSwapped)
398 {
399 txParams.m_protection.swap(protection);
400 }
401 if (acknowledgmentSwapped)
402 {
403 txParams.m_acknowledgment.swap(acknowledgment);
404 }
405 return false;
406 }
407
408 return true;
409}
410
411bool
413 const WifiTxParameters& txParams,
414 Time ppduDurationLimit) const
415{
416 NS_ASSERT(mpdu);
417 NS_LOG_FUNCTION(this << *mpdu << &txParams << ppduDurationLimit);
418
419 // A QoS station only has to check that the MPDU transmission time does not
420 // exceed the given limit
421 return IsWithinSizeAndTimeLimits(mpdu->GetSize(),
422 mpdu->GetHeader().GetAddr1(),
423 txParams,
424 ppduDurationLimit);
425}
426
427bool
429 Mac48Address receiver,
430 const WifiTxParameters& txParams,
431 Time ppduDurationLimit) const
432{
433 NS_LOG_FUNCTION(this << ppduPayloadSize << receiver << &txParams << ppduDurationLimit);
434
435 if (ppduDurationLimit != Time::Min() && ppduDurationLimit.IsNegative())
436 {
437 NS_LOG_DEBUG("ppduDurationLimit is null or negative, time limit is trivially exceeded");
438 return false;
439 }
440
441 if (ppduPayloadSize > WifiPhy::GetMaxPsduSize(txParams.m_txVector.GetModulationClass()))
442 {
443 NS_LOG_DEBUG("the frame exceeds the max PSDU size");
444 return false;
445 }
446
447 // Get the maximum PPDU Duration based on the preamble type
448 Time maxPpduDuration = GetPpduMaxTime(txParams.m_txVector.GetPreambleType());
449
450 NS_ASSERT_MSG(txParams.m_txDuration, "TX duration not yet computed");
451 auto txTime = txParams.m_txDuration.value();
452 NS_LOG_DEBUG("PPDU duration: " << txTime.As(Time::MS));
453
454 if ((ppduDurationLimit.IsStrictlyPositive() && txTime > ppduDurationLimit) ||
455 (maxPpduDuration.IsStrictlyPositive() && txTime > maxPpduDuration))
456 {
458 "the frame does not meet the constraint on max PPDU duration or PPDU duration limit");
459 return false;
460 }
461
462 return true;
463}
464
465Time
467 uint32_t size,
468 const WifiTxParameters& txParams,
469 Ptr<Packet> fragmentedPacket) const
470{
471 NS_LOG_FUNCTION(this << header << size << &txParams << fragmentedPacket);
472
473 // TODO This will be removed once no Txop is installed on a QoS station
474 if (!m_edca)
475 {
476 return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
477 }
478
480 {
481 return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
482 }
483
484 NS_ASSERT(txParams.m_acknowledgment &&
485 txParams.m_acknowledgment->acknowledgmentTime.has_value());
486
487 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
488 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
489 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
490 // of 802.11-2016)
491 return std::max(
494 *txParams.m_acknowledgment->acknowledgmentTime);
495}
496
497Time
499 Time txDuration,
500 Time response) const
501{
502 NS_LOG_FUNCTION(this << rtsTxVector << txDuration << response);
503
504 // TODO This will be removed once no Txop is installed on a QoS station
505 if (!m_edca)
506 {
507 return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
508 }
509
511 {
512 return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
513 }
514
515 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
516 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
517 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
518 // of 802.11-2016)
519 return std::max(
522 Seconds(0));
523}
524
525Time
527 Time txDuration,
528 Time response) const
529{
530 NS_LOG_FUNCTION(this << ctsTxVector << txDuration << response);
531
532 // TODO This will be removed once no Txop is installed on a QoS station
533 if (!m_edca)
534 {
535 return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
536 }
537
539 {
540 return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
541 }
542
543 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
544 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
545 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
546 // of 802.11-2016)
547 return std::max(
550 Seconds(0));
551}
552
553void
555{
556 NS_LOG_FUNCTION(this << *mpdu << txVector);
557
558 WifiMacHeader& hdr = mpdu->GetHeader();
559
560 if (hdr.IsQosData() && m_mac->GetTypeOfStation() == STA &&
561 (m_setQosQueueSize || hdr.IsQosEosp()))
562 {
563 uint8_t tid = hdr.GetQosTid();
564 hdr.SetQosEosp();
565 hdr.SetQosQueueSize(
566 m_mac->GetQosTxop(tid)->GetQosQueueSize(tid,
567 mpdu->GetOriginal()->GetHeader().GetAddr1()));
568 }
570}
571
572void
574{
575 NS_LOG_DEBUG(this);
576
577 // TODO This will be removed once no Txop is installed on a QoS station
578 if (!m_edca)
579 {
581 return;
582 }
583
586 {
587 NS_LOG_DEBUG("Schedule another transmission in a SIFS");
590
591 // we are continuing a TXOP, hence the txopDuration parameter is unused
593
595 {
597 }
598 }
599 else
600 {
602 m_edca = nullptr;
603 }
604 m_initialFrame = false;
605 m_sentFrameTo.clear();
606}
607
608void
610{
611 NS_LOG_FUNCTION(this << forceCurrentCw);
612
613 // TODO This will be removed once no Txop is installed on a QoS station
614 if (!m_edca)
615 {
617 return;
618 }
619
620 if (m_initialFrame)
621 {
622 // The backoff procedure shall be invoked by an EDCAF when the transmission
623 // of an MPDU in the initial PPDU of a TXOP fails (Sec. 10.22.2.2 of 802.11-2016)
624 NS_LOG_DEBUG("TX of the initial frame of a TXOP failed: terminate TXOP");
625 if (!forceCurrentCw)
626 {
628 }
630 m_edca = nullptr;
631 }
632 else
633 {
634 // some STA(s) did not respond, they are no longer protected
635 for (const auto& address : m_txTimer.GetStasExpectedToRespond())
636 {
637 NS_LOG_DEBUG(address << " did not respond, hence it is no longer protected");
638 m_protectedStas.erase(address);
639 }
640
642 "Cannot transmit more than one frame if TXOP Limit is zero");
643
644 // A STA can perform a PIFS recovery or perform a backoff as a response to
645 // transmission failure within a TXOP. How it chooses between these two is
646 // implementation dependent. (Sec. 10.22.2.2 of 802.11-2016)
647 if (m_pifsRecovery)
648 {
649 // we can continue the TXOP if the carrier sense mechanism indicates that
650 // the medium is idle in a PIFS
651 NS_LOG_DEBUG("TX of a non-initial frame of a TXOP failed: perform PIFS recovery");
655 this,
656 forceCurrentCw);
657 }
658 else
659 {
660 // In order not to terminate (yet) the TXOP, we call the NotifyChannelReleased
661 // method of the Txop class, which only generates a new backoff value and
662 // requests channel access if needed,
663 NS_LOG_DEBUG("TX of a non-initial frame of a TXOP failed: invoke backoff");
664 m_edca->Txop::NotifyChannelReleased(m_linkId);
665 // CW and QSRC shall be updated in this case (see Section 10.23.2.2 of 802.11-2020)
666 if (!forceCurrentCw)
667 {
669 }
671 m_edca = nullptr;
672 }
673 }
674 m_initialFrame = false;
675 m_sentFrameTo.clear();
676 // reset TXNAV because transmission failed
678}
679
680void
682{
683 NS_LOG_FUNCTION(this << psdu << txVector);
684
685 // APs store buffer size report of associated stations
686 if (m_mac->GetTypeOfStation() == AP && psdu->GetAddr1() == m_self)
687 {
688 for (const auto& mpdu : *PeekPointer(psdu))
689 {
690 const WifiMacHeader& hdr = mpdu->GetHeader();
691
692 if (hdr.IsQosData() && hdr.IsQosEosp())
693 {
694 NS_LOG_DEBUG("Station " << hdr.GetAddr2() << " reported a buffer status of "
695 << +hdr.GetQosQueueSize()
696 << " for tid=" << +hdr.GetQosTid());
697 m_apMac->SetBufferStatus(hdr.GetQosTid(),
698 mpdu->GetOriginal()->GetHeader().GetAddr2(),
699 hdr.GetQosQueueSize());
700 }
701 }
702 }
703
704 // before updating the NAV, check if the NAV counted down to zero. In such a
705 // case, clear the saved TXOP holder address.
707
709}
710
711void
713{
714 NS_LOG_FUNCTION(this << psdu << txVector);
715
716 SetTxopHolder(psdu, txVector);
718}
719
720void
722{
723 NS_LOG_FUNCTION(this << psdu << txVector);
724 if (auto txopHolder = FindTxopHolder(psdu->GetHeader(0), txVector))
725 {
726 m_txopHolder = *txopHolder;
727 }
728}
729
730std::optional<Mac48Address>
732{
733 NS_LOG_FUNCTION(this << hdr << txVector);
734
735 // A STA shall save the TXOP holder address for the BSS in which it is associated.
736 // The TXOP holder address is the MAC address from the Address 2 field of the frame
737 // that initiated a frame exchange sequence, except if this is a CTS frame, in which
738 // case the TXOP holder address is the Address 1 field. (Sec. 10.23.2.4 of 802.11-2020)
739 if ((hdr.IsQosData() || hdr.IsMgt() || hdr.IsRts() || hdr.IsBlockAckReq()) &&
740 (hdr.GetAddr1() == m_bssid || hdr.GetAddr2() == m_bssid))
741 {
742 return hdr.GetAddr2();
743 }
744 if (hdr.IsCts() && hdr.GetAddr1() == m_bssid)
745 {
746 return hdr.GetAddr1();
747 }
748 return std::nullopt;
749}
750
751void
760
761void
763{
764 NS_LOG_FUNCTION(this << psdu << txVector);
765 if (psdu->GetHeader(0).IsCfEnd())
766 {
767 NS_LOG_DEBUG("Received CF-End, resetting NAV");
769 return;
770 }
771
772 FrameExchangeManager::UpdateNav(psdu, txVector);
773}
774
775void
782
783void
785 RxSignalInfo rxSignalInfo,
786 const WifiTxVector& txVector,
787 bool inAmpdu)
788{
789 NS_LOG_FUNCTION(this << *mpdu << rxSignalInfo << txVector << inAmpdu);
790
791 // The received MPDU is either broadcast or addressed to this station
792 NS_ASSERT(mpdu->GetHeader().GetAddr1().IsGroup() || mpdu->GetHeader().GetAddr1() == m_self);
793
794 double rxSnr = rxSignalInfo.snr;
795 const WifiMacHeader& hdr = mpdu->GetHeader();
796
797 if (hdr.IsRts())
798 {
799 NS_ABORT_MSG_IF(inAmpdu, "Received RTS as part of an A-MPDU");
800
801 // If a non-VHT STA receives an RTS frame with the RA address matching the
802 // MAC address of the STA and the MAC address in the TA field in the RTS
803 // frame matches the saved TXOP holder address, then the STA shall send the
804 // CTS frame after SIFS, without regard for, and without resetting, its NAV.
805 // (sec. 10.22.2.4 of 802.11-2016)
806 if (hdr.GetAddr2() == m_txopHolder || VirtualCsMediumIdle())
807 {
808 NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", schedule CTS");
811 this,
812 hdr,
813 txVector.GetMode(),
814 rxSnr);
815 }
816 else
817 {
818 NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", cannot schedule CTS");
819 }
820 return;
821 }
822
823 if (hdr.IsQosData())
824 {
826 {
827 NS_LOG_DEBUG("Received " << hdr.GetTypeString() << " from=" << hdr.GetAddr2()
828 << ", schedule ACK");
831 this,
832 hdr,
833 txVector,
834 rxSnr);
835 }
836
837 // Forward up the frame
838 m_rxMiddle->Receive(mpdu, m_linkId);
839
840 // the received data frame has been processed
841 return;
842 }
843
844 return FrameExchangeManager::ReceiveMpdu(mpdu, rxSignalInfo, txVector, inAmpdu);
845}
846
847} // namespace ns3
AttributeValue implementation for Boolean.
Definition boolean.h:26
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition event-id.cc:65
FrameExchangeManager is a base class handling the basic frame exchange sequences for non-QoS stations...
uint8_t m_linkId
the ID of the link this object is associated with
Ptr< WifiMac > m_mac
the MAC layer on this station
bool m_protectedIfResponded
whether a STA is assumed to be protected if replied to a frame requiring acknowledgment
virtual void UpdateNav(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Update the NAV, if needed, based on the Duration/ID of the given psdu.
void SendMpduWithProtection(Ptr< WifiMpdu > mpdu, WifiTxParameters &txParams)
Send an MPDU with the given TX parameters (with the specified protection).
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager() const
void UpdateTxDuration(Mac48Address receiver, WifiTxParameters &txParams) const
Update the TX duration field of the given TX parameters after that the PSDU addressed to the given re...
virtual void CalculateAcknowledgmentTime(WifiAcknowledgment *acknowledgment) const
Calculate the time required to acknowledge a frame according to the given acknowledgment method.
void SendNormalAck(const WifiMacHeader &hdr, const WifiTxVector &dataTxVector, double dataSnr)
Send Normal Ack.
Mac48Address m_self
the MAC address of this device
WifiTxTimer m_txTimer
the timer set upon frame transmission
virtual void SendCtsAfterRts(const WifiMacHeader &rtsHdr, WifiMode rtsTxMode, double rtsSnr)
Send CTS after receiving RTS.
std::set< Mac48Address > m_protectedStas
STAs that have replied to an RTS in this TXOP.
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 ...
virtual void ForwardMpduDown(Ptr< WifiMpdu > mpdu, WifiTxVector &txVector)
Forward an MPDU down to the PHY layer.
virtual bool VirtualCsMediumIdle() const
virtual void NotifyChannelReleased(Ptr< Txop > txop)
Notify the given Txop that channel has been released.
virtual void CalculateProtectionTime(WifiProtection *protection) const
Calculate the time required to protect a frame according to the given protection method.
Ptr< WifiAckManager > GetAckManager() const
Get the Acknowledgment Manager used by this node.
virtual void NavResetTimeout()
Reset the NAV upon expiration of the NAV reset timer.
Ptr< WifiProtectionManager > GetProtectionManager() const
Get the Protection Manager used by this node.
Ptr< MacRxMiddle > m_rxMiddle
the MAC RX Middle on this station
virtual void TransmissionSucceeded()
Take necessary actions upon a transmission success.
Ptr< Txop > m_dcf
the DCF/EDCAF that gained channel access
EventId m_sendCtsEvent
the event to send a CTS after an (MU-)RTS
Ptr< WifiPhy > m_phy
the PHY layer on this station
Ptr< WifiMpdu > GetFirstFragmentIfNeeded(Ptr< WifiMpdu > mpdu)
Fragment the given MPDU if needed.
std::set< Mac48Address > m_sentFrameTo
the STA(s) to which we sent a frame requesting a response
virtual void PreProcessFrame(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Perform actions that are possibly needed when receiving any frame, independently of whether the frame...
virtual Time GetFrameDurationId(const WifiMacHeader &header, uint32_t size, const WifiTxParameters &txParams, Ptr< Packet > fragmentedPacket) const
Compute how to set the Duration/ID field of a frame being transmitted with the given TX parameters.
virtual Time GetCtsToSelfDurationId(const WifiTxVector &ctsTxVector, Time txDuration, Time response) const
Compute how to set the Duration/ID field of a CTS-to-self frame to send to protect a frame transmitte...
Ptr< ApWifiMac > m_apMac
AP MAC layer pointer (null if not an AP)
Mac48Address m_bssid
BSSID address (Mac48Address)
virtual void TransmissionFailed(bool forceCurrentCw=false)
Take necessary actions upon a transmission failure.
virtual void PostProcessFrame(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Perform actions that are possibly needed after receiving any frame, independently of whether the fram...
Ptr< ChannelAccessManager > m_channelAccessManager
the channel access manager
virtual void ReceiveMpdu(Ptr< const WifiMpdu > mpdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, bool inAmpdu)
This method handles the reception of an MPDU (possibly included in an A-MPDU)
virtual bool StartTransmission(Ptr< Txop > dcf, MHz_u allowedWidth)
Request the FrameExchangeManager to start a frame exchange sequence.
MHz_u m_allowedWidth
the allowed width for the current transmission
Time m_navEnd
NAV expiration time.
void DoDispose() override
Destructor implementation.
an EUI-48 address
static Mac48Address GetBroadcast()
Smart pointer class similar to boost::intrusive_ptr.
QosFrameExchangeManager handles the frame exchange sequences for QoS stations.
EventId m_pifsRecoveryEvent
event associated with an attempt of PIFS recovery
void ForwardMpduDown(Ptr< WifiMpdu > mpdu, WifiTxVector &txVector) override
Forward an MPDU down to the PHY layer.
virtual void ClearTxopHolderIfNeeded()
Clear the TXOP holder if the NAV counted down to zero (includes the case of NAV reset).
void ReceiveMpdu(Ptr< const WifiMpdu > mpdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, bool inAmpdu) override
This method handles the reception of an MPDU (possibly included in an A-MPDU)
virtual bool StartFrameExchange(Ptr< QosTxop > edca, Time availableTime, bool initialFrame)
Start a frame exchange (including protection frames and acknowledgment frames as needed) that fits wi...
void SetTxopHolder(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Set the TXOP holder, if needed, based on the received frame.
Time GetFrameDurationId(const WifiMacHeader &header, uint32_t size, const WifiTxParameters &txParams, Ptr< Packet > fragmentedPacket) const override
Compute how to set the Duration/ID field of a frame being transmitted with the given TX parameters.
Time GetCtsToSelfDurationId(const WifiTxVector &ctsTxVector, Time txDuration, Time response) const override
Compute how to set the Duration/ID field of a CTS-to-self frame to send to protect a frame transmitte...
Ptr< QosTxop > m_edca
the EDCAF that gained channel access
virtual bool IsWithinLimitsIfAddMpdu(Ptr< const WifiMpdu > mpdu, const WifiTxParameters &txParams, Time ppduDurationLimit) const
Check whether the given MPDU can be added to the frame being built (as described by the given TX para...
void PifsRecovery(bool forceCurrentCw)
Perform a PIFS recovery as a response to transmission failure within a TXOP.
std::optional< Mac48Address > m_txopHolder
MAC address of the TXOP holder.
void PostProcessFrame(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector) override
Perform actions that are possibly needed after receiving any frame, independently of whether the fram...
void TransmissionFailed(bool forceCurrentCw=false) override
Take necessary actions upon a transmission failure.
Time GetRtsDurationId(const WifiTxVector &rtsTxVector, Time txDuration, Time response) const override
Compute how to set the Duration/ID field of an RTS frame to send to protect a frame transmitted with ...
virtual std::optional< Mac48Address > FindTxopHolder(const WifiMacHeader &hdr, const WifiTxVector &txVector)
Determine the holder of the TXOP, if possible, based on the received frame.
virtual bool SendCfEndIfNeeded()
Send a CF-End frame to indicate the completion of the TXOP, provided that the remaining duration is l...
bool m_initialFrame
true if transmitting the initial frame of a TXOP
virtual Ptr< WifiMpdu > CreateAliasIfNeeded(Ptr< WifiMpdu > mpdu) const
Create an alias of the given MPDU for transmission by this Frame Exchange Manager.
void TransmissionSucceeded() override
Take necessary actions upon a transmission success.
static TypeId GetTypeId()
Get the type ID.
void UpdateNav(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector) override
Update the NAV, if needed, based on the Duration/ID of the given psdu.
bool m_pifsRecovery
true if performing a PIFS recovery after failure
Ptr< Txop > m_edcaBackingOff
channel access function that invoked backoff during TXOP
void PreProcessFrame(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector) override
Perform actions that are possibly needed when receiving any frame, independently of whether the frame...
bool m_setQosQueueSize
whether to set the Queue Size subfield of the QoS Control field of QoS data frames
virtual bool IsWithinSizeAndTimeLimits(uint32_t ppduPayloadSize, Mac48Address receiver, const WifiTxParameters &txParams, Time ppduDurationLimit) const
Check whether the transmission time of the frame being built (as described by the given TX parameters...
void NavResetTimeout() override
Reset the NAV upon expiration of the NAV reset timer.
void CancelPifsRecovery()
Cancel the PIFS recovery event and have the EDCAF attempting PIFS recovery release the channel.
bool TryAddMpdu(Ptr< const WifiMpdu > mpdu, WifiTxParameters &txParams, Time availableTime) const
Recompute the protection and acknowledgment methods to use if the given MPDU is added to the frame be...
bool StartTransmission(Ptr< Txop > edca, MHz_u allowedWidth) override
Request the FrameExchangeManager to start a frame exchange sequence.
void DoDispose() override
Destructor implementation.
virtual Time GetRemainingTxop(uint8_t linkId) const
Return the remaining duration in the current TXOP on the given link.
Definition qos-txop.cc:637
virtual std::optional< Time > GetTxopStartTime(uint8_t linkId) const
Definition qos-txop.cc:592
void NotifyChannelAccessed(uint8_t linkId, Time txopDuration) override
Called by the FrameExchangeManager to notify that channel access has been granted on the given link f...
Definition qos-txop.cc:581
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition nstime.h:340
bool IsNegative() const
Exactly equivalent to t <= 0.
Definition nstime.h:313
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition nstime.h:276
@ MS
millisecond
Definition nstime.h:106
bool IsZero() const
Exactly equivalent to t == 0.
Definition nstime.h:304
Time GetTxopLimit() const
Return the TXOP limit.
Definition txop.cc:602
void UpdateFailedCw(uint8_t linkId)
Update the value of the CW variable for the given link to take into account a transmission failure.
Definition txop.cc:378
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid() const
Return the Traffic ID of a QoS header.
bool IsBlockAckReq() const
Return true if the header is a BlockAckRequest header.
bool IsCts() const
Return true if the header is a CTS header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
void SetNoMoreFragments()
Un-set the More Fragment bit in the Frame Control Field.
bool IsMgt() const
Return true if the Type is Management.
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
bool IsQosEosp() const
Return if the end of service period (EOSP) is set.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetQosQueueSize(uint8_t size)
Set the Queue Size subfield in the QoS control field.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
virtual const char * GetTypeString() const
Return a string corresponds to the header type.
QosAckPolicy GetQosAckPolicy() const
Return the QoS Ack policy in the QoS control field.
void SetDuration(Time duration)
Set the Duration/ID field with the given duration (Time object).
bool IsRts() const
Return true if the header is a RTS header.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
void SetQosEosp()
Set the end of service period (EOSP) bit in the QoS control field.
uint8_t GetQosQueueSize() const
Get the Queue Size subfield in the QoS control field.
void SetDsNotTo()
Un-set the To DS bit in the Frame Control field.
void SetNoRetry()
Un-set the Retry bit in the Frame Control field.
Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
Definition wifi-phy.cc:829
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition wifi-phy.cc:1587
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition wifi-phy.cc:1616
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition wifi-phy.cc:1069
Time GetPifs() const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition wifi-phy.cc:853
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
std::optional< Time > m_txDuration
TX duration of the frame.
std::unique_ptr< WifiProtection > m_protection
protection method
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
void UndoAddMpdu()
Undo the addition of the last MPDU added by calling AddMpdu().
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
void AddMpdu(Ptr< const WifiMpdu > mpdu)
Record that an MPDU is being added to the current frame.
bool IsRunning() const
Return true if the timer is running.
void Cancel()
Cancel the timer.
const std::set< Mac48Address > & GetStasExpectedToRespond() const
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
WifiPreamble GetPreambleType() const
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition boolean.h:70
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
@ STA
Definition wifi-mac.h:58
@ AP
Definition wifi-mac.h:59
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Time GetPpduMaxTime(WifiPreamble preamble)
Get the maximum PPDU duration (see Section 10.14 of 802.11-2016) for the PHY layers defining the aPPD...
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
uint32_t GetRtsSize()
Return the total RTS size (including FCS trailer).
Definition wifi-utils.cc:95
@ WIFI_MAC_CTL_END
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:587
uint32_t GetCtsSize()
Return the total CTS size (including FCS trailer).
RxSignalInfo structure containing info on the received signal.
Definition wifi-types.h:72
double snr
SNR in linear scale.
Definition wifi-types.h:73