A Discrete-Event Network Simulator
API
wifi-mac-queue-scheduler-impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Stefano Avallone <stavallo@unina.it>
18  */
19 
20 #ifndef WIFI_MAC_QUEUE_SCHEDULER_IMPL_H
21 #define WIFI_MAC_QUEUE_SCHEDULER_IMPL_H
22 
24 #include "wifi-mac-queue.h"
25 #include "wifi-mac.h"
26 
27 #include <algorithm>
28 #include <functional>
29 #include <list>
30 #include <map>
31 #include <numeric>
32 #include <unordered_map>
33 #include <vector>
34 
36 
37 namespace ns3
38 {
39 
40 class WifiMpdu;
41 class WifiMacQueue;
42 
50 template <class Priority, class Compare = std::less<Priority>>
52 {
53  public:
55  friend class ::WifiMacQueueDropOldestTest;
56 
61  static TypeId GetTypeId();
62 
67 
71  std::optional<WifiContainerQueueId> GetNext(AcIndex ac, std::optional<uint8_t> linkId) final;
76  std::optional<WifiContainerQueueId> GetNext(AcIndex ac,
77  std::optional<uint8_t> linkId,
78  const WifiContainerQueueId& prevQueueId) final;
80  std::list<uint8_t> GetLinkIds(AcIndex ac, Ptr<const WifiMpdu> mpdu) final;
83  AcIndex ac,
84  const std::list<WifiContainerQueueType>& types,
85  const Mac48Address& rxAddress,
86  const Mac48Address& txAddress,
87  const std::set<uint8_t>& tids,
88  const std::set<uint8_t>& linkIds) final;
91  AcIndex ac,
92  const std::list<WifiContainerQueueType>& types,
93  const Mac48Address& rxAddress,
94  const Mac48Address& txAddress,
95  const std::set<uint8_t>& tids,
96  const std::set<uint8_t>& linkIds) final;
98  std::optional<Mask> GetQueueLinkMask(AcIndex ac,
99  const WifiContainerQueueId& queueId,
100  uint8_t linkId) final;
104  void NotifyEnqueue(AcIndex ac, Ptr<WifiMpdu> mpdu) final;
106  void NotifyDequeue(AcIndex ac, const std::list<Ptr<WifiMpdu>>& mpdus) final;
108  void NotifyRemove(AcIndex ac, const std::list<Ptr<WifiMpdu>>& mpdus) final;
109 
110  protected:
112  void DoDispose() override;
113 
121  void SetPriority(AcIndex ac, const WifiContainerQueueId& queueId, const Priority& priority);
122 
123  struct QueueInfo;
124 
131  using QueueInfoMap = std::unordered_map<WifiContainerQueueId, QueueInfo>;
132 
134  using QueueInfoPair = std::pair<const WifiContainerQueueId, QueueInfo>;
135 
145  using SortedQueues = std::multimap<Priority, std::reference_wrapper<QueueInfoPair>, Compare>;
146 
150  struct QueueInfo
151  {
152  std::optional<typename SortedQueues::iterator>
155  std::map<uint8_t, Mask> linkIds;
159  };
160 
164  struct PerAcInfo
165  {
169  };
170 
180 
188 
189  private:
201  typename QueueInfoMap::iterator InitQueueInfo(AcIndex ac, Ptr<const WifiMpdu> mpdu);
202 
214  std::optional<WifiContainerQueueId> DoGetNext(AcIndex ac,
215  std::optional<uint8_t> linkId,
216  typename SortedQueues::iterator sortedQueuesIt);
217 
234  virtual void DoNotifyEnqueue(AcIndex ac, Ptr<WifiMpdu> mpdu) = 0;
243  virtual void DoNotifyDequeue(AcIndex ac, const std::list<Ptr<WifiMpdu>>& mpdus) = 0;
252  virtual void DoNotifyRemove(AcIndex ac, const std::list<Ptr<WifiMpdu>>& mpdus) = 0;
253 
268  void DoBlockQueues(bool block,
269  WifiQueueBlockedReason reason,
270  AcIndex ac,
271  const std::list<WifiContainerQueueType>& types,
272  const Mac48Address& rxAddress,
273  const Mac48Address& txAddress,
274  const std::set<uint8_t>& tids,
275  const std::set<uint8_t>& linkIds);
276 
277  std::vector<PerAcInfo> m_perAcInfo{AC_UNDEF};
279 };
280 
285 template <class Priority, class Compare>
287  : NS_LOG_TEMPLATE_DEFINE("WifiMacQueueScheduler")
288 {
289 }
290 
291 template <class Priority, class Compare>
292 TypeId
294 {
295  static TypeId tid = TypeId("ns3::WifiMacQueueSchedulerImpl")
297  .SetGroupName("Wifi");
298  return tid;
299 }
300 
301 template <class Priority, class Compare>
302 void
304 {
305  m_perAcInfo.clear();
307 }
308 
309 template <class Priority, class Compare>
310 void
312 {
313  for (auto ac : {AC_BE, AC_BK, AC_VI, AC_VO, AC_BE_NQOS, AC_BEACON})
314  {
315  if (auto queue = mac->GetTxopQueue(ac); queue != nullptr)
316  {
317  m_perAcInfo.at(ac).wifiMacQueue = queue;
318  queue->SetScheduler(this);
319  }
320  }
322 }
323 
324 template <class Priority, class Compare>
327 {
328  NS_ASSERT(static_cast<uint8_t>(ac) < AC_UNDEF);
329  return m_perAcInfo.at(ac).wifiMacQueue;
330 }
331 
332 template <class Priority, class Compare>
335 {
336  NS_ASSERT(static_cast<uint8_t>(ac) < AC_UNDEF);
337  return m_perAcInfo.at(ac).sortedQueues;
338 }
339 
340 template <class Priority, class Compare>
343 {
344  NS_LOG_FUNCTION(this << ac << *mpdu);
345 
346  auto queueId = WifiMacQueueContainer::GetQueueId(mpdu);
347  // insert queueId in the queue info map if not present yet
348  auto [queueInfoIt, ret] = m_perAcInfo[ac].queueInfoMap.insert({queueId, QueueInfo()});
349 
350  // Initialize/update the set of link IDs depending on the container queue type
351  if (GetMac() && GetMac()->GetNLinks() > 1 &&
352  mpdu->GetHeader().GetAddr2() == GetMac()->GetAddress())
353  {
354  // this is an MLD and the TA field of the frame contains the MLD address,
355  // which means that the frame can be sent on multiple links
356  const auto rxAddr = mpdu->GetHeader().GetAddr1();
357 
358  // this assert checks that the RA field also contain an MLD address, unless
359  // it contains the broadcast address
360  NS_ASSERT_MSG(rxAddr.IsGroup() || GetMac()->GetMldAddress(rxAddr) == rxAddr,
361  "Address 1 (" << rxAddr << ") is not an MLD address");
362 
363  // this assert checks that association (ML setup) has been established
364  // between sender and receiver (unless the receiver is the broadcast address)
365  NS_ASSERT_MSG(GetMac()->CanForwardPacketsTo(rxAddr), "Cannot forward frame to " << rxAddr);
366  // we have to include all the links in case of broadcast frame (we are an AP)
367  // and the links that have been setup with the receiver in case of unicast frame
368  for (const auto linkId : GetMac()->GetLinkIds())
369  {
370  if (rxAddr.IsGroup() ||
371  GetMac()->GetWifiRemoteStationManager(linkId)->GetAffiliatedStaAddress(rxAddr))
372  {
373  // the mask is not modified if linkId is already in the map
374  queueInfoIt->second.linkIds.emplace(linkId, Mask{});
375  }
376  else
377  {
378  // this link is no (longer) setup
379  queueInfoIt->second.linkIds.erase(linkId);
380  }
381  }
382  }
383  else
384  {
385  // the TA field of the frame contains a link address, which means that the
386  // frame can only be sent on the corresponding link
387  auto linkId = GetMac() ? GetMac()->GetLinkIdByAddress(mpdu->GetHeader().GetAddr2())
388  : SINGLE_LINK_OP_ID; // make unit test happy
389  NS_ASSERT(linkId.has_value());
390  auto& linkIdsMap = queueInfoIt->second.linkIds;
391  NS_ASSERT_MSG(linkIdsMap.size() <= 1,
392  "At most one link can be associated with this container queue");
393  // set the link map to contain one entry corresponding to the computed link ID;
394  // unless the link map already contained such an entry (in which case the mask
395  // is preserved)
396  if (linkIdsMap.empty() || linkIdsMap.cbegin()->first != *linkId)
397  {
398  linkIdsMap = {{*linkId, Mask{}}};
399  }
400  }
401 
402  return queueInfoIt;
403 }
404 
405 template <class Priority, class Compare>
406 void
408  const WifiContainerQueueId& queueId,
409  const Priority& priority)
410 {
411  NS_LOG_FUNCTION(this << +ac);
412  NS_ASSERT(static_cast<uint8_t>(ac) < AC_UNDEF);
413 
414  NS_ABORT_MSG_IF(GetWifiMacQueue(ac)->GetNBytes(queueId) == 0,
415  "Cannot set the priority of an empty queue");
416 
417  auto queueInfoIt = m_perAcInfo[ac].queueInfoMap.find(queueId);
418  NS_ASSERT_MSG(queueInfoIt != m_perAcInfo[ac].queueInfoMap.end(),
419  "No queue info for the given container queue");
420  typename SortedQueues::iterator sortedQueuesIt;
421 
422  if (queueInfoIt->second.priorityIt.has_value())
423  {
424  // an element for queueId is present in the set of sorted queues. If the priority
425  // has not changed, do nothing. Otherwise, unlink the node containing such element,
426  // change the priority and insert it back
427  if (queueInfoIt->second.priorityIt.value()->first == priority)
428  {
429  return;
430  }
431 
432  auto handle = m_perAcInfo[ac].sortedQueues.extract(queueInfoIt->second.priorityIt.value());
433  handle.key() = priority;
434  sortedQueuesIt = m_perAcInfo[ac].sortedQueues.insert(std::move(handle));
435  }
436  else
437  {
438  // an element for queueId is not present in the set of sorted queues
439  sortedQueuesIt = m_perAcInfo[ac].sortedQueues.insert({priority, std::ref(*queueInfoIt)});
440  }
441  // update the stored iterator
442  queueInfoIt->second.priorityIt = sortedQueuesIt;
443 }
444 
445 template <class Priority, class Compare>
446 std::list<uint8_t>
448 {
449  auto queueInfoIt = InitQueueInfo(ac, mpdu);
450  std::list<uint8_t> linkIds;
451 
452  // include only links that are not blocked in the returned list
453  for (const auto& [linkId, mask] : queueInfoIt->second.linkIds)
454  {
455  if (mask.none())
456  {
457  linkIds.emplace_back(linkId);
458  }
459  }
460 
461  return linkIds;
462 }
463 
464 template <class Priority, class Compare>
465 void
467  bool block,
468  WifiQueueBlockedReason reason,
469  AcIndex ac,
470  const std::list<WifiContainerQueueType>& types,
471  const Mac48Address& rxAddress,
472  const Mac48Address& txAddress,
473  const std::set<uint8_t>& tids,
474  const std::set<uint8_t>& linkIds)
475 {
476  NS_LOG_FUNCTION(this << block << reason << ac << rxAddress << txAddress);
477  std::list<WifiMacHeader> headers;
478 
479  for (const auto queueType : types)
480  {
481  switch (queueType)
482  {
483  case WIFI_CTL_QUEUE:
484  headers.emplace_back(WIFI_MAC_CTL_BACKREQ);
485  break;
486  case WIFI_MGT_QUEUE:
487  headers.emplace_back(WIFI_MAC_MGT_ACTION);
488  break;
489  case WIFI_QOSDATA_QUEUE:
490  NS_ASSERT_MSG(!tids.empty(),
491  "TID must be specified for queues containing QoS data frames");
492  for (const auto tid : tids)
493  {
494  headers.emplace_back(WIFI_MAC_QOSDATA);
495  headers.back().SetQosTid(tid);
496  }
497  break;
498  case WIFI_DATA_QUEUE:
499  headers.emplace_back(WIFI_MAC_DATA);
500  break;
501  }
502  }
503  for (auto& hdr : headers)
504  {
505  hdr.SetAddr1(rxAddress);
506  hdr.SetAddr2(txAddress);
507 
508  auto queueInfoIt = InitQueueInfo(ac, Create<WifiMpdu>(Create<Packet>(), hdr));
509  for (auto& [linkId, mask] : queueInfoIt->second.linkIds)
510  {
511  if (linkIds.empty() || linkIds.count(linkId) > 0)
512  {
513  mask.set(static_cast<std::size_t>(reason), block);
514  }
515  }
516  }
517 }
518 
519 template <class Priority, class Compare>
520 void
522  WifiQueueBlockedReason reason,
523  AcIndex ac,
524  const std::list<WifiContainerQueueType>& types,
525  const Mac48Address& rxAddress,
526  const Mac48Address& txAddress,
527  const std::set<uint8_t>& tids,
528  const std::set<uint8_t>& linkIds)
529 {
530  DoBlockQueues(true, reason, ac, types, rxAddress, txAddress, tids, linkIds);
531 }
532 
533 template <class Priority, class Compare>
534 void
536  WifiQueueBlockedReason reason,
537  AcIndex ac,
538  const std::list<WifiContainerQueueType>& types,
539  const Mac48Address& rxAddress,
540  const Mac48Address& txAddress,
541  const std::set<uint8_t>& tids,
542  const std::set<uint8_t>& linkIds)
543 {
544  DoBlockQueues(false, reason, ac, types, rxAddress, txAddress, tids, linkIds);
545 }
546 
547 template <class Priority, class Compare>
548 std::optional<WifiMacQueueScheduler::Mask>
550  const WifiContainerQueueId& queueId,
551  uint8_t linkId)
552 {
553  NS_LOG_FUNCTION(this << +ac << +linkId);
554 
555  const auto queueInfoIt = m_perAcInfo[ac].queueInfoMap.find(queueId);
556 
557  if (queueInfoIt == m_perAcInfo[ac].queueInfoMap.cend())
558  {
559  // the given container queue does not exist
560  return std::nullopt;
561  }
562 
563  const auto& linkIds = queueInfoIt->second.linkIds;
564  if (const auto linkIt = linkIds.find(linkId); linkIt != linkIds.cend())
565  {
566  return linkIt->second;
567  }
568 
569  return std::nullopt;
570 }
571 
572 template <class Priority, class Compare>
573 std::optional<WifiContainerQueueId>
575 {
576  NS_LOG_FUNCTION(this << +ac << linkId.has_value());
577  return DoGetNext(ac, linkId, m_perAcInfo[ac].sortedQueues.begin());
578 }
579 
580 template <class Priority, class Compare>
581 std::optional<WifiContainerQueueId>
583  std::optional<uint8_t> linkId,
584  const WifiContainerQueueId& prevQueueId)
585 {
586  NS_LOG_FUNCTION(this << +ac << linkId.has_value());
587 
588  auto queueInfoIt = m_perAcInfo[ac].queueInfoMap.find(prevQueueId);
589  NS_ABORT_IF(queueInfoIt == m_perAcInfo[ac].queueInfoMap.end() ||
590  !queueInfoIt->second.priorityIt.has_value());
591 
592  auto sortedQueuesIt = queueInfoIt->second.priorityIt.value();
593  NS_ABORT_IF(sortedQueuesIt == m_perAcInfo[ac].sortedQueues.end());
594 
595  return DoGetNext(ac, linkId, ++sortedQueuesIt);
596 }
597 
598 template <class Priority, class Compare>
599 std::optional<WifiContainerQueueId>
601  AcIndex ac,
602  std::optional<uint8_t> linkId,
603  typename SortedQueues::iterator sortedQueuesIt)
604 {
605  NS_LOG_FUNCTION(this << +ac << linkId.has_value());
606  NS_ASSERT(static_cast<uint8_t>(ac) < AC_UNDEF);
607 
608  while (sortedQueuesIt != m_perAcInfo[ac].sortedQueues.end())
609  {
610  const auto& queueInfoPair = sortedQueuesIt->second.get();
611  const auto& linkIds = queueInfoPair.second.linkIds;
612  typename std::decay_t<decltype(linkIds)>::const_iterator linkIt;
613 
614  if (!linkId.has_value() ||
615  ((linkIt = linkIds.find(*linkId)) != linkIds.cend() && linkIt->second.none()))
616  {
617  // Packets in this queue can be sent over the link we got channel access on.
618  // Now remove packets with expired lifetime from this queue.
619  // In case the queue becomes empty, the queue is removed from the sorted
620  // list and sortedQueuesIt is invalidated; thus, store an iterator to the
621  // previous queue in the sorted list (if any) to resume the search afterwards.
622  std::optional<typename SortedQueues::iterator> prevQueueIt;
623  if (sortedQueuesIt != m_perAcInfo[ac].sortedQueues.begin())
624  {
625  prevQueueIt = std::prev(sortedQueuesIt);
626  }
627 
628  GetWifiMacQueue(ac)->ExtractExpiredMpdus(queueInfoPair.first);
629 
630  if (GetWifiMacQueue(ac)->GetNBytes(queueInfoPair.first) == 0)
631  {
632  sortedQueuesIt = (prevQueueIt.has_value() ? std::next(prevQueueIt.value())
633  : m_perAcInfo[ac].sortedQueues.begin());
634  continue;
635  }
636  break;
637  }
638 
639  sortedQueuesIt++;
640  }
641 
642  std::optional<WifiContainerQueueId> queueId;
643 
644  if (sortedQueuesIt != m_perAcInfo[ac].sortedQueues.end())
645  {
646  queueId = sortedQueuesIt->second.get().first;
647  }
648  return queueId;
649 }
650 
651 template <class Priority, class Compare>
654 {
655  NS_LOG_FUNCTION(this << +ac << *mpdu);
656  return HasToDropBeforeEnqueuePriv(ac, mpdu);
657 }
658 
659 template <class Priority, class Compare>
660 void
662 {
663  NS_LOG_FUNCTION(this << +ac << *mpdu);
664  NS_ASSERT(static_cast<uint8_t>(ac) < AC_UNDEF);
665 
666  // add information for the queue storing the MPDU to the queue info map, if not present yet
667  auto queueInfoIt = InitQueueInfo(ac, mpdu);
668 
669  DoNotifyEnqueue(ac, mpdu);
670 
671  if (!queueInfoIt->second.priorityIt.has_value())
672  {
673  NS_ABORT_MSG(
674  "No info for the queue the MPDU was stored into (forgot to call SetPriority()?)");
675  }
676 }
677 
678 template <class Priority, class Compare>
679 void
681  const std::list<Ptr<WifiMpdu>>& mpdus)
682 {
683  NS_LOG_FUNCTION(this << +ac);
684  NS_ASSERT(static_cast<uint8_t>(ac) < AC_UNDEF);
685 
686  DoNotifyDequeue(ac, mpdus);
687 
688  std::list<WifiContainerQueueId> queueIds;
689 
690  for (const auto& mpdu : mpdus)
691  {
692  queueIds.push_back(WifiMacQueueContainer::GetQueueId(mpdu));
693  }
694 
695  for (const auto& queueId : queueIds)
696  {
697  if (GetWifiMacQueue(ac)->GetNBytes(queueId) == 0)
698  {
699  // The queue has now become empty and needs to be removed from the sorted
700  // list kept by the scheduler
701  auto queueInfoIt = m_perAcInfo[ac].queueInfoMap.find(queueId);
702  NS_ASSERT(queueInfoIt != m_perAcInfo[ac].queueInfoMap.end());
703  if (queueInfoIt->second.priorityIt.has_value())
704  {
705  m_perAcInfo[ac].sortedQueues.erase(queueInfoIt->second.priorityIt.value());
706  queueInfoIt->second.priorityIt.reset();
707  }
708  }
709  }
710 }
711 
712 template <class Priority, class Compare>
713 void
715  const std::list<Ptr<WifiMpdu>>& mpdus)
716 {
717  NS_LOG_FUNCTION(this << +ac);
718  NS_ASSERT(static_cast<uint8_t>(ac) < AC_UNDEF);
719 
720  DoNotifyRemove(ac, mpdus);
721 
722  std::list<WifiContainerQueueId> queueIds;
723 
724  for (const auto& mpdu : mpdus)
725  {
726  queueIds.push_back(WifiMacQueueContainer::GetQueueId(mpdu));
727  }
728 
729  for (const auto& queueId : queueIds)
730  {
731  if (GetWifiMacQueue(ac)->GetNBytes(queueId) == 0)
732  {
733  // The queue has now become empty and needs to be removed from the sorted
734  // list kept by the scheduler
735  auto queueInfoIt = m_perAcInfo[ac].queueInfoMap.find(queueId);
736  NS_ASSERT(queueInfoIt != m_perAcInfo[ac].queueInfoMap.end());
737  if (queueInfoIt->second.priorityIt.has_value())
738  {
739  m_perAcInfo[ac].sortedQueues.erase(queueInfoIt->second.priorityIt.value());
740  queueInfoIt->second.priorityIt.reset();
741  }
742  }
743  }
744 }
745 
746 } // namespace ns3
747 
748 #endif /* WIFI_MAC_QUEUE_SCHEDULER_IMPL_H */
Test DROP_OLDEST setting.
an EUI-48 address
Definition: mac48-address.h:46
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
static WifiContainerQueueId GetQueueId(Ptr< const WifiMpdu > mpdu)
Return the QueueId identifying the container queue in which the given MPDU is (or is to be) enqueued.
WifiMacQueueScheduler is an abstract base class defining the public interface for a wifi MAC queue sc...
virtual void SetWifiMac(Ptr< WifiMac > mac)
Set the wifi MAC.
std::bitset< static_cast< std::size_t >(WifiQueueBlockedReason::REASONS_COUNT)> Mask
Bitset identifying the reasons to block individual links for a container queue.
void DoDispose() override
Destructor implementation.
WifiMacQueueSchedulerImpl is a template class enabling the definition of different types of priority ...
void DoBlockQueues(bool block, WifiQueueBlockedReason reason, AcIndex ac, const std::list< WifiContainerQueueType > &types, const Mac48Address &rxAddress, const Mac48Address &txAddress, const std::set< uint8_t > &tids, const std::set< uint8_t > &linkIds)
Block or unblock the given set of links for the container queues of the given types and Access Catego...
void UnblockQueues(WifiQueueBlockedReason reason, AcIndex ac, const std::list< WifiContainerQueueType > &types, const Mac48Address &rxAddress, const Mac48Address &txAddress, const std::set< uint8_t > &tids, const std::set< uint8_t > &linkIds) final
Unblock the given set of links for the container queues of the given types and Access Category that h...
std::pair< const WifiContainerQueueId, QueueInfo > QueueInfoPair
typedef for a QueueInfoMap element
std::optional< Mask > GetQueueLinkMask(AcIndex ac, const WifiContainerQueueId &queueId, uint8_t linkId) final
Get the mask associated with the given container queue indicating whether the given link is blocked a...
void SetWifiMac(Ptr< WifiMac > mac) final
Set the wifi MAC.
virtual void DoNotifyDequeue(AcIndex ac, const std::list< Ptr< WifiMpdu >> &mpdus)=0
Notify the scheduler that the given list of MPDUs have been dequeued by the given Access Category.
void DoDispose() override
Destructor implementation.
std::unordered_map< WifiContainerQueueId, QueueInfo > QueueInfoMap
Map identifiers (QueueIds) to information associated with container queues.
void NotifyEnqueue(AcIndex ac, Ptr< WifiMpdu > mpdu) final
Notify the scheduler that the given MPDU has been enqueued by the given Access Category.
void NotifyRemove(AcIndex ac, const std::list< Ptr< WifiMpdu >> &mpdus) final
Notify the scheduler that the given list of MPDUs have been removed by the given Access Category.
void BlockQueues(WifiQueueBlockedReason reason, AcIndex ac, const std::list< WifiContainerQueueType > &types, const Mac48Address &rxAddress, const Mac48Address &txAddress, const std::set< uint8_t > &tids, const std::set< uint8_t > &linkIds) final
Block the given set of links for the container queues of the given types and Access Category that hol...
virtual void DoNotifyEnqueue(AcIndex ac, Ptr< WifiMpdu > mpdu)=0
Notify the scheduler that the given MPDU has been enqueued by the given Access Category.
virtual Ptr< WifiMpdu > HasToDropBeforeEnqueuePriv(AcIndex ac, Ptr< WifiMpdu > mpdu)=0
Check whether an MPDU has to be dropped before enqueuing the given MPDU.
Ptr< WifiMacQueue > GetWifiMacQueue(AcIndex ac) const
Get the wifi MAC queue associated with the given Access Category.
std::list< uint8_t > GetLinkIds(AcIndex ac, Ptr< const WifiMpdu > mpdu) final
Get the list of the IDs of the links the given MPDU (belonging to the given Access Category) can be s...
static TypeId GetTypeId()
Get the type ID.
std::vector< PerAcInfo > m_perAcInfo
vector of per-AC information
std::optional< WifiContainerQueueId > GetNext(AcIndex ac, std::optional< uint8_t > linkId) final
Get the next queue to serve, which is guaranteed to contain at least an MPDU whose lifetime has not e...
const SortedQueues & GetSortedQueues(AcIndex ac) const
Get a const reference to the sorted list of container queues for the given Access Category.
Ptr< WifiMpdu > HasToDropBeforeEnqueue(AcIndex ac, Ptr< WifiMpdu > mpdu) final
Check whether an MPDU has to be dropped before enqueuing the given MPDU.
virtual void DoNotifyRemove(AcIndex ac, const std::list< Ptr< WifiMpdu >> &mpdus)=0
Notify the scheduler that the given list of MPDUs have been removed by the given Access Category.
void NotifyDequeue(AcIndex ac, const std::list< Ptr< WifiMpdu >> &mpdus) final
Notify the scheduler that the given list of MPDUs have been dequeued by the given Access Category.
QueueInfoMap::iterator InitQueueInfo(AcIndex ac, Ptr< const WifiMpdu > mpdu)
If no information for the container queue used to store the given MPDU of the given Access Category i...
std::optional< WifiContainerQueueId > GetNext(AcIndex ac, std::optional< uint8_t > linkId, const WifiContainerQueueId &prevQueueId) final
Get the next queue to serve, which is guaranteed to contain at least an MPDU whose lifetime has not e...
std::multimap< Priority, std::reference_wrapper< QueueInfoPair >, Compare > SortedQueues
List of container queues sorted in decreasing order of priority.
std::optional< WifiContainerQueueId > DoGetNext(AcIndex ac, std::optional< uint8_t > linkId, typename SortedQueues::iterator sortedQueuesIt)
Get the next queue to serve.
void SetPriority(AcIndex ac, const WifiContainerQueueId &queueId, const Priority &priority)
Set the priority for the given container queue belonging to the given Access Category.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_TEMPLATE_DEFINE(name)
Initialize a reference to a Log component.
Definition: log.h:236
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
WifiQueueBlockedReason
Enumeration of the reasons to block container queues.
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:73
@ AC_BE_NQOS
Non-QoS.
Definition: qos-utils.h:83
@ AC_BE
Best Effort.
Definition: qos-utils.h:75
@ AC_VO
Voice.
Definition: qos-utils.h:81
@ AC_VI
Video.
Definition: qos-utils.h:79
@ AC_BK
Background.
Definition: qos-utils.h:77
@ AC_UNDEF
Total number of ACs.
Definition: qos-utils.h:87
@ AC_BEACON
Beacon queue.
Definition: qos-utils.h:85
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::tuple< WifiContainerQueueType, WifiReceiverAddressType, Mac48Address, std::optional< uint8_t > > WifiContainerQueueId
Tuple (queue type, receiver address type, Address, TID) identifying a container queue.
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:192
@ WIFI_MAC_CTL_BACKREQ
@ WIFI_MAC_MGT_ACTION
@ WIFI_MAC_DATA
@ WIFI_MAC_QOSDATA
mac
Definition: third.py:92
#define list
Information specific to a wifi MAC queue.
SortedQueues sortedQueues
sorted list of container queues
Ptr< WifiMacQueue > wifiMacQueue
pointer to the WifiMacQueue object
QueueInfoMap queueInfoMap
information associated with container queues
Information associated with a container queue.
std::map< uint8_t, Mask > linkIds
Maps ID of each link on which packets contained in this queue can be sent to a bitset indicating whet...
std::optional< typename SortedQueues::iterator > priorityIt
iterator pointing to the entry for this queue in the sorted list
uint32_t prev