A Discrete-Event Network Simulator
API
wifi-phy-ofdma-test.cc
Go to the documentation of this file.
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
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 
64 class OfdmaTestHePhy : public HePhy
65 {
66 public:
72  OfdmaTestHePhy (uint16_t staId);
73  virtual ~OfdmaTestHePhy ();
74 
82  uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const override;
83 
89  void SetGlobalPpduUid (uint64_t uid);
90 
91 private:
92  uint16_t m_staId;
93 }; //class OfdmaTestHePhy
94 
96  : HePhy (),
97  m_staId (staId)
98 {
99 }
100 
102 {
103 }
104 
105 uint16_t
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
117 {
118  m_globalPpduUid = uid;
119 }
120 
125 {
126 public:
131  static TypeId GetTypeId (void);
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 
150  typedef void (*TxPpduUidCallback)(uint64_t uid);
151 
155  void StartTx (Ptr<WifiPpdu> ppdu) override;
160  uint16_t GetGuardBandwidth (uint16_t currentChannelWidth) const override;
161 
167  void SetPpduUid (uint64_t uid);
168 
174  void SetTriggerFrameUid (uint64_t uid);
175 
179  std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > & GetCurrentPreambleEvents (void);
184 
195  Time GetEnergyDuration (double energyW, WifiSpectrumBand band);
196 
200  Ptr<const HePhy> GetHePhy (void) const;
201 
202 private:
205 }; //class OfdmaSpectrumWifiPhy
206 
207 TypeId
209 {
210  static TypeId tid = TypeId ("ns3::OfdmaSpectrumWifiPhy")
212  .SetGroupName ("Wifi")
213  .AddTraceSource ("TxPpduUid",
214  "UID of the PPDU to be transmitted",
216  "ns3::OfdmaSpectrumWifiPhy::TxPpduUidCallback")
217  ;
218  return tid;
219 }
220 
222  : SpectrumWifiPhy ()
223 {
224  m_ofdmTestHePhy = Create<OfdmaTestHePhy> (staId);
225  m_ofdmTestHePhy->SetOwner (this);
226 }
227 
229 {
230 }
231 
232 void
234 {
235  //Replace HE PHY instance with test instance
237  SpectrumWifiPhy::DoInitialize ();
238 }
239 
240 void
242 {
243  m_ofdmTestHePhy = 0;
244  SpectrumWifiPhy::DoDispose ();
245 }
246 
247 void
249 {
251  m_previouslyRxPpduUid = uid;
252 }
253 
254 void
256 {
257  m_previouslyRxPpduUid = uid;
258 }
259 
260 void
262 {
263  m_phyTxPpduUidTrace (ppdu->GetUid ());
264  SpectrumWifiPhy::StartTx (ppdu);
265 }
266 
267 std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > &
269 {
271 }
272 
273 uint16_t
274 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 
283 {
284  return m_currentEvent;
285 }
286 
287 Time
289 {
290  return m_interference.GetEnergyDuration (energyW, band);
291 }
292 
295 {
296  return DynamicCast<const HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE));
297 }
298 
306 {
307 public:
309  virtual ~TestDlOfdmaPhyTransmission ();
310 
311 private:
312  void DoSetup (void) override;
313  void DoTeardown (void) override;
314  void DoRun (void) override;
315 
323  void RxSuccessSta1 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
324  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
332  void RxSuccessSta2 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
333  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
341  void RxSuccessSta3 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
342  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
343 
348  void RxFailureSta1 (Ptr<WifiPsdu> psdu);
353  void RxFailureSta2 (Ptr<WifiPsdu> psdu);
358  void RxFailureSta3 (Ptr<WifiPsdu> psdu);
359 
366  void CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
373  void CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
380  void CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
381 
385  void ResetResults ();
386 
392  void SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2);
393 
399  void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
403  void StopInterference (void);
404 
408  void RunOne ();
409 
422 
432 
438 
439  uint16_t m_frequency;
440  uint16_t m_channelWidth;
442 };
443 
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
463 {
470  m_countRxBytesSta1 = 0;
471  m_countRxBytesSta2 = 0;
472  m_countRxBytesSta3 = 0;
473 }
474 
475 void
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
536 {
537  m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
538  m_phyInterferer->SetPeriod (duration);
540  Simulator::Schedule (duration, &TestDlOfdmaPhyTransmission::StopInterference, this);
541 }
542 
543 void
545 {
547 }
548 
550 {
551 }
552 
553 void
555  WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
556 {
557  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
559  m_countRxBytesSta1 += (psdu->GetSize () - 30);
560 }
561 
562 void
564  WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
565 {
566  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
568  m_countRxBytesSta2 += (psdu->GetSize () - 30);
569 }
570 
571 void
573  WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
574 {
575  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
577  m_countRxBytesSta3 += (psdu->GetSize () - 30);
578 }
579 
580 void
582 {
583  NS_LOG_FUNCTION (this << *psdu);
585 }
586 
587 void
589 {
590  NS_LOG_FUNCTION (this << *psdu);
592 }
593 
594 void
596 {
597  NS_LOG_FUNCTION (this << *psdu);
599 }
600 
601 void
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
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
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
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
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
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> ();
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);
674  m_phySta1->SetErrorRateModel (error);
675  m_phySta1->SetDevice (sta1Dev);
676  m_phySta1->SetChannel (spectrumChannel);
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);
690  m_phySta2->SetErrorRateModel (error);
691  m_phySta2->SetDevice (sta2Dev);
692  m_phySta2->SetChannel (spectrumChannel);
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);
706  m_phySta3->SetErrorRateModel (error);
707  m_phySta3->SetDevice (sta3Dev);
708  m_phySta3->SetChannel (spectrumChannel);
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);
723  interfererNode->AddDevice (interfererDev);
724 }
725 
726 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;
738  m_phyInterferer = 0;
739 }
740 
741 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 
754 
757 
760 
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.
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.
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.
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.
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.
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
925 {
926  m_frequency = 5180;
927  m_channelWidth = 20;
929  RunOne ();
930 
931  m_frequency = 5190;
932  m_channelWidth = 40;
934  RunOne ();
935 
936  m_frequency = 5210;
937  m_channelWidth = 80;
939  RunOne ();
940 
941  m_frequency = 5250;
942  m_channelWidth = 160;
944  RunOne ();
945 
946  Simulator::Destroy ();
947 }
948 
949 
957 {
958 public:
960  virtual ~TestUlOfdmaPpduUid ();
961 
962 private:
963  void DoSetup (void) override;
964  void DoTeardown (void) override;
965  void DoRun (void) override;
966 
971  void TxPpduAp (uint64_t uid);
976  void TxPpduSta1 (uint64_t uid);
981  void TxPpduSta2 (uint64_t uid);
985  void ResetPpduUid (void);
986 
990  void SendMuPpdu (void);
994  void SendTbPpdu (void);
999  void SendSuPpdu (uint16_t txStaId);
1000 
1006  void CheckUid (uint16_t staId, uint64_t expectedUid);
1007 
1011 
1012  uint64_t m_ppduUidAp;
1013  uint64_t m_ppduUidSta1;
1014  uint64_t m_ppduUidSta2;
1015 };
1016 
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 
1026 {
1027 }
1028 
1029 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);
1044  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1045  m_phyAp->SetErrorRateModel (error);
1048  m_phyAp->SetDevice (apDev);
1049  m_phyAp->SetChannel (spectrumChannel);
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);
1062  m_phySta1->SetErrorRateModel (error);
1065  m_phySta1->SetDevice (sta1Dev);
1066  m_phySta1->SetChannel (spectrumChannel);
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);
1079  m_phySta2->SetErrorRateModel (error);
1082  m_phySta2->SetDevice (sta2Dev);
1083  m_phySta2->SetChannel (spectrumChannel);
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
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
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
1130 {
1131  NS_LOG_FUNCTION (this << uid);
1132  m_ppduUidAp = uid;
1133 }
1134 
1135 void
1137 {
1138  NS_LOG_FUNCTION (this << uid);
1139  m_ppduUidSta1 = uid;
1140 }
1141 
1142 void
1144 {
1145  NS_LOG_FUNCTION (this << uid);
1146  m_ppduUidSta2 = uid;
1147 }
1148 
1149 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
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
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
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
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 
1325 {
1326 public:
1328  virtual ~TestMultipleHeTbPreambles ();
1329 
1330 private:
1331  void DoSetup (void) override;
1332  void DoTeardown (void) override;
1333  void DoRun (void) override;
1334 
1343  void RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize);
1344 
1359 
1366 
1370  void Reset (void);
1371 
1377  void CheckHeTbPreambles (size_t nEvents, std::vector <uint64_t> uids);
1378 
1383  void CheckBytesDropped (size_t expectedBytesDropped);
1384 
1386 
1388 };
1389 
1391  : TestCase ("UL-OFDMA multiple RX events test"),
1392  m_totalBytesDropped (0)
1393 {
1394 }
1395 
1397 {
1398 }
1399 
1400 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
1411 {
1412  NS_LOG_FUNCTION (this << p << reason);
1413  m_totalBytesDropped += (p->GetSize () - 30);
1414 }
1415 
1416 void
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
1432 {
1433  NS_TEST_ASSERT_MSG_EQ (m_totalBytesDropped, expectedBytesDropped, "The number of dropped bytes is not correct!");
1434 }
1435 
1436 void
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);
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
1490 {
1491  Simulator::ScheduleNow (&TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart, this, rxParamsOfdma);
1492 }
1493 
1494 void
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
1504 {
1505  Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice> ();
1506  m_phy = CreateObject<OfdmaSpectrumWifiPhy> (0);
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);
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
1526 {
1527  m_phy->Dispose ();
1528  m_phy = 0;
1529 }
1530 
1531 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 
1635 {
1636 public:
1638  virtual ~TestUlOfdmaPhyTransmission ();
1639 
1640 private:
1641  void DoSetup (void) override;
1642  void DoTeardown (void) override;
1643  void DoRun (void) override;
1644 
1652  WifiTxVector GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_t index, uint8_t bssColor) const;
1661  void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
1662 
1670  void SendHeSuPpdu (uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
1671 
1677  void SetBssColor (Ptr<WifiPhy> phy, uint8_t bssColor);
1678 
1684  void SetPsdLimit (Ptr<WifiPhy> phy, double psdLimit);
1685 
1691  void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
1695  void StopInterference (void);
1696 
1700  void RunOne ();
1701 
1708  void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
1709 
1716  void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
1717 
1724  void CheckNonOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower);
1731  void CheckOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower);
1732 
1736  void VerifyEventsCleared (void);
1737 
1746 
1750  void Reset ();
1751 
1759  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1760 
1765  void RxFailure (Ptr<WifiPsdu> psdu);
1766 
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 
1797  void SchedulePowerMeasurementChecks (Time delay, double rxPowerNonOfdmaRu1, double rxPowerNonOfdmaRu2,
1798  double rxPowerOfdmaRu1, double rxPowerOfdmaRu2);
1804  void LogScenario (std::string log) const;
1805 
1810 
1812 
1819 
1820  uint16_t m_frequency;
1821  uint16_t m_channelWidth;
1823 };
1824 
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
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 
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 
1881 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
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 
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
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
1973 {
1974  m_phyInterferer->Stop();
1975 }
1976 
1978 {
1979 }
1980 
1981 void
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  {
1988  m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
1989  }
1990  else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
1991  {
1993  m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
1994  }
1995 }
1996 
1997 void
1999 {
2000  NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
2001  if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2002  {
2004  }
2005  else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2006  {
2008  }
2009 }
2010 
2011 void
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
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
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
2040 {
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
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
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
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
2091 {
2098  m_phySta1->SetPpduUid (0);
2101  SetBssColor (m_phyAp, 0);
2102 }
2103 
2104 void
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
2114 {
2115  NS_LOG_FUNCTION (this << phy << psdLimit);
2116  phy->SetAttribute ("PowerDensityLimit", DoubleValue (psdLimit));
2117 }
2118 
2119 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);
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);
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);
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);
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);
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);
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
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;
2233  m_phyInterferer = 0;
2234 }
2235 
2236 void
2238 {
2239  NS_LOG_INFO (log);
2240 }
2241 
2242 void
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
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  {
2297  //Check received power on non-OFDMA portion
2298  Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2300  nonOfdmaBand[i], rxPowerNonOfdma[i]);
2301  Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2303  nonOfdmaBand[i], rxPowerNonOfdma[i]);
2304  //Check received power on OFDMA portion
2305  Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2307  ofdmaBand[i], rxPowerOfdma[i]);
2308  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2310  ofdmaBand[i], rxPowerOfdma[i]);
2311 
2317  //Check received power on non-OFDMA portion
2318  Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2320  nonOfdmaBand[i], rxPowerNonOfdma[i]);
2321  Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2323  nonOfdmaBand[i], rxPowerNonOfdma[i]);
2324  //Check received power on OFDMA portion
2325  Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2327  ofdmaBand[i], rxPowerOfdma[i]);
2328  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2330  ofdmaBand[i], rxPowerOfdma[i]);
2331  }
2332 
2333  if (rxPowerOfdmaRu1 != 0.0)
2334  {
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)
2344  nonOfdmaBand[0], rxPowerNonOfdmaSta1Only);
2345  Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2347  nonOfdmaBand[0], rxPowerNonOfdmaSta1Only);
2348  //Check received power on OFDMA portion
2349  Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2351  ofdmaBand[0], rxPowerOfdma[0]);
2352  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2354  ofdmaBand[0], rxPowerOfdma[0]);
2355  }
2356 }
2357 
2358 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 
2371 
2374 
2377 
2380 
2381  Time delay = Seconds (0.0);
2382  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::Reset, this);
2383  delay += Seconds (1.0);
2384 
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,
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,
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,
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,
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,
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,
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)
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,
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
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  }
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,
2708  ScheduleTest (delay, true,
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
2722  rxPowerNonOfdma, rxPowerNonOfdma,
2723  rxPower, rxPower);
2724  ScheduleTest (delay, true,
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
2749 {
2750  m_frequency = 5180;
2751  m_channelWidth = 20;
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;
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;
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;
2771  NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2772  RunOne ();
2773 
2774  Simulator::Destroy ();
2775 }
2776 
2784 {
2785 public:
2787  virtual ~TestPhyPaddingExclusion ();
2788 
2789 private:
2790  void DoSetup (void) override;
2791  void DoTeardown (void) override;
2792  void DoRun (void) override;
2793 
2801  void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration);
2802 
2808  void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
2812  void StopInterference (void);
2813 
2817  void RunOne ();
2818 
2825  void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
2826 
2833  void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
2834 
2838  void VerifyEventsCleared (void);
2839 
2848 
2852  void Reset ();
2853 
2861  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
2862 
2867  void RxFailure (Ptr<WifiPsdu> psdu);
2868 
2872 
2874 
2881 };
2882 
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
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 
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
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
2945 {
2946  m_phyInterferer->Stop();
2947 }
2948 
2950 {
2951 }
2952 
2953 void
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  {
2960  m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
2961  }
2962  else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2963  {
2965  m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
2966  }
2967 }
2968 
2969 void
2971 {
2972  NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
2973  if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2974  {
2976  }
2977  else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2978  {
2980  }
2981 }
2982 
2983 void
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
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
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
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
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
3024 {
3031  m_phySta1->SetPpduUid (0);
3034 }
3035 
3036 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);
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);
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);
3080  m_phySta1->SetErrorRateModel (error);
3081  m_phySta1->SetDevice (sta1Dev);
3082  m_phySta1->SetChannel (spectrumChannel);
3083  m_phySta1->AssignStreams (streamNumber);
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);
3097  m_phySta2->SetErrorRateModel (error);
3098  m_phySta2->SetDevice (sta2Dev);
3099  m_phySta2->SetChannel (spectrumChannel);
3100  m_phySta2->AssignStreams (streamNumber);
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);
3115  interfererNode->AddDevice (interfererDev);
3116 }
3117 
3118 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;
3128  m_phyInterferer = 0;
3129 }
3130 
3131 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 
3201 {
3202 public:
3204  virtual ~TestUlOfdmaPowerControl ();
3205 
3206 private:
3207  void DoSetup (void) override;
3208  void DoTeardown (void) override;
3209  void DoRun (void) override;
3210 
3216  void SendMuBar (std::vector <uint16_t> staIds);
3217 
3224  void SetupBa (Address destination);
3225 
3232  void RunOne (bool setupBa);
3233 
3238  void ReplaceReceiveOkCallbackOfAp (void);
3239 
3249  void ReceiveOkCallbackAtAp (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
3250  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
3251 
3252  uint8_t m_bssColor;
3253 
3257 
3259 
3260  double m_txPowerAp;
3262  double m_txPowerEnd;
3264 
3267 
3268  double m_rssiSta1;
3269  double m_rssiSta2;
3270 
3271  double m_tol;
3272 };
3273 
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 
3290 {
3291  m_phyAp = 0;
3292  m_apDev = 0;
3293  m_sta1Dev = 0;
3294  m_sta2Dev = 0;
3295 }
3296 
3297 void
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
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 
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;
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
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
3423 {
3424  //Now that BA session has been established we can plug our method
3426 }
3427 
3428 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 
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 
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
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
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
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 
3650 {
3651 public:
3653 };
3654 
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 
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
PHY entity for HE (11ax)HE PHY is based on VHT PHY.
Definition: he-phy.h:60
void RxSuccessSta3(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function for STA 3.
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:140
void SetTriggerFrameUid(uint64_t uid)
Since we assume trigger frame was previously received from AP, this is used to set its UID...
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void CheckResultsSta2(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 2.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Ptr< WifiPpdu > Copy(void) const override
Copy this instance.
Definition: he-ppdu.cc:160
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
double m_rssiSta2
expected RSSI (in dBm) from STA 2 at AP for HE TB PPDUs
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class, for the WifiPhy instance...
Definition: wifi-phy.cc:878
void SendMuPpdu(uint16_t rxStaId1, uint16_t rxStaId2)
Send MU-PPDU function.
double m_rssiSta1
expected RSSI (in dBm) from STA 1 at AP for HE TB PPDUs
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint32_t m_countRxFailureSta2
count RX failure for STA 2
uint32_t m_countRxBytesFromSta1
count RX bytes from STA 1
RU Specification.
Definition: he-ru.h:67
void SetType(TriggerFrameType type)
Set the Trigger frame type.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Ptr< WifiNetDevice > m_sta2Dev
network device of STA 2
Ptr< HeConfiguration > GetHeConfiguration(void) const
double m_txPowerAp
transmit power (in dBm) of AP
Headers for Trigger frames.
Definition: ctrl-headers.h:885
Ptr< T > Get(void) const
Definition: pointer.h:201
void StopInterference(void)
Stop interference function.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
void SetDevice(Ptr< NetDevice > d)
Set the associated NetDevice instance.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint64_t m_totalBytesDropped
total number of dropped bytes
Time CalculateNonOfdmaDurationForHeTb(const WifiTxVector &txVector) const
Definition: he-phy.cc:282
uint64_t GetUid(void) const
Get the UID of the PPDU.
Definition: wifi-ppdu.cc:129
void SetDuration(Time duration)
Set the Duration/ID field on all the MPDUs.
Definition: wifi-psdu.cc:156
Ptr< OfdmaTestHePhy > m_ofdmTestHePhy
Pointer to HE PHY instance used for OFDMA test.
void DoRun(void) override
Implementation to actually run this TestCase.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
double m_txPowerStart
minimum transmission power (in dBm) for STAs
uint32_t m_countRxFailureFromSta1
count RX failure from STA 1
uint32_t m_countRxFailureFromSta1
count RX failure from STA 1
Ptr< WifiPpdu > ppdu
The PPDU being transmitted.
Hold variables of type string.
Definition: string.h:41
void RxHeTbPpduOfdmaPart(Ptr< WifiSpectrumSignalParameters > rxParamsOfdma)
Receive OFDMA part of HE TB PPDU function.
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
uint32_t m_countRxBytesSta2
count RX bytes for STA 2
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1124
void CheckPhyState(Ptr< OfdmaSpectrumWifiPhy > phy, WifiPhyState expectedState)
Check the PHY state.
void CheckNonOfdmaRxPower(Ptr< OfdmaSpectrumWifiPhy > phy, WifiSpectrumBand band, double expectedRxPower)
Check the received power for the non-OFDMA of the HE TB PPDUs over the given band.
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:41
A suite of tests to run.
Definition: test.h:1343
void DoCheckPhyState(Ptr< OfdmaSpectrumWifiPhy > phy, WifiPhyState expectedState)
Check the PHY state.
void TxPpduAp(uint64_t uid)
Transmitted PPDU information function for AP.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
Time m_expectedPpduDuration
expected duration to send MU PPDU
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
Ptr< OfdmaSpectrumWifiPhy > m_phySta3
PHY of STA 3.
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:641
void RxSuccessSta2(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function for STA 2.
uint32_t m_countRxSuccessSta3
count RX success for STA 3
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
void RxFailureSta2(Ptr< WifiPsdu > psdu)
Receive failure function for STA 2.
void SetChannel(Ptr< SpectrumChannel > c)
Set the channel attached to this device.
void RunOne()
Run one function.
void Reset(void)
Reset function.
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:789
void VerifyEventsCleared(void)
Verify all events are cleared at end of TX or RX.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
void SetUlTargetRssi(int8_t dBm)
Set the UL Target RSSI subfield to indicate the expected receive signal power in dBm.
uint32_t m_countRxBytesSta3
count RX bytes for STA 3
void Reset(void)
Reset data upon end of TX or RX.
Definition: wifi-phy.cc:1882
Ptr< WifiNetDevice > m_apDev
network device of AP
The 5 GHz band.
Definition: wifi-phy-band.h:37
encapsulates test code
Definition: test.h:1153
void AddPropagationLossModel(Ptr< PropagationLossModel > loss)
Add the single-frequency propagation loss model to be used.
Ptr< OfdmaSpectrumWifiPhy > m_phySta2
PHY of STA 2.
void CheckRxFromSta2(uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
Check the received PSDUs from STA2.
void SetUlFecCodingType(bool ldpc)
Set the UL FEC Coding Type subfield, which indicates whether BCC or LDPC is used. ...
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function.
void CheckBytesDropped(size_t expectedBytesDropped)
Check the number of bytes dropped.
helps to create WifiNetDevice objects
Definition: wifi-helper.h:326
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
uint32_t m_countRxSuccessSta2
count RX success for STA 2
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txs)
Set the Power Spectral Density used for outgoing waveforms.
void SetTxPsdFlag(TxPsdFlag flag)
Definition: he-ppdu.cc:274
uint32_t m_countRxSuccessFromSta2
count RX success from STA 2
void SetDutyCycle(double value)
void SendTbPpdu(void)
Send TB-PPDU from both STAs.
void CheckPhyState(Ptr< OfdmaSpectrumWifiPhy > phy, WifiPhyState expectedState)
Schedule now to check the PHY state.
virtual void Start()
Start the waveform generator.
std::vector< BandInfo > Bands
Container of BandInfo.
uint32_t m_countRxBytesFromSta1
count RX bytes from STA 1
Ptr< OfdmaSpectrumWifiPhy > m_phySta1
PHY of STA 1.
static const WifiPhyBand DEFAULT_WIFI_BAND
void DoCheckPhyState(Ptr< OfdmaSpectrumWifiPhy > phy, WifiPhyState expectedState)
Check the PHY state now.
a polymophic address class
Definition: address.h:90
void SendHeTbPpdu(uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration)
Send HE TB PPDU function.
void SetMuBarTriggerDepUserInfo(const CtrlBAckRequestHeader &bar)
Set the Trigger Dependent User Info subfield for the MU-BAR variant of Trigger frames, which includes a BAR Control subfield and a BAR Information subfield.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
uint16_t GetStaId(const Ptr< const WifiPpdu > ppdu) const override
Return the STA ID that has been assigned to the station this PHY belongs to.
mobility
Definition: third.py:108
uint32_t GetSize(void) const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:260
phy
Definition: third.py:93
void CheckResultsSta1(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 1.
void SetDevice(const Ptr< NetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:777
void SetBssColor(Ptr< WifiPhy > phy, uint8_t bssColor)
Set the BSS color.
void VerifyEventsCleared(void)
Verify all events are cleared at end of TX or RX.
uint32_t m_countRxBytesSta1
count RX bytes for STA 1
WifiPreamble GetPreambleType(void) const
void StartTx(Ptr< WifiPpdu > ppdu) override
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1610
WifiTxVector GetTxVectorForHeTbPpdu(uint16_t txStaId, std::size_t index, uint8_t bssColor) const
Get TXVECTOR for HE TB PPDU.
Keep track of the current position and velocity of an object.
double m_requestedRssiSta1
requested RSSI (in dBm) from STA 1 at AP for HE TB PPDUs
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:66
void SendHeSuPpdu(uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
Send HE SU PPDU function.
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const override
TracedCallback< uint64_t > m_phyTxPpduUidTrace
Callback providing UID of the PPDU that is about to be transmitted.
void CheckOfdmaRxPower(Ptr< OfdmaSpectrumWifiPhy > phy, WifiSpectrumBand band, double expectedRxPower)
Check the received power for the OFDMA part of the HE TB PPDUs over the given band.
SpectrumWifiPhy used for testing OFDMA.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
#define max(a, b)
Definition: 80211b.c:43
void CheckHeTbPreambles(size_t nEvents, std::vector< uint64_t > uids)
Check the received HE TB preambles.
void ResetPpduUid(void)
Reset the global PPDU UID counter in WifiPhy.
HE PHY slightly modified so as to return a given STA-ID in case of DL MU for OfdmaSpectrumWifiPhy.
Ptr< OfdmaSpectrumWifiPhy > m_phySta1
PHY of STA 1.
AttributeValue implementation for Time.
Definition: nstime.h:1353
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
double rssi
RSSI in dBm.
Definition: phy-entity.h:69
void SetMac(const Ptr< WifiMac > mac)
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
void RxHeTbPpdu(uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize)
Receive HE TB PPDU function.
double m_txPowerEnd
maximum transmission power (in dBm) for STAs
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
void RxFailureSta3(Ptr< WifiPsdu > psdu)
Receive failure function for STA 3.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
void SetType(BlockAckReqType type)
Set the BlockAckRequest type.
void SetChannel(Ptr< SpectrumChannel > channel)
Hold an unsigned integer type.
Definition: uinteger.h:44
Address GetAddress(void) const override
void SetPhyIndex(uint16_t bw, uint8_t p20Index)
Set the RU PHY index.
Definition: he-ru.cc:188
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void LogScenario(std::string log) const
Log scenario description.
void SchedulePowerMeasurementChecks(Time delay, double rxPowerNonOfdmaRu1, double rxPowerNonOfdmaRu2, double rxPowerOfdmaRu1, double rxPowerOfdmaRu2)
Schedule power measurement related checks.
void DoRun(void) override
Implementation to actually run this TestCase.
double fc
center frequency
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
Ptr< const HePhy > GetHePhy(void) const
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
uint64_t m_ppduUidAp
UID of PPDU transmitted by AP.
uint32_t m_countRxSuccessSta1
count RX success for STA 1
void CheckRxFromSta1(uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
Check the received PSDUs from STA1.
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:828
holds a vector of ns3::NetDevice pointers
mac
Definition: third.py:99
void Reset()
Reset function.
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1175
void SetAid12(uint16_t aid)
Set the AID12 subfield, which carries the 12 LSBs of the AID of the station for which this User Info ...
Ptr< Event > GetCurrentEvent(void)
The PHY layer has sense the medium busy through the CCA mechanism.
Ptr< SpectrumPhy > txPhy
The SpectrumPhy instance that is making the transmission.
UL-OFDMA power control test.
void CheckPhyState(Ptr< OfdmaSpectrumWifiPhy > phy, WifiPhyState expectedState)
Check the PHY state.
void CheckRxFromSta2(uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
Check the received PSDUs from STA2.
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
uint16_t m_channelWidth
channel width in MHz
802.11 PHY layer modelThis PHY implements a spectrum-aware enhancement of the 802.11 SpectrumWifiPhy model.
Ptr< OfdmaSpectrumWifiPhy > m_phySta3
PHY of STA 3.
void SetPeriod(Time period)
Set the period according to which the WaveformGenerator switches on and off.
uint32_t m_countRxFailureFromSta2
count RX failure from STA 2
void RxSuccessSta1(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function for STA 1.
uint32_t m_countRxBytesFromSta2
count RX bytes from STA 2
UL-OFDMA multiple RX events test.
Mac48Address GetAddr2(void) const
Get the Transmitter Address (TA), which is common to all the MPDUs.
Definition: wifi-psdu.cc:126
void RunOne()
Run one function.
Ptr< OfdmaSpectrumWifiPhy > m_phyAp
PHY of AP.
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:378
const WifiMacHeader & GetHeader(std::size_t i) const
Get the header of the i-th MPDU.
Definition: wifi-psdu.cc:266
uint16_t m_channelWidth
channel width in MHz
Ptr< OfdmaSpectrumWifiPhy > m_phySta1
PHY of STA 1.
void SetOwner(Ptr< WifiPhy > wifiPhy)
Set the WifiPhy owning this PHY entity.
Definition: phy-entity.cc:82
void SetNss(uint8_t nss)
Sets the number of Nss.
uint32_t m_countRxFailureSta1
count RX failure for STA 1
void CheckUid(uint16_t staId, uint64_t expectedUid)
Check the UID of the transmitted PPDU.
Ptr< OfdmaSpectrumWifiPhy > m_phy
Phy.
void CheckResultsSta3(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 3.
uint16_t m_frequency
frequency in MHz
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:808
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void SetGlobalPpduUid(uint64_t uid)
Set the global PPDU UID counter.
void DoRun(void) override
Implementation to actually run this TestCase.
Ptr< WifiPhy > GetPhy(void) const
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
static TypeId GetTypeId(void)
Get the type ID.
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
std::size_t GetNMpdus(void) const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:319
uint32_t m_countRxBytesFromSta2
count RX bytes from STA 2
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t m_countRxSuccessFromSta1
count RX success from STA 1
double fl
lower limit of subband
keep track of a set of node pointers.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void DoDispose(void) override
Destructor implementation.
The PHY layer is IDLE.
void RunOne(bool setupBa)
Run one simulation with an optional BA session set up phase.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void ReplaceReceiveOkCallbackOfAp(void)
Replace the AP&#39;s MacLow callback on its PHY&#39;s ReceiveOkCallback by the ReceiveOkCallbackAtAp method...
WifiPhyState
The state of the PHY layer.
uint32_t m_countRxSuccessFromSta1
count RX success from STA 1
void(* TxPpduUidCallback)(uint64_t uid)
TracedCallback signature for UID of transmitted PPDU.
static uint64_t m_globalPpduUid
Global counter of the PPDU UID.
Definition: phy-entity.h:801
void CheckRxFromSta1(uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
Check the received PSDUs from STA1.
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > m_currentPreambleEvents
store event associated to a PPDU (that has a unique ID and preamble combination) whose preamble is be...
Definition: wifi-phy.h:1173
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:41
void DoInitialize(void) override
Initialize() implementation.
an EUI-48 address
Definition: mac48-address.h:43
void SendMuBar(std::vector< uint16_t > staIds)
Send a MU BAR through the AP to the STAs listed in the provided vector.
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
void DoRun(void) override
Implementation to actually run this TestCase.
wifi PHY OFDMA Test Suite
void RxFailure(Ptr< WifiPsdu > psdu)
Receive failure function.
Ptr< OfdmaSpectrumWifiPhy > m_phySta2
PHY of STA 2.
double m_tol
tolerance (in dB) between received and expected RSSIs
void SendSuPpdu(uint16_t txStaId)
Send SU-PPDU function.
uint32_t m_countRxFailureSta3
count RX failure for STA 3
void SetupBa(Address destination)
Send a QoS Data packet to the destination station in order to set up a block Ack session (so that the...
create MAC layers for a ns3::WifiNetDevice.
Ptr< WifiNetDevice > m_sta1Dev
network device of STA 1
void SetErrorRateModel(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Definition: wifi-helper.cc:146
WifiSpectrumBand GetRuBandForRx(const WifiTxVector &txVector, uint16_t staId) const
Get the band in the RX spectrum associated with the RU used by the PSDU transmitted to/by a given STA...
Definition: he-phy.cc:745
void TxPpduSta1(uint64_t uid)
Transmitted PPDU information function for STA 1.
void Reset(void)
Reset the initial value of every attribute as well as the value of every global to what they were bef...
Definition: config.cc:820
User Info field of Trigger frames.
Definition: ctrl-headers.h:581
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
static const uint8_t DEFAULT_CHANNEL_NUMBER
void StopInterference(void)
Stop interference function.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
virtual void Stop()
Stop the waveform generator.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:32
wifi
Definition: third.py:96
Helper class used to assign positions and mobility models to nodes.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:635
This objects implements the PHY state machine of the Wifi device.
void SetRuAllocation(HeRu::RuSpec ru)
Set the RU Allocation subfield according to the specified RU.
WifiPhyState GetState(void) const
Return the current state of WifiPhy.
uint32_t m_countRxFailureFromSta2
count RX failure from STA 2
Ptr< WifiMac > GetMac(void) const
void SetFrequency(uint16_t freq) override
If the operating channel for this object has not been set yet, the given center frequency is saved an...
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
uint64_t m_ppduUidSta2
UID of PPDU transmitted by STA2.
static const uint16_t DEFAULT_CHANNEL_WIDTH
std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > & GetCurrentPreambleEvents(void)
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:910
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
void Reset()
Reset function.
void DoCheckPhyState(Ptr< OfdmaSpectrumWifiPhy > phy, WifiPhyState expectedState)
Check the PHY state.
uint32_t m_countRxSuccessFromSta2
count RX success from STA 2
PHY padding exclusion test.
void TxPpduSta2(uint64_t uid)
Transmitted PPDU information function for STA 2.
void SetSsAllocation(uint8_t startingSs, uint8_t nSs)
Set the SS Allocation subfield, which is present when the AID12 subfield is neither 0 nor 2045...
InterferenceHelper m_interference
the class handling interference computations
Definition: wifi-phy.h:1162
void SetPsdLimit(Ptr< WifiPhy > phy, double psdLimit)
Set the PSD limit.
Ptr< OfdmaSpectrumWifiPhy > m_phyAp
PHY of AP.
void DoRun(void) override
Implementation to actually run this TestCase.
OfdmaTestHePhy(uint16_t staId)
Constructor.
void SetPropagationDelayModel(Ptr< PropagationDelayModel > delay)
Set the propagation delay model to be used.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
uint32_t GetBlockAckSize(BlockAckType type)
Return the total BlockAck size (including FCS trailer).
Definition: wifi-utils.cc:172
void StopInterference(void)
Stop interference function.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
The PHY layer is receiving a packet.
void SetChannelNumber(uint8_t id) override
Set channel number.
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
Wrapper to InterferenceHelper method.
void Add(Vector v)
Add a position to the list of positions.
double m_requestedRssiSta2
requested RSSI (in dBm) from STA 2 at AP for HE TB PPDUs
void RunOne()
Run one function.
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument...
Definition: wifi-phy.cc:1768
void SendMuPpdu(void)
Send MU-PPDU toward both STAs.
UL-OFDMA PPDU UID attribution test.
Time duration
The duration of the packet transmission.
void SetDsFrom(void)
Set the From DS bit in the Frame Control field.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
void SetUlMcs(uint8_t mcs)
Set the UL MCS subfield, which indicates the MCS of the solicited HE TB PPDU.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Time m_expectedPpduDuration
expected duration to send MU PPDU
void ResetResults()
Reset the results.
Ptr< OfdmaSpectrumWifiPhy > m_phySta2
PHY of STA 2.
Ptr< OfdmaSpectrumWifiPhy > m_phySta2
PHY of STA 2.
void SetLength(uint16_t length)
Set the LENGTH field of the L-SIG.
OfdmaSpectrumWifiPhy(uint16_t staId)
Constructor.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void SendHeTbPpdu(uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
Send HE TB PPDU function.
double fh
upper limit of subband
Headers for BlockAckRequest.
Definition: ctrl-headers.h:48
uint16_t m_staId
ID of the STA to which this PHY belongs to.
void SetChannel(const Ptr< SpectrumChannel > channel)
Set the SpectrumChannel this SpectrumWifiPhy is to be connected to.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1194
void ReceiveOkCallbackAtAp(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive OK callback function at AP.
void RxFailure(Ptr< WifiPsdu > psdu)
Receive failure function.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
The building block of a SpectrumModel.
WifiSpectrumBand GetNonOfdmaBand(const WifiTxVector &txVector, uint16_t staId) const
Get the band used to transmit the non-OFDMA part of an HE TB PPDU.
Definition: he-phy.cc:762
void SetChannelWidth(uint16_t channelwidth) override
If the operating channel for this object has not been set yet, the given channel width is saved and w...
Ptr< OfdmaSpectrumWifiPhy > m_phyAp
PHY of AP.
void RxFailureSta1(Ptr< WifiPsdu > psdu)
Receive failure function for STA 1.
a unique identifier for an interface.
Definition: type-id.h:58
uint8_t m_txPowerLevels
number of transmission power levels for STAs
void ConfigureStandardAndBand(WifiPhyStandard standard, WifiPhyBand band) override
Configure the PHY-level parameters for different Wi-Fi standard.
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
void SetRu(HeRu::RuSpec ru, uint16_t staId)
Set the RU specification for the STA-ID.
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:1172
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
#define SU_STA_ID
Definition: wifi-mode.h:32
static const uint16_t DEFAULT_GUARD_WIDTH
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
uint64_t m_ppduUidSta1
UID of PPDU transmitted by STA1.
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
void DoRun(void) override
Implementation to actually run this TestCase.
void SetPpduUid(uint64_t uid)
Set the global PPDU UID counter.
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Definition: wifi-phy.cc:2298
static WifiPhyOfdmaTestSuite wifiPhyOfdmaTestSuite
the test suite
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Implements the IEEE 802.11 MAC header.
void DoRxHeTbPpduOfdmaPart(Ptr< WifiSpectrumSignalParameters > rxParamsOfdma)
Receive OFDMA part of HE TB PPDU function.
Ptr< OfdmaSpectrumWifiPhy > m_phySta1
PHY of STA 1.
void CreateWifiSpectrumPhyInterface(Ptr< NetDevice > device)
Method to encapsulate the creation of the WifiSpectrumPhyInterface object (used to bind the WifiSpect...
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=true, WifiPhyState expectedStateBeforeEnd=WifiPhyState::RX)
Schedule test to perform.
void SetUlDcm(bool dcm)
Set the UL DCM subfield, which indicates whether or not DCM is used.
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
uint16_t m_frequency
frequency in MHz
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
virtual WifiPpduType GetType(void) const
Return the PPDU type (.
Definition: wifi-ppdu.cc:141
static const uint32_t DEFAULT_FREQUENCY
Make it easy to create and manage PHY objects for the spectrum model.