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
56 static const uint16_t DEFAULT_CHANNEL_WIDTH = 20; // MHz
57 static const uint16_t DEFAULT_GUARD_WIDTH = DEFAULT_CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
58 
63 class OfdmaTestHePhy : public HePhy
64 {
65 public:
71  OfdmaTestHePhy (uint16_t staId);
72  virtual ~OfdmaTestHePhy ();
73 
81  uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const override;
82 
88  void SetGlobalPpduUid (uint64_t uid);
89 
90 private:
91  uint16_t m_staId;
92 }; //class OfdmaTestHePhy
93 
95  : HePhy (),
96  m_staId (staId)
97 {
98 }
99 
101 {
102 }
103 
104 uint16_t
106 {
107  if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
108  {
109  return m_staId;
110  }
111  return HePhy::GetStaId (ppdu);
112 }
113 
114 void
116 {
117  m_globalPpduUid = uid;
118 }
119 
124 {
125 public:
130  static TypeId GetTypeId (void);
136  OfdmaSpectrumWifiPhy (uint16_t staId);
137  virtual ~OfdmaSpectrumWifiPhy ();
138 
139  // Inherited
140  virtual void DoInitialize (void) override;
141  virtual 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 
172  void SetTriggerFrameUid (uint64_t uid);
173 
177  std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > & GetCurrentPreambleEvents (void);
182 
193  Time GetEnergyDuration (double energyW, WifiSpectrumBand band);
194 
198  Ptr<const HePhy> GetHePhy (void) const;
199 
200 private:
203 }; //class OfdmaSpectrumWifiPhy
204 
205 TypeId
207 {
208  static TypeId tid = TypeId ("ns3::OfdmaSpectrumWifiPhy")
210  .SetGroupName ("Wifi")
211  .AddTraceSource ("TxPpduUid",
212  "UID of the PPDU to be transmitted",
214  "ns3::OfdmaSpectrumWifiPhy::TxPpduUidCallback")
215  ;
216  return tid;
217 }
218 
220  : SpectrumWifiPhy ()
221 {
222  m_ofdmTestHePhy = Create<OfdmaTestHePhy> (staId);
223  m_ofdmTestHePhy->SetOwner (this);
224 }
225 
227 {
228 }
229 
230 void
232 {
233  //Replace HE PHY instance with test instance
235  SpectrumWifiPhy::DoInitialize ();
236 }
237 
238 void
240 {
241  m_ofdmTestHePhy = 0;
242  SpectrumWifiPhy::DoDispose ();
243 }
244 
245 void
247 {
249  m_previouslyRxPpduUid = uid;
250 }
251 
252 void
254 {
255  m_previouslyRxPpduUid = uid;
256 }
257 
258 void
260 {
261  m_phyTxPpduUidTrace (ppdu->GetUid ());
262  SpectrumWifiPhy::StartTx (ppdu);
263 }
264 
265 std::map <std::pair<uint64_t, WifiPreamble>, Ptr<Event> > &
267 {
269 }
270 
271 uint16_t
272 OfdmaSpectrumWifiPhy::GetGuardBandwidth (uint16_t currentChannelWidth) const
273 {
274  // return a small enough value to avoid having too much out of band transmission
275  // knowing that slopes are not configurable yet.
276  return 1;
277 }
278 
281 {
282  return m_currentEvent;
283 }
284 
285 Time
287 {
288  return m_interference.GetEnergyDuration (energyW, band);
289 }
290 
293 {
294  return DynamicCast<const HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE));
295 }
296 
304 {
305 public:
307  virtual ~TestDlOfdmaPhyTransmission ();
308 
309 private:
310  virtual void DoSetup (void);
311  virtual void DoTeardown (void);
312  virtual void DoRun (void);
313 
321  void RxSuccessSta1 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
322  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
330  void RxSuccessSta2 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
331  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
339  void RxSuccessSta3 (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
340  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
341 
346  void RxFailureSta1 (Ptr<WifiPsdu> psdu);
351  void RxFailureSta2 (Ptr<WifiPsdu> psdu);
356  void RxFailureSta3 (Ptr<WifiPsdu> psdu);
357 
364  void CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
371  void CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
378  void CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
379 
383  void ResetResults ();
384 
390  void SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2);
391 
397  void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
401  void StopInterference (void);
402 
406  void RunOne ();
407 
420 
430 
436 
437  uint16_t m_frequency;
438  uint16_t m_channelWidth;
440 };
441 
443  : TestCase ("DL-OFDMA PHY test"),
444  m_countRxSuccessSta1 (0),
445  m_countRxSuccessSta2 (0),
446  m_countRxSuccessSta3 (0),
447  m_countRxFailureSta1 (0),
448  m_countRxFailureSta2 (0),
449  m_countRxFailureSta3 (0),
450  m_countRxBytesSta1 (0),
451  m_countRxBytesSta2 (0),
452  m_countRxBytesSta3 (0),
453  m_frequency (DEFAULT_FREQUENCY),
454  m_channelWidth (DEFAULT_CHANNEL_WIDTH),
455  m_expectedPpduDuration (NanoSeconds (306400))
456 {
457 }
458 
459 void
461 {
468  m_countRxBytesSta1 = 0;
469  m_countRxBytesSta2 = 0;
470  m_countRxBytesSta3 = 0;
471 }
472 
473 void
474 TestDlOfdmaPhyTransmission::SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2)
475 {
476  NS_LOG_FUNCTION (this << rxStaId1 << rxStaId2);
477  WifiConstPsduMap psdus;
478  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_MU, 800, 1, 1, 0, m_channelWidth, false, false);
479  HeRu::RuType ruType = HeRu::RU_106_TONE;
480  if (m_channelWidth == 20)
481  {
482  ruType = HeRu::RU_106_TONE;
483  }
484  else if (m_channelWidth == 40)
485  {
486  ruType = HeRu::RU_242_TONE;
487  }
488  else if (m_channelWidth == 80)
489  {
490  ruType = HeRu::RU_484_TONE;
491  }
492  else if (m_channelWidth == 160)
493  {
494  ruType = HeRu::RU_996_TONE;
495  }
496  else
497  {
498  NS_ASSERT_MSG (false, "Unsupported channel width");
499  }
500 
501  HeRu::RuSpec ru1;
502  ru1.primary80MHz = true;
503  ru1.ruType = ruType;
504  ru1.index = 1;
505  txVector.SetRu (ru1, rxStaId1);
506  txVector.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
507  txVector.SetNss (1, rxStaId1);
508 
509  HeRu::RuSpec ru2;
510  ru2.primary80MHz = (m_channelWidth == 160) ? false : true;
511  ru2.ruType = ruType;
512  ru2.index = 2;
513  txVector.SetRu (ru2, rxStaId2);
514  txVector.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
515  txVector.SetNss (1, rxStaId2);
516 
517  Ptr<Packet> pkt1 = Create<Packet> (1000);
518  WifiMacHeader hdr1;
519  hdr1.SetType (WIFI_MAC_QOSDATA);
520  hdr1.SetQosTid (0);
521  hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:01"));
522  hdr1.SetSequenceNumber (1);
523  Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
524  psdus.insert (std::make_pair (rxStaId1, psdu1));
525 
526  Ptr<Packet> pkt2 = Create<Packet> (1500);
527  WifiMacHeader hdr2;
528  hdr2.SetType (WIFI_MAC_QOSDATA);
529  hdr2.SetQosTid (0);
530  hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
531  hdr2.SetSequenceNumber (2);
532  Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
533  psdus.insert (std::make_pair (rxStaId2, psdu2));
534 
535  m_phyAp->Send (psdus, txVector);
536 }
537 
538 void
540 {
541  m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
542  m_phyInterferer->SetPeriod (duration);
544  Simulator::Schedule (duration, &TestDlOfdmaPhyTransmission::StopInterference, this);
545 }
546 
547 void
549 {
551 }
552 
554 {
555 }
556 
557 void
559  WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
560 {
561  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
563  m_countRxBytesSta1 += (psdu->GetSize () - 30);
564 }
565 
566 void
568  WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
569 {
570  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
572  m_countRxBytesSta2 += (psdu->GetSize () - 30);
573 }
574 
575 void
577  WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
578 {
579  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
581  m_countRxBytesSta3 += (psdu->GetSize () - 30);
582 }
583 
584 void
586 {
587  NS_LOG_FUNCTION (this << *psdu);
589 }
590 
591 void
593 {
594  NS_LOG_FUNCTION (this << *psdu);
596 }
597 
598 void
600 {
601  NS_LOG_FUNCTION (this << *psdu);
603 }
604 
605 void
606 TestDlOfdmaPhyTransmission::CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
607 {
608  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta1, expectedRxSuccess, "The number of successfully received packets by STA 1 is not correct!");
609  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta1, expectedRxFailure, "The number of unsuccessfully received packets by STA 1 is not correct!");
610  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta1, expectedRxBytes, "The number of bytes received by STA 1 is not correct!");
611 }
612 
613 void
614 TestDlOfdmaPhyTransmission::CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
615 {
616  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta2, expectedRxSuccess, "The number of successfully received packets by STA 2 is not correct!");
617  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta2, expectedRxFailure, "The number of unsuccessfully received packets by STA 2 is not correct!");
618  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta2, expectedRxBytes, "The number of bytes received by STA 2 is not correct!");
619 }
620 
621 void
622 TestDlOfdmaPhyTransmission::CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
623 {
624  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta3, expectedRxSuccess, "The number of successfully received packets by STA 3 is not correct!");
625  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta3, expectedRxFailure, "The number of unsuccessfully received packets by STA 3 is not correct!");
626  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta3, expectedRxBytes, "The number of bytes received by STA 3 is not correct!");
627 }
628 
629 void
631 {
632  //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
633  Simulator::ScheduleNow (&TestDlOfdmaPhyTransmission::DoCheckPhyState, this, phy, expectedState);
634 }
635 
636 void
638 {
639  WifiPhyState currentState;
640  PointerValue ptr;
641  phy->GetAttribute ("State", ptr);
642  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
643  currentState = state->GetState ();
644  NS_LOG_FUNCTION (this << currentState);
645  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
646 }
647 
648 void
650 {
651  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
652  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
653  lossModel->SetFrequency (m_frequency * 1e6);
654  spectrumChannel->AddPropagationLossModel (lossModel);
655  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
656  spectrumChannel->SetPropagationDelayModel (delayModel);
657 
658  Ptr<Node> apNode = CreateObject<Node> ();
659  Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
660  m_phyAp = CreateObject<SpectrumWifiPhy> ();
663  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
664  m_phyAp->SetErrorRateModel (error);
665  m_phyAp->SetDevice (apDev);
666  m_phyAp->SetChannel (spectrumChannel);
667  Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
668  m_phyAp->SetMobility (apMobility);
669  apDev->SetPhy (m_phyAp);
670  apNode->AggregateObject (apMobility);
671  apNode->AddDevice (apDev);
672 
673  Ptr<Node> sta1Node = CreateObject<Node> ();
674  Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
675  m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
678  m_phySta1->SetErrorRateModel (error);
679  m_phySta1->SetDevice (sta1Dev);
680  m_phySta1->SetChannel (spectrumChannel);
683  Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
684  m_phySta1->SetMobility (sta1Mobility);
685  sta1Dev->SetPhy (m_phySta1);
686  sta1Node->AggregateObject (sta1Mobility);
687  sta1Node->AddDevice (sta1Dev);
688 
689  Ptr<Node> sta2Node = CreateObject<Node> ();
690  Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
691  m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
694  m_phySta2->SetErrorRateModel (error);
695  m_phySta2->SetDevice (sta2Dev);
696  m_phySta2->SetChannel (spectrumChannel);
699  Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
700  m_phySta2->SetMobility (sta2Mobility);
701  sta2Dev->SetPhy (m_phySta2);
702  sta2Node->AggregateObject (sta2Mobility);
703  sta2Node->AddDevice (sta2Dev);
704 
705  Ptr<Node> sta3Node = CreateObject<Node> ();
706  Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice> ();
707  m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy> (3);
710  m_phySta3->SetErrorRateModel (error);
711  m_phySta3->SetDevice (sta3Dev);
712  m_phySta3->SetChannel (spectrumChannel);
715  Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel> ();
716  m_phySta3->SetMobility (sta3Mobility);
717  sta3Dev->SetPhy (m_phySta3);
718  sta3Node->AggregateObject (sta3Mobility);
719  sta3Node->AddDevice (sta3Dev);
720 
721  Ptr<Node> interfererNode = CreateObject<Node> ();
722  Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
723  m_phyInterferer = CreateObject<WaveformGenerator> ();
724  m_phyInterferer->SetDevice (interfererDev);
725  m_phyInterferer->SetChannel (spectrumChannel);
727  interfererNode->AddDevice (interfererDev);
728 }
729 
730 void
732 {
733  m_phyAp->Dispose ();
734  m_phyAp = 0;
735  m_phySta1->Dispose ();
736  m_phySta1 = 0;
737  m_phySta2->Dispose ();
738  m_phySta2 = 0;
739  m_phySta3->Dispose ();
740  m_phySta3 = 0;
742  m_phyInterferer = 0;
743 }
744 
745 void
747 {
748  RngSeedManager::SetSeed (1);
749  RngSeedManager::SetRun (1);
750  int64_t streamNumber = 0;
751  m_phyAp->AssignStreams (streamNumber);
752  m_phySta1->AssignStreams (streamNumber);
753  m_phySta2->AssignStreams (streamNumber);
754  m_phySta3->AssignStreams (streamNumber);
755 
758 
761 
764 
767 
768  Simulator::Schedule (Seconds (0.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
769 
770  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
771  //Each STA should receive its PSDU.
772  Simulator::Schedule (Seconds (1.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
773 
774  //Since it takes m_expectedPpduDuration to transmit the PPDU,
775  //all 3 PHYs should be back to IDLE at the same time,
776  //even the PHY that has no PSDU addressed to it.
783 
784  //One PSDU of 1000 bytes should have been successfully received by STA 1
785  Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
786  //One PSDU of 1500 bytes should have been successfully received by STA 2
787  Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 1, 0, 1500);
788  //No PSDU should have been received by STA 3
789  Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
790 
791  Simulator::Schedule (Seconds (1.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
792 
793  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 3:
794  //STA 1 should receive its PSDU, whereas STA 2 should not receive any PSDU
795  //but should keep its PHY busy during all PPDU duration.
796  Simulator::Schedule (Seconds (2.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 3);
797 
798  //Since it takes m_expectedPpduDuration to transmit the PPDU,
799  //all 3 PHYs should be back to IDLE at the same time,
800  //even the PHY that has no PSDU addressed to it.
807 
808  //One PSDU of 1000 bytes should have been successfully received by STA 1
809  Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
810  //No PSDU should have been received by STA 2
811  Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 0, 0);
812  //One PSDU of 1500 bytes should have been successfully received by STA 3
813  Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 1, 0, 1500);
814 
815  Simulator::Schedule (Seconds (2.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
816 
817  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
818  Simulator::Schedule (Seconds (3.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
819 
820  //A strong non-wifi interference is generated on RU 1 during PSDU reception
821  BandInfo bandInfo;
822  bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
823  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
824  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
825  Bands bands;
826  bands.push_back (bandInfo);
827 
828  Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
829  Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
830  double interferencePower = 0.1; //watts
831  *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
832 
833  Simulator::Schedule (Seconds (3.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
834 
835  //Since it takes m_expectedPpduDuration to transmit the PPDU,
836  //both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
837  //even the PHY that has no PSDU addressed to it.
844 
845  //One PSDU of 1000 bytes should have been unsuccessfully received by STA 1 (since interference occupies RU 1)
846  Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 0, 1, 0);
847  //One PSDU of 1500 bytes should have been successfully received by STA 2
848  Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 1, 0, 1500);
849  //No PSDU should have been received by STA3
850  Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
851 
852  Simulator::Schedule (Seconds (3.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
853 
854  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
855  Simulator::Schedule (Seconds (4.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
856 
857  //A strong non-wifi interference is generated on RU 2 during PSDU reception
858  bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
859  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
860  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
861  bands.clear ();
862  bands.push_back (bandInfo);
863 
864  Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel> (bands);
865  Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue> (SpectrumInterferenceRu2);
866  *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
867 
868  Simulator::Schedule (Seconds (4.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
869 
870  //Since it takes m_expectedPpduDuration to transmit the PPDU,
871  //both PHYs should be back to IDLE (or CCA_BUSY if interference on the primary 20 MHz) at the same time,
872  //even the PHY that has no PSDU addressed to it.
879 
880  //One PSDU of 1000 bytes should have been successfully received by STA 1
881  Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
882  //One PSDU of 1500 bytes should have been unsuccessfully received by STA 2 (since interference occupies RU 2)
883  Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 1, 0);
884  //No PSDU should have been received by STA3
885  Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
886 
887  Simulator::Schedule (Seconds (4.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
888 
889  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
890  Simulator::Schedule (Seconds (5.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
891 
892  //A strong non-wifi interference is generated on the full band during PSDU reception
893  bandInfo.fc = m_frequency * 1e6;
894  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
895  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
896  bands.clear ();
897  bands.push_back (bandInfo);
898 
899  Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel> (bands);
900  Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue> (SpectrumInterferenceAll);
901  *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
902 
903  Simulator::Schedule (Seconds (5.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
904 
905  //Since it takes m_expectedPpduDuration to transmit the PPDU,
906  //both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
907  //even the PHY that has no PSDU addressed to it.
914 
915  //One PSDU of 1000 bytes should have been unsuccessfully received by STA 1 (since interference occupies RU 1)
916  Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 0, 1, 0);
917  //One PSDU of 1500 bytes should have been unsuccessfully received by STA 2 (since interference occupies RU 2)
918  Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 1, 0);
919  //No PSDU should have been received by STA3
920  Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
921 
922  Simulator::Schedule (Seconds (5.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
923 
924  Simulator::Run ();
925 }
926 
927 void
929 {
930  m_frequency = 5180;
931  m_channelWidth = 20;
933  RunOne ();
934 
935  m_frequency = 5190;
936  m_channelWidth = 40;
938  RunOne ();
939 
940  m_frequency = 5210;
941  m_channelWidth = 80;
943  RunOne ();
944 
945  m_frequency = 5250;
946  m_channelWidth = 160;
948  RunOne ();
949 
950  Simulator::Destroy ();
951 }
952 
953 
961 {
962 public:
964  virtual ~TestUlOfdmaPpduUid ();
965 
966 private:
967  virtual void DoSetup (void);
968  virtual void DoTeardown (void);
969  virtual void DoRun (void);
970 
975  void TxPpduAp (uint64_t uid);
980  void TxPpduSta1 (uint64_t uid);
985  void TxPpduSta2 (uint64_t uid);
989  void ResetPpduUid (void);
990 
994  void SendMuPpdu (void);
998  void SendTbPpdu (void);
1003  void SendSuPpdu (uint16_t txStaId);
1004 
1010  void CheckUid (uint16_t staId, uint64_t expectedUid);
1011 
1015 
1016  uint64_t m_ppduUidAp;
1017  uint64_t m_ppduUidSta1;
1018  uint64_t m_ppduUidSta2;
1019 };
1020 
1022  : TestCase ("UL-OFDMA PPDU UID attribution test"),
1023  m_ppduUidAp (UINT64_MAX),
1024  m_ppduUidSta1 (UINT64_MAX),
1025  m_ppduUidSta2 (UINT64_MAX)
1026 {
1027 }
1028 
1030 {
1031 }
1032 
1033 void
1035 {
1036  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
1037  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
1038  lossModel->SetFrequency (DEFAULT_FREQUENCY);
1039  spectrumChannel->AddPropagationLossModel (lossModel);
1040  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
1041  spectrumChannel->SetPropagationDelayModel (delayModel);
1042 
1043  Ptr<Node> apNode = CreateObject<Node> ();
1044  Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
1045  m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
1048  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1049  m_phyAp->SetErrorRateModel (error);
1052  m_phyAp->SetDevice (apDev);
1053  m_phyAp->SetChannel (spectrumChannel);
1055  Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
1056  m_phyAp->SetMobility (apMobility);
1057  apDev->SetPhy (m_phyAp);
1058  apNode->AggregateObject (apMobility);
1059  apNode->AddDevice (apDev);
1060 
1061  Ptr<Node> sta1Node = CreateObject<Node> ();
1062  Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
1063  m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
1066  m_phySta1->SetErrorRateModel (error);
1069  m_phySta1->SetDevice (sta1Dev);
1070  m_phySta1->SetChannel (spectrumChannel);
1072  Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
1073  m_phySta1->SetMobility (sta1Mobility);
1074  sta1Dev->SetPhy (m_phySta1);
1075  sta1Node->AggregateObject (sta1Mobility);
1076  sta1Node->AddDevice (sta1Dev);
1077 
1078  Ptr<Node> sta2Node = CreateObject<Node> ();
1079  Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
1080  m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
1083  m_phySta2->SetErrorRateModel (error);
1086  m_phySta2->SetDevice (sta2Dev);
1087  m_phySta2->SetChannel (spectrumChannel);
1089  Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
1090  m_phySta2->SetMobility (sta2Mobility);
1091  sta2Dev->SetPhy (m_phySta2);
1092  sta2Node->AggregateObject (sta2Mobility);
1093  sta2Node->AddDevice (sta2Dev);
1094 }
1095 
1096 void
1098 {
1099  m_phyAp->Dispose ();
1100  m_phyAp = 0;
1101  m_phySta1->Dispose ();
1102  m_phySta1 = 0;
1103  m_phySta2->Dispose ();
1104  m_phySta2 = 0;
1105 }
1106 
1107 void
1108 TestUlOfdmaPpduUid::CheckUid (uint16_t staId, uint64_t expectedUid)
1109 {
1110  uint64_t uid;
1111  std::string device;
1112  switch (staId)
1113  {
1114  case 0:
1115  uid = m_ppduUidAp;
1116  device = "AP";
1117  break;
1118  case 1:
1119  uid = m_ppduUidSta1;
1120  device = "STA1";
1121  break;
1122  case 2:
1123  uid = m_ppduUidSta2;
1124  device = "STA2";
1125  break;
1126  default:
1127  NS_ABORT_MSG ("Unexpected STA-ID");
1128  }
1129  NS_TEST_ASSERT_MSG_EQ (uid, expectedUid, "UID " << uid << " does not match expected one " << expectedUid << " for " << device << " at " << Simulator::Now ());
1130 }
1131 
1132 void
1134 {
1135  NS_LOG_FUNCTION (this << uid);
1136  m_ppduUidAp = uid;
1137 }
1138 
1139 void
1141 {
1142  NS_LOG_FUNCTION (this << uid);
1143  m_ppduUidSta1 = uid;
1144 }
1145 
1146 void
1148 {
1149  NS_LOG_FUNCTION (this << uid);
1150  m_ppduUidSta2 = uid;
1151 }
1152 
1153 void
1155 {
1156  NS_LOG_FUNCTION (this);
1157  m_phyAp->SetPpduUid (0); //one is enough since it's a global attribute
1158  return;
1159 }
1160 
1161 void
1163 {
1164  WifiConstPsduMap psdus;
1165  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_MU, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1166 
1167  uint16_t rxStaId1 = 1;
1168  HeRu::RuSpec ru1;
1169  ru1.primary80MHz = false;
1170  ru1.ruType = HeRu::RU_106_TONE;
1171  ru1.index = 1;
1172  txVector.SetRu (ru1, rxStaId1);
1173  txVector.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
1174  txVector.SetNss (1, rxStaId1);
1175 
1176  uint16_t rxStaId2 = 2;
1177  HeRu::RuSpec ru2;
1178  ru2.primary80MHz = false;
1179  ru2.ruType = HeRu::RU_106_TONE;
1180  ru2.index = 2;
1181  txVector.SetRu (ru2, rxStaId2);
1182  txVector.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
1183  txVector.SetNss (1, rxStaId2);
1184 
1185  Ptr<Packet> pkt1 = Create<Packet> (1000);
1186  WifiMacHeader hdr1;
1187  hdr1.SetType (WIFI_MAC_QOSDATA);
1188  hdr1.SetQosTid (0);
1189  hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:01"));
1190  hdr1.SetSequenceNumber (1);
1191  Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
1192  psdus.insert (std::make_pair (rxStaId1, psdu1));
1193 
1194  Ptr<Packet> pkt2 = Create<Packet> (1500);
1195  WifiMacHeader hdr2;
1196  hdr2.SetType (WIFI_MAC_QOSDATA);
1197  hdr2.SetQosTid (0);
1198  hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
1199  hdr2.SetSequenceNumber (2);
1200  Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
1201  psdus.insert (std::make_pair (rxStaId2, psdu2));
1202 
1203  m_phyAp->Send (psdus, txVector);
1204 }
1205 
1206 void
1208 {
1209  WifiConstPsduMap psdus1;
1210  WifiConstPsduMap psdus2;
1211  WifiTxVector txVector1 = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1212  WifiTxVector txVector2 = txVector1;
1213 
1214  uint16_t rxStaId1 = 1;
1215  HeRu::RuSpec ru1;
1216  ru1.primary80MHz = false;
1217  ru1.ruType = HeRu::RU_106_TONE;
1218  ru1.index = 1;
1219  txVector1.SetRu (ru1, rxStaId1);
1220  txVector1.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
1221  txVector1.SetNss (1, rxStaId1);
1222 
1223  Ptr<Packet> pkt1 = Create<Packet> (1000);
1224  WifiMacHeader hdr1;
1225  hdr1.SetType (WIFI_MAC_QOSDATA);
1226  hdr1.SetQosTid (0);
1227  hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1228  hdr1.SetSequenceNumber (1);
1229  Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
1230  psdus1.insert (std::make_pair (rxStaId1, psdu1));
1231 
1232  uint16_t rxStaId2 = 2;
1233  HeRu::RuSpec ru2;
1234  ru2.primary80MHz = false;
1235  ru2.ruType = HeRu::RU_106_TONE;
1236  ru2.index = 2;
1237  txVector2.SetRu (ru2, rxStaId2);
1238  txVector2.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
1239  txVector2.SetNss (1, rxStaId2);
1240 
1241  Ptr<Packet> pkt2 = Create<Packet> (1500);
1242  WifiMacHeader hdr2;
1243  hdr2.SetType (WIFI_MAC_QOSDATA);
1244  hdr2.SetQosTid (0);
1245  hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1246  hdr2.SetSequenceNumber (2);
1247  Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
1248  psdus2.insert (std::make_pair (rxStaId2, psdu2));
1249 
1250  Time txDuration1 = m_phySta1->CalculateTxDuration (psdu1->GetSize (), txVector1,
1251  m_phySta1->GetPhyBand (), rxStaId1);
1252  Time txDuration2 = m_phySta2->CalculateTxDuration (psdu2->GetSize (), txVector2,
1253  m_phySta1->GetPhyBand (), rxStaId2);
1254  Time txDuration = std::max (txDuration1, txDuration2);
1255 
1256  txVector1.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta1->GetPhyBand ()));
1257  txVector2.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta2->GetPhyBand ()));
1258 
1259  m_phySta1->Send (psdus1, txVector1);
1260  m_phySta2->Send (psdus2, txVector2);
1261 }
1262 
1263 void
1265 {
1266  WifiConstPsduMap psdus;
1267  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1268 
1269  Ptr<Packet> pkt = Create<Packet> (1000);
1270  WifiMacHeader hdr;
1271  hdr.SetType (WIFI_MAC_QOSDATA);
1272  hdr.SetQosTid (0);
1273  hdr.SetAddr1 (Mac48Address::GetBroadcast ());
1274  hdr.SetSequenceNumber (1);
1275  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1276  psdus.insert (std::make_pair (SU_STA_ID, psdu));
1277 
1278  switch (txStaId)
1279  {
1280  case 0:
1281  m_phyAp->Send (psdus, txVector);
1282  break;
1283  case 1:
1284  m_phySta1->Send (psdus, txVector);
1285  break;
1286  case 2:
1287  m_phySta2->Send (psdus, txVector);
1288  break;
1289  default:
1290  NS_ABORT_MSG ("Unexpected STA-ID");
1291  }
1292 }
1293 
1294 void
1296 {
1297  RngSeedManager::SetSeed (1);
1298  RngSeedManager::SetRun (1);
1299  int64_t streamNumber = 0;
1300  m_phyAp->AssignStreams (streamNumber);
1301  m_phySta1->AssignStreams (streamNumber);
1302  m_phySta2->AssignStreams (streamNumber);
1303 
1304  //Reset PPDU UID so as not to be dependent on previously executed test cases,
1305  //since global attribute will be changed).
1306  ResetPpduUid ();
1307 
1308  //Send HE MU PPDU with two PSDUs addressed to STA 1 and STA 2.
1309  //PPDU UID should be equal to 0 (the first counter value).
1310  Simulator::Schedule (Seconds (1.0), &TestUlOfdmaPpduUid::SendMuPpdu, this);
1311  Simulator::Schedule (Seconds (1.0), &TestUlOfdmaPpduUid::CheckUid, this, 0, 0);
1312 
1313  //Send HE SU PPDU from AP.
1314  //PPDU UID should be incremented since this is a new PPDU.
1315  Simulator::Schedule (Seconds (1.1), &TestUlOfdmaPpduUid::SendSuPpdu, this, 0);
1316  Simulator::Schedule (Seconds (1.1), &TestUlOfdmaPpduUid::CheckUid, this, 0, 1);
1317 
1318  //Send HE TB PPDU from STAs to AP.
1319  //PPDU UID should NOT be incremented since HE TB PPDUs reuse the UID of the immediately
1320  //preceding correctly received PPDU (which normally contains the trigger frame).
1321  Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::SendTbPpdu, this);
1322  Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::CheckUid, this, 1, 1);
1323  Simulator::Schedule (Seconds (1.15), &TestUlOfdmaPpduUid::CheckUid, this, 2, 1);
1324 
1325  //Send HE SU PPDU from STA1.
1326  //PPDU UID should be incremented since this is a new PPDU.
1327  Simulator::Schedule (Seconds (1.2), &TestUlOfdmaPpduUid::SendSuPpdu, this, 1);
1328  Simulator::Schedule (Seconds (1.2), &TestUlOfdmaPpduUid::CheckUid, this, 1, 2);
1329 
1330  Simulator::Run ();
1331  Simulator::Destroy ();
1332 }
1333 
1341 {
1342 public:
1344  virtual ~TestMultipleHeTbPreambles ();
1345 
1346 private:
1347  virtual void DoSetup (void);
1348  virtual void DoTeardown (void);
1349  virtual void DoRun (void);
1350 
1359  void RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize);
1360 
1375 
1382 
1386  void Reset (void);
1387 
1393  void CheckHeTbPreambles (size_t nEvents, std::vector <uint64_t> uids);
1394 
1399  void CheckBytesDropped (size_t expectedBytesDropped);
1400 
1402 
1404 };
1405 
1407  : TestCase ("UL-OFDMA multiple RX events test"),
1408  m_totalBytesDropped (0)
1409 {
1410 }
1411 
1413 {
1414 }
1415 
1416 void
1418 {
1419  NS_LOG_FUNCTION (this);
1420  m_totalBytesDropped = 0;
1421  //We have to reset PHY here since we do not trigger OFDMA payload RX event in this test
1422  m_phy->Reset ();
1423 }
1424 
1425 void
1427 {
1428  NS_LOG_FUNCTION (this << p << reason);
1429  m_totalBytesDropped += (p->GetSize () - 30);
1430 }
1431 
1432 void
1433 TestMultipleHeTbPreambles::CheckHeTbPreambles (size_t nEvents, std::vector <uint64_t> uids)
1434 {
1435  auto events = m_phy->GetCurrentPreambleEvents ();
1436  NS_TEST_ASSERT_MSG_EQ (events.size (), nEvents, "The number of UL MU events is not correct!");
1437  for (auto const& uid : uids)
1438  {
1439  auto pair = std::make_pair (uid, WIFI_PREAMBLE_HE_TB);
1440  auto it = events.find (pair);
1441  bool found = (it != events.end ());
1442  NS_TEST_ASSERT_MSG_EQ (found, true, "HE TB PPDU with UID " << uid << " has not been received!");
1443  }
1444 }
1445 
1446 void
1448 {
1449  NS_TEST_ASSERT_MSG_EQ (m_totalBytesDropped, expectedBytesDropped, "The number of dropped bytes is not correct!");
1450 }
1451 
1452 void
1453 TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize)
1454 {
1455  WifiConstPsduMap psdus;
1456  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
1457 
1458  HeRu::RuSpec ru;
1459  ru.primary80MHz = false;
1460  ru.ruType = HeRu::RU_106_TONE;
1461  ru.index = staId;
1462  txVector.SetRu (ru, staId);
1463  txVector.SetMode (HePhy::GetHeMcs7 (), staId);
1464  txVector.SetNss (1, staId);
1465 
1466  Ptr<Packet> pkt = Create<Packet> (payloadSize);
1467  WifiMacHeader hdr;
1468  hdr.SetType (WIFI_MAC_QOSDATA);
1469  hdr.SetQosTid (0);
1470  hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1471  hdr.SetSequenceNumber (1);
1472  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1473  psdus.insert (std::make_pair (staId, psdu));
1474 
1475  Time ppduDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand (), staId);
1476  Ptr<HePpdu> ppdu = Create<HePpdu> (psdus, txVector, ppduDuration, WIFI_PHY_BAND_5GHZ, uid,
1477  HePpdu::PSD_HE_TB_NON_OFDMA_PORTION);
1478 
1479  //Send non-OFDMA part
1480  Time nonOfdmaDuration = m_phy->GetHePhy ()->CalculateNonOfdmaDurationForHeTb (txVector);
1481  uint32_t centerFrequency = m_phy->GetHePhy ()->GetCenterFrequencyForNonOfdmaPart (txVector, staId);
1482  uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
1483  uint16_t channelWidth = ruWidth < 20 ? 20 : ruWidth;
1484  Ptr<SpectrumValue> rxPsd = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerWatts, m_phy->GetGuardBandwidth (channelWidth));
1485  Ptr<WifiSpectrumSignalParameters> rxParams = Create<WifiSpectrumSignalParameters> ();
1486  rxParams->psd = rxPsd;
1487  rxParams->txPhy = 0;
1488  rxParams->duration = nonOfdmaDuration;
1489  rxParams->ppdu = ppdu;
1490 
1491  m_phy->StartRx (rxParams);
1492 
1493  //Schedule OFDMA part
1494  Ptr<HePpdu> ppduOfdma = DynamicCast<HePpdu> (ppdu->Copy ()); //since flag will be modified
1495  ppduOfdma->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
1496  WifiSpectrumBand band = m_phy->GetHePhy ()->GetRuBandForRx (txVector, staId);
1497  Ptr<SpectrumValue> rxPsdOfdma = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (DEFAULT_FREQUENCY, DEFAULT_CHANNEL_WIDTH, txPowerWatts, DEFAULT_GUARD_WIDTH, band);
1498  Ptr<WifiSpectrumSignalParameters> rxParamsOfdma = Create<WifiSpectrumSignalParameters> ();
1499  rxParamsOfdma->psd = rxPsd;
1500  rxParamsOfdma->txPhy = 0;
1501  rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration;
1502  rxParamsOfdma->ppdu = ppduOfdma;
1503  Simulator::Schedule (nonOfdmaDuration, &TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart, this, rxParamsOfdma);
1504 }
1505 
1506 void
1508 {
1509  Simulator::ScheduleNow (&TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart, this, rxParamsOfdma);
1510 }
1511 
1512 void
1514 {
1515  //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
1516  //For normal WifiNetDevices, this the reception of the OFDMA part is scheduled after end of HE-SIG-A decoding.
1517  m_phy->StartRx (rxParamsOfdma);
1518 }
1519 
1520 void
1522 {
1523  Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice> ();
1524  m_phy = CreateObject<OfdmaSpectrumWifiPhy> (0);
1526  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1527  Ptr<ApWifiMac> mac = CreateObject<ApWifiMac> ();
1528  mac->SetAttribute ("BeaconGeneration", BooleanValue (false));
1529  dev->SetMac (mac);
1530  m_phy->SetErrorRateModel (error);
1535  m_phy->SetDevice (dev);
1536  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1537  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
1538  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
1539  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1540 }
1541 
1542 void
1544 {
1545  m_phy->Dispose ();
1546  m_phy = 0;
1547 }
1548 
1549 void
1551 {
1552  RngSeedManager::SetSeed (1);
1553  RngSeedManager::SetRun (1);
1554  int64_t streamNumber = 0;
1555  m_phy->AssignStreams (streamNumber);
1556 
1557  double txPowerWatts = 0.01;
1558 
1559  {
1560  //Verify a single UL MU transmission with two stations belonging to the same BSS
1561  std::vector<uint64_t> uids {0};
1562  Simulator::Schedule (Seconds (1), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1563  Simulator::Schedule (Seconds (1) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1564  //Check that we received a single UL MU transmission with the corresponding UID
1565  Simulator::Schedule (Seconds (1.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, uids);
1566  Simulator::Schedule (Seconds (1.5), &TestMultipleHeTbPreambles::Reset, this);
1567  }
1568 
1569  {
1570  //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1571  //arrives during the preamble detection window and with half the power of the first transmission.
1572  std::vector<uint64_t> uids {1, 2};
1573  Simulator::Schedule (Seconds (2), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1574  Simulator::Schedule (Seconds (2) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1575  Simulator::Schedule (Seconds (2) + NanoSeconds (200), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts / 2, 1003);
1576  Simulator::Schedule (Seconds (2) + NanoSeconds (300), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts / 2, 1004);
1577  //Check that we received the correct reception of 2 UL MU transmissions with the corresponding UIDs
1578  Simulator::Schedule (Seconds (2.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 2, uids);
1579  Simulator::Schedule (Seconds (2.5), &TestMultipleHeTbPreambles::Reset, this);
1580  //TODO: verify PPDUs from second UL MU transmission are dropped
1581  }
1582 
1583  {
1584  //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1585  //arrives during the preamble detection window and with twice the power of the first transmission.
1586  std::vector<uint64_t> uids {3, 4};
1587  Simulator::Schedule (Seconds (3), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts / 2, 1001);
1588  Simulator::Schedule (Seconds (3) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts / 2, 1002);
1589  Simulator::Schedule (Seconds (3) + NanoSeconds (200), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1590  Simulator::Schedule (Seconds (3) + NanoSeconds (300), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1591  //Check that we received the correct reception of 2 UL MU transmissions with the corresponding UIDs
1592  Simulator::Schedule (Seconds (3.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 2, uids);
1593  Simulator::Schedule (Seconds (3.5), &TestMultipleHeTbPreambles::Reset, this);
1594  //TODO: verify PPDUs from first UL MU transmission are dropped
1595  }
1596 
1597  {
1598  //Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where the second transmission
1599  //arrives during PHY header reception and with the same power as the first transmission.
1600  std::vector<uint64_t> uids {5, 6};
1601  Simulator::Schedule (Seconds (4), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1602  Simulator::Schedule (Seconds (4) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1603  Simulator::Schedule (Seconds (4) + MicroSeconds (5), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1604  Simulator::Schedule (Seconds (4) + MicroSeconds (5) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1605  //Check that we received the correct reception of the first UL MU transmission with the corresponding UID (second one dropped)
1606  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, std::vector<uint64_t> {uids[0]});
1607  //The packets of the second UL MU transmission should have been dropped
1608  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1003 + 1004);
1609  Simulator::Schedule (Seconds (4.5), &TestMultipleHeTbPreambles::Reset, this);
1610  }
1611 
1612  {
1613  //Verify the correct reception of one UL MU transmission out of 2 with two stations per BSS, where the second transmission
1614  //arrives during payload reception and with the same power as the first transmission.
1615  std::vector<uint64_t> uids {7, 8};
1616  Simulator::Schedule (Seconds (5), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1617  Simulator::Schedule (Seconds (5) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1618  Simulator::Schedule (Seconds (5) + MicroSeconds (50), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 1, txPowerWatts, 1003);
1619  Simulator::Schedule (Seconds (5) + MicroSeconds (50) + NanoSeconds (100), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[1], 2, txPowerWatts, 1004);
1620  //Check that we received the correct reception of the first UL MU transmission with the corresponding UID (second one dropped)
1621  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, std::vector<uint64_t> {uids[0]});
1622  //The packets of the second UL MU transmission should have been dropped
1623  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1003 + 1004);
1624  Simulator::Schedule (Seconds (5.5), &TestMultipleHeTbPreambles::Reset, this);
1625  }
1626 
1627  {
1628  //Verify the correct reception of a single UL MU transmission with two stations belonging to the same BSS,
1629  //and the second PPDU arrives 500ns after the first PPDU, i.e. it exceeds the delay spread of 400ns
1630  std::vector<uint64_t> uids {9};
1631  Simulator::Schedule (Seconds (6), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 1, txPowerWatts, 1001);
1632  Simulator::Schedule (Seconds (6) + NanoSeconds (500), &TestMultipleHeTbPreambles::RxHeTbPpdu, this, uids[0], 2, txPowerWatts, 1002);
1633  //Check that we received a single UL MU transmission with the corresponding UID
1634  Simulator::Schedule (Seconds (6.0) + MicroSeconds (1), &TestMultipleHeTbPreambles::CheckHeTbPreambles, this, 1, uids);
1635  //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):
1636  //the second HE TB PPDU is acting as interference since it arrived after the maximum allowed 400ns.
1637  //Obviously, that second packet of 1002 bytes is dropped as well.
1638  Simulator::Schedule (Seconds (6.0) + MicroSeconds (5), &TestMultipleHeTbPreambles::CheckBytesDropped, this, 1001 + 1002);
1639  Simulator::Schedule (Seconds (6.5), &TestMultipleHeTbPreambles::Reset, this);
1640  }
1641 
1642  Simulator::Run ();
1643  Simulator::Destroy ();
1644 }
1645 
1653 {
1654 public:
1656  virtual ~TestUlOfdmaPhyTransmission ();
1657 
1658 private:
1659  virtual void DoSetup (void);
1660  virtual void DoTeardown (void);
1661  virtual void DoRun (void);
1662 
1669  WifiTxVector GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_t index, uint8_t bssColor) const;
1678  void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
1679 
1687  void SendHeSuPpdu (uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
1688 
1694  void SetBssColor (Ptr<WifiPhy> phy, uint8_t bssColor);
1695 
1701  void SetPsdLimit (Ptr<WifiPhy> phy, double psdLimit);
1702 
1708  void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
1712  void StopInterference (void);
1713 
1717  void RunOne ();
1718 
1725  void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
1726 
1733  void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
1734 
1741  void CheckNonOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower);
1748  void CheckOfdmaRxPower (Ptr<OfdmaSpectrumWifiPhy> phy, WifiSpectrumBand band, double expectedRxPower);
1749 
1753  void VerifyEventsCleared (void);
1754 
1762 
1766  void Reset ();
1767 
1775  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1776 
1781  void RxFailure (Ptr<WifiPsdu> psdu);
1782 
1799  void ScheduleTest (Time delay, bool solicited, WifiPhyState expectedStateAtEnd,
1800  uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1,
1801  uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2,
1802  bool scheduleTxSta1 = true, WifiPhyState expectedStateBeforeEnd = WifiPhyState::RX);
1803 
1813  void SchedulePowerMeasurementChecks (Time delay, double rxPowerNonOfdmaRu1, double rxPowerNonOfdmaRu2,
1814  double rxPowerOfdmaRu1, double rxPowerOfdmaRu2);
1820  void LogScenario (std::string log) const;
1821 
1826 
1828 
1835 
1836  uint16_t m_frequency;
1837  uint16_t m_channelWidth;
1839 };
1840 
1842  : TestCase ("UL-OFDMA PHY test"),
1843  m_countRxSuccessFromSta1 (0),
1844  m_countRxSuccessFromSta2 (0),
1845  m_countRxFailureFromSta1 (0),
1846  m_countRxFailureFromSta2 (0),
1847  m_countRxBytesFromSta1 (0),
1848  m_countRxBytesFromSta2 (0),
1849  m_frequency (DEFAULT_FREQUENCY),
1850  m_channelWidth (DEFAULT_CHANNEL_WIDTH),
1851  m_expectedPpduDuration (NanoSeconds (271200))
1852 {
1853 }
1854 
1855 void
1856 TestUlOfdmaPhyTransmission::SendHeSuPpdu (uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
1857 {
1858  NS_LOG_FUNCTION (this << txStaId << payloadSize << uid << +bssColor);
1859  WifiConstPsduMap psdus;
1860 
1861  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, m_channelWidth, false, false, false, bssColor);
1862 
1863  Ptr<Packet> pkt = Create<Packet> (payloadSize);
1864  WifiMacHeader hdr;
1865  hdr.SetType (WIFI_MAC_QOSDATA);
1866  hdr.SetQosTid (0);
1867  hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1868  std::ostringstream addr;
1869  addr << "00:00:00:00:00:0" << txStaId;
1870  hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
1871  hdr.SetSequenceNumber (1);
1872  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1873  psdus.insert (std::make_pair (SU_STA_ID, psdu));
1874 
1876  if (txStaId == 1)
1877  {
1878  phy = m_phySta1;
1879  }
1880  else if (txStaId == 2)
1881  {
1882  phy = m_phySta2;
1883  }
1884  else if (txStaId == 3)
1885  {
1886  phy = m_phySta3;
1887  }
1888  else if (txStaId == 0)
1889  {
1890  phy = m_phyAp;
1891  }
1892  phy->SetPpduUid (uid);
1893  phy->Send (psdus, txVector);
1894 }
1895 
1897 TestUlOfdmaPhyTransmission::GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_t index, uint8_t bssColor) const
1898 {
1899  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, m_channelWidth, false, false, false, bssColor);
1900 
1901  HeRu::RuType ruType = HeRu::RU_106_TONE;
1902  if (m_channelWidth == 20)
1903  {
1904  ruType = HeRu::RU_106_TONE;
1905  }
1906  else if (m_channelWidth == 40)
1907  {
1908  ruType = HeRu::RU_242_TONE;
1909  }
1910  else if (m_channelWidth == 80)
1911  {
1912  ruType = HeRu::RU_484_TONE;
1913  }
1914  else if (m_channelWidth == 160)
1915  {
1916  ruType = HeRu::RU_996_TONE;
1917  }
1918  else
1919  {
1920  NS_ASSERT_MSG (false, "Unsupported channel width");
1921  }
1922 
1923  HeRu::RuSpec ru;
1924  if (m_channelWidth == 160 && (index == 1))
1925  {
1926  ru.primary80MHz = true;
1927  }
1928  else
1929  {
1930  ru.primary80MHz = false;
1931  }
1932  ru.ruType = ruType;
1933  ru.index = index;
1934  txVector.SetRu (ru, txStaId);
1935  txVector.SetMode (HePhy::GetHeMcs7 (), txStaId);
1936  txVector.SetNss (1, txStaId);
1937  return txVector;
1938 }
1939 
1940 void
1941 TestUlOfdmaPhyTransmission::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
1942 {
1943  NS_LOG_FUNCTION (this << txStaId << index << payloadSize << uid << +bssColor);
1944  WifiConstPsduMap psdus;
1945 
1946  WifiTxVector txVector = GetTxVectorForHeTbPpdu (txStaId, index, bssColor);
1947  Ptr<Packet> pkt = Create<Packet> (payloadSize);
1948  WifiMacHeader hdr;
1949  hdr.SetType (WIFI_MAC_QOSDATA);
1950  hdr.SetQosTid (0);
1951  hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
1952  std::ostringstream addr;
1953  addr << "00:00:00:00:00:0" << txStaId;
1954  hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
1955  hdr.SetSequenceNumber (1);
1956  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1957  psdus.insert (std::make_pair (txStaId, psdu));
1958 
1960  if (txStaId == 1)
1961  {
1962  phy = m_phySta1;
1963  }
1964  else if (txStaId == 2)
1965  {
1966  phy = m_phySta2;
1967  }
1968  else if (txStaId == 3)
1969  {
1970  phy = m_phySta3;
1971  }
1972 
1973  Time txDuration = phy->CalculateTxDuration (psdu->GetSize (), txVector, phy->GetPhyBand (), txStaId);
1974  txVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
1975 
1976  phy->SetPpduUid (uid);
1977  phy->Send (psdus, txVector);
1978 }
1979 
1980 void
1982 {
1983  NS_LOG_FUNCTION (this << duration);
1984  m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
1985  m_phyInterferer->SetPeriod (duration);
1986  m_phyInterferer->Start ();
1987  Simulator::Schedule (duration, &TestUlOfdmaPhyTransmission::StopInterference, this);
1988 }
1989 
1990 void
1992 {
1993  m_phyInterferer->Stop();
1994 }
1995 
1997 {
1998 }
1999 
2000 void
2001 TestUlOfdmaPhyTransmission::RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
2002 {
2003  NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 () << rxSignalInfo << txVector);
2004  if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2005  {
2007  m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
2008  }
2009  else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2010  {
2012  m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
2013  }
2014 }
2015 
2016 void
2018 {
2019  NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
2020  if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2021  {
2023  }
2024  else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2025  {
2027  }
2028 }
2029 
2030 void
2031 TestUlOfdmaPhyTransmission::CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2032 {
2033  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta1, expectedSuccess, "The number of successfully received packets from STA 1 is not correct!");
2034  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta1, expectedFailures, "The number of unsuccessfully received packets from STA 1 is not correct!");
2035  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta1, expectedBytes, "The number of bytes received from STA 1 is not correct!");
2036 }
2037 
2038 void
2039 TestUlOfdmaPhyTransmission::CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
2040 {
2041  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta2, expectedSuccess, "The number of successfully received packets from STA 2 is not correct!");
2042  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta2, expectedFailures, "The number of unsuccessfully received packets from STA 2 is not correct!");
2043  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta2, expectedBytes, "The number of bytes received from STA 2 is not correct!");
2044 }
2045 
2046 void
2048 {
2049  Ptr<Event> event = phy->GetCurrentEvent ();
2050  NS_ASSERT (event);
2051  double rxPower = event->GetRxPowerW (band);
2052  NS_LOG_FUNCTION (this << band.first << band.second << expectedRxPower << rxPower);
2053  //Since there is out of band emission due to spectrum mask, the tolerance cannot be very low
2054  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 ());
2055 }
2056 
2057 void
2059 {
2065  NS_LOG_FUNCTION (this << band.first << band.second << expectedRxPower);
2066  double step = 5e-3;
2067  if (expectedRxPower > 0.0)
2068  {
2069  NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower - step, band).IsStrictlyPositive (), true,
2070  "At least " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2071  NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower + step, band).IsStrictlyPositive (), false,
2072  "At most " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2073  }
2074  else
2075  {
2076  NS_TEST_ASSERT_MSG_EQ (phy->GetEnergyDuration (expectedRxPower + step, band).IsStrictlyPositive (), false,
2077  "At most " << expectedRxPower << " W expected for OFDMA part over (" << band.first << ", " << band.second << ") at " << Simulator::Now ());
2078  }
2079 }
2080 
2081 void
2083 {
2084  NS_TEST_ASSERT_MSG_EQ (m_phyAp->GetCurrentEvent (), 0, "m_currentEvent for AP was not cleared");
2085  NS_TEST_ASSERT_MSG_EQ (m_phySta1->GetCurrentEvent (), 0, "m_currentEvent for STA 1 was not cleared");
2086  NS_TEST_ASSERT_MSG_EQ (m_phySta2->GetCurrentEvent (), 0, "m_currentEvent for STA 2 was not cleared");
2087 }
2088 
2089 void
2091 {
2092  //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
2093  Simulator::ScheduleNow (&TestUlOfdmaPhyTransmission::DoCheckPhyState, this, phy, expectedState);
2094 }
2095 
2096 void
2098 {
2099  WifiPhyState currentState;
2100  PointerValue ptr;
2101  phy->GetAttribute ("State", ptr);
2102  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
2103  currentState = state->GetState ();
2104  NS_LOG_FUNCTION (this << currentState);
2105  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
2106 }
2107 
2108 void
2110 {
2117  m_phySta1->SetPpduUid (0);
2120  SetBssColor (m_phyAp, 0);
2121 }
2122 
2123 void
2125 {
2126  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (phy->GetDevice ());
2127  Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
2128  heConfiguration->SetAttribute ("BssColor", UintegerValue (bssColor));
2129 }
2130 
2131 void
2133 {
2134  NS_LOG_FUNCTION (this << phy << psdLimit);
2135  phy->SetAttribute ("PowerDensityLimit", DoubleValue (psdLimit));
2136 }
2137 
2138 void
2140 {
2141  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
2142  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
2143  lossModel->SetFrequency (m_frequency);
2144  spectrumChannel->AddPropagationLossModel (lossModel);
2145  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
2146  spectrumChannel->SetPropagationDelayModel (delayModel);
2147 
2148  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
2149  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-8)); //to ensure that transmission in neighboring channel is ignored (16 dBm baseline)
2150  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (-100)); //no limit on SNR
2151 
2152  Ptr<Node> apNode = CreateObject<Node> ();
2153  Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
2154  Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac> ();
2155  apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
2156  apDev->SetMac (apMac);
2157  m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
2160  Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration> ();
2161  apDev->SetHeConfiguration (heConfiguration);
2162  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
2163  m_phyAp->SetErrorRateModel (error);
2164  m_phyAp->SetDevice (apDev);
2165  m_phyAp->SetChannel (spectrumChannel);
2168  m_phyAp->SetPreambleDetectionModel (preambleDetectionModel);
2169  Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
2170  m_phyAp->SetMobility (apMobility);
2171  apDev->SetPhy (m_phyAp);
2172  apNode->AggregateObject (apMobility);
2173  apNode->AddDevice (apDev);
2174 
2175  Ptr<Node> sta1Node = CreateObject<Node> ();
2176  Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
2177  m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
2180  m_phySta1->SetErrorRateModel (error);
2181  m_phySta1->SetDevice (sta1Dev);
2182  m_phySta1->SetChannel (spectrumChannel);
2183  m_phySta1->SetPreambleDetectionModel (preambleDetectionModel);
2184  Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
2185  m_phySta1->SetMobility (sta1Mobility);
2186  sta1Dev->SetPhy (m_phySta1);
2187  sta1Node->AggregateObject (sta1Mobility);
2188  sta1Node->AddDevice (sta1Dev);
2189 
2190  Ptr<Node> sta2Node = CreateObject<Node> ();
2191  Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
2192  m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
2195  m_phySta2->SetErrorRateModel (error);
2196  m_phySta2->SetDevice (sta2Dev);
2197  m_phySta2->SetChannel (spectrumChannel);
2198  m_phySta2->SetPreambleDetectionModel (preambleDetectionModel);
2199  Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
2200  m_phySta2->SetMobility (sta2Mobility);
2201  sta2Dev->SetPhy (m_phySta2);
2202  sta2Node->AggregateObject (sta2Mobility);
2203  sta2Node->AddDevice (sta2Dev);
2204 
2205  Ptr<Node> sta3Node = CreateObject<Node> ();
2206  Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice> ();
2207  m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy> (3);
2210  m_phySta3->SetErrorRateModel (error);
2211  m_phySta3->SetDevice (sta3Dev);
2212  m_phySta3->SetChannel (spectrumChannel);
2213  m_phySta3->SetPreambleDetectionModel (preambleDetectionModel);
2214  Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel> ();
2215  m_phySta3->SetMobility (sta3Mobility);
2216  sta3Dev->SetPhy (m_phySta3);
2217  sta3Node->AggregateObject (sta3Mobility);
2218  sta3Node->AddDevice (sta3Dev);
2219 
2220  Ptr<Node> interfererNode = CreateObject<Node> ();
2221  Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
2222  m_phyInterferer = CreateObject<WaveformGenerator> ();
2223  m_phyInterferer->SetDevice (interfererDev);
2224  m_phyInterferer->SetChannel (spectrumChannel);
2226  interfererNode->AddDevice (interfererDev);
2227 
2228  //Configure power attributes of all wifi devices
2229  std::list<Ptr<WifiPhy>> phys {m_phyAp, m_phySta1, m_phySta2, m_phySta3};
2230  for (auto & phy : phys)
2231  {
2232  phy->SetAttribute ("TxGain", DoubleValue (1.0));
2233  phy->SetAttribute ("TxPowerStart", DoubleValue (16.0));
2234  phy->SetAttribute ("TxPowerEnd", DoubleValue (16.0));
2235  phy->SetAttribute ("PowerDensityLimit", DoubleValue (100.0)); //no impact by default
2236  phy->SetAttribute ("RxGain", DoubleValue (2.0));
2237  }
2238 }
2239 
2240 void
2242 {
2243  m_phyAp->Dispose ();
2244  m_phyAp = 0;
2245  m_phySta1->Dispose ();
2246  m_phySta1 = 0;
2247  m_phySta2->Dispose ();
2248  m_phySta2 = 0;
2249  m_phySta3->Dispose ();
2250  m_phySta3 = 0;
2252  m_phyInterferer = 0;
2253 }
2254 
2255 void
2257 {
2258  NS_LOG_INFO (log);
2259 }
2260 
2261 void
2262 TestUlOfdmaPhyTransmission::ScheduleTest (Time delay, bool solicited, WifiPhyState expectedStateAtEnd,
2263  uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1,
2264  uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2,
2265  bool scheduleTxSta1, WifiPhyState expectedStateBeforeEnd)
2266 {
2267  //AP send SU packet with UID = 0 (2) to mimic transmission of solicited (unsolicited) HE TB PPDUs
2268  Simulator::Schedule (delay - MilliSeconds (10), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 0, 50, solicited ? 0 : 2, 0);
2269  //STA1 and STA2 send MU UL PPDUs addressed to AP
2270  if (scheduleTxSta1)
2271  {
2272  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 1, 1, 1000, 0, 0);
2273  }
2274  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 2, 2, 1001, 0, 0);
2275 
2276  //Verify it takes m_expectedPpduDuration to transmit the PPDUs
2277  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateBeforeEnd);
2278  Simulator::Schedule (delay + m_expectedPpduDuration, &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateAtEnd);
2279  //TODO: add checks on TX stop for STAs
2280 
2281  delay += MilliSeconds (100);
2282  //Check reception state from STA 1
2283  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::CheckRxFromSta1, this,
2284  expectedSuccessFromSta1, expectedFailuresFromSta1, expectedBytesFromSta1);
2285  //Check reception state from STA 2
2286  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::CheckRxFromSta2, this,
2287  expectedSuccessFromSta2, expectedFailuresFromSta2, expectedBytesFromSta2);
2288  //Verify events data have been cleared
2289  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::VerifyEventsCleared, this);
2290 
2291  delay += MilliSeconds (100);
2292  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::Reset, this);
2293 }
2294 
2295 void
2296 TestUlOfdmaPhyTransmission::SchedulePowerMeasurementChecks (Time delay, double rxPowerNonOfdmaRu1, double rxPowerNonOfdmaRu2,
2297  double rxPowerOfdmaRu1, double rxPowerOfdmaRu2)
2298 {
2299  Time detectionDuration = WifiPhy::GetPreambleDetectionDuration ();
2300  WifiTxVector txVectorSta1 = GetTxVectorForHeTbPpdu (1, 1, 0);
2301  WifiTxVector txVectorSta2 = GetTxVectorForHeTbPpdu (2, 2, 0);
2302  Ptr<const HePhy> hePhy = m_phyAp->GetHePhy ();
2303  Time nonOfdmaDuration = hePhy->CalculateNonOfdmaDurationForHeTb (txVectorSta2);
2304  NS_ASSERT (nonOfdmaDuration == hePhy->CalculateNonOfdmaDurationForHeTb (txVectorSta1));
2305 
2306  std::vector<double> rxPowerNonOfdma { rxPowerNonOfdmaRu1, rxPowerNonOfdmaRu2 };
2307  std::vector<WifiSpectrumBand> nonOfdmaBand { hePhy->GetNonOfdmaBand (txVectorSta1, 1), hePhy->GetNonOfdmaBand (txVectorSta2, 2) };
2308  std::vector<double> rxPowerOfdma { rxPowerOfdmaRu1, rxPowerOfdmaRu2 };
2309  std::vector<WifiSpectrumBand> ofdmaBand { hePhy->GetRuBandForRx (txVectorSta1, 1), hePhy->GetRuBandForRx (txVectorSta2, 2) };
2310 
2311  for (uint8_t i = 0; i < 2; ++i)
2312  {
2316  //Check received power on non-OFDMA portion
2317  Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2319  nonOfdmaBand[i], rxPowerNonOfdma[i]);
2320  Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2322  nonOfdmaBand[i], rxPowerNonOfdma[i]);
2323  //Check received power on OFDMA portion
2324  Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2326  ofdmaBand[i], rxPowerOfdma[i]);
2327  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2329  ofdmaBand[i], rxPowerOfdma[i]);
2330 
2336  //Check received power on non-OFDMA portion
2337  Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2339  nonOfdmaBand[i], rxPowerNonOfdma[i]);
2340  Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2342  nonOfdmaBand[i], rxPowerNonOfdma[i]);
2343  //Check received power on OFDMA portion
2344  Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2346  ofdmaBand[i], rxPowerOfdma[i]);
2347  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2349  ofdmaBand[i], rxPowerOfdma[i]);
2350  }
2351 
2352  if (rxPowerOfdmaRu1 != 0.0)
2353  {
2359  double rxPowerNonOfdmaSta1Only = (m_channelWidth >= 40) ? rxPowerNonOfdma[0] : rxPowerNonOfdma[0] / 2; //both STAs transmit over the same 20 MHz channel
2360  //Check received power on non-OFDMA portion
2361  Simulator::Schedule (delay + detectionDuration + NanoSeconds (1), //just after beginning of portion (once event is stored)
2363  nonOfdmaBand[0], rxPowerNonOfdmaSta1Only);
2364  Simulator::Schedule (delay + nonOfdmaDuration - NanoSeconds (1), //just before end of portion
2366  nonOfdmaBand[0], rxPowerNonOfdmaSta1Only);
2367  //Check received power on OFDMA portion
2368  Simulator::Schedule (delay + nonOfdmaDuration + NanoSeconds (1), //just after beginning of portion
2370  ofdmaBand[0], rxPowerOfdma[0]);
2371  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), //just before end of portion
2373  ofdmaBand[0], rxPowerOfdma[0]);
2374  }
2375 }
2376 
2377 void
2379 {
2380  RngSeedManager::SetSeed (1);
2381  RngSeedManager::SetRun (1);
2382  int64_t streamNumber = 0;
2383  m_phyAp->AssignStreams (streamNumber);
2384  m_phySta1->AssignStreams (streamNumber);
2385  m_phySta2->AssignStreams (streamNumber);
2386  m_phySta3->AssignStreams (streamNumber);
2387 
2390 
2393 
2396 
2399 
2400  Time delay = Seconds (0.0);
2401  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::Reset, this);
2402  delay += Seconds (1.0);
2403 
2412  //---------------------------------------------------------------------------
2413  //Verify that both solicited HE TB PPDUs have been corrected received
2414  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2415  "Reception of solicited HE TB PPDUs");
2416  ScheduleTest (delay, true,
2418  1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2419  1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2420  delay += Seconds (1.0);
2421 
2422  //---------------------------------------------------------------------------
2423  //Verify that both unsolicited HE TB PPDUs have been corrected received
2424  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2425  "Reception of unsolicited HE TB PPDUs");
2426  ScheduleTest (delay, false,
2428  1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2429  1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2430  delay += Seconds (1.0);
2431 
2432  //---------------------------------------------------------------------------
2433  //Generate an interference on RU 1 and verify that only STA 1's solicited HE TB PPDU has been impacted
2434  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2435  "Reception of solicited HE TB PPDUs with interference on RU 1 during PSDU reception");
2436  //A strong non-wifi interference is generated on RU 1 during PSDU reception
2437  BandInfo bandInfo;
2438  bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
2439  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
2440  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
2441  Bands bands;
2442  bands.push_back (bandInfo);
2443 
2444  Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
2445  Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
2446  double interferencePower = 0.1; //watts
2447  *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
2448 
2449  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
2450  ScheduleTest (delay, true,
2451  WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2452  0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2453  1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2454  delay += Seconds (1.0);
2455 
2456  //---------------------------------------------------------------------------
2457  //Generate an interference on RU 1 and verify that only STA 1's unsolicited HE TB PPDU has been impacted
2458  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2459  "Reception of unsolicited HE TB PPDUs with interference on RU 1 during PSDU reception");
2460  //A strong non-wifi interference is generated on RU 1 during PSDU reception
2461  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
2462  ScheduleTest (delay, false,
2463  WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference (primary channel)
2464  0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2465  1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2466  delay += Seconds (1.0);
2467 
2468  //---------------------------------------------------------------------------
2469  //Generate an interference on RU 2 and verify that only STA 2's solicited HE TB PPDU has been impacted
2470  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2471  "Reception of solicited HE TB PPDUs with interference on RU 2 during PSDU reception");
2472  //A strong non-wifi interference is generated on RU 2 during PSDU reception
2473  bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
2474  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
2475  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
2476  bands.clear ();
2477  bands.push_back (bandInfo);
2478 
2479  Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel> (bands);
2480  Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue> (SpectrumInterferenceRu2);
2481  *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
2482 
2483  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
2484  ScheduleTest (delay, true,
2485  WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY since measurement channel encompasses total channel width
2486  1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2487  0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2488  delay += Seconds (1.0);
2489 
2490  //---------------------------------------------------------------------------
2491  //Generate an interference on RU 2 and verify that only STA 2's unsolicited HE TB PPDU has been impacted
2492  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2493  "Reception of unsolicited HE TB PPDUs with interference on RU 2 during PSDU reception");
2494  //A strong non-wifi interference is generated on RU 2 during PSDU reception
2495  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
2496  ScheduleTest (delay, false,
2497  (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE if interference on primary channel
2498  1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2499  0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2500  delay += Seconds (1.0);
2501 
2502  //---------------------------------------------------------------------------
2503  //Generate an interference on the full band and verify that both solicited HE TB PPDUs have been impacted
2504  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2505  "Reception of solicited HE TB PPDUs with interference on the full band during PSDU reception");
2506  //A strong non-wifi interference is generated on the full band during PSDU reception
2507  bandInfo.fc = m_frequency * 1e6;
2508  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
2509  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
2510  bands.clear ();
2511  bands.push_back (bandInfo);
2512 
2513  Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel> (bands);
2514  Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue> (SpectrumInterferenceAll);
2515  *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
2516 
2517  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
2518  ScheduleTest (delay, true,
2519  WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2520  0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2521  0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2522  delay += Seconds (1.0);
2523 
2524  //---------------------------------------------------------------------------
2525  //Generate an interference on the full band and verify that both unsolicited HE TB PPDUs have been impacted
2526  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2527  "Reception of unsolicited HE TB PPDUs with interference on the full band during PSDU reception");
2528  //A strong non-wifi interference is generated on the full band during PSDU reception
2529  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
2530  ScheduleTest (delay, false,
2531  WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
2532  0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
2533  0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
2534  delay += Seconds (1.0);
2535 
2536  //---------------------------------------------------------------------------
2537  //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
2538  // 20 MHz channel. Only STA 1's solicited HE TB PPDU is impacted otherwise.
2539  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2540  "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU 1 during PSDU reception");
2541  //Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
2542  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 0);
2543  //Expected figures from STA 2
2544  uint32_t succ, fail, bytes;
2545  if (m_channelWidth > 20)
2546  {
2547  //One PSDU of 1001 bytes should have been successfully received from STA 2 (since interference from STA 3 on distinct 20 MHz channel)
2548  succ = 1;
2549  fail = 0;
2550  bytes = 1001;
2551  }
2552  else
2553  {
2554  //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2555  succ = 0;
2556  fail = 1;
2557  bytes = 0;
2558  }
2559  ScheduleTest (delay, true,
2560  WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on measurement channel width
2561  0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2562  succ, fail, bytes);
2563  delay += Seconds (1.0);
2564 
2565  //---------------------------------------------------------------------------
2566  //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
2567  // 20 MHz channel. Only STA 1's unsolicited HE TB PPDU is impacted otherwise.
2568  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2569  "Reception of unsolicited HE TB PPDUs with another HE TB PPDU arriving on RU 1 during PSDU reception");
2570  //Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
2571  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 0);
2572  ScheduleTest (delay, false,
2573  WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on primary channel width
2574  0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2575  succ, fail, bytes); //same as solicited case
2576  delay += Seconds (1.0);
2577 
2578  //---------------------------------------------------------------------------
2579  //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
2580  // 20 MHz channel. Only STA 2's solicited HE TB PPDU is impacted otherwise.
2581  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2582  "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU 2 during PSDU reception");
2583  //Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
2584  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 2, 1002, 1, 0);
2585  //Expected figures from STA 1
2586  if (m_channelWidth > 20)
2587  {
2588  //One PSDU of 1000 bytes should have been successfully received from STA 1 (since interference from STA 3 on distinct 20 MHz channel)
2589  succ = 1;
2590  fail = 0;
2591  bytes = 1000;
2592  }
2593  else
2594  {
2595  //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
2596  succ = 0;
2597  fail = 1;
2598  bytes = 0;
2599  }
2600  ScheduleTest (delay, true,
2601  WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on measurement channel width
2602  succ, fail, bytes,
2603  0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2604  delay += Seconds (1.0);
2605 
2606  //---------------------------------------------------------------------------
2607  //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
2608  // 20 MHz channel. Only STA 2's unsolicited HE TB PPDU is impacted otherwise.
2609  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2610  "Reception of unsolicited HE TB PPDUs with another HE TB PPDU arriving on RU2 during payload reception");
2611  //Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
2612  Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 2, 1002, 1, 0);
2613  ScheduleTest (delay, false,
2614  (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE if interference on primary channel
2615  succ, fail, bytes, //same as solicited case
2616  0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
2617  delay += Seconds (1.0);
2618 
2619  //---------------------------------------------------------------------------
2620  //Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been impacted
2621  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2622  "Reception of solicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
2623  //One HE SU arrives at AP during the 400ns window
2624  Simulator::Schedule (delay + NanoSeconds (300), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 3, 1002, 1, 0);
2625  ScheduleTest (delay, true,
2627  0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference from STA 3)
2628  0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3)
2629  delay += Seconds (1.0);
2630 
2631  //---------------------------------------------------------------------------
2632  //Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been impacted
2633  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2634  "Reception of unsolicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
2635  //One HE SU arrives at AP during the 400ns window
2636  Simulator::Schedule (delay + NanoSeconds (300), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 3, 1002, 1, 0);
2637  ScheduleTest (delay, false,
2639  0, 1, 0, //Reception of the PSDU from STA 1 should have failed failed (since interference from STA 3)
2640  0, 1, 0); //Reception of the PSDU from STA 2 should have failed failed (since interference from STA 3)
2641  delay += Seconds (1.0);
2642 
2643  //---------------------------------------------------------------------------
2644  //Only send a solicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly received
2645  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2646  "Reception of solicited HE TB PPDU only on RU 2");
2647  //Check that STA3 will correctly set its state to RX if in measurement channel or IDLE otherwise
2648  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3,
2649  (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::RX); //PHY should move to RX instead of IDLE if HE TB PPDU on primary channel;
2650  ScheduleTest (delay, true,
2652  0, 0, 0, //No transmission scheduled for STA 1
2653  1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2654  false, WifiPhyState::RX); //Measurement channel is total channel width
2655  delay += Seconds (1.0);
2656 
2657  //---------------------------------------------------------------------------
2658  //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
2659  // correct measurement channel
2660  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2661  "Reception of unsolicited HE TB PPDUs only on RU 2");
2662  //Check that STA3 will correctly set its state to RX if in measurement channel or IDLE otherwise
2663  Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3,
2664  (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::RX); //PHY should move to RX instead of IDLE if HE TB PPDU on primary channel;
2665  //Expected figures from STA 2
2666  WifiPhyState state;
2667  if (m_channelWidth == 20)
2668  {
2669  //One PSDU of 1001 bytes should have been successfully received from STA 2 (since measurement channel is primary channel)
2670  succ = 1;
2671  fail = 0;
2672  bytes = 1001;
2673  state = WifiPhyState::RX;
2674  }
2675  else
2676  {
2677  //No PSDU should have been received from STA 2 (since measurement channel is primary channel)
2678  succ = 0;
2679  fail = 0;
2680  bytes = 0;
2681  state = WifiPhyState::IDLE;
2682  }
2683  ScheduleTest (delay, false,
2685  0, 0, 0, //No transmission scheduled for STA 1
2686  succ, fail, bytes,
2687  false, state);
2688  delay += Seconds (1.0);
2689 
2690  //---------------------------------------------------------------------------
2691  //Measure the power of a solicited HE TB PPDU from STA 2 on RU 2
2692  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2693  "Measure power for reception of HE TB PPDU only on RU 2");
2694  double rxPower = DbmToW (19); //16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
2696  (m_channelWidth >= 40) ? 0.0 : rxPower, rxPower, //power detected on RU1 only if same 20 MHz as RU 2
2697  0.0, rxPower);
2698  ScheduleTest (delay, true,
2700  0, 0, 0, //No transmission scheduled for STA 1
2701  1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2702  false, WifiPhyState::RX); //Measurement channel is total channel width
2703  delay += Seconds (1.0);
2704 
2705  //---------------------------------------------------------------------------
2706  //Measure the power of a solicited HE TB PPDU from STA 2 on RU 2 with power spectrum density limitation enforced
2707  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2708  "Measure power for reception of HE TB PPDU only on RU 2 with PSD limitation");
2709  //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
2710  Simulator::Schedule (delay - NanoSeconds (1), //just before sending HE TB
2712 
2713  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
2714  double rxPowerOfdma = rxPower;
2715  if (m_channelWidth <= 40)
2716  {
2717  rxPowerOfdma = (m_channelWidth == 20) ? DbmToW (14.0309) //11.0309+1 dBm at STA and +2 at AP if 106-tone RU
2718  : DbmToW (18.0103); //15.0103+1 dBm at STA 2 and +2 at AP if 242-tone RU
2719  }
2721  (m_channelWidth >= 40) ? 0.0 : rxPower, rxPower, //power detected on RU1 only if same 20 MHz as RU 2
2722  0.0, rxPowerOfdma);
2723 
2724  //Reset PSD limitation once HE TB has been sent
2725  Simulator::Schedule (delay + m_expectedPpduDuration,
2727  ScheduleTest (delay, true,
2729  0, 0, 0, //No transmission scheduled for STA 1
2730  1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
2731  false, WifiPhyState::RX); //Measurement channel is total channel width
2732  delay += Seconds (1.0);
2733 
2734  //---------------------------------------------------------------------------
2735  //Measure the power of 2 solicited HE TB PPDU from both STAs
2736  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2737  "Measure power for reception of HE TB PPDU on both RUs");
2738  rxPower = DbmToW (19); //16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
2739  double rxPowerNonOfdma = (m_channelWidth >= 40) ? rxPower : rxPower * 2; //both STAs transmit over the same 20 MHz channel
2741  rxPowerNonOfdma, rxPowerNonOfdma,
2742  rxPower, rxPower);
2743  ScheduleTest (delay, true,
2745  1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
2746  1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
2747  delay += Seconds (1.0);
2748 
2749  //---------------------------------------------------------------------------
2750  //Verify that an HE SU PPDU from another BSS has been correctly received (no UL MU transmission ongoing)
2751  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
2752  "Reception of an HE SU PPDU from another BSS");
2753  //One HE SU from another BSS (BSS color 2) arrives at AP (BSS color 1)
2754  Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SetBssColor, this, m_phyAp, 1);
2755  Simulator::Schedule (delay + MilliSeconds (100), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 2);
2756 
2757  //Verify events data have been cleared
2758  Simulator::Schedule (delay + MilliSeconds (200), &TestUlOfdmaPhyTransmission::VerifyEventsCleared, this);
2759 
2760  Simulator::Schedule (delay + MilliSeconds (500), &TestUlOfdmaPhyTransmission::Reset, this);
2761  delay += Seconds (1.0);
2762 
2763  Simulator::Run ();
2764 }
2765 
2766 void
2768 {
2769  m_frequency = 5180;
2770  m_channelWidth = 20;
2772  NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2773  RunOne ();
2774 
2775  m_frequency = 5190;
2776  m_channelWidth = 40;
2778  NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2779  RunOne ();
2780 
2781  m_frequency = 5210;
2782  m_channelWidth = 80;
2784  NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2785  RunOne ();
2786 
2787  m_frequency = 5250;
2788  m_channelWidth = 160;
2790  NS_LOG_DEBUG ("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
2791  RunOne ();
2792 
2793  Simulator::Destroy ();
2794 }
2795 
2803 {
2804 public:
2806  virtual ~TestPhyPaddingExclusion ();
2807 
2808 private:
2809  virtual void DoSetup (void);
2810  virtual void DoTeardown (void);
2811  virtual void DoRun (void);
2812 
2820  void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration);
2821 
2827  void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
2831  void StopInterference (void);
2832 
2836  void RunOne ();
2837 
2844  void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
2845 
2852  void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
2853 
2857  void VerifyEventsCleared (void);
2858 
2866 
2870  void Reset ();
2871 
2879  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
2880 
2885  void RxFailure (Ptr<WifiPsdu> psdu);
2886 
2890 
2892 
2899 };
2900 
2902  : TestCase ("PHY padding exclusion test"),
2903  m_countRxSuccessFromSta1 (0),
2904  m_countRxSuccessFromSta2 (0),
2905  m_countRxFailureFromSta1 (0),
2906  m_countRxFailureFromSta2 (0),
2907  m_countRxBytesFromSta1 (0),
2908  m_countRxBytesFromSta2 (0)
2909 {
2910 }
2911 
2912 void
2913 TestPhyPaddingExclusion::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration)
2914 {
2915  WifiConstPsduMap psdus;
2916 
2917  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false, 1);
2918 
2919  HeRu::RuSpec ru;
2920  ru.primary80MHz = false;
2921  ru.ruType = HeRu::RU_106_TONE;
2922  ru.index = index;
2923  txVector.SetRu (ru, txStaId);
2924  txVector.SetMode (HePhy::GetHeMcs7 (), txStaId);
2925  txVector.SetNss (1, txStaId);
2926 
2927  Ptr<Packet> pkt = Create<Packet> (payloadSize);
2928  WifiMacHeader hdr;
2929  hdr.SetType (WIFI_MAC_QOSDATA);
2930  hdr.SetQosTid (0);
2931  hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
2932  std::ostringstream addr;
2933  addr << "00:00:00:00:00:0" << txStaId;
2934  hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
2935  hdr.SetSequenceNumber (1);
2936  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
2937  psdus.insert (std::make_pair (txStaId, psdu));
2938 
2940  if (txStaId == 1)
2941  {
2942  phy = m_phySta1;
2943  }
2944  else if (txStaId == 2)
2945  {
2946  phy = m_phySta2;
2947  }
2948 
2949  txVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
2950 
2951  phy->SetPpduUid (0);
2952  phy->Send (psdus, txVector);
2953 }
2954 
2955 void
2957 {
2958  m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
2959  m_phyInterferer->SetPeriod (duration);
2960  m_phyInterferer->Start ();
2961  Simulator::Schedule (duration, &TestPhyPaddingExclusion::StopInterference, this);
2962 }
2963 
2964 void
2966 {
2967  m_phyInterferer->Stop();
2968 }
2969 
2971 {
2972 }
2973 
2974 void
2975 TestPhyPaddingExclusion::RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
2976 {
2977  NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 () << rxSignalInfo << txVector);
2978  if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2979  {
2981  m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
2982  }
2983  else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2984  {
2986  m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
2987  }
2988 }
2989 
2990 void
2992 {
2993  NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
2994  if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
2995  {
2997  }
2998  else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
2999  {
3001  }
3002 }
3003 
3004 void
3005 TestPhyPaddingExclusion::CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
3006 {
3007  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta1, expectedSuccess, "The number of successfully received packets from STA 1 is not correct!");
3008  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta1, expectedFailures, "The number of unsuccessfully received packets from STA 1 is not correct!");
3009  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta1, expectedBytes, "The number of bytes received from STA 1 is not correct!");
3010 }
3011 
3012 void
3013 TestPhyPaddingExclusion::CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
3014 {
3015  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta2, expectedSuccess, "The number of successfully received packets from STA 2 is not correct!");
3016  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta2, expectedFailures, "The number of unsuccessfully received packets from STA 2 is not correct!");
3017  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta2, expectedBytes, "The number of bytes received from STA 2 is not correct!");
3018 }
3019 
3020 void
3022 {
3023  NS_TEST_ASSERT_MSG_EQ (m_phyAp->GetCurrentEvent (), 0, "m_currentEvent for AP was not cleared");
3024  NS_TEST_ASSERT_MSG_EQ (m_phySta1->GetCurrentEvent (), 0, "m_currentEvent for STA 1 was not cleared");
3025  NS_TEST_ASSERT_MSG_EQ (m_phySta2->GetCurrentEvent (), 0, "m_currentEvent for STA 2 was not cleared");
3026 }
3027 
3028 void
3030 {
3031  //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
3032  Simulator::ScheduleNow (&TestPhyPaddingExclusion::DoCheckPhyState, this, phy, expectedState);
3033 }
3034 
3035 void
3037 {
3038  WifiPhyState currentState = phy->GetState ()->GetState ();
3039  NS_LOG_FUNCTION (this << currentState);
3040  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
3041 }
3042 
3043 void
3045 {
3052  m_phySta1->SetPpduUid (0);
3055 }
3056 
3057 void
3059 {
3060  RngSeedManager::SetSeed (1);
3061  RngSeedManager::SetRun (1);
3062  int64_t streamNumber = 0;
3063 
3064  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
3065  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
3066  lossModel->SetFrequency (DEFAULT_FREQUENCY * 1e6);
3067  spectrumChannel->AddPropagationLossModel (lossModel);
3068  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
3069  spectrumChannel->SetPropagationDelayModel (delayModel);
3070 
3071  Ptr<Node> apNode = CreateObject<Node> ();
3072  Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
3073  Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac> ();
3074  apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
3075  apDev->SetMac (apMac);
3076  m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
3079  Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration> ();
3080  apDev->SetHeConfiguration (heConfiguration);
3081  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
3082  m_phyAp->SetErrorRateModel (error);
3083  m_phyAp->SetDevice (apDev);
3084  m_phyAp->SetChannel (spectrumChannel);
3085  m_phyAp->AssignStreams (streamNumber);
3090  Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
3091  m_phyAp->SetMobility (apMobility);
3092  apDev->SetPhy (m_phyAp);
3093  apNode->AggregateObject (apMobility);
3094  apNode->AddDevice (apDev);
3095 
3096  Ptr<Node> sta1Node = CreateObject<Node> ();
3097  Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
3098  m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
3101  m_phySta1->SetErrorRateModel (error);
3102  m_phySta1->SetDevice (sta1Dev);
3103  m_phySta1->SetChannel (spectrumChannel);
3104  m_phySta1->AssignStreams (streamNumber);
3107  Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
3108  m_phySta1->SetMobility (sta1Mobility);
3109  sta1Dev->SetPhy (m_phySta1);
3110  sta1Node->AggregateObject (sta1Mobility);
3111  sta1Node->AddDevice (sta1Dev);
3112 
3113  Ptr<Node> sta2Node = CreateObject<Node> ();
3114  Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
3115  m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
3118  m_phySta2->SetErrorRateModel (error);
3119  m_phySta2->SetDevice (sta2Dev);
3120  m_phySta2->SetChannel (spectrumChannel);
3121  m_phySta2->AssignStreams (streamNumber);
3124  Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
3125  m_phySta2->SetMobility (sta2Mobility);
3126  sta2Dev->SetPhy (m_phySta2);
3127  sta2Node->AggregateObject (sta2Mobility);
3128  sta2Node->AddDevice (sta2Dev);
3129 
3130  Ptr<Node> interfererNode = CreateObject<Node> ();
3131  Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
3132  m_phyInterferer = CreateObject<WaveformGenerator> ();
3133  m_phyInterferer->SetDevice (interfererDev);
3134  m_phyInterferer->SetChannel (spectrumChannel);
3136  interfererNode->AddDevice (interfererDev);
3137 }
3138 
3139 void
3141 {
3142  m_phyAp->Dispose ();
3143  m_phyAp = 0;
3144  m_phySta1->Dispose ();
3145  m_phySta1 = 0;
3146  m_phySta2->Dispose ();
3147  m_phySta2 = 0;
3149  m_phyInterferer = 0;
3150 }
3151 
3152 void
3154 {
3155  Time expectedPpduDuration = NanoSeconds (279200);
3156  Time ppduWithPaddingDuration = expectedPpduDuration + 10 * NanoSeconds (12800 + 800 /* GI */); //add 10 extra OFDM symbols
3157 
3158  Simulator::Schedule (Seconds (0.0), &TestPhyPaddingExclusion::Reset, this);
3159 
3160  //STA1 and STA2 send MU UL PPDUs addressed to AP:
3161  Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
3162  Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
3163 
3164  //Verify it takes expectedPpduDuration + padding to transmit the PPDUs
3165  Simulator::Schedule (Seconds (1.0) + ppduWithPaddingDuration - NanoSeconds (1), &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::RX);
3166  Simulator::Schedule (Seconds (1.0) + ppduWithPaddingDuration, &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::IDLE);
3167 
3168  //One PSDU of 1000 bytes should have been successfully received from STA 1
3169  Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::CheckRxFromSta1, this, 1, 0, 1000);
3170  //One PSDU of 1001 bytes should have been successfully received from STA 2
3171  Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::CheckRxFromSta2, this, 1, 0, 1001);
3172  //Verify events data have been cleared
3173  Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::VerifyEventsCleared, this);
3174 
3175  Simulator::Schedule (Seconds (1.5), &TestPhyPaddingExclusion::Reset, this);
3176 
3177 
3178  //STA1 and STA2 send MU UL PPDUs addressed to AP:
3179  Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
3180  Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
3181 
3182  //A strong non-wifi interference is generated on RU 1 during padding reception
3183  BandInfo bandInfo;
3184  bandInfo.fc = (DEFAULT_FREQUENCY - (DEFAULT_CHANNEL_WIDTH / 4)) * 1e6;
3185  bandInfo.fl = bandInfo.fc - ((DEFAULT_CHANNEL_WIDTH / 4) * 1e6);
3186  bandInfo.fh = bandInfo.fc + ((DEFAULT_CHANNEL_WIDTH / 4) * 1e6);
3187  Bands bands;
3188  bands.push_back (bandInfo);
3189 
3190  Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
3191  Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
3192  double interferencePower = 0.1; //watts
3193  *interferencePsdRu1 = interferencePower / ((DEFAULT_CHANNEL_WIDTH / 2) * 20e6);
3194 
3195  Simulator::Schedule (Seconds (2.0) + MicroSeconds (50) + expectedPpduDuration, &TestPhyPaddingExclusion::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
3196 
3197  //Verify it takes expectedPpduDuration + padding to transmit the PPDUs (PHY should move to CCA_BUSY instead of IDLE due to the interference)
3198  Simulator::Schedule (Seconds (2.0) + ppduWithPaddingDuration - NanoSeconds (1), &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::RX);
3199  Simulator::Schedule (Seconds (2.0) + ppduWithPaddingDuration, &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::CCA_BUSY);
3200 
3201  //One PSDU of 1000 bytes should have been successfully received from STA 1 (since interference occupies RU 1 after payload, during PHY padding)
3202  Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::CheckRxFromSta1, this, 1, 0, 1000);
3203  //One PSDU of 1001 bytes should have been successfully received from STA 2
3204  Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::CheckRxFromSta2, this, 1, 0, 1001);
3205  //Verify events data have been cleared
3206  Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::VerifyEventsCleared, this);
3207 
3208  Simulator::Schedule (Seconds (2.5), &TestPhyPaddingExclusion::Reset, this);
3209 
3210  Simulator::Run ();
3211 
3212  Simulator::Destroy ();
3213 }
3214 
3222 {
3223 public:
3225  virtual ~TestUlOfdmaPowerControl ();
3226 
3227 private:
3228  virtual void DoSetup (void);
3229  virtual void DoTeardown (void);
3230  virtual void DoRun (void);
3231 
3237  void SendMuBar (std::vector <uint16_t> staIds);
3238 
3245  void SetupBa (Address destination);
3246 
3253  void RunOne (bool setupBa);
3254 
3259  void ReplaceReceiveOkCallbackOfAp (void);
3260 
3270  void ReceiveOkCallbackAtAp (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
3271  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
3272 
3273  uint8_t m_bssColor;
3274 
3278 
3280 
3281  double m_txPowerAp;
3283  double m_txPowerEnd;
3285 
3288 
3289  double m_rssiSta1;
3290  double m_rssiSta2;
3291 
3292  double m_tol;
3293 };
3294 
3296  : TestCase ("UL-OFDMA power control test"),
3297  m_bssColor (1),
3298  m_txPowerAp (0),
3299  m_txPowerStart (0),
3300  m_txPowerEnd (0),
3301  m_txPowerLevels (0),
3302  m_requestedRssiSta1 (0),
3303  m_requestedRssiSta2 (0),
3304  m_rssiSta1 (0),
3305  m_rssiSta2 (0),
3306  m_tol (0.1)
3307 {
3308 }
3309 
3311 {
3312  m_phyAp = 0;
3313  m_apDev = 0;
3314  m_sta1Dev = 0;
3315  m_sta2Dev = 0;
3316 }
3317 
3318 void
3320 {
3321  //Only one packet is sufficient to set up BA since AP and STAs are HE capable
3322  Ptr<Packet> pkt = Create<Packet> (100); // 100 dummy bytes of data
3323  m_apDev->Send (pkt, destination, 0);
3324 }
3325 
3326 void
3327 TestUlOfdmaPowerControl::SendMuBar (std::vector <uint16_t> staIds)
3328 {
3329 #ifdef NOTYET
3330  NS_ASSERT (!staIds.empty () && staIds.size () <= 2);
3331 
3332  //Build MU-BAR trigger frame
3333  CtrlTriggerHeader muBar;
3334  muBar.SetType (MU_BAR_TRIGGER);
3335  muBar.SetUlLength (HePhy::ConvertHeTbPpduDurationToLSigLength (MicroSeconds (128), WIFI_PHY_BAND_5GHZ));
3336  muBar.SetMoreTF (true);
3337  muBar.SetCsRequired (true);
3338  muBar.SetUlBandwidth (DEFAULT_CHANNEL_WIDTH);
3339  muBar.SetGiAndLtfType (1600, 2);
3340  muBar.SetApTxPower (static_cast<int8_t> (m_txPowerAp));
3341  muBar.SetUlSpatialReuse (60500);
3342 
3343  HeRu::RuType ru = (staIds.size () == 1) ? HeRu::RU_242_TONE : HeRu::RU_106_TONE;
3344  std::size_t index = 1;
3345  int8_t ulTargetRssi = -40; //will be overwritten
3346  for (auto const& staId : staIds)
3347  {
3348  CtrlTriggerUserInfoField& ui = muBar.AddUserInfoField ();
3349  ui.SetAid12 (staId);
3350  ui.SetRuAllocation ({true, ru, index});
3351  ui.SetUlFecCodingType (true);
3352  ui.SetUlMcs (7);
3353  ui.SetUlDcm (false);
3354  ui.SetSsAllocation (1, 1);
3355  if (staId == 1)
3356  {
3357  ulTargetRssi = m_requestedRssiSta1;
3358  }
3359  else if (staId == 2)
3360  {
3361  ulTargetRssi = m_requestedRssiSta2;
3362  }
3363  else
3364  {
3365  NS_ABORT_MSG ("Unknown STA-ID (" << staId << ")");
3366  }
3367  ui.SetUlTargetRssi (ulTargetRssi);
3368 
3370  bar.SetType (BlockAckReqType::COMPRESSED);
3371  bar.SetTidInfo (0);
3372  bar.SetStartingSequence (4095);
3373  ui.SetMuBarTriggerDepUserInfo (bar);
3374 
3375  ++index;
3376  }
3377 
3378  WifiConstPsduMap psdus;
3379  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0,
3380  DEFAULT_CHANNEL_WIDTH, false, false, false, m_bssColor);
3381 
3382  Ptr<Packet> bar = Create<Packet> ();
3383  bar->AddHeader (muBar);
3384 
3385  Mac48Address receiver = Mac48Address::GetBroadcast ();
3386  if (staIds.size () == 1)
3387  {
3388  uint16_t aidSta1 = DynamicCast<StaWifiMac> (m_sta1Dev->GetMac ())->GetAssociationId ();
3389  if (staIds.front () == aidSta1)
3390  {
3391  receiver = Mac48Address::ConvertFrom (m_sta1Dev->GetAddress ());
3392  }
3393  else
3394  {
3395  NS_ASSERT (staIds.front () == DynamicCast<StaWifiMac> (m_sta2Dev->GetMac ())->GetAssociationId ());
3396  receiver = Mac48Address::ConvertFrom (m_sta2Dev->GetAddress ());
3397  }
3398  }
3399 
3400  WifiMacHeader hdr;
3402  hdr.SetAddr1 (receiver);
3403  hdr.SetAddr2 (Mac48Address::ConvertFrom (m_apDev->GetAddress ()));
3404  hdr.SetAddr3 (Mac48Address::ConvertFrom (m_apDev->GetAddress ()));
3405  hdr.SetDsNotTo ();
3406  hdr.SetDsFrom ();
3407  hdr.SetNoRetry ();
3408  hdr.SetNoMoreFragments ();
3409  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (bar, hdr);
3410 
3411  Time nav = m_apDev->GetPhy ()->GetSifs ();
3412  uint16_t staId = staIds.front (); //either will do
3413  nav += m_phyAp->CalculateTxDuration (GetBlockAckSize (BlockAckType::COMPRESSED), muBar.GetHeTbTxVector (staId), DEFAULT_FREQUENCY, staId);
3414  psdu->SetDuration (nav);
3415  psdus.insert (std::make_pair (SU_STA_ID, psdu));
3416 
3417  m_phyAp->Send (psdus, txVector);
3418 #endif
3419 }
3420 
3421 void
3423  WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
3424 {
3425  NS_TEST_ASSERT_MSG_EQ (txVector.GetPreambleType (), WIFI_PREAMBLE_HE_TB, "HE TB PPDU expected");
3426  double rssi = rxSignalInfo.rssi;
3427  NS_ASSERT (psdu->GetNMpdus () == 1);
3428  WifiMacHeader hdr = psdu->GetHeader (0);
3429  NS_TEST_ASSERT_MSG_EQ (hdr.GetType (), WIFI_MAC_CTL_BACKRESP, "Block ACK expected");
3430  if (hdr.GetAddr2 () == m_sta1Dev->GetAddress ())
3431  {
3432  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 << ")");
3433  }
3434  else if (psdu->GetAddr2 () == m_sta2Dev->GetAddress ())
3435  {
3436  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 << ")");
3437  }
3438  else
3439  {
3440  NS_ABORT_MSG ("The receiver address is unknown");
3441  }
3442 }
3443 
3444 void
3446 {
3447  //Now that BA session has been established we can plug our method
3449 }
3450 
3451 void
3453 {
3454  Ptr<Node> apNode = CreateObject<Node> ();
3455  NodeContainer staNodes;
3456  staNodes.Create (2);
3457 
3458  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
3459  Ptr<MatrixPropagationLossModel> lossModel = CreateObject<MatrixPropagationLossModel> ();
3460  spectrumChannel->AddPropagationLossModel (lossModel);
3461  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
3462  spectrumChannel->SetPropagationDelayModel (delayModel);
3463 
3464  SpectrumWifiPhyHelper spectrumPhy;
3465  spectrumPhy.SetChannel (spectrumChannel);
3466  spectrumPhy.SetErrorRateModel ("ns3::NistErrorRateModel");
3467  spectrumPhy.Set ("Frequency", UintegerValue (DEFAULT_FREQUENCY));
3468  spectrumPhy.Set ("ChannelWidth", UintegerValue (DEFAULT_CHANNEL_WIDTH));
3469 
3470  WifiHelper wifi;
3471  wifi.SetStandard (WIFI_STANDARD_80211ax_5GHZ);
3472  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
3473  "DataMode", StringValue ("HeMcs7"),
3474  "ControlMode", StringValue ("HeMcs7"));
3475 
3477  mac.SetType ("ns3::StaWifiMac");
3478  NetDeviceContainer staDevs = wifi.Install (spectrumPhy, mac, staNodes);
3479  wifi.AssignStreams (staDevs, 0);
3480  m_sta1Dev = DynamicCast<WifiNetDevice> (staDevs.Get (0));
3481  NS_ASSERT (m_sta1Dev);
3482  m_sta2Dev = DynamicCast<WifiNetDevice> (staDevs.Get (1));
3483  NS_ASSERT (m_sta2Dev);
3484 
3485  //Set the beacon interval long enough so that associated STAs may not consider link lost when
3486  //beacon generation is disabled during the actual tests. Having such a long interval also
3487  //avoids bloating logs with beacons during the set up phase.
3488  mac.SetType ("ns3::ApWifiMac",
3489  "BeaconGeneration", BooleanValue (true),
3490  "BeaconInterval", TimeValue (MicroSeconds (1024 * 600)));
3491  m_apDev = DynamicCast<WifiNetDevice> (wifi.Install (spectrumPhy, mac, apNode).Get (0));
3492  NS_ASSERT (m_apDev);
3493  m_apDev->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (m_bssColor));
3494  m_phyAp = DynamicCast<SpectrumWifiPhy> (m_apDev->GetPhy ());
3495  NS_ASSERT (m_phyAp);
3496  //ReceiveOkCallback of AP will be set to corresponding test's method once BA sessions have been set up for both STAs
3497 
3499  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
3500  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
3501  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
3502  positionAlloc->Add (Vector (1.0, 0.0, 0.0)); // put close enough in order to use MCS
3503  positionAlloc->Add (Vector (2.0, 0.0, 0.0)); // STA 2 is a bit further away, but still in range of MCS
3504  mobility.SetPositionAllocator (positionAlloc);
3505 
3506  mobility.Install (apNode);
3507  mobility.Install (staNodes);
3508 
3509  lossModel->SetDefaultLoss (50.0);
3510  lossModel->SetLoss (apNode->GetObject<MobilityModel> (), staNodes.Get (1)->GetObject<MobilityModel> (),
3511  56.0, true); //+6 dB between AP <-> STA 2 compared to AP <-> STA 1
3512 }
3513 
3514 void
3516 {
3517  m_phyAp->Dispose ();
3518  m_phyAp = 0;
3519  m_apDev->Dispose ();
3520  m_apDev = 0;
3521  m_sta1Dev->Dispose ();
3522  m_sta1Dev = 0;
3523  m_sta2Dev->Dispose ();
3524  m_sta2Dev = 0;
3525 }
3526 
3527 void
3529 {
3530  RngSeedManager::SetSeed (1);
3531  RngSeedManager::SetRun (1);
3532  int64_t streamNumber = 0;
3533 
3534  Ptr<WifiPhy> phySta1 = m_sta1Dev->GetPhy ();
3535  Ptr<WifiPhy> phySta2 = m_sta2Dev->GetPhy ();
3536 
3537  m_phyAp->AssignStreams (streamNumber);
3538  phySta1->AssignStreams (streamNumber);
3539  phySta2->AssignStreams (streamNumber);
3540 
3541  m_phyAp->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerAp));
3542  m_phyAp->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerAp));
3543  m_phyAp->SetAttribute ("TxPowerLevels", UintegerValue (1));
3544 
3545  phySta1->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerStart));
3546  phySta1->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerEnd));
3547  phySta1->SetAttribute ("TxPowerLevels", UintegerValue (m_txPowerLevels));
3548 
3549  phySta2->SetAttribute ("TxPowerStart", DoubleValue (m_txPowerStart));
3550  phySta2->SetAttribute ("TxPowerEnd", DoubleValue (m_txPowerEnd));
3551  phySta2->SetAttribute ("TxPowerLevels", UintegerValue (m_txPowerLevels));
3552 
3553  Time relativeStart = MilliSeconds (0);
3554  if (setupBa)
3555  {
3556  //Set up BA for each station once the association phase has ended
3557  //so that a BA session is established when the MU-BAR is received.
3558  Simulator::Schedule (MilliSeconds (800), &TestUlOfdmaPowerControl::SetupBa, this, m_sta1Dev->GetAddress ());
3559  Simulator::Schedule (MilliSeconds (850), &TestUlOfdmaPowerControl::SetupBa, this, m_sta2Dev->GetAddress ());
3560  relativeStart = MilliSeconds (1000);
3561  }
3562  else
3563  {
3564  Ptr<ApWifiMac> apMac = DynamicCast<ApWifiMac> (m_apDev->GetMac ());
3565  NS_ASSERT (apMac);
3566  apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
3567  }
3568 
3569  Simulator::Schedule (relativeStart, &TestUlOfdmaPowerControl::ReplaceReceiveOkCallbackOfAp, this);
3570 
3571  {
3572  //Verify that the RSSI from STA 1 is consistent with what was requested
3573  std::vector<uint16_t> staIds {1};
3574  Simulator::Schedule (relativeStart, &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3575  }
3576 
3577  {
3578  //Verify that the RSSI from STA 2 is consistent with what was requested
3579  std::vector<uint16_t> staIds {2};
3580  Simulator::Schedule (relativeStart + MilliSeconds (20), &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3581  }
3582 
3583  {
3584  //Verify that the RSSI from STA 1 and 2 is consistent with what was requested
3585  std::vector<uint16_t> staIds {1, 2};
3586  Simulator::Schedule (relativeStart + MilliSeconds (40), &TestUlOfdmaPowerControl::SendMuBar, this, staIds);
3587  }
3588 
3589  Simulator::Stop (relativeStart + MilliSeconds (100));
3590  Simulator::Run ();
3591 }
3592 
3593 void
3595 {
3596  //Power configurations
3597  m_txPowerAp = 20; //dBm, so as to have -30 and -36 dBm at STA 1 and STA 2 resp.,
3598  //since path loss = 50 dB for AP <-> STA 1 and 56 dB for AP <-> STA 2
3599  m_txPowerStart = 15; //dBm
3600 
3601  //Requested UL RSSIs: should correspond to 20 dBm transmit power at STAs
3602  m_requestedRssiSta1 = -30.0;
3603  m_requestedRssiSta2 = -36.0;
3604 
3605  //Test single power level
3606  {
3607  //STA power configurations: 15 dBm only
3608  m_txPowerEnd = 15;
3609  m_txPowerLevels = 1;
3610 
3611  //Expected UL RSSIs, considering that the provided power is 5 dB less than requested,
3612  //regardless of the estimated path loss.
3613  m_rssiSta1 = -35.0; // 15 dBm - 50 dB
3614  m_rssiSta2 = -41.0; // 15 dBm - 56 dB
3615 
3616  RunOne (true);
3617  }
3618 
3619  //Test 2 dBm granularity
3620  {
3621  //STA power configurations: [15:2:25] dBm
3622  m_txPowerEnd = 25;
3623  m_txPowerLevels = 6;
3624 
3625  //Expected UL RSSIs, considering that the provided power (21 dBm) is 1 dB more than requested
3626  m_rssiSta1 = -29.0; // 21 dBm - 50 dB
3627  m_rssiSta2 = -35.0; // 21 dBm - 50 dB
3628 
3629  RunOne (false);
3630  }
3631 
3632  //Test 1 dBm granularity
3633  {
3634  //STA power configurations: [15:1:25] dBm
3635  m_txPowerEnd = 25;
3636  m_txPowerLevels = 11;
3637 
3638  //Expected UL RSSIs, considering that we can correctly tune the transmit power
3639  m_rssiSta1 = -30.0; // 20 dBm - 50 dB
3640  m_rssiSta2 = -36.0; // 20 dBm - 56 dB
3641 
3642  RunOne (false);
3643  }
3644 
3645  //Ask for different power levels (3 dB difference between HE_TB_PPDUs)
3646  {
3647  //STA power configurations: [15:1:25] dBm
3648  m_txPowerEnd = 25;
3649  m_txPowerLevels = 11;
3650 
3651  //Requested UL RSSIs
3652  m_requestedRssiSta1 = -28.0; //2 dB higher than previously -> Tx power = 22 dBm at STA 1
3653  m_requestedRssiSta2 = -37.0; //1 dB less than previously -> Tx power = 19 dBm at STA 2
3654 
3655  //Expected UL RSSIs, considering that we can correctly tune the transmit power
3656  m_rssiSta1 = -28.0; // 22 dBm - 50 dB
3657  m_rssiSta2 = -37.0; // 19 dBm - 56 dB
3658 
3659  RunOne (false);
3660  }
3661 
3662  Simulator::Destroy ();
3663 }
3664 
3665 
3673 {
3674 public:
3676 };
3677 
3679  : TestSuite ("wifi-phy-ofdma", UNIT)
3680 {
3681  AddTestCase (new TestDlOfdmaPhyTransmission, TestCase::QUICK);
3682  AddTestCase (new TestUlOfdmaPpduUid, TestCase::QUICK);
3683  AddTestCase (new TestMultipleHeTbPreambles, TestCase::QUICK);
3684  AddTestCase (new TestUlOfdmaPhyTransmission, TestCase::QUICK);
3685  AddTestCase (new TestPhyPaddingExclusion, TestCase::QUICK);
3686  AddTestCase (new TestUlOfdmaPowerControl, TestCase::QUICK); //FIXME: requires changes at MAC layer
3687 }
3688 
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...
virtual void DoRun(void)
Implementation to actually run 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
RuType ruType
RU type.
Definition: he-ru.h:67
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
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
uint32_t m_countRxBytesFromSta1
count RX bytes from STA 1
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:751
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:104
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.
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.
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...
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition: wifi-ppdu.h:38
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)
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
bool primary80MHz
true if the RU is allocated in the primary 80MHz channel
Definition: he-ru.h:66
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.
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
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
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
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
virtual void DoRun(void)
Implementation to actually run this TestCase.
void Reset(void)
Definition: wifi-phy.cc:1878
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.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
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
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:241
uint32_t m_countRxSuccessFromSta2
count RX success from STA 2
void SetDutyCycle(double value)
void SendTbPpdu(void)
Send TB-PPDU from both STAs.
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
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
Address GetAddress(void) const
Ptr< OfdmaSpectrumWifiPhy > m_phySta1
PHY of STA 1.
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.
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:1616
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 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
RU Specification.
Definition: he-ru.h:64
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
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.
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:1186
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
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.
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
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoDispose(void) override
Destructor implementation.
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
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:826
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:1184
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:41
virtual 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.
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.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
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:450
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
static const uint8_t DEFAULT_CHANNEL_NUMBER
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
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.
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 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
virtual 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)
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:1173
void SetPsdLimit(Ptr< WifiPhy > phy, double psdLimit)
Set the PSD limit.
Ptr< OfdmaSpectrumWifiPhy > m_phyAp
PHY of AP.
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.
virtual void SetChannelNumber(uint8_t id) override
Set channel number.
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
Wrapper to InterferenceHelper method.
std::size_t index
index (starting at 1)
Definition: he-ru.h:68
virtual void DoRun(void)
Implementation to actually run this TestCase.
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:1774
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
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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 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:47
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:1205
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 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
virtual 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...
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
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
virtual 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:1183
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
#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 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:2294
static WifiPhyOfdmaTestSuite wifiPhyOfdmaTestSuite
the test suite
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
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
virtual WifiPpduType GetType(void) const
Return the PPDU type (.
Definition: wifi-ppdu.cc:116
static const uint32_t DEFAULT_FREQUENCY
Make it easy to create and manage PHY objects for the spectrum model.