A Discrete-Event Network Simulator
API
qos-frame-exchange-manager.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Stefano Avallone <stavallo@unina.it>
19 */
20
21#include "ns3/log.h"
22#include "ns3/abort.h"
24#include "wifi-mac-queue.h"
25#include "wifi-mac-trailer.h"
26#include "ap-wifi-mac.h"
27
28#undef NS_LOG_APPEND_CONTEXT
29#define NS_LOG_APPEND_CONTEXT std::clog << "[link=" << +m_linkId << "][mac=" << m_self << "] "
30
31namespace ns3 {
32
33NS_LOG_COMPONENT_DEFINE ("QosFrameExchangeManager");
34
35NS_OBJECT_ENSURE_REGISTERED (QosFrameExchangeManager);
36
37TypeId
39{
40 static TypeId tid = TypeId ("ns3::QosFrameExchangeManager")
42 .AddConstructor<QosFrameExchangeManager> ()
43 .SetGroupName ("Wifi")
44 .AddAttribute ("PifsRecovery",
45 "Perform a PIFS recovery as a response to transmission failure "
46 "within a TXOP",
47 BooleanValue (true),
50 .AddAttribute ("SetQueueSize",
51 "Whether to set the Queue Size subfield of the QoS Control field "
52 "of QoS data frames sent by non-AP stations",
53 BooleanValue (false),
56 ;
57 return tid;
58}
59
61 : m_initialFrame (false)
62{
63 NS_LOG_FUNCTION (this);
64}
65
67{
69}
70
71void
73{
74 NS_LOG_FUNCTION (this);
75 m_edca = 0;
79}
80
81bool
83{
84 NS_LOG_FUNCTION (this);
87
88 WifiMacHeader cfEnd;
90 cfEnd.SetDsNotFrom ();
91 cfEnd.SetDsNotTo ();
92 cfEnd.SetNoRetry ();
93 cfEnd.SetNoMoreFragments ();
94 cfEnd.SetDuration (Seconds (0));
96 cfEnd.SetAddr2 (m_self);
97
99
100 Time txDuration = m_phy->CalculateTxDuration (cfEnd.GetSize () + WIFI_MAC_FCS_LENGTH,
101 cfEndTxVector, m_phy->GetPhyBand ());
102
103 // Send the CF-End frame if the remaining duration is long enough to transmit this frame
104 if (m_edca->GetRemainingTxop (m_linkId) > txDuration)
105 {
106 NS_LOG_DEBUG ("Send CF-End frame");
107 m_phy->Send (Create<WifiPsdu> (Create<Packet> (), cfEnd), cfEndTxVector);
109 return true;
110 }
111
113 m_edca = 0;
114 return false;
115}
116
117void
119{
120 NS_LOG_FUNCTION (this);
123
124 // Release the channel if it has not been idle for the last PIFS interval
126 > Simulator::Now () - m_phy->GetPifs ())
127 {
129 m_edca = 0;
130 }
131 else
132 {
133 // the txopDuration parameter is unused because we are not starting a new TXOP
135 }
136}
137
138void
140{
141 NS_LOG_FUNCTION (this);
144
145 NS_LOG_DEBUG ("Cancel PIFS recovery being attempted by EDCAF " << m_edca);
148}
149
150bool
152{
153 NS_LOG_FUNCTION (this << edca << allowedWidth);
154
156 {
157 // Another AC (having AIFS=1 or lower, if the user changed the default settings)
158 // gained channel access while performing PIFS recovery. Abort PIFS recovery
160 }
161
162 // TODO This will become an assert once no Txop is installed on a QoS station
163 if (!edca->IsQosTxop ())
164 {
165 m_edca = 0;
166 return FrameExchangeManager::StartTransmission (edca, allowedWidth);
167 }
168
169 m_allowedWidth = allowedWidth;
170 auto qosTxop = StaticCast<QosTxop> (edca);
171 return StartTransmission (qosTxop, qosTxop->GetTxopLimit (m_linkId));
172}
173
174bool
176{
177 NS_LOG_FUNCTION (this << edca << txopDuration);
178
180 {
181 // Another AC (having AIFS=1 or lower, if the user changed the default settings)
182 // gained channel access while performing PIFS recovery. Abort PIFS recovery
184 }
185
186 if (m_txTimer.IsRunning ())
187 {
188 m_txTimer.Cancel ();
189 }
190 m_dcf = edca;
191 m_edca = edca;
192
193 // We check if this EDCAF invoked the backoff procedure (without terminating
194 // the TXOP) because the transmission of a non-initial frame of a TXOP failed
195 bool backingOff = (m_edcaBackingOff == m_edca);
196
197 if (backingOff)
198 {
203
204 // clear the member variable
206 }
207
209 {
210 // TXOP limit is not null. We have to check if this EDCAF is starting a
211 // new TXOP. This includes the case when the transmission of a non-initial
212 // frame of a TXOP failed and backoff was invoked without terminating the
213 // TXOP. In such a case, we assume that a new TXOP is being started if it
214 // elapsed more than TXOPlimit since the start of the paused TXOP. Note
215 // that GetRemainingTxop returns 0 iff Now - TXOPstart >= TXOPlimit
217 || (backingOff && m_edca->GetRemainingTxop (m_linkId).IsZero ()))
218 {
219 // starting a new TXOP
220 m_edca->NotifyChannelAccessed (m_linkId, txopDuration);
221
222 if (StartFrameExchange (m_edca, txopDuration, true))
223 {
224 m_initialFrame = true;
225 return true;
226 }
227
228 // TXOP not even started, return false
229 NS_LOG_DEBUG ("No frame transmitted");
231 m_edca = 0;
232 return false;
233 }
234
235 // We are continuing a TXOP, check if we can transmit another frame
237
239 {
240 NS_LOG_DEBUG ("Not enough remaining TXOP time");
241 return SendCfEndIfNeeded ();
242 }
243
244 return true;
245 }
246
247 // we get here if TXOP limit is null
248 m_initialFrame = true;
249
250 if (StartFrameExchange (m_edca, Time::Min (), true))
251 {
253 return true;
254 }
255
256 NS_LOG_DEBUG ("No frame transmitted");
258 m_edca = 0;
259 return false;
260}
261
262bool
263QosFrameExchangeManager::StartFrameExchange (Ptr<QosTxop> edca, Time availableTime, bool initialFrame)
264{
265 NS_LOG_FUNCTION (this << edca << availableTime << initialFrame);
266
267 Ptr<WifiMpdu> mpdu = edca->PeekNextMpdu (m_linkId);
268
269 // Even though channel access is requested when the queue is not empty, at
270 // the time channel access is granted the lifetime of the packet might be
271 // expired and the queue might be empty.
272 if (!mpdu)
273 {
274 NS_LOG_DEBUG ("Queue empty");
275 return false;
276 }
277
278 WifiTxParameters txParams;
279 txParams.m_txVector = GetWifiRemoteStationManager ()->GetDataTxVector (mpdu->GetHeader (), m_allowedWidth);
280
281 Ptr<WifiMpdu> item = edca->GetNextMpdu (m_linkId, mpdu, txParams, availableTime, initialFrame);
282
283 if (!item)
284 {
285 NS_LOG_DEBUG ("Not enough time to transmit a frame");
286 return false;
287 }
288
289 NS_ASSERT_MSG (!item->GetHeader ().IsQosData () || !item->GetHeader ().IsQosAmsdu (),
290 "We should not get an A-MSDU here");
291
292 // check if the MSDU needs to be fragmented
293 item = GetFirstFragmentIfNeeded (item);
294
295 // update the protection method if the frame was fragmented
296 if (item->IsFragment () && item->GetSize () != mpdu->GetSize ())
297 {
298 WifiTxParameters fragmentTxParams;
299 fragmentTxParams.m_txVector = txParams.m_txVector;
300 txParams.m_protection = GetProtectionManager ()->TryAddMpdu (item, fragmentTxParams);
301 NS_ASSERT (txParams.m_protection);
302 }
303
304 SendMpduWithProtection (item, txParams);
305
306 return true;
307}
308
309bool
311 Time availableTime) const
312{
313 NS_ASSERT (mpdu);
314 NS_LOG_FUNCTION (this << *mpdu << &txParams << availableTime);
315
316 // check if adding the given MPDU requires a different protection method
317 Time protectionTime = Time::Min (); // uninitialized
318 if (txParams.m_protection)
319 {
320 protectionTime = txParams.m_protection->protectionTime;
321 }
322
323 std::unique_ptr<WifiProtection> protection;
324 protection = GetProtectionManager ()->TryAddMpdu (mpdu, txParams);
325 bool protectionSwapped = false;
326
327 if (protection)
328 {
329 // the protection method has changed, calculate the new protection time
330 CalculateProtectionTime (protection.get ());
331 protectionTime = protection->protectionTime;
332 // swap unique pointers, so that the txParams that is passed to the next
333 // call to IsWithinLimitsIfAddMpdu is the most updated one
334 txParams.m_protection.swap (protection);
335 protectionSwapped = true;
336 }
337 NS_ASSERT (protectionTime != Time::Min ());
338 NS_LOG_DEBUG ("protection time=" << protectionTime);
339
340 // check if adding the given MPDU requires a different acknowledgment method
341 Time acknowledgmentTime = Time::Min (); // uninitialized
342 if (txParams.m_acknowledgment)
343 {
344 acknowledgmentTime = txParams.m_acknowledgment->acknowledgmentTime;
345 }
346
347 std::unique_ptr<WifiAcknowledgment> acknowledgment;
348 acknowledgment = GetAckManager ()->TryAddMpdu (mpdu, txParams);
349 bool acknowledgmentSwapped = false;
350
351 if (acknowledgment)
352 {
353 // the acknowledgment method has changed, calculate the new acknowledgment time
354 CalculateAcknowledgmentTime (acknowledgment.get ());
355 acknowledgmentTime = acknowledgment->acknowledgmentTime;
356 // swap unique pointers, so that the txParams that is passed to the next
357 // call to IsWithinLimitsIfAddMpdu is the most updated one
358 txParams.m_acknowledgment.swap (acknowledgment);
359 acknowledgmentSwapped = true;
360 }
361 NS_ASSERT (acknowledgmentTime != Time::Min ());
362 NS_LOG_DEBUG ("acknowledgment time=" << acknowledgmentTime);
363
364 Time ppduDurationLimit = Time::Min ();
365 if (availableTime != Time::Min ())
366 {
367 ppduDurationLimit = availableTime - protectionTime - acknowledgmentTime;
368 }
369
370 if (!IsWithinLimitsIfAddMpdu (mpdu, txParams, ppduDurationLimit))
371 {
372 // adding MPDU failed, restore protection and acknowledgment methods
373 // if they were swapped
374 if (protectionSwapped)
375 {
376 txParams.m_protection.swap (protection);
377 }
378 if (acknowledgmentSwapped)
379 {
380 txParams.m_acknowledgment.swap (acknowledgment);
381 }
382 return false;
383 }
384
385 // the given MPDU can be added, hence update the txParams
386 txParams.AddMpdu (mpdu);
387 UpdateTxDuration (mpdu->GetHeader ().GetAddr1 (), txParams);
388
389 return true;
390}
391
392bool
394 const WifiTxParameters& txParams,
395 Time ppduDurationLimit) const
396{
397 NS_ASSERT (mpdu);
398 NS_LOG_FUNCTION (this << *mpdu << &txParams << ppduDurationLimit);
399
400 // A QoS station only has to check that the MPDU transmission time does not
401 // exceed the given limit
402 return IsWithinSizeAndTimeLimits (mpdu->GetSize (), mpdu->GetHeader ().GetAddr1 (),
403 txParams, ppduDurationLimit);
404}
405
406bool
408 const WifiTxParameters& txParams,
409 Time ppduDurationLimit) const
410{
411 NS_LOG_FUNCTION (this << ppduPayloadSize << receiver << &txParams << ppduDurationLimit);
412
413 if (ppduDurationLimit != Time::Min () && ppduDurationLimit.IsNegative ())
414 {
415 NS_LOG_DEBUG ("ppduDurationLimit is null or negative, time limit is trivially exceeded");
416 return false;
417 }
418
419 if (ppduPayloadSize > WifiPhy::GetMaxPsduSize (txParams.m_txVector.GetModulationClass ()))
420 {
421 NS_LOG_DEBUG ("the frame exceeds the max PSDU size");
422 return false;
423 }
424
425 // Get the maximum PPDU Duration based on the preamble type
426 Time maxPpduDuration = GetPpduMaxTime (txParams.m_txVector.GetPreambleType ());
427
428 Time txTime = GetTxDuration (ppduPayloadSize, receiver, txParams);
429 NS_LOG_DEBUG ("PPDU duration: " << txTime.As (Time::MS));
430
431 if ((ppduDurationLimit.IsStrictlyPositive () && txTime > ppduDurationLimit)
432 || (maxPpduDuration.IsStrictlyPositive () && txTime > maxPpduDuration))
433 {
434 NS_LOG_DEBUG ("the frame does not meet the constraint on max PPDU duration or PPDU duration limit");
435 return false;
436 }
437
438 return true;
439}
440
441Time
443 const WifiTxParameters& txParams,
444 Ptr<Packet> fragmentedPacket) const
445{
446 NS_LOG_FUNCTION (this << header << size << &txParams << fragmentedPacket);
447
448 // TODO This will be removed once no Txop is installed on a QoS station
449 if (!m_edca)
450 {
451 return FrameExchangeManager::GetFrameDurationId (header, size, txParams, fragmentedPacket);
452 }
453
455 {
456 return FrameExchangeManager::GetFrameDurationId (header, size, txParams, fragmentedPacket);
457 }
458
459 NS_ASSERT (txParams.m_acknowledgment && txParams.m_acknowledgment->acknowledgmentTime != Time::Min ());
460
461 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
462 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
463 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
464 // of 802.11-2016)
466 - m_phy->CalculateTxDuration (size, txParams.m_txVector, m_phy->GetPhyBand ()),
467 txParams.m_acknowledgment->acknowledgmentTime);
468}
469
470Time
471QosFrameExchangeManager::GetRtsDurationId (const WifiTxVector& rtsTxVector, Time txDuration, Time response) const
472{
473 NS_LOG_FUNCTION (this << rtsTxVector << txDuration << response);
474
475 // TODO This will be removed once no Txop is installed on a QoS station
476 if (!m_edca)
477 {
478 return FrameExchangeManager::GetRtsDurationId (rtsTxVector, txDuration, response);
479 }
480
482 {
483 return FrameExchangeManager::GetRtsDurationId (rtsTxVector, txDuration, response);
484 }
485
486 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
487 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
488 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
489 // of 802.11-2016)
491 - m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, m_phy->GetPhyBand ()),
492 Seconds (0));
493}
494
495Time
497 Time txDuration, Time response) const
498{
499 NS_LOG_FUNCTION (this << ctsTxVector << txDuration << response);
500
501 // TODO This will be removed once no Txop is installed on a QoS station
502 if (!m_edca)
503 {
504 return FrameExchangeManager::GetCtsToSelfDurationId (ctsTxVector, txDuration, response);
505 }
506
508 {
509 return FrameExchangeManager::GetCtsToSelfDurationId (ctsTxVector, txDuration, response);
510 }
511
512 // under multiple protection settings, if the TXOP limit is not null, Duration/ID
513 // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
514 // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
515 // of 802.11-2016)
517 - m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, m_phy->GetPhyBand ()),
518 Seconds (0));
519}
520
521void
523{
524 NS_LOG_FUNCTION (this << *mpdu << txVector);
525
526 WifiMacHeader& hdr = mpdu->GetHeader ();
527
528 if (hdr.IsQosData () && m_mac->GetTypeOfStation () == STA
529 && (m_setQosQueueSize || hdr.IsQosEosp ()))
530 {
531 uint8_t tid = hdr.GetQosTid ();
532 hdr.SetQosEosp ();
533 hdr.SetQosQueueSize (m_mac->GetQosTxop (tid)->GetQosQueueSize (tid, hdr.GetAddr1 ()));
534 }
536}
537
538void
540{
541 NS_LOG_DEBUG (this);
542
543 // TODO This will be removed once no Txop is installed on a QoS station
544 if (!m_edca)
545 {
547 return;
548 }
549
552 {
553 NS_LOG_DEBUG ("Schedule another transmission in a SIFS");
555
556 // we are continuing a TXOP, hence the txopDuration parameter is unused
557 Simulator::Schedule (m_phy->GetSifs (), fp, this, m_edca, Seconds (0));
558 }
559 else
560 {
562 m_edca = 0;
563 }
564 m_initialFrame = false;
565}
566
567void
569{
570 NS_LOG_FUNCTION (this);
571
572 // TODO This will be removed once no Txop is installed on a QoS station
573 if (!m_edca)
574 {
576 return;
577 }
578
579 if (m_initialFrame)
580 {
581 // The backoff procedure shall be invoked by an EDCAF when the transmission
582 // of an MPDU in the initial PPDU of a TXOP fails (Sec. 10.22.2.2 of 802.11-2016)
583 NS_LOG_DEBUG ("TX of the initial frame of a TXOP failed: terminate TXOP");
585 m_edca = 0;
586 }
587 else
588 {
590 "Cannot transmit more than one frame if TXOP Limit is zero");
591
592 // A STA can perform a PIFS recovery or perform a backoff as a response to
593 // transmission failure within a TXOP. How it chooses between these two is
594 // implementation dependent. (Sec. 10.22.2.2 of 802.11-2016)
595 if (m_pifsRecovery)
596 {
597 // we can continue the TXOP if the carrier sense mechanism indicates that
598 // the medium is idle in a PIFS
599 NS_LOG_DEBUG ("TX of a non-initial frame of a TXOP failed: perform PIFS recovery");
602 }
603 else
604 {
605 // In order not to terminate (yet) the TXOP, we call the NotifyChannelReleased
606 // method of the Txop class, which only generates a new backoff value and
607 // requests channel access if needed,
608 NS_LOG_DEBUG ("TX of a non-initial frame of a TXOP failed: invoke backoff");
609 m_edca->Txop::NotifyChannelReleased (m_linkId);
611 m_edca = 0;
612 }
613 }
614 m_initialFrame = false;
615}
616
617void
619{
620 NS_LOG_FUNCTION (this << psdu << txVector);
621
622 SetTxopHolder (psdu, txVector);
623
624 // APs store buffer size report of associated stations
625 if (m_mac->GetTypeOfStation () == AP && psdu->GetAddr1 () == m_self)
626 {
627 for (const auto& mpdu : *PeekPointer (psdu))
628 {
629 const WifiMacHeader& hdr = mpdu->GetHeader ();
630
631 if (hdr.IsQosData () && hdr.IsQosEosp ())
632 {
633 NS_LOG_DEBUG ("Station " << hdr.GetAddr2 () << " reported a buffer status of "
634 << +hdr.GetQosQueueSize () << " for tid=" << +hdr.GetQosTid ());
635 StaticCast<ApWifiMac> (m_mac)->SetBufferStatus (hdr.GetQosTid (), hdr.GetAddr2 (), hdr.GetQosQueueSize ());
636 }
637 }
638 }
639
641}
642
643void
645{
646 NS_LOG_FUNCTION (this << psdu << txVector);
647
648 const WifiMacHeader& hdr = psdu->GetHeader (0);
649
650 if (hdr.IsQosData () || hdr.IsMgt () || hdr.IsRts ())
651 {
652 m_txopHolder = psdu->GetAddr2 ();
653 }
654 else if (hdr.IsCts () || hdr.IsAck ())
655 {
656 m_txopHolder = psdu->GetAddr1 ();
657 }
658}
659
660void
662 const WifiTxVector& txVector, bool inAmpdu)
663{
664 // The received MPDU is either broadcast or addressed to this station
665 NS_ASSERT (mpdu->GetHeader ().GetAddr1 ().IsGroup ()
666 || mpdu->GetHeader ().GetAddr1 () == m_self);
667
668 double rxSnr = rxSignalInfo.snr;
669 const WifiMacHeader& hdr = mpdu->GetHeader ();
670
671 if (hdr.IsCfEnd ())
672 {
673 // reset NAV
675 return;
676 }
677
678 if (hdr.IsRts ())
679 {
680 NS_ABORT_MSG_IF (inAmpdu, "Received RTS as part of an A-MPDU");
681
682 // If a non-VHT STA receives an RTS frame with the RA address matching the
683 // MAC address of the STA and the MAC address in the TA field in the RTS
684 // frame matches the saved TXOP holder address, then the STA shall send the
685 // CTS frame after SIFS, without regard for, and without resetting, its NAV.
686 // (sec. 10.22.2.4 of 802.11-2016)
687 if (hdr.GetAddr2 () == m_txopHolder || m_navEnd <= Simulator::Now ())
688 {
689 NS_LOG_DEBUG ("Received RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
691 this, hdr, txVector.GetMode (), rxSnr);
692 }
693 else
694 {
695 NS_LOG_DEBUG ("Received RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
696 }
697 return;
698 }
699
700 if (hdr.IsQosData ())
701 {
702 if (hdr.GetAddr1 () == m_self && hdr.GetQosAckPolicy () == WifiMacHeader::NORMAL_ACK)
703 {
704 NS_LOG_DEBUG ("Received " << hdr.GetTypeString () << " from=" << hdr.GetAddr2 () << ", schedule ACK");
706 this, hdr, txVector, rxSnr);
707 }
708
709 // Forward up the frame if it is not a QoS Null frame
710 if (hdr.HasData ())
711 {
712 m_rxMiddle->Receive (mpdu, m_linkId);
713 }
714
715 // the received data frame has been processed
716 return;
717 }
718
719 return FrameExchangeManager::ReceiveMpdu (mpdu, rxSignalInfo, txVector, inAmpdu);
720}
721
722} //namespace ns3
#define max(a, b)
Definition: 80211b.c:43
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.
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
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 TransmissionSucceeded(void)
Take necessary actions upon a transmission success.
void SendMpduWithProtection(Ptr< WifiMpdu > mpdu, WifiTxParameters &txParams)
Send an MPDU with the given TX parameters (with the specified protection).
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
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.
Ptr< WifiProtectionManager > GetProtectionManager(void) const
Get the Protection Manager used by this node.
virtual void CalculateProtectionTime(WifiProtection *protection) const
Calculate the time required to protect a frame according to the given protection method.
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(void) const
Ptr< MacRxMiddle > m_rxMiddle
the MAC RX Middle on this station
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 TransmissionFailed(void)
Take necessary actions upon a transmission failure.
Ptr< WifiAckManager > GetAckManager(void) const
Get the Acknowledgment Manager used by this node.
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< 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.
virtual void NavResetTimeout(void)
Reset the NAV upon expiration of the NAV reset timer.
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:44
static Mac48Address GetBroadcast(void)
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.
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...
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...
virtual bool SendCfEndIfNeeded(void)
Send a CF-End frame to indicate the completion of the TXOP, provided that the remaining duration is l...
Mac48Address m_txopHolder
MAC address of the TXOP holder.
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 ...
void CancelPifsRecovery(void)
Cancel the PIFS recovery event and have the EDCAF attempting PIFS recovery release the channel.
void TransmissionSucceeded(void) override
Take necessary actions upon a transmission success.
bool m_initialFrame
true if transmitting the initial frame of a TXOP
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...
void TransmissionFailed(void) override
Take necessary actions upon a transmission failure.
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 PifsRecovery(void)
Perform a PIFS recovery as a response to transmission failure within a TXOP.
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...
static TypeId GetTypeId(void)
Get the type ID.
void DoDispose() override
Destructor implementation.
void NotifyChannelReleased(uint8_t linkId) override
Called by the FrameExchangeManager to notify the completion of the transmissions.
Definition: qos-txop.cc:549
virtual Time GetRemainingTxop(uint8_t linkId) const
Return the remaining duration in the current TXOP on the given link.
Definition: qos-txop.cc:564
Ptr< WifiMpdu > PeekNextMpdu(uint8_t linkId, uint8_t tid=8, Mac48Address recipient=Mac48Address::GetBroadcast(), Ptr< WifiMpdu > item=nullptr)
Peek the next frame to transmit on the given link to the given receiver and of the given TID from the...
Definition: qos-txop.cc:354
Ptr< WifiMpdu > GetNextMpdu(uint8_t linkId, Ptr< WifiMpdu > peekedItem, WifiTxParameters &txParams, Time availableTime, bool initialFrame)
Prepare the frame to transmit on the given link starting from the MPDU that has been previously peeke...
Definition: qos-txop.cc:440
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:530
virtual bool IsTxopStarted(uint8_t linkId) const
Return true if a TXOP has started on the given link.
Definition: qos-txop.cc:541
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:555
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:274
@ MS
millisecond
Definition: nstime.h:116
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
bool IsNegative(void) const
Exactly equivalent to t <= 0.
Definition: nstime.h:309
Time GetTxopLimit(void) const
Return the TXOP limit.
Definition: txop.cc:455
virtual void NotifyChannelReleased(uint8_t linkId)
Called by the FrameExchangeManager to notify the completion of the transmissions.
Definition: txop.cc:566
virtual bool IsQosTxop() const
Check for QoS TXOP.
Definition: txop.cc:627
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Implements the IEEE 802.11 MAC header.
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
bool IsAck(void) const
Return true if the header is an Ack header.
bool HasData(void) const
Return true if the header type is DATA and is not DATA_NULL.
bool IsRts(void) const
Return true if the header is a RTS header.
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
bool IsCts(void) const
Return true if the header is a CTS header.
uint32_t GetSize(void) const
Return the size of the WifiMacHeader in octets.
uint8_t GetQosQueueSize(void) const
Get the Queue Size subfield in the QoS control field.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
bool IsCfEnd(void) const
Return true if the header is a CF-End header.
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.
const char * GetTypeString(void) const
Return a string corresponds to the header type.
QosAckPolicy GetQosAckPolicy(void) 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).
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
bool IsMgt(void) const
Return true if the Type is Management.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
bool IsQosEosp(void) const
Return if the end of service period (EOSP) is set.
void SetQosEosp()
Set the end of service period (EOSP) bit in the QoS control field.
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:1568
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:938
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1389
Time GetPifs(void) const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:740
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition: wifi-phy.cc:1410
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:716
const WifiMacHeader & GetHeader(std::size_t i) const
Get the header of the i-th MPDU.
Definition: wifi-psdu.cc:266
Mac48Address GetAddr2(void) const
Get the Transmitter Address (TA), which is common to all the MPDUs.
Definition: wifi-psdu.cc:126
Mac48Address GetAddr1(void) const
Get the Receiver Address (RA), which is common to all the MPDUs.
Definition: wifi-psdu.cc:111
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(void) const
Return true if the timer is running.
void Cancel(void)
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(void) const
WifiModulationClass GetModulationClass(void) 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:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:85
#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:206
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:274
#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:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:794
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:489
@ STA
Definition: wifi-mac.h:59
@ AP
Definition: wifi-mac.h:60
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
uint32_t GetRtsSize(void)
Return the total RTS size (including FCS trailer).
Definition: wifi-utils.cc:100
uint32_t GetCtsSize(void)
Return the total CTS size (including FCS trailer).
Definition: wifi-utils.cc:108
@ WIFI_MAC_CTL_END
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:69
double snr
SNR in linear scale.
Definition: phy-entity.h:70