A Discrete-Event Network Simulator
API
qos-utils.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 MIRKO BANCHI
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  * Authors: Mirko Banchi <mk.banchi@gmail.com>
18  * Cecchi Niccolò <insa@igeek.it>
19  */
20 
21 #include "qos-utils.h"
22 
23 #include "ctrl-headers.h"
24 #include "mgt-headers.h"
25 #include "wifi-mac-header.h"
26 
27 #include "ns3/queue-item.h"
28 #include "ns3/socket.h"
29 
30 namespace ns3
31 {
32 
33 std::size_t
35 {
36  uint8_t buffer[7];
37  addressTidPair.first.CopyTo(buffer);
38  buffer[6] = addressTidPair.second;
39 
40  std::string s(buffer, buffer + 7);
41  return std::hash<std::string>{}(s);
42 }
43 
44 std::size_t
46 {
47  uint8_t buffer[6];
48  address.CopyTo(buffer);
49 
50  std::string s(buffer, buffer + 6);
51  return std::hash<std::string>{}(s);
52 }
53 
54 WifiAc::WifiAc(uint8_t lowTid, uint8_t highTid)
55  : m_lowTid(lowTid),
56  m_highTid(highTid)
57 {
58 }
59 
60 uint8_t
62 {
63  return m_lowTid;
64 }
65 
66 uint8_t
68 {
69  return m_highTid;
70 }
71 
72 uint8_t
73 WifiAc::GetOtherTid(uint8_t tid) const
74 {
75  if (tid == m_lowTid)
76  {
77  return m_highTid;
78  }
79  if (tid == m_highTid)
80  {
81  return m_lowTid;
82  }
83  NS_ABORT_MSG("TID " << tid << " does not belong to this AC");
84 }
85 
86 bool
88 {
89  NS_ABORT_MSG_IF(left > 3 || right > 3, "Cannot compare non-QoS ACs");
90 
91  if (left == right)
92  {
93  return false;
94  }
95  if (left == AC_BK)
96  {
97  return false;
98  }
99  if (right == AC_BK)
100  {
101  return true;
102  }
103  return static_cast<uint8_t>(left) > static_cast<uint8_t>(right);
104 }
105 
106 bool
108 {
109  NS_ABORT_MSG_IF(left > 3 || right > 3, "Cannot compare non-QoS ACs");
110 
111  return (left == right || left > right);
112 }
113 
114 bool
115 operator<(AcIndex left, AcIndex right)
116 {
117  return !(left >= right);
118 }
119 
120 bool
121 operator<=(AcIndex left, AcIndex right)
122 {
123  return !(left > right);
124 }
125 
126 const std::map<AcIndex, WifiAc> wifiAcList = {
127  {AC_BE, {0, 3}},
128  {AC_BK, {1, 2}},
129  {AC_VI, {4, 5}},
130  {AC_VO, {6, 7}},
131 };
132 
133 AcIndex
134 QosUtilsMapTidToAc(uint8_t tid)
135 {
136  NS_ASSERT_MSG(tid < 8, "Tid " << +tid << " out of range");
137  switch (tid)
138  {
139  case 0:
140  case 3:
141  return AC_BE;
142  break;
143  case 1:
144  case 2:
145  return AC_BK;
146  break;
147  case 4:
148  case 5:
149  return AC_VI;
150  break;
151  case 6:
152  case 7:
153  return AC_VO;
154  break;
155  }
156  return AC_UNDEF;
157 }
158 
159 uint8_t
161 {
162  SocketPriorityTag qos;
163  uint8_t tid = 8;
164  if (packet->PeekPacketTag(qos))
165  {
166  if (qos.GetPriority() < 8)
167  {
168  tid = qos.GetPriority();
169  }
170  }
171  return tid;
172 }
173 
174 uint32_t
175 QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
176 {
177  uint32_t integer = 0;
178  uint16_t numberSeq = (seqControl >> 4) & 0x0fff;
179  integer = (4096 - (endSequence + 1) + numberSeq) % 4096;
180  integer *= 16;
181  integer += (seqControl & 0x000f);
182  return integer;
183 }
184 
185 bool
186 QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
187 {
188  NS_ASSERT(startingSeq < 4096);
189  NS_ASSERT(seqNumber < 4096);
190  uint16_t distance = ((seqNumber - startingSeq) + 4096) % 4096;
191  return (distance >= 2048);
192 }
193 
194 uint8_t
196 {
197  NS_ASSERT(hdr.IsQosData() || packet);
198  if (hdr.IsQosData())
199  {
200  return hdr.GetQosTid();
201  }
202  else if (hdr.IsBlockAckReq())
203  {
204  CtrlBAckRequestHeader baReqHdr;
205  packet->PeekHeader(baReqHdr);
206  return baReqHdr.GetTidInfo();
207  }
208  else if (hdr.IsBlockAck())
209  {
210  CtrlBAckResponseHeader baRespHdr;
211  packet->PeekHeader(baRespHdr);
212  return baRespHdr.GetTidInfo();
213  }
214  else if (hdr.IsMgt() && hdr.IsAction())
215  {
216  Ptr<Packet> pkt = packet->Copy();
217  WifiActionHeader actionHdr;
218  pkt->RemoveHeader(actionHdr);
219 
220  if (actionHdr.GetCategory() == WifiActionHeader::BLOCK_ACK)
221  {
222  switch (actionHdr.GetAction().blockAck)
223  {
225  MgtAddBaRequestHeader reqHdr;
226  pkt->RemoveHeader(reqHdr);
227  return reqHdr.GetTid();
228  }
230  MgtAddBaResponseHeader respHdr;
231  pkt->RemoveHeader(respHdr);
232  return respHdr.GetTid();
233  }
235  MgtDelBaHeader delHdr;
236  pkt->RemoveHeader(delHdr);
237  return delHdr.GetTid();
238  }
239  default: {
240  NS_FATAL_ERROR("Cannot extract Traffic ID from this BA action frame");
241  }
242  }
243  }
244  else
245  {
246  NS_FATAL_ERROR("Cannot extract Traffic ID from this action frame");
247  }
248  }
249  else
250  {
251  NS_FATAL_ERROR("Packet has no Traffic ID");
252  }
253  return 0; // Silence compiler warning about lack of return value
254 }
255 
256 uint8_t
258 {
259  uint8_t dscp;
260  uint8_t priority = 0;
261  if (item->GetUint8Value(QueueItem::IP_DSFIELD, dscp))
262  {
263  // if the QoS map element is implemented, it should be used here
264  // to set the priority.
265  // User priority is set to the three most significant bits of the DS field
266  priority = dscp >> 5;
267  }
268 
269  // replace the priority tag
270  SocketPriorityTag priorityTag;
271  priorityTag.SetPriority(priority);
272  item->GetPacket()->ReplacePacketTag(priorityTag);
273 
274  // if the admission control were implemented, here we should check whether
275  // the access category assigned to the packet should be downgraded
276 
277  return static_cast<uint8_t>(QosUtilsMapTidToAc(priority));
278 }
279 
280 } // namespace ns3
Headers for BlockAckRequest.
Definition: ctrl-headers.h:52
uint8_t GetTidInfo() const
Return the Traffic ID (TID).
Headers for BlockAck response.
Definition: ctrl-headers.h:203
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
Definition: mac48-address.h:46
Implement the header for management frames of type Add Block Ack request.
Definition: mgt-headers.h:1511
uint8_t GetTid() const
Return the Traffic ID (TID).
Implement the header for management frames of type Add Block Ack response.
Definition: mgt-headers.h:1642
uint8_t GetTid() const
Return the Traffic ID (TID).
Implement the header for management frames of type Delete Block Ack.
Definition: mgt-headers.h:1761
uint8_t GetTid() const
Return the Traffic ID (TID).
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:1002
indicates whether the socket has a priority set.
Definition: socket.h:1316
uint8_t GetPriority() const
Get the tag's priority.
Definition: socket.cc:858
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:852
WifiAc(uint8_t lowTid, uint8_t highTid)
Constructor.
Definition: qos-utils.cc:54
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:73
uint8_t m_highTid
the TID with higher priority
Definition: qos-utils.h:125
uint8_t GetHighTid() const
Get the TID with higher priority.
Definition: qos-utils.cc:67
uint8_t GetLowTid() const
Get the TID with lower priority.
Definition: qos-utils.cc:61
uint8_t m_lowTid
the TID with lower priority
Definition: qos-utils.h:124
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:1279
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: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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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
bool operator>=(const int64x64_t &lhs, const int64x64_t &rhs)
Greater or equal operator.
Definition: int64x64.h:174
bool operator<=(const int64x64_t &lhs, const int64x64_t &rhs)
Less or equal operator.
Definition: int64x64.h:161
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition: length.cc:421
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:186
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:175
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:195
uint8_t QosUtilsGetTidForPacket(Ptr< const Packet > packet)
If a QoS tag is attached to the packet, returns a value < 8.
Definition: qos-utils.cc:160
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:72
uint8_t SelectQueueByDSField(Ptr< QueueItem > item)
Determine the TX queue for a given packet.
Definition: qos-utils.cc:257
@ AC_BE
Best Effort.
Definition: qos-utils.h:74
@ AC_VO
Voice.
Definition: qos-utils.h:80
@ AC_VI
Video.
Definition: qos-utils.h:78
@ AC_BK
Background.
Definition: qos-utils.h:76
@ AC_UNDEF
Total number of ACs.
Definition: qos-utils.h:86
address
Definition: first.py:40
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:170
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:126
std::pair< Mac48Address, uint8_t > WifiAddressTidPair
(MAC address, TID) pair
Definition: qos-utils.h:33
std::size_t operator()(const Mac48Address &address) const
Functional operator for MAC address hash computation.
Definition: qos-utils.cc:45
std::size_t operator()(const WifiAddressTidPair &addressTidPair) const
Functional operator for (MAC address, TID) hash computation.
Definition: qos-utils.cc:34
BlockAckActionValue blockAck
block ack
Definition: mgt-headers.h:1446