1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 University of Washington
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: Sébastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/test.h"
23 #include "ns3/node.h"
24 #include "ns3/pointer.h"
25 #include "ns3/string.h"
26 #include "ns3/simulator.h"
27 #include "ns3/rng-seed-manager.h"
28 #include "ns3/constant-position-mobility-model.h"
29 #include "ns3/wifi-spectrum-signal-parameters.h"
30 #include "ns3/wifi-spectrum-value-helper.h"
31 #include "ns3/multi-model-spectrum-channel.h"
32 #include "ns3/spectrum-wifi-phy.h"
33 #include "ns3/nist-error-rate-model.h"
34 #include "ns3/wifi-mac-header.h"
35 #include "ns3/wifi-net-device.h"
36 #include "ns3/wifi-psdu.h"
37 #include "ns3/he-ppdu.h"
38 #include "ns3/wifi-utils.h"
39 #include "ns3/ap-wifi-mac.h"
40 #include "ns3/sta-wifi-mac.h"
41 #include "ns3/he-configuration.h"
42 #include "ns3/ctrl-headers.h"
43 #include "ns3/threshold-preamble-detection-model.h"
44 #include "ns3/he-phy.h"
45 #include "ns3/waveform-generator.h"
46 #include "ns3/non-communicating-net-device.h"
47 #include "ns3/spectrum-wifi-helper.h"
48 #include "ns3/mobility-helper.h"
49 
50 using namespace ns3;
51 
52 NS_LOG_COMPONENT_DEFINE ("WifiPhyOfdmaTest");
53 
54 static const uint8_t DEFAULT_CHANNEL_NUMBER = 36;
55 static const uint32_t DEFAULT_FREQUENCY = 5180; // MHz
56 static const WifiPhyBand DEFAULT_WIFI_BAND = WIFI_PHY_BAND_5GHZ;
57 static const uint16_t DEFAULT_CHANNEL_WIDTH = 20; // MHz
58 static const uint16_t DEFAULT_GUARD_WIDTH = DEFAULT_CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
59 
60 /**
61  * HE PHY slightly modified so as to return a given
62  * STA-ID in case of DL MU for OfdmaSpectrumWifiPhy.
63  */
64 class OfdmaTestHePhy : public HePhy
65 {
66 public:
67   /**
68    * Constructor
69    *
70    * \param staId the ID of the STA to which this PHY belongs to
71    */
72   OfdmaTestHePhy (uint16_t staId);
73   virtual ~OfdmaTestHePhy ();
74 
75   /**
76    * Return the STA ID that has been assigned to the station this PHY belongs to.
77    * This is typically called for MU PPDUs, in order to pick the correct PSDU.
78    *
79    * \param ppdu the PPDU for which the STA ID is requested
80    * \return the STA ID
81    */
82   uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const override;
83 
84   /**
85    * Set the global PPDU UID counter.
86    *
87    * \param uid the value to which the global PPDU UID counter should be set
88    */
89   void SetGlobalPpduUid (uint64_t uid);
90 
91 private:
92   uint16_t m_staId; ///< ID of the STA to which this PHY belongs to
93 }; //class OfdmaTestHePhy
94 
OfdmaTestHePhy(uint16_t staId)95 OfdmaTestHePhy::OfdmaTestHePhy (uint16_t staId)
96   : HePhy (),
97     m_staId (staId)
98 {
99 }
100 
~OfdmaTestHePhy()101 OfdmaTestHePhy::~OfdmaTestHePhy ()
102 {
103 }
104 
105 uint16_t
GetStaId(const Ptr<const WifiPpdu> ppdu) const106 OfdmaTestHePhy::GetStaId (const Ptr<const WifiPpdu> ppdu) const
107 {
108   if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
109     {
110       return m_staId;
111     }
112   return HePhy::GetStaId (ppdu);
113 }
114 
115 void
SetGlobalPpduUid(uint64_t uid)116 OfdmaTestHePhy::SetGlobalPpduUid (uint64_t uid)
117 {
118   m_globalPpduUid = uid;
119 }
120 
121 /**
122  * SpectrumWifiPhy used for testing OFDMA.
123  */
124 class OfdmaSpectrumWifiPhy : public SpectrumWifiPhy
125 {
126 public:
127   /**
128    * \brief Get the type ID.
129    * \return the object TypeId
130    */
131   static TypeId GetTypeId (void);
132   /**
133    * Constructor
134    *
135    * \param staId the ID of the STA to which this PHY belongs to
136    */
137   OfdmaSpectrumWifiPhy (uint16_t staId);
138   virtual ~OfdmaSpectrumWifiPhy ();
139 
140   void DoInitialize (void) override;
141   void DoDispose (void) override;
142 
143   using WifiPhy::Reset;
144 
145   /**
146    * TracedCallback signature for UID of transmitted PPDU.
147    *
148    * \param uid the UID of the transmitted PPDU
149    */
150   typedef void (*TxPpduUidCallback)(uint64_t uid);
151 
152   /**
153    * \param ppdu the PPDU to send
154    */
155   void StartTx (Ptr<WifiPpdu> ppdu) override;
156   /**
157    * \param currentChannelWidth channel width of the current transmission (MHz)
158    * \return the width of the guard band (MHz) set to 2
159    */
160   uint16_t GetGuardBandwidth (uint16_t currentChannelWidth) const override;
161 
162   /**
163    * Set the global PPDU UID counter.
164    *
165    * \param uid the value to which the global PPDU UID counter should be set
166    */
167   void SetPpduUid (uint64_t uid);
168 
169   /**
170    * Since we assume trigger frame was previously received from AP, this is used to set its UID
171    *
172    * \param uid the PPDU UID of the trigger frame
173    */
174   void SetTriggerFrameUid (uint64_t uid);
175 
176   /**
177    * \return the current preamble events map
178    */
179   std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > & GetCurrentPreambleEvents (void);
180   /**
181    * \return the current event
182    */
183   Ptr<Event> GetCurrentEvent (void);
184 
185   /**
186    * Wrapper to InterferenceHelper method.
187    *
188    * \param energyW the minimum energy (W) requested
189    * \param band identify the requested band
190    *
191    * \returns the expected amount of time the observed
192    *          energy on the medium for a given band will
193    *          be higher than the requested threshold.
194    */
195   Time GetEnergyDuration (double energyW, WifiSpectrumBand band);
196 
197   /**
198    * \return a const pointer to the HE PHY instance
199    */
200   Ptr<const HePhy> GetHePhy (void) const;
201 
202 private:
203   Ptr<OfdmaTestHePhy> m_ofdmTestHePhy; ///< Pointer to HE PHY instance used for OFDMA test
204   TracedCallback<uint64_t> m_phyTxPpduUidTrace; //!< Callback providing UID of the PPDU that is about to be transmitted
205 }; //class OfdmaSpectrumWifiPhy
206 
207 TypeId
GetTypeId(void)208 OfdmaSpectrumWifiPhy::GetTypeId (void)
209 {
210   static TypeId tid = TypeId ("ns3::OfdmaSpectrumWifiPhy")
211     .SetParent<SpectrumWifiPhy> ()
212     .SetGroupName ("Wifi")
213     .AddTraceSource ("TxPpduUid",
214                      "UID of the PPDU to be transmitted",
215                      MakeTraceSourceAccessor (&OfdmaSpectrumWifiPhy::m_phyTxPpduUidTrace),
216                      "ns3::OfdmaSpectrumWifiPhy::TxPpduUidCallback")
217   ;
218   return tid;
219 }
220 
OfdmaSpectrumWifiPhy(uint16_t staId)221 OfdmaSpectrumWifiPhy::OfdmaSpectrumWifiPhy (uint16_t staId)
222   : SpectrumWifiPhy ()
223 {
224   m_ofdmTestHePhy = Create<OfdmaTestHePhy> (staId);
225   m_ofdmTestHePhy->SetOwner (this);
226 }
227 
~OfdmaSpectrumWifiPhy()228 OfdmaSpectrumWifiPhy::~OfdmaSpectrumWifiPhy()
229 {
230 }
231 
232 void
DoInitialize(void)233 OfdmaSpectrumWifiPhy::DoInitialize (void)
234 {
235   //Replace HE PHY instance with test instance
236   m_phyEntities[WIFI_MOD_CLASS_HE] = m_ofdmTestHePhy;
237   SpectrumWifiPhy::DoInitialize ();
238 }
239 
240 void
DoDispose(void)241 OfdmaSpectrumWifiPhy::DoDispose (void)
242 {
243   m_ofdmTestHePhy = 0;
244   SpectrumWifiPhy::DoDispose ();
245 }
246 
247 void
SetPpduUid(uint64_t uid)248 OfdmaSpectrumWifiPhy::SetPpduUid (uint64_t uid)
249 {
250   m_ofdmTestHePhy->SetGlobalPpduUid (uid);
251   m_previouslyRxPpduUid = uid;
252 }
253 
254 void
SetTriggerFrameUid(uint64_t uid)255 OfdmaSpectrumWifiPhy::SetTriggerFrameUid (uint64_t uid)
256 {
257   m_previouslyRxPpduUid = uid;
258 }
259 
260 void
StartTx(Ptr<WifiPpdu> ppdu)261 OfdmaSpectrumWifiPhy::StartTx (Ptr<WifiPpdu> ppdu)
262 {
263   m_phyTxPpduUidTrace (ppdu->GetUid ());
264   SpectrumWifiPhy::StartTx (ppdu);
265 }
266 
267 std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > &
GetCurrentPreambleEvents(void)268 OfdmaSpectrumWifiPhy::GetCurrentPreambleEvents (void)
269 {
270   return m_currentPreambleEvents;
271 }
272 
273 uint16_t
GetGuardBandwidth(uint16_t currentChannelWidth) const274 OfdmaSpectrumWifiPhy::GetGuardBandwidth (uint16_t currentChannelWidth) const
275 {
276   // return a small enough value to avoid having too much out of band transmission
277   // knowing that slopes are not configurable yet.
278   return 1;
279 }
280 
281 Ptr<Event>
GetCurrentEvent(void)282 OfdmaSpectrumWifiPhy::GetCurrentEvent (void)
283 {
284   return m_currentEvent;
285 }
286 
287 Time
GetEnergyDuration(double energyW,WifiSpectrumBand band)288 OfdmaSpectrumWifiPhy::GetEnergyDuration (double energyW, WifiSpectrumBand band)
289 {
290   return m_interference.GetEnergyDuration (energyW, band);
291 }
292 
293 Ptr<const HePhy>
GetHePhy(void) const294 OfdmaSpectrumWifiPhy::GetHePhy (void) const
295 {
296   return DynamicCast<const HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE));
297 }
298 
299 /**
300  * \ingroup wifi-test
301  * \ingroup tests
302  *
303  * \brief DL-OFDMA PHY test
304  */
305 class TestDlOfdmaPhyTransmission : public TestCase
306 {
307 public:
308   TestDlOfdmaPhyTransmission ();
309   virtual ~TestDlOfdmaPhyTransmission ();
310 
311 private:
312   void DoSetup (void) override;
313   void DoTeardown (void) override;
314   void DoRun (void) override;
315 
316   /**
317    * Receive success function for STA 1
318    * \param psdu the PSDU
319    * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
320    * \param txVector the transmit vector
321    * \param statusPerMpdu reception status per MPDU
322    */
323   void RxSuccessSta1 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
324                       WifiTxVector txVector, std::vector<bool> statusPerMpdu);
325   /**
326    * Receive success function for STA 2
327    * \param psdu the PSDU
328    * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
329    * \param txVector the transmit vector
330    * \param statusPerMpdu reception status per MPDU
331    */
332   void RxSuccessSta2 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
333                       WifiTxVector txVector, std::vector<bool> statusPerMpdu);
334   /**
335    * Receive success function for STA 3
336    * \param psdu the PSDU
337    * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
338    * \param txVector the transmit vector
339    * \param statusPerMpdu reception status per MPDU
340    */
341   void RxSuccessSta3 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
342                       WifiTxVector txVector, std::vector<bool> statusPerMpdu);
343 
344   /**
345    * Receive failure function for STA 1
346    * \param psdu the PSDU
347    */
348   void RxFailureSta1 (Ptr<WifiPsdu> psdu);
349   /**
350    * Receive failure function for STA 2
351    * \param psdu the PSDU
352    */
353   void RxFailureSta2 (Ptr<WifiPsdu> psdu);
354   /**
355    * Receive failure function for STA 3
356    * \param psdu the PSDU
357    */
358   void RxFailureSta3 (Ptr<WifiPsdu> psdu);
359 
360   /**
361    * Check the results for STA 1
362    * \param expectedRxSuccess the expected number of RX success
363    * \param expectedRxFailure the expected number of RX failures
364    * \param expectedRxBytes the expected number of RX bytes
365    */
366   void CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
367   /**
368    * Check the results for STA 2
369    * \param expectedRxSuccess the expected number of RX success
370    * \param expectedRxFailure the expected number of RX failures
371    * \param expectedRxBytes the expected number of RX bytes
372    */
373   void CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
374   /**
375    * Check the results for STA 3
376    * \param expectedRxSuccess the expected number of RX success
377    * \param expectedRxFailure the expected number of RX failures
378    * \param expectedRxBytes the expected number of RX bytes
379    */
380   void CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
381 
382   /**
383    * Reset the results
384    */
385   void ResetResults ();
386 
387   /**
388    * Send MU-PPDU function
389    * \param rxStaId1 the ID of the recipient STA for the first PSDU
390    * \param rxStaId2 the ID of the recipient STA for the second PSDU
391    */
392   void SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2);
393 
394   /**
395    * Generate interference function
396    * \param interferencePsd the PSD of the interference to be generated
397    * \param duration the duration of the interference
398    */
399   void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
400   /**
401    * Stop interference function
402    */
403   void StopInterference (void);
404 
405   /**
406    * Run one function
407    */
408   void RunOne ();
409 
410   /**
411    * Schedule now to check  the PHY state
412    * \param phy the PHY
413    * \param expectedState the expected state of the PHY
414    */
415   void CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
416   /**
417    * Check the PHY state now
418    * \param phy the PHY
419    * \param expectedState the expected state of the PHY
420    */
421   void DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
422 
423   uint32_t m_countRxSuccessSta1; ///< count RX success for STA 1
424   uint32_t m_countRxSuccessSta2; ///< count RX success for STA 2
425   uint32_t m_countRxSuccessSta3; ///< count RX success for STA 3
426   uint32_t m_countRxFailureSta1; ///< count RX failure for STA 1
427   uint32_t m_countRxFailureSta2; ///< count RX failure for STA 2
428   uint32_t m_countRxFailureSta3; ///< count RX failure for STA 3
429   uint32_t m_countRxBytesSta1;   ///< count RX bytes for STA 1
430   uint32_t m_countRxBytesSta2;   ///< count RX bytes for STA 2
431   uint32_t m_countRxBytesSta3;   ///< count RX bytes for STA 3
432 
433   Ptr<SpectrumWifiPhy> m_phyAp;           ///< PHY of AP
434   Ptr<OfdmaSpectrumWifiPhy> m_phySta1;    ///< PHY of STA 1
435   Ptr<OfdmaSpectrumWifiPhy> m_phySta2;    ///< PHY of STA 2
436   Ptr<OfdmaSpectrumWifiPhy> m_phySta3;    ///< PHY of STA 3
437   Ptr<WaveformGenerator> m_phyInterferer; ///< PHY of interferer
438 
439   uint16_t m_frequency;        ///< frequency in MHz
440   uint16_t m_channelWidth;     ///< channel width in MHz
441   Time m_expectedPpduDuration; ///< expected duration to send MU PPDU
442 };
443 
TestDlOfdmaPhyTransmission()444 TestDlOfdmaPhyTransmission::TestDlOfdmaPhyTransmission ()
445   : TestCase ("DL-OFDMA PHY test"),
446     m_countRxSuccessSta1 (0),
447     m_countRxSuccessSta2 (0),
448     m_countRxSuccessSta3 (0),
449     m_countRxFailureSta1 (0),
450     m_countRxFailureSta2 (0),
451     m_countRxFailureSta3 (0),
452     m_countRxBytesSta1 (0),
453     m_countRxBytesSta2 (0),
454     m_countRxBytesSta3 (0),
455     m_frequency (DEFAULT_FREQUENCY),
456     m_channelWidth (DEFAULT_CHANNEL_WIDTH),
457     m_expectedPpduDuration (NanoSeconds (306400))
458 {
459 }
460 
461 void
ResetResults(void)462 TestDlOfdmaPhyTransmission::ResetResults (void)
463 {
464   m_countRxSuccessSta1 = 0;
465   m_countRxSuccessSta2 = 0;
466   m_countRxSuccessSta3 = 0;
467   m_countRxFailureSta1 = 0;
468   m_countRxFailureSta2 = 0;
469   m_countRxFailureSta3 = 0;
470   m_countRxBytesSta1 = 0;
471   m_countRxBytesSta2 = 0;
472   m_countRxBytesSta3 = 0;
473 }
474 
475 void
SendMuPpdu(uint16_t rxStaId1,uint16_t rxStaId2)476 TestDlOfdmaPhyTransmission::SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2)
477 {
478   NS_LOG_FUNCTION (this << rxStaId1 << rxStaId2);
479   WifiConstPsduMap psdus;
480   WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_MU, 800, 1, 1, 0, m_channelWidth, false, false);
481   HeRu::RuType ruType = HeRu::RU_106_TONE;
482   if (m_channelWidth == 20)
483     {
484       ruType = HeRu::RU_106_TONE;
485     }
486   else if (m_channelWidth == 40)
487     {
488       ruType = HeRu::RU_242_TONE;
489     }
490   else if (m_channelWidth == 80)
491     {
492       ruType = HeRu::RU_484_TONE;
493     }
494   else if (m_channelWidth == 160)
495     {
496       ruType = HeRu::RU_996_TONE;
497     }
498   else
499     {
500       NS_ASSERT_MSG (false, "Unsupported channel width");
501     }
502 
503   HeRu::RuSpec ru1 (ruType, 1, true);
504   txVector.SetRu (ru1, rxStaId1);
505   txVector.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
506   txVector.SetNss (1, rxStaId1);
507 
508   HeRu::RuSpec ru2 (ruType, (m_channelWidth == 160 ? 1 : 2), (m_channelWidth == 160 ? false : true));
509   txVector.SetRu (ru2, rxStaId2);
510   txVector.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
511   txVector.SetNss (1, rxStaId2);
512 
513   Ptr<Packet> pkt1 = Create<Packet> (1000);
514   WifiMacHeader hdr1;
515   hdr1.SetType (WIFI_MAC_QOSDATA);
516   hdr1.SetQosTid (0);
517   hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:01"));
518   hdr1.SetSequenceNumber (1);
519   Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
520   psdus.insert (std::make_pair (rxStaId1, psdu1));
521 
522   Ptr<Packet> pkt2 = Create<Packet> (1500);
523   WifiMacHeader hdr2;
524   hdr2.SetType (WIFI_MAC_QOSDATA);
525   hdr2.SetQosTid (0);
526   hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
527   hdr2.SetSequenceNumber (2);
528   Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
529   psdus.insert (std::make_pair (rxStaId2, psdu2));
530 
531   m_phyAp->Send (psdus, txVector);
532 }
533 
534 void
GenerateInterference(Ptr<SpectrumValue> interferencePsd,Time duration)535 TestDlOfdmaPhyTransmission::GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration)
536 {
537   m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
538   m_phyInterferer->SetPeriod (duration);
539   m_phyInterferer->Start ();
540   Simulator::Schedule (duration, &TestDlOfdmaPhyTransmission::StopInterference, this);
541 }
542 
543 void
StopInterference(void)544 TestDlOfdmaPhyTransmission::StopInterference (void)
545 {
546   m_phyInterferer->Stop();
547 }
548 
~TestDlOfdmaPhyTransmission()549 TestDlOfdmaPhyTransmission::~TestDlOfdmaPhyTransmission ()
550 {
551 }
552 
553 void
RxSuccessSta1(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)554 TestDlOfdmaPhyTransmission::RxSuccessSta1 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
555                                            WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
556 {
557   NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
558   m_countRxSuccessSta1++;
559   m_countRxBytesSta1 += (psdu->GetSize () - 30);
560 }
561 
562 void
RxSuccessSta2(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)563 TestDlOfdmaPhyTransmission::RxSuccessSta2 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
564                                            WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
565 {
566   NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
567   m_countRxSuccessSta2++;
568   m_countRxBytesSta2 += (psdu->GetSize () - 30);
569 }
570 
571 void
RxSuccessSta3(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)572 TestDlOfdmaPhyTransmission::RxSuccessSta3 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
573                                            WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
574 {
575   NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
576   m_countRxSuccessSta3++;
577   m_countRxBytesSta3 += (psdu->GetSize () - 30);
578 }
579 
580 void
RxFailureSta1(Ptr<WifiPsdu> psdu)581 TestDlOfdmaPhyTransmission::RxFailureSta1 (Ptr<WifiPsdu> psdu)
582 {
583   NS_LOG_FUNCTION (this << *psdu);
584   m_countRxFailureSta1++;
585 }
586 
587 void
RxFailureSta2(Ptr<WifiPsdu> psdu)588 TestDlOfdmaPhyTransmission::RxFailureSta2 (Ptr<WifiPsdu> psdu)
589 {
590   NS_LOG_FUNCTION (this << *psdu);
591   m_countRxFailureSta2++;
592 }
593 
594 void
RxFailureSta3(Ptr<WifiPsdu> psdu)595 TestDlOfdmaPhyTransmission::RxFailureSta3 (Ptr<WifiPsdu> psdu)
596 {
597   NS_LOG_FUNCTION (this << *psdu);
598   m_countRxFailureSta3++;
599 }
600 
601 void
CheckResultsSta1(uint32_t expectedRxSuccess,uint32_t expectedRxFailure,uint32_t expectedRxBytes)602 TestDlOfdmaPhyTransmission::CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
603 {
604   NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta1, expectedRxSuccess, "The number of successfully received packets by STA 1 is not correct!");
605   NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta1, expectedRxFailure, "The number of unsuccessfully received packets by STA 1 is not correct!");
606   NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta1, expectedRxBytes, "The number of bytes received by STA 1 is not correct!");
607 }
608 
609 void
CheckResultsSta2(uint32_t expectedRxSuccess,uint32_t expectedRxFailure,uint32_t expectedRxBytes)610 TestDlOfdmaPhyTransmission::CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
611 {
612   NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta2, expectedRxSuccess, "The number of successfully received packets by STA 2 is not correct!");
613   NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta2, expectedRxFailure, "The number of unsuccessfully received packets by STA 2 is not correct!");
614   NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta2, expectedRxBytes, "The number of bytes received by STA 2 is not correct!");
615 }
616 
617 void
CheckResultsSta3(uint32_t expectedRxSuccess,uint32_t expectedRxFailure,uint32_t expectedRxBytes)618 TestDlOfdmaPhyTransmission::CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
619 {
620   NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta3, expectedRxSuccess, "The number of successfully received packets by STA 3 is not correct!");
621   NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta3, expectedRxFailure, "The number of unsuccessfully received packets by STA 3 is not correct!");
622   NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta3, expectedRxBytes, "The number of bytes received by STA 3 is not correct!");
623 }
624 
625 void
CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)626 TestDlOfdmaPhyTransmission::CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
627 {
628   //This is needed to make sure PHY state will be checked as the last event if a state change occured at the exact same time as the check
629   Simulator::ScheduleNow (&TestDlOfdmaPhyTransmission::DoCheckPhyState, this, phy, expectedState);
630 }
631 
632 void
DoCheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)633 TestDlOfdmaPhyTransmission::DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
634 {
635   WifiPhyState currentState;
636   PointerValue ptr;
637   phy->GetAttribute ("State", ptr);
638   Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
639   currentState = state->GetState ();
640   NS_LOG_FUNCTION (this << currentState);
641   NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
642 }
643 
644 void
DoSetup(void)645 TestDlOfdmaPhyTransmission::DoSetup (void)
646 {
647   Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
648   Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
649   lossModel->SetFrequency (m_frequency * 1e6);
650   spectrumChannel->AddPropagationLossModel (lossModel);
651   Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
652   spectrumChannel->SetPropagationDelayModel (delayModel);
653 
654   Ptr<Node> apNode = CreateObject<Node> ();
655   Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
656   m_phyAp = CreateObject<SpectrumWifiPhy> ();
657   m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
658   m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
659   Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
660   m_phyAp->SetErrorRateModel (error);
661   m_phyAp->SetDevice (apDev);
662   m_phyAp->SetChannel (spectrumChannel);
663   Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
664   m_phyAp->SetMobility (apMobility);
665   apDev->SetPhy (m_phyAp);
666   apNode->AggregateObject (apMobility);
667   apNode->AddDevice (apDev);
668 
669   Ptr<Node> sta1Node = CreateObject<Node> ();
670   Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
671   m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
672   m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
673   m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
674   m_phySta1->SetErrorRateModel (error);
675   m_phySta1->SetDevice (sta1Dev);
676   m_phySta1->SetChannel (spectrumChannel);
677   m_phySta1->SetReceiveOkCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxSuccessSta1, this));
678   m_phySta1->SetReceiveErrorCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxFailureSta1, this));
679   Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
680   m_phySta1->SetMobility (sta1Mobility);
681   sta1Dev->SetPhy (m_phySta1);
682   sta1Node->AggregateObject (sta1Mobility);
683   sta1Node->AddDevice (sta1Dev);
684 
685   Ptr<Node> sta2Node = CreateObject<Node> ();
686   Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
687   m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
688   m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
689   m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
690   m_phySta2->SetErrorRateModel (error);
691   m_phySta2->SetDevice (sta2Dev);
692   m_phySta2->SetChannel (spectrumChannel);
693   m_phySta2->SetReceiveOkCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxSuccessSta2, this));
694   m_phySta2->SetReceiveErrorCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxFailureSta2, this));
695   Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
696   m_phySta2->SetMobility (sta2Mobility);
697   sta2Dev->SetPhy (m_phySta2);
698   sta2Node->AggregateObject (sta2Mobility);
699   sta2Node->AddDevice (sta2Dev);
700 
701   Ptr<Node> sta3Node = CreateObject<Node> ();
702   Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice> ();
703   m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy> (3);
704   m_phySta3->CreateWifiSpectrumPhyInterface (sta3Dev);
705   m_phySta3->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
706   m_phySta3->SetErrorRateModel (error);
707   m_phySta3->SetDevice (sta3Dev);
708   m_phySta3->SetChannel (spectrumChannel);
709   m_phySta3->SetReceiveOkCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxSuccessSta3, this));
710   m_phySta3->SetReceiveErrorCallback (MakeCallback (&TestDlOfdmaPhyTransmission::RxFailureSta3, this));
711   Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel> ();
712   m_phySta3->SetMobility (sta3Mobility);
713   sta3Dev->SetPhy (m_phySta3);
714   sta3Node->AggregateObject (sta3Mobility);
715   sta3Node->AddDevice (sta3Dev);
716 
717   Ptr<Node> interfererNode = CreateObject<Node> ();
718   Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
719   m_phyInterferer = CreateObject<WaveformGenerator> ();
720   m_phyInterferer->SetDevice (interfererDev);
721   m_phyInterferer->SetChannel (spectrumChannel);
722   m_phyInterferer->SetDutyCycle (1);
723   interfererNode->AddDevice (interfererDev);
724 }
725 
726 void
DoTeardown(void)727 TestDlOfdmaPhyTransmission::DoTeardown (void)
728 {
729   m_phyAp->Dispose ();
730   m_phyAp = 0;
731   m_phySta1->Dispose ();
732   m_phySta1 = 0;
733   m_phySta2->Dispose ();
734   m_phySta2 = 0;
735   m_phySta3->Dispose ();
736   m_phySta3 = 0;
737   m_phyInterferer->Dispose ();
738   m_phyInterferer = 0;
739 }
740 
741 void
RunOne(void)742 TestDlOfdmaPhyTransmission::RunOne (void)
743 {
744   RngSeedManager::SetSeed (1);
745   RngSeedManager::SetRun (1);
746   int64_t streamNumber = 0;
747   m_phyAp->AssignStreams (streamNumber);
748   m_phySta1->AssignStreams (streamNumber);
749   m_phySta2->AssignStreams (streamNumber);
750   m_phySta3->AssignStreams (streamNumber);
751 
752   m_phyAp->SetFrequency (m_frequency);
753   m_phyAp->SetChannelWidth (m_channelWidth);
754 
755   m_phySta1->SetFrequency (m_frequency);
756   m_phySta1->SetChannelWidth (m_channelWidth);
757 
758   m_phySta2->SetFrequency (m_frequency);
759   m_phySta2->SetChannelWidth (m_channelWidth);
760 
761   m_phySta3->SetFrequency (m_frequency);
762   m_phySta3->SetChannelWidth (m_channelWidth);
763 
764   Simulator::Schedule (Seconds (0.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
765 
766   //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
767   //Each STA should receive its PSDU.
768   Simulator::Schedule (Seconds (1.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
769 
770   //Since it takes m_expectedPpduDuration to transmit the PPDU,
771   //all 3 PHYs should be back to IDLE at the same time,
772   //even the PHY that has no PSDU addressed to it.
773   Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
774   Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::RX);
775   Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
776   Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::IDLE);
777   Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::IDLE);
778   Simulator::Schedule (Seconds (1.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::IDLE);
779 
780   //One PSDU of 1000 bytes should have been successfully received by STA 1
781   Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
782   //One PSDU of 1500 bytes should have been successfully received by STA 2
783   Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 1, 0, 1500);
784   //No PSDU should have been received by STA 3
785   Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
786 
787   Simulator::Schedule (Seconds (1.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
788 
789   //Send MU PPDU with two PSDUs addressed to STA 1 and STA 3:
790   //STA 1 should receive its PSDU, whereas STA 2 should not receive any PSDU
791   //but should keep its PHY busy during all PPDU duration.
792   Simulator::Schedule (Seconds (2.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 3);
793 
794   //Since it takes m_expectedPpduDuration to transmit the PPDU,
795   //all 3 PHYs should be back to IDLE at the same time,
796   //even the PHY that has no PSDU addressed to it.
797   Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
798   Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::CCA_BUSY);
799   Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::RX);
800   Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::IDLE);
801   Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::IDLE);
802   Simulator::Schedule (Seconds (2.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::IDLE);
803 
804   //One PSDU of 1000 bytes should have been successfully received by STA 1
805   Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
806   //No PSDU should have been received by STA 2
807   Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 0, 0);
808   //One PSDU of 1500 bytes should have been successfully received by STA 3
809   Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 1, 0, 1500);
810 
811   Simulator::Schedule (Seconds (2.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
812 
813   //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
814   Simulator::Schedule (Seconds (3.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
815 
816   //A strong non-wifi interference is generated on RU 1 during PSDU reception
817   BandInfo bandInfo;
818   bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
819   bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
820   bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
821   Bands bands;
822   bands.push_back (bandInfo);
823 
824   Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
825   Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
826   double interferencePower = 0.1; //watts
827   *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
828 
829   Simulator::Schedule (Seconds (3.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
830 
831   //Since it takes m_expectedPpduDuration to transmit the PPDU,
832   //both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
833   //even the PHY that has no PSDU addressed to it.
834   Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
835   Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::RX);
836   Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
837   Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::CCA_BUSY);
838   Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::CCA_BUSY);
839   Simulator::Schedule (Seconds (3.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
840 
841   //One PSDU of 1000 bytes should have been unsuccessfully received by STA 1 (since interference occupies RU 1)
842   Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 0, 1, 0);
843   //One PSDU of 1500 bytes should have been successfully received by STA 2
844   Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 1, 0, 1500);
845   //No PSDU should have been received by STA3
846   Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
847 
848   Simulator::Schedule (Seconds (3.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
849 
850   //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
851   Simulator::Schedule (Seconds (4.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
852 
853   //A strong non-wifi interference is generated on RU 2 during PSDU reception
854   bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
855   bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
856   bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
857   bands.clear ();
858   bands.push_back (bandInfo);
859 
860   Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel> (bands);
861   Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue> (SpectrumInterferenceRu2);
862   *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
863 
864   Simulator::Schedule (Seconds (4.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
865 
866   //Since it takes m_expectedPpduDuration to transmit the PPDU,
867   //both PHYs should be back to IDLE (or CCA_BUSY if interference on the primary 20 MHz) at the same time,
868   //even the PHY that has no PSDU addressed to it.
869   Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
870   Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::RX);
871   Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
872   Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
873   Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
874   Simulator::Schedule (Seconds (4.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
875 
876   //One PSDU of 1000 bytes should have been successfully received by STA 1
877   Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
878   //One PSDU of 1500 bytes should have been unsuccessfully received by STA 2 (since interference occupies RU 2)
879   Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 1, 0);
880   //No PSDU should have been received by STA3
881   Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
882 
883   Simulator::Schedule (Seconds (4.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
884 
885   //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
886   Simulator::Schedule (Seconds (5.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
887 
888   //A strong non-wifi interference is generated on the full band during PSDU reception
889   bandInfo.fc = m_frequency * 1e6;
890   bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
891   bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
892   bands.clear ();
893   bands.push_back (bandInfo);
894 
895   Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel> (bands);
896   Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue> (SpectrumInterferenceAll);
897   *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
898 
899   Simulator::Schedule (Seconds (5.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
900 
901   //Since it takes m_expectedPpduDuration to transmit the PPDU,
902   //both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
903   //even the PHY that has no PSDU addressed to it.
904   Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::RX);
905   Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::RX);
906   Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration - NanoSeconds (1), &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
907   Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta1, WifiPhyState::CCA_BUSY);
908   Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta2, WifiPhyState::CCA_BUSY);
909   Simulator::Schedule (Seconds (5.0) + m_expectedPpduDuration, &TestDlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3, WifiPhyState::CCA_BUSY);
910 
911   //One PSDU of 1000 bytes should have been unsuccessfully received by STA 1 (since interference occupies RU 1)
912   Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 0, 1, 0);
913   //One PSDU of 1500 bytes should have been unsuccessfully received by STA 2 (since interference occupies RU 2)
914   Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 1, 0);
915   //No PSDU should have been received by STA3
916   Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
917 
918   Simulator::Schedule (Seconds (5.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
919 
920   Simulator::Run ();
921 }
922 
923 void
DoRun(void)924 TestDlOfdmaPhyTransmission::DoRun (void)
925 {
926   m_frequency = 5180;
927   m_channelWidth = 20;
928   m_expectedPpduDuration = NanoSeconds (306400);
929   RunOne ();
930 
931   m_frequency = 5190;
932   m_channelWidth = 40;
933   m_expectedPpduDuration = NanoSeconds (156800);
934   RunOne ();
935 
936   m_frequency = 5210;
937   m_channelWidth = 80;
938   m_expectedPpduDuration = NanoSeconds (102400);
939   RunOne ();
940 
941   m_frequency = 5250;
942   m_channelWidth = 160;
943   m_expectedPpduDuration = NanoSeconds (75200);
944   RunOne ();
945 
946   Simulator::Destroy ();
947 }
948 
949 
950 /**
951  * \ingroup wifi-test
952  * \ingroup tests
953  *
954  * \brief UL-OFDMA PPDU UID attribution test
955  */
956 class TestUlOfdmaPpduUid : public TestCase
957 {
958 public:
959   TestUlOfdmaPpduUid ();
960   virtual ~TestUlOfdmaPpduUid ();
961 
962 private:
963   void DoSetup (void) override;
964   void DoTeardown (void) override;
965   void DoRun (void) override;
966 
967   /**
968    * Transmitted PPDU information function for AP
969    * \param uid the UID of the transmitted PPDU
970    */
971   void TxPpduAp (uint64_t uid);
972   /**
973    * Transmitted PPDU information function for STA 1
974    * \param uid the UID of the transmitted PPDU
975    */
976   void TxPpduSta1 (uint64_t uid);
977   /**
978    * Transmitted PPDU information function for STA 2
979    * \param uid the UID of the transmitted PPDU
980    */
981   void TxPpduSta2 (uint64_t uid);
982   /**
983    * Reset the global PPDU UID counter in WifiPhy
984    */
985   void ResetPpduUid (void);
986 
987   /**
988    * Send MU-PPDU toward both STAs.
989    */
990   void SendMuPpdu (void);
991   /**
992    * Send TB-PPDU from both STAs.
993    */
994   void SendTbPpdu (void);
995   /**
996    * Send SU-PPDU function
997    * \param txStaId the ID of the sending STA
998    */
999   void SendSuPpdu (uint16_t txStaId);
1000 
1001   /**
1002    * Check the UID of the transmitted PPDU
1003    * \param staId the STA-ID of the PHY (0 for AP)
1004    * \param expectedUid the expected UID
1005    */
1006   void CheckUid (uint16_t staId, uint64_t expectedUid);
1007 
1008   Ptr<OfdmaSpectrumWifiPhy> m_phyAp;   ///< PHY of AP
1009   Ptr<OfdmaSpectrumWifiPhy> m_phySta1; ///< PHY of STA 1
1010   Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
1011 
1012   uint64_t m_ppduUidAp; ///< UID of PPDU transmitted by AP
1013   uint64_t m_ppduUidSta1; ///< UID of PPDU transmitted by STA1
1014   uint64_t m_ppduUidSta2; ///< UID of PPDU transmitted by STA2
1015 };
1016 
TestUlOfdmaPpduUid()1017 TestUlOfdmaPpduUid::TestUlOfdmaPpduUid ()
1018   : TestCase ("UL-OFDMA PPDU UID attribution test"),
1019     m_ppduUidAp (UINT64_MAX),
1020     m_ppduUidSta1 (UINT64_MAX),
1021     m_ppduUidSta2 (UINT64_MAX)
1022 {
1023 }
1024 
~TestUlOfdmaPpduUid()1025 TestUlOfdmaPpduUid::~TestUlOfdmaPpduUid ()
1026 {
1027 }
1028 
1029 void
DoSetup(void)1030 TestUlOfdmaPpduUid::DoSetup (void)
1031 {
1032   Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
1033   Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
1034   lossModel->SetFrequency (DEFAULT_FREQUENCY);
1035   spectrumChannel->AddPropagationLossModel (lossModel);
1036   Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
1037   spectrumChannel->SetPropagationDelayModel (delayModel);
1038 
1039   Ptr<Node> apNode = CreateObject<Node> ();
1040   Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
1041   m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
1042   m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
1043   m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
1044   Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1045   m_phyAp->SetErrorRateModel (error);
1046   m_phyAp->SetFrequency (DEFAULT_FREQUENCY);
1047   m_phyAp->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
1048   m_phyAp->SetDevice (apDev);
1049   m_phyAp->SetChannel (spectrumChannel);
1050   m_phyAp->TraceConnectWithoutContext ("TxPpduUid", MakeCallback (&TestUlOfdmaPpduUid::TxPpduAp, this));
1051   Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
1052   m_phyAp->SetMobility (apMobility);
1053   apDev->SetPhy (m_phyAp);
1054   apNode->AggregateObject (apMobility);
1055   apNode->AddDevice (apDev);
1056 
1057   Ptr<Node> sta1Node = CreateObject<Node> ();
1058   Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
1059   m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
1060   m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
1061   m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
1062   m_phySta1->SetErrorRateModel (error);
1063   m_phySta1->SetFrequency (DEFAULT_FREQUENCY);
1064   m_phySta1->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
1065   m_phySta1->SetDevice (sta1Dev);
1066   m_phySta1->SetChannel (spectrumChannel);
1067   m_phySta1->TraceConnectWithoutContext ("TxPpduUid", MakeCallback (&TestUlOfdmaPpduUid::TxPpduSta1, this));
1068   Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
1069   m_phySta1->SetMobility (sta1Mobility);
1070   sta1Dev->SetPhy (m_phySta1);
1071   sta1Node->AggregateObject (sta1Mobility);
1072   sta1Node->AddDevice (sta1Dev);
1073 
1074   Ptr<Node> sta2Node = CreateObject<Node> ();
1075   Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
1076   m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
1077   m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
1078   m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
1079   m_phySta2->SetErrorRateModel (error);
1080   m_phySta2->SetFrequency (DEFAULT_FREQUENCY);
1081   m_phySta2->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
1082   m_phySta2->SetDevice (sta2Dev);
1083   m_phySta2->SetChannel (spectrumChannel);
1084   m_phySta2->TraceConnectWithoutContext ("TxPpduUid", MakeCallback (&TestUlOfdmaPpduUid::TxPpduSta2, this));
1085   Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
1086   m_phySta2->SetMobility (sta2Mobility);
1087   sta2Dev->SetPhy (m_phySta2);
1088   sta2Node->AggregateObject (sta2Mobility);
1089   sta2Node->AddDevice (sta2Dev);
1090 }
1091 
1092 void
DoTeardown(void)1093 TestUlOfdmaPpduUid::DoTeardown (void)
1094 {
1095   m_phyAp->Dispose ();
1096   m_phyAp = 0;
1097   m_phySta1->Dispose ();
1098   m_phySta1 = 0;
1099   m_phySta2->Dispose ();
1100   m_phySta2 = 0;
1101 }
1102 
1103 void
CheckUid(uint16_t staId,uint64_t expectedUid)1104 TestUlOfdmaPpduUid::CheckUid (uint16_t staId, uint64_t expectedUid)
1105 {
1106   uint64_t uid;
1107   std::string device;
1108   switch (staId)
1109     {
1110       case 0:
1111         uid = m_ppduUidAp;
1112         device = "AP";
1113         break;
1114       case 1:
1115         uid = m_ppduUidSta1;
1116         device = "STA1";
1117         break;
1118       case 2:
1119         uid = m_ppduUidSta2;
1120         device = "STA2";
1121         break;
1122       default:
1123         NS_ABORT_MSG ("Unexpected STA-ID");
1124     }
1125   NS_TEST_ASSERT_MSG_EQ (uid, expectedUid, "UID " << uid << " does not match expected one " << expectedUid << " for " << device << " at " << Simulator::Now ());
1126 }
1127 
1128 void
TxPpduAp(uint64_t uid)1129 TestUlOfdmaPpduUid::TxPpduAp (uint64_t uid)
1130 {
1131   NS_LOG_FUNCTION (this << uid);
1132   m_ppduUidAp = uid;
1133 }
1134 
1135 void
TxPpduSta1(uint64_t uid)1136 TestUlOfdmaPpduUid::TxPpduSta1 (uint64_t uid)
1137 {
1138   NS_LOG_FUNCTION (this << uid);
1139   m_ppduUidSta1 = uid;
1140 }
1141 
1142 void
TxPpduSta2(uint64_t uid)1143 TestUlOfdmaPpduUid::TxPpduSta2 (uint64_t uid)
1144 {
1145   NS_LOG_FUNCTION (this << uid);
1146   m_ppduUidSta2 = uid;
1147 }
1148 
1149 void
ResetPpduUid(void)1150 TestUlOfdmaPpduUid::ResetPpduUid (void)
1151 {
1152   NS_LOG_FUNCTION (this);
1153   m_phyAp->SetPpduUid (0); //one is enough since it's a global attribute
1154   return;
1155 }
1156 
1157 void
SendMuPpdu(void)1158 TestUlOfdmaPpduUid::SendMuPpdu (void)
1159 {
1160   WifiConstPsduMap psdus;
1161   WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_MU, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1162 
1163   uint16_t rxStaId1 = 1;
1164   HeRu::RuSpec ru1 (HeRu::RU_106_TONE, 1, false);
1165   txVector.SetRu (ru1, rxStaId1);
1166   txVector.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
1167   txVector.SetNss (1, rxStaId1);
1168 
1169   uint16_t rxStaId2 = 2;
1170   HeRu::RuSpec ru2 (HeRu::RU_106_TONE, 2, false);
1171   txVector.SetRu (ru2, rxStaId2);
1172   txVector.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
1173   txVector.SetNss (1, rxStaId2);
1174 
1175   Ptr<Packet> pkt1 = Create<Packet> (1000);
1176   WifiMacHeader hdr1;
1177   hdr1.SetType (WIFI_MAC_QOSDATA);
1178   hdr1.SetQosTid (0);
1179   hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:01"));
1180   hdr1.SetSequenceNumber (1);
1181   Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
1182   psdus.insert (std::make_pair (rxStaId1, psdu1));
1183 
1184   Ptr<Packet> pkt2 = Create<Packet> (1500);
1185   WifiMacHeader hdr2;
1186   hdr2.SetType (WIFI_MAC_QOSDATA);
1187   hdr2.SetQosTid (0);
1188   hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
1189   hdr2.SetSequenceNumber (2);
1190   Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
1191   psdus.insert (std::make_pair (rxStaId2, psdu2));
1192 
1193   m_phyAp->Send (psdus, txVector);
1194 }
1195 
1196 void
SendTbPpdu(void)1197 TestUlOfdmaPpduUid::SendTbPpdu (void)
1198 {
1199   WifiConstPsduMap psdus1;
1200   WifiConstPsduMap psdus2;
1201   WifiTxVector txVector1 = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1202   WifiTxVector txVector2 = txVector1;
1203 
1204   uint16_t rxStaId1 = 1;
1205   HeRu::RuSpec ru1 (HeRu::RU_106_TONE, 1, false);
1206   txVector1.SetRu (ru1, rxStaId1);
1207   txVector1.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
1208   txVector1.SetNss (1, rxStaId1);
1209 
1210   Ptr<Packet> pkt1 = Create<Packet> (1000);
1211   WifiMacHeader hdr1;
1212   hdr1.SetType (WIFI_MAC_QOSDATA);
1213   hdr1.SetQosTid (0);
1214   hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1215   hdr1.SetSequenceNumber (1);
1216   Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
1217   psdus1.insert (std::make_pair (rxStaId1, psdu1));
1218 
1219   uint16_t rxStaId2 = 2;
1220   HeRu::RuSpec ru2 (HeRu::RU_106_TONE, 2, false);
1221   txVector2.SetRu (ru2, rxStaId2);
1222   txVector2.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
1223   txVector2.SetNss (1, rxStaId2);
1224 
1225   Ptr<Packet> pkt2 = Create<Packet> (1500);
1226   WifiMacHeader hdr2;
1227   hdr2.SetType (WIFI_MAC_QOSDATA);
1228   hdr2.SetQosTid (0);
1229   hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1230   hdr2.SetSequenceNumber (2);
1231   Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
1232   psdus2.insert (std::make_pair (rxStaId2, psdu2));
1233 
1234   Time txDuration1 = m_phySta1->CalculateTxDuration (psdu1->GetSize (), txVector1,
1235                                                      m_phySta1->GetPhyBand (), rxStaId1);
1236   Time txDuration2 = m_phySta2->CalculateTxDuration (psdu2->GetSize (), txVector2,
1237                                                      m_phySta1->GetPhyBand (), rxStaId2);
1238   Time txDuration = std::max (txDuration1, txDuration2);
1239 
1240   txVector1.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta1->GetPhyBand ()));
1241   txVector2.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta2->GetPhyBand ()));
1242 
1243   m_phySta1->Send (psdus1, txVector1);
1244   m_phySta2->Send (psdus2, txVector2);
1245 }
1246 
1247 void
SendSuPpdu(uint16_t txStaId)1248 TestUlOfdmaPpduUid::SendSuPpdu (uint16_t txStaId)
1249 {
1250   WifiConstPsduMap psdus;
1251   WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1252 
1253   Ptr<Packet> pkt = Create<Packet> (1000);
1254   WifiMacHeader hdr;
1255   hdr.SetType (WIFI_MAC_QOSDATA);
1256   hdr.SetQosTid (0);
1257   hdr.SetAddr1 (Mac48Address::GetBroadcast ());
1258   hdr.SetSequenceNumber (1);
1259   Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1260   psdus.insert (std::make_pair (SU_STA_ID, psdu));
1261 
1262   switch (txStaId)
1263     {
1264       case 0:
1265         m_phyAp->Send (psdus, txVector);
1266         break;
1267       case 1:
1268         m_phySta1->Send (psdus, txVector);
1269         break;
1270       case 2:
1271         m_phySta2->Send (psdus, txVector);
1272         break;
1273       default:
1274         NS_ABORT_MSG ("Unexpected STA-ID");
1275     }
1276 }
1277 
1278 void
DoRun(void)1279 TestUlOfdmaPpduUid::DoRun (void)
1280 {
1281   RngSeedManager::SetSeed (1);
1282   RngSeedManager::SetRun (1);
1283   int64_t streamNumber = 0;
1284   m_phyAp->AssignStreams (streamNumber);
1285   m_phySta1->AssignStreams (streamNumber);
1286   m_phySta2->AssignStreams (streamNumber);
1287 
1288   //Reset PPDU UID so as not to be dependent on previously executed test cases,
1289   //since global attribute will be changed).
1290   ResetPpduUid ();
1291 
1292   //Send HE MU PPDU with two PSDUs addressed to STA 1 and STA 2.
1293   //PPDU UID should be equal to 0 (the first counter value).
1294   Simulator::Schedule (Seconds (1.0), &TestUlOfdmaPpduUid::SendMuPpdu, this);
1295   Simulator::Schedule (Seconds (1.0), &TestUlOfdmaPpduUid::CheckUid, this, 0, 0);
1296 
1297   //Send HE SU PPDU from AP.
1298   //PPDU UID should be incremented since this is a new PPDU.
1299   Simulator::Schedule (Seconds (1.1), &TestUlOfdmaPpduUid::SendSuPpdu, this, 0);
1300   Simulator::Schedule (Seconds (1.1), &TestUlOfdmaPpduUid::CheckUid, this, 0, 1);
1301 
1302   //Send HE TB PPDU from STAs to AP.
1303   //PPDU UID should NOT be incremented since HE TB PPDUs reuse the UID of the immediately
1304   //preceding correctly received PPDU (which normally contains the trigger frame).
1305   Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::SendTbPpdu, this);
1306   Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::CheckUid, this, 1, 1);
1307   Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::CheckUid, this, 2, 1);
1308 
1309   //Send HE SU PPDU from STA1.
1310   //PPDU UID should be incremented since this is a new PPDU.
1311   Simulator::Schedule (Seconds (1.2), &TestUlOfdmaPpduUid::SendSuPpdu, this, 1);
1312   Simulator::Schedule (Seconds (1.2), &TestUlOfdmaPpduUid::CheckUid, this, 1, 2);
1313 
1314   Simulator::Run ();
1315   Simulator::Destroy ();
1316 }
1317 
1318 /**
1319  * \ingroup wifi-test
1320  * \ingroup tests
1321  *
1322  * \brief UL-OFDMA multiple RX events test
1323  */
1324 class TestMultipleHeTbPreambles : public TestCase
1325 {
1326 public:
1327   TestMultipleHeTbPreambles ();
1328   virtual ~TestMultipleHeTbPreambles ();
1329 
1330 private:
1331   void DoSetup (void) override;
1332   void DoTeardown (void) override;
1333   void DoRun (void) override;
1334 
1335   /**
1336    * Receive HE TB PPDU function.
1337    *
1338    * \param uid the UID used to identify a set of HE TB PPDUs belonging to the same UL-MU transmission
1339    * \param staId the STA ID
1340    * \param txPowerWatts the TX power in watts
1341    * \param payloadSize the size of the payload in bytes
1342    */
1343   void RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize);
1344 
1345   /**
1346    * Receive OFDMA part of HE TB PPDU function.
1347    * Immediately schedules DoRxHeTbPpduOfdmaPart.
1348    *
1349    * \param rxParamsOfdma the spectrum signal parameters to send for OFDMA part
1350    */
1351   void RxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma);
1352   /**
1353    * Receive OFDMA part of HE TB PPDU function.
1354    * Actual reception call.
1355    *
1356    * \param rxParamsOfdma the spectrum signal parameters to send for OFDMA part
1357    */
1358   void DoRxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma);
1359 
1360   /**
1361    * RX dropped function
1362    * \param p the packet
1363    * \param reason the reason
1364    */
1365   void RxDropped (Ptr<const Packet> p, WifiPhyRxfailureReason reason);
1366 
1367   /**
1368    * Reset function
1369    */
1370   void Reset (void);
1371 
1372   /**
1373    * Check the received HE TB preambles
1374    * \param nEvents the number of events created by the PHY
1375    * \param uids the vector of expected UIDs
1376    */
1377   void CheckHeTbPreambles (size_t nEvents, std::vector <uint64_t> uids);
1378 
1379   /**
1380    * Check the number of bytes dropped
1381    * \param expectedBytesDropped the expected number of bytes dropped
1382    */
1383   void CheckBytesDropped (size_t expectedBytesDropped);
1384 
1385   Ptr<OfdmaSpectrumWifiPhy> m_phy; ///< Phy
1386 
1387   uint64_t m_totalBytesDropped; ///< total number of dropped bytes
1388 };
1389 
TestMultipleHeTbPreambles()1390 TestMultipleHeTbPreambles::TestMultipleHeTbPreambles ()
1391   : TestCase ("UL-OFDMA multiple RX events test"),
1392     m_totalBytesDropped (0)
1393 {
1394 }
1395 
~TestMultipleHeTbPreambles()1396 TestMultipleHeTbPreambles::~TestMultipleHeTbPreambles ()
1397 {
1398 }
1399 
1400 void
Reset(void)1401 TestMultipleHeTbPreambles::Reset (void)
1402 {
1403   NS_LOG_FUNCTION (this);
1404   m_totalBytesDropped = 0;
1405   //We have to reset PHY here since we do not trigger OFDMA payload RX event in this test
1406   m_phy->Reset ();
1407 }
1408 
1409 void
RxDropped(Ptr<const Packet> p,WifiPhyRxfailureReason reason)1410 TestMultipleHeTbPreambles::RxDropped (Ptr<const Packet> p, WifiPhyRxfailureReason reason)
1411 {
1412   NS_LOG_FUNCTION (this << p << reason);
1413   m_totalBytesDropped += (p->GetSize () - 30);
1414 }
1415 
1416 void
CheckHeTbPreambles(size_t nEvents,std::vector<uint64_t> uids)1417 TestMultipleHeTbPreambles::CheckHeTbPreambles (size_t nEvents, std::vector <uint64_t> uids)
1418 {
1419   auto events = m_phy->GetCurrentPreambleEvents ();
1420   NS_TEST_ASSERT_MSG_EQ (events.size (), nEvents, "The number of UL MU events is not correct!");
1421   for (auto const& uid : uids)
1422     {
1423       auto pair = std::make_pair (uid, WIFI_PREAMBLE_HE_TB);
1424       auto it = events.find (pair);
1425       bool found = (it != events.end ());
1426       NS_TEST_ASSERT_MSG_EQ (found, true, "HE TB PPDU with UID " << uid << " has not been received!");
1427     }
1428 }
1429 
1430 void
CheckBytesDropped(size_t expectedBytesDropped)1431 TestMultipleHeTbPreambles::CheckBytesDropped (size_t expectedBytesDropped)
1432 {
1433   NS_TEST_ASSERT_MSG_EQ (m_totalBytesDropped, expectedBytesDropped, "The number of dropped bytes is not correct!");
1434 }
1435 
1436 void
RxHeTbPpdu(uint64_t uid,uint16_t staId,double txPowerWatts,size_t payloadSize)1437 TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize)
1438 {
1439   WifiConstPsduMap psdus;
1440   WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1441 
1442   HeRu::RuSpec ru (HeRu::RU_106_TONE, staId, false);
1443   ru.SetPhyIndex (DEFAULT_CHANNEL_WIDTH, 0);
1444   txVector.SetRu (ru, staId);
1445   txVector.SetMode (HePhy::GetHeMcs7 (), staId);
1446   txVector.SetNss (1, staId);
1447 
1448   Ptr<Packet> pkt = Create<Packet> (payloadSize);
1449   WifiMacHeader hdr;
1450   hdr.SetType (WIFI_MAC_QOSDATA);
1451   hdr.SetQosTid (0);
1452   hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1453   hdr.SetSequenceNumber (1);
1454   Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1455   psdus.insert (std::make_pair (staId, psdu));
1456 
1457   Time ppduDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand (), staId);
1458   Ptr<HePpdu> ppdu = Create<HePpdu> (psdus, txVector, ppduDuration, WIFI_PHY_BAND_5GHZ, uid,
1459                                      HePpdu::PSD_HE_TB_NON_OFDMA_PORTION);
1460 
1461   //Send non-OFDMA part
1462   Time nonOfdmaDuration = m_phy->GetHePhy ()->CalculateNonOfdmaDurationForHeTb (txVector);
1463   uint32_t centerFrequency = m_phy->GetHePhy ()->GetCenterFrequencyForNonOfdmaPart (txVector, staId);
1464   uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1465   uint16_t channelWidth = ruWidth < 20 ? 20 : ruWidth;
1466   Ptr<SpectrumValue> rxPsd = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerWatts, m_phy->GetGuardBandwidth (channelWidth));
1467   Ptr<WifiSpectrumSignalParameters> rxParams = Create<WifiSpectrumSignalParameters> ();
1468   rxParams->psd = rxPsd;
1469   rxParams->txPhy = 0;
1470   rxParams->duration = nonOfdmaDuration;
1471   rxParams->ppdu = ppdu;
1472 
1473   m_phy->StartRx (rxParams);
1474 
1475   //Schedule OFDMA part
1476   Ptr<HePpdu> ppduOfdma = DynamicCast<HePpdu> (ppdu->Copy ()); //since flag will be modified
1477   ppduOfdma->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
1478   WifiSpectrumBand band = m_phy->GetHePhy ()->GetRuBandForRx (txVector, staId);
1479   Ptr<SpectrumValue> rxPsdOfdma = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (DEFAULT_FREQUENCY, DEFAULT_CHANNEL_WIDTH, txPowerWatts, DEFAULT_GUARD_WIDTH, band);
1480   Ptr<WifiSpectrumSignalParameters> rxParamsOfdma = Create<WifiSpectrumSignalParameters> ();
1481   rxParamsOfdma->psd = rxPsd;
1482   rxParamsOfdma->txPhy = 0;
1483   rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration;
1484   rxParamsOfdma->ppdu = ppduOfdma;
1485   Simulator::Schedule (nonOfdmaDuration, &TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart, this, rxParamsOfdma);
1486 }
1487 
1488 void
RxHeTbPpduOfdmaPart(Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)1489 TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)
1490 {
1491   Simulator::ScheduleNow (&TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart, this, rxParamsOfdma);
1492 }
1493 
1494 void
DoRxHeTbPpduOfdmaPart(Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)1495 TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)
1496 {
1497   //This is needed to make sure the OFDMA part is started as the last event since HE-SIG-A should end at the exact same time as the start
1498   //For normal WifiNetDevices, this the reception of the OFDMA part is scheduled after end of HE-SIG-A decoding.
1499   m_phy->StartRx (rxParamsOfdma);
1500 }
1501 
1502 void
DoSetup(void)1503 TestMultipleHeTbPreambles::DoSetup (void)
1504 {
1505   Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice> ();
1506   m_phy = CreateObject<OfdmaSpectrumWifiPhy> (0);
1507   m_phy->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
1508   Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1509   Ptr<ApWifiMac> mac = CreateObject<ApWifiMac> ();
1510   mac->SetAttribute ("BeaconGeneration", BooleanValue (false));
1511   dev->SetMac (mac);
1512   m_phy->SetErrorRateModel (error);
1513   m_phy->SetChannelNumber (DEFAULT_CHANNEL_NUMBER);
1514   m_phy->SetFrequency (DEFAULT_FREQUENCY);
1515   m_phy->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
1516   m_phy->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&TestMultipleHeTbPreambles::RxDropped, this));
1517   m_phy->SetDevice (dev);
1518   Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1519   preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
1520   preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
1521   m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1522 }
1523 
1524 void
DoTeardown(void)1525 TestMultipleHeTbPreambles::DoTeardown (void)
1526 {
1527   m_phy->Dispose ();
1528   m_phy = 0;
1529 }
1530 
1531 void
DoRun(void)1532 TestMultipleHeTbPreambles::DoRun (void)
1533 {
1534   RngSeedManager::SetSeed (1);
1535   RngSeedManager::SetRun (1);
1536   int64_t streamNumber = 0;
1537   m_phy->AssignStreams (streamNumber);
1538 
1539   double txPowerWatts = 0.01;
1540 
1541   {
1542     //Verify a single UL MU transmission with two stations belonging to the same BSS
1543     std::vector<uint64_t> uids {0};
1544     Simulator::Schedule (Seconds (1), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1545     Simulator::Schedule (Seconds (1) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1546     //Check that we received a single UL MU transmission with the corresponding UID
1547     Simulator::Schedule (Seconds (1.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, uids);
1548     Simulator::Schedule (Seconds (1.5), &TestMultipleHeTbPreambles::Reset, this);
1549   }
1550 
1551   {
1552     //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1553     //arrives during the preamble detection window and with half the power of the first transmission.
1554     std::vector<uint64_t> uids {1, 2};
1555     Simulator::Schedule (Seconds (2), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1556     Simulator::Schedule (Seconds (2) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1557     Simulator::Schedule (Seconds (2) + NanoSeconds (200), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts / 2, 1003);
1558     Simulator::Schedule (Seconds (2) + NanoSeconds (300), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts / 2, 1004);
1559     //Check that we received the correct reception of 2 UL MU transmissions with the corresponding UIDs
1560     Simulator::Schedule (Seconds (2.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 2, uids);
1561     Simulator::Schedule (Seconds (2.5), &TestMultipleHeTbPreambles::Reset, this);
1562     //TODO: verify PPDUs from second UL MU transmission are dropped
1563   }
1564 
1565   {
1566     //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1567     //arrives during the preamble detection window and with twice the power of the first transmission.
1568     std::vector<uint64_t> uids {3, 4};
1569     Simulator::Schedule (Seconds (3), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts / 2, 1001);
1570     Simulator::Schedule (Seconds (3) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts / 2, 1002);
1571     Simulator::Schedule (Seconds (3) + NanoSeconds (200), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1572     Simulator::Schedule (Seconds (3) + NanoSeconds (300), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1573     //Check that we received the correct reception of 2 UL MU transmissions with the corresponding UIDs
1574     Simulator::Schedule (Seconds (3.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 2, uids);
1575     Simulator::Schedule (Seconds (3.5), &TestMultipleHeTbPreambles::Reset, this);
1576     //TODO: verify PPDUs from first UL MU transmission are dropped
1577   }
1578 
1579   {
1580     //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1581     //arrives during PHY header reception and with the same power as the first transmission.
1582     std::vector<uint64_t> uids {5, 6};
1583     Simulator::Schedule (Seconds (4), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1584     Simulator::Schedule (Seconds (4) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1585     Simulator::Schedule (Seconds (4) + MicroSeconds (5), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1586     Simulator::Schedule (Seconds (4) + MicroSeconds (5) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1587     //Check that we received the correct reception of the first UL MU transmission with the corresponding UID (second one dropped)
1588     Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, std::vector<uint64_t> {uids[0]});
1589     //The packets of the second UL MU transmission should have been dropped
1590     Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1003 + 1004);
1591     Simulator::Schedule (Seconds (4.5), &TestMultipleHeTbPreambles::Reset, this);
1592   }
1593 
1594   {
1595     //Verify the correct reception of one UL MU transmission out of 2 with two stations per BSS, where the second transmission
1596     //arrives during payload reception and with the same power as the first transmission.
1597     std::vector<uint64_t> uids {7, 8};
1598     Simulator::Schedule (Seconds (5), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1599     Simulator::Schedule (Seconds (5) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1600     Simulator::Schedule (Seconds (5) + MicroSeconds (50), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1601     Simulator::Schedule (Seconds (5) + MicroSeconds (50) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1602     //Check that we received the correct reception of the first UL MU transmission with the corresponding UID (second one dropped)
1603     Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, std::vector<uint64_t> {uids[0]});
1604     //The packets of the second UL MU transmission should have been dropped
1605     Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1003 + 1004);
1606     Simulator::Schedule (Seconds (5.5), &TestMultipleHeTbPreambles::Reset, this);
1607   }
1608 
1609   {
1610     //Verify the correct reception of a single UL MU transmission with two stations belonging to the same BSS,
1611     //and the second PPDU arrives 500ns after the first PPDU, i.e. it exceeds the delay spread of 400ns
1612     std::vector<uint64_t> uids {9};
1613     Simulator::Schedule (Seconds (6), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1614     Simulator::Schedule (Seconds (6) + NanoSeconds (500), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1615     //Check that we received a single UL MU transmission with the corresponding UID
1616     Simulator::Schedule (Seconds (6.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, uids);
1617     //The first packet of 1001 bytes should be dropped because preamble is not detected after 4us (because the PPDU that arrived at 500ns is interfering):
1618     //the second HE TB PPDU is acting as interference since it arrived after the maximum allowed 400ns.
1619     //Obviously, that second packet of 1002 bytes is dropped as well.
1620     Simulator::Schedule (Seconds (6.0) + MicroSeconds (5), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1001 + 1002);
1621     Simulator::Schedule (Seconds (6.5), &TestMultipleHeTbPreambles::Reset, this);
1622   }
1623 
1624   Simulator::Run ();
1625   Simulator::Destroy ();
1626 }
1627 
1628 /**
1629  * \ingroup wifi-test
1630  * \ingroup tests
1631  *
1632  * \brief UL-OFDMA PHY test
1633  */
1634 class TestUlOfdmaPhyTransmission : public TestCase
1635 {
1636 public:
1637   TestUlOfdmaPhyTransmission ();
1638   virtual ~TestUlOfdmaPhyTransmission ();
1639 
1640 private:
1641   void DoSetup (void) override;
1642   void DoTeardown (void) override;
1643   void DoRun (void) override;
1644 
1645   /**
1646    * Get TXVECTOR for HE TB PPDU.
1647    * \param txStaId the ID of the TX STA
1648    * \param index the RU index used for the transmission
1649    * \param bssColor the BSS color of the TX STA
1650    * \return the TXVECTOR for HE TB PPDU
1651    */
1652   WifiTxVector GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_t index, uint8_t bssColor) const;
1653   /**
1654    * Send HE TB PPDU function
1655    * \param txStaId the ID of the TX STA
1656    * \param index the RU index used for the transmission
1657    * \param payloadSize the size of the payload in bytes
1658    * \param uid the UID of the trigger frame that is initiating this transmission
1659    * \param bssColor the BSS color of the TX STA
1660    */
1661   void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
1662 
1663   /**
1664    * Send HE SU PPDU function
1665    * \param txStaId the ID of the TX STA
1666    * \param payloadSize the size of the payload in bytes
1667    * \param uid the UID of the trigger frame that is initiating this transmission
1668    * \param bssColor the BSS color of the TX STA
1669    */
1670   void SendHeSuPpdu (uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
1671 
1672   /**
1673    * Set the BSS color
1674    * \param phy the PHY
1675    * \param bssColor the BSS color
1676    */
1677   void SetBssColor (Ptr<WifiPhy> phy, uint8_t bssColor);
1678 
1679   /**
1680    * Set the PSD limit
1681    * \param phy the PHY
1682    * \param psdLimit the PSD limit in dBm/MHz
1683    */
1684   void SetPsdLimit (Ptr<WifiPhy> phy, double psdLimit);
1685 
1686   /**
1687    * Generate interference function
1688    * \param interferencePsd the PSD of the interference to be generated
1689    * \param duration the duration of the interference
1690    */
1691   void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
1692   /**
1693    * Stop interference function
1694    */
1695   void StopInterference (void);
1696 
1697   /**
1698    * Run one function
1699    */
1700   void RunOne ();
1701 
1702   /**
1703    * Check the received PSDUs from STA1
1704    * \param expectedSuccess the expected number of success
1705    * \param expectedFailures the expected number of failures
1706    * \param expectedBytes the expected number of bytes
1707    */
1708   void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
1709 
1710   /**
1711    * Check the received PSDUs from STA2
1712    * \param expectedSuccess the expected number of success
1713    * \param expectedFailures the expected number of failures
1714    * \param expectedBytes the expected number of bytes
1715    */
1716   void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
1717 
1718   /**
1719    * Check the received power for the non-OFDMA of the HE TB PPDUs over the given band
1720    * \param phy the PHY
1721    * \param band the WifiSpectrumBand over which the power is measured
1722    * \param expectedRxPower the expected received power in W
1723    */
1724   void CheckNonOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower);
1725   /**
1726    * Check the received power for the OFDMA part of the HE TB PPDUs over the given band
1727    * \param phy the PHY
1728    * \param band the WifiSpectrumBand over which the power is measured
1729    * \param expectedRxPower the expected received power in W
1730    */
1731   void CheckOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower);
1732 
1733   /**
1734    * Verify all events are cleared at end of TX or RX
1735    */
1736   void VerifyEventsCleared (void);
1737 
1738   /**
1739    * Check the PHY state
1740    * \param phy the PHY
1741    * \param expectedState the expected state of the PHY
1742    */
1743   void CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
1744   /// \copydoc CheckPhyState
1745   void DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
1746 
1747   /**
1748    * Reset function
1749    */
1750   void Reset ();
1751 
1752   /**
1753    * Receive success function
1754    * \param psdu the PSDU
1755    * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
1756    * \param txVector the transmit vector
1757    * \param statusPerMpdu reception status per MPDU
1758    */
1759   void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1760 
1761   /**
1762    * Receive failure function
1763    * \param psdu the PSDU
1764    */
1765   void RxFailure (Ptr<WifiPsdu> psdu);
1766 
1767   /**
1768    * Schedule test to perform.
1769    * The interference generation should be scheduled apart.
1770    *
1771    * \param delay the reference delay to schedule the events
1772    * \param solicited flag indicating if HE TB PPDUs were solicited by the AP
1773    * \param expectedStateAtEnd the expected state of the PHY at the end of the reception
1774    * \param expectedSuccessFromSta1 the expected number of success from STA 1
1775    * \param expectedFailuresFromSta1 the expected number of failures from STA 1
1776    * \param expectedBytesFromSta1 the expected number of bytes from STA 1
1777    * \param expectedSuccessFromSta2 the expected number of success from STA 2
1778    * \param expectedFailuresFromSta2 the expected number of failures from STA 2
1779    * \param expectedBytesFromSta2 the expected number of bytes from STA 2
1780    * \param scheduleTxSta1 flag indicating to schedule a HE TB PPDU from STA 1
1781    * \param expectedStateBeforeEnd the expected state of the PHY before the end of the transmission
1782    */
1783   void ScheduleTest (Time delay, bool solicited, WifiPhyState expectedStateAtEnd,
1784                      uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1,
1785                      uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2,
1786                      bool scheduleTxSta1 = true, WifiPhyState expectedStateBeforeEnd = WifiPhyState::RX);
1787 
1788   /**
1789    * Schedule power measurement related checks.
1790    *
1791    * \param delay the reference delay used to schedule the events
1792    * \param rxPowerNonOfdmaRu1 the received power (in watts) on the non-OFDMA part of RU1
1793    * \param rxPowerNonOfdmaRu2 the received power (in watts) on the non-OFDMA part of RU2
1794    * \param rxPowerOfdmaRu1 the received power (in watts) on RU1
1795    * \param rxPowerOfdmaRu2 the received power (in watts) on RU2
1796    */
1797   void SchedulePowerMeasurementChecks (Time delay, double rxPowerNonOfdmaRu1, double rxPowerNonOfdmaRu2,
1798                                        double rxPowerOfdmaRu1, double rxPowerOfdmaRu2);
1799   /**
1800    * Log scenario description
1801    *
1802    * \param log the scenario description to add to log
1803    */
1804   void LogScenario (std::string log) const;
1805 
1806   Ptr<OfdmaSpectrumWifiPhy> m_phyAp;   ///< PHY of AP
1807   Ptr<OfdmaSpectrumWifiPhy> m_phySta1; ///< PHY of STA 1
1808   Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
1809   Ptr<OfdmaSpectrumWifiPhy> m_phySta3; ///< PHY of STA 3
1810 
1811   Ptr<WaveformGenerator> m_phyInterferer; ///< PHY of interferer
1812 
1813   uint32_t m_countRxSuccessFromSta1; ///< count RX success from STA 1
1814   uint32_t m_countRxSuccessFromSta2; ///< count RX success from STA 2
1815   uint32_t m_countRxFailureFromSta1; ///< count RX failure from STA 1
1816   uint32_t m_countRxFailureFromSta2; ///< count RX failure from STA 2
1817   uint32_t m_countRxBytesFromSta1;   ///< count RX bytes from STA 1
1818   uint32_t m_countRxBytesFromSta2;   ///< count RX bytes from STA 2
1819 
1820   uint16_t m_frequency;        ///< frequency in MHz
1821   uint16_t m_channelWidth;     ///< channel width in MHz
1822   Time m_expectedPpduDuration; ///< expected duration to send MU PPDU
1823 };
1824 
TestUlOfdmaPhyTransmission()1825 TestUlOfdmaPhyTransmission::TestUlOfdmaPhyTransmission ()
1826   : TestCase ("UL-OFDMA PHY test"),
1827     m_countRxSuccessFromSta1 (0),
1828     m_countRxSuccessFromSta2 (0),
1829     m_countRxFailureFromSta1 (0),
1830     m_countRxFailureFromSta2 (0),
1831     m_countRxBytesFromSta1 (0),
1832     m_countRxBytesFromSta2 (0),
1833     m_frequency (DEFAULT_FREQUENCY),
1834     m_channelWidth (DEFAULT_CHANNEL_WIDTH),
1835     m_expectedPpduDuration (NanoSeconds (271200))
1836 {
1837 }
1838 
1839 void
SendHeSuPpdu(uint16_t txStaId,std::size_t payloadSize,uint64_t uid,uint8_t bssColor)1840 TestUlOfdmaPhyTransmission::SendHeSuPpdu (uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
1841 {
1842   NS_LOG_FUNCTION (this << txStaId << payloadSize << uid << +bssColor);
1843   WifiConstPsduMap psdus;
1844 
1845   WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, m_channelWidth, false, false, false, bssColor);
1846 
1847   Ptr<Packet> pkt = Create<Packet> (payloadSize);
1848   WifiMacHeader hdr;
1849   hdr.SetType (WIFI_MAC_QOSDATA);
1850   hdr.SetQosTid (0);
1851   hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1852   std::ostringstream addr;
1853   addr << "00:00:00:00:00:0" << txStaId;
1854   hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
1855   hdr.SetSequenceNumber (1);
1856   Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1857   psdus.insert (std::make_pair (SU_STA_ID, psdu));
1858 
1859   Ptr<OfdmaSpectrumWifiPhy> phy;
1860   if (txStaId == 1)
1861     {
1862       phy = m_phySta1;
1863     }
1864   else if (txStaId == 2)
1865     {
1866       phy = m_phySta2;
1867     }
1868   else if (txStaId == 3)
1869     {
1870       phy = m_phySta3;
1871     }
1872   else if (txStaId == 0)
1873     {
1874       phy = m_phyAp;
1875     }
1876   phy->SetPpduUid (uid);
1877   phy->Send (psdus, txVector);
1878 }
1879 
1880 WifiTxVector
GetTxVectorForHeTbPpdu(uint16_t txStaId,std::size_t index,uint8_t bssColor) const1881 TestUlOfdmaPhyTransmission::GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_t index, uint8_t bssColor) const
1882 {
1883   WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, m_channelWidth, false, false, false, bssColor);
1884 
1885   HeRu::RuType ruType = HeRu::RU_106_TONE;
1886   if (m_channelWidth == 20)
1887     {
1888       ruType = HeRu::RU_106_TONE;
1889     }
1890   else if (m_channelWidth == 40)
1891     {
1892       ruType = HeRu::RU_242_TONE;
1893     }
1894   else if (m_channelWidth == 80)
1895     {
1896       ruType = HeRu::RU_484_TONE;
1897     }
1898   else if (m_channelWidth == 160)
1899     {
1900       ruType = HeRu::RU_996_TONE;
1901     }
1902   else
1903     {
1904       NS_ASSERT_MSG (false, "Unsupported channel width");
1905     }
1906 
1907   bool primary80MHz = true;
1908   if (m_channelWidth == 160 && index == 2)
1909     {
1910       primary80MHz = false;
1911       index = 1;
1912     }
1913   HeRu::RuSpec ru (ruType, index, primary80MHz);
1914   ru.SetPhyIndex (m_channelWidth, 0);
1915   txVector.SetRu (ru, txStaId);
1916   txVector.SetMode (HePhy::GetHeMcs7 (), txStaId);
1917   txVector.SetNss (1, txStaId);
1918   return txVector;
1919 }
1920 
1921 void
SendHeTbPpdu(uint16_t txStaId,std::size_t index,std::size_t payloadSize,uint64_t uid,uint8_t bssColor)1922 TestUlOfdmaPhyTransmission::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
1923 {
1924   NS_LOG_FUNCTION (this << txStaId << index << payloadSize << uid << +bssColor);
1925   WifiConstPsduMap psdus;
1926 
1927   WifiTxVector txVector = GetTxVectorForHeTbPpdu (txStaId, index, bssColor);
1928   Ptr<Packet> pkt = Create<Packet> (payloadSize);
1929   WifiMacHeader hdr;
1930   hdr.SetType (WIFI_MAC_QOSDATA);
1931   hdr.SetQosTid (0);
1932   hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1933   std::ostringstream addr;
1934   addr << "00:00:00:00:00:0" << txStaId;
1935   hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
1936   hdr.SetSequenceNumber (1);
1937   Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1938   psdus.insert (std::make_pair (txStaId, psdu));
1939 
1940   Ptr<OfdmaSpectrumWifiPhy> phy;
1941   if (txStaId == 1)
1942     {
1943       phy = m_phySta1;
1944     }
1945   else if (txStaId == 2)
1946     {
1947       phy = m_phySta2;
1948     }
1949   else if (txStaId == 3)
1950     {
1951       phy = m_phySta3;
1952     }
1953 
1954   Time txDuration = phy->CalculateTxDuration (psdu->GetSize (), txVector, phy->GetPhyBand (), txStaId);
1955   txVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
1956 
1957   phy->SetPpduUid (uid);
1958   phy->Send (psdus, txVector);
1959 }
1960 
1961 void
GenerateInterference(Ptr<SpectrumValue> interferencePsd,Time duration)1962 TestUlOfdmaPhyTransmission::GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration)
1963 {
1964   NS_LOG_FUNCTION (this << duration);
1965   m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
1966   m_phyInterferer->SetPeriod (duration);
1967   m_phyInterferer->Start ();
1968   Simulator::Schedule (duration, &TestUlOfdmaPhyTransmission::StopInterference, this);
1969 }
1970 
1971 void
StopInterference(void)1972 TestUlOfdmaPhyTransmission::StopInterference (void)
1973 {
1974   m_phyInterferer->Stop();
1975 }
1976 
~TestUlOfdmaPhyTransmission()1977 TestUlOfdmaPhyTransmission::~TestUlOfdmaPhyTransmission ()
1978 {
1979 }
1980 
1981 void
RxSuccess(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)1982 TestUlOfdmaPhyTransmission::RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
1983 {
1984   NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 () << rxSignalInfo << txVector);
1985   if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
1986     {
1987       m_countRxSuccessFromSta1++;
1988       m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
1989     }
1990   else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
1991     {
1992       m_countRxSuccessFromSta2++;
1993       m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
1994     }
1995 }
1996 
1997 void
RxFailure(Ptr<WifiPsdu> psdu)1998 TestUlOfdmaPhyTransmission::RxFailure (Ptr<WifiPsdu> psdu)
1999 {
2000   NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
2001   if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2002     {
2003       m_countRxFailureFromSta1++;
2004     }
2005   else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2006     {
2007       m_countRxFailureFromSta2++;
2008     }
2009 }
2010 
2011 void
CheckRxFromSta1(uint32_t expectedSuccess,uint32_t expectedFailures,uint32_t expectedBytes)2012 TestUlOfdmaPhyTransmission::CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2013 {
2014   NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta1, expectedSuccess, "The number of successfully received packets from STA 1 is not correct!");
2015   NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta1, expectedFailures, "The number of unsuccessfully received packets from STA 1 is not correct!");
2016   NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta1, expectedBytes, "The number of bytes received from STA 1 is not correct!");
2017 }
2018 
2019 void
CheckRxFromSta2(uint32_t expectedSuccess,uint32_t expectedFailures,uint32_t expectedBytes)2020 TestUlOfdmaPhyTransmission::CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2021 {
2022   NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta2, expectedSuccess, "The number of successfully received packets from STA 2 is not correct!");
2023   NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta2, expectedFailures, "The number of unsuccessfully received packets from STA 2 is not correct!");
2024   NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta2, expectedBytes, "The number of bytes received from STA 2 is not correct!");
2025 }
2026 
2027 void
CheckNonOfdmaRxPower(Ptr<OfdmaSpectrumWifiPhy> phy,WifiSpectrumBand band,double expectedRxPower)2028 TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower)
2029 {
2030   Ptr<Event> event = phy->GetCurrentEvent ();
2031   NS_ASSERT (event);
2032   double rxPower = event->GetRxPowerW (band);
2033   NS_LOG_FUNCTION (this << band.first << band.second << expectedRxPower << rxPower);
2034   //Since there is out of band emission due to spectrum mask, the tolerance cannot be very low
2035   NS_TEST_ASSERT_MSG_EQ_TOL (rxPower, expectedRxPower, 5e-3, "RX power " << rxPower << " over (" << band.first << ", " << band.second << ") does not match expected power " << expectedRxPower << " at " << Simulator::Now ());
2036 }
2037 
2038 void
CheckOfdmaRxPower(Ptr<OfdmaSpectrumWifiPhy> phy,WifiSpectrumBand band,double expectedRxPower)2039 TestUlOfdmaPhyTransmission::CheckOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower)
2040 {
2041   /**
2042    * The current event cannot be used since it points to the preamble part of the HE TB PPDU.
2043    * We will have to check if the expected power is indeed the max power returning a positive
2044    * duration when calling GetEnergyDuration.
2045    */
2046   NS_LOG_FUNCTION (this << band.first << band.second << expectedRxPower);
2047   double step = 5e-3;
2048   if (expectedRxPower > 0.0)
2049     {
2050       NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower - step, band).IsStrictlyPositive (), true,
2051                              "At least " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2052       NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower + step, band).IsStrictlyPositive (), false,
2053                              "At most " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2054     }
2055   else
2056     {
2057       NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower + step, band).IsStrictlyPositive (), false,
2058                              "At most " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2059     }
2060 }
2061 
2062 void
VerifyEventsCleared(void)2063 TestUlOfdmaPhyTransmission::VerifyEventsCleared (void)
2064 {
2065   NS_TEST_ASSERT_MSG_EQ (m_phyAp->GetCurrentEvent (), 0, "m_currentEvent for AP was not cleared");
2066   NS_TEST_ASSERT_MSG_EQ (m_phySta1->GetCurrentEvent (), 0, "m_currentEvent for STA 1 was not cleared");
2067   NS_TEST_ASSERT_MSG_EQ (m_phySta2->GetCurrentEvent (), 0, "m_currentEvent for STA 2 was not cleared");
2068 }
2069 
2070 void
CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)2071 TestUlOfdmaPhyTransmission::CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
2072 {
2073   //This is needed to make sure PHY state will be checked as the last event if a state change occurred at the exact same time as the check
2074   Simulator::ScheduleNow (&TestUlOfdmaPhyTransmission::DoCheckPhyState, this, phy, expectedState);
2075 }
2076 
2077 void
DoCheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)2078 TestUlOfdmaPhyTransmission::DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
2079 {
2080   WifiPhyState currentState;
2081   PointerValue ptr;
2082   phy->GetAttribute ("State", ptr);
2083   Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
2084   currentState = state->GetState ();
2085   NS_LOG_FUNCTION (this << currentState);
2086   NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
2087 }
2088 
2089 void
Reset(void)2090 TestUlOfdmaPhyTransmission::Reset (void)
2091 {
2092   m_countRxSuccessFromSta1 = 0;
2093   m_countRxSuccessFromSta2 = 0;
2094   m_countRxFailureFromSta1 = 0;
2095   m_countRxFailureFromSta2 = 0;
2096   m_countRxBytesFromSta1 = 0;
2097   m_countRxBytesFromSta2 = 0;
2098   m_phySta1->SetPpduUid (0);
2099   m_phySta1->SetTriggerFrameUid (0);
2100   m_phySta2->SetTriggerFrameUid (0);
2101   SetBssColor (m_phyAp, 0);
2102 }
2103 
2104 void
SetBssColor(Ptr<WifiPhy> phy,uint8_t bssColor)2105 TestUlOfdmaPhyTransmission::SetBssColor (Ptr<WifiPhy> phy, uint8_t bssColor)
2106 {
2107   Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (phy->GetDevice ());
2108   Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
2109   heConfiguration->SetAttribute ("BssColor", UintegerValue (bssColor));
2110 }
2111 
2112 void
SetPsdLimit(Ptr<WifiPhy> phy,double psdLimit)2113 TestUlOfdmaPhyTransmission::SetPsdLimit (Ptr<WifiPhy> phy, double psdLimit)
2114 {
2115   NS_LOG_FUNCTION (this << phy << psdLimit);
2116   phy->SetAttribute ("PowerDensityLimit", DoubleValue (psdLimit));
2117 }
2118 
2119 void
DoSetup(void)2120 TestUlOfdmaPhyTransmission::DoSetup (void)
2121 {
2122   Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
2123   Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
2124   lossModel->SetFrequency (m_frequency);
2125   spectrumChannel->AddPropagationLossModel (lossModel);
2126   Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
2127   spectrumChannel->SetPropagationDelayModel (delayModel);
2128 
2129   Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
2130   preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-8)); //to ensure that transmission in neighboring channel is ignored (16 dBm baseline)
2131   preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (-100)); //no limit on SNR
2132 
2133   Ptr<Node> apNode = CreateObject<Node> ();
2134   Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
2135   Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac> ();
2136   apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
2137   apDev->SetMac (apMac);
2138   m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
2139   m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
2140   m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
2141   Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration> ();
2142   apDev->SetHeConfiguration (heConfiguration);
2143   Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
2144   m_phyAp->SetErrorRateModel (error);
2145   m_phyAp->SetDevice (apDev);
2146   m_phyAp->SetChannel (spectrumChannel);
2147   m_phyAp->SetReceiveOkCallback (MakeCallback (&TestUlOfdmaPhyTransmission::RxSuccess, this));
2148   m_phyAp->SetReceiveErrorCallback (MakeCallback (&TestUlOfdmaPhyTransmission::RxFailure, this));
2149   m_phyAp->SetPreambleDetectionModel (preambleDetectionModel);
2150   Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
2151   m_phyAp->SetMobility (apMobility);
2152   apDev->SetPhy (m_phyAp);
2153   apNode->AggregateObject (apMobility);
2154   apNode->AddDevice (apDev);
2155 
2156   Ptr<Node> sta1Node = CreateObject<Node> ();
2157   Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
2158   m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
2159   m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
2160   m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
2161   m_phySta1->SetErrorRateModel (error);
2162   m_phySta1->SetDevice (sta1Dev);
2163   m_phySta1->SetChannel (spectrumChannel);
2164   m_phySta1->SetPreambleDetectionModel (preambleDetectionModel);
2165   Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
2166   m_phySta1->SetMobility (sta1Mobility);
2167   sta1Dev->SetPhy (m_phySta1);
2168   sta1Node->AggregateObject (sta1Mobility);
2169   sta1Node->AddDevice (sta1Dev);
2170 
2171   Ptr<Node> sta2Node = CreateObject<Node> ();
2172   Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
2173   m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
2174   m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
2175   m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
2176   m_phySta2->SetErrorRateModel (error);
2177   m_phySta2->SetDevice (sta2Dev);
2178   m_phySta2->SetChannel (spectrumChannel);
2179   m_phySta2->SetPreambleDetectionModel (preambleDetectionModel);
2180   Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
2181   m_phySta2->SetMobility (sta2Mobility);
2182   sta2Dev->SetPhy (m_phySta2);
2183   sta2Node->AggregateObject (sta2Mobility);
2184   sta2Node->AddDevice (sta2Dev);
2185 
2186   Ptr<Node> sta3Node = CreateObject<Node> ();
2187   Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice> ();
2188   m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy> (3);
2189   m_phySta3->CreateWifiSpectrumPhyInterface (sta3Dev);
2190   m_phySta3->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
2191   m_phySta3->SetErrorRateModel (error);
2192   m_phySta3->SetDevice (sta3Dev);
2193   m_phySta3->SetChannel (spectrumChannel);
2194   m_phySta3->SetPreambleDetectionModel (preambleDetectionModel);
2195   Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel> ();
2196   m_phySta3->SetMobility (sta3Mobility);
2197   sta3Dev->SetPhy (m_phySta3);
2198   sta3Node->AggregateObject (sta3Mobility);
2199   sta3Node->AddDevice (sta3Dev);
2200 
2201   Ptr<Node> interfererNode = CreateObject<Node> ();
2202   Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
2203   m_phyInterferer = CreateObject<WaveformGenerator> ();
2204   m_phyInterferer->SetDevice (interfererDev);
2205   m_phyInterferer->SetChannel (spectrumChannel);
2206   m_phyInterferer->SetDutyCycle (1);
2207   interfererNode->AddDevice (interfererDev);
2208 
2209   //Configure power attributes of all wifi devices
2210   std::list<Ptr<WifiPhy>> phys {m_phyAp, m_phySta1, m_phySta2, m_phySta3};
2211   for (auto & phy : phys)
2212     {
2213       phy->SetAttribute ("TxGain", DoubleValue (1.0));
2214       phy->SetAttribute ("TxPowerStart", DoubleValue (16.0));
2215       phy->SetAttribute ("TxPowerEnd", DoubleValue (16.0));
2216       phy->SetAttribute ("PowerDensityLimit", DoubleValue (100.0)); //no impact by default
2217       phy->SetAttribute ("RxGain", DoubleValue (2.0));
2218     }
2219 }
2220 
2221 void
DoTeardown(void)2222 TestUlOfdmaPhyTransmission::DoTeardown (void)
2223 {
2224   m_phyAp->Dispose ();
2225   m_phyAp = 0;
2226   m_phySta1->Dispose ();
2227   m_phySta1 = 0;
2228   m_phySta2->Dispose ();
2229   m_phySta2 = 0;
2230   m_phySta3->Dispose ();
2231   m_phySta3 = 0;
2232   m_phyInterferer->Dispose ();
2233   m_phyInterferer = 0;
2234 }
2235 
2236 void
LogScenario(std::string log) const2237 TestUlOfdmaPhyTransmission::LogScenario (std::string log) const
2238 {
2239   NS_LOG_INFO (log);
2240 }
2241 
2242 void
ScheduleTest(Time delay,bool solicited,WifiPhyState expectedStateAtEnd,uint32_t expectedSuccessFromSta1,uint32_t expectedFailuresFromSta1,uint32_t expectedBytesFromSta1,uint32_t expectedSuccessFromSta2,uint32_t expectedFailuresFromSta2,uint32_t expectedBytesFromSta2,bool scheduleTxSta1,WifiPhyState expectedStateBeforeEnd)2243 TestUlOfdmaPhyTransmission::ScheduleTest (Time delay, bool solicited, WifiPhyState expectedStateAtEnd,
2244                                           uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1,
2245                                           uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2,
2246                                           bool scheduleTxSta1, WifiPhyState expectedStateBeforeEnd)
2247 {
2248   //AP send SU packet with UID = 0 (2) to mimic transmission of solicited (unsolicited) HE TB PPDUs
2249   Simulator::Schedule (delay - MilliSeconds (10), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 0, 50, solicited ? 0 : 2, 0);
2250   //STA1 and STA2 send MU UL PPDUs addressed to AP
2251   if (scheduleTxSta1)
2252     {
2253       Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 1, 1, 1000, 0, 0);
2254     }
2255   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 2, 2, 1001, 0, 0);
2256 
2257   //Verify it takes m_expectedPpduDuration to transmit the PPDUs
2258   Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateBeforeEnd);
2259   Simulator::Schedule (delay + m_expectedPpduDuration, &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateAtEnd);
2260   //TODO: add checks on TX stop for STAs
2261 
2262   delay += MilliSeconds (100);
2263   //Check reception state from STA 1
2264   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::CheckRxFromSta1, this,
2265                        expectedSuccessFromSta1, expectedFailuresFromSta1, expectedBytesFromSta1);
2266   //Check reception state from STA 2
2267   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::CheckRxFromSta2, this,
2268                        expectedSuccessFromSta2, expectedFailuresFromSta2, expectedBytesFromSta2);
2269   //Verify events data have been cleared
2270   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::VerifyEventsCleared, this);
2271 
2272   delay += MilliSeconds (100);
2273   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::Reset, this);
2274 }
2275 
2276 void
SchedulePowerMeasurementChecks(Time delay,double rxPowerNonOfdmaRu1,double rxPowerNonOfdmaRu2,double rxPowerOfdmaRu1,double rxPowerOfdmaRu2)2277 TestUlOfdmaPhyTransmission::SchedulePowerMeasurementChecks (Time delay, double rxPowerNonOfdmaRu1, double rxPowerNonOfdmaRu2,
2278                                                             double rxPowerOfdmaRu1, double rxPowerOfdmaRu2)
2279 {
2280   Time detectionDuration = WifiPhy::GetPreambleDetectionDuration ();
2281   WifiTxVector txVectorSta1 = GetTxVectorForHeTbPpdu (1, 1, 0);
2282   WifiTxVector txVectorSta2 = GetTxVectorForHeTbPpdu (2, 2, 0);
2283   Ptr<const HePhy> hePhy = m_phyAp->GetHePhy ();
2284   Time nonOfdmaDuration = hePhy->CalculateNonOfdmaDurationForHeTb (txVectorSta2);
2285   NS_ASSERT (nonOfdmaDuration == hePhy->CalculateNonOfdmaDurationForHeTb (txVectorSta1));
2286 
2287   std::vector<double> rxPowerNonOfdma { rxPowerNonOfdmaRu1, rxPowerNonOfdmaRu2 };
2288   std::vector<WifiSpectrumBand> nonOfdmaBand { hePhy->GetNonOfdmaBand (txVectorSta1, 1), hePhy->GetNonOfdmaBand (txVectorSta2, 2) };
2289   std::vector<double> rxPowerOfdma { rxPowerOfdmaRu1, rxPowerOfdmaRu2 };
2290   std::vector<WifiSpectrumBand> ofdmaBand { hePhy->GetRuBandForRx (txVectorSta1, 1), hePhy->GetRuBandForRx (txVectorSta2, 2) };
2291 
2292   for (uint8_t i = 0; i < 2; ++i)
2293     {
2294       /**
2295        * Perform checks at AP
2296        */
2297       //Check received power on non-OFDMA portion
2298       Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2299                            &TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower, this, m_phyAp,
2300                            nonOfdmaBand[i], rxPowerNonOfdma[i]);
2301       Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2302                            &TestUlOfdmaPhyTransmission::CheckNonOfdmaRxPower, this, m_phyAp,
2303                            nonOfdmaBand[i], rxPowerNonOfdma[i]);
2304       //Check received power on OFDMA portion
2305       Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2306                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phyAp,
2307                            ofdmaBand[i], rxPowerOfdma[i]);
2308       Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2309                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phyAp,
2310                            ofdmaBand[i], rxPowerOfdma[i]);
2311 
2312       /**
2313        * Perform checks for non-transmitting STA (STA 3).
2314        * Cannot use CheckNonOfdmaRxPower method since current event may be reset if
2315        * preamble not detected (e.g. not on primary).
2316        */
2317       //Check received power on non-OFDMA portion
2318       Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2319                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta3,
2320                            nonOfdmaBand[i], rxPowerNonOfdma[i]);
2321       Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2322                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta3,
2323                            nonOfdmaBand[i], rxPowerNonOfdma[i]);
2324       //Check received power on OFDMA portion
2325       Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2326                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta3,
2327                            ofdmaBand[i], rxPowerOfdma[i]);
2328       Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2329                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta3,
2330                            ofdmaBand[i], rxPowerOfdma[i]);
2331     }
2332 
2333   if (rxPowerOfdmaRu1 != 0.0)
2334     {
2335       /**
2336        * Perform checks for transmitting STA (STA 2) to ensure it has correctly logged
2337        * power received from other transmitting STA (STA 1).
2338        * Cannot use CheckNonOfdmaRxPower method since current event not set.
2339        */
2340       double rxPowerNonOfdmaSta1Only = (m_channelWidth >= 40) ? rxPowerNonOfdma[0] : rxPowerNonOfdma[0] / 2; //both STAs transmit over the same 20 MHz channel
2341       //Check received power on non-OFDMA portion
2342       Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2343                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta2,
2344                            nonOfdmaBand[0], rxPowerNonOfdmaSta1Only);
2345       Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2346                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta2,
2347                            nonOfdmaBand[0], rxPowerNonOfdmaSta1Only);
2348       //Check received power on OFDMA portion
2349       Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2350                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta2,
2351                            ofdmaBand[0], rxPowerOfdma[0]);
2352       Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2353                            &TestUlOfdmaPhyTransmission::CheckOfdmaRxPower, this, m_phySta2,
2354                            ofdmaBand[0], rxPowerOfdma[0]);
2355     }
2356 }
2357 
2358 void
RunOne(void)2359 TestUlOfdmaPhyTransmission::RunOne (void)
2360 {
2361   RngSeedManager::SetSeed (1);
2362   RngSeedManager::SetRun (1);
2363   int64_t streamNumber = 0;
2364   m_phyAp->AssignStreams (streamNumber);
2365   m_phySta1->AssignStreams (streamNumber);
2366   m_phySta2->AssignStreams (streamNumber);
2367   m_phySta3->AssignStreams (streamNumber);
2368 
2369   m_phyAp->SetFrequency (m_frequency);
2370   m_phyAp->SetChannelWidth (m_channelWidth);
2371 
2372   m_phySta1->SetFrequency (m_frequency);
2373   m_phySta1->SetChannelWidth (m_channelWidth);
2374 
2375   m_phySta2->SetFrequency (m_frequency);
2376   m_phySta2->SetChannelWidth (m_channelWidth);
2377 
2378   m_phySta3->SetFrequency (m_frequency);
2379   m_phySta3->SetChannelWidth (m_channelWidth);
2380 
2381   Time delay = Seconds (0.0);
2382   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::Reset, this);
2383   delay += Seconds (1.0);
2384 
2385   /**
2386    * In all the following tests, 2 HE TB PPDUs of the same UL MU transmission
2387    * are sent on RU 1 for STA 1 and RU 2 for STA 2.
2388    * The difference between solicited and unsolicited lies in that their PPDU
2389    * ID correspond to the one of the immediately preceding HE SU PPDU (thus
2390    * mimicing trigger frame reception).
2391    */
2392 
2393   //---------------------------------------------------------------------------
2394   //Verify that both solicited HE TB PPDUs have been corrected received
2395   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2396                        "Reception of solicited HE TB PPDUs");
2397   ScheduleTest (delay, true,
2398                 WifiPhyState::IDLE,
2399                 1, 0, 1000,  //One PSDU of 1000 bytes should have been successfully received from STA 1
2400                 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2401   delay += Seconds (1.0);
2402 
2403   //---------------------------------------------------------------------------
2404   //Verify that both unsolicited HE TB PPDUs have been corrected received
2405   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2406                        "Reception of unsolicited HE TB PPDUs");
2407   ScheduleTest (delay, false,
2408                 WifiPhyState::IDLE,
2409                 1, 0, 1000,  //One PSDU of 1000 bytes should have been successfully received from STA 1
2410                 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2411   delay += Seconds (1.0);
2412 
2413   //---------------------------------------------------------------------------
2414   //Generate an interference on RU 1 and verify that only STA 1's solicited HE TB PPDU has been impacted
2415   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2416                        "Reception of solicited HE TB PPDUs with interference on RU 1 during PSDU reception");
2417   //A strong non-wifi interference is generated on RU 1 during PSDU reception
2418   BandInfo bandInfo;
2419   bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
2420   bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
2421   bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
2422   Bands bands;
2423   bands.push_back (bandInfo);
2424 
2425   Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
2426   Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
2427   double interferencePower = 0.1; //watts
2428   *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
2429 
2430   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
2431   ScheduleTest (delay, true,
2432                 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2433                 0, 1, 0,     //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2434                 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2435   delay += Seconds (1.0);
2436 
2437   //---------------------------------------------------------------------------
2438   //Generate an interference on RU 1 and verify that only STA 1's unsolicited HE TB PPDU has been impacted
2439   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2440                        "Reception of unsolicited HE TB PPDUs with interference on RU 1 during PSDU reception");
2441   //A strong non-wifi interference is generated on RU 1 during PSDU reception
2442   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
2443   ScheduleTest (delay, false,
2444                 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference (primary channel)
2445                 0, 1, 0,     //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2446                 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2447   delay += Seconds (1.0);
2448 
2449   //---------------------------------------------------------------------------
2450   //Generate an interference on RU 2 and verify that only STA 2's solicited HE TB PPDU has been impacted
2451   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2452                        "Reception of solicited HE TB PPDUs with interference on RU 2 during PSDU reception");
2453   //A strong non-wifi interference is generated on RU 2 during PSDU reception
2454   bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
2455   bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
2456   bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
2457   bands.clear ();
2458   bands.push_back (bandInfo);
2459 
2460   Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel> (bands);
2461   Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue> (SpectrumInterferenceRu2);
2462   *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
2463 
2464   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
2465   ScheduleTest (delay, true,
2466                 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY since measurement channel encompasses total channel width
2467                 1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2468                 0, 1, 0);   //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2469   delay += Seconds (1.0);
2470 
2471   //---------------------------------------------------------------------------
2472   //Generate an interference on RU 2 and verify that only STA 2's unsolicited HE TB PPDU has been impacted
2473   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2474                        "Reception of unsolicited HE TB PPDUs with interference on RU 2 during PSDU reception");
2475   //A strong non-wifi interference is generated on RU 2 during PSDU reception
2476   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
2477   ScheduleTest (delay, false,
2478                 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE if interference on primary channel
2479                 1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2480                 0, 1, 0);   //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2481   delay += Seconds (1.0);
2482 
2483   //---------------------------------------------------------------------------
2484   //Generate an interference on the full band and verify that both solicited HE TB PPDUs have been impacted
2485   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2486                        "Reception of solicited HE TB PPDUs with interference on the full band during PSDU reception");
2487   //A strong non-wifi interference is generated on the full band during PSDU reception
2488   bandInfo.fc = m_frequency * 1e6;
2489   bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
2490   bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
2491   bands.clear ();
2492   bands.push_back (bandInfo);
2493 
2494   Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel> (bands);
2495   Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue> (SpectrumInterferenceAll);
2496   *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
2497 
2498   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
2499   ScheduleTest (delay, true,
2500                 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2501                 0, 1, 0,  //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2502                 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2503   delay += Seconds (1.0);
2504 
2505   //---------------------------------------------------------------------------
2506   //Generate an interference on the full band and verify that both unsolicited HE TB PPDUs have been impacted
2507   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2508                        "Reception of unsolicited HE TB PPDUs with interference on the full band during PSDU reception");
2509   //A strong non-wifi interference is generated on the full band during PSDU reception
2510   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
2511   ScheduleTest (delay, false,
2512                 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2513                 0, 1, 0,  //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2514                 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2515   delay += Seconds (1.0);
2516 
2517   //---------------------------------------------------------------------------
2518   //Send another HE TB PPDU (of another UL MU transmission) on RU 1 and verify that both solicited HE TB PPDUs have been impacted if they are on the same
2519   // 20 MHz channel. Only STA 1's solicited HE TB PPDU is impacted otherwise.
2520   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2521                        "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU 1 during PSDU reception");
2522   //Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
2523   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 0);
2524   //Expected figures from STA 2
2525   uint32_t succ, fail, bytes;
2526   if (m_channelWidth > 20)
2527     {
2528       //One PSDU of 1001 bytes should have been successfully received from STA 2 (since interference from STA 3 on distinct 20 MHz channel)
2529       succ = 1;
2530       fail = 0;
2531       bytes = 1001;
2532     }
2533   else
2534     {
2535       //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2536       succ = 0;
2537       fail = 1;
2538       bytes = 0;
2539     }
2540   ScheduleTest (delay, true,
2541                 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on measurement channel width
2542                 0, 1, 0,  //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2543                 succ, fail, bytes);
2544   delay += Seconds (1.0);
2545 
2546   //---------------------------------------------------------------------------
2547   //Send another HE TB PPDU (of another UL MU transmission) on RU 1 and verify that both unsolicited HE TB PPDUs have been impacted if they are on the same
2548   // 20 MHz channel. Only STA 1's unsolicited HE TB PPDU is impacted otherwise.
2549   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2550                        "Reception of unsolicited HE TB PPDUs with another HE TB PPDU arriving on RU 1 during PSDU reception");
2551   //Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
2552   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 0);
2553   ScheduleTest (delay, false,
2554                 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on primary channel width
2555                 0, 1, 0,  //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2556                 succ, fail, bytes); //same as solicited case
2557   delay += Seconds (1.0);
2558 
2559   //---------------------------------------------------------------------------
2560   //Send another HE TB PPDU (of another UL MU transmission) on RU 2 and verify that both solicited HE TB PPDUs have been impacted if they are on the same
2561   // 20 MHz channel. Only STA 2's solicited HE TB PPDU is impacted otherwise.
2562   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2563                        "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU 2 during PSDU reception");
2564   //Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
2565   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 2, 1002, 1, 0);
2566   //Expected figures from STA 1
2567   if (m_channelWidth > 20)
2568     {
2569       //One PSDU of 1000 bytes should have been successfully received from STA 1 (since interference from STA 3 on distinct 20 MHz channel)
2570       succ = 1;
2571       fail = 0;
2572       bytes = 1000;
2573     }
2574   else
2575     {
2576       //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2577       succ = 0;
2578       fail = 1;
2579       bytes = 0;
2580     }
2581   ScheduleTest (delay, true,
2582                 WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on measurement channel width
2583                 succ, fail, bytes,
2584                 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2585   delay += Seconds (1.0);
2586 
2587   //---------------------------------------------------------------------------
2588   //Send another HE TB PPDU (of another UL MU transmission) on RU 2 and verify that both unsolicited HE TB PPDUs have been impacted if they are on the same
2589   // 20 MHz channel. Only STA 2's unsolicited HE TB PPDU is impacted otherwise.
2590   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2591                        "Reception of unsolicited HE TB PPDUs with another HE TB PPDU arriving on RU2 during payload reception");
2592   //Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
2593   Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 2, 1002, 1, 0);
2594   ScheduleTest (delay, false,
2595                 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE if interference on primary channel
2596                 succ, fail, bytes, //same as solicited case
2597                 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2598   delay += Seconds (1.0);
2599 
2600   //---------------------------------------------------------------------------
2601   //Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been impacted
2602   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2603                        "Reception of solicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
2604   //One HE SU arrives at AP during the 400ns window
2605   Simulator::Schedule (delay + NanoSeconds (300), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 3, 1002, 1, 0);
2606   ScheduleTest (delay, true,
2607                 WifiPhyState::IDLE,
2608                 0, 1, 0,  //Reception of the PSDU from STA 1 should have failed (since interference from STA 3)
2609                 0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3)
2610   delay += Seconds (1.0);
2611 
2612   //---------------------------------------------------------------------------
2613   //Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been impacted
2614   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2615                        "Reception of unsolicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
2616   //One HE SU arrives at AP during the 400ns window
2617   Simulator::Schedule (delay + NanoSeconds (300), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 3, 1002, 1, 0);
2618   ScheduleTest (delay, false,
2619                 WifiPhyState::IDLE,
2620                 0, 1, 0,  //Reception of the PSDU from STA 1 should have failed failed (since interference from STA 3)
2621                 0, 1, 0); //Reception of the PSDU from STA 2 should have failed failed (since interference from STA 3)
2622   delay += Seconds (1.0);
2623 
2624   //---------------------------------------------------------------------------
2625   //Only send a solicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly received
2626   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2627                        "Reception of solicited HE TB PPDU only on RU 2");
2628   //Check that STA3 will correctly set its state to RX if in measurement channel or IDLE otherwise
2629   Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3,
2630                        (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::RX); //PHY should move to RX instead of IDLE if HE TB PPDU on primary channel;
2631   ScheduleTest (delay, true,
2632                 WifiPhyState::IDLE,
2633                 0, 0, 0,    //No transmission scheduled for STA 1
2634                 1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2635                 false, WifiPhyState::RX); //Measurement channel is total channel width
2636   delay += Seconds (1.0);
2637 
2638   //---------------------------------------------------------------------------
2639   //Only send an unsolicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly received if it's in the
2640   // correct measurement channel
2641   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2642                        "Reception of unsolicited HE TB PPDUs only on RU 2");
2643   //Check that STA3 will correctly set its state to RX if in measurement channel or IDLE otherwise
2644   Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3,
2645                        (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::RX); //PHY should move to RX instead of IDLE if HE TB PPDU on primary channel;
2646   //Expected figures from STA 2
2647   WifiPhyState state;
2648   if (m_channelWidth == 20)
2649     {
2650       //One PSDU of 1001 bytes should have been successfully received from STA 2 (since measurement channel is primary channel)
2651       succ = 1;
2652       fail = 0;
2653       bytes = 1001;
2654       state = WifiPhyState::RX;
2655     }
2656   else
2657     {
2658       //No PSDU should have been received from STA 2 (since measurement channel is primary channel)
2659       succ = 0;
2660       fail = 0;
2661       bytes = 0;
2662       state = WifiPhyState::IDLE;
2663     }
2664   ScheduleTest (delay, false,
2665                 WifiPhyState::IDLE,
2666                 0, 0, 0, //No transmission scheduled for STA 1
2667                 succ, fail, bytes,
2668                 false, state);
2669   delay += Seconds (1.0);
2670 
2671   //---------------------------------------------------------------------------
2672   //Measure the power of a solicited HE TB PPDU from STA 2 on RU 2
2673   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2674                        "Measure power for reception of HE TB PPDU only on RU 2");
2675   double rxPower = DbmToW (19); //16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
2676   SchedulePowerMeasurementChecks (delay,
2677                                   (m_channelWidth >= 40) ? 0.0 : rxPower, rxPower, //power detected on RU1 only if same 20 MHz as RU 2
2678                                   0.0, rxPower);
2679   ScheduleTest (delay, true,
2680                 WifiPhyState::IDLE,
2681                 0, 0, 0,    //No transmission scheduled for STA 1
2682                 1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2683                 false, WifiPhyState::RX); //Measurement channel is total channel width
2684   delay += Seconds (1.0);
2685 
2686   //---------------------------------------------------------------------------
2687   //Measure the power of a solicited HE TB PPDU from STA 2 on RU 2 with power spectrum density limitation enforced
2688   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2689                        "Measure power for reception of HE TB PPDU only on RU 2 with PSD limitation");
2690   //Configure PSD limitation at 3 dBm/MHz -> 3+13.0103=16.0103 dBm max for 20 MHz, 3+9.0309=12.0309 dBm max for 106-tone RU, no impact for 40 MHz and above
2691   Simulator::Schedule (delay - NanoSeconds (1), //just before sending HE TB
2692                        &TestUlOfdmaPhyTransmission::SetPsdLimit, this, m_phySta2, 3.0);
2693 
2694   rxPower = (m_channelWidth > 40) ? DbmToW (19) : DbmToW (18.0103); //15.0103+1 dBm at STA 2 and +2 at AP for non-OFDMA transmitted only on one 20 MHz channel
2695   double rxPowerOfdma = rxPower;
2696   if (m_channelWidth <= 40)
2697     {
2698       rxPowerOfdma = (m_channelWidth == 20) ? DbmToW (14.0309) //11.0309+1 dBm at STA and +2 at AP if 106-tone RU
2699                                             : DbmToW (18.0103); //15.0103+1 dBm at STA 2 and +2 at AP if 242-tone RU
2700     }
2701   SchedulePowerMeasurementChecks (delay,
2702                                   (m_channelWidth >= 40) ? 0.0 : rxPower, rxPower, //power detected on RU1 only if same 20 MHz as RU 2
2703                                   0.0, rxPowerOfdma);
2704 
2705   //Reset PSD limitation once HE TB has been sent
2706   Simulator::Schedule (delay + m_expectedPpduDuration,
2707                        &TestUlOfdmaPhyTransmission::SetPsdLimit, this, m_phySta2, 100.0);
2708   ScheduleTest (delay, true,
2709                 WifiPhyState::IDLE,
2710                 0, 0, 0,    //No transmission scheduled for STA 1
2711                 1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2712                 false, WifiPhyState::RX); //Measurement channel is total channel width
2713   delay += Seconds (1.0);
2714 
2715   //---------------------------------------------------------------------------
2716   //Measure the power of 2 solicited HE TB PPDU from both STAs
2717   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2718                        "Measure power for reception of HE TB PPDU on both RUs");
2719   rxPower = DbmToW (19); //16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
2720   double rxPowerNonOfdma = (m_channelWidth >= 40) ? rxPower : rxPower * 2; //both STAs transmit over the same 20 MHz channel
2721   SchedulePowerMeasurementChecks (delay,
2722                                   rxPowerNonOfdma, rxPowerNonOfdma,
2723                                   rxPower, rxPower);
2724   ScheduleTest (delay, true,
2725                 WifiPhyState::IDLE,
2726                 1, 0, 1000,  //One PSDU of 1000 bytes should have been successfully received from STA 1
2727                 1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2728   delay += Seconds (1.0);
2729 
2730   //---------------------------------------------------------------------------
2731   //Verify that an HE SU PPDU from another BSS has been correctly received (no UL MU transmission ongoing)
2732   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2733                        "Reception of an HE SU PPDU from another BSS");
2734   //One HE SU from another BSS (BSS color 2) arrives at AP (BSS color 1)
2735   Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SetBssColor, this, m_phyAp, 1);
2736   Simulator::Schedule (delay + MilliSeconds (100), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 2);
2737 
2738   //Verify events data have been cleared
2739   Simulator::Schedule (delay + MilliSeconds (200), &TestUlOfdmaPhyTransmission::VerifyEventsCleared, this);
2740 
2741   Simulator::Schedule (delay + MilliSeconds (500), &TestUlOfdmaPhyTransmission::Reset, this);
2742   delay += Seconds (1.0);
2743 
2744   Simulator::Run ();
2745 }
2746 
2747 void
DoRun(void)2748 TestUlOfdmaPhyTransmission::DoRun (void)
2749 {
2750   m_frequency = 5180;
2751   m_channelWidth = 20;
2752   m_expectedPpduDuration = NanoSeconds (279200);
2753   NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2754   RunOne ();
2755 
2756   m_frequency = 5190;
2757   m_channelWidth = 40;
2758   m_expectedPpduDuration = NanoSeconds (156800);
2759   NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2760   RunOne ();
2761 
2762   m_frequency = 5210;
2763   m_channelWidth = 80;
2764   m_expectedPpduDuration = NanoSeconds (102400);
2765   NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2766   RunOne ();
2767 
2768   m_frequency = 5250;
2769   m_channelWidth = 160;
2770   m_expectedPpduDuration = NanoSeconds (75200);
2771   NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2772   RunOne ();
2773 
2774   Simulator::Destroy ();
2775 }
2776 
2777 /**
2778  * \ingroup wifi-test
2779  * \ingroup tests
2780  *
2781  * \brief PHY padding exclusion test
2782  */
2783 class TestPhyPaddingExclusion : public TestCase
2784 {
2785 public:
2786   TestPhyPaddingExclusion ();
2787   virtual ~TestPhyPaddingExclusion ();
2788 
2789 private:
2790   void DoSetup (void) override;
2791   void DoTeardown (void) override;
2792   void DoRun (void) override;
2793 
2794   /**
2795    * Send HE TB PPDU function
2796    * \param txStaId the ID of the TX STA
2797    * \param index the RU index used for the transmission
2798    * \param payloadSize the size of the payload in bytes
2799    * \param txDuration the duration of the PPDU
2800    */
2801   void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration);
2802 
2803   /**
2804    * Generate interference function
2805    * \param interferencePsd the PSD of the interference to be generated
2806    * \param duration the duration of the interference
2807    */
2808   void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
2809   /**
2810    * Stop interference function
2811    */
2812   void StopInterference (void);
2813 
2814   /**
2815    * Run one function
2816    */
2817   void RunOne ();
2818 
2819   /**
2820    * Check the received PSDUs from STA1
2821    * \param expectedSuccess the expected number of success
2822    * \param expectedFailures the expected number of failures
2823    * \param expectedBytes the expected number of bytes
2824    */
2825   void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
2826 
2827   /**
2828    * Check the received PSDUs from STA2
2829    * \param expectedSuccess the expected number of success
2830    * \param expectedFailures the expected number of failures
2831    * \param expectedBytes the expected number of bytes
2832    */
2833   void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
2834 
2835   /**
2836    * Verify all events are cleared at end of TX or RX
2837    */
2838   void VerifyEventsCleared (void);
2839 
2840   /**
2841    * Check the PHY state
2842    * \param phy the PHY
2843    * \param expectedState the expected state of the PHY
2844    */
2845   void CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
2846   /// \copydoc CheckPhyState
2847   void DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
2848 
2849   /**
2850    * Reset function
2851    */
2852   void Reset ();
2853 
2854   /**
2855    * Receive success function
2856    * \param psdu the PSDU
2857    * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
2858    * \param txVector the transmit vector
2859    * \param statusPerMpdu reception status per MPDU
2860    */
2861   void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
2862 
2863   /**
2864    * Receive failure function
2865    * \param psdu the PSDU
2866    */
2867   void RxFailure (Ptr<WifiPsdu> psdu);
2868 
2869   Ptr<OfdmaSpectrumWifiPhy> m_phyAp;   ///< PHY of AP
2870   Ptr<OfdmaSpectrumWifiPhy> m_phySta1; ///< PHY of STA 1
2871   Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
2872 
2873   Ptr<WaveformGenerator> m_phyInterferer; ///< PHY of interferer
2874 
2875   uint32_t m_countRxSuccessFromSta1; ///< count RX success from STA 1
2876   uint32_t m_countRxSuccessFromSta2; ///< count RX success from STA 2
2877   uint32_t m_countRxFailureFromSta1; ///< count RX failure from STA 1
2878   uint32_t m_countRxFailureFromSta2; ///< count RX failure from STA 2
2879   uint32_t m_countRxBytesFromSta1;   ///< count RX bytes from STA 1
2880   uint32_t m_countRxBytesFromSta2;   ///< count RX bytes from STA 2
2881 };
2882 
TestPhyPaddingExclusion()2883 TestPhyPaddingExclusion::TestPhyPaddingExclusion ()
2884   : TestCase ("PHY padding exclusion test"),
2885     m_countRxSuccessFromSta1 (0),
2886     m_countRxSuccessFromSta2 (0),
2887     m_countRxFailureFromSta1 (0),
2888     m_countRxFailureFromSta2 (0),
2889     m_countRxBytesFromSta1 (0),
2890     m_countRxBytesFromSta2 (0)
2891 {
2892 }
2893 
2894 void
SendHeTbPpdu(uint16_t txStaId,std::size_t index,std::size_t payloadSize,Time txDuration)2895 TestPhyPaddingExclusion::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration)
2896 {
2897   WifiConstPsduMap psdus;
2898 
2899   WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false, 1);
2900 
2901   HeRu::RuSpec ru (HeRu::RU_106_TONE, index, false);
2902   txVector.SetRu (ru, txStaId);
2903   txVector.SetMode (HePhy::GetHeMcs7 (), txStaId);
2904   txVector.SetNss (1, txStaId);
2905 
2906   Ptr<Packet> pkt = Create<Packet> (payloadSize);
2907   WifiMacHeader hdr;
2908   hdr.SetType (WIFI_MAC_QOSDATA);
2909   hdr.SetQosTid (0);
2910   hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
2911   std::ostringstream addr;
2912   addr << "00:00:00:00:00:0" << txStaId;
2913   hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
2914   hdr.SetSequenceNumber (1);
2915   Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
2916   psdus.insert (std::make_pair (txStaId, psdu));
2917 
2918   Ptr<OfdmaSpectrumWifiPhy> phy;
2919   if (txStaId == 1)
2920     {
2921       phy = m_phySta1;
2922     }
2923   else if (txStaId == 2)
2924     {
2925       phy = m_phySta2;
2926     }
2927 
2928   txVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
2929 
2930   phy->SetPpduUid (0);
2931   phy->Send (psdus, txVector);
2932 }
2933 
2934 void
GenerateInterference(Ptr<SpectrumValue> interferencePsd,Time duration)2935 TestPhyPaddingExclusion::GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration)
2936 {
2937   m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
2938   m_phyInterferer->SetPeriod (duration);
2939   m_phyInterferer->Start ();
2940   Simulator::Schedule (duration, &TestPhyPaddingExclusion::StopInterference, this);
2941 }
2942 
2943 void
StopInterference(void)2944 TestPhyPaddingExclusion::StopInterference (void)
2945 {
2946   m_phyInterferer->Stop();
2947 }
2948 
~TestPhyPaddingExclusion()2949 TestPhyPaddingExclusion::~TestPhyPaddingExclusion ()
2950 {
2951 }
2952 
2953 void
RxSuccess(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)2954 TestPhyPaddingExclusion::RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
2955 {
2956   NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 () << rxSignalInfo << txVector);
2957   if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2958     {
2959       m_countRxSuccessFromSta1++;
2960       m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
2961     }
2962   else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2963     {
2964       m_countRxSuccessFromSta2++;
2965       m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
2966     }
2967 }
2968 
2969 void
RxFailure(Ptr<WifiPsdu> psdu)2970 TestPhyPaddingExclusion::RxFailure (Ptr<WifiPsdu> psdu)
2971 {
2972   NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
2973   if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2974     {
2975       m_countRxFailureFromSta1++;
2976     }
2977   else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2978     {
2979       m_countRxFailureFromSta2++;
2980     }
2981 }
2982 
2983 void
CheckRxFromSta1(uint32_t expectedSuccess,uint32_t expectedFailures,uint32_t expectedBytes)2984 TestPhyPaddingExclusion::CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2985 {
2986   NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta1, expectedSuccess, "The number of successfully received packets from STA 1 is not correct!");
2987   NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta1, expectedFailures, "The number of unsuccessfully received packets from STA 1 is not correct!");
2988   NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta1, expectedBytes, "The number of bytes received from STA 1 is not correct!");
2989 }
2990 
2991 void
CheckRxFromSta2(uint32_t expectedSuccess,uint32_t expectedFailures,uint32_t expectedBytes)2992 TestPhyPaddingExclusion::CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2993 {
2994   NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta2, expectedSuccess, "The number of successfully received packets from STA 2 is not correct!");
2995   NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta2, expectedFailures, "The number of unsuccessfully received packets from STA 2 is not correct!");
2996   NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta2, expectedBytes, "The number of bytes received from STA 2 is not correct!");
2997 }
2998 
2999 void
VerifyEventsCleared(void)3000 TestPhyPaddingExclusion::VerifyEventsCleared (void)
3001 {
3002   NS_TEST_ASSERT_MSG_EQ (m_phyAp->GetCurrentEvent (), 0, "m_currentEvent for AP was not cleared");
3003   NS_TEST_ASSERT_MSG_EQ (m_phySta1->GetCurrentEvent (), 0, "m_currentEvent for STA 1 was not cleared");
3004   NS_TEST_ASSERT_MSG_EQ (m_phySta2->GetCurrentEvent (), 0, "m_currentEvent for STA 2 was not cleared");
3005 }
3006 
3007 void
CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)3008 TestPhyPaddingExclusion::CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
3009 {
3010   //This is needed to make sure PHY state will be checked as the last event if a state change occurred at the exact same time as the check
3011   Simulator::ScheduleNow (&TestPhyPaddingExclusion::DoCheckPhyState, this, phy, expectedState);
3012 }
3013 
3014 void
DoCheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy,WifiPhyState expectedState)3015 TestPhyPaddingExclusion::DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
3016 {
3017   WifiPhyState currentState = phy->GetState ()->GetState ();
3018   NS_LOG_FUNCTION (this << currentState);
3019   NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
3020 }
3021 
3022 void
Reset(void)3023 TestPhyPaddingExclusion::Reset (void)
3024 {
3025   m_countRxSuccessFromSta1 = 0;
3026   m_countRxSuccessFromSta2 = 0;
3027   m_countRxFailureFromSta1 = 0;
3028   m_countRxFailureFromSta2 = 0;
3029   m_countRxBytesFromSta1 = 0;
3030   m_countRxBytesFromSta2 = 0;
3031   m_phySta1->SetPpduUid (0);
3032   m_phySta1->SetTriggerFrameUid (0);
3033   m_phySta2->SetTriggerFrameUid (0);
3034 }
3035 
3036 void
DoSetup(void)3037 TestPhyPaddingExclusion::DoSetup (void)
3038 {
3039   RngSeedManager::SetSeed (1);
3040   RngSeedManager::SetRun (1);
3041   int64_t streamNumber = 0;
3042 
3043   Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
3044   Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
3045   lossModel->SetFrequency (DEFAULT_FREQUENCY * 1e6);
3046   spectrumChannel->AddPropagationLossModel (lossModel);
3047   Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
3048   spectrumChannel->SetPropagationDelayModel (delayModel);
3049 
3050   Ptr<Node> apNode = CreateObject<Node> ();
3051   Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
3052   Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac> ();
3053   apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
3054   apDev->SetMac (apMac);
3055   m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
3056   m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
3057   m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
3058   Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration> ();
3059   apDev->SetHeConfiguration (heConfiguration);
3060   Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
3061   m_phyAp->SetErrorRateModel (error);
3062   m_phyAp->SetDevice (apDev);
3063   m_phyAp->SetChannel (spectrumChannel);
3064   m_phyAp->AssignStreams (streamNumber);
3065   m_phyAp->SetFrequency (DEFAULT_FREQUENCY);
3066   m_phyAp->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
3067   m_phyAp->SetReceiveOkCallback (MakeCallback (&TestPhyPaddingExclusion::RxSuccess, this));
3068   m_phyAp->SetReceiveErrorCallback (MakeCallback (&TestPhyPaddingExclusion::RxFailure, this));
3069   Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
3070   m_phyAp->SetMobility (apMobility);
3071   apDev->SetPhy (m_phyAp);
3072   apNode->AggregateObject (apMobility);
3073   apNode->AddDevice (apDev);
3074 
3075   Ptr<Node> sta1Node = CreateObject<Node> ();
3076   Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
3077   m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
3078   m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
3079   m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
3080   m_phySta1->SetErrorRateModel (error);
3081   m_phySta1->SetDevice (sta1Dev);
3082   m_phySta1->SetChannel (spectrumChannel);
3083   m_phySta1->AssignStreams (streamNumber);
3084   m_phySta1->SetFrequency (DEFAULT_FREQUENCY);
3085   m_phySta1->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
3086   Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
3087   m_phySta1->SetMobility (sta1Mobility);
3088   sta1Dev->SetPhy (m_phySta1);
3089   sta1Node->AggregateObject (sta1Mobility);
3090   sta1Node->AddDevice (sta1Dev);
3091 
3092   Ptr<Node> sta2Node = CreateObject<Node> ();
3093   Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
3094   m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
3095   m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
3096   m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
3097   m_phySta2->SetErrorRateModel (error);
3098   m_phySta2->SetDevice (sta2Dev);
3099   m_phySta2->SetChannel (spectrumChannel);
3100   m_phySta2->AssignStreams (streamNumber);
3101   m_phySta2->SetFrequency (DEFAULT_FREQUENCY);
3102   m_phySta2->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
3103   Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
3104   m_phySta2->SetMobility (sta2Mobility);
3105   sta2Dev->SetPhy (m_phySta2);
3106   sta2Node->AggregateObject (sta2Mobility);
3107   sta2Node->AddDevice (sta2Dev);
3108 
3109   Ptr<Node> interfererNode = CreateObject<Node> ();
3110   Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
3111   m_phyInterferer = CreateObject<WaveformGenerator> ();
3112   m_phyInterferer->SetDevice (interfererDev);
3113   m_phyInterferer->SetChannel (spectrumChannel);
3114   m_phyInterferer->SetDutyCycle (1);
3115   interfererNode->AddDevice (interfererDev);
3116 }
3117 
3118 void
DoTeardown(void)3119 TestPhyPaddingExclusion::DoTeardown (void)
3120 {
3121   m_phyAp->Dispose ();
3122   m_phyAp = 0;
3123   m_phySta1->Dispose ();
3124   m_phySta1 = 0;
3125   m_phySta2->Dispose ();
3126   m_phySta2 = 0;
3127   m_phyInterferer->Dispose ();
3128   m_phyInterferer = 0;
3129 }
3130 
3131 void
DoRun(void)3132 TestPhyPaddingExclusion::DoRun (void)
3133 {
3134   Time expectedPpduDuration = NanoSeconds (279200);
3135   Time ppduWithPaddingDuration = expectedPpduDuration + 10 * NanoSeconds (12800 + 800 /* GI */); //add 10 extra OFDM symbols
3136 
3137   Simulator::Schedule (Seconds (0.0), &TestPhyPaddingExclusion::Reset, this);
3138 
3139   //STA1 and STA2 send MU UL PPDUs addressed to AP:
3140   Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
3141   Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
3142 
3143   //Verify it takes expectedPpduDuration + padding to transmit the PPDUs
3144   Simulator::Schedule (Seconds (1.0) + ppduWithPaddingDuration - NanoSeconds (1), &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::RX);
3145   Simulator::Schedule (Seconds (1.0) + ppduWithPaddingDuration, &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::IDLE);
3146 
3147   //One PSDU of 1000 bytes should have been successfully received from STA 1
3148   Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::CheckRxFromSta1, this, 1, 0, 1000);
3149   //One PSDU of 1001 bytes should have been successfully received from STA 2
3150   Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::CheckRxFromSta2, this, 1, 0, 1001);
3151   //Verify events data have been cleared
3152   Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::VerifyEventsCleared, this);
3153 
3154   Simulator::Schedule (Seconds (1.5), &TestPhyPaddingExclusion::Reset, this);
3155 
3156 
3157   //STA1 and STA2 send MU UL PPDUs addressed to AP:
3158   Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
3159   Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
3160 
3161   //A strong non-wifi interference is generated on RU 1 during padding reception
3162   BandInfo bandInfo;
3163   bandInfo.fc = (DEFAULT_FREQUENCY - (DEFAULT_CHANNEL_WIDTH / 4)) * 1e6;
3164   bandInfo.fl = bandInfo.fc - ((DEFAULT_CHANNEL_WIDTH / 4) * 1e6);
3165   bandInfo.fh = bandInfo.fc + ((DEFAULT_CHANNEL_WIDTH / 4) * 1e6);
3166   Bands bands;
3167   bands.push_back (bandInfo);
3168 
3169   Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
3170   Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
3171   double interferencePower = 0.1; //watts
3172   *interferencePsdRu1 = interferencePower / ((DEFAULT_CHANNEL_WIDTH / 2) * 20e6);
3173 
3174   Simulator::Schedule (Seconds (2.0) + MicroSeconds (50) + expectedPpduDuration, &TestPhyPaddingExclusion::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
3175 
3176   //Verify it takes  expectedPpduDuration + padding to transmit the PPDUs (PHY should move to CCA_BUSY instead of IDLE due to the interference)
3177   Simulator::Schedule (Seconds (2.0) + ppduWithPaddingDuration - NanoSeconds (1), &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::RX);
3178   Simulator::Schedule (Seconds (2.0) + ppduWithPaddingDuration, &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::CCA_BUSY);
3179 
3180   //One PSDU of 1000 bytes should have been successfully received from STA 1 (since interference occupies RU 1 after payload, during PHY padding)
3181   Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::CheckRxFromSta1, this, 1, 0, 1000);
3182   //One PSDU of 1001 bytes should have been successfully received from STA 2
3183   Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::CheckRxFromSta2, this, 1, 0, 1001);
3184   //Verify events data have been cleared
3185   Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::VerifyEventsCleared, this);
3186 
3187   Simulator::Schedule (Seconds (2.5), &TestPhyPaddingExclusion::Reset, this);
3188 
3189   Simulator::Run ();
3190 
3191   Simulator::Destroy ();
3192 }
3193 
3194 /**
3195  * \ingroup wifi-test
3196  * \ingroup tests
3197  *
3198  * \brief UL-OFDMA power control test
3199  */
3200 class TestUlOfdmaPowerControl : public TestCase
3201 {
3202 public:
3203   TestUlOfdmaPowerControl ();
3204   virtual ~TestUlOfdmaPowerControl ();
3205 
3206 private:
3207   void DoSetup (void) override;
3208   void DoTeardown (void) override;
3209   void DoRun (void) override;
3210 
3211   /**
3212    * Send a MU BAR through the AP to the STAs listed in the provided vector.
3213    *
3214    * \param staIds the vector of STA-IDs of STAs to address the MU-BAR to
3215    */
3216   void SendMuBar (std::vector <uint16_t> staIds);
3217 
3218   /**
3219    * Send a QoS Data packet to the destination station in order
3220    * to set up a block Ack session (so that the MU-BAR may have a reply).
3221    *
3222    * \param destination the address of the destination station
3223    */
3224   void SetupBa (Address destination);
3225 
3226   /**
3227    * Run one simulation with an optional BA session set up phase.
3228    *
3229    * \param setupBa true if BA session should be set up (i.e. upon first run),
3230    *                false otherwise
3231    */
3232   void RunOne (bool setupBa);
3233 
3234   /**
3235    * Replace the AP's callback on its PHY's ReceiveOkCallback
3236    * by the ReceiveOkCallbackAtAp method.
3237    */
3238   void ReplaceReceiveOkCallbackOfAp (void);
3239 
3240   /**
3241    * Receive OK callback function at AP.
3242    * This method will be plugged into the AP PHY's ReceiveOkCallback once the
3243    * block Ack session has been set up. This is done in the Reset function.
3244    * \param psdu the PSDU
3245    * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
3246    * \param txVector the TXVECTOR used for the packet
3247    * \param statusPerMpdu reception status per MPDU
3248    */
3249   void ReceiveOkCallbackAtAp (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
3250                               WifiTxVector txVector, std::vector<bool> statusPerMpdu);
3251 
3252   uint8_t m_bssColor;           ///< BSS color
3253 
3254   Ptr<WifiNetDevice> m_apDev;   ///< network device of AP
3255   Ptr<WifiNetDevice> m_sta1Dev; ///< network device of STA 1
3256   Ptr<WifiNetDevice> m_sta2Dev; ///< network device of STA 2
3257 
3258   Ptr<SpectrumWifiPhy> m_phyAp; ///< PHY of AP
3259 
3260   double m_txPowerAp;           ///< transmit power (in dBm) of AP
3261   double m_txPowerStart;        ///< minimum transmission power (in dBm) for STAs
3262   double m_txPowerEnd;          ///< maximum transmission power (in dBm) for STAs
3263   uint8_t m_txPowerLevels;      ///< number of transmission power levels for STAs
3264 
3265   double m_requestedRssiSta1;   ///< requested RSSI (in dBm) from STA 1 at AP for HE TB PPDUs
3266   double m_requestedRssiSta2;   ///< requested RSSI (in dBm) from STA 2 at AP for HE TB PPDUs
3267 
3268   double m_rssiSta1;            ///< expected RSSI (in dBm) from STA 1 at AP for HE TB PPDUs
3269   double m_rssiSta2;            ///< expected RSSI (in dBm) from STA 2 at AP for HE TB PPDUs
3270 
3271   double m_tol;                 ///< tolerance (in dB) between received and expected RSSIs
3272 };
3273 
TestUlOfdmaPowerControl()3274 TestUlOfdmaPowerControl::TestUlOfdmaPowerControl ()
3275   : TestCase ("UL-OFDMA power control test"),
3276     m_bssColor (1),
3277     m_txPowerAp (0),
3278     m_txPowerStart (0),
3279     m_txPowerEnd (0),
3280     m_txPowerLevels (0),
3281     m_requestedRssiSta1 (0),
3282     m_requestedRssiSta2 (0),
3283     m_rssiSta1 (0),
3284     m_rssiSta2 (0),
3285     m_tol (0.1)
3286 {
3287 }
3288 
~TestUlOfdmaPowerControl()3289 TestUlOfdmaPowerControl::~TestUlOfdmaPowerControl ()
3290 {
3291   m_phyAp = 0;
3292   m_apDev = 0;
3293   m_sta1Dev = 0;
3294   m_sta2Dev = 0;
3295 }
3296 
3297 void
SetupBa(Address destination)3298 TestUlOfdmaPowerControl::SetupBa (Address destination)
3299 {
3300   //Only one packet is sufficient to set up BA since AP and STAs are HE capable
3301   Ptr<Packet> pkt = Create<Packet> (100);  // 100 dummy bytes of data
3302   m_apDev->Send (pkt, destination, 0);
3303 }
3304 
3305 void
SendMuBar(std::vector<uint16_t> staIds)3306 TestUlOfdmaPowerControl::SendMuBar (std::vector <uint16_t> staIds)
3307 {
3308   NS_ASSERT (!staIds.empty () && staIds.size () <= 2);
3309 
3310   //Build MU-BAR trigger frame
3311   CtrlTriggerHeader muBar;
3312   muBar.SetType (MU_BAR_TRIGGER);
3313   muBar.SetUlLength (HePhy::ConvertHeTbPpduDurationToLSigLength (MicroSeconds (128), WIFI_PHY_BAND_5GHZ));
3314   muBar.SetMoreTF (true);
3315   muBar.SetCsRequired (true);
3316   muBar.SetUlBandwidth (DEFAULT_CHANNEL_WIDTH);
3317   muBar.SetGiAndLtfType (1600, 2);
3318   muBar.SetApTxPower (static_cast<int8_t> (m_txPowerAp));
3319   muBar.SetUlSpatialReuse (60500);
3320 
3321   HeRu::RuType ru = (staIds.size () == 1) ? HeRu::RU_242_TONE : HeRu::RU_106_TONE;
3322   std::size_t index = 1;
3323   int8_t ulTargetRssi = -40; //will be overwritten
3324   for (auto const& staId : staIds)
3325     {
3326       CtrlTriggerUserInfoField& ui = muBar.AddUserInfoField ();
3327       ui.SetAid12 (staId);
3328       ui.SetRuAllocation ({ru, index, true});
3329       ui.SetUlFecCodingType (true);
3330       ui.SetUlMcs (7);
3331       ui.SetUlDcm (false);
3332       ui.SetSsAllocation (1, 1);
3333       if (staId == 1)
3334         {
3335           ulTargetRssi = m_requestedRssiSta1;
3336         }
3337       else if (staId == 2)
3338         {
3339           ulTargetRssi = m_requestedRssiSta2;
3340         }
3341       else
3342         {
3343           NS_ABORT_MSG ("Unknown STA-ID (" << staId << ")");
3344         }
3345       ui.SetUlTargetRssi (ulTargetRssi);
3346 
3347       CtrlBAckRequestHeader bar;
3348       bar.SetType (BlockAckReqType::COMPRESSED);
3349       bar.SetTidInfo (0);
3350       bar.SetStartingSequence (4095);
3351       ui.SetMuBarTriggerDepUserInfo (bar);
3352 
3353       ++index;
3354     }
3355 
3356   WifiConstPsduMap psdus;
3357   WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0,
3358                                         DEFAULT_CHANNEL_WIDTH, false, false, false, m_bssColor);
3359 
3360   Ptr<Packet> bar = Create<Packet> ();
3361   bar->AddHeader (muBar);
3362 
3363   Mac48Address receiver = Mac48Address::GetBroadcast ();
3364   if (staIds.size () == 1)
3365     {
3366       uint16_t aidSta1 = DynamicCast<StaWifiMac> (m_sta1Dev->GetMac ())->GetAssociationId ();
3367       if (staIds.front () == aidSta1)
3368         {
3369           receiver = Mac48Address::ConvertFrom (m_sta1Dev->GetAddress ());
3370         }
3371       else
3372         {
3373           NS_ASSERT (staIds.front () == DynamicCast<StaWifiMac> (m_sta2Dev->GetMac ())->GetAssociationId ());
3374           receiver = Mac48Address::ConvertFrom (m_sta2Dev->GetAddress ());
3375         }
3376     }
3377 
3378   WifiMacHeader hdr;
3379   hdr.SetType (WIFI_MAC_CTL_TRIGGER);
3380   hdr.SetAddr1 (receiver);
3381   hdr.SetAddr2 (Mac48Address::ConvertFrom (m_apDev->GetAddress ()));
3382   hdr.SetAddr3 (Mac48Address::ConvertFrom (m_apDev->GetAddress ()));
3383   hdr.SetDsNotTo ();
3384   hdr.SetDsFrom ();
3385   hdr.SetNoRetry ();
3386   hdr.SetNoMoreFragments ();
3387   Ptr<WifiPsdu> psdu = Create<WifiPsdu> (bar, hdr);
3388 
3389   Time nav = m_apDev->GetPhy ()->GetSifs ();
3390   uint16_t staId = staIds.front (); //either will do
3391   nav += m_phyAp->CalculateTxDuration (GetBlockAckSize (BlockAckType::COMPRESSED), muBar.GetHeTbTxVector (staId), DEFAULT_WIFI_BAND, staId);
3392   psdu->SetDuration (nav);
3393   psdus.insert (std::make_pair (SU_STA_ID, psdu));
3394 
3395   m_phyAp->Send (psdus, txVector);
3396 }
3397 
3398 void
ReceiveOkCallbackAtAp(Ptr<WifiPsdu> psdu,RxSignalInfo rxSignalInfo,WifiTxVector txVector,std::vector<bool>)3399 TestUlOfdmaPowerControl::ReceiveOkCallbackAtAp (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
3400                                             WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
3401 {
3402   NS_TEST_ASSERT_MSG_EQ (txVector.GetPreambleType (), WIFI_PREAMBLE_HE_TB, "HE TB PPDU expected");
3403   double rssi = rxSignalInfo.rssi;
3404   NS_ASSERT (psdu->GetNMpdus () == 1);
3405   WifiMacHeader hdr = psdu->GetHeader (0);
3406   NS_TEST_ASSERT_MSG_EQ (hdr.GetType (), WIFI_MAC_CTL_BACKRESP, "Block ACK expected");
3407   if (hdr.GetAddr2 () == m_sta1Dev->GetAddress ())
3408     {
3409       NS_TEST_ASSERT_MSG_EQ_TOL (rssi, m_rssiSta1, m_tol, "The obtained RSSI from STA 1 at AP is different from the expected one (" << rssi << " vs " << m_rssiSta1 << ", with tolerance of " << m_tol << ")");
3410     }
3411   else if (psdu->GetAddr2 () == m_sta2Dev->GetAddress ())
3412     {
3413       NS_TEST_ASSERT_MSG_EQ_TOL (rssi, m_rssiSta2, m_tol, "The obtained RSSI from STA 2 at AP is different from the expected one (" << rssi << " vs " << m_rssiSta2 << ", with tolerance of " << m_tol << ")");
3414     }
3415   else
3416     {
3417       NS_ABORT_MSG ("The receiver address is unknown");
3418     }
3419 }
3420 
3421 void
ReplaceReceiveOkCallbackOfAp(void)3422 TestUlOfdmaPowerControl::ReplaceReceiveOkCallbackOfAp (void)
3423 {
3424   //Now that BA session has been established we can plug our method
3425   m_phyAp->SetReceiveOkCallback (MakeCallback (&TestUlOfdmaPowerControl::ReceiveOkCallbackAtAp, this));
3426 }
3427 
3428 void
DoSetup(void)3429 TestUlOfdmaPowerControl::DoSetup (void)
3430 {
3431   Ptr<Node> apNode = CreateObject<Node> ();
3432   NodeContainer staNodes;
3433   staNodes.Create (2);
3434 
3435   Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
3436   Ptr<MatrixPropagationLossModel> lossModel = CreateObject<MatrixPropagationLossModel> ();
3437   spectrumChannel->AddPropagationLossModel (lossModel);
3438   Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
3439   spectrumChannel->SetPropagationDelayModel (delayModel);
3440 
3441   SpectrumWifiPhyHelper spectrumPhy;
3442   spectrumPhy.SetChannel (spectrumChannel);
3443   spectrumPhy.SetErrorRateModel ("ns3::NistErrorRateModel");
3444   spectrumPhy.Set ("Frequency", UintegerValue (DEFAULT_FREQUENCY));
3445   spectrumPhy.Set ("ChannelWidth", UintegerValue (DEFAULT_CHANNEL_WIDTH));
3446 
3447   WifiHelper wifi;
3448   wifi.SetStandard (WIFI_STANDARD_80211ax_5GHZ);
3449   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
3450                                 "DataMode", StringValue ("HeMcs7"),
3451                                 "ControlMode", StringValue ("HeMcs7"));
3452 
3453   WifiMacHelper mac;
3454   mac.SetType ("ns3::StaWifiMac");
3455   NetDeviceContainer staDevs = wifi.Install (spectrumPhy, mac, staNodes);
3456   wifi.AssignStreams (staDevs, 0);
3457   m_sta1Dev = DynamicCast<WifiNetDevice> (staDevs.Get (0));
3458   NS_ASSERT (m_sta1Dev);
3459   m_sta2Dev = DynamicCast<WifiNetDevice> (staDevs.Get (1));
3460   NS_ASSERT (m_sta2Dev);
3461 
3462   //Set the beacon interval long enough so that associated STAs may not consider link lost when
3463   //beacon generation is disabled during the actual tests. Having such a long interval also
3464   //avoids bloating logs with beacons during the set up phase.
3465   mac.SetType ("ns3::ApWifiMac",
3466                "BeaconGeneration", BooleanValue (true),
3467                "BeaconInterval", TimeValue (MicroSeconds (1024 * 600)));
3468   m_apDev = DynamicCast<WifiNetDevice> (wifi.Install (spectrumPhy, mac, apNode).Get (0));
3469   NS_ASSERT (m_apDev);
3470   m_apDev->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (m_bssColor));
3471   m_phyAp = DynamicCast<SpectrumWifiPhy> (m_apDev->GetPhy ());
3472   NS_ASSERT (m_phyAp);
3473   //ReceiveOkCallback of AP will be set to corresponding test's method once BA sessions have been set up for both STAs
3474 
3475   MobilityHelper mobility;
3476   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
3477   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
3478   positionAlloc->Add (Vector (0.0, 0.0, 0.0));
3479   positionAlloc->Add (Vector (1.0, 0.0, 0.0)); // put close enough in order to use MCS
3480   positionAlloc->Add (Vector (2.0, 0.0, 0.0)); // STA 2 is a bit further away, but still in range of MCS
3481   mobility.SetPositionAllocator (positionAlloc);
3482 
3483   mobility.Install (apNode);
3484   mobility.Install (staNodes);
3485 
3486   lossModel->SetDefaultLoss (50.0);
3487   lossModel->SetLoss (apNode->GetObject<MobilityModel> (), staNodes.Get (1)->GetObject<MobilityModel> (),
3488                       56.0, true); //+6 dB between AP <-> STA 2 compared to AP <-> STA 1
3489 }
3490 
3491 void
DoTeardown(void)3492 TestUlOfdmaPowerControl::DoTeardown (void)
3493 {
3494   m_phyAp->Dispose ();
3495   m_phyAp = 0;
3496   m_apDev->Dispose ();
3497   m_apDev = 0;
3498   m_sta1Dev->Dispose ();
3499   m_sta1Dev = 0;
3500   m_sta2Dev->Dispose ();
3501   m_sta2Dev = 0;
3502 }
3503 
3504 void
RunOne(bool setupBa)3505 TestUlOfdmaPowerControl::RunOne (bool setupBa)
3506 {
3507   RngSeedManager::SetSeed (1);
3508   RngSeedManager::SetRun (1);
3509   int64_t streamNumber = 0;
3510 
3511   Ptr<WifiPhy> phySta1 = m_sta1Dev->GetPhy ();
3512   Ptr<WifiPhy> phySta2 = m_sta2Dev->GetPhy ();
3513 
3514   m_phyAp->AssignStreams (streamNumber);
3515   phySta1->AssignStreams (streamNumber);
3516   phySta2->AssignStreams (streamNumber);
3517 
3518   m_phyAp->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerAp));
3519   m_phyAp->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerAp));
3520   m_phyAp->SetAttribute ("TxPowerLevels", UintegerValue (1));
3521 
3522   phySta1->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerStart));
3523   phySta1->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerEnd));
3524   phySta1->SetAttribute ("TxPowerLevels", UintegerValue (m_txPowerLevels));
3525 
3526   phySta2->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerStart));
3527   phySta2->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerEnd));
3528   phySta2->SetAttribute ("TxPowerLevels", UintegerValue (m_txPowerLevels));
3529 
3530   Time relativeStart = MilliSeconds (0);
3531   if (setupBa)
3532     {
3533       //Set up BA for each station once the association phase has ended
3534       //so that a BA session is established when the MU-BAR is received.
3535       Simulator::Schedule (MilliSeconds (800), &TestUlOfdmaPowerControl::SetupBa, this, m_sta1Dev->GetAddress ());
3536       Simulator::Schedule (MilliSeconds (850), &TestUlOfdmaPowerControl::SetupBa, this, m_sta2Dev->GetAddress ());
3537       relativeStart = MilliSeconds (1000);
3538     }
3539   else
3540     {
3541       Ptr<ApWifiMac> apMac = DynamicCast<ApWifiMac> (m_apDev->GetMac ());
3542       NS_ASSERT (apMac);
3543       apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
3544     }
3545 
3546   Simulator::Schedule (relativeStart, &TestUlOfdmaPowerControl::ReplaceReceiveOkCallbackOfAp, this);
3547 
3548   {
3549     //Verify that the RSSI from STA 1 is consistent with what was requested
3550     std::vector<uint16_t> staIds {1};
3551     Simulator::Schedule (relativeStart, &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3552   }
3553 
3554   {
3555     //Verify that the RSSI from STA 2 is consistent with what was requested
3556     std::vector<uint16_t> staIds {2};
3557     Simulator::Schedule (relativeStart + MilliSeconds (20), &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3558   }
3559 
3560   {
3561     //Verify that the RSSI from STA 1 and 2 is consistent with what was requested
3562     std::vector<uint16_t> staIds {1, 2};
3563     Simulator::Schedule (relativeStart + MilliSeconds (40), &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3564   }
3565 
3566   Simulator::Stop (relativeStart + MilliSeconds (100));
3567   Simulator::Run ();
3568 }
3569 
3570 void
DoRun(void)3571 TestUlOfdmaPowerControl::DoRun (void)
3572 {
3573   //Power configurations
3574   m_txPowerAp = 20; //dBm, so as to have -30 and -36 dBm at STA 1 and STA 2 resp.,
3575                     //since path loss = 50 dB for AP <-> STA 1 and 56 dB for AP <-> STA 2
3576   m_txPowerStart = 15; //dBm
3577 
3578   //Requested UL RSSIs: should correspond to 20 dBm transmit power at STAs
3579   m_requestedRssiSta1 = -30.0;
3580   m_requestedRssiSta2 = -36.0;
3581 
3582   //Test single power level
3583   {
3584     //STA power configurations: 15 dBm only
3585     m_txPowerEnd = 15;
3586     m_txPowerLevels = 1;
3587 
3588     //Expected UL RSSIs, considering that the provided power is 5 dB less than requested,
3589     //regardless of the estimated path loss.
3590     m_rssiSta1 = -35.0; // 15 dBm - 50 dB
3591     m_rssiSta2 = -41.0; // 15 dBm - 56 dB
3592 
3593     RunOne (true);
3594   }
3595 
3596   //Test 2 dBm granularity
3597   {
3598     //STA power configurations: [15:2:25] dBm
3599     m_txPowerEnd = 25;
3600     m_txPowerLevels = 6;
3601 
3602     //Expected UL RSSIs, considering that the provided power (21 dBm) is 1 dB more than requested
3603     m_rssiSta1 = -29.0; // 21 dBm - 50 dB
3604     m_rssiSta2 = -35.0; // 21 dBm - 50 dB
3605 
3606     RunOne (false);
3607   }
3608 
3609   //Test 1 dBm granularity
3610   {
3611     //STA power configurations: [15:1:25] dBm
3612     m_txPowerEnd = 25;
3613     m_txPowerLevels = 11;
3614 
3615     //Expected UL RSSIs, considering that we can correctly tune the transmit power
3616     m_rssiSta1 = -30.0; // 20 dBm - 50 dB
3617     m_rssiSta2 = -36.0; // 20 dBm - 56 dB
3618 
3619     RunOne (false);
3620   }
3621 
3622   //Ask for different power levels (3 dB difference between HE_TB_PPDUs)
3623   {
3624     //STA power configurations: [15:1:25] dBm
3625     m_txPowerEnd = 25;
3626     m_txPowerLevels = 11;
3627 
3628     //Requested UL RSSIs
3629     m_requestedRssiSta1 = -28.0; //2 dB higher than previously -> Tx power = 22 dBm at STA 1
3630     m_requestedRssiSta2 = -37.0; //1 dB less than previously -> Tx power = 19 dBm at STA 2
3631 
3632     //Expected UL RSSIs, considering that we can correctly tune the transmit power
3633     m_rssiSta1 = -28.0; // 22 dBm - 50 dB
3634     m_rssiSta2 = -37.0; // 19 dBm - 56 dB
3635 
3636     RunOne (false);
3637   }
3638 
3639   Simulator::Destroy ();
3640 }
3641 
3642 
3643 /**
3644  * \ingroup wifi-test
3645  * \ingroup tests
3646  *
3647  * \brief wifi PHY OFDMA Test Suite
3648  */
3649 class WifiPhyOfdmaTestSuite : public TestSuite
3650 {
3651 public:
3652   WifiPhyOfdmaTestSuite ();
3653 };
3654 
WifiPhyOfdmaTestSuite()3655 WifiPhyOfdmaTestSuite::WifiPhyOfdmaTestSuite ()
3656   : TestSuite ("wifi-phy-ofdma", UNIT)
3657 {
3658   AddTestCase (new TestDlOfdmaPhyTransmission, TestCase::QUICK);
3659   AddTestCase (new TestUlOfdmaPpduUid, TestCase::QUICK);
3660   AddTestCase (new TestMultipleHeTbPreambles, TestCase::QUICK);
3661   AddTestCase (new TestUlOfdmaPhyTransmission, TestCase::QUICK);
3662   AddTestCase (new TestPhyPaddingExclusion, TestCase::QUICK);
3663   AddTestCase (new TestUlOfdmaPowerControl, TestCase::QUICK);
3664 }
3665 
3666 static WifiPhyOfdmaTestSuite wifiPhyOfdmaTestSuite; ///< the test suite
3667