A Discrete-Event Network Simulator
API
wifi-mac-queue-container.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Universita' degli Studi di Napoli Federico II
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Stefano Avallone <stavallo@unina.it>
18 */
19
21
22#include "wifi-mpdu.h"
23
24#include "ns3/mac48-address.h"
25#include "ns3/simulator.h"
26
27namespace ns3
28{
29
30void
32{
33 m_queues.clear();
34 m_expiredQueue.clear();
35 m_nBytesPerQueue.clear();
36}
37
40{
41 WifiContainerQueueId queueId = GetQueueId(item);
42
43 NS_ABORT_MSG_UNLESS(pos == m_queues[queueId].cend() || GetQueueId(pos->mpdu) == queueId,
44 "pos iterator does not point to the correct container queue");
45
46 auto [it, ret] = m_nBytesPerQueue.insert({queueId, 0});
47 it->second += item->GetSize();
48
49 return m_queues[queueId].emplace(pos, item);
50}
51
54{
55 if (pos->expired)
56 {
57 return m_expiredQueue.erase(pos);
58 }
59
60 WifiContainerQueueId queueId = GetQueueId(pos->mpdu);
61 auto it = m_nBytesPerQueue.find(queueId);
62 NS_ASSERT(it != m_nBytesPerQueue.end());
63 NS_ASSERT(it->second >= pos->mpdu->GetSize());
64 it->second -= pos->mpdu->GetSize();
65
66 return m_queues[queueId].erase(pos);
67}
68
71{
72 return it->mpdu;
73}
74
77{
78 const WifiMacHeader& hdr = mpdu->GetHeader();
79 NS_ABORT_IF(hdr.IsCtl());
80
81 if (hdr.IsMgt())
82 {
84 }
85 if (hdr.IsQosData())
86 {
87 if (hdr.GetAddr1().IsGroup())
88 {
89 return {WIFI_QOSDATA_BROADCAST_QUEUE, hdr.GetAddr2(), hdr.GetQosTid()};
90 }
91 return {WIFI_QOSDATA_UNICAST_QUEUE, hdr.GetAddr1(), hdr.GetQosTid()};
92 }
94}
95
98{
99 return m_queues[queueId];
100}
101
104{
105 if (auto it = m_queues.find(queueId); it == m_queues.end() || it->second.empty())
106 {
107 return 0;
108 }
109 return m_nBytesPerQueue.at(queueId);
110}
111
112std::pair<WifiMacQueueContainer::iterator, WifiMacQueueContainer::iterator>
114{
115 return DoExtractExpiredMpdus(m_queues[queueId]);
116}
117
118std::pair<WifiMacQueueContainer::iterator, WifiMacQueueContainer::iterator>
120{
121 iterator firstExpiredIt = queue.begin();
122 iterator lastExpiredIt = firstExpiredIt;
123 Time now = Simulator::Now();
124
125 while (lastExpiredIt != queue.end() && lastExpiredIt->expiryTime <= now)
126 {
127 lastExpiredIt->expired = true;
128 // this MPDU is no longer queued
129 lastExpiredIt->ac = AC_UNDEF;
130 lastExpiredIt->deleter(lastExpiredIt->mpdu);
131
132 WifiContainerQueueId queueId = GetQueueId(lastExpiredIt->mpdu);
133 auto it = m_nBytesPerQueue.find(queueId);
134 NS_ASSERT(it != m_nBytesPerQueue.end());
135 NS_ASSERT(it->second >= lastExpiredIt->mpdu->GetSize());
136 it->second -= lastExpiredIt->mpdu->GetSize();
137
138 ++lastExpiredIt;
139 }
140
141 if (lastExpiredIt != firstExpiredIt)
142 {
143 // transfer MPDUs with expired lifetime to the tail of m_expiredQueue
144 m_expiredQueue.splice(m_expiredQueue.end(), queue, firstExpiredIt, lastExpiredIt);
145 return {firstExpiredIt, m_expiredQueue.end()};
146 }
147
148 return {m_expiredQueue.end(), m_expiredQueue.end()};
149}
150
151std::pair<WifiMacQueueContainer::iterator, WifiMacQueueContainer::iterator>
153{
154 iterator firstExpiredIt = m_expiredQueue.end();
155
156 for (auto& queue : m_queues)
157 {
158 auto [firstIt, lastIt] = DoExtractExpiredMpdus(queue.second);
159
160 if (firstIt != lastIt && firstExpiredIt == m_expiredQueue.end())
161 {
162 // this is the first queue with MPDUs with expired lifetime
163 firstExpiredIt = firstIt;
164 }
165 }
166 return {firstExpiredIt, m_expiredQueue.end()};
167}
168
169std::pair<WifiMacQueueContainer::iterator, WifiMacQueueContainer::iterator>
171{
172 return {m_expiredQueue.begin(), m_expiredQueue.end()};
173}
174
175} // namespace ns3
176
177/****************************************************
178 * Global Functions (outside namespace ns3)
179 ***************************************************/
180
181std::size_t
183{
184 auto [type, address, tid] = queueId;
185
186 uint8_t buffer[8];
187 buffer[0] = type;
188 address.CopyTo(buffer + 1);
189 buffer[7] = tid;
190
191 std::string s(buffer, buffer + 8);
192 return std::hash<std::string>{}(s);
193}
bool IsGroup() const
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
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.
bool IsMgt() const
Return true if the Type is Management.
bool IsCtl() const
Return true if the Type is Control.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
const ContainerQueue & GetQueue(const WifiContainerQueueId &queueId) const
Get a const reference to the container queue identified by the given QueueId.
void clear()
Erase all elements from the container.
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.
ContainerQueue::iterator iterator
iterator over elements in a container queue
std::unordered_map< WifiContainerQueueId, uint32_t > m_nBytesPerQueue
size in bytes of the container queues
uint32_t GetNBytes(const WifiContainerQueueId &queueId) const
Get the total size of the MPDUs stored in the queue identified by the given QueueId.
Ptr< WifiMpdu > GetItem(const const_iterator it) const
Return the WifiMpdu included in the element pointed to by the given iterator.
std::pair< iterator, iterator > ExtractAllExpiredMpdus() const
Transfer MPDUs with expired lifetime in all the container queues to the container queue storing MPDUs...
iterator insert(const_iterator pos, Ptr< WifiMpdu > item)
Insert the given item at the specified location in the container.
std::unordered_map< WifiContainerQueueId, ContainerQueue > m_queues
the container queues
std::list< WifiMacQueueElem > ContainerQueue
Type of a queue held by the container.
iterator erase(const_iterator pos)
Erase the specified elements from the container.
std::pair< iterator, iterator > GetAllExpiredMpdus() const
Get the range [first, last) of iterators pointing to all the MPDUs queued in the container queue stor...
ContainerQueue::const_iterator const_iterator
const iterator over elements in a container queue
ContainerQueue m_expiredQueue
queue storing MPDUs with expired lifetime
std::pair< iterator, iterator > ExtractExpiredMpdus(const WifiContainerQueueId &queueId) const
Transfer MPDUs with expired lifetime in the container queue identified by the given QueueId to the co...
std::pair< iterator, iterator > DoExtractExpiredMpdus(ContainerQueue &queue) const
Transfer MPDUs with expired lifetime in the given container queue to the container queue storing MPDU...
#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_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
@ AC_UNDEF
Total number of ACs.
Definition: qos-utils.h:88
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::tuple< WifiContainerQueueType, Mac48Address, uint8_t > WifiContainerQueueId
Tuple (queue type, Address, TID) identifying a container queue.
@ WIFI_QOSDATA_UNICAST_QUEUE
@ WIFI_QOSDATA_BROADCAST_QUEUE
#define WIFI_TID_UNDEFINED
Definition: qos-utils.h:37
std::size_t operator()(ns3::WifiContainerQueueId queueId) const
The functor.