1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Orange Labs
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  * Authors: Rediet <getachew.redieteab@orange.com>
19  *          Sébastien Deronne <sebastien.deronne@gmail.com> (for logic ported from wifi-phy and spectrum-wifi-phy)
20  *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr> (for logic ported from wifi-phy)
21  */
22 
23 #ifndef PHY_ENTITY_H
24 #define PHY_ENTITY_H
25 
26 #include "wifi-mpdu-type.h"
27 #include "wifi-tx-vector.h"
28 #include "wifi-phy-band.h"
29 #include "wifi-ppdu.h"
30 #include "wifi-mpdu-type.h"
31 #include "wifi-ppdu.h"
32 #include "ns3/event-id.h"
33 #include "ns3/simple-ref-count.h"
34 #include "ns3/nstime.h"
35 #include "ns3/wifi-spectrum-value-helper.h"
36 #include <list>
37 #include <map>
38 #include <tuple>
39 
40 /**
41  * \file
42  * \ingroup wifi
43  * Declaration of:
44  * - ns3::PhyEntity class
45  * - ns3::SignalNoiseDbm, ns3::MpduInfo, and ns3::RxSignalInfo structs
46  * - ns3::RxPowerWattPerChannelBand typedef
47  */
48 
49 namespace ns3 {
50 
51 /// SignalNoiseDbm structure
52 struct SignalNoiseDbm
53 {
54   double signal; ///< signal strength in dBm
55   double noise;  ///< noise power in dBm
56 };
57 
58 /// MpduInfo structure
59 struct MpduInfo
60 {
61   MpduType type;          ///< type of MPDU
62   uint32_t mpduRefNumber; ///< MPDU ref number
63 };
64 
65 /// RxSignalInfo structure containing info on the received signal
66 struct RxSignalInfo
67 {
68   double snr;  ///< SNR in linear scale
69   double rssi; ///< RSSI in dBm
70 };
71 
72 /**
73  * A map of the received power (Watts) for each band
74  */
75 typedef std::map <WifiSpectrumBand, double> RxPowerWattPerChannelBand;
76 
77 class WifiPsdu;
78 class WifiPhy;
79 class InterferenceHelper;
80 class Event;
81 class WifiPhyStateHelper;
82 class WifiPsdu;
83 class WifiPpdu;
84 
85 /**
86  * \brief Abstract class for PHY entities
87  * \ingroup wifi
88  *
89  * This class enables to have a unique set of APIs
90  * to be used by each PHY entity, corresponding to
91  * the different amendments of the IEEE 802.11 standard.
92  */
93 class PhyEntity : public SimpleRefCount<PhyEntity>
94 {
95 public:
96 
97   /**
98    * Action to perform in case of RX failure.
99    */
100   enum PhyRxFailureAction
101   {
102     DROP = 0, //!< drop PPDU and set CCA_BUSY
103     ABORT,    //!< abort reception of PPDU
104     IGNORE    //!< ignore the reception
105   };
106 
107   /**
108    * Status of the reception of the PPDU field.
109    */
110   struct PhyFieldRxStatus
111   {
112     /* *NS_CHECK_STYLE_OFF* */
113     bool isSuccess {true}; //!< outcome (\c true if success) of the reception
114     WifiPhyRxfailureReason reason {UNKNOWN}; //!< failure reason
115     PhyRxFailureAction actionIfFailure {DROP}; //!< action to perform in case of failure \see PhyRxFailureAction
116     /**
117      * Constructor setting outcome of reception.
118      *
119      * \param s \c true if success
120      */
PhyFieldRxStatusPhyFieldRxStatus121     PhyFieldRxStatus (bool s) : isSuccess (s) {};
122     /**
123      * Constructor.
124      *
125      * \param s \c true if success
126      * \param r reason of failure
127      * \param a action to perform in case of failure
128      */
PhyFieldRxStatusPhyFieldRxStatus129     PhyFieldRxStatus (bool s, WifiPhyRxfailureReason r, PhyRxFailureAction a) : isSuccess (s), reason (r), actionIfFailure (a) {};
130     /* *NS_CHECK_STYLE_ON* */
131   };
132 
133   /**
134    * A struct for both SNR and PER
135    */
136   struct SnrPer
137   {
138     double snr {0.0}; ///< SNR in linear scale
139     double per {1.0}; ///< PER
140     /**
141      * Default constructor.
142      */
SnrPerSnrPer143     SnrPer () {};
144     /**
145      * Constructor for SnrPer.
146      *
147      * \param s the SNR in linear scale
148      * \param p the PER
149      */
SnrPerSnrPer150     SnrPer (double s, double p) : snr (s), per (p) {};
151   };
152 
153   /**
154    * Destructor for PHY entity
155    */
156   virtual ~PhyEntity ();
157 
158   /**
159    * Set the WifiPhy owning this PHY entity.
160    *
161    * \param wifiPhy the WifiPhy owning this PHY entity
162    */
163   void SetOwner (Ptr<WifiPhy> wifiPhy);
164 
165   /**
166    * Check if the WifiMode is supported.
167    *
168    * \param mode the WifiMode to check
169    * \return true if the WifiMode is supported,
170    *         false otherwise
171    */
172   virtual bool IsModeSupported (WifiMode mode) const;
173   /**
174    * \return the number of WifiModes supported by this entity
175    */
176   virtual uint8_t GetNumModes (void) const;
177 
178   /**
179    * Get the WifiMode corresponding to the given MCS index.
180    *
181    * \param index the index of the MCS
182    * \return the WifiMode corresponding to the MCS index
183    *
184    * This method should be used only for HtPhy and child classes.
185    */
186   virtual WifiMode GetMcs (uint8_t index) const;
187   /**
188    * Check if the WifiMode corresponding to the given MCS index is supported.
189    *
190    * \param index the index of the MCS
191    * \return true if the WifiMode corresponding to the MCS index is supported,
192    *         false otherwise
193    *
194    * Will return false for non-MCS modes.
195    */
196   virtual bool IsMcsSupported (uint8_t index) const;
197   /**
198    * Check if the WifiModes handled by this PHY are MCSs.
199    *
200    * \return true if the handled WifiModes are MCSs,
201    *         false if they are non-MCS modes
202    */
203   virtual bool HandlesMcsModes (void) const;
204 
205   /**
206    * Get the WifiMode for the SIG field specified by the PPDU field.
207    *
208    * \param field the PPDU field
209    * \param txVector the transmission parameters
210    *
211    * \return the WifiMode used for the SIG field
212    */
213   virtual WifiMode GetSigMode (WifiPpduField field, const WifiTxVector& txVector) const;
214 
215   /**
216    * \brief Return a const iterator to the first WifiMode
217    *
218    * \return a const iterator to the first WifiMode.
219    */
220   std::list<WifiMode>::const_iterator begin (void) const;
221   /**
222    * \brief Return a const iterator to past-the-last WifiMode
223    *
224    * \return a const iterator to past-the-last WifiMode.
225    */
226   std::list<WifiMode>::const_iterator end (void) const;
227 
228   /**
229    * Return the field following the provided one.
230    *
231    * \param currentField the considered PPDU field
232    * \param preamble the preamble indicating the PPDU format
233    * \return the PPDU field following the reference one
234    */
235   WifiPpduField GetNextField (WifiPpduField currentField, WifiPreamble preamble) const;
236 
237   /**
238    * Get the duration of the PPDU field (or group of fields)
239    * used by this entity for the given transmission parameters.
240    *
241    * \param field the PPDU field (or group of fields)
242    * \param txVector the transmission parameters
243    *
244    * \return the duration of the PPDU field
245    */
246   virtual Time GetDuration (WifiPpduField field, const WifiTxVector& txVector) const;
247   /**
248    * \param txVector the transmission parameters
249    *
250    * \return the total duration of the PHY preamble and PHY header.
251    */
252   Time CalculatePhyPreambleAndHeaderDuration (const WifiTxVector& txVector) const;
253 
254   /**
255    * \param size the number of bytes in the packet to send
256    * \param txVector the TXVECTOR used for the transmission of this packet
257    * \param band the frequency band
258    * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
259    * \param incFlag this flag is used to indicate that the variables need to be update or not
260    * This function is called a couple of times for the same packet so variables should not be increased each time.
261    * \param totalAmpduSize the total size of the previously transmitted MPDUs for the concerned A-MPDU.
262    * If incFlag is set, this parameter will be updated.
263    * \param totalAmpduNumSymbols the number of symbols previously transmitted for the MPDUs in the concerned A-MPDU,
264    * used for the computation of the number of symbols needed for the last MPDU.
265    * If incFlag is set, this parameter will be updated.
266    * \param staId the STA-ID of the PSDU (only used for MU PPDUs)
267    *
268    * \return the duration of the PSDU
269    */
270   virtual Time GetPayloadDuration (uint32_t size, const WifiTxVector& txVector, WifiPhyBand band, MpduType mpdutype,
271                                    bool incFlag, uint32_t &totalAmpduSize, double &totalAmpduNumSymbols,
272                                    uint16_t staId) const = 0;
273 
274   /**
275    * Get a WifiConstPsduMap from a PSDU and the TXVECTOR to use to send the PSDU.
276    * The STA-ID value is properly determined based on whether the given PSDU has
277    * to be transmitted as a DL or UL frame.
278    *
279    * \param psdu the given PSDU
280    * \param txVector the TXVECTOR to use to send the PSDU
281    * \return a WifiConstPsduMap built from the given PSDU and the given TXVECTOR
282    */
283   virtual WifiConstPsduMap GetWifiConstPsduMap (Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector) const;
284 
285   /**
286    * Get the maximum PSDU size in bytes.
287    *
288    * \return the maximum PSDU size in bytes
289    */
290   virtual uint32_t GetMaxPsduSize (void) const = 0;
291 
292   /**
293    * A pair containing information on the PHY header chunk, namely
294    * the start and stop times of the chunk and the WifiMode used.
295    */
296   typedef std::pair<std::pair<Time /* start */, Time /* stop */>, WifiMode> PhyHeaderChunkInfo;
297   /**
298    * A map of PhyHeaderChunkInfo elements per PPDU field.
299    * \see PhyHeaderChunkInfo
300    */
301   typedef std::map<WifiPpduField, PhyHeaderChunkInfo> PhyHeaderSections;
302   /**
303    * Return a map of PHY header chunk information per PPDU field.
304    * This map will contain the PPDU fields that are actually present based
305    * on the \p txVector information.
306    *
307    * \param txVector the transmission parameters
308    * \param ppduStart the time at which the PPDU started
309    * \return the list of preamble sections
310    *
311    * \see PhyHeaderSections
312    */
313   PhyHeaderSections GetPhyHeaderSections (const WifiTxVector& txVector, Time ppduStart) const;
314 
315   /**
316    * Build amendment-specific PPDU.
317    *
318    * \param psdus the PHY payloads (PSDUs)
319    * \param txVector the TXVECTOR that was used for the PPDU
320    * \param ppduDuration the transmission duration of the PPDU
321    *
322    * \return the amendment-specific WifiPpdu
323    */
324   virtual Ptr<WifiPpdu> BuildPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, Time ppduDuration);
325 
326   /**
327    * Get the duration of the PPDU up to (but excluding) the given field.
328    *
329    * \param field the considered PPDU field
330    * \param txVector the transmission parameters
331    * \return the duration from the beginning of the PPDU up to the field
332    */
333   Time GetDurationUpToField (WifiPpduField field, const WifiTxVector& txVector) const;
334   /**
335    * Get the remaining duration of the PPDU after the end of the given field.
336    *
337    * \param field the considered PPDU field
338    * \param ppdu the received PPDU
339    * \return the remaining duration of the PPDU after the end of to the field
340    */
341   Time GetRemainingDurationAfterField (Ptr<const WifiPpdu> ppdu, WifiPpduField field) const;
342 
343   /**
344    * Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
345    *
346    * \param ppdu the PPDU to extract the PSDU from
347    * \return the PSDU addressed to that PHY
348    */
349   virtual Ptr<const WifiPsdu> GetAddressedPsduInPpdu (Ptr<const WifiPpdu> ppdu) const;
350 
351   /**
352    * Start receiving the PHY preamble of a PPDU (i.e. the first bit of the preamble has arrived).
353    *
354    * This method triggers the start of the preamble detection period (\see
355    * StartPreambleDetectionPeriod) if the PHY can process the PPDU.
356    *
357    * \param ppdu the arriving PPDU
358    * \param rxPowersW the receive power in W per band
359    * \param rxDuration the duration of the PPDU
360    */
361   virtual void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand& rxPowersW,
362                                      Time rxDuration);
363   /**
364    * Start receiving a given field.
365    *
366    * This method will call the DoStartReceiveField.
367    * EndReceiveField is also scheduled after the duration of the field
368    * (except for the special case of preambles \see DoStartReceivePreamble).
369    * The PHY is kept in CCA busy during the reception of the field (except for
370    * data field which should be in RX).
371    *
372    * \param field the starting PPDU field
373    * \param event the event holding incoming PPDU's information
374    */
375   void StartReceiveField (WifiPpduField field, Ptr<Event> event);
376   /**
377    * End receiving a given field.
378    *
379    * This method will call the DoEndReceiveField  to obtain the outcome of the reception.
380    * In case of success, reception of the next field is triggered.
381    * In case of failure, the indications in the returned \see PhyFieldRxStatus
382    * are performed.
383    *
384    * \param field the ending PPDU field
385    * \param event the event holding incoming PPDU's information
386    */
387   void EndReceiveField (WifiPpduField field, Ptr<Event> event);
388 
389   /**
390    * The last symbol of the PPDU has arrived.
391    *
392    * \param event the event holding incoming PPDU's information
393    */
394   void EndReceivePayload (Ptr<Event> event);
395 
396   /**
397    * Reset PHY at the end of the PPDU under reception after it has failed the PHY header.
398    *
399    * \param event the event holding incoming PPDU's information
400    */
401   void ResetReceive (Ptr<Event> event);
402 
403   /**
404    * Cancel and clear all running events.
405    */
406   virtual void CancelAllEvents (void);
407   /**
408    * \return \c true if there is no end preamble detection event running, \c false otherwise
409    */
410   bool NoEndPreambleDetectionEvents (void) const;
411   /**
412    * Cancel and eventually clear all end preamble detection events.
413    *
414    * \param clear whether to clear the end preamble detection events' list
415    */
416   void CancelRunningEndPreambleDetectionEvents (bool clear = false);
417 
418   /**
419    * Return the STA ID that has been assigned to the station this PHY belongs to.
420    * This is typically called for MU PPDUs, in order to pick the correct PSDU.
421    *
422    * \param ppdu the PPDU for which the STA ID is requested
423    * \return the STA ID
424    */
425   virtual uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const;
426 
427   /**
428    * Return the channel width used to measure the RSSI.
429    *
430    * \param ppdu the PPDU that is being received
431    * \return the channel width (in MHz) used for RSSI measurement
432    */
433   virtual uint16_t GetMeasurementChannelWidth (const Ptr<const WifiPpdu> ppdu) const;
434 
435   /**
436    * Return the channel width used in the reception spectrum model.
437    *
438    * \param txVector the TXVECTOR of the PPDU that is being received
439    * \return the channel width (in MHz) used for RxSpectrumModel
440    */
441   virtual uint16_t GetRxChannelWidth (const WifiTxVector& txVector) const;
442 
443   /**
444    * This function is called by SpectrumWifiPhy to send
445    * the PPDU while performing amendment-specific actions.
446    * \see SpectrumWifiPhy::StartTx
447    *
448    * \param ppdu the PPDU to send
449    */
450   virtual void StartTx (Ptr<WifiPpdu> ppdu);
451 
452   /**
453    * This function prepares most of the WifiSpectrumSignalParameters
454    * parameters and invokes SpectrumWifiPhy's Transmit method.
455    * \see SpectrumWifiPhy::Transmit
456    *
457    * \param txDuration the duration of the transmission
458    * \param ppdu the PPDU to send
459    * \param type the type of transmission (for logging)
460    */
461   void Transmit (Time txDuration, Ptr<WifiPpdu> ppdu, std::string type);
462 
463   /**
464    * \param psduMap the PSDU(s) to transmit indexed by STA-ID
465    * \param txVector the TXVECTOR used for the transmission of the PPDU
466    * \param band the frequency band being used
467    *
468    * \return the total amount of time this PHY will stay busy for the transmission of the PPDU
469    */
470   virtual Time CalculateTxDuration (WifiConstPsduMap psduMap, const WifiTxVector& txVector, WifiPhyBand band) const;
471 
472 protected:
473   /**
474    * A map of PPDU field elements per preamble type.
475    * This corresponds to the different PPDU formats introduced by each amendment.
476    */
477   typedef std::map<WifiPreamble, std::vector<WifiPpduField> > PpduFormats;
478 
479   /**
480    * A pair to hold modulation information: code rate and constellation size.
481    */
482   typedef std::pair<WifiCodeRate, uint16_t> CodeRateConstellationSizePair;
483 
484   /**
485    * A modulation lookup table using unique name of modulation as key.
486    */
487   typedef std::map<std::string, CodeRateConstellationSizePair> ModulationLookupTable;
488 
489   /**
490    * Return the PPDU formats of the PHY.
491    *
492    * \return the PPDU formats of the PHY
493    */
494   virtual const PpduFormats & GetPpduFormats (void) const = 0;
495 
496   /**
497    * Start receiving a given field, perform amendment-specific actions, and
498    * signify if it is supported.
499    *
500    * \param field the starting PPDU field
501    * \param event the event holding incoming PPDU's information
502    * \return \c true if the field is supported, \c false otherwise
503    */
504   virtual bool DoStartReceiveField (WifiPpduField field, Ptr<Event> event);
505   /**
506    * End receiving a given field, perform amendment-specific actions, and
507    * provide the status of the reception.
508    *
509    * \param field the ending PPDU field
510    * \param event the event holding incoming PPDU's information
511    * \return status of the reception of the PPDU field
512    */
513   virtual PhyFieldRxStatus DoEndReceiveField (WifiPpduField field, Ptr<Event> event);
514 
515   /**
516    * Get the event corresponding to the incoming PPDU.
517    *
518    * We store all incoming preamble events, perform amendment-specific actions,
519    * and a decision is made at the end of the preamble detection window.
520    *
521    * \param ppdu the incoming PPDU
522    * \param rxPowersW the receive power in W per band
523    * \return the event holding the incoming PPDU's information
524    */
525   virtual Ptr<Event> DoGetEvent (Ptr<const WifiPpdu> ppdu, RxPowerWattPerChannelBand& rxPowersW);
526   /**
527    * End receiving the preamble, perform amendment-specific actions, and
528    * provide the status of the reception.
529    *
530    * \param event the event holding incoming PPDU's information
531    * \return status of the reception of the preamble
532    */
533   virtual PhyFieldRxStatus DoEndReceivePreamble (Ptr<Event> event);
534   /**
535    * Start the preamble detection period.
536    *
537    * \param event the event holding incoming PPDU's information
538    */
539   void StartPreambleDetectionPeriod (Ptr<Event> event);
540   /**
541    * End the preamble detection period.
542    *
543    * The PHY will focus on the strongest PPDU and drop others.
544    * In addition, in case of successful detection, the end of the
545    * preamble reception is triggered (\see DoEndReceivePreamble).
546    *
547    * \param event the event holding incoming PPDU's information
548    */
549   void EndPreambleDetectionPeriod (Ptr<Event> event);
550 
551   /**
552    * Start receiving the PSDU (i.e. the first symbol of the PSDU has arrived).
553    *
554    * \param event the event holding incoming PPDU's information
555    */
556   void StartReceivePayload (Ptr<Event> event);
557 
558   /**
559    * Start receiving the PSDU (i.e. the first symbol of the PSDU has arrived)
560    * and perform amendment-specific actions.
561    *
562    * \param event the event holding incoming PPDU's information
563    */
564   virtual void DoStartReceivePayload (Ptr<Event> event);
565 
566   /**
567    * Perform amendment-specific actions before resetting PHY at
568    * the end of the PPDU under reception after it has failed the PHY header.
569    *
570    * \param event the event holding incoming PPDU's information
571    */
572   virtual void DoResetReceive (Ptr<Event> event);
573 
574   /**
575    * Perform amendment-specific actions before aborting the
576    * current reception.
577    *
578    * \param reason the reason the reception is aborted
579    */
580   virtual void DoAbortCurrentReception (WifiPhyRxfailureReason reason);
581 
582   /**
583    * Checks if the signaled configuration (excluding bandwidth)
584    * is supported by the PHY.
585    *
586    * \param ppdu the received PPDU
587    * \return \c true if supported, \c false otherwise
588    */
589   virtual bool IsConfigSupported (Ptr<const WifiPpdu> ppdu) const;
590 
591   /**
592    * Drop the PPDU and the corresponding preamble detection event, but keep CCA busy
593    * state after the completion of the currently processed event.
594    *
595    * \param ppdu the incoming PPDU
596    * \param reason the reason the PPDU is dropped
597    * \param endRx the end of the incoming PPDU's reception
598    * \param measurementChannelWidth the measurement width (in MHz) to consider for the PPDU
599    */
600   void DropPreambleEvent (Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason, Time endRx, uint16_t measurementChannelWidth);
601 
602   /**
603    * Erase the event corresponding to the PPDU from the list of preamble events,
604    * but consider it as noise after the completion of the current event.
605    *
606    * \param ppdu the incoming PPDU
607    * \param rxDuration the duration of the PPDU
608    */
609   void ErasePreambleEvent (Ptr<const WifiPpdu> ppdu, Time rxDuration);
610 
611   /**
612    * Get the reception status for the provided MPDU and notify.
613    *
614    * \param psdu the arriving MPDU formatted as a PSDU
615    * \param event the event holding incoming PPDU's information
616    * \param staId the station ID of the PSDU (only used for MU)
617    * \param relativeMpduStart the relative start time of the MPDU within the A-MPDU. 0 for normal MPDUs
618    * \param mpduDuration the duration of the MPDU
619    *
620    * \return information on MPDU reception: status, signal power (dBm), and noise power (in dBm)
621    */
622   std::pair<bool, SignalNoiseDbm> GetReceptionStatus (Ptr<const WifiPsdu> psdu,
623                                                       Ptr<Event> event, uint16_t staId,
624                                                       Time relativeMpduStart,
625                                                       Time mpduDuration);
626   /**
627    * The last symbol of an MPDU in an A-MPDU has arrived.
628    *
629    * \param event the event holding incoming PPDU's information
630    * \param psdu the arriving MPDU formatted as a PSDU containing a normal MPDU
631    * \param mpduIndex the index of the MPDU within the A-MPDU
632    * \param relativeStart the relative start time of the MPDU within the A-MPDU.
633    * \param mpduDuration the duration of the MPDU
634    */
635   void EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex, Time relativeStart, Time mpduDuration);
636 
637   /**
638    * Schedule end of MPDUs events.
639    *
640    * \param event the event holding incoming PPDU's information
641    */
642   void ScheduleEndOfMpdus (Ptr<Event> event);
643 
644   /**
645    * Perform amendment-specific actions at the end of the reception of
646    * the payload.
647    *
648    * \param ppdu the incoming PPDU
649    */
650   virtual void DoEndReceivePayload (Ptr<const WifiPpdu> ppdu);
651 
652   /**
653    * Get the channel width and band to use (will be overloaded by child classes).
654    *
655    * \param txVector the transmission parameters
656    * \param staId the station ID of the PSDU
657    * \return a pair of channel width (MHz) and band
658    */
659   virtual std::pair<uint16_t, WifiSpectrumBand> GetChannelWidthAndBand (const WifiTxVector& txVector, uint16_t staId) const;
660 
661   /**
662    * Abort the current reception.
663    *
664    * \param reason the reason the reception is aborted
665    */
666   void AbortCurrentReception (WifiPhyRxfailureReason reason);
667 
668   /**
669    * Obtain a random value from the WifiPhy's generator.
670    * Wrapper used by child classes.
671    *
672    * \return a uniform random value
673    */
674   double GetRandomValue (void) const;
675   /**
676    * Obtain the SNR and PER of the PPDU field from the WifiPhy's InterferenceHelper class.
677    * Wrapper used by child classes.
678    *
679    * \param field the PPDU field
680    * \param event the event holding incoming PPDU's information
681    * \return the SNR and PER
682    */
683   SnrPer GetPhyHeaderSnrPer (WifiPpduField field, Ptr<Event> event) const;
684   /**
685    * Obtain the received power (W) for a given band.
686    * Wrapper used by child classes.
687    *
688    * \param event the event holding incoming PPDU's information
689    * \return the received power (W) for the event over a given band
690    */
691   double GetRxPowerWForPpdu (Ptr<Event> event) const;
692   /**
693    * Get the pointer to the current event (stored in WifiPhy).
694    * Wrapper used by child classes.
695    *
696    * \return the pointer to the current event
697    */
698   Ptr<const Event> GetCurrentEvent (void) const;
699   /**
700    * Get the map of current preamble events (stored in WifiPhy).
701    * Wrapper used by child classes.
702    *
703    * \return the reference to the map of current preamble events
704    */
705   const std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > & GetCurrentPreambleEvents (void) const;
706   /**
707    * Add an entry to the map of current preamble events (stored in WifiPhy).
708    * Wrapper used by child classes.
709    *
710    * \param event the event holding incoming PPDU's information
711    */
712   void AddPreambleEvent (Ptr<Event> event);
713 
714   /**
715    * Create an event using WifiPhy's InterferenceHelper class.
716    * Wrapper used by child classes.
717    *
718    * \copydoc InterferenceHelper::Add
719    */
720   Ptr<Event> CreateInterferenceEvent (Ptr<const WifiPpdu> ppdu, const WifiTxVector& txVector, Time duration, RxPowerWattPerChannelBand& rxPower, bool isStartOfdmaRxing = false);
721   /**
722    * Update an event in WifiPhy's InterferenceHelper class.
723    * Wrapper used by child classes.
724    *
725    * \copydoc InterferenceHelper::UpdateEvent
726    */
727   void UpdateInterferenceEvent (Ptr<Event> event, const RxPowerWattPerChannelBand& rxPower);
728   /**
729    * Notify WifiPhy's InterferenceHelper of the end of the reception,
730    * clear maps and end of MPDU event, and eventually reset WifiPhy.
731    *
732    * \param reset whether to reset WifiPhy
733    */
734   void NotifyInterferenceRxEndAndClear (bool reset);
735 
736   /**
737    * Obtain the next UID for the PPDU to transmit.
738    * Note that the global UID counter could be incremented.
739    *
740    * \param txVector the transmission parameters
741    * \return the UID to use for the PPDU to transmit
742    */
743   virtual uint64_t ObtainNextUid (const WifiTxVector& txVector);
744 
745   /**
746    * \param txPowerW power in W to spread across the bands
747    * \param ppdu the PPDU that will be transmitted
748    * \return Pointer to SpectrumValue
749    *
750    * This is a helper function to create the right TX PSD corresponding
751    * to the amendment of this PHY.
752    */
753   virtual Ptr<SpectrumValue> GetTxPowerSpectralDensity (double txPowerW, Ptr<const WifiPpdu> ppdu) const = 0;
754 
755   /**
756    * Get the center frequency of the channel corresponding the current TxVector rather than
757    * that of the supported channel width.
758    * Consider that this "primary channel" is on the lower part for the time being.
759    *
760    * \param txVector the TXVECTOR that has the channel width that is to be used
761    * \return the center frequency in MHz corresponding to the channel width to be used
762    */
763   uint16_t GetCenterFrequencyForChannelWidth (const WifiTxVector& txVector) const;
764 
765   /**
766    * \param currentChannelWidth channel width of the current transmission (MHz)
767    * \return the width of the guard band (MHz)
768    *
769    * Wrapper method used by child classes for PSD generation.
770    * Note that this method is necessary for testing UL OFDMA.
771    */
772   uint16_t GetGuardBandwidth (uint16_t currentChannelWidth) const;
773   /**
774    * \return a tuple containing the minimum rejection (in dBr) for the inner band,
775    *                            the minimum rejection (in dBr) for the outer band, and
776    *                            the maximum rejection (in dBr) for the outer band
777    *                            for the transmit spectrum mask.
778    *
779    * Wrapper method used by child classes for PSD generation.
780    */
781   std::tuple<double, double, double> GetTxMaskRejectionParams (void) const;
782 
783   Ptr<WifiPhy> m_wifiPhy;          //!< Pointer to the owning WifiPhy
784   Ptr<WifiPhyStateHelper> m_state; //!< Pointer to WifiPhyStateHelper of the WifiPhy (to make it reachable for child classes)
785 
786   std::list<WifiMode> m_modeList;  //!< the list of supported modes
787 
788   std::vector <EventId> m_endPreambleDetectionEvents; //!< the end of preamble detection events
789   std::vector <EventId> m_endOfMpduEvents; //!< the end of MPDU events (only used for A-MPDUs)
790 
791   std::vector <EventId> m_endRxPayloadEvents; //!< the end of receive events (only one unless UL MU reception)
792 
793   /**
794    * A pair of a UID and STA_ID
795    */
796   typedef std::pair <uint64_t /* UID */, uint16_t /* STA-ID */> UidStaIdPair;
797 
798   std::map<UidStaIdPair, std::vector<bool> > m_statusPerMpduMap; //!< Map of the current reception status per MPDU that is filled in as long as MPDUs are being processed by the PHY in case of an A-MPDU
799   std::map<UidStaIdPair, SignalNoiseDbm> m_signalNoiseMap; //!< Map of the latest signal power and noise power in dBm (noise power includes the noise figure)
800 
801   static uint64_t m_globalPpduUid; //!< Global counter of the PPDU UID
802 }; //class PhyEntity
803 
804 /**
805  * \brief Stream insertion operator.
806  *
807  * \param os the stream
808  * \param action the action to perform in case of failure
809  * \returns a reference to the stream
810  */
811 std::ostream& operator<< (std::ostream& os, const PhyEntity::PhyRxFailureAction &action);
812 /**
813  * \brief Stream insertion operator.
814  *
815  * \param os the stream
816  * \param status the status of the reception of a PPDU field
817  * \returns a reference to the stream
818  */
819 std::ostream& operator<< (std::ostream& os, const PhyEntity::PhyFieldRxStatus &status);
820 
821 } //namespace ns3
822 
823 #endif /* PHY_ENTITY_H */
824