1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II 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 * Author: Stefano Avallone <stavallo@unina.it> 19 */ 20 21 #ifndef WIFI_ACKNOWLEDGMENT_H 22 #define WIFI_ACKNOWLEDGMENT_H 23 24 #include "ns3/nstime.h" 25 #include "wifi-tx-vector.h" 26 #include "block-ack-type.h" 27 #include "wifi-mac-header.h" 28 #include "ctrl-headers.h" 29 #include <map> 30 #include <memory> 31 32 33 namespace ns3 { 34 35 class Mac48Address; 36 37 /** 38 * \ingroup wifi 39 * 40 * WifiAcknowledgment is an abstract base struct. Each derived struct defines an acknowledgment 41 * method and stores the information needed to perform acknowledgment according to 42 * that method. 43 */ 44 struct WifiAcknowledgment 45 { 46 /** 47 * \enum Method 48 * \brief Available acknowledgment methods 49 */ 50 enum Method 51 { 52 NONE = 0, 53 NORMAL_ACK, 54 BLOCK_ACK, 55 BAR_BLOCK_ACK, 56 DL_MU_BAR_BA_SEQUENCE, 57 DL_MU_TF_MU_BAR, 58 DL_MU_AGGREGATE_TF, 59 UL_MU_MULTI_STA_BA, 60 ACK_AFTER_TB_PPDU 61 }; 62 63 /** 64 * Constructor. 65 * \param m the acknowledgment method for this object 66 */ 67 WifiAcknowledgment (Method m); 68 virtual ~WifiAcknowledgment (); 69 70 /** 71 * Clone this object. 72 * \return a pointer to the cloned object 73 */ 74 virtual std::unique_ptr<WifiAcknowledgment> Copy (void) const = 0; 75 76 /** 77 * Get the QoS Ack policy to use for the MPDUs addressed to the given receiver 78 * and belonging to the given TID. 79 * 80 * \param receiver the MAC address of the receiver 81 * \param tid the TID 82 * \return the QoS Ack policy to use 83 */ 84 WifiMacHeader::QosAckPolicy GetQosAckPolicy (Mac48Address receiver, uint8_t tid) const; 85 86 /** 87 * Set the QoS Ack policy to use for the MPDUs addressed to the given receiver 88 * and belonging to the given TID. If the pair (receiver, TID) already exists, 89 * it is overwritten with the given QoS Ack policy. 90 * 91 * \param receiver the MAC address of the receiver 92 * \param tid the TID 93 * \param ackPolicy the QoS Ack policy to use 94 */ 95 void SetQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy); 96 97 /** 98 * \brief Print the object contents. 99 * \param os output stream in which the data should be printed. 100 */ 101 virtual void Print (std::ostream &os) const = 0; 102 103 const Method method; //!< acknowledgment method 104 Time acknowledgmentTime; //!< time required by the acknowledgment method 105 106 private: 107 /** 108 * Check whether the given QoS Ack policy can be used for the MPDUs addressed 109 * to the given receiver and belonging to the given TID. 110 * 111 * \param receiver the MAC address of the receiver 112 * \param tid the TID 113 * \param ackPolicy the QoS Ack policy to use 114 * \return true if the given QoS Ack policy can be used, false otherwise 115 */ 116 virtual bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, 117 WifiMacHeader::QosAckPolicy ackPolicy) const = 0; 118 119 /// Qos Ack Policy to set for MPDUs addressed to a given receiver and having a given TID 120 std::map<std::pair<Mac48Address, uint8_t>, WifiMacHeader::QosAckPolicy> m_ackPolicy; 121 }; 122 123 124 /** 125 * \ingroup wifi 126 * 127 * WifiNoAck specifies that no acknowledgment is required. 128 */ 129 struct WifiNoAck : public WifiAcknowledgment 130 { 131 WifiNoAck (); 132 133 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 134 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 135 void Print (std::ostream &os) const override; 136 }; 137 138 139 /** 140 * \ingroup wifi 141 * 142 * WifiNormalAck specifies that acknowledgment via Normal Ack is required. 143 */ 144 struct WifiNormalAck : public WifiAcknowledgment 145 { 146 WifiNormalAck (); 147 148 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 149 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 150 void Print (std::ostream &os) const override; 151 152 WifiTxVector ackTxVector; //!< Ack TXVECTOR 153 }; 154 155 156 /** 157 * \ingroup wifi 158 * 159 * WifiBlockAck specifies that acknowledgment via Block Ack is required. 160 */ 161 struct WifiBlockAck : public WifiAcknowledgment 162 { 163 WifiBlockAck (); 164 165 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 166 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 167 void Print (std::ostream &os) const override; 168 169 WifiTxVector blockAckTxVector; //!< BlockAck TXVECTOR 170 BlockAckType baType; //!< BlockAck type 171 }; 172 173 174 /** 175 * \ingroup wifi 176 * 177 * WifiBarBlockAck specifies that a BlockAckReq is sent to solicit a Block Ack response. 178 */ 179 struct WifiBarBlockAck : public WifiAcknowledgment 180 { 181 WifiBarBlockAck (); 182 183 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 184 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 185 void Print (std::ostream &os) const override; 186 187 WifiTxVector blockAckReqTxVector; //!< BlockAckReq TXVECTOR 188 WifiTxVector blockAckTxVector; //!< BlockAck TXVECTOR 189 BlockAckReqType barType; //!< BlockAckReq type 190 BlockAckType baType; //!< BlockAck type 191 }; 192 193 194 /** 195 * \ingroup wifi 196 * 197 * WifiDlMuBarBaSequence specifies that a DL MU PPDU is acknowledged through a 198 * sequence of BlockAckReq and BlockAck frames. Only one station may be allowed 199 * to reply a SIFS after the DL MU PPDU by sending either a Normal Ack or a BlockAck. 200 */ 201 struct WifiDlMuBarBaSequence : public WifiAcknowledgment 202 { 203 WifiDlMuBarBaSequence (); 204 205 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 206 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 207 void Print (std::ostream &os) const override; 208 209 /// information related to an Ack frame sent by a station 210 struct AckInfo 211 { 212 WifiTxVector ackTxVector; //!< TXVECTOR for the Ack frame 213 }; 214 /// information related to a BlockAck frame sent by a station 215 struct BlockAckInfo 216 { 217 WifiTxVector blockAckTxVector; //!< TXVECTOR for the BlockAck frame 218 BlockAckType baType; //!< BlockAck type 219 }; 220 /// information related to a BlockAckReq frame sent to a station 221 struct BlockAckReqInfo 222 { 223 WifiTxVector blockAckReqTxVector; //!< TXVECTOR for the BlockAckReq frame 224 BlockAckReqType barType; //!< BlockAckReq type 225 WifiTxVector blockAckTxVector; //!< TXVECTOR for the BlockAck frame 226 BlockAckType baType; //!< BlockAck type 227 }; 228 229 /// Set of stations replying with an Ack frame (no more than one) 230 std::map<Mac48Address, AckInfo> stationsReplyingWithNormalAck; 231 /// Set of stations replying with a BlockAck frame (no more than one) 232 std::map<Mac48Address, BlockAckInfo> stationsReplyingWithBlockAck; 233 /// Set of stations receiving a BlockAckReq frame and replying with a BlockAck frame 234 std::map<Mac48Address, BlockAckReqInfo> stationsSendBlockAckReqTo; 235 }; 236 237 238 /** 239 * \ingroup wifi 240 * 241 * WifiDlMuTfMuBar specifies that a DL MU PPDU is followed after a SIFS duration 242 * by a MU-BAR Trigger Frame (sent as single user frame) soliciting BlockAck 243 * frames sent as HE TB PPDUs. 244 */ 245 struct WifiDlMuTfMuBar : public WifiAcknowledgment 246 { 247 WifiDlMuTfMuBar (); 248 249 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 250 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 251 void Print (std::ostream &os) const override; 252 253 /// information related to a BlockAck frame sent by a station 254 struct BlockAckInfo 255 { 256 CtrlBAckRequestHeader barHeader; //!< BlockAckReq header 257 WifiTxVector blockAckTxVector; //!< TXVECTOR for the BlockAck frame 258 BlockAckType baType; //!< BlockAck type 259 }; 260 261 /// Set of stations replying with a BlockAck frame 262 std::map<Mac48Address, BlockAckInfo> stationsReplyingWithBlockAck; 263 std::list<BlockAckReqType> barTypes; //!< BAR types 264 uint16_t ulLength; //!< the UL Length field of the MU-BAR Trigger Frame 265 WifiTxVector muBarTxVector; //!< TXVECTOR used to transmit the MU-BAR Trigger Frame 266 }; 267 268 269 /** 270 * \ingroup wifi 271 * 272 * WifiDlMuAggregateTf specifies that a DL MU PPDU made of PSDUs including each 273 * a MU-BAR Trigger Frame is acknowledged through BlockAck frames sent as 274 * HE TB PPDUs. 275 */ 276 struct WifiDlMuAggregateTf : public WifiAcknowledgment 277 { 278 WifiDlMuAggregateTf (); 279 280 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 281 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 282 void Print (std::ostream &os) const override; 283 284 /// information related to a BlockAck frame sent by a station 285 struct BlockAckInfo 286 { 287 uint32_t muBarSize; //!< size in bytes of a MU-BAR Trigger Frame 288 CtrlBAckRequestHeader barHeader; //!< BlockAckReq header 289 WifiTxVector blockAckTxVector; //!< TXVECTOR for the BlockAck frame 290 BlockAckType baType; //!< BlockAck type 291 }; 292 293 /// Set of stations replying with a BlockAck frame 294 std::map<Mac48Address, BlockAckInfo> stationsReplyingWithBlockAck; 295 uint16_t ulLength; //!< the UL Length field of the MU-BAR Trigger Frames 296 }; 297 298 299 /** 300 * \ingroup wifi 301 * 302 * WifiUlMuMultiStaBa specifies that a Basic Trigger Frame is being sent to 303 * solicit TB PPDUs that will be acknowledged through a multi-STA BlockAck frame. 304 */ 305 struct WifiUlMuMultiStaBa : public WifiAcknowledgment 306 { 307 WifiUlMuMultiStaBa (); 308 309 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 310 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 311 void Print (std::ostream &os) const override; 312 313 /// Map (originator, tid) pairs to the their index in baType 314 std::map<std::pair<Mac48Address, uint8_t>, std::size_t> stationsReceivingMultiStaBa; 315 BlockAckType baType; //!< BlockAck type 316 WifiTxVector tbPpduTxVector; //!< TXVECTOR for a TB PPDU 317 WifiTxVector multiStaBaTxVector; //!< TXVECTOR for the Multi-STA BlockAck 318 }; 319 320 321 /** 322 * \ingroup wifi 323 * 324 * WifiAckAfterTbPpdu is used when a station prepares a TB PPDU to send in 325 * response to a Basic Trigger Frame. The acknowledgment time must be 326 * zero because the time taken by the actual acknowledgment is not included 327 * in the duration indicated by the Trigger Frame. The QoS ack policy instead 328 * must be Normal Ack/Implicit Block Ack Request. 329 */ 330 struct WifiAckAfterTbPpdu : public WifiAcknowledgment 331 { 332 WifiAckAfterTbPpdu (); 333 334 std::unique_ptr<WifiAcknowledgment> Copy (void) const override; 335 bool CheckQosAckPolicy (Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy) const override; 336 void Print (std::ostream &os) const override; 337 }; 338 339 340 /** 341 * \brief Stream insertion operator. 342 * 343 * \param os the output stream 344 * \param acknowledgment the acknowledgment method 345 * \returns a reference to the stream 346 */ 347 std::ostream& operator<< (std::ostream& os, const WifiAcknowledgment* acknowledgment); 348 349 } //namespace ns3 350 351 #endif /* WIFI_ACKNOWLEDGMENT_H */ 352