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 HE_FRAME_EXCHANGE_MANAGER_H 22 #define HE_FRAME_EXCHANGE_MANAGER_H 23 24 #include "ns3/vht-frame-exchange-manager.h" 25 #include "mu-snr-tag.h" 26 #include <map> 27 #include <unordered_map> 28 29 namespace ns3 { 30 31 class MultiUserScheduler; 32 class ApWifiMac; 33 class StaWifiMac; 34 class CtrlTriggerHeader; 35 36 /** 37 * Map of PSDUs indexed by STA-ID 38 */ 39 typedef std::unordered_map <uint16_t /* staId */, Ptr<WifiPsdu> /* PSDU */> WifiPsduMap; 40 /** 41 * Map of const PSDUs indexed by STA-ID 42 */ 43 typedef std::unordered_map <uint16_t /* staId */, Ptr<const WifiPsdu> /* PSDU */> WifiConstPsduMap; 44 45 /** 46 * \ingroup wifi 47 * 48 * HeFrameExchangeManager handles the frame exchange sequences 49 * for HE stations. 50 */ 51 class HeFrameExchangeManager : public VhtFrameExchangeManager 52 { 53 public: 54 /** 55 * \brief Get the type ID. 56 * \return the object TypeId 57 */ 58 static TypeId GetTypeId (void); 59 HeFrameExchangeManager (); 60 virtual ~HeFrameExchangeManager (); 61 62 uint16_t GetSupportedBaBufferSize (void) const override; 63 bool StartFrameExchange (Ptr<QosTxop> edca, Time availableTime, bool initialFrame) override; 64 void SetWifiMac (const Ptr<RegularWifiMac> mac) override; 65 void CalculateAcknowledgmentTime (WifiAcknowledgment* acknowledgment) const override; 66 67 /** 68 * Set the Multi-user Scheduler associated with this Frame Exchange Manager. 69 * 70 * \param muScheduler the Multi-user Scheduler associated with this Frame Exchange Manager 71 */ 72 void SetMultiUserScheduler (const Ptr<MultiUserScheduler> muScheduler); 73 74 /** 75 * Get the PSDU in the given PSDU map that is addressed to the given MAC address, 76 * if any, or a null pointer, otherwise. 77 * 78 * \param to the MAC address 79 * \param psduMap the PSDU map 80 * \return the PSDU, if any, or a null pointer, otherwise 81 */ 82 static Ptr<WifiPsdu> GetPsduTo (Mac48Address to, const WifiPsduMap& psduMap); 83 84 /** 85 * Set the UL Target RSSI subfield of every User Info fields of the given 86 * Trigger Frame to the most recent RSSI observed from the corresponding 87 * station. 88 * 89 * \param trigger the given Trigger Frame 90 */ 91 virtual void SetTargetRssi (CtrlTriggerHeader& trigger) const; 92 93 protected: 94 void DoDispose () override; 95 96 void ReceiveMpdu (Ptr<WifiMacQueueItem> mpdu, RxSignalInfo rxSignalInfo, 97 const WifiTxVector& txVector, bool inAmpdu) override; 98 void EndReceiveAmpdu (Ptr<const WifiPsdu> psdu, const RxSignalInfo& rxSignalInfo, 99 const WifiTxVector& txVector, const std::vector<bool>& perMpduStatus) override; 100 Time GetTxDuration (uint32_t ppduPayloadSize, Mac48Address receiver, 101 const WifiTxParameters& txParams) const override; 102 bool SendMpduFromBaManager (Ptr<QosTxop> edca, Time availableTime, bool initialFrame) override; 103 104 /** 105 * Send a map of PSDUs as a DL MU PPDU. 106 * Note that both <i>psduMap</i> and <i>txParams</i> are moved to m_psduMap and 107 * m_txParams, respectively, and hence are left in an undefined state. 108 * 109 * \param psduMap the map of PSDUs to send 110 * \param txParams the TX parameters to use to transmit the PSDUs 111 */ 112 void SendPsduMapWithProtection (WifiPsduMap psduMap, WifiTxParameters& txParams); 113 114 /** 115 * Forward a map of PSDUs down to the PHY layer. 116 * 117 * \param psduMap the map of PSDUs to transmit 118 * \param txVector the TXVECTOR used to transmit the MU PPDU 119 */ 120 void ForwardPsduMapDown (WifiConstPsduMap psduMap, WifiTxVector& txVector); 121 122 /** 123 * Take the necessary actions after that some BlockAck frames are missing 124 * in response to a DL MU PPDU. This method must not be called if all the 125 * expected BlockAck frames were received. 126 * 127 * \param psduMap a pointer to PSDU map transmitted in a DL MU PPDU 128 * \param staMissedBlockAckFrom set of stations we missed a BlockAck frame from 129 * \param nSolicitedStations the number of stations solicited to send a TB PPDU 130 */ 131 virtual void BlockAcksInTbPpduTimeout (WifiPsduMap* psduMap, 132 const std::set<Mac48Address>* staMissedBlockAckFrom, 133 std::size_t nSolicitedStations); 134 135 /** 136 * Take the necessary actions after that some TB PPDUs are missing in 137 * response to Trigger Frame. This method must not be called if all the 138 * expected TB PPDUs were received. 139 * 140 * \param psduMap a pointer to PSDU map transmitted in a DL MU PPDU 141 * \param staMissedTbPpduFrom set of stations we missed a TB PPDU from 142 * \param nSolicitedStations the number of stations solicited to send a TB PPDU 143 */ 144 virtual void TbPpduTimeout (WifiPsduMap* psduMap, 145 const std::set<Mac48Address>* staMissedTbPpduFrom, 146 std::size_t nSolicitedStations); 147 148 /** 149 * Take the necessary actions after that a Block Ack is missing after a 150 * TB PPDU solicited through a Trigger Frame. 151 * 152 * \param psdu the PSDU in the TB PPDU 153 * \param txVector the TXVECTOR used to transmit the TB PPDU 154 */ 155 virtual void BlockAckAfterTbPpduTimeout (Ptr<WifiPsdu> psdu, const WifiTxVector& txVector); 156 157 /** 158 * Return a TXVECTOR for the UL frame that the station will send in response to 159 * the given Trigger frame, configured with the BSS color and transmit power 160 * level to use for the consequent HE TB PPDU. 161 * Note that this method should only be called by non-AP stations only. 162 * 163 * \param trigger the received Trigger frame 164 * \param triggerSender the MAC address of the AP sending the Trigger frame 165 * \return TXVECTOR for the HE TB PPDU frame 166 */ 167 WifiTxVector GetHeTbTxVector (CtrlTriggerHeader trigger, Mac48Address triggerSender) const; 168 169 /** 170 * Build a MU-BAR Trigger Frame starting from the TXVECTOR used to respond to 171 * the MU-BAR (in case of multiple responders, their TXVECTORs need to be 172 * "merged" into a single TXVECTOR) and from the BlockAckReq headers for 173 * every recipient. 174 * Note that the number of recipients must match the number of users addressed 175 * by the given TXVECTOR. 176 * 177 * \param responseTxVector the given TXVECTOR 178 * \param recipients the list of BlockAckReq headers indexed by the station's AID 179 * \return the MPDU containing the built MU-BAR 180 */ 181 Ptr<WifiMacQueueItem> PrepareMuBar (const WifiTxVector& responseTxVector, 182 std::map<uint16_t, CtrlBAckRequestHeader> recipients) const; 183 184 /** 185 * Send a Multi-STA Block Ack frame after the reception of some TB PPDUs. 186 * 187 * \param txParams the TX parameters for the Trigger Frame that solicited the TB PPDUs 188 */ 189 void SendMultiStaBlockAck (const WifiTxParameters& txParams); 190 191 /** 192 * Send QoS Null frames in response to a Basic or BSRP Trigger Frame. The number 193 * of QoS Null frames that are actually aggregated depends on the available time 194 * as indicated by the Trigger Frame and is at most 8 (one QoS Null frame per TID). 195 * 196 * \param trigger the Basic or BSRP Trigger Frame content 197 * \param hdr the MAC header of the Basic or BSRP Trigger Frame 198 */ 199 void SendQosNullFramesInTbPpdu (const CtrlTriggerHeader& trigger, const WifiMacHeader& hdr); 200 201 Ptr<ApWifiMac> m_apMac; //!< MAC pointer (null if not an AP) 202 Ptr<StaWifiMac> m_staMac; //!< MAC pointer (null if not a STA) 203 204 private: 205 /** 206 * Send the current PSDU map as a DL MU PPDU. 207 */ 208 void SendPsduMap (void); 209 210 /** 211 * Take the necessary actions when receiveing a Basic Trigger Frame. 212 * 213 * \param trigger the Basic Trigger Frame content 214 * \param hdr the MAC header of the Basic Trigger Frame 215 */ 216 void ReceiveBasicTrigger (const CtrlTriggerHeader& trigger, const WifiMacHeader& hdr); 217 218 WifiPsduMap m_psduMap; //!< the A-MPDU being transmitted 219 WifiTxParameters m_txParams; //!< the TX parameters for the current PPDU 220 Ptr<MultiUserScheduler> m_muScheduler; //!< Multi-user Scheduler (HE APs only) 221 Ptr<WifiMacQueueItem> m_triggerFrame; //!< Trigger Frame being sent 222 std::set<Mac48Address> m_staExpectTbPpduFrom; //!< set of stations expected to send a TB PPDU 223 EventId m_multiStaBaEvent; //!< Sending a Multi-STA BlockAck event 224 MuSnrTag m_muSnrTag; //!< Tag to attach to Multi-STA BlockAck frames 225 bool m_triggerFrameInAmpdu; //!< True if the received A-MPDU contains an MU-BAR 226 }; 227 228 } //namespace ns3 229 230 #endif /* HE_FRAME_EXCHANGE_MANAGER_H */ 231