1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2005,2006,2007 INRIA 4 * Copyright (c) 2020 Orange Labs 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation; 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * 19 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 20 * Rediet <getachew.redieteab@orange.com> 21 */ 22 23 #ifndef WIFI_PHY_COMMON_H 24 #define WIFI_PHY_COMMON_H 25 26 #include <ostream> 27 #include "ns3/fatal-error.h" 28 #include "ns3/ptr.h" 29 30 /** 31 * \file 32 * \ingroup wifi 33 * Declaration of the following enums: 34 * - ns3::WifiPreamble 35 * - ns3::WifiModulationClass 36 * - ns3::WifiPpduField 37 * - ns3::WifiPpduType 38 * - ns3::WifiPhyRxfailureReason 39 */ 40 41 namespace ns3 { 42 43 class WifiNetDevice; 44 class WifiMode; 45 class Time; 46 47 /** 48 * These constants define the various convolutional coding rates 49 * used for the OFDM transmission modes in the IEEE 802.11 50 * standard. DSSS (for example) rates which do not have an explicit 51 * coding stage in their generation should have this parameter set to 52 * WIFI_CODE_RATE_UNDEFINED. 53 * \note This typedef and constants could be converted to an enum or scoped 54 * enum if pybindgen is upgraded to support Callback<WifiCodeRate> 55 */ 56 typedef uint16_t WifiCodeRate; 57 const uint16_t WIFI_CODE_RATE_UNDEFINED = 0; //!< undefined coding rate 58 const uint16_t WIFI_CODE_RATE_1_2 = 1; //!< 1/2 coding rate 59 const uint16_t WIFI_CODE_RATE_2_3 = 2; //!< 2/3 coding rate 60 const uint16_t WIFI_CODE_RATE_3_4 = 3; //!< 3/4 coding rate 61 const uint16_t WIFI_CODE_RATE_5_6 = 4; //!< 5/6 coding rate 62 63 /** 64 * \ingroup wifi 65 * The type of preamble to be used by an IEEE 802.11 transmission 66 */ 67 enum WifiPreamble 68 { 69 WIFI_PREAMBLE_LONG, 70 WIFI_PREAMBLE_SHORT, 71 WIFI_PREAMBLE_HT_MF, 72 WIFI_PREAMBLE_VHT_SU, 73 WIFI_PREAMBLE_VHT_MU, 74 WIFI_PREAMBLE_HE_SU, 75 WIFI_PREAMBLE_HE_ER_SU, 76 WIFI_PREAMBLE_HE_MU, 77 WIFI_PREAMBLE_HE_TB 78 }; 79 80 /** 81 * \brief Stream insertion operator. 82 * 83 * \param os the stream 84 * \param preamble the preamble 85 * \returns a reference to the stream 86 */ 87 inline std::ostream& operator<< (std::ostream &os, const WifiPreamble &preamble) 88 { 89 switch (preamble) 90 { 91 case WIFI_PREAMBLE_LONG: 92 return (os << "LONG"); 93 case WIFI_PREAMBLE_SHORT: 94 return (os << "SHORT"); 95 case WIFI_PREAMBLE_HT_MF: 96 return (os << "HT_MF"); 97 case WIFI_PREAMBLE_VHT_SU: 98 return (os << "VHT_SU"); 99 case WIFI_PREAMBLE_VHT_MU: 100 return (os << "VHT_MU"); 101 case WIFI_PREAMBLE_HE_SU: 102 return (os << "HE_SU"); 103 case WIFI_PREAMBLE_HE_ER_SU: 104 return (os << "HE_ER_SU"); 105 case WIFI_PREAMBLE_HE_MU: 106 return (os << "HE_MU"); 107 case WIFI_PREAMBLE_HE_TB: 108 return (os << "HE_TB"); 109 default: 110 NS_FATAL_ERROR ("Invalid preamble"); 111 return (os << "INVALID"); 112 } 113 } 114 115 /** 116 * \ingroup wifi 117 * This enumeration defines the modulation classes per 118 * (Table 10-6 "Modulation classes"; IEEE 802.11-2016, with 119 * updated in 802.11ax/D6.0 as Table 10-9). 120 */ 121 enum WifiModulationClass 122 { 123 /** Modulation class unknown or unspecified. A WifiMode with this 124 WifiModulationClass has not been properly initialized. */ 125 WIFI_MOD_CLASS_UNKNOWN = 0, 126 WIFI_MOD_CLASS_DSSS, //!< DSSS (Clause 15) 127 WIFI_MOD_CLASS_HR_DSSS, //!< HR/DSSS (Clause 16) 128 WIFI_MOD_CLASS_ERP_OFDM, //!< ERP-OFDM (18.4) 129 WIFI_MOD_CLASS_OFDM, //!< OFDM (Clause 17) 130 WIFI_MOD_CLASS_HT, //!< HT (Clause 19) 131 WIFI_MOD_CLASS_VHT, //!< VHT (Clause 22) 132 WIFI_MOD_CLASS_HE //!< HE (Clause 27) 133 }; 134 135 /** 136 * \brief Stream insertion operator. 137 * 138 * \param os the stream 139 * \param modulation the WifiModulationClass 140 * \returns a reference to the stream 141 */ 142 inline std::ostream& operator<< (std::ostream &os, const WifiModulationClass &modulation) 143 { 144 switch (modulation) 145 { 146 case WIFI_MOD_CLASS_DSSS: 147 return (os << "DSSS"); 148 case WIFI_MOD_CLASS_HR_DSSS: 149 return (os << "HR/DSSS"); 150 case WIFI_MOD_CLASS_ERP_OFDM: 151 return (os << "ERP-OFDM"); 152 case WIFI_MOD_CLASS_OFDM: 153 return (os << "OFDM"); 154 case WIFI_MOD_CLASS_HT: 155 return (os << "HT"); 156 case WIFI_MOD_CLASS_VHT: 157 return (os << "VHT"); 158 case WIFI_MOD_CLASS_HE: 159 return (os << "HE"); 160 default: 161 NS_FATAL_ERROR ("Unknown modulation"); 162 return (os << "unknown"); 163 } 164 } 165 166 /** 167 * \ingroup wifi 168 * The type of PPDU field (grouped for convenience) 169 */ 170 enum WifiPpduField 171 { 172 /** 173 * SYNC + SFD fields for DSSS or ERP, 174 * shortSYNC + shortSFD fields for HR/DSSS or ERP, 175 * HT-GF-STF + HT-GF-LTF1 fields for HT-GF, 176 * L-STF + L-LTF fields otherwise. 177 */ 178 WIFI_PPDU_FIELD_PREAMBLE = 0, 179 /** 180 * PHY header field for DSSS or ERP, 181 * short PHY header field for HR/DSSS or ERP, 182 * field not present for HT-GF, 183 * L-SIG field or L-SIG + RL-SIG fields otherwise. 184 */ 185 WIFI_PPDU_FIELD_NON_HT_HEADER, 186 WIFI_PPDU_FIELD_HT_SIG, //!< HT-SIG field 187 WIFI_PPDU_FIELD_TRAINING, //!< STF + LTF fields (excluding those in preamble for HT-GF) 188 WIFI_PPDU_FIELD_SIG_A, //!< SIG-A field 189 WIFI_PPDU_FIELD_SIG_B, //!< SIG-B field 190 WIFI_PPDU_FIELD_DATA //!< data field 191 }; 192 193 /** 194 * \brief Stream insertion operator. 195 * 196 * \param os the stream 197 * \param field the PPDU field 198 * \returns a reference to the stream 199 */ 200 inline std::ostream& operator<< (std::ostream &os, const WifiPpduField &field) 201 { 202 switch (field) 203 { 204 case WIFI_PPDU_FIELD_PREAMBLE: 205 return (os << "preamble"); 206 case WIFI_PPDU_FIELD_NON_HT_HEADER: 207 return (os << "non-HT header"); 208 case WIFI_PPDU_FIELD_HT_SIG: 209 return (os << "HT-SIG"); 210 case WIFI_PPDU_FIELD_TRAINING: 211 return (os << "training"); 212 case WIFI_PPDU_FIELD_SIG_A: 213 return (os << "SIG-A"); 214 case WIFI_PPDU_FIELD_SIG_B: 215 return (os << "SIG-B"); 216 case WIFI_PPDU_FIELD_DATA: 217 return (os << "data"); 218 default: 219 NS_FATAL_ERROR ("Unknown field"); 220 return (os << "unknown"); 221 } 222 } 223 224 /** 225 * \ingroup wifi 226 * The type of PPDU (SU, DL MU, or UL MU) 227 */ 228 enum WifiPpduType 229 { 230 WIFI_PPDU_TYPE_SU = 0, 231 WIFI_PPDU_TYPE_DL_MU, 232 WIFI_PPDU_TYPE_UL_MU 233 }; 234 235 /** 236 * \brief Stream insertion operator. 237 * 238 * \param os the stream 239 * \param type the PPDU type 240 * \returns a reference to the stream 241 */ 242 inline std::ostream& operator<< (std::ostream &os, const WifiPpduType &type) 243 { 244 switch (type) 245 { 246 case WIFI_PPDU_TYPE_SU: 247 return (os << "SU"); 248 case WIFI_PPDU_TYPE_DL_MU: 249 return (os << "DL MU"); 250 case WIFI_PPDU_TYPE_UL_MU: 251 return (os << "UL MU"); 252 default: 253 NS_FATAL_ERROR ("Unknown type"); 254 return (os << "unknown"); 255 } 256 } 257 258 /** 259 * \ingroup wifi 260 * Enumeration of the possible reception failure reasons. 261 */ 262 enum WifiPhyRxfailureReason 263 { 264 UNKNOWN = 0, 265 UNSUPPORTED_SETTINGS, 266 CHANNEL_SWITCHING, 267 RXING, 268 TXING, 269 SLEEPING, 270 BUSY_DECODING_PREAMBLE, 271 PREAMBLE_DETECT_FAILURE, 272 RECEPTION_ABORTED_BY_TX, 273 L_SIG_FAILURE, 274 HT_SIG_FAILURE, 275 SIG_A_FAILURE, 276 SIG_B_FAILURE, 277 PREAMBLE_DETECTION_PACKET_SWITCH, 278 FRAME_CAPTURE_PACKET_SWITCH, 279 OBSS_PD_CCA_RESET, 280 HE_TB_PPDU_TOO_LATE, 281 FILTERED 282 }; 283 284 /** 285 * \brief Stream insertion operator. 286 * 287 * \param os the stream 288 * \param reason the failure reason 289 * \returns a reference to the stream 290 */ 291 inline std::ostream& operator<< (std::ostream &os, const WifiPhyRxfailureReason &reason) 292 { 293 switch (reason) 294 { 295 case UNSUPPORTED_SETTINGS: 296 return (os << "UNSUPPORTED_SETTINGS"); 297 case CHANNEL_SWITCHING: 298 return (os << "CHANNEL_SWITCHING"); 299 case RXING: 300 return (os << "RXING"); 301 case TXING: 302 return (os << "TXING"); 303 case SLEEPING: 304 return (os << "SLEEPING"); 305 case BUSY_DECODING_PREAMBLE: 306 return (os << "BUSY_DECODING_PREAMBLE"); 307 case PREAMBLE_DETECT_FAILURE: 308 return (os << "PREAMBLE_DETECT_FAILURE"); 309 case RECEPTION_ABORTED_BY_TX: 310 return (os << "RECEPTION_ABORTED_BY_TX"); 311 case L_SIG_FAILURE: 312 return (os << "L_SIG_FAILURE"); 313 case HT_SIG_FAILURE: 314 return (os << "HT_SIG_FAILURE"); 315 case SIG_A_FAILURE: 316 return (os << "SIG_A_FAILURE"); 317 case SIG_B_FAILURE: 318 return (os << "SIG_B_FAILURE"); 319 case PREAMBLE_DETECTION_PACKET_SWITCH: 320 return (os << "PREAMBLE_DETECTION_PACKET_SWITCH"); 321 case FRAME_CAPTURE_PACKET_SWITCH: 322 return (os << "FRAME_CAPTURE_PACKET_SWITCH"); 323 case OBSS_PD_CCA_RESET: 324 return (os << "OBSS_PD_CCA_RESET"); 325 case HE_TB_PPDU_TOO_LATE: 326 return (os << "HE_TB_PPDU_TOO_LATE"); 327 case FILTERED: 328 return (os << "FILTERED"); 329 case UNKNOWN: 330 default: 331 NS_FATAL_ERROR ("Unknown reason"); 332 return (os << "UNKNOWN"); 333 } 334 } 335 336 /** 337 * Convert the guard interval to nanoseconds based on the WifiMode. 338 * 339 * \param mode the WifiMode 340 * \param device pointer to the WifiNetDevice object 341 * 342 * \return the guard interval duration in nanoseconds 343 */ 344 uint16_t ConvertGuardIntervalToNanoSeconds (WifiMode mode, const Ptr<WifiNetDevice> device); 345 346 /** 347 * Convert the guard interval to nanoseconds based on the WifiMode. 348 * 349 * \param mode the WifiMode 350 * \param htShortGuardInterval whether HT/VHT short guard interval is enabled 351 * \param heGuardInterval the HE guard interval duration 352 * 353 * \return the guard interval duration in nanoseconds 354 */ 355 uint16_t ConvertGuardIntervalToNanoSeconds (WifiMode mode, bool htShortGuardInterval, Time heGuardInterval); 356 357 /** 358 * Return the preamble to be used for the transmission. 359 * 360 * \param modulation the modulation selected for the transmission 361 * \param useShortPreamble whether short preamble should be used 362 * 363 * \return the preamble to be used for the transmission 364 */ 365 WifiPreamble GetPreambleForTransmission (WifiModulationClass modulation, bool useShortPreamble); 366 367 /** 368 * Return the channel width that corresponds to the selected mode (instead of 369 * letting the PHY's default channel width). This is especially useful when using 370 * non-HT modes with HT/VHT/HE capable stations (with default width above 20 MHz). 371 * 372 * \param mode selected WifiMode 373 * \param maxSupportedChannelWidth maximum channel width supported by the PHY layer 374 * \return channel width adapted to the selected mode 375 */ 376 uint16_t GetChannelWidthForTransmission (WifiMode mode, uint16_t maxSupportedChannelWidth); 377 378 /** 379 * Return whether the modulation class of the selected mode for the 380 * control answer frame is allowed. 381 * 382 * \param modClassReq modulation class of the request frame 383 * \param modClassAnswer modulation class of the answer frame 384 * 385 * \return true if the modulation class of the selected mode for the 386 * control answer frame is allowed, false otherwise 387 */ 388 bool IsAllowedControlAnswerModulationClass (WifiModulationClass modClassReq, WifiModulationClass modClassAnswer); 389 390 /** 391 * Get the maximum PPDU duration (see Section 10.14 of 802.11-2016) for 392 * the PHY layers defining the aPPDUMaxTime characteristic (HT, VHT and HE). 393 * Return zero otherwise. 394 * 395 * \param preamble the preamble type 396 * 397 * \return the maximum PPDU duration, if defined, and zero otherwise 398 */ 399 Time GetPpduMaxTime (WifiPreamble preamble); 400 401 /** 402 * Return true if a preamble corresponds to a multi-user transmission. 403 * 404 * \param preamble the preamble 405 * \return true if the provided preamble corresponds to a multi-user transmission 406 */ 407 bool IsMu (WifiPreamble preamble); 408 409 /** 410 * Return true if a preamble corresponds to a downlink multi-user transmission. 411 * 412 * \param preamble the preamble 413 * \return true if the provided preamble corresponds to a downlink multi-user transmission 414 */ 415 bool IsDlMu (WifiPreamble preamble); 416 417 /** 418 * Return true if a preamble corresponds to a uplink multi-user transmission. 419 * 420 * \param preamble the preamble 421 * \return true if the provided preamble corresponds to a uplink multi-user transmission 422 */ 423 bool IsUlMu (WifiPreamble preamble); 424 425 } //namespace ns3 426 427 #endif /* WIFI_PHY_COMMON_H */ 428