A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
qos-utils.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 MIRKO BANCHI
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Mirko Banchi <mk.banchi@gmail.com>
7 * Cecchi Niccolò <insa@igeek.it>
8 */
9
10#include "qos-utils.h"
11
12#include "ctrl-headers.h"
13#include "mgt-action-headers.h"
14#include "wifi-mac-header.h"
15
16#include "ns3/queue-item.h"
17#include "ns3/socket.h"
18
19namespace ns3
20{
21
22std::size_t
24{
25 uint8_t buffer[7];
26 addressTidPair.first.CopyTo(buffer);
27 buffer[6] = addressTidPair.second;
28
29 std::string s(buffer, buffer + 7);
30 return std::hash<std::string>{}(s);
31}
32
33std::size_t
35{
36 uint8_t buffer[6];
37 address.CopyTo(buffer);
38
39 std::string s(buffer, buffer + 6);
40 return std::hash<std::string>{}(s);
41}
42
43WifiAc::WifiAc(uint8_t lowTid, uint8_t highTid)
44 : m_lowTid(lowTid),
45 m_highTid(highTid)
46{
47}
48
49uint8_t
51{
52 return m_lowTid;
53}
54
55uint8_t
57{
58 return m_highTid;
59}
60
61uint8_t
62WifiAc::GetOtherTid(uint8_t tid) const
63{
64 if (tid == m_lowTid)
65 {
66 return m_highTid;
67 }
68 if (tid == m_highTid)
69 {
70 return m_lowTid;
71 }
72 NS_ABORT_MSG("TID " << tid << " does not belong to this AC");
73}
74
75bool
77{
78 NS_ABORT_MSG_IF(left > 3 || right > 3, "Cannot compare non-QoS ACs");
79
80 if (left == right)
81 {
82 return false;
83 }
84 if (left == AC_BK)
85 {
86 return false;
87 }
88 if (right == AC_BK)
89 {
90 return true;
91 }
92 return static_cast<uint8_t>(left) > static_cast<uint8_t>(right);
93}
94
95bool
97{
98 NS_ABORT_MSG_IF(left > 3 || right > 3, "Cannot compare non-QoS ACs");
99
100 return (left == right || left > right);
101}
102
103bool
104operator<(AcIndex left, AcIndex right)
105{
106 return !(left >= right);
107}
108
109bool
110operator<=(AcIndex left, AcIndex right)
111{
112 return !(left > right);
113}
114
115const std::map<AcIndex, WifiAc> wifiAcList = {
116 {AC_BE, {0, 3}},
117 {AC_BK, {1, 2}},
118 {AC_VI, {4, 5}},
119 {AC_VO, {6, 7}},
120};
121
122AcIndex
124{
125 NS_ASSERT_MSG(tid < 8, "Tid " << +tid << " out of range");
126 switch (tid)
127 {
128 case 0:
129 case 3:
130 return AC_BE;
131 case 1:
132 case 2:
133 return AC_BK;
134 case 4:
135 case 5:
136 return AC_VI;
137 case 6:
138 case 7:
139 return AC_VO;
140 }
141 return AC_UNDEF;
142}
143
145QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
146{
147 uint32_t integer = 0;
148 uint16_t numberSeq = (seqControl >> 4) & 0x0fff;
149 integer = (4096 - (endSequence + 1) + numberSeq) % 4096;
150 integer *= 16;
151 integer += (seqControl & 0x000f);
152 return integer;
153}
154
155bool
156QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
157{
158 NS_ASSERT(startingSeq < 4096);
159 NS_ASSERT(seqNumber < 4096);
160 uint16_t distance = ((seqNumber - startingSeq) + 4096) % 4096;
161 return (distance >= 2048);
162}
163
164uint8_t
166{
167 NS_ASSERT(hdr.IsQosData() || packet);
168 if (hdr.IsQosData())
169 {
170 return hdr.GetQosTid();
171 }
172 else if (hdr.IsBlockAckReq())
173 {
174 CtrlBAckRequestHeader baReqHdr;
175 packet->PeekHeader(baReqHdr);
176 return baReqHdr.GetTidInfo();
177 }
178 else if (hdr.IsBlockAck())
179 {
180 CtrlBAckResponseHeader baRespHdr;
181 packet->PeekHeader(baRespHdr);
182 return baRespHdr.GetTidInfo();
183 }
184 else if (hdr.IsMgt() && hdr.IsAction())
185 {
186 Ptr<Packet> pkt = packet->Copy();
187 WifiActionHeader actionHdr;
188 pkt->RemoveHeader(actionHdr);
189
190 if (actionHdr.GetCategory() == WifiActionHeader::BLOCK_ACK)
191 {
192 switch (actionHdr.GetAction().blockAck)
193 {
196 pkt->RemoveHeader(reqHdr);
197 return reqHdr.GetTid();
198 }
201 pkt->RemoveHeader(respHdr);
202 return respHdr.GetTid();
203 }
205 MgtDelBaHeader delHdr;
206 pkt->RemoveHeader(delHdr);
207 return delHdr.GetTid();
208 }
209 default: {
210 NS_FATAL_ERROR("Cannot extract Traffic ID from this BA action frame");
211 }
212 }
213 }
214 else
215 {
216 NS_FATAL_ERROR("Cannot extract Traffic ID from this action frame");
217 }
218 }
219 else
220 {
221 NS_FATAL_ERROR("Packet has no Traffic ID");
222 }
223 return 0; // Silence compiler warning about lack of return value
224}
225
226uint8_t
228{
229 uint8_t dscp;
230 uint8_t priority = 0;
231 if (item->GetUint8Value(QueueItem::IP_DSFIELD, dscp))
232 {
233 // if the QoS map element is implemented, it should be used here
234 // to set the priority.
235 // User priority is set to the three most significant bits of the DS field
236 priority = dscp >> 5;
237 }
238
239 // replace the priority tag
240 SocketPriorityTag priorityTag;
241 priorityTag.SetPriority(priority);
242 item->GetPacket()->ReplacePacketTag(priorityTag);
243
244 // if the admission control were implemented, here we should check whether
245 // the access category assigned to the packet should be downgraded
246
247 return static_cast<uint8_t>(QosUtilsMapTidToAc(priority));
248}
249
250} // namespace ns3
Headers for BlockAckRequest.
uint8_t GetTidInfo() const
Return the Traffic ID (TID).
Headers for BlockAck response.
uint8_t GetTidInfo(std::size_t index=0) const
For Block Ack variants other than Multi-STA Block Ack, get the TID_INFO subfield of the BA Control fi...
an EUI-48 address
Implement the header for management frames of type Add Block Ack request.
uint8_t GetTid() const
Return the Traffic ID (TID).
Implement the header for management frames of type Add Block Ack response.
uint8_t GetTid() const
Return the Traffic ID (TID).
Implement the header for management frames of type Delete Block Ack.
uint8_t GetTid() const
Return the Traffic ID (TID).
Smart pointer class similar to boost::intrusive_ptr.
indicates whether the socket has a priority set.
Definition socket.h:1307
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition socket.cc:843
WifiAc(uint8_t lowTid, uint8_t highTid)
Constructor.
Definition qos-utils.cc:43
uint8_t GetOtherTid(uint8_t tid) const
Given a TID belonging to this Access Category, get the other TID of this AC.
Definition qos-utils.cc:62
uint8_t m_highTid
the TID with higher priority
Definition qos-utils.h:147
uint8_t GetHighTid() const
Get the TID with higher priority.
Definition qos-utils.cc:56
uint8_t GetLowTid() const
Get the TID with lower priority.
Definition qos-utils.cc:50
uint8_t m_lowTid
the TID with lower priority
Definition qos-utils.h:146
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
CategoryValue GetCategory() const
Return the category value.
ActionValue GetAction() const
Return the action value.
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid() const
Return the Traffic ID of a QoS header.
bool IsBlockAckReq() const
Return true if the header is a BlockAckRequest header.
bool IsMgt() const
Return true if the Type is Management.
bool IsAction() const
Return true if the header is an Action header.
bool IsBlockAck() const
Return true if the header is a BlockAck header.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
bool operator>=(const int64x64_t &lhs, const int64x64_t &rhs)
Greater or equal operator.
Definition int64x64.h:162
bool operator<=(const int64x64_t &lhs, const int64x64_t &rhs)
Less or equal operator.
Definition int64x64.h:149
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition length.cc:410
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition qos-utils.cc:123
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:156
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Next function is useful to correctly sort buffered packets under block ack.
Definition qos-utils.cc:145
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr)
This function is useful to get traffic id of different packet types.
Definition qos-utils.cc:165
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition qos-utils.h:62
uint8_t SelectQueueByDSField(Ptr< QueueItem > item)
Determine the TX queue for a given packet.
Definition qos-utils.cc:227
@ AC_BE
Best Effort.
Definition qos-utils.h:64
@ AC_VO
Voice.
Definition qos-utils.h:70
@ AC_VI
Video.
Definition qos-utils.h:68
@ AC_BK
Background.
Definition qos-utils.h:66
@ AC_UNDEF
Total number of ACs.
Definition qos-utils.h:76
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:168
const std::map< AcIndex, WifiAc > wifiAcList
Map containing the four ACs in increasing order of priority (according to Table 10-1 "UP-to-AC Mappin...
Definition qos-utils.cc:115
std::pair< Mac48Address, uint8_t > WifiAddressTidPair
(MAC address, TID) pair
Definition qos-utils.h:25
std::size_t operator()(const Mac48Address &address) const
Functional operator for MAC address hash computation.
Definition qos-utils.cc:34
std::size_t operator()(const WifiAddressTidPair &addressTidPair) const
Functional operator for (MAC address, TID) hash computation.
Definition qos-utils.cc:23
BlockAckActionValue blockAck
block ack