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);
78
79 WifiMacHeader cfEnd;
81 cfEnd.SetDsNotFrom();
82 cfEnd.SetDsNotTo();
83 cfEnd.SetNoRetry();
84 cfEnd.SetNoMoreFragments();
85 cfEnd.SetDuration(Seconds(0));
87 cfEnd.SetAddr2(m_self);
88
89 WifiTxVector cfEndTxVector =
90 GetWifiRemoteStationManager()->GetRtsTxVector(cfEnd.GetAddr1(), m_allowedWidth);
91
92 auto mpdu = Create<WifiMpdu>(Create<Packet>(), cfEnd);
93 auto txDuration =
94 m_phy->CalculateTxDuration(mpdu->GetSize(), cfEndTxVector, m_phy->GetPhyBand());
95
96 // Send the CF-End frame if the remaining duration is long enough to transmit this frame
97 if (m_edca->GetRemainingTxop(m_linkId) > txDuration)
98 {
99 NS_LOG_DEBUG("Send CF-End frame");
100 ForwardMpduDown(mpdu, cfEndTxVector);
101 Simulator::Schedule(txDuration,
103 this,
104 m_edca);
105 return true;
106 }
107
109 m_edca = nullptr;
110 return false;
111}
112
113void
115{
116 NS_LOG_FUNCTION(this);
119
120 // Release the channel if it has not been idle for the last PIFS interval
121 m_allowedWidth = std::min(
123 m_channelAccessManager->GetLargestIdlePrimaryChannel(m_phy->GetPifs(), Simulator::Now()));
124
125 if (m_allowedWidth == 0)
126 {
128 m_edca = nullptr;
129 }
130 else
131 {
132 // the txopDuration parameter is unused because we are not starting a new TXOP
134 }
135}
136
137void
139{
140 NS_LOG_FUNCTION(this);
143
144 NS_LOG_DEBUG("Cancel PIFS recovery being attempted by EDCAF " << m_edca);
147}
148
149bool
151{
152 NS_LOG_FUNCTION(this << edca << allowedWidth);
153
155 {
156 // Another AC (having AIFS=1 or lower, if the user changed the default settings)
157 // gained channel access while performing PIFS recovery. Abort PIFS recovery
159 }
160
161 // TODO This will become an assert once no Txop is installed on a QoS station
162 if (!edca->IsQosTxop())
163 {
164 m_edca = nullptr;
165 return FrameExchangeManager::StartTransmission(edca, allowedWidth);
166 }
167
168 m_allowedWidth = allowedWidth;
169 auto qosTxop = StaticCast<QosTxop>(edca);
170 return StartTransmission(qosTxop, qosTxop->GetTxopLimit(m_linkId));
171}
172
173bool
175{
176 NS_LOG_FUNCTION(this << edca << txopDuration);
177
179 {
180 // Another AC (having AIFS=1 or lower, if the user changed the default settings)
181 // gained channel access while performing PIFS recovery. Abort PIFS recovery
183 }
184
185 if (m_txTimer.IsRunning())
186 {
188 }
189 m_dcf = edca;
190 m_edca = edca;
191
192 // We check if this EDCAF invoked the backoff procedure (without terminating
193 // the TXOP) because the transmission of a non-initial frame of a TXOP failed
194 bool backingOff = (m_edcaBackingOff == m_edca);
195
196 if (backingOff)
197 {
202
203 // clear the member variable
204 m_edcaBackingOff = nullptr;
205 }
206
208 {
209 // TXOP limit is not null. We have to check if this EDCAF is starting a
210 // new TXOP. This includes the case when the transmission of a non-initial
211 // frame of a TXOP failed and backoff was invoked without terminating the
212 // TXOP. In such a case, we assume that a new TXOP is being started if it
213 // elapsed more than TXOPlimit since the start of the paused TXOP. Note
214 // that GetRemainingTxop returns 0 iff Now - TXOPstart >= TXOPlimit
216 (backingOff && m_edca->GetRemainingTxop(m_linkId).IsZero()))
217 {
218 // starting a new TXOP
219 m_edca->NotifyChannelAccessed(m_linkId, txopDuration);
220
221 if (StartFrameExchange(m_edca, txopDuration, true))
222 {
223 m_initialFrame = true;
224 return true;
225 }
226
227 // TXOP not even started, return false
228 NS_LOG_DEBUG("No frame transmitted");
230 m_edca = nullptr;
231 return false;
232 }
233
234 // We are continuing a TXOP, check if we can transmit another frame
236
238 {
239 NS_LOG_DEBUG("Not enough remaining TXOP time");
240 return SendCfEndIfNeeded();
241 }
242
243 return true;
244 }
245
246 // we get here if TXOP limit is null
247 m_initialFrame = true;
248
249 if (StartFrameExchange(m_edca, Time::Min(), true))
250 {
252 return true;
253 }
254
255 NS_LOG_DEBUG("No frame transmitted");
257 m_edca = nullptr;
258 return false;
259}
260
261bool
263 Time availableTime,
264 bool initialFrame)
265{
266 NS_LOG_FUNCTION(this << edca << availableTime << initialFrame);
267
268 Ptr<WifiMpdu> mpdu = edca->PeekNextMpdu(m_linkId);
269
270 // Even though channel access is requested when the queue is not empty, at
271 // the time channel access is granted the lifetime of the packet might be
272 // expired and the queue might be empty.
273 if (!mpdu)
274 {
275 NS_LOG_DEBUG("Queue empty");
276 return false;
277 }
278
279 mpdu = CreateAliasIfNeeded(mpdu);
280 WifiTxParameters txParams;
281 txParams.m_txVector =
282 GetWifiRemoteStationManager()->GetDataTxVector(mpdu->GetHeader(), m_allowedWidth);
283
284 Ptr<WifiMpdu> item = edca->GetNextMpdu(m_linkId, mpdu, txParams, availableTime, initialFrame);
285
286 if (!item)
287 {
288 NS_LOG_DEBUG("Not enough time to transmit a frame");
289 return false;
290 }
291
292 NS_ASSERT_MSG(!item->GetHeader().IsQosData() || !item->GetHeader().IsQosAmsdu(),
293 "We should not get an A-MSDU here");
294
295 // check if the MSDU needs to be fragmented
296 item = GetFirstFragmentIfNeeded(item);
297
298 // update the protection method if the frame was fragmented
299 if (item->IsFragment() && item->GetSize() != mpdu->GetSize())
300 {
301 WifiTxParameters fragmentTxParams;
302 fragmentTxParams.m_txVector = txParams.m_txVector;
303 fragmentTxParams.AddMpdu(item);
304 UpdateTxDuration(item->GetHeader().GetAddr1(), fragmentTxParams);
305 txParams.m_protection = GetProtectionManager()->TryAddMpdu(item, fragmentTxParams);
306 NS_ASSERT(txParams.m_protection);
307 }
308
309 SendMpduWithProtection(item, txParams);
310
311 return true;
312}
313
316{
317 return mpdu;
318}
319
320bool
322 WifiTxParameters& txParams,
323 Time availableTime) const
324{
325 NS_ASSERT(mpdu);
326 NS_LOG_FUNCTION(this << *mpdu << &txParams << availableTime);
327
328 // tentatively add the given MPDU
329 auto prevTxDuration = txParams.m_txDuration;
330 txParams.AddMpdu(mpdu);
331 UpdateTxDuration(mpdu->GetHeader().GetAddr1(), txParams);
332
333 // check if adding the given MPDU requires a different protection method
334 std::optional<Time> protectionTime; // uninitialized
335 if (txParams.m_protection)
336 {
337 protectionTime = txParams.m_protection->protectionTime;
338 }
339
340 std::unique_ptr<WifiProtection> protection;
341 protection = GetProtectionManager()->TryAddMpdu(mpdu, txParams);
342 bool protectionSwapped = false;
343
344 if (protection)
345 {
346 // the protection method has changed, calculate the new protection time
347 CalculateProtectionTime(protection.get());
348 protectionTime = protection->protectionTime;
349 // swap unique pointers, so that the txParams that is passed to the next
350 // call to IsWithinLimitsIfAddMpdu is the most updated one
351 txParams.m_protection.swap(protection);
352 protectionSwapped = true;
353 }
354 NS_ASSERT(protectionTime.has_value());
355 NS_LOG_DEBUG("protection time=" << *protectionTime);
356
357 // check if adding the given MPDU requires a different acknowledgment method
358 std::optional<Time> acknowledgmentTime; // uninitialized
359 if (txParams.m_acknowledgment)
360 {
361 acknowledgmentTime = txParams.m_acknowledgment->acknowledgmentTime;
362 }
363
364 std::unique_ptr<WifiAcknowledgment> acknowledgment;
365 acknowledgment = GetAckManager()->TryAddMpdu(mpdu, txParams);
366 bool acknowledgmentSwapped = false;
367
368 if (acknowledgment)
369 {
370 // the acknowledgment method has changed, calculate the new acknowledgment time
371 CalculateAcknowledgmentTime(acknowledgment.get());
372 acknowledgmentTime = acknowledgment->acknowledgmentTime;
373 // swap unique pointers, so that the txParams that is passed to the next
374 // call to IsWithinLimitsIfAddMpdu is the most updated one
375 txParams.m_acknowledgment.swap(acknowledgment);
376 acknowledgmentSwapped = true;
377 }
378 NS_ASSERT(acknowledgmentTime.has_value());
379 NS_LOG_DEBUG("acknowledgment time=" << *acknowledgmentTime);
380
381 Time ppduDurationLimit = Time::Min();
382 if (availableTime != Time::Min())
383 {
384 ppduDurationLimit = availableTime - *protectionTime - *acknowledgmentTime;
385 }
386
387 if (!IsWithinLimitsIfAddMpdu(mpdu, txParams, ppduDurationLimit))
388 {
389 // adding MPDU failed, undo the addition of the MPDU and restore protection and
390 // acknowledgment methods if they were swapped
391 txParams.UndoAddMpdu();
392 txParams.m_txDuration = prevTxDuration;
393 if (protectionSwapped)
394 {
395 txParams.m_protection.swap(protection);
396 }
397 if (acknowledgmentSwapped)
398 {
399 txParams.m_acknowledgment.swap(acknowledgment);
400 }
401 return false;
402 }
403
404 return true;
405}
406
407bool
409 const WifiTxParameters& txParams,
410 Time ppduDurationLimit) const
411{
412 NS_ASSERT(mpdu);
413 NS_LOG_FUNCTION(this << *mpdu << &txParams << ppduDurationLimit);
414
415 // A QoS station only has to check that the MPDU transmission time does not
416 // exceed the given limit
417 return IsWithinSizeAndTimeLimits(mpdu->GetSize(),
418 mpdu->GetHeader().GetAddr1(),
419 txParams,
420 ppduDurationLimit);
421}
422
423bool
425 Mac48Address receiver,
426 const WifiTxParameters& txParams,
427 Time ppduDurationLimit) const
428{
429 NS_LOG_FUNCTION(this << ppduPayloadSize << receiver << &txParams << ppduDurationLimit);
430
431 if (ppduDurationLimit != Time::Min() && ppduDurationLimit.IsNegative())
432 {
433 NS_LOG_DEBUG("ppduDurationLimit is null or negative, time limit is trivially exceeded");
434 return false;
435 }
436
437 if (ppduPayloadSize > WifiPhy::GetMaxPsduSize(txParams.m_txVector.GetModulationClass()))
438 {
439 NS_LOG_DEBUG("the frame exceeds the max PSDU size");
440 return false;
441 }
442
443 // Get the maximum PPDU Duration based on the preamble type
444 Time maxPpduDuration = GetPpduMaxTime(txParams.m_txVector.GetPreambleType());
445
446 NS_ASSERT_MSG(txParams.m_txDuration, "TX duration not yet computed");
447 auto txTime = txParams.m_txDuration.value();
448 NS_LOG_DEBUG("PPDU duration: " << txTime.As(Time::MS));
449
450 if ((ppduDurationLimit.IsStrictlyPositive() && txTime > ppduDurationLimit) ||
451 (maxPpduDuration.IsStrictlyPositive() && txTime > maxPpduDuration))
452 {
454 "the frame does not meet the constraint on max PPDU duration or PPDU duration limit");
455 return false;
456 }
457
458 return true;
459}
460
461Time
463 uint32_t size,
464 const WifiTxParameters& txParams,
465 Ptr<Packet> fragmentedPacket) const
466{
467 NS_LOG_FUNCTION(this << header << size << &txParams << fragmentedPacket);
468
469 // TODO This will be removed once no Txop is installed on a QoS station
470 if (!m_edca)
471 {
472 return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
473 }
474
476 {
477 return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
478 }
479
480 NS_ASSERT(txParams.m_acknowledgment &&
481 txParams.m_acknowledgment->acknowledgmentTime.has_value());
482
483 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
484 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
485 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
486 // of 802.11-2016)
487 return std::max(m_edca->GetRemainingTxop(m_linkId) -
489 *txParams.m_acknowledgment->acknowledgmentTime);
490}
491
492Time
494 Time txDuration,
495 Time response) const
496{
497 NS_LOG_FUNCTION(this << rtsTxVector << txDuration << response);
498
499 // TODO This will be removed once no Txop is installed on a QoS station
500 if (!m_edca)
501 {
502 return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
503 }
504
506 {
507 return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
508 }
509
510 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
511 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
512 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
513 // of 802.11-2016)
514 return std::max(m_edca->GetRemainingTxop(m_linkId) -
516 Seconds(0));
517}
518
519Time
521 Time txDuration,
522 Time response) const
523{
524 NS_LOG_FUNCTION(this << ctsTxVector << txDuration << response);
525
526 // TODO This will be removed once no Txop is installed on a QoS station
527 if (!m_edca)
528 {
529 return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
530 }
531
533 {
534 return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
535 }
536
537 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
538 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
539 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
540 // of 802.11-2016)
541 return std::max(m_edca->GetRemainingTxop(m_linkId) -
543 Seconds(0));
544}
545
546void
548{
549 NS_LOG_FUNCTION(this << *mpdu << txVector);
550
551 WifiMacHeader& hdr = mpdu->GetHeader();
552
553 if (hdr.IsQosData() && m_mac->GetTypeOfStation() == STA &&
554 (m_setQosQueueSize || hdr.IsQosEosp()))
555 {
556 uint8_t tid = hdr.GetQosTid();
557 hdr.SetQosEosp();
558 hdr.SetQosQueueSize(
559 m_mac->GetQosTxop(tid)->GetQosQueueSize(tid,
560 mpdu->GetOriginal()->GetHeader().GetAddr1()));
561 }
563}
564
565void
567{
568 NS_LOG_DEBUG(this);
569
570 // TODO This will be removed once no Txop is installed on a QoS station
571 if (!m_edca)
572 {
574 return;
575 }
576
579 {
580 NS_LOG_DEBUG("Schedule another transmission in a SIFS");
583
584 // we are continuing a TXOP, hence the txopDuration parameter is unused
586 }
587 else
588 {
590 m_edca = nullptr;
591 }
592 m_initialFrame = false;
593}
594
595void
597{
598 NS_LOG_FUNCTION(this);
599
600 // TODO This will be removed once no Txop is installed on a QoS station
601 if (!m_edca)
602 {
604 return;
605 }
606
607 if (m_initialFrame)
608 {
609 // The backoff procedure shall be invoked by an EDCAF when the transmission
610 // of an MPDU in the initial PPDU of a TXOP fails (Sec. 10.22.2.2 of 802.11-2016)
611 NS_LOG_DEBUG("TX of the initial frame of a TXOP failed: terminate TXOP");
613 m_edca = nullptr;
614 }
615 else
616 {
617 // some STA(s) did not respond, they are no longer protected
618 for (const auto& address : m_txTimer.GetStasExpectedToRespond())
619 {
620 NS_LOG_DEBUG(address << " did not respond, hence it is no longer protected");
621 m_protectedStas.erase(address);
622 }
623
625 "Cannot transmit more than one frame if TXOP Limit is zero");
626
627 // A STA can perform a PIFS recovery or perform a backoff as a response to
628 // transmission failure within a TXOP. How it chooses between these two is
629 // implementation dependent. (Sec. 10.22.2.2 of 802.11-2016)
630 if (m_pifsRecovery)
631 {
632 // we can continue the TXOP if the carrier sense mechanism indicates that
633 // the medium is idle in a PIFS
634 NS_LOG_DEBUG("TX of a non-initial frame of a TXOP failed: perform PIFS recovery");
638 }
639 else
640 {
641 // In order not to terminate (yet) the TXOP, we call the NotifyChannelReleased
642 // method of the Txop class, which only generates a new backoff value and
643 // requests channel access if needed,
644 NS_LOG_DEBUG("TX of a non-initial frame of a TXOP failed: invoke backoff");
645 m_edca->Txop::NotifyChannelReleased(m_linkId);
647 m_edca = nullptr;
648 }
649 }
650 m_initialFrame = false;
651}
652
653void
655{
656 NS_LOG_FUNCTION(this << psdu << txVector);
657
658 // APs store buffer size report of associated stations
659 if (m_mac->GetTypeOfStation() == AP && psdu->GetAddr1() == m_self)
660 {
661 for (const auto& mpdu : *PeekPointer(psdu))
662 {
663 const WifiMacHeader& hdr = mpdu->GetHeader();
664
665 if (hdr.IsQosData() && hdr.IsQosEosp())
666 {
667 NS_LOG_DEBUG("Station " << hdr.GetAddr2() << " reported a buffer status of "
668 << +hdr.GetQosQueueSize()
669 << " for tid=" << +hdr.GetQosTid());
670 StaticCast<ApWifiMac>(m_mac)->SetBufferStatus(
671 hdr.GetQosTid(),
672 mpdu->GetOriginal()->GetHeader().GetAddr2(),
673 hdr.GetQosQueueSize());
674 }
675 }
676 }
677
678 // before updating the NAV, check if the NAV counted down to zero. In such a
679 // case, clear the saved TXOP holder address.
681
683}
684
685void
687{
688 NS_LOG_FUNCTION(this << psdu << txVector);
689
690 SetTxopHolder(psdu, txVector);
692}
693
694void
696{
697 NS_LOG_FUNCTION(this << psdu << txVector);
698 if (auto txopHolder = FindTxopHolder(psdu->GetHeader(0), txVector))
699 {
700 m_txopHolder = *txopHolder;
701 }
702}
703
704std::optional<Mac48Address>
706{
707 NS_LOG_FUNCTION(this << hdr << txVector);
708
709 // A STA shall save the TXOP holder address for the BSS in which it is associated.
710 // The TXOP holder address is the MAC address from the Address 2 field of the frame
711 // that initiated a frame exchange sequence, except if this is a CTS frame, in which
712 // case the TXOP holder address is the Address 1 field. (Sec. 10.23.2.4 of 802.11-2020)
713 if ((hdr.IsQosData() || hdr.IsMgt() || hdr.IsRts() || hdr.IsBlockAckReq()) &&
714 (hdr.GetAddr1() == m_bssid || hdr.GetAddr2() == m_bssid))
715 {
716 return hdr.GetAddr2();
717 }
718 if (hdr.IsCts() && hdr.GetAddr1() == m_bssid)
719 {
720 return hdr.GetAddr1();
721 }
722 return std::nullopt;
723}
724
725void
734
735void
737{
738 NS_LOG_FUNCTION(this << psdu << txVector);
739 if (psdu->GetHeader(0).IsCfEnd())
740 {
741 NS_LOG_DEBUG("Received CF-End, resetting NAV");
743 return;
744 }
745
746 FrameExchangeManager::UpdateNav(psdu, txVector);
747}
748
749void
756
757void
759 RxSignalInfo rxSignalInfo,
760 const WifiTxVector& txVector,
761 bool inAmpdu)
762{
763 // The received MPDU is either broadcast or addressed to this station
764 NS_ASSERT(mpdu->GetHeader().GetAddr1().IsGroup() || mpdu->GetHeader().GetAddr1() == m_self);
765
766 double rxSnr = rxSignalInfo.snr;
767 const WifiMacHeader& hdr = mpdu->GetHeader();
768
769 if (hdr.IsRts())
770 {
771 NS_ABORT_MSG_IF(inAmpdu, "Received RTS as part of an A-MPDU");
772
773 // If a non-VHT STA receives an RTS frame with the RA address matching the
774 // MAC address of the STA and the MAC address in the TA field in the RTS
775 // frame matches the saved TXOP holder address, then the STA shall send the
776 // CTS frame after SIFS, without regard for, and without resetting, its NAV.
777 // (sec. 10.22.2.4 of 802.11-2016)
778 if (hdr.GetAddr2() == m_txopHolder || VirtualCsMediumIdle())
779 {
780 NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", schedule CTS");
783 this,
784 hdr,
785 txVector.GetMode(),
786 rxSnr);
787 }
788 else
789 {
790 NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", cannot schedule CTS");
791 }
792 return;
793 }
794
795 if (hdr.IsQosData())
796 {
798 {
799 NS_LOG_DEBUG("Received " << hdr.GetTypeString() << " from=" << hdr.GetAddr2()
800 << ", schedule ACK");
803 this,
804 hdr,
805 txVector,
806 rxSnr);
807 }
808
809 // Forward up the frame
810 m_rxMiddle->Receive(mpdu, m_linkId);
811
812 // the received data frame has been processed
813 return;
814 }
815
816 return FrameExchangeManager::ReceiveMpdu(mpdu, rxSignalInfo, txVector, inAmpdu);
817}
818
819} // namespace ns3
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
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
virtual void TransmissionFailed()
Take necessary actions upon a transmission failure.
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
Ptr< WifiPhy > m_phy
the PHY layer on this station
Ptr< WifiMpdu > GetFirstFragmentIfNeeded(Ptr< WifiMpdu > mpdu)
Fragment the given MPDU if needed.
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...
Mac48Address m_bssid
BSSID address (Mac48Address)
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)
void TransmissionFailed() override
Take necessary actions upon a transmission failure.
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...
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...
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
void PifsRecovery()
Perform a PIFS recovery as a response to transmission failure within a TXOP.
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:632
virtual std::optional< Time > GetTxopStartTime(uint8_t linkId) const
Definition qos-txop.cc:587
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:576
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:579
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:823
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition wifi-phy.cc:1572
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition wifi-phy.cc:1601
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition wifi-phy.cc:1063
Time GetPifs() const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition wifi-phy.cc:847
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
#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:1308
@ 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...
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
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