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