A Discrete-Event Network Simulator
API
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 .AddTraceSource("TxopTrace",
94 "Trace source for TXOP start and duration times",
96 "ns3::QosTxop::TxopTracedCallback");
97 return tid;
98}
99
102 m_ac(ac)
103{
104 NS_LOG_FUNCTION(this);
105 m_qosBlockedDestinations = Create<QosBlockedDestinations>();
106 m_baManager = CreateObject<BlockAckManager>();
107 m_baManager->SetQueue(m_queue);
108 m_baManager->SetBlockDestinationCallback(
110 m_baManager->SetUnblockDestinationCallback(
112 m_queue->TraceConnectWithoutContext(
113 "Expired",
115}
116
118{
119 NS_LOG_FUNCTION(this);
120}
121
122void
124{
125 NS_LOG_FUNCTION(this);
126 if (m_baManager)
127 {
128 m_baManager->Dispose();
129 }
130 m_baManager = nullptr;
131 m_qosBlockedDestinations = nullptr;
133}
134
135std::unique_ptr<Txop::LinkEntity>
137{
138 return std::make_unique<QosLinkEntity>();
139}
140
142QosTxop::GetLink(uint8_t linkId) const
143{
144 return static_cast<QosLinkEntity&>(Txop::GetLink(linkId));
145}
146
147uint8_t
148QosTxop::GetQosQueueSize(uint8_t tid, Mac48Address receiver) const
149{
150 WifiContainerQueueId queueId{WIFI_QOSDATA_UNICAST_QUEUE, receiver, tid};
151 uint32_t bufferSize = m_queue->GetNBytes(queueId);
152 // A queue size value of 254 is used for all sizes greater than 64 768 octets.
153 uint8_t queueSize = static_cast<uint8_t>(std::ceil(std::min(bufferSize, 64769U) / 256.0));
154 NS_LOG_DEBUG("Buffer size=" << bufferSize << " Queue Size=" << +queueSize);
155 return queueSize;
156}
157
158void
160{
161 NS_LOG_FUNCTION(this << &callback);
163 m_baManager->SetDroppedOldMpduCallback(callback.Bind(WIFI_MAC_DROP_QOS_OLD_PACKET));
164}
165
166void
167QosTxop::SetMuCwMin(uint16_t cwMin, uint8_t linkId)
168{
169 NS_LOG_FUNCTION(this << cwMin << +linkId);
170 GetLink(linkId).muCwMin = cwMin;
171}
172
173void
174QosTxop::SetMuCwMax(uint16_t cwMax, uint8_t linkId)
175{
176 NS_LOG_FUNCTION(this << cwMax << +linkId);
177 GetLink(linkId).muCwMax = cwMax;
178}
179
180void
181QosTxop::SetMuAifsn(uint8_t aifsn, uint8_t linkId)
182{
183 NS_LOG_FUNCTION(this << +aifsn << +linkId);
184 GetLink(linkId).muAifsn = aifsn;
185}
186
187void
188QosTxop::SetMuEdcaTimer(Time timer, uint8_t linkId)
189{
190 NS_LOG_FUNCTION(this << timer << +linkId);
191 GetLink(linkId).muEdcaTimer = timer;
192}
193
194void
196{
197 NS_LOG_FUNCTION(this << +linkId);
198 auto& link = GetLink(linkId);
199 link.muEdcaTimerStartTime = Simulator::Now();
200 if (EdcaDisabled(linkId))
201 {
202 NS_LOG_DEBUG("Disable EDCA for " << link.muEdcaTimer.As(Time::MS));
203 m_mac->GetChannelAccessManager(linkId)->DisableEdcaFor(this, link.muEdcaTimer);
204 }
205}
206
207bool
208QosTxop::MuEdcaTimerRunning(uint8_t linkId) const
209{
210 auto& link = GetLink(linkId);
211 return (link.muEdcaTimerStartTime.IsStrictlyPositive() &&
212 link.muEdcaTimer.IsStrictlyPositive() &&
213 link.muEdcaTimerStartTime + link.muEdcaTimer > Simulator::Now());
214}
215
216bool
217QosTxop::EdcaDisabled(uint8_t linkId) const
218{
219 return (MuEdcaTimerRunning(linkId) && GetLink(linkId).muAifsn == 0);
220}
221
223QosTxop::GetMinCw(uint8_t linkId) const
224{
225 if (!MuEdcaTimerRunning(linkId))
226 {
227 return GetLink(linkId).cwMin;
228 }
229 NS_ASSERT(!EdcaDisabled(linkId));
230 return GetLink(linkId).muCwMin;
231}
232
234QosTxop::GetMaxCw(uint8_t linkId) const
235{
236 if (!MuEdcaTimerRunning(linkId))
237 {
238 return GetLink(linkId).cwMax;
239 }
240 NS_ASSERT(!EdcaDisabled(linkId));
241 return GetLink(linkId).muCwMax;
242}
243
244uint8_t
245QosTxop::GetAifsn(uint8_t linkId) const
246{
247 if (!MuEdcaTimerRunning(linkId))
248 {
249 return GetLink(linkId).aifsn;
250 }
251 return GetLink(linkId).muAifsn;
252}
253
256{
257 return m_baManager;
258}
259
260bool
262{
263 return m_baManager->ExistsAgreementInState(address,
264 tid,
266}
267
268uint16_t
270{
271 return m_baManager->GetRecipientBufferSize(address, tid);
272}
273
274uint16_t
276{
277 return m_baManager->GetOriginatorStartingSequence(address, tid);
278}
279
282{
283 NS_LOG_FUNCTION(this << recipient << +tid);
285
286 CtrlBAckRequestHeader reqHdr = m_baManager->GetBlockAckReqHeader(recipient, tid);
287 Ptr<Packet> bar = Create<Packet>();
288 bar->AddHeader(reqHdr);
289
290 WifiMacHeader hdr;
292 hdr.SetAddr1(recipient);
293 hdr.SetAddr2(m_mac->GetAddress());
294 hdr.SetDsNotTo();
295 hdr.SetDsNotFrom();
296 hdr.SetNoRetry();
297 hdr.SetNoMoreFragments();
298
299 return Create<const WifiMpdu>(bar, hdr);
300}
301
302void
303QosTxop::ScheduleBar(Ptr<const WifiMpdu> bar, bool skipIfNoDataQueued)
304{
305 m_baManager->ScheduleBar(bar, skipIfNoDataQueued);
306}
307
308bool
310{
312}
313
314bool
316{
317 // check if the BA manager has anything to send, so that expired
318 // frames (if any) are removed and a BlockAckRequest is scheduled to advance
319 // the starting sequence number of the transmit (and receiver) window
320 bool baManagerHasPackets{m_baManager->GetBar(false)};
321 // remove MSDUs with expired lifetime starting from the head of the queue
322 m_queue->WipeAllExpiredMpdus();
323 bool queueIsNotEmpty = (bool)(m_queue->PeekFirstAvailable(linkId, m_qosBlockedDestinations));
324
325 NS_LOG_FUNCTION(this << baManagerHasPackets << queueIsNotEmpty);
326 return baManagerHasPackets || queueIsNotEmpty;
327}
328
329uint16_t
331{
332 return m_txMiddle->GetNextSequenceNumberFor(hdr);
333}
334
335uint16_t
337{
338 return m_txMiddle->PeekNextSequenceNumberFor(hdr);
339}
340
341bool
343{
344 NS_LOG_FUNCTION(this << *mpdu);
345
346 if (!mpdu->GetHeader().IsQosData())
347 {
348 return false;
349 }
350
351 Mac48Address recipient = mpdu->GetHeader().GetAddr1();
352 uint8_t tid = mpdu->GetHeader().GetQosTid();
353
354 if (!GetBaAgreementEstablished(recipient, tid))
355 {
356 return false;
357 }
358
359 if (QosUtilsIsOldPacket(GetBaStartingSequence(recipient, tid),
360 mpdu->GetHeader().GetSequenceNumber()))
361 {
362 return true;
363 }
364 return false;
365}
366
368QosTxop::PeekNextMpdu(uint8_t linkId, uint8_t tid, Mac48Address recipient, Ptr<WifiMpdu> item)
369{
370 NS_LOG_FUNCTION(this << +linkId << +tid << recipient << item);
371
372 // lambda to peek the next frame
373 auto peek = [this, &linkId, &tid, &recipient, &item]() -> Ptr<WifiMpdu> {
374 if (tid == 8 && recipient.IsBroadcast()) // undefined TID and recipient
375 {
376 return m_queue->PeekFirstAvailable(linkId, m_qosBlockedDestinations, item);
377 }
378 if (m_qosBlockedDestinations->IsBlocked(recipient, tid))
379 {
380 return nullptr;
381 }
382 return m_queue->PeekByTidAndAddress(tid, recipient, item);
383 };
384
385 item = peek();
386 // remove old packets (must be retransmissions or in flight, otherwise they did
387 // not get a sequence number assigned)
388 while (item && !item->IsFragment())
389 {
390 if ((item->GetHeader().IsRetry() || item->IsInFlight()) && IsQosOldPacket(item))
391 {
392 NS_LOG_DEBUG("Removing an old packet from EDCA queue: " << *item);
394 {
396 }
397 auto oldItem = item;
398 item = peek();
399 m_queue->Remove(oldItem);
400 }
401 else if (item->IsInFlight())
402 {
403 NS_LOG_DEBUG("Skipping in flight MPDU: " << *item);
404 item = peek();
405 }
406 else if (item->GetHeader().HasData() &&
407 !m_mac->CanForwardPacketsTo(item->GetHeader().GetAddr1()))
408 {
409 NS_LOG_DEBUG("Skipping frame that cannot be forwarded: " << *item);
410 item = peek();
411 }
412 else
413 {
414 break;
415 }
416 }
417 if (item)
418 {
419 NS_ASSERT(!item->IsInFlight());
420 WifiMacHeader& hdr = item->GetHeader();
421
422 // peek the next sequence number and check if it is within the transmit window
423 // in case of QoS data frame
424 uint16_t sequence =
425 (hdr.IsRetry() ? hdr.GetSequenceNumber() : m_txMiddle->PeekNextSequenceNumberFor(&hdr));
426 if (hdr.IsQosData())
427 {
428 Mac48Address recipient = hdr.GetAddr1();
429 uint8_t tid = hdr.GetQosTid();
430
431 if (GetBaAgreementEstablished(recipient, tid) &&
432 !IsInWindow(sequence,
433 GetBaStartingSequence(recipient, tid),
434 GetBaBufferSize(recipient, tid)))
435 {
436 NS_LOG_DEBUG("Packet beyond the end of the current transmit window");
437 return nullptr;
438 }
439 }
440
441 // Assign a sequence number if this is not a fragment nor a retransmission
442 if (!item->IsFragment() && !hdr.IsRetry())
443 {
444 hdr.SetSequenceNumber(sequence);
445 }
446 NS_LOG_DEBUG("Packet peeked from EDCA queue: " << *item);
447 return item;
448 }
449
450 return nullptr;
451}
452
454QosTxop::GetNextMpdu(uint8_t linkId,
455 Ptr<WifiMpdu> peekedItem,
456 WifiTxParameters& txParams,
457 Time availableTime,
458 bool initialFrame)
459{
460 NS_ASSERT(peekedItem);
461 NS_LOG_FUNCTION(this << +linkId << *peekedItem << &txParams << availableTime << initialFrame);
462
463 Mac48Address recipient = peekedItem->GetHeader().GetAddr1();
464
465 // The TXOP limit can be exceeded by the TXOP holder if it does not transmit more
466 // than one Data or Management frame in the TXOP and the frame is not in an A-MPDU
467 // consisting of more than one MPDU (Sec. 10.22.2.8 of 802.11-2016)
468 Time actualAvailableTime =
469 (initialFrame && txParams.GetSize(recipient) == 0 ? Time::Min() : availableTime);
470
471 auto qosFem = StaticCast<QosFrameExchangeManager>(m_mac->GetFrameExchangeManager(linkId));
472 if (!qosFem->TryAddMpdu(peekedItem, txParams, actualAvailableTime))
473 {
474 return nullptr;
475 }
476
477 NS_ASSERT(peekedItem->IsQueued());
478 Ptr<WifiMpdu> mpdu;
479
480 // If it is a non-broadcast QoS Data frame and it is not a retransmission nor a fragment,
481 // attempt A-MSDU aggregation
482 if (peekedItem->GetHeader().IsQosData())
483 {
484 uint8_t tid = peekedItem->GetHeader().GetQosTid();
485
486 // we should not be asked to dequeue an MPDU that is beyond the transmit window.
487 // Note that PeekNextMpdu() temporarily assigns the next available sequence number
488 // to the peeked frame
489 NS_ASSERT(!GetBaAgreementEstablished(recipient, tid) ||
490 IsInWindow(peekedItem->GetHeader().GetSequenceNumber(),
491 GetBaStartingSequence(recipient, tid),
492 GetBaBufferSize(recipient, tid)));
493
494 // try A-MSDU aggregation
495 if (m_mac->GetHtSupported() && !recipient.IsBroadcast() &&
496 !peekedItem->GetHeader().IsRetry() && !peekedItem->IsFragment() &&
497 !peekedItem->IsInFlight())
498 {
499 auto htFem = StaticCast<HtFrameExchangeManager>(qosFem);
500 mpdu = htFem->GetMsduAggregator()->GetNextAmsdu(peekedItem, txParams, availableTime);
501 }
502
503 if (mpdu)
504 {
505 NS_LOG_DEBUG("Prepared an MPDU containing an A-MSDU");
506 }
507 // else aggregation was not attempted or failed
508 }
509
510 if (!mpdu)
511 {
512 mpdu = peekedItem;
513 }
514
515 // Assign a sequence number if this is not a fragment nor a retransmission
517 NS_LOG_DEBUG("Got MPDU from EDCA queue: " << *mpdu);
518
519 return mpdu;
520}
521
522void
524{
525 NS_LOG_FUNCTION(this << *mpdu);
526
527 if (!mpdu->IsFragment() && !mpdu->GetHeader().IsRetry() && !mpdu->IsInFlight())
528 {
529 uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor(&mpdu->GetHeader());
530 mpdu->GetHeader().SetSequenceNumber(sequence);
531 }
532}
533
535QosTxop::GetBlockAckReqType(Mac48Address recipient, uint8_t tid) const
536{
537 return m_baManager->GetBlockAckReqType(recipient, tid);
538}
539
541QosTxop::GetBlockAckType(Mac48Address recipient, uint8_t tid) const
542{
543 return m_baManager->GetBlockAckType(recipient, tid);
544}
545
546void
547QosTxop::NotifyChannelAccessed(uint8_t linkId, Time txopDuration)
548{
549 NS_LOG_FUNCTION(this << +linkId << txopDuration);
550
551 NS_ASSERT(txopDuration != Time::Min());
552 GetLink(linkId).startTxop = Simulator::Now();
553 GetLink(linkId).txopDuration = txopDuration;
555}
556
557bool
558QosTxop::IsTxopStarted(uint8_t linkId) const
559{
560 auto& link = GetLink(linkId);
561 NS_LOG_FUNCTION(this << !link.startTxop.IsZero());
562 return (!link.startTxop.IsZero());
563}
564
565void
567{
568 NS_LOG_FUNCTION(this << +linkId);
569 auto& link = GetLink(linkId);
570
571 if (link.startTxop.IsStrictlyPositive())
572 {
573 NS_LOG_DEBUG("Terminating TXOP. Duration = " << Simulator::Now() - link.startTxop);
574 m_txopTrace(link.startTxop, Simulator::Now() - link.startTxop, linkId);
575 }
576 link.startTxop = Seconds(0);
578}
579
580Time
581QosTxop::GetRemainingTxop(uint8_t linkId) const
582{
583 auto& link = GetLink(linkId);
584 NS_ASSERT(link.startTxop.IsStrictlyPositive());
585
586 Time remainingTxop = link.txopDuration;
587 remainingTxop -= (Simulator::Now() - link.startTxop);
588 if (remainingTxop.IsStrictlyNegative())
589 {
590 remainingTxop = Seconds(0);
591 }
592 NS_LOG_FUNCTION(this << remainingTxop);
593 return remainingTxop;
594}
595
596void
598{
599 NS_LOG_FUNCTION(this << respHdr << recipient);
600 uint8_t tid = respHdr->GetTid();
601 if (respHdr->GetStatusCode().IsSuccess())
602 {
603 NS_LOG_DEBUG("block ack agreement established with " << recipient << " tid " << +tid);
604 // A (destination, TID) pair is "blocked" (i.e., no more packets are sent)
605 // when an Add BA Request is sent to the destination. However, when the
606 // Add BA Request timer expires, the (destination, TID) pair is "unblocked"
607 // and packets to the destination are sent again (under normal ack policy).
608 // Thus, there may be a packet needing to be retransmitted when the
609 // Add BA Response is received. In this case, the starting sequence number
610 // shall be set equal to the sequence number of such packet.
611 uint16_t startingSeq = m_txMiddle->GetNextSeqNumberByTidAndAddress(tid, recipient);
612 auto peekedItem = m_queue->PeekByTidAndAddress(tid, recipient);
613 if (peekedItem && peekedItem->GetHeader().IsRetry())
614 {
615 startingSeq = peekedItem->GetHeader().GetSequenceNumber();
616 }
617 m_baManager->UpdateAgreement(respHdr, recipient, startingSeq);
618 }
619 else
620 {
621 NS_LOG_DEBUG("discard ADDBA response" << recipient);
622 m_baManager->NotifyAgreementRejected(recipient, tid);
623 }
624
627 {
628 m_mac->GetChannelAccessManager(SINGLE_LINK_OP_ID)->RequestAccess(this);
629 }
630}
631
632void
634{
635 NS_LOG_FUNCTION(this << delBaHdr << recipient);
636 NS_LOG_DEBUG("received DELBA frame from=" << recipient);
637 m_baManager->DestroyAgreement(recipient, delBaHdr->GetTid());
638}
639
640void
642{
643 NS_ASSERT(mpdu->GetHeader().IsQosData());
644 // If there is an established BA agreement, store the packet in the queue of outstanding packets
645 if (GetBaAgreementEstablished(mpdu->GetHeader().GetAddr1(), mpdu->GetHeader().GetQosTid()))
646 {
647 m_baManager->StorePacket(mpdu);
648 }
649}
650
651void
653{
654 NS_LOG_FUNCTION(this << +threshold);
655 m_blockAckThreshold = threshold;
656 m_baManager->SetBlockAckThreshold(threshold);
657}
658
659void
661{
662 NS_LOG_FUNCTION(this << timeout);
664}
665
666uint8_t
668{
669 NS_LOG_FUNCTION(this);
670 return m_blockAckThreshold;
671}
672
673uint16_t
675{
677}
678
679void
681{
682 NS_LOG_FUNCTION(this << recipient << +tid);
683 // If agreement is still pending, ADDBA response is not received
684 if (m_baManager->ExistsAgreementInState(recipient, tid, OriginatorBlockAckAgreement::PENDING))
685 {
686 m_baManager->NotifyAgreementNoReply(recipient, tid);
691 {
692 m_mac->GetChannelAccessManager(SINGLE_LINK_OP_ID)->RequestAccess(this);
693 }
694 }
695}
696
697void
698QosTxop::ResetBa(Mac48Address recipient, uint8_t tid)
699{
700 NS_LOG_FUNCTION(this << recipient << +tid);
701 // This function is scheduled when waiting for an ADDBA response. However,
702 // before this function is called, a DELBA request may arrive, which causes
703 // the agreement to be deleted. Hence, check if an agreement exists before
704 // notifying that the agreement has to be reset.
705 if (m_baManager->ExistsAgreement(recipient, tid) &&
706 !m_baManager->ExistsAgreementInState(recipient,
707 tid,
709 {
710 m_baManager->NotifyAgreementReset(recipient, tid);
711 }
712}
713
714void
716{
717 NS_LOG_FUNCTION(this << addBaResponseTimeout);
718 m_addBaResponseTimeout = addBaResponseTimeout;
719}
720
721Time
723{
725}
726
727void
729{
730 NS_LOG_FUNCTION(this << failedAddBaTimeout);
731 m_failedAddBaTimeout = failedAddBaTimeout;
732}
733
734Time
736{
738}
739
740bool
742{
743 return true;
744}
745
748{
749 return m_ac;
750}
751
752} // namespace ns3
#define min(a, b)
Definition: 80211b.c:42
void NotifyDiscardedMpdu(Ptr< const WifiMpdu > mpdu)
AttributeValue implementation for Boolean.
Definition: boolean.h:37
auto Bind(BoundArgs... bargs)
Bind a variable number of arguments.
Definition: callback.h:544
bool IsNull() const
Check for null implementation.
Definition: callback.h:556
Headers for BlockAckRequest.
Definition: ctrl-headers.h:51
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:1607
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:1726
uint8_t GetTid() const
Return the Traffic ID (TID).
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void Unblock(Mac48Address dest, uint8_t tid)
Un-block the given destination address and TID (e.g.
void Block(Mac48Address dest, uint8_t tid)
Block the given destination address and TID from sending (e.g.
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:73
QosTxop(AcIndex ac=AC_UNDEF)
Constructor.
Definition: qos-txop.cc:100
std::unique_ptr< LinkEntity > CreateLinkEntity() const override
Create a LinkEntity object.
Definition: qos-txop.cc:136
~QosTxop() override
Definition: qos-txop.cc:117
uint8_t m_blockAckThreshold
the block ack threshold (use BA mechanism if number of packets in queue reaches this value.
Definition: qos-txop.h:498
Ptr< BlockAckManager > GetBaManager()
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:255
Time m_failedAddBaTimeout
timeout after failed BA agreement
Definition: qos-txop.h:505
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:336
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:167
bool UseExplicitBarAfterMissedBlockAck() const
Return true if an explicit BlockAckRequest is sent after a missed BlockAck.
Definition: qos-txop.cc:309
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:217
Time GetAddBaResponseTimeout() const
Get the timeout for ADDBA response.
Definition: qos-txop.cc:722
AcIndex GetAccessCategory() const
Get the access category of this object.
Definition: qos-txop.cc:747
void AddBaResponseTimeout(Mac48Address recipient, uint8_t tid)
Callback when ADDBA response is not received after timeout.
Definition: qos-txop.cc:680
uint16_t GetBaBufferSize(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:269
Ptr< const WifiMpdu > PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:281
void DoDispose() override
Destructor implementation.
Definition: qos-txop.cc:123
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:174
void ScheduleBar(Ptr< const WifiMpdu > bar, bool skipIfNoDataQueued=false)
Definition: qos-txop.cc:303
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:208
void StartMuEdcaTimerNow(uint8_t linkId)
Start the MU EDCA Timer for the given link.
Definition: qos-txop.cc:195
uint8_t GetBlockAckThreshold() const
Return the current threshold for block ack mechanism.
Definition: qos-txop.cc:667
void NotifyChannelReleased(uint8_t linkId) override
Called by the FrameExchangeManager to notify the completion of the transmissions.
Definition: qos-txop.cc:566
uint16_t GetNextSequenceNumberFor(const WifiMacHeader *hdr)
Return the next sequence number for the given header.
Definition: qos-txop.cc:330
uint16_t GetBlockAckInactivityTimeout() const
Get the BlockAck inactivity timeout.
Definition: qos-txop.cc:674
TxopTracedCallback m_txopTrace
TXOP trace callback.
Definition: qos-txop.h:513
virtual Time GetRemainingTxop(uint8_t linkId) const
Return the remaining duration in the current TXOP on the given link.
Definition: qos-txop.cc:581
AcIndex m_ac
the access category
Definition: qos-txop.h:495
void SetDroppedMpduCallback(DroppedMpdu callback) override
Definition: qos-txop.cc:159
bool m_useExplicitBarAfterMissedBlockAck
flag whether explicit BlockAckRequest should be sent upon missed BlockAck Response
Definition: qos-txop.h:506
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:181
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:148
bool GetBaAgreementEstablished(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:261
void ResetBa(Mac48Address recipient, uint8_t tid)
Reset BA agreement after BA negotiation failed.
Definition: qos-txop.cc:698
Time GetFailedAddBaTimeout() const
Get the timeout for failed BA agreement.
Definition: qos-txop.cc:735
BlockAckType GetBlockAckType(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:541
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:523
void SetFailedAddBaTimeout(Time failedAddBaTimeout)
Set the timeout for failed BA agreement.
Definition: qos-txop.cc:728
uint16_t m_blockAckInactivityTimeout
the BlockAck inactivity timeout value (in TUs, i.e.
Definition: qos-txop.h:502
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:368
QosLinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: qos-txop.cc:142
void GotAddBaResponse(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
Event handler when an ADDBA response is received.
Definition: qos-txop.cc:597
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:454
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ack mechanism.
Definition: qos-txop.cc:652
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:342
void GotDelBaFrame(const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
Event handler when a DELBA frame is received.
Definition: qos-txop.cc:633
void SetBlockAckInactivityTimeout(uint16_t timeout)
Set the BlockAck inactivity timeout.
Definition: qos-txop.cc:660
BlockAckReqType GetBlockAckReqType(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:535
void CompleteMpduTx(Ptr< WifiMpdu > mpdu)
Stores an MPDU (part of an A-MPDU) in block ack agreement (i.e.
Definition: qos-txop.cc:641
void SetAddBaResponseTimeout(Time addBaResponseTimeout)
Set the timeout to wait for ADDBA response.
Definition: qos-txop.cc:715
bool HasFramesToTransmit(uint8_t linkId) override
Check if the Txop has frames to transmit over the given link.
Definition: qos-txop.cc:315
uint16_t GetBaStartingSequence(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:275
bool IsQosTxop() const override
Check for QoS TXOP.
Definition: qos-txop.cc:741
Ptr< QosBlockedDestinations > m_qosBlockedDestinations
the QoS blocked destinations
Definition: qos-txop.h:496
Time m_addBaResponseTimeout
timeout for ADDBA response
Definition: qos-txop.h:504
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:547
void SetMuEdcaTimer(Time timer, uint8_t linkId)
Set the MU EDCA Timer for the given link.
Definition: qos-txop.cc:188
Ptr< BlockAckManager > m_baManager
the block ack manager
Definition: qos-txop.h:497
virtual bool IsTxopStarted(uint8_t linkId) const
Return true if a TXOP has started on the given link.
Definition: qos-txop.cc:558
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:1425
Handle packet fragmentation and retransmissions for data and management frames.
Definition: txop.h:71
Ptr< WifiMac > m_mac
the wifi MAC
Definition: txop.h:516
Ptr< WifiMacQueue > m_queue
the wifi MAC queue
Definition: txop.h:514
void DoDispose() override
Destructor implementation.
Definition: txop.cc:157
uint32_t GetMinCw() const
Return the minimum contention window size.
Definition: txop.cc:404
@ NOT_REQUESTED
Definition: txop.h:100
virtual void NotifyChannelReleased(uint8_t linkId)
Called by the FrameExchangeManager to notify the completion of the transmissions.
Definition: txop.cc:585
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: txop.cc:174
DroppedMpdu m_droppedMpduCallback
the dropped MPDU callback
Definition: txop.h:513
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
Definition: txop.cc:209
virtual void GenerateBackoff(uint8_t linkId)
Generate a new backoff for the given link now.
Definition: txop.cc:607
Ptr< MacTxMiddle > m_txMiddle
the MacTxMiddle
Definition: txop.h:515
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:578
uint8_t GetAifsn() const
Return the number of slots that make up an AIFS.
Definition: txop.cc:450
uint32_t GetMaxCw() const
Return the maximum contention window size.
Definition: txop.cc:427
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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.
bool IsRetry() const
Return if the Retry bit is set.
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.
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:230
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1426
#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:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
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:132
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:184
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:74
address
Definition: first.py:40
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:691
std::tuple< WifiContainerQueueType, Mac48Address, uint8_t > WifiContainerQueueId
Tuple (queue type, Address, TID) identifying a container queue.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...
Definition: wifi-utils.h:140
@ WIFI_MAC_CTL_BACKREQ
@ WIFI_QOSDATA_UNICAST_QUEUE
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
Definition: wifi-utils.cc:119
@ WIFI_MAC_DROP_QOS_OLD_PACKET
Definition: wifi-mac.h:77
ns3::Time timeout
The different BlockAckRequest variants.
The different BlockAck variants.