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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Stefano Avallone <stavallo@unina.it>
18 */
19
21
22#include "ap-wifi-mac.h"
23#include "wifi-mac-queue.h"
24#include "wifi-mac-trailer.h"
25
26#include "ns3/abort.h"
27#include "ns3/log.h"
28
29#undef NS_LOG_APPEND_CONTEXT
30#define NS_LOG_APPEND_CONTEXT std::clog << "[link=" << +m_linkId << "][mac=" << m_self << "] "
31
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("QosFrameExchangeManager");
36
37NS_OBJECT_ENSURE_REGISTERED(QosFrameExchangeManager);
38
39TypeId
41{
42 static TypeId tid =
43 TypeId("ns3::QosFrameExchangeManager")
45 .AddConstructor<QosFrameExchangeManager>()
46 .SetGroupName("Wifi")
47 .AddAttribute("PifsRecovery",
48 "Perform a PIFS recovery as a response to transmission failure "
49 "within a TXOP",
50 BooleanValue(true),
53 .AddAttribute("SetQueueSize",
54 "Whether to set the Queue Size subfield of the QoS Control field "
55 "of QoS data frames sent by non-AP stations",
56 BooleanValue(false),
59 return tid;
60}
61
63 : m_initialFrame(false)
64{
65 NS_LOG_FUNCTION(this);
66}
67
69{
71}
72
73void
75{
76 NS_LOG_FUNCTION(this);
77 m_edca = nullptr;
78 m_edcaBackingOff = nullptr;
81}
82
83bool
85{
86 NS_LOG_FUNCTION(this);
89
90 WifiMacHeader cfEnd;
92 cfEnd.SetDsNotFrom();
93 cfEnd.SetDsNotTo();
94 cfEnd.SetNoRetry();
95 cfEnd.SetNoMoreFragments();
96 cfEnd.SetDuration(Seconds(0));
98 cfEnd.SetAddr2(m_self);
99
101
103 cfEndTxVector,
104 m_phy->GetPhyBand());
105
106 // Send the CF-End frame if the remaining duration is long enough to transmit this frame
107 if (m_edca->GetRemainingTxop(m_linkId) > txDuration)
108 {
109 NS_LOG_DEBUG("Send CF-End frame");
110 m_phy->Send(Create<WifiPsdu>(Create<Packet>(), cfEnd), cfEndTxVector);
111 Simulator::Schedule(txDuration,
113 this,
114 m_edca);
115 return true;
116 }
117
119 m_edca = nullptr;
120 return false;
121}
122
123void
125{
126 NS_LOG_FUNCTION(this);
129
130 // Release the channel if it has not been idle for the last PIFS interval
133 {
135 m_edca = nullptr;
136 }
137 else
138 {
139 // the txopDuration parameter is unused because we are not starting a new TXOP
141 }
142}
143
144void
146{
147 NS_LOG_FUNCTION(this);
150
151 NS_LOG_DEBUG("Cancel PIFS recovery being attempted by EDCAF " << m_edca);
154}
155
156bool
158{
159 NS_LOG_FUNCTION(this << edca << allowedWidth);
160
162 {
163 // Another AC (having AIFS=1 or lower, if the user changed the default settings)
164 // gained channel access while performing PIFS recovery. Abort PIFS recovery
166 }
167
168 // TODO This will become an assert once no Txop is installed on a QoS station
169 if (!edca->IsQosTxop())
170 {
171 m_edca = nullptr;
172 return FrameExchangeManager::StartTransmission(edca, allowedWidth);
173 }
174
175 m_allowedWidth = allowedWidth;
176 auto qosTxop = StaticCast<QosTxop>(edca);
177 return StartTransmission(qosTxop, qosTxop->GetTxopLimit(m_linkId));
178}
179
180bool
182{
183 NS_LOG_FUNCTION(this << edca << txopDuration);
184
186 {
187 // Another AC (having AIFS=1 or lower, if the user changed the default settings)
188 // gained channel access while performing PIFS recovery. Abort PIFS recovery
190 }
191
192 if (m_txTimer.IsRunning())
193 {
195 }
196 m_dcf = edca;
197 m_edca = edca;
198
199 // We check if this EDCAF invoked the backoff procedure (without terminating
200 // the TXOP) because the transmission of a non-initial frame of a TXOP failed
201 bool backingOff = (m_edcaBackingOff == m_edca);
202
203 if (backingOff)
204 {
209
210 // clear the member variable
211 m_edcaBackingOff = nullptr;
212 }
213
215 {
216 // TXOP limit is not null. We have to check if this EDCAF is starting a
217 // new TXOP. This includes the case when the transmission of a non-initial
218 // frame of a TXOP failed and backoff was invoked without terminating the
219 // TXOP. In such a case, we assume that a new TXOP is being started if it
220 // elapsed more than TXOPlimit since the start of the paused TXOP. Note
221 // that GetRemainingTxop returns 0 iff Now - TXOPstart >= TXOPlimit
223 (backingOff && m_edca->GetRemainingTxop(m_linkId).IsZero()))
224 {
225 // starting a new TXOP
226 m_edca->NotifyChannelAccessed(m_linkId, txopDuration);
227
228 if (StartFrameExchange(m_edca, txopDuration, true))
229 {
230 m_initialFrame = true;
231 return true;
232 }
233
234 // TXOP not even started, return false
235 NS_LOG_DEBUG("No frame transmitted");
237 m_edca = nullptr;
238 return false;
239 }
240
241 // We are continuing a TXOP, check if we can transmit another frame
243
245 {
246 NS_LOG_DEBUG("Not enough remaining TXOP time");
247 return SendCfEndIfNeeded();
248 }
249
250 return true;
251 }
252
253 // we get here if TXOP limit is null
254 m_initialFrame = true;
255
256 if (StartFrameExchange(m_edca, Time::Min(), true))
257 {
259 return true;
260 }
261
262 NS_LOG_DEBUG("No frame transmitted");
264 m_edca = nullptr;
265 return false;
266}
267
268bool
270 Time availableTime,
271 bool initialFrame)
272{
273 NS_LOG_FUNCTION(this << edca << availableTime << initialFrame);
274
275 Ptr<WifiMpdu> mpdu = edca->PeekNextMpdu(m_linkId);
276
277 // Even though channel access is requested when the queue is not empty, at
278 // the time channel access is granted the lifetime of the packet might be
279 // expired and the queue might be empty.
280 if (!mpdu)
281 {
282 NS_LOG_DEBUG("Queue empty");
283 return false;
284 }
285
286 mpdu = CreateAliasIfNeeded(mpdu);
287 WifiTxParameters txParams;
288 txParams.m_txVector =
290
291 Ptr<WifiMpdu> item = edca->GetNextMpdu(m_linkId, mpdu, txParams, availableTime, initialFrame);
292
293 if (!item)
294 {
295 NS_LOG_DEBUG("Not enough time to transmit a frame");
296 return false;
297 }
298
299 NS_ASSERT_MSG(!item->GetHeader().IsQosData() || !item->GetHeader().IsQosAmsdu(),
300 "We should not get an A-MSDU here");
301
302 // check if the MSDU needs to be fragmented
303 item = GetFirstFragmentIfNeeded(item);
304
305 // update the protection method if the frame was fragmented
306 if (item->IsFragment() && item->GetSize() != mpdu->GetSize())
307 {
308 WifiTxParameters fragmentTxParams;
309 fragmentTxParams.m_txVector = txParams.m_txVector;
310 txParams.m_protection = GetProtectionManager()->TryAddMpdu(item, fragmentTxParams);
311 NS_ASSERT(txParams.m_protection);
312 }
313
314 SendMpduWithProtection(item, txParams);
315
316 return true;
317}
318
321{
322 return mpdu;
323}
324
325bool
327 WifiTxParameters& txParams,
328 Time availableTime) const
329{
330 NS_ASSERT(mpdu);
331 NS_LOG_FUNCTION(this << *mpdu << &txParams << availableTime);
332
333 // check if adding the given MPDU requires a different protection method
334 Time protectionTime = Time::Min(); // 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 != Time::Min());
355 NS_LOG_DEBUG("protection time=" << protectionTime);
356
357 // check if adding the given MPDU requires a different acknowledgment method
358 Time acknowledgmentTime = Time::Min(); // 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 != Time::Min());
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, restore protection and acknowledgment methods
390 // if they were swapped
391 if (protectionSwapped)
392 {
393 txParams.m_protection.swap(protection);
394 }
395 if (acknowledgmentSwapped)
396 {
397 txParams.m_acknowledgment.swap(acknowledgment);
398 }
399 return false;
400 }
401
402 // the given MPDU can be added, hence update the txParams
403 txParams.AddMpdu(mpdu);
404 UpdateTxDuration(mpdu->GetHeader().GetAddr1(), txParams);
405
406 return true;
407}
408
409bool
411 const WifiTxParameters& txParams,
412 Time ppduDurationLimit) const
413{
414 NS_ASSERT(mpdu);
415 NS_LOG_FUNCTION(this << *mpdu << &txParams << ppduDurationLimit);
416
417 // A QoS station only has to check that the MPDU transmission time does not
418 // exceed the given limit
419 return IsWithinSizeAndTimeLimits(mpdu->GetSize(),
420 mpdu->GetHeader().GetAddr1(),
421 txParams,
422 ppduDurationLimit);
423}
424
425bool
427 Mac48Address receiver,
428 const WifiTxParameters& txParams,
429 Time ppduDurationLimit) const
430{
431 NS_LOG_FUNCTION(this << ppduPayloadSize << receiver << &txParams << ppduDurationLimit);
432
433 if (ppduDurationLimit != Time::Min() && ppduDurationLimit.IsNegative())
434 {
435 NS_LOG_DEBUG("ppduDurationLimit is null or negative, time limit is trivially exceeded");
436 return false;
437 }
438
439 if (ppduPayloadSize > WifiPhy::GetMaxPsduSize(txParams.m_txVector.GetModulationClass()))
440 {
441 NS_LOG_DEBUG("the frame exceeds the max PSDU size");
442 return false;
443 }
444
445 // Get the maximum PPDU Duration based on the preamble type
446 Time maxPpduDuration = GetPpduMaxTime(txParams.m_txVector.GetPreambleType());
447
448 Time txTime = GetTxDuration(ppduPayloadSize, receiver, txParams);
449 NS_LOG_DEBUG("PPDU duration: " << txTime.As(Time::MS));
450
451 if ((ppduDurationLimit.IsStrictlyPositive() && txTime > ppduDurationLimit) ||
452 (maxPpduDuration.IsStrictlyPositive() && txTime > maxPpduDuration))
453 {
455 "the frame does not meet the constraint on max PPDU duration or PPDU duration limit");
456 return false;
457 }
458
459 return true;
460}
461
462Time
464 uint32_t size,
465 const WifiTxParameters& txParams,
466 Ptr<Packet> fragmentedPacket) const
467{
468 NS_LOG_FUNCTION(this << header << size << &txParams << fragmentedPacket);
469
470 // TODO This will be removed once no Txop is installed on a QoS station
471 if (!m_edca)
472 {
473 return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
474 }
475
477 {
478 return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
479 }
480
481 NS_ASSERT(txParams.m_acknowledgment &&
482 txParams.m_acknowledgment->acknowledgmentTime != Time::Min());
483
484 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
485 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
486 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
487 // of 802.11-2016)
488 return std::max(m_edca->GetRemainingTxop(m_linkId) -
490 txParams.m_acknowledgment->acknowledgmentTime);
491}
492
493Time
495 Time txDuration,
496 Time response) const
497{
498 NS_LOG_FUNCTION(this << rtsTxVector << txDuration << response);
499
500 // TODO This will be removed once no Txop is installed on a QoS station
501 if (!m_edca)
502 {
503 return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
504 }
505
507 {
508 return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
509 }
510
511 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
512 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
513 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
514 // of 802.11-2016)
515 return std::max(m_edca->GetRemainingTxop(m_linkId) -
517 Seconds(0));
518}
519
520Time
522 Time txDuration,
523 Time response) const
524{
525 NS_LOG_FUNCTION(this << ctsTxVector << txDuration << response);
526
527 // TODO This will be removed once no Txop is installed on a QoS station
528 if (!m_edca)
529 {
530 return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
531 }
532
534 {
535 return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
536 }
537
538 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
539 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
540 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
541 // of 802.11-2016)
542 return std::max(m_edca->GetRemainingTxop(m_linkId) -
544 Seconds(0));
545}
546
547void
549{
550 NS_LOG_FUNCTION(this << *mpdu << txVector);
551
552 WifiMacHeader& hdr = mpdu->GetHeader();
553
554 if (hdr.IsQosData() && m_mac->GetTypeOfStation() == STA &&
555 (m_setQosQueueSize || hdr.IsQosEosp()))
556 {
557 uint8_t tid = hdr.GetQosTid();
558 hdr.SetQosEosp();
560 }
562}
563
564void
566{
567 NS_LOG_DEBUG(this);
568
569 // TODO This will be removed once no Txop is installed on a QoS station
570 if (!m_edca)
571 {
573 return;
574 }
575
578 {
579 NS_LOG_DEBUG("Schedule another transmission in a SIFS");
582
583 // we are continuing a TXOP, hence the txopDuration parameter is unused
585 }
586 else
587 {
589 m_edca = nullptr;
590 }
591 m_initialFrame = false;
592}
593
594void
596{
597 NS_LOG_FUNCTION(this);
598
599 // TODO This will be removed once no Txop is installed on a QoS station
600 if (!m_edca)
601 {
603 return;
604 }
605
606 if (m_initialFrame)
607 {
608 // The backoff procedure shall be invoked by an EDCAF when the transmission
609 // of an MPDU in the initial PPDU of a TXOP fails (Sec. 10.22.2.2 of 802.11-2016)
610 NS_LOG_DEBUG("TX of the initial frame of a TXOP failed: terminate TXOP");
612 m_edca = nullptr;
613 }
614 else
615 {
617 "Cannot transmit more than one frame if TXOP Limit is zero");
618
619 // A STA can perform a PIFS recovery or perform a backoff as a response to
620 // transmission failure within a TXOP. How it chooses between these two is
621 // implementation dependent. (Sec. 10.22.2.2 of 802.11-2016)
622 if (m_pifsRecovery)
623 {
624 // we can continue the TXOP if the carrier sense mechanism indicates that
625 // the medium is idle in a PIFS
626 NS_LOG_DEBUG("TX of a non-initial frame of a TXOP failed: perform PIFS recovery");
630 }
631 else
632 {
633 // In order not to terminate (yet) the TXOP, we call the NotifyChannelReleased
634 // method of the Txop class, which only generates a new backoff value and
635 // requests channel access if needed,
636 NS_LOG_DEBUG("TX of a non-initial frame of a TXOP failed: invoke backoff");
637 m_edca->Txop::NotifyChannelReleased(m_linkId);
639 m_edca = nullptr;
640 }
641 }
642 m_initialFrame = false;
643}
644
645void
647{
648 NS_LOG_FUNCTION(this << psdu << txVector);
649
650 // APs store buffer size report of associated stations
651 if (m_mac->GetTypeOfStation() == AP && psdu->GetAddr1() == m_self)
652 {
653 for (const auto& mpdu : *PeekPointer(psdu))
654 {
655 const WifiMacHeader& hdr = mpdu->GetHeader();
656
657 if (hdr.IsQosData() && hdr.IsQosEosp())
658 {
659 NS_LOG_DEBUG("Station " << hdr.GetAddr2() << " reported a buffer status of "
660 << +hdr.GetQosQueueSize()
661 << " for tid=" << +hdr.GetQosTid());
662 StaticCast<ApWifiMac>(m_mac)->SetBufferStatus(
663 hdr.GetQosTid(),
664 mpdu->GetOriginal()->GetHeader().GetAddr2(),
665 hdr.GetQosQueueSize());
666 }
667 }
668 }
669
670 // before updating the NAV, check if the NAV counted down to zero. In such a
671 // case, clear the saved TXOP holder address.
673
675}
676
677void
679{
680 NS_LOG_FUNCTION(this << psdu << txVector);
681
682 SetTxopHolder(psdu, txVector);
684}
685
686void
688{
689 NS_LOG_FUNCTION(this << psdu << txVector);
690
691 const WifiMacHeader& hdr = psdu->GetHeader(0);
692
693 // A STA shall save the TXOP holder address for the BSS in which it is associated.
694 // The TXOP holder address is the MAC address from the Address 2 field of the frame
695 // that initiated a frame exchange sequence, except if this is a CTS frame, in which
696 // case the TXOP holder address is the Address 1 field. (Sec. 10.23.2.4 of 802.11-2020)
697 if ((hdr.IsQosData() || hdr.IsMgt() || hdr.IsRts()) &&
698 (hdr.GetAddr1() == m_bssid || hdr.GetAddr2() == m_bssid))
699 {
700 m_txopHolder = psdu->GetAddr2();
701 }
702 else if (hdr.IsCts() && hdr.GetAddr1() == m_bssid)
703 {
704 m_txopHolder = psdu->GetAddr1();
705 }
706}
707
708void
710{
711 NS_LOG_FUNCTION(this);
712 if (m_navEnd <= Simulator::Now())
713 {
714 m_txopHolder.reset();
715 }
716}
717
718void
720{
721 NS_LOG_FUNCTION(this << psdu << txVector);
722 if (psdu->GetHeader(0).IsCfEnd())
723 {
724 NS_LOG_DEBUG("Received CF-End, resetting NAV");
726 return;
727 }
728
729 FrameExchangeManager::UpdateNav(psdu, txVector);
730}
731
732void
734{
735 NS_LOG_FUNCTION(this);
738}
739
740void
742 RxSignalInfo rxSignalInfo,
743 const WifiTxVector& txVector,
744 bool inAmpdu)
745{
746 // The received MPDU is either broadcast or addressed to this station
747 NS_ASSERT(mpdu->GetHeader().GetAddr1().IsGroup() || mpdu->GetHeader().GetAddr1() == m_self);
748
749 double rxSnr = rxSignalInfo.snr;
750 const WifiMacHeader& hdr = mpdu->GetHeader();
751
752 if (hdr.IsRts())
753 {
754 NS_ABORT_MSG_IF(inAmpdu, "Received RTS as part of an A-MPDU");
755
756 // If a non-VHT STA receives an RTS frame with the RA address matching the
757 // MAC address of the STA and the MAC address in the TA field in the RTS
758 // frame matches the saved TXOP holder address, then the STA shall send the
759 // CTS frame after SIFS, without regard for, and without resetting, its NAV.
760 // (sec. 10.22.2.4 of 802.11-2016)
761 if (hdr.GetAddr2() == m_txopHolder || VirtualCsMediumIdle())
762 {
763 NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", schedule CTS");
766 this,
767 hdr,
768 txVector.GetMode(),
769 rxSnr);
770 }
771 else
772 {
773 NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", cannot schedule CTS");
774 }
775 return;
776 }
777
778 if (hdr.IsQosData())
779 {
781 {
782 NS_LOG_DEBUG("Received " << hdr.GetTypeString() << " from=" << hdr.GetAddr2()
783 << ", schedule ACK");
786 this,
787 hdr,
788 txVector,
789 rxSnr);
790 }
791
792 // Forward up the frame
793 m_rxMiddle->Receive(mpdu, m_linkId);
794
795 // the received data frame has been processed
796 return;
797 }
798
799 return FrameExchangeManager::ReceiveMpdu(mpdu, rxSignalInfo, txVector, inAmpdu);
800}
801
802} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Time GetAccessGrantStart(bool ignoreNav=false) const
Access will never be granted to the medium before the time returned by this method.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
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.
uint16_t m_allowedWidth
the allowed width in MHz for the current transmission
WifiTxTimer m_txTimer
the timer set upon frame transmission
void SendCtsAfterRts(const WifiMacHeader &rtsHdr, WifiMode rtsTxMode, double rtsSnr)
Send CTS after receiving RTS.
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)
Time m_navEnd
NAV expiration time.
void DoDispose() override
Destructor implementation.
virtual bool StartTransmission(Ptr< Txop > dcf, uint16_t allowedWidth)
Request the FrameExchangeManager to start a frame exchange sequence.
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...
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetBroadcast()
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
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...
virtual 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...
bool StartTransmission(Ptr< Txop > edca, uint16_t allowedWidth) override
Request the FrameExchangeManager to start a frame exchange sequence.
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 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...
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:599
uint8_t GetQosQueueSize(uint8_t tid, Mac48Address receiver) const
Get the value for the Queue Size subfield of the QoS Control field of a QoS data frame of the given T...
Definition: qos-txop.cc:166
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:565
virtual bool IsTxopStarted(uint8_t linkId) const
Return true if a TXOP has started on the given link.
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:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:350
bool IsNegative() const
Exactly equivalent to t <= 0.
Definition: nstime.h:323
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:286
@ MS
millisecond
Definition: nstime.h:117
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:314
Time GetTxopLimit() const
Return the TXOP limit.
Definition: txop.cc:469
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid() const
Return the Traffic ID of a QoS 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.
uint32_t GetSize() const
Return the size of the WifiMacHeader in octets.
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.
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.
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.
TypeOfStation GetTypeOfStation() const
Return the type of station.
Definition: wifi-mac.cc:425
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
Definition: wifi-mac.cc:497
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
Definition: wifi-phy.cc:1709
Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:783
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1496
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition: wifi-phy.cc:1525
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1005
Time GetPifs() const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:807
WifiTxVector GetDataTxVector(const WifiMacHeader &header, uint16_t allowedWidth)
WifiTxVector GetRtsTxVector(Mac48Address address)
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
std::unique_ptr< WifiProtection > m_protection
protection method
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
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.
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:66
#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:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
@ STA
Definition: wifi-mac.h:63
@ AP
Definition: wifi-mac.h:64
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:488
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octets of the IEEE 802.11 MAC FCS field.
uint32_t GetRtsSize()
Return the total RTS size (including FCS trailer).
Definition: wifi-utils.cc:103
@ WIFI_MAC_CTL_END
uint32_t GetCtsSize()
Return the total CTS size (including FCS trailer).
Definition: wifi-utils.cc:111
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:70
double snr
SNR in linear scale.
Definition: phy-entity.h:71