A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
qos-txop.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2006, 2009 INRIA
3 * Copyright (c) 2009 MIRKO BANCHI
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 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 * Mirko Banchi <mk.banchi@gmail.com>
20 * Stefano Avallone <stavalli@unina.it>
21 */
22
23#include "qos-txop.h"
24
26#include "ctrl-headers.h"
27#include "mac-tx-middle.h"
28#include "mgt-headers.h"
29#include "mpdu-aggregator.h"
30#include "msdu-aggregator.h"
32#include "wifi-mac-queue.h"
33#include "wifi-mac-trailer.h"
34#include "wifi-phy.h"
35#include "wifi-psdu.h"
36#include "wifi-tx-parameters.h"
37
38#include "ns3/ht-frame-exchange-manager.h"
39#include "ns3/log.h"
40#include "ns3/pointer.h"
41#include "ns3/random-variable-stream.h"
42#include "ns3/simulator.h"
43
44#undef NS_LOG_APPEND_CONTEXT
45#define NS_LOG_APPEND_CONTEXT \
46 if (m_mac) \
47 { \
48 std::clog << "[mac=" << m_mac->GetAddress() << "] "; \
49 }
50
51namespace ns3
52{
53
55
57
58TypeId
60{
61 static TypeId tid =
62 TypeId("ns3::QosTxop")
64 .SetGroupName("Wifi")
65 .AddConstructor<QosTxop>()
66 .AddAttribute("UseExplicitBarAfterMissedBlockAck",
67 "Specify whether explicit BlockAckRequest should be sent upon missed "
68 "BlockAck Response.",
69 BooleanValue(true),
72 .AddAttribute("AddBaResponseTimeout",
73 "The timeout to wait for ADDBA response after the Ack to "
74 "ADDBA request is received.",
79 .AddAttribute(
80 "FailedAddBaTimeout",
81 "The timeout after a failed BA agreement. During this "
82 "timeout, the originator resumes sending packets using normal "
83 "MPDU. After that, BA agreement is reset and the originator "
84 "will retry BA negotiation.",
88 .AddAttribute("BlockAckManager",
89 "The BlockAckManager object.",
92 MakePointerChecker<BlockAckManager>())
93 .AddAttribute("NMaxInflights",
94 "The maximum number of links (in the range 1-15) on which an MPDU can be "
95 "simultaneously in-flight.",
98 MakeUintegerChecker<uint8_t>(1, 15))
99 .AddTraceSource("TxopTrace",
100 "Trace source for TXOP start and duration times",
102 "ns3::QosTxop::TxopTracedCallback");
103 return tid;
104}
105
108 m_ac(ac)
109{
110 NS_LOG_FUNCTION(this);
111 m_baManager = CreateObject<BlockAckManager>();
112 m_baManager->SetQueue(m_queue);
113 m_baManager->SetBlockDestinationCallback(
114 Callback<void, Mac48Address, uint8_t>([this](Mac48Address recipient, uint8_t tid) {
116 m_ac,
118 recipient,
119 m_mac->GetLocalAddress(recipient),
120 {tid});
121 }));
122 m_baManager->SetUnblockDestinationCallback(
123 Callback<void, Mac48Address, uint8_t>([this](Mac48Address recipient, uint8_t tid) {
125 m_ac,
127 recipient,
128 m_mac->GetLocalAddress(recipient),
129 {tid});
130 }));
131 m_queue->TraceConnectWithoutContext(
132 "Expired",
134}
135
137{
138 NS_LOG_FUNCTION(this);
139}
140
141void
143{
144 NS_LOG_FUNCTION(this);
145 if (m_baManager)
146 {
147 m_baManager->Dispose();
148 }
149 m_baManager = nullptr;
151}
152
153std::unique_ptr<Txop::LinkEntity>
155{
156 return std::make_unique<QosLinkEntity>();
157}
158
160QosTxop::GetLink(uint8_t linkId) const
161{
162 return static_cast<QosLinkEntity&>(Txop::GetLink(linkId));
163}
164
165uint8_t
166QosTxop::GetQosQueueSize(uint8_t tid, Mac48Address receiver) const
167{
169 uint32_t bufferSize = m_queue->GetNBytes(queueId);
170 // A queue size value of 254 is used for all sizes greater than 64 768 octets.
171 uint8_t queueSize = static_cast<uint8_t>(std::ceil(std::min(bufferSize, 64769U) / 256.0));
172 NS_LOG_DEBUG("Buffer size=" << bufferSize << " Queue Size=" << +queueSize);
173 return queueSize;
174}
175
176void
178{
179 NS_LOG_FUNCTION(this << &callback);
181 m_baManager->SetDroppedOldMpduCallback(callback.Bind(WIFI_MAC_DROP_QOS_OLD_PACKET));
182}
183
184void
185QosTxop::SetMuCwMin(uint16_t cwMin, uint8_t linkId)
186{
187 NS_LOG_FUNCTION(this << cwMin << +linkId);
188 GetLink(linkId).muCwMin = cwMin;
189}
190
191void
192QosTxop::SetMuCwMax(uint16_t cwMax, uint8_t linkId)
193{
194 NS_LOG_FUNCTION(this << cwMax << +linkId);
195 GetLink(linkId).muCwMax = cwMax;
196}
197
198void
199QosTxop::SetMuAifsn(uint8_t aifsn, uint8_t linkId)
200{
201 NS_LOG_FUNCTION(this << +aifsn << +linkId);
202 GetLink(linkId).muAifsn = aifsn;
203}
204
205void
206QosTxop::SetMuEdcaTimer(Time timer, uint8_t linkId)
207{
208 NS_LOG_FUNCTION(this << timer << +linkId);
209 GetLink(linkId).muEdcaTimer = timer;
210}
211
212void
214{
215 NS_LOG_FUNCTION(this << +linkId);
216 auto& link = GetLink(linkId);
217 link.muEdcaTimerStartTime = Simulator::Now();
218 if (EdcaDisabled(linkId))
219 {
220 NS_LOG_DEBUG("Disable EDCA for " << link.muEdcaTimer.As(Time::MS));
221 m_mac->GetChannelAccessManager(linkId)->DisableEdcaFor(this, link.muEdcaTimer);
222 }
223}
224
225bool
226QosTxop::MuEdcaTimerRunning(uint8_t linkId) const
227{
228 auto& link = GetLink(linkId);
229 return (link.muEdcaTimerStartTime.IsStrictlyPositive() &&
230 link.muEdcaTimer.IsStrictlyPositive() &&
231 link.muEdcaTimerStartTime + link.muEdcaTimer > Simulator::Now());
232}
233
234bool
235QosTxop::EdcaDisabled(uint8_t linkId) const
236{
237 return (MuEdcaTimerRunning(linkId) && GetLink(linkId).muAifsn == 0);
238}
239
241QosTxop::GetMinCw(uint8_t linkId) const
242{
243 if (!MuEdcaTimerRunning(linkId))
244 {
245 return GetLink(linkId).cwMin;
246 }
247 NS_ASSERT(!EdcaDisabled(linkId));
248 return GetLink(linkId).muCwMin;
249}
250
252QosTxop::GetMaxCw(uint8_t linkId) const
253{
254 if (!MuEdcaTimerRunning(linkId))
255 {
256 return GetLink(linkId).cwMax;
257 }
258 NS_ASSERT(!EdcaDisabled(linkId));
259 return GetLink(linkId).muCwMax;
260}
261
262uint8_t
263QosTxop::GetAifsn(uint8_t linkId) const
264{
265 if (!MuEdcaTimerRunning(linkId))
266 {
267 return GetLink(linkId).aifsn;
268 }
269 return GetLink(linkId).muAifsn;
270}
271
274{
275 return m_baManager;
276}
277
278uint16_t
279QosTxop::GetBaBufferSize(Mac48Address address, uint8_t tid) const
280{
281 return m_baManager->GetRecipientBufferSize(address, tid);
282}
283
284uint16_t
286{
287 return m_baManager->GetOriginatorStartingSequence(address, tid);
288}
289
290std::pair<CtrlBAckRequestHeader, WifiMacHeader>
292{
293 NS_LOG_FUNCTION(this << recipient << +tid);
295
296 auto recipientMld = m_mac->GetMldAddress(recipient);
297
298 CtrlBAckRequestHeader reqHdr =
299 m_baManager->GetBlockAckReqHeader(recipientMld.value_or(recipient), tid);
300
301 WifiMacHeader hdr;
303 hdr.SetAddr1(recipient);
304 hdr.SetAddr2(m_mac->GetLocalAddress(recipient));
305 hdr.SetDsNotTo();
306 hdr.SetDsNotFrom();
307 hdr.SetNoRetry();
308 hdr.SetNoMoreFragments();
309
310 return {reqHdr, hdr};
311}
312
313bool
315{
317}
318
319bool
321{
322 // remove MSDUs with expired lifetime starting from the head of the queue
323 m_queue->WipeAllExpiredMpdus();
324 bool queueIsNotEmpty = (bool)(m_queue->PeekFirstAvailable(linkId));
325
326 NS_LOG_FUNCTION(this << queueIsNotEmpty);
327 return queueIsNotEmpty;
328}
329
330uint16_t
332{
333 return m_txMiddle->GetNextSequenceNumberFor(hdr);
334}
335
336uint16_t
338{
339 return m_txMiddle->PeekNextSequenceNumberFor(hdr);
340}
341
342bool
344{
345 NS_LOG_FUNCTION(this << *mpdu);
346
347 if (!mpdu->GetHeader().IsQosData())
348 {
349 return false;
350 }
351
352 Mac48Address recipient = mpdu->GetHeader().GetAddr1();
353 uint8_t tid = mpdu->GetHeader().GetQosTid();
354
355 if (!m_mac->GetBaAgreementEstablishedAsOriginator(recipient, tid))
356 {
357 return false;
358 }
359
360 return QosUtilsIsOldPacket(GetBaStartingSequence(recipient, tid),
361 mpdu->GetHeader().GetSequenceNumber());
362}
363
365QosTxop::PeekNextMpdu(uint8_t linkId, uint8_t tid, Mac48Address recipient, Ptr<const WifiMpdu> mpdu)
366{
367 NS_LOG_FUNCTION(this << +linkId << +tid << recipient << mpdu);
368
369 // lambda to peek the next frame
370 auto peek = [this, &linkId, &tid, &recipient, &mpdu]() -> Ptr<WifiMpdu> {
371 if (tid == 8 && recipient.IsBroadcast()) // undefined TID and recipient
372 {
373 return m_queue->PeekFirstAvailable(linkId, mpdu);
374 }
375 WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, recipient, tid);
376 if (auto mask = m_mac->GetMacQueueScheduler()->GetQueueLinkMask(m_ac, queueId, linkId);
377 !mask || mask->none())
378 {
379 return m_queue->PeekByQueueId(queueId, mpdu);
380 }
381 return nullptr;
382 };
383
384 auto item = peek();
385 // remove old packets (must be retransmissions or in flight, otherwise they did
386 // not get a sequence number assigned)
387 while (item && !item->IsFragment())
388 {
389 if (item->GetHeader().IsCtl())
390 {
391 NS_LOG_DEBUG("Skipping control frame: " << *item);
392 mpdu = item;
393 item = peek();
394 continue;
395 }
396
397 if (item->HasSeqNoAssigned() && IsQosOldPacket(item))
398 {
399 NS_LOG_DEBUG("Removing an old packet from EDCA queue: " << *item);
401 {
403 }
404 mpdu = item;
405 item = peek();
406 m_queue->Remove(mpdu);
407 continue;
408 }
409
410 if (auto linkIds = item->GetInFlightLinkIds(); !linkIds.empty()) // MPDU is in-flight
411 {
412 // if the MPDU is not already in-flight on the link for which we are requesting an
413 // MPDU and the number of links on which the MPDU is in-flight is less than the
414 // maximum number, then we can transmit this MPDU
415 if (linkIds.count(linkId) == 0 && linkIds.size() < m_nMaxInflights)
416 {
417 break;
418 }
419
420 // if no BA agreement, we cannot have multiple MPDUs in-flight
421 if (item->GetHeader().IsQosData() &&
422 !m_mac->GetBaAgreementEstablishedAsOriginator(item->GetHeader().GetAddr1(),
423 item->GetHeader().GetQosTid()))
424 {
425 NS_LOG_DEBUG("No BA agreement and an MPDU is already in-flight");
426 return nullptr;
427 }
428
429 NS_LOG_DEBUG("Skipping in flight MPDU: " << *item);
430 mpdu = item;
431 item = peek();
432 continue;
433 }
434
435 if (item->GetHeader().HasData() &&
436 !m_mac->CanForwardPacketsTo(item->GetHeader().GetAddr1()))
437 {
438 NS_LOG_DEBUG("Skipping frame that cannot be forwarded: " << *item);
439 mpdu = item;
440 item = peek();
441 continue;
442 }
443 break;
444 }
445
446 if (!item)
447 {
448 return nullptr;
449 }
450
451 WifiMacHeader& hdr = item->GetHeader();
452
453 // peek the next sequence number and check if it is within the transmit window
454 // in case of QoS data frame
455 uint16_t sequence = item->HasSeqNoAssigned() ? hdr.GetSequenceNumber()
456 : m_txMiddle->PeekNextSequenceNumberFor(&hdr);
457 if (hdr.IsQosData())
458 {
459 Mac48Address recipient = hdr.GetAddr1();
460 uint8_t tid = hdr.GetQosTid();
461
462 if (m_mac->GetBaAgreementEstablishedAsOriginator(recipient, tid) &&
463 !IsInWindow(sequence,
464 GetBaStartingSequence(recipient, tid),
465 GetBaBufferSize(recipient, tid)))
466 {
467 NS_LOG_DEBUG("Packet beyond the end of the current transmit window");
468 return nullptr;
469 }
470 }
471
472 // Assign a sequence number if this is not a fragment nor it already has one assigned
473 if (!item->IsFragment() && !item->HasSeqNoAssigned())
474 {
475 hdr.SetSequenceNumber(sequence);
476 }
477 NS_LOG_DEBUG("Packet peeked from EDCA queue: " << *item);
478 return item;
479}
480
482QosTxop::GetNextMpdu(uint8_t linkId,
483 Ptr<WifiMpdu> peekedItem,
484 WifiTxParameters& txParams,
485 Time availableTime,
486 bool initialFrame)
487{
488 NS_ASSERT(peekedItem);
489 NS_LOG_FUNCTION(this << +linkId << *peekedItem << &txParams << availableTime << initialFrame);
490
491 Mac48Address recipient = peekedItem->GetHeader().GetAddr1();
492
493 // The TXOP limit can be exceeded by the TXOP holder if it does not transmit more
494 // than one Data or Management frame in the TXOP and the frame is not in an A-MPDU
495 // consisting of more than one MPDU (Sec. 10.22.2.8 of 802.11-2016)
496 Time actualAvailableTime =
497 (initialFrame && txParams.GetSize(recipient) == 0 ? Time::Min() : availableTime);
498
499 auto qosFem = StaticCast<QosFrameExchangeManager>(m_mac->GetFrameExchangeManager(linkId));
500 if (!qosFem->TryAddMpdu(peekedItem, txParams, actualAvailableTime))
501 {
502 return nullptr;
503 }
504
505 NS_ASSERT(peekedItem->IsQueued());
506 Ptr<WifiMpdu> mpdu;
507
508 // If it is a non-broadcast QoS Data frame and it is not a retransmission nor a fragment,
509 // attempt A-MSDU aggregation
510 if (peekedItem->GetHeader().IsQosData())
511 {
512 uint8_t tid = peekedItem->GetHeader().GetQosTid();
513
514 // we should not be asked to dequeue an MPDU that is beyond the transmit window.
515 // Note that PeekNextMpdu() temporarily assigns the next available sequence number
516 // to the peeked frame
519 peekedItem->GetHeader().GetSequenceNumber(),
520 GetBaStartingSequence(peekedItem->GetOriginal()->GetHeader().GetAddr1(), tid),
521 GetBaBufferSize(peekedItem->GetOriginal()->GetHeader().GetAddr1(), tid)));
522
523 // try A-MSDU aggregation
524 if (m_mac->GetHtSupported() && !recipient.IsBroadcast() &&
525 !peekedItem->HasSeqNoAssigned() && !peekedItem->IsFragment())
526 {
527 auto htFem = StaticCast<HtFrameExchangeManager>(qosFem);
528 mpdu = htFem->GetMsduAggregator()->GetNextAmsdu(peekedItem, txParams, availableTime);
529 }
530
531 if (mpdu)
532 {
533 NS_LOG_DEBUG("Prepared an MPDU containing an A-MSDU");
534 }
535 // else aggregation was not attempted or failed
536 }
537
538 if (!mpdu)
539 {
540 mpdu = peekedItem;
541 }
542
543 // Assign a sequence number if this is not a fragment nor a retransmission
545 NS_LOG_DEBUG("Got MPDU from EDCA queue: " << *mpdu);
546
547 return mpdu;
548}
549
550void
552{
553 NS_LOG_FUNCTION(this << *mpdu);
554
555 if (!mpdu->IsFragment() && !mpdu->HasSeqNoAssigned())
556 {
557 // in case of 11be MLDs, sequence numbers refer to the MLD address
558 auto origMpdu = m_queue->GetOriginal(mpdu);
559 uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor(&origMpdu->GetHeader());
560 mpdu->AssignSeqNo(sequence);
561 }
562}
563
564void
565QosTxop::NotifyChannelAccessed(uint8_t linkId, Time txopDuration)
566{
567 NS_LOG_FUNCTION(this << +linkId << txopDuration);
568
569 NS_ASSERT(txopDuration != Time::Min());
570 GetLink(linkId).startTxop = Simulator::Now();
571 GetLink(linkId).txopDuration = txopDuration;
573}
574
575bool
576QosTxop::IsTxopStarted(uint8_t linkId) const
577{
578 auto& link = GetLink(linkId);
579 NS_LOG_FUNCTION(this << !link.startTxop.IsZero());
580 return (!link.startTxop.IsZero());
581}
582
583void
585{
586 NS_LOG_FUNCTION(this << +linkId);
587 auto& link = GetLink(linkId);
588
589 if (link.startTxop.IsStrictlyPositive())
590 {
591 NS_LOG_DEBUG("Terminating TXOP. Duration = " << Simulator::Now() - link.startTxop);
592 m_txopTrace(link.startTxop, Simulator::Now() - link.startTxop, linkId);
593 }
594 link.startTxop = Seconds(0);
596}
597
598Time
599QosTxop::GetRemainingTxop(uint8_t linkId) const
600{
601 auto& link = GetLink(linkId);
602 NS_ASSERT(link.startTxop.IsStrictlyPositive());
603
604 Time remainingTxop = link.txopDuration;
605 remainingTxop -= (Simulator::Now() - link.startTxop);
606 if (remainingTxop.IsStrictlyNegative())
607 {
608 remainingTxop = Seconds(0);
609 }
610 NS_LOG_FUNCTION(this << remainingTxop);
611 return remainingTxop;
612}
613
614void
616{
617 NS_LOG_FUNCTION(this << respHdr << recipient);
618 uint8_t tid = respHdr.GetTid();
619 if (respHdr.GetStatusCode().IsSuccess())
620 {
621 NS_LOG_DEBUG("block ack agreement established with " << recipient << " tid " << +tid);
622 // A (destination, TID) pair is "blocked" (i.e., no more packets are sent)
623 // when an Add BA Request is sent to the destination. However, when the
624 // Add BA Request timer expires, the (destination, TID) pair is "unblocked"
625 // and packets to the destination are sent again (under normal ack policy).
626 // Thus, there may be a packet needing to be retransmitted when the
627 // Add BA Response is received. In this case, the starting sequence number
628 // shall be set equal to the sequence number of such packet.
629 uint16_t startingSeq = m_txMiddle->GetNextSeqNumberByTidAndAddress(tid, recipient);
630 auto peekedItem = m_queue->PeekByTidAndAddress(tid, recipient);
631 if (peekedItem && peekedItem->GetHeader().IsRetry())
632 {
633 startingSeq = peekedItem->GetHeader().GetSequenceNumber();
634 }
635 m_baManager->UpdateOriginatorAgreement(respHdr, recipient, startingSeq);
636 }
637 else
638 {
639 NS_LOG_DEBUG("discard ADDBA response" << recipient);
640 m_baManager->NotifyOriginatorAgreementRejected(recipient, tid);
641 }
642
643 for (uint8_t linkId = 0; linkId < GetNLinks(); linkId++)
644 {
645 StartAccessIfNeeded(linkId);
646 }
647}
648
649void
651{
652 NS_LOG_FUNCTION(this << delBaHdr << recipient);
653 NS_LOG_DEBUG("received DELBA frame from=" << recipient);
654 m_baManager->DestroyOriginatorAgreement(recipient, delBaHdr->GetTid());
655}
656
657void
659{
660 NS_LOG_FUNCTION(this << recipient << tid);
661
662 m_baManager->NotifyOriginatorAgreementNoReply(recipient, tid);
663 // the recipient has been "unblocked" and transmissions can resume using normal
664 // acknowledgment, hence start access (if needed) on all the links
665 for (uint8_t linkId = 0; linkId < GetNLinks(); linkId++)
666 {
667 StartAccessIfNeeded(linkId);
668 }
669}
670
671void
673{
674 NS_ASSERT(mpdu->GetHeader().IsQosData());
675 // If there is an established BA agreement, store the packet in the queue of outstanding packets
676 if (m_mac->GetBaAgreementEstablishedAsOriginator(mpdu->GetHeader().GetAddr1(),
677 mpdu->GetHeader().GetQosTid()))
678 {
679 NS_ASSERT(mpdu->IsQueued());
680 NS_ASSERT(m_queue->GetAc() == mpdu->GetQueueAc());
681 m_baManager->StorePacket(m_queue->GetOriginal(mpdu));
682 }
683}
684
685void
687{
688 NS_LOG_FUNCTION(this << +threshold);
689 m_blockAckThreshold = threshold;
690 m_baManager->SetBlockAckThreshold(threshold);
691}
692
693void
695{
696 NS_LOG_FUNCTION(this << timeout);
698}
699
700uint8_t
702{
703 NS_LOG_FUNCTION(this);
704 return m_blockAckThreshold;
705}
706
707uint16_t
709{
711}
712
713void
715{
716 NS_LOG_FUNCTION(this << recipient << +tid);
717 // If agreement is still pending, ADDBA response is not received
718 if (auto agreement = m_baManager->GetAgreementAsOriginator(recipient, tid);
719 agreement && agreement->get().IsPending())
720 {
721 NotifyOriginatorAgreementNoReply(recipient, tid);
723 }
724}
725
726void
727QosTxop::ResetBa(Mac48Address recipient, uint8_t tid)
728{
729 NS_LOG_FUNCTION(this << recipient << +tid);
730 // This function is scheduled when waiting for an ADDBA response. However,
731 // before this function is called, a DELBA request may arrive, which causes
732 // the agreement to be deleted. Hence, check if an agreement exists before
733 // notifying that the agreement has to be reset.
734 if (auto agreement = m_baManager->GetAgreementAsOriginator(recipient, tid);
735 agreement && !agreement->get().IsEstablished())
736 {
737 m_baManager->NotifyOriginatorAgreementReset(recipient, tid);
738 }
739}
740
741void
743{
744 NS_LOG_FUNCTION(this << addBaResponseTimeout);
745 m_addBaResponseTimeout = addBaResponseTimeout;
746}
747
748Time
750{
752}
753
754void
756{
757 NS_LOG_FUNCTION(this << failedAddBaTimeout);
758 m_failedAddBaTimeout = failedAddBaTimeout;
759}
760
761Time
763{
765}
766
767bool
769{
770 return true;
771}
772
775{
776 return m_ac;
777}
778
779} // namespace ns3
void NotifyDiscardedMpdu(Ptr< const WifiMpdu > mpdu)
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:438
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
auto Bind(BoundArgs &&... bargs)
Bind a variable number of arguments.
Definition: callback.h:555
void DisableEdcaFor(Ptr< Txop > qosTxop, Time duration)
Headers for BlockAckRequest.
Definition: ctrl-headers.h:52
an EUI-48 address
Definition: mac48-address.h:46
bool IsBroadcast() const
Implement the header for management frames of type Add Block Ack response.
Definition: mgt-headers.h:926
StatusCode GetStatusCode() const
Return the status code.
uint8_t GetTid() const
Return the Traffic ID (TID).
Implement the header for management frames of type Delete Block Ack.
Definition: mgt-headers.h:1045
uint8_t GetTid() const
Return the Traffic ID (TID).
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:72
QosTxop(AcIndex ac=AC_UNDEF)
Constructor.
Definition: qos-txop.cc:106
std::unique_ptr< LinkEntity > CreateLinkEntity() const override
Create a LinkEntity object.
Definition: qos-txop.cc:154
~QosTxop() override
Definition: qos-txop.cc:136
uint8_t m_blockAckThreshold
the block ack threshold (use BA mechanism if number of packets in queue reaches this value.
Definition: qos-txop.h:469
Ptr< BlockAckManager > GetBaManager()
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:273
Time m_failedAddBaTimeout
timeout after failed BA agreement
Definition: qos-txop.h:476
Ptr< WifiMpdu > PeekNextMpdu(uint8_t linkId, uint8_t tid=8, Mac48Address recipient=Mac48Address::GetBroadcast(), Ptr< const WifiMpdu > mpdu=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:365
uint16_t PeekNextSequenceNumberFor(const WifiMacHeader *hdr)
Return the next sequence number for the Traffic ID and destination, but do not pick it (i....
Definition: qos-txop.cc:337
void SetMuCwMin(uint16_t cwMin, uint8_t linkId)
Set the minimum contention window size to use while the MU EDCA Timer is running for the given link.
Definition: qos-txop.cc:185
bool UseExplicitBarAfterMissedBlockAck() const
Return true if an explicit BlockAckRequest is sent after a missed BlockAck.
Definition: qos-txop.cc:314
bool EdcaDisabled(uint8_t linkId) const
Return true if the EDCA is disabled (the MU EDCA Timer is running and the MU AIFSN is zero) for the g...
Definition: qos-txop.cc:235
Time GetAddBaResponseTimeout() const
Get the timeout for ADDBA response.
Definition: qos-txop.cc:749
AcIndex GetAccessCategory() const
Get the access category of this object.
Definition: qos-txop.cc:774
void AddBaResponseTimeout(Mac48Address recipient, uint8_t tid)
Callback when ADDBA response is not received after timeout.
Definition: qos-txop.cc:714
uint16_t GetBaBufferSize(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:279
void DoDispose() override
Destructor implementation.
Definition: qos-txop.cc:142
void SetMuCwMax(uint16_t cwMax, uint8_t linkId)
Set the maximum contention window size to use while the MU EDCA Timer is running for the given link.
Definition: qos-txop.cc:192
bool MuEdcaTimerRunning(uint8_t linkId) const
Return true if the MU EDCA Timer is running for the given link, false otherwise.
Definition: qos-txop.cc:226
void StartMuEdcaTimerNow(uint8_t linkId)
Start the MU EDCA Timer for the given link.
Definition: qos-txop.cc:213
uint8_t GetBlockAckThreshold() const
Return the current threshold for block ack mechanism.
Definition: qos-txop.cc:701
void NotifyChannelReleased(uint8_t linkId) override
Called by the FrameExchangeManager to notify the completion of the transmissions.
Definition: qos-txop.cc:584
uint16_t GetNextSequenceNumberFor(const WifiMacHeader *hdr)
Return the next sequence number for the given header.
Definition: qos-txop.cc:331
uint16_t GetBlockAckInactivityTimeout() const
Get the BlockAck inactivity timeout.
Definition: qos-txop.cc:708
TxopTracedCallback m_txopTrace
TXOP trace callback.
Definition: qos-txop.h:487
virtual Time GetRemainingTxop(uint8_t linkId) const
Return the remaining duration in the current TXOP on the given link.
Definition: qos-txop.cc:599
AcIndex m_ac
the access category
Definition: qos-txop.h:467
void SetDroppedMpduCallback(DroppedMpdu callback) override
Definition: qos-txop.cc:177
bool m_useExplicitBarAfterMissedBlockAck
flag whether explicit BlockAckRequest should be sent upon missed BlockAck Response
Definition: qos-txop.h:477
void SetMuAifsn(uint8_t aifsn, uint8_t linkId)
Set the number of slots that make up an AIFS while the MU EDCA Timer is running for the given link.
Definition: qos-txop.cc:199
void NotifyOriginatorAgreementNoReply(const Mac48Address &recipient, uint8_t tid)
Take action upon notification of ADDBA_REQUEST frame being discarded (likely due to exceeded max retr...
Definition: qos-txop.cc:658
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 ResetBa(Mac48Address recipient, uint8_t tid)
Reset BA agreement after BA negotiation failed.
Definition: qos-txop.cc:727
Time GetFailedAddBaTimeout() const
Get the timeout for failed BA agreement.
Definition: qos-txop.cc:762
void GotAddBaResponse(const MgtAddBaResponseHeader &respHdr, Mac48Address recipient)
Event handler when an ADDBA response is received.
Definition: qos-txop.cc:615
static TypeId GetTypeId()
Get the type ID.
Definition: qos-txop.cc:59
void AssignSequenceNumber(Ptr< WifiMpdu > mpdu) const
Assign a sequence number to the given MPDU, if it is not a fragment and it is not a retransmitted fra...
Definition: qos-txop.cc:551
void SetFailedAddBaTimeout(Time failedAddBaTimeout)
Set the timeout for failed BA agreement.
Definition: qos-txop.cc:755
uint16_t m_blockAckInactivityTimeout
the BlockAck inactivity timeout value (in TUs, i.e.
Definition: qos-txop.h:473
QosLinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: qos-txop.cc:160
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:482
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ack mechanism.
Definition: qos-txop.cc:686
bool IsQosOldPacket(Ptr< const WifiMpdu > mpdu)
Check if the given MPDU is to be considered old according to the current starting sequence number of ...
Definition: qos-txop.cc:343
void GotDelBaFrame(const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
Event handler when a DELBA frame is received.
Definition: qos-txop.cc:650
void SetBlockAckInactivityTimeout(uint16_t timeout)
Set the BlockAck inactivity timeout.
Definition: qos-txop.cc:694
uint8_t m_nMaxInflights
the maximum number of links on which an MPDU can be in-flight at the same time
Definition: qos-txop.h:479
void CompleteMpduTx(Ptr< WifiMpdu > mpdu)
Stores an MPDU (part of an A-MPDU) in block ack agreement (i.e.
Definition: qos-txop.cc:672
void SetAddBaResponseTimeout(Time addBaResponseTimeout)
Set the timeout to wait for ADDBA response.
Definition: qos-txop.cc:742
std::pair< CtrlBAckRequestHeader, WifiMacHeader > PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:291
bool HasFramesToTransmit(uint8_t linkId) override
Check if the Txop has frames to transmit over the given link.
Definition: qos-txop.cc:320
uint16_t GetBaStartingSequence(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:285
bool IsQosTxop() const override
Check for QoS TXOP.
Definition: qos-txop.cc:768
Time m_addBaResponseTimeout
timeout for ADDBA response
Definition: qos-txop.h:475
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
void SetMuEdcaTimer(Time timer, uint8_t linkId)
Set the MU EDCA Timer for the given link.
Definition: qos-txop.cc:206
Ptr< BlockAckManager > m_baManager
the block ack manager
Definition: qos-txop.h:468
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
bool IsSuccess() const
Return whether the status code is success.
Definition: status-code.cc:42
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
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 IsStrictlyNegative() const
Exactly equivalent to t < 0.
Definition: nstime.h:341
AttributeValue implementation for Time.
Definition: nstime.h:1423
Handle packet fragmentation and retransmissions for data and management frames.
Definition: txop.h:71
virtual void StartAccessIfNeeded(uint8_t linkId)
Request access from Txop on the given link if needed.
Definition: txop.cc:538
Ptr< WifiMac > m_mac
the wifi MAC
Definition: txop.h:517
Ptr< WifiMacQueue > m_queue
the wifi MAC queue
Definition: txop.h:515
void DoDispose() override
Destructor implementation.
Definition: txop.cc:153
uint32_t GetMinCw() const
Return the minimum contention window size.
Definition: txop.cc:400
virtual void NotifyChannelReleased(uint8_t linkId)
Called by the FrameExchangeManager to notify the completion of the transmissions.
Definition: txop.cc:579
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: txop.cc:170
DroppedMpdu m_droppedMpduCallback
the dropped MPDU callback
Definition: txop.h:514
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
Definition: txop.cc:205
Ptr< MacTxMiddle > m_txMiddle
the MacTxMiddle
Definition: txop.h:516
virtual void NotifyChannelAccessed(uint8_t linkId, Time txopDuration=Seconds(0))
Called by the FrameExchangeManager to notify that channel access has been granted on the given link f...
Definition: txop.cc:572
uint8_t GetAifsn() const
Return the number of slots that make up an AIFS.
Definition: txop.cc:446
uint32_t GetMaxCw() const
Return the maximum contention window size.
Definition: txop.cc:423
uint8_t GetNLinks() const
Get the number of links.
Definition: txop.cc:178
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid() const
Return the Traffic ID of a QoS header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
uint16_t GetSequenceNumber() const
Return the sequence number of the header.
void SetNoMoreFragments()
Un-set the More Fragment bit in the Frame Control Field.
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
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 SetDsNotTo()
Un-set the To DS bit in the Frame Control field.
void SetNoRetry()
Un-set the Retry bit in the Frame Control field.
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Definition: wifi-mac.cc:864
std::optional< Mac48Address > GetMldAddress(const Mac48Address &remoteAddr) const
Definition: wifi-mac.cc:1358
Ptr< WifiMacQueueScheduler > GetMacQueueScheduler() const
Get the wifi MAC queue scheduler.
Definition: wifi-mac.cc:574
bool GetHtSupported() const
Return whether the device supports HT.
Definition: wifi-mac.cc:1487
Mac48Address GetLocalAddress(const Mac48Address &remoteAddr) const
Get the local MAC address used to communicate with a remote STA.
Definition: wifi-mac.cc:1371
OriginatorAgreementOptConstRef GetBaAgreementEstablishedAsOriginator(Mac48Address recipient, uint8_t tid) const
Definition: wifi-mac.cc:1405
virtual bool CanForwardPacketsTo(Mac48Address to) const =0
Return true if packets can be forwarded to the given destination, false otherwise.
Ptr< ChannelAccessManager > GetChannelAccessManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Channel Access Manager associated with the given link.
Definition: wifi-mac.cc:870
This queue implements the timeout procedure described in (Section 9.19.2.6 "Retransmit procedures" pa...
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
#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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#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(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:579
#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
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:134
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet.
Definition: qos-utils.cc:182
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:72
@ WIFI_MAC_DROP_QOS_OLD_PACKET
Definition: wifi-mac.h:79
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:702
std::tuple< WifiContainerQueueType, WifiReceiverAddressType, Mac48Address, std::optional< uint8_t > > WifiContainerQueueId
Tuple (queue type, receiver address type, Address, TID) identifying a container queue.
@ WIFI_MAC_CTL_BACKREQ
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
Definition: wifi-utils.cc:119
ns3::Time timeout