1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2018 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_RU_H 22 #define HE_RU_H 23 24 #include <map> 25 #include <vector> 26 #include <cstdint> 27 #include <ostream> 28 29 namespace ns3 { 30 31 32 /** 33 * This class stores the subcarrier groups of all the available HE RUs. 34 */ 35 class HeRu 36 { 37 public: 38 /** 39 * The different HE Resource Unit (RU) types. 40 */ 41 enum RuType 42 { 43 RU_26_TONE = 0, 44 RU_52_TONE, 45 RU_106_TONE, 46 RU_242_TONE, 47 RU_484_TONE, 48 RU_996_TONE, 49 RU_2x996_TONE 50 }; 51 52 /// (lowest index, highest index) pair defining a subcarrier range 53 typedef std::pair<int16_t, int16_t> SubcarrierRange; 54 55 /// a vector of subcarrier ranges defining a subcarrier group 56 typedef std::vector<SubcarrierRange> SubcarrierGroup; 57 58 59 /** 60 * RU Specification. Stores the information carried by the RU Allocation subfield 61 * of the User Info field of Trigger frames (see 9.3.1.22.1 of 802.11ax D8.0). 62 * Note that primary80MHz must be true if ruType is RU_2x996_TONE. 63 * Internally, this class also stores the RU PHY index (ranging from 1 to the number 64 * of RUs of the given type in a channel of the considered width), so that this class 65 * contains all the information needed to locate the RU in a 160 MHz channel. 66 */ 67 class RuSpec 68 { 69 public: 70 /** 71 * Default constructor 72 */ 73 RuSpec (); 74 /** 75 * Constructor 76 * 77 * \param ruType the RU type 78 * \param index the RU index (starting at 1) 79 * \param primary80MHz whether the RU is allocated in the primary 80MHz channel 80 */ 81 RuSpec (RuType ruType, std::size_t index, bool primary80MHz); 82 83 /** 84 * Get the RU type 85 * 86 * \return the RU type 87 */ 88 RuType GetRuType (void) const; 89 /** 90 * Get the RU index 91 * 92 * \return the RU index 93 */ 94 std::size_t GetIndex (void) const; 95 /** 96 * Get the primary 80 MHz flag 97 * 98 * \return true if the RU is in the primary 80 MHz channel and false otherwise 99 */ 100 bool GetPrimary80MHz (void) const; 101 /** 102 * Set the RU PHY index 103 * 104 * \param bw the width of the channel of which the RU is part (in MHz) 105 * \param p20Index the index of the primary20 channel 106 */ 107 void SetPhyIndex (uint16_t bw, uint8_t p20Index); 108 /** 109 * Return true if the RU PHY index has been set, false otherwise 110 * 111 * \return true if the RU PHY index has been set, false otherwise 112 */ 113 bool IsPhyIndexSet (void) const; 114 /** 115 * Get the RU PHY index 116 * 117 * \return the RU PHY index 118 */ 119 std::size_t GetPhyIndex (void) const; 120 121 private: 122 RuType m_ruType; //!< RU type 123 std::size_t m_index; /**< RU index (starting at 1) as defined by Tables 27-7 124 to 27-9 of 802.11ax D8.0 */ 125 bool m_primary80MHz; //!< true if the RU is allocated in the primary 80MHz channel 126 std::size_t m_phyIndex; /**< the RU PHY index, which is used to indicate whether an 127 RU is located in the lower half or the higher half of 128 a 160MHz channel. For channel widths less than 160MHz, 129 the RU PHY index equals the RU index */ 130 }; 131 132 133 /** 134 * Get the number of distinct RUs of the given type (number of tones) 135 * available in a HE PPDU of the given bandwidth. 136 * 137 * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) 138 * \param ruType the RU type (number of tones) 139 * \return the number of distinct RUs available 140 */ 141 static std::size_t GetNRus (uint16_t bw, RuType ruType); 142 143 /** 144 * Get the set of distinct RUs of the given type (number of tones) 145 * available in a HE PPDU of the given bandwidth. 146 * 147 * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) 148 * \param ruType the RU type (number of tones) 149 * \return the set of distinct RUs available 150 */ 151 static std::vector<HeRu::RuSpec> GetRusOfType (uint16_t bw, HeRu::RuType ruType); 152 153 /** 154 * Get the set of 26-tone RUs that can be additionally allocated if the given 155 * bandwidth is split in RUs of the given type. 156 * 157 * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) 158 * \param ruType the RU type (number of tones) 159 * \return the set of 26-tone RUs that can be additionally allocated 160 */ 161 static std::vector<HeRu::RuSpec> GetCentral26TonesRus (uint16_t bw, HeRu::RuType ruType); 162 163 /** 164 * Get the subcarrier group of the RU having the given PHY index among all the 165 * RUs of the given type (number of tones) available in a HE PPDU of the 166 * given bandwidth. A subcarrier group is defined as one or more pairs 167 * indicating the lowest frequency index and the highest frequency index. 168 * Note that for channel width of 160 MHz the returned range is relative to 169 * the 160 MHz channel (i.e. -1012 to 1012). The PHY index parameter is used to 170 * distinguish between lower and higher 80 MHz subchannels. 171 * 172 * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) 173 * \param ruType the RU type (number of tones) 174 * \param phyIndex the PHY index (starting at 1) of the RU 175 * \return the subcarrier range of the specified RU 176 */ 177 static SubcarrierGroup GetSubcarrierGroup (uint16_t bw, RuType ruType, std::size_t phyIndex); 178 179 /** 180 * Check whether the given RU overlaps with the given set of RUs. 181 * Note that for channel width of 160 MHz the returned range is relative to 182 * the 160 MHz channel (i.e. -1012 to 1012). 183 * 184 * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) 185 * \param ru the given RU allocation 186 * \param v the given set of RUs 187 * \return true if the given RU overlaps with the given set of RUs. 188 */ 189 static bool DoesOverlap (uint16_t bw, RuSpec ru, const std::vector<RuSpec> &v); 190 191 /** 192 * Check whether the given RU overlaps with the given tone ranges. 193 * Note that for channel width of 160 MHz the returned range is relative to 194 * the 160 MHz channel (i.e. -1012 to 1012). 195 * 196 * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) 197 * \param ru the given RU allocation 198 * \param toneRanges the given set of tone ranges 199 * \return true if the given RU overlaps with the given set of tone ranges. 200 */ 201 static bool DoesOverlap (uint16_t bw, RuSpec ru, const SubcarrierGroup &toneRanges); 202 203 /** 204 * Find the RU allocation of the given RU type overlapping the given 205 * reference RU allocation. 206 * Note that an assert is generated if the RU allocation is not found. 207 * 208 * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) 209 * \param referenceRu the reference RU allocation 210 * \param searchedRuType the searched RU type 211 * \return the searched RU allocation. 212 */ 213 static RuSpec FindOverlappingRu (uint16_t bw, RuSpec referenceRu, RuType searchedRuType); 214 215 /** 216 * Get the approximate bandwidth occupied by a RU. 217 * 218 * \param ruType the RU type 219 * \return the approximate bandwidth (in MHz) occupied by the RU 220 */ 221 static uint16_t GetBandwidth (RuType ruType); 222 223 /** 224 * Get the RU corresponding to the approximate bandwidth. 225 * 226 * \param bandwidth the approximate bandwidth (in MHz) occupied by the RU 227 * \return the RU type 228 */ 229 static RuType GetRuType (uint16_t bandwidth); 230 231 /** 232 * Given the channel bandwidth and the number of stations candidate for being 233 * assigned an RU, maximize the number of candidate stations that can be assigned 234 * an RU subject to the constraint that all the stations must be assigned an RU 235 * of the same size (in terms of number of tones). 236 * 237 * \param bandwidth the channel bandwidth in MHz 238 * \param nStations the number of candidate stations. On return, it is set to 239 * the number of stations that are assigned an RU 240 * \param[out] nCentral26TonesRus the number of additional 26-tone RUs that can be 241 * allocated if the returned RU size is greater than 26 tones 242 * \return the RU type 243 */ 244 static RuType GetEqualSizedRusForStations (uint16_t bandwidth, std::size_t& nStations, 245 std::size_t& nCentral26TonesRus); 246 247 /// (bandwidth, number of tones) pair 248 typedef std::pair<uint8_t, RuType> BwTonesPair; 249 250 /// map (bandwidth, number of tones) pairs to the group of subcarrier ranges 251 typedef std::map<BwTonesPair, std::vector<SubcarrierGroup> > SubcarrierGroups; 252 253 /// Subcarrier groups for all RUs (with indices being applicable to primary 80 MHz channel) 254 static const SubcarrierGroups m_heRuSubcarrierGroups; 255 }; 256 257 /** 258 * \brief Stream insertion operator. 259 * 260 * \param os the stream 261 * \param ruType the RU type 262 * \returns a reference to the stream 263 */ 264 std::ostream& operator<< (std::ostream& os, const HeRu::RuType &ruType); 265 266 /** 267 * \brief Stream insertion operator. 268 * 269 * \param os the stream 270 * \param ru the RU 271 * \returns a reference to the stream 272 */ 273 std::ostream& operator<< (std::ostream& os, const HeRu::RuSpec &ru); 274 275 } //namespace ns3 276 277 #endif /* HE_RU_H */ 278