1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2005,2006 INRIA 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 19 */ 20 21 #ifndef INTERFERENCE_HELPER_H 22 #define INTERFERENCE_HELPER_H 23 24 #include "phy-entity.h" 25 26 namespace ns3 { 27 28 class WifiPpdu; 29 class WifiPsdu; 30 class ErrorRateModel; 31 32 /** 33 * \ingroup wifi 34 * \brief handles interference calculations 35 * \brief signal event for a PPDU. 36 */ 37 class Event : public SimpleRefCount<Event> 38 { 39 public: 40 /** 41 * Create an Event with the given parameters. Note that <i>rxPower</i> will 42 * be moved into this object. 43 * 44 * \param ppdu the PPDU 45 * \param txVector the TXVECTOR 46 * \param duration duration of the PPDU 47 * \param rxPower the received power per band (W) 48 */ 49 Event (Ptr<const WifiPpdu> ppdu, const WifiTxVector& txVector, Time duration, RxPowerWattPerChannelBand&& rxPower); 50 ~Event (); 51 52 /** 53 * Return the PPDU. 54 * 55 * \return the PPDU 56 */ 57 Ptr<const WifiPpdu> GetPpdu (void) const; 58 /** 59 * Return the start time of the signal. 60 * 61 * \return the start time of the signal 62 */ 63 Time GetStartTime (void) const; 64 /** 65 * Return the end time of the signal. 66 * 67 * \return the end time of the signal 68 */ 69 Time GetEndTime (void) const; 70 /** 71 * Return the duration of the signal. 72 * 73 * \return the duration of the signal 74 */ 75 Time GetDuration (void) const; 76 /** 77 * Return the total received power (W). 78 * 79 * \return the total received power (W) 80 */ 81 double GetRxPowerW (void) const; 82 /** 83 * Return the received power (W) for a given band. 84 * 85 * \param band the band for which the power should be returned 86 * \return the received power (W) for a given band 87 */ 88 double GetRxPowerW (WifiSpectrumBand band) const; 89 /** 90 * Return the received power (W) for all bands. 91 * 92 * \return the received power (W) for all bands. 93 */ 94 const RxPowerWattPerChannelBand& GetRxPowerWPerBand (void) const; 95 /** 96 * Return the TXVECTOR of the PPDU. 97 * 98 * \return the TXVECTOR of the PPDU 99 */ 100 const WifiTxVector& GetTxVector (void) const; 101 /** 102 * Update the received power (W) for all bands, i.e. add up the received power 103 * to the current received power, for each band. 104 * 105 * \param rxPower the received power (W) for all bands. 106 */ 107 void UpdateRxPowerW (const RxPowerWattPerChannelBand& rxPower); 108 109 110 private: 111 Ptr<const WifiPpdu> m_ppdu; //!< PPDU 112 WifiTxVector m_txVector; //!< TXVECTOR 113 Time m_startTime; //!< start time 114 Time m_endTime; //!< end time 115 RxPowerWattPerChannelBand m_rxPowerW; //!< received power in watts per band 116 }; 117 118 /** 119 * \brief Stream insertion operator. 120 * 121 * \param os the stream 122 * \param event the event 123 * \returns a reference to the stream 124 */ 125 std::ostream& operator<< (std::ostream& os, const Event &event); 126 127 128 /** 129 * \ingroup wifi 130 * \brief handles interference calculations 131 */ 132 class InterferenceHelper 133 { 134 public: 135 InterferenceHelper (); 136 ~InterferenceHelper (); 137 138 /** 139 * Add a frequency band. 140 * 141 * \param band the band to be created 142 */ 143 void AddBand (WifiSpectrumBand band); 144 145 /** 146 * Remove the frequency bands. 147 */ 148 void RemoveBands (void); 149 150 /** 151 * Set the noise figure. 152 * 153 * \param value noise figure in linear scale 154 */ 155 void SetNoiseFigure (double value); 156 /** 157 * Set the error rate model for this interference helper. 158 * 159 * \param rate Error rate model 160 */ 161 void SetErrorRateModel (const Ptr<ErrorRateModel> rate); 162 163 /** 164 * Return the error rate model. 165 * 166 * \return Error rate model 167 */ 168 Ptr<ErrorRateModel> GetErrorRateModel (void) const; 169 /** 170 * Set the number of RX antennas in the receiver corresponding to this 171 * interference helper. 172 * 173 * \param rx the number of RX antennas 174 */ 175 void SetNumberOfReceiveAntennas (uint8_t rx); 176 177 /** 178 * \param energyW the minimum energy (W) requested 179 * \param band identify the requested band 180 * 181 * \returns the expected amount of time the observed 182 * energy on the medium for a given band will 183 * be higher than the requested threshold. 184 */ 185 Time GetEnergyDuration (double energyW, WifiSpectrumBand band); 186 187 /** 188 * Add the PPDU-related signal to interference helper. 189 * 190 * \param ppdu the PPDU 191 * \param txVector the TXVECTOR 192 * \param duration the PPDU duration 193 * \param rxPower received power per band (W) 194 * \param isStartOfdmaRxing flag whether the event corresponds to the start of the OFDMA payload reception (only used for UL-OFDMA) //TODO simplify this once WifiPpdu is subclassed by adding an attribute 195 * 196 * \return Event 197 */ 198 Ptr<Event> Add (Ptr<const WifiPpdu> ppdu, const WifiTxVector& txVector, Time duration, RxPowerWattPerChannelBand& rxPower, bool isStartOfdmaRxing = false); 199 200 /** 201 * Add a non-Wifi signal to interference helper. 202 * \param duration the duration of the signal 203 * \param rxPower received power per band (W) 204 */ 205 void AddForeignSignal (Time duration, RxPowerWattPerChannelBand& rxPower); 206 /** 207 * Calculate the SNIR at the start of the payload and accumulate 208 * all SNIR changes in the SNIR vector for each MPDU of an A-MPDU. 209 * This workaround is required in order to provide one PER per MPDU, for 210 * reception success/failure evaluation, while hiding aggregation details from 211 * this class. 212 * 213 * \param event the event corresponding to the first time the corresponding PPDU arrives 214 * \param channelWidth the channel width used to transmit the PSDU (in MHz) 215 * \param band identify the band used by the PSDU 216 * \param staId the station ID of the PSDU (only used for MU) 217 * \param relativeMpduStartStop the time window (pair of start and end times) of PHY payload to focus on 218 * 219 * \return struct of SNR and PER (with PER being evaluated over the provided time window) 220 */ 221 struct PhyEntity::SnrPer CalculatePayloadSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band, 222 uint16_t staId, std::pair<Time, Time> relativeMpduStartStop) const; 223 /** 224 * Calculate the SNIR for the event (starting from now until the event end). 225 * 226 * \param event the event corresponding to the first time the corresponding PPDU arrives 227 * \param channelWidth the channel width (in MHz) 228 * \param nss the number of spatial streams 229 * \param band identify the band used by the PSDU 230 * 231 * \return the SNR for the PPDU in linear scale 232 */ 233 double CalculateSnr (Ptr<Event> event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const; 234 /** 235 * Calculate the SNIR at the start of the PHY header and accumulate 236 * all SNIR changes in the SNIR vector. 237 * 238 * \param event the event corresponding to the first time the corresponding PPDU arrives 239 * \param channelWidth the channel width (in MHz) for header measurement 240 * \param band identify the band used by the PSDU 241 * \param header the PHY header to consider 242 * 243 * \return struct of SNR and PER 244 */ 245 struct PhyEntity::SnrPer CalculatePhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band, 246 WifiPpduField header) const; 247 248 /** 249 * Notify that RX has started. 250 */ 251 void NotifyRxStart (); 252 /** 253 * Notify that RX has ended. 254 * 255 * \param endTime the end time of the signal 256 */ 257 void NotifyRxEnd (Time endTime); 258 /** 259 * Erase all events. 260 */ 261 void EraseEvents (void); 262 263 /** 264 * Update event to scale its received power (W) per band. 265 * 266 * \param event the event to be updated 267 * \param rxPower the received power (W) per band to be added to the current event 268 */ 269 void UpdateEvent (Ptr<Event> event, const RxPowerWattPerChannelBand& rxPower); 270 271 272 protected: 273 /** 274 * Calculate SNR (linear ratio) from the given signal power and noise+interference power. 275 * 276 * \param signal signal power, W 277 * \param noiseInterference noise and interference power, W 278 * \param channelWidth signal width (MHz) 279 * \param nss the number of spatial streams 280 * 281 * \return SNR in linear scale 282 */ 283 double CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth, uint8_t nss) const; 284 /** 285 * Calculate the success rate of the chunk given the SINR, duration, and TXVECTOR. 286 * The duration and TXVECTOR are used to calculate how many bits are present in the chunk. 287 * 288 * \param snir the SINR 289 * \param duration the duration of the chunk 290 * \param mode the WifiMode 291 * \param txVector the TXVECTOR 292 * \param field the PPDU field to which the chunk belongs to 293 * 294 * \return the success rate 295 */ 296 double CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, const WifiTxVector& txVector, WifiPpduField field) const; 297 /** 298 * Calculate the success rate of the payload chunk given the SINR, duration, and TXVECTOR. 299 * The duration and TXVECTOR are used to calculate how many bits are present in the payload chunk. 300 * 301 * \param snir the SINR 302 * \param duration the duration of the chunk 303 * \param txVector the TXVECTOR 304 * \param staId the station ID of the PSDU (only used for MU) 305 * 306 * \return the success rate 307 */ 308 double CalculatePayloadChunkSuccessRate (double snir, Time duration, const WifiTxVector& txVector, uint16_t staId = SU_STA_ID) const; 309 310 private: 311 /** 312 * Noise and Interference (thus Ni) event. 313 */ 314 class NiChange 315 { 316 public: 317 /** 318 * Create a NiChange at the given time and the amount of NI change. 319 * 320 * \param power the power in watts 321 * \param event causes this NI change 322 */ 323 NiChange (double power, Ptr<Event> event); 324 ~NiChange (); 325 /** 326 * Return the power 327 * 328 * \return the power in watts 329 */ 330 double GetPower (void) const; 331 /** 332 * Add a given amount of power. 333 * 334 * \param power the power to be added to the existing value in watts 335 */ 336 void AddPower (double power); 337 /** 338 * Return the event causes the corresponding NI change 339 * 340 * \return the event 341 */ 342 Ptr<Event> GetEvent (void) const; 343 344 345 private: 346 double m_power; ///< power in watts 347 Ptr<Event> m_event; ///< event 348 }; 349 350 /** 351 * typedef for a multimap of NiChange 352 */ 353 typedef std::multimap<Time, NiChange> NiChanges; 354 355 /** 356 * Map of NiChanges per band 357 */ 358 typedef std::map <WifiSpectrumBand, NiChanges> NiChangesPerBand; 359 360 /** 361 * Append the given Event. 362 * 363 * \param event the event to be appended 364 * \param isStartOfdmaRxing flag whether event corresponds to the start of the OFDMA payload reception (only used for UL-OFDMA) 365 */ 366 void AppendEvent (Ptr<Event> event, bool isStartOfdmaRxing); 367 368 /** 369 * Calculate noise and interference power in W. 370 * 371 * \param event the event 372 * \param nis the NiChanges 373 * \param band the band 374 * 375 * \return noise and interference power 376 */ 377 double CalculateNoiseInterferenceW (Ptr<Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const; 378 /** 379 * Calculate the error rate of the given PHY payload only in the provided time 380 * window (thus enabling per MPDU PER information). The PHY payload can be divided into 381 * multiple chunks (e.g. due to interference from other transmissions). 382 * 383 * \param event the event 384 * \param channelWidth the channel width used to transmit the PSDU (in MHz) 385 * \param nis the NiChanges 386 * \param band identify the band used by the PSDU 387 * \param staId the station ID of the PSDU (only used for MU) 388 * \param window time window (pair of start and end times) of PHY payload to focus on 389 * 390 * \return the error rate of the payload 391 */ 392 double CalculatePayloadPer (Ptr<const Event> event, uint16_t channelWidth, NiChangesPerBand *nis, WifiSpectrumBand band, 393 uint16_t staId, std::pair<Time, Time> window) const; 394 /** 395 * Calculate the error rate of the PHY header. The PHY header 396 * can be divided into multiple chunks (e.g. due to interference from other transmissions). 397 * 398 * \param event the event 399 * \param nis the NiChanges 400 * \param channelWidth the channel width (in MHz) for header measurement 401 * \param band the band 402 * \param header the PHY header to consider 403 * 404 * \return the error rate of the HT PHY header 405 */ 406 double CalculatePhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, 407 uint16_t channelWidth, WifiSpectrumBand band, 408 WifiPpduField header) const; 409 /** 410 * Calculate the success rate of the PHY header sections for the provided event. 411 * 412 * \param event the event 413 * \param nis the NiChanges 414 * \param channelWidth the channel width (in MHz) for header measurement 415 * \param band the band 416 * \param phyHeaderSections the map of PHY header sections (\see PhyEntity::PhyHeaderSections) 417 * 418 * \return the success rate of the PHY header sections 419 */ 420 double CalculatePhyHeaderSectionPsr (Ptr<const Event> event, NiChangesPerBand *nis, 421 uint16_t channelWidth, WifiSpectrumBand band, 422 PhyEntity::PhyHeaderSections phyHeaderSections) const; 423 424 double m_noiseFigure; //!< noise figure (linear) 425 Ptr<ErrorRateModel> m_errorRateModel; //!< error rate model 426 uint8_t m_numRxAntennas; //!< the number of RX antennas in the corresponding receiver 427 NiChangesPerBand m_niChangesPerBand; //!< NI Changes for each band 428 std::map <WifiSpectrumBand, double> m_firstPowerPerBand; //!< first power of each band in watts 429 bool m_rxing; //!< flag whether it is in receiving state 430 431 /** 432 * Returns an iterator to the first NiChange that is later than moment 433 * 434 * \param moment time to check from 435 * \param niIt iterator of the band to check 436 * \returns an iterator to the list of NiChanges 437 */ 438 NiChanges::iterator GetNextPosition (Time moment, NiChangesPerBand::iterator niIt); 439 /** 440 * Returns an iterator to the last NiChange that is before than moment 441 * 442 * \param moment time to check from 443 * \param niIt iterator of the band to check 444 * \returns an iterator to the list of NiChanges 445 */ 446 NiChanges::iterator GetPreviousPosition (Time moment, NiChangesPerBand::iterator niIt); 447 448 /** 449 * Add NiChange to the list at the appropriate position and 450 * return the iterator of the new event. 451 * 452 * \param moment time to check from 453 * \param change the NiChange to add 454 * \param niIt iterator of the band to check 455 * \returns the iterator of the new event 456 */ 457 NiChanges::iterator AddNiChangeEvent (Time moment, NiChange change, NiChangesPerBand::iterator niIt); 458 }; 459 460 } //namespace ns3 461 462 #endif /* INTERFERENCE_HELPER_H */ 463