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 
66 {
68 }
69 
70 std::unique_ptr<WifiAcknowledgment>
72 {
73  return std::make_unique<WifiNoAck>(*this);
74 }
75 
76 bool
78  uint8_t tid,
79  WifiMacHeader::QosAckPolicy ackPolicy) const
80 {
81  return ackPolicy == WifiMacHeader::NO_ACK || ackPolicy == WifiMacHeader::BLOCK_ACK;
82 }
83 
84 void
85 WifiNoAck::Print(std::ostream& os) const
86 {
87  os << "NONE";
88 }
89 
90 /*
91  * WifiNormalAck
92  */
93 
95  : WifiAcknowledgment(NORMAL_ACK)
96 {
97 }
98 
99 std::unique_ptr<WifiAcknowledgment>
101 {
102  return std::make_unique<WifiNormalAck>(*this);
103 }
104 
105 bool
107  uint8_t tid,
108  WifiMacHeader::QosAckPolicy ackPolicy) const
109 {
110  return ackPolicy == WifiMacHeader::NORMAL_ACK;
111 }
112 
113 void
114 WifiNormalAck::Print(std::ostream& os) const
115 {
116  os << "NORMAL_ACK";
117 }
118 
119 /*
120  * WifiBlockAck
121  */
122 
124  : WifiAcknowledgment(BLOCK_ACK)
125 {
126 }
127 
128 std::unique_ptr<WifiAcknowledgment>
130 {
131  return std::make_unique<WifiBlockAck>(*this);
132 }
133 
134 bool
136  uint8_t tid,
137  WifiMacHeader::QosAckPolicy ackPolicy) const
138 {
139  return ackPolicy == WifiMacHeader::NORMAL_ACK;
140 }
141 
142 void
143 WifiBlockAck::Print(std::ostream& os) const
144 {
145  os << "BLOCK_ACK";
146 }
147 
148 /*
149  * WifiBarBlockAck
150  */
151 
153  : WifiAcknowledgment(BAR_BLOCK_ACK)
154 {
155 }
156 
157 std::unique_ptr<WifiAcknowledgment>
159 {
160  return std::make_unique<WifiBarBlockAck>(*this);
161 }
162 
163 bool
165  uint8_t tid,
166  WifiMacHeader::QosAckPolicy ackPolicy) const
167 {
168  return ackPolicy == WifiMacHeader::BLOCK_ACK;
169 }
170 
171 void
172 WifiBarBlockAck::Print(std::ostream& os) const
173 {
174  os << "BAR_BLOCK_ACK";
175 }
176 
177 /*
178  * WifiDlMuBarBaSequence
179  */
180 
183 {
184 }
185 
186 std::unique_ptr<WifiAcknowledgment>
188 {
189  return std::make_unique<WifiDlMuBarBaSequence>(*this);
190 }
191 
192 bool
194  uint8_t tid,
195  WifiMacHeader::QosAckPolicy ackPolicy) const
196 {
197  if (ackPolicy == WifiMacHeader::NORMAL_ACK)
198  {
199  // The given receiver must be the only one to send an immediate reply
200  if (stationsReplyingWithNormalAck.size() == 1 &&
201  stationsReplyingWithNormalAck.begin()->first == receiver)
202  {
203  return true;
204  }
205 
206  if (stationsReplyingWithBlockAck.size() == 1 &&
207  stationsReplyingWithBlockAck.begin()->first == receiver)
208  {
209  return true;
210  }
211 
212  return false;
213  }
214 
215  return ackPolicy == WifiMacHeader::BLOCK_ACK;
216 }
217 
218 void
219 WifiDlMuBarBaSequence::Print(std::ostream& os) const
220 {
221  os << "DL_MU_BAR_BA_SEQUENCE [";
222  for (const auto& sta : stationsReplyingWithNormalAck)
223  {
224  os << " (ACK) " << sta.first;
225  }
226  for (const auto& sta : stationsReplyingWithBlockAck)
227  {
228  os << " (BA) " << sta.first;
229  }
230  for (const auto& sta : stationsSendBlockAckReqTo)
231  {
232  os << " (BAR+BA) " << sta.first;
233  }
234  os << "]";
235 }
236 
237 /*
238  * WifiDlMuTfMuBar
239  */
240 
242  : WifiAcknowledgment(DL_MU_TF_MU_BAR),
243  ulLength(0)
244 {
245 }
246 
247 std::unique_ptr<WifiAcknowledgment>
249 {
250  return std::make_unique<WifiDlMuTfMuBar>(*this);
251 }
252 
253 bool
255  uint8_t tid,
256  WifiMacHeader::QosAckPolicy ackPolicy) const
257 {
258  // the only admitted ack policy is Block Ack because stations need to wait for a MU-BAR
259  return ackPolicy == WifiMacHeader::BLOCK_ACK;
260 }
261 
262 void
263 WifiDlMuTfMuBar::Print(std::ostream& os) const
264 {
265  os << "DL_MU_TF_MU_BAR [";
266  for (const auto& sta : stationsReplyingWithBlockAck)
267  {
268  os << " (BA) " << sta.first;
269  }
270  os << "]";
271 }
272 
273 /*
274  * WifiDlMuAggregateTf
275  */
276 
278  : WifiAcknowledgment(DL_MU_AGGREGATE_TF),
279  ulLength(0)
280 {
281 }
282 
283 std::unique_ptr<WifiAcknowledgment>
285 {
286  return std::make_unique<WifiDlMuAggregateTf>(*this);
287 }
288 
289 bool
291  uint8_t tid,
292  WifiMacHeader::QosAckPolicy ackPolicy) const
293 {
294  // the only admitted ack policy is No explicit acknowledgment or TB PPDU Ack policy
295  return ackPolicy == WifiMacHeader::NO_EXPLICIT_ACK;
296 }
297 
298 void
299 WifiDlMuAggregateTf::Print(std::ostream& os) const
300 {
301  os << "DL_MU_AGGREGATE_TF [";
302  for (const auto& sta : stationsReplyingWithBlockAck)
303  {
304  os << " (BA) " << sta.first;
305  }
306  os << "]";
307 }
308 
309 /*
310  * WifiUlMuMultiStaBa
311  */
312 
314  : WifiAcknowledgment(UL_MU_MULTI_STA_BA),
315  baType(BlockAckType::MULTI_STA)
316 {
317 }
318 
319 std::unique_ptr<WifiAcknowledgment>
321 {
322  return std::make_unique<WifiUlMuMultiStaBa>(*this);
323 }
324 
325 bool
327  uint8_t tid,
328  WifiMacHeader::QosAckPolicy ackPolicy) const
329 {
330  // a Basic Trigger Frame has no QoS ack policy
331  return true;
332 }
333 
334 void
335 WifiUlMuMultiStaBa::Print(std::ostream& os) const
336 {
337  os << "UL_MU_MULTI_STA_BA [";
338  for (const auto& sta : stationsReceivingMultiStaBa)
339  {
340  os << "(" << sta.first.first << "," << +sta.first.second << ") ";
341  }
342  os << "]";
343 }
344 
345 /*
346  * WifiAckAfterTbPpdu
347  */
348 
350  : WifiAcknowledgment(ACK_AFTER_TB_PPDU)
351 {
352 }
353 
354 std::unique_ptr<WifiAcknowledgment>
356 {
357  return std::make_unique<WifiAckAfterTbPpdu>(*this);
358 }
359 
360 bool
362  uint8_t tid,
363  WifiMacHeader::QosAckPolicy ackPolicy) const
364 {
365  return ackPolicy == WifiMacHeader::NORMAL_ACK;
366 }
367 
368 void
369 WifiAckAfterTbPpdu::Print(std::ostream& os) const
370 {
371  os << "ACK_AFTER_TB_PPDU";
372 }
373 
374 std::ostream&
375 operator<<(std::ostream& os, const WifiAcknowledgment* acknowledgment)
376 {
377  acknowledgment->Print(os);
378  return os;
379 }
380 
381 } // 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:1326
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:159
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 ...