A Discrete-Event Network Simulator
API
wifi-acknowledgment.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 #include "wifi-acknowledgment.h"
21 
22 #include "wifi-utils.h"
23 
24 #include "ns3/mac48-address.h"
25 
26 namespace ns3
27 {
28 
29 /*
30  * WifiAcknowledgment
31  */
32 
34  : method(m),
35  acknowledgmentTime(Time::Min()) // uninitialized
36 {
37 }
38 
40 {
41 }
42 
45 {
46  auto it = m_ackPolicy.find({receiver, tid});
47  NS_ASSERT(it != m_ackPolicy.end());
48  return it->second;
49 }
50 
51 void
53  uint8_t tid,
55 {
56  NS_ABORT_MSG_IF(!CheckQosAckPolicy(receiver, tid, ackPolicy), "QoS Ack policy not admitted");
57  m_ackPolicy[{receiver, tid}] = ackPolicy;
58 }
59 
60 /*
61  * WifiNoAck
62  */
63 
65  : WifiAcknowledgment(NONE)
66 {
68 }
69 
70 std::unique_ptr<WifiAcknowledgment>
72 {
73  return std::unique_ptr<WifiAcknowledgment>(new WifiNoAck(*this));
74 }
75 
76 bool
78  uint8_t tid,
79  WifiMacHeader::QosAckPolicy ackPolicy) const
80 {
81  if (ackPolicy == WifiMacHeader::NO_ACK || ackPolicy == WifiMacHeader::BLOCK_ACK)
82  {
83  return true;
84  }
85  return false;
86 }
87 
88 void
89 WifiNoAck::Print(std::ostream& os) const
90 {
91  os << "NONE";
92 }
93 
94 /*
95  * WifiNormalAck
96  */
97 
99  : WifiAcknowledgment(NORMAL_ACK)
100 {
101 }
102 
103 std::unique_ptr<WifiAcknowledgment>
105 {
106  return std::unique_ptr<WifiAcknowledgment>(new WifiNormalAck(*this));
107 }
108 
109 bool
111  uint8_t tid,
112  WifiMacHeader::QosAckPolicy ackPolicy) const
113 {
114  if (ackPolicy == WifiMacHeader::NORMAL_ACK)
115  {
116  return true;
117  }
118  return false;
119 }
120 
121 void
122 WifiNormalAck::Print(std::ostream& os) const
123 {
124  os << "NORMAL_ACK";
125 }
126 
127 /*
128  * WifiBlockAck
129  */
130 
132  : WifiAcknowledgment(BLOCK_ACK)
133 {
134 }
135 
136 std::unique_ptr<WifiAcknowledgment>
138 {
139  return std::unique_ptr<WifiAcknowledgment>(new WifiBlockAck(*this));
140 }
141 
142 bool
144  uint8_t tid,
145  WifiMacHeader::QosAckPolicy ackPolicy) const
146 {
147  if (ackPolicy == WifiMacHeader::NORMAL_ACK)
148  {
149  return true;
150  }
151  return false;
152 }
153 
154 void
155 WifiBlockAck::Print(std::ostream& os) const
156 {
157  os << "BLOCK_ACK";
158 }
159 
160 /*
161  * WifiBarBlockAck
162  */
163 
165  : WifiAcknowledgment(BAR_BLOCK_ACK)
166 {
167 }
168 
169 std::unique_ptr<WifiAcknowledgment>
171 {
172  return std::unique_ptr<WifiAcknowledgment>(new WifiBarBlockAck(*this));
173 }
174 
175 bool
177  uint8_t tid,
178  WifiMacHeader::QosAckPolicy ackPolicy) const
179 {
180  if (ackPolicy == WifiMacHeader::BLOCK_ACK)
181  {
182  return true;
183  }
184  return false;
185 }
186 
187 void
188 WifiBarBlockAck::Print(std::ostream& os) const
189 {
190  os << "BAR_BLOCK_ACK";
191 }
192 
193 /*
194  * WifiDlMuBarBaSequence
195  */
196 
199 {
200 }
201 
202 std::unique_ptr<WifiAcknowledgment>
204 {
205  return std::unique_ptr<WifiAcknowledgment>(new WifiDlMuBarBaSequence(*this));
206 }
207 
208 bool
210  uint8_t tid,
211  WifiMacHeader::QosAckPolicy ackPolicy) const
212 {
213  if (ackPolicy == WifiMacHeader::NORMAL_ACK)
214  {
215  // The given receiver must be the only one to send an immediate reply
216  if (stationsReplyingWithNormalAck.size() == 1 &&
217  stationsReplyingWithNormalAck.begin()->first == receiver)
218  {
219  return true;
220  }
221 
222  if (stationsReplyingWithBlockAck.size() == 1 &&
223  stationsReplyingWithBlockAck.begin()->first == receiver)
224  {
225  return true;
226  }
227 
228  return false;
229  }
230 
231  if (ackPolicy == WifiMacHeader::BLOCK_ACK)
232  {
233  return true;
234  }
235 
236  return false;
237 }
238 
239 void
240 WifiDlMuBarBaSequence::Print(std::ostream& os) const
241 {
242  os << "DL_MU_BAR_BA_SEQUENCE [";
243  for (const auto& sta : stationsReplyingWithNormalAck)
244  {
245  os << " (ACK) " << sta.first;
246  }
247  for (const auto& sta : stationsReplyingWithBlockAck)
248  {
249  os << " (BA) " << sta.first;
250  }
251  for (const auto& sta : stationsSendBlockAckReqTo)
252  {
253  os << " (BAR+BA) " << sta.first;
254  }
255  os << "]";
256 }
257 
258 /*
259  * WifiDlMuTfMuBar
260  */
261 
263  : WifiAcknowledgment(DL_MU_TF_MU_BAR),
264  ulLength(0)
265 {
266 }
267 
268 std::unique_ptr<WifiAcknowledgment>
270 {
271  return std::unique_ptr<WifiAcknowledgment>(new WifiDlMuTfMuBar(*this));
272 }
273 
274 bool
276  uint8_t tid,
277  WifiMacHeader::QosAckPolicy ackPolicy) const
278 {
279  // the only admitted ack policy is Block Ack because stations need to wait for a MU-BAR
280  if (ackPolicy == WifiMacHeader::BLOCK_ACK)
281  {
282  return true;
283  }
284 
285  return false;
286 }
287 
288 void
289 WifiDlMuTfMuBar::Print(std::ostream& os) const
290 {
291  os << "DL_MU_TF_MU_BAR [";
292  for (const auto& sta : stationsReplyingWithBlockAck)
293  {
294  os << " (BA) " << sta.first;
295  }
296  os << "]";
297 }
298 
299 /*
300  * WifiDlMuAggregateTf
301  */
302 
304  : WifiAcknowledgment(DL_MU_AGGREGATE_TF),
305  ulLength(0)
306 {
307 }
308 
309 std::unique_ptr<WifiAcknowledgment>
311 {
312  return std::unique_ptr<WifiAcknowledgment>(new WifiDlMuAggregateTf(*this));
313 }
314 
315 bool
317  uint8_t tid,
318  WifiMacHeader::QosAckPolicy ackPolicy) const
319 {
320  // the only admitted ack policy is No explicit acknowledgment or TB PPDU Ack policy
321  if (ackPolicy == WifiMacHeader::NO_EXPLICIT_ACK)
322  {
323  return true;
324  }
325 
326  return false;
327 }
328 
329 void
330 WifiDlMuAggregateTf::Print(std::ostream& os) const
331 {
332  os << "DL_MU_AGGREGATE_TF [";
333  for (const auto& sta : stationsReplyingWithBlockAck)
334  {
335  os << " (BA) " << sta.first;
336  }
337  os << "]";
338 }
339 
340 /*
341  * WifiUlMuMultiStaBa
342  */
343 
345  : WifiAcknowledgment(UL_MU_MULTI_STA_BA),
346  baType(BlockAckType::MULTI_STA)
347 {
348 }
349 
350 std::unique_ptr<WifiAcknowledgment>
352 {
353  return std::unique_ptr<WifiAcknowledgment>(new WifiUlMuMultiStaBa(*this));
354 }
355 
356 bool
358  uint8_t tid,
359  WifiMacHeader::QosAckPolicy ackPolicy) const
360 {
361  // a Basic Trigger Frame has no QoS ack policy
362  return true;
363 }
364 
365 void
366 WifiUlMuMultiStaBa::Print(std::ostream& os) const
367 {
368  os << "UL_MU_MULTI_STA_BA [";
369  for (const auto& sta : stationsReceivingMultiStaBa)
370  {
371  os << "(" << sta.first.first << "," << +sta.first.second << ") ";
372  }
373  os << "]";
374 }
375 
376 /*
377  * WifiAckAfterTbPpdu
378  */
379 
381  : WifiAcknowledgment(ACK_AFTER_TB_PPDU)
382 {
383 }
384 
385 std::unique_ptr<WifiAcknowledgment>
387 {
388  return std::unique_ptr<WifiAcknowledgment>(new WifiAckAfterTbPpdu(*this));
389 }
390 
391 bool
393  uint8_t tid,
394  WifiMacHeader::QosAckPolicy ackPolicy) const
395 {
396  if (ackPolicy == WifiMacHeader::NORMAL_ACK)
397  {
398  return true;
399  }
400 
401  return false;
402 }
403 
404 void
405 WifiAckAfterTbPpdu::Print(std::ostream& os) const
406 {
407  os << "ACK_AFTER_TB_PPDU";
408 }
409 
410 std::ostream&
411 operator<<(std::ostream& os, const WifiAcknowledgment* acknowledgment)
412 {
413  acknowledgment->Print(os);
414  return os;
415 }
416 
417 } // namespace ns3
an EUI-48 address
Definition: mac48-address.h:46
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
QosAckPolicy
Ack policy for QoS frames.
#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_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
Definition: int64x64.h:229
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
The different BlockAck variants.
void Print(std::ostream &os) const override
Print the object contents.
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
WifiAcknowledgment is an abstract base struct.
WifiAcknowledgment(Method m)
Constructor.
std::map< std::pair< Mac48Address, uint8_t >, WifiMacHeader::QosAckPolicy > m_ackPolicy
Qos Ack Policy to set for MPDUs addressed to a given receiver and having a given TID.
Time acknowledgmentTime
time required by the acknowledgment method
void SetQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy)
Set the QoS Ack policy to use for the MPDUs addressed to the given receiver and belonging to the give...
WifiMacHeader::QosAckPolicy GetQosAckPolicy(Mac48Address receiver, uint8_t tid) const
Get the QoS Ack policy to use for the MPDUs addressed to the given receiver and belonging to the give...
virtual void Print(std::ostream &os) const =0
Print the object contents.
Method
Available acknowledgment methods.
virtual bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const =0
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
void Print(std::ostream &os) const override
Print the object contents.
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
void Print(std::ostream &os) const override
Print the object contents.
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
void Print(std::ostream &os) const override
Print the object contents.
std::map< Mac48Address, BlockAckInfo > stationsReplyingWithBlockAck
Set of stations replying with a BlockAck frame.
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
void Print(std::ostream &os) const override
Print the object contents.
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
std::map< Mac48Address, BlockAckReqInfo > stationsSendBlockAckReqTo
Set of stations receiving a BlockAckReq frame and replying with a BlockAck frame.
std::map< Mac48Address, BlockAckInfo > stationsReplyingWithBlockAck
Set of stations replying with a BlockAck frame (no more than one)
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
std::map< Mac48Address, AckInfo > stationsReplyingWithNormalAck
Set of stations replying with an Ack frame (no more than one)
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
std::map< Mac48Address, BlockAckInfo > stationsReplyingWithBlockAck
Set of stations replying with a BlockAck frame.
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
void Print(std::ostream &os) const override
Print the object contents.
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
void Print(std::ostream &os) const override
Print the object contents.
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...
void Print(std::ostream &os) const override
Print the object contents.
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
std::unique_ptr< WifiAcknowledgment > Copy() const override
Clone this object.
std::map< std::pair< Mac48Address, uint8_t >, std::size_t > stationsReceivingMultiStaBa
Map (originator, tid) pairs to the their index in baType.
void Print(std::ostream &os) const override
Print the object contents.
bool CheckQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override
Check whether the given QoS Ack policy can be used for the MPDUs addressed to the given receiver and ...