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/simulator.h"
26 #include "ns3/rng-seed-manager.h"
27 #include "ns3/constant-position-mobility-model.h"
28 #include "ns3/wifi-spectrum-signal-parameters.h"
29 #include "ns3/wifi-spectrum-value-helper.h"
30 #include "ns3/multi-model-spectrum-channel.h"
31 #include "ns3/spectrum-wifi-phy.h"
32 #include "ns3/nist-error-rate-model.h"
33 #include "ns3/wifi-mac-header.h"
34 #include "ns3/wifi-net-device.h"
35 #include "ns3/wifi-psdu.h"
36 #include "ns3/wifi-ppdu.h"
37 #include "ns3/waveform-generator.h"
38 #include "ns3/non-communicating-net-device.h"
39 
40 using namespace ns3;
41 
42 NS_LOG_COMPONENT_DEFINE ("WifiPhyOfdmaTest");
43 
44 static const uint32_t DEFAULT_FREQUENCY = 5180; // MHz
45 static const uint16_t DEFAULT_CHANNEL_WIDTH = 20; // MHz
46 
48 {
49 public:
55  OfdmaSpectrumWifiPhy (uint16_t staId);
56  virtual ~OfdmaSpectrumWifiPhy ();
57 
58 private:
65  uint16_t GetStaId (void) const override;
66 
67  uint16_t m_staId;
68 };
69 
71  : SpectrumWifiPhy (),
72  m_staId (staId)
73 {
74 }
75 
77 {
78 }
79 
80 uint16_t
82 {
83  return m_staId;
84 }
85 
93 {
94 public:
96  virtual ~TestDlOfdmaPhyTransmission ();
97 
98 private:
99  virtual void DoSetup (void);
100  virtual void DoRun (void);
101 
109  void RxSuccessSta1 (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
117  void RxSuccessSta2 (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
125  void RxSuccessSta3 (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
126 
131  void RxFailureSta1 (Ptr<WifiPsdu> psdu);
136  void RxFailureSta2 (Ptr<WifiPsdu> psdu);
141  void RxFailureSta3 (Ptr<WifiPsdu> psdu);
142 
149  void CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
156  void CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
163  void CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes);
164 
168  void ResetResults ();
169 
175  void SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2);
176 
182  void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
186  void StopInterference (void);
187 
191  void RunOne ();
192 
205 
215 
221 
222  uint16_t m_frequency;
223  uint16_t m_channelWidth;
225 };
226 
228  : TestCase ("DL-OFDMA PHY test"),
229  m_countRxSuccessSta1 (0),
230  m_countRxSuccessSta2 (0),
231  m_countRxSuccessSta3 (0),
232  m_countRxFailureSta1 (0),
233  m_countRxFailureSta2 (0),
234  m_countRxFailureSta3 (0),
235  m_countRxBytesSta1 (0),
236  m_countRxBytesSta2 (0),
237  m_countRxBytesSta3 (0),
238  m_frequency (DEFAULT_FREQUENCY),
239  m_channelWidth (DEFAULT_CHANNEL_WIDTH),
240  m_expectedPpduDuration (NanoSeconds (306400))
241 {
242 }
243 
244 void
246 {
253  m_countRxBytesSta1 = 0;
254  m_countRxBytesSta2 = 0;
255  m_countRxBytesSta3 = 0;
256 }
257 
258 void
259 TestDlOfdmaPhyTransmission::SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2)
260 {
261  NS_LOG_FUNCTION (this << rxStaId1 << rxStaId2);
262  WifiConstPsduMap psdus;
263  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_MU, 800, 1, 1, 0, m_channelWidth, false, false);
264  HeRu::RuType ruType = HeRu::RU_106_TONE;
265  if (m_channelWidth == 20)
266  {
267  ruType = HeRu::RU_106_TONE;
268  }
269  else if (m_channelWidth == 40)
270  {
271  ruType = HeRu::RU_242_TONE;
272  }
273  else if (m_channelWidth == 80)
274  {
275  ruType = HeRu::RU_484_TONE;
276  }
277  else if (m_channelWidth == 160)
278  {
279  ruType = HeRu::RU_996_TONE;
280  }
281  else
282  {
283  NS_ASSERT_MSG (false, "Unsupported channel width");
284  }
285 
286  HeRu::RuSpec ru1;
287  ru1.primary80MHz = true;
288  ru1.ruType = ruType;
289  ru1.index = 1;
290  txVector.SetRu (ru1, rxStaId1);
291  txVector.SetMode (WifiPhy::GetHeMcs7 (), rxStaId1);
292  txVector.SetNss (1, rxStaId1);
293 
294  HeRu::RuSpec ru2;
295  ru2.primary80MHz = (m_channelWidth == 160) ? false : true;
296  ru2.ruType = ruType;
297  ru2.index = 2;
298  txVector.SetRu (ru2, rxStaId2);
299  txVector.SetMode (WifiPhy::GetHeMcs9 (), rxStaId2);
300  txVector.SetNss (1, rxStaId2);
301 
302  Ptr<Packet> pkt1 = Create<Packet> (1000);
303  WifiMacHeader hdr1;
304  hdr1.SetType (WIFI_MAC_QOSDATA);
305  hdr1.SetQosTid (0);
306  hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:01"));
307  hdr1.SetSequenceNumber (1);
308  Ptr<WifiPsdu> psdu1 = Create<WifiPsdu> (pkt1, hdr1);
309  psdus.insert (std::make_pair (rxStaId1, psdu1));
310 
311  Ptr<Packet> pkt2 = Create<Packet> (1500);
312  WifiMacHeader hdr2;
313  hdr2.SetType (WIFI_MAC_QOSDATA);
314  hdr2.SetQosTid (0);
315  hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
316  hdr2.SetSequenceNumber (2);
317  Ptr<WifiPsdu> psdu2 = Create<WifiPsdu> (pkt2, hdr2);
318  psdus.insert (std::make_pair (rxStaId2, psdu2));
319 
320  m_phyAp->Send (psdus, txVector);
321 }
322 
323 void
325 {
326  m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
327  m_phyInterferer->SetPeriod (duration);
329  Simulator::Schedule (duration, &TestDlOfdmaPhyTransmission::StopInterference, this);
330 }
331 
332 void
334 {
336 }
337 
339 {
340  m_phyAp = 0;
341  m_phySta1 = 0;
342  m_phySta2 = 0;
343  m_phySta3 = 0;
344  m_phyInterferer = 0;
345 }
346 
347 void
348 TestDlOfdmaPhyTransmission::RxSuccessSta1 (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
349 {
350  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
352  m_countRxBytesSta1 += (psdu->GetSize () - 30);
353 }
354 
355 void
356 TestDlOfdmaPhyTransmission::RxSuccessSta2 (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
357 {
358  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
360  m_countRxBytesSta2 += (psdu->GetSize () - 30);
361 }
362 
363 void
364 TestDlOfdmaPhyTransmission::RxSuccessSta3 (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
365 {
366  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
368  m_countRxBytesSta3 += (psdu->GetSize () - 30);
369 }
370 
371 void
373 {
374  NS_LOG_FUNCTION (this << *psdu);
376 }
377 
378 void
380 {
381  NS_LOG_FUNCTION (this << *psdu);
383 }
384 
385 void
387 {
388  NS_LOG_FUNCTION (this << *psdu);
390 }
391 
392 void
393 TestDlOfdmaPhyTransmission::CheckResultsSta1 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
394 {
395  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta1, expectedRxSuccess, "The number of successfully received packets by STA 1 is not correct!");
396  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta1, expectedRxFailure, "The number of unsuccessfully received packets by STA 1 is not correct!");
397  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta1, expectedRxBytes, "The number of bytes received by STA 1 is not correct!");
398 }
399 
400 void
401 TestDlOfdmaPhyTransmission::CheckResultsSta2 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
402 {
403  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta2, expectedRxSuccess, "The number of successfully received packets by STA 2 is not correct!");
404  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta2, expectedRxFailure, "The number of unsuccessfully received packets by STA 2 is not correct!");
405  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta2, expectedRxBytes, "The number of bytes received by STA 2 is not correct!");
406 }
407 
408 void
409 TestDlOfdmaPhyTransmission::CheckResultsSta3 (uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
410 {
411  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessSta3, expectedRxSuccess, "The number of successfully received packets by STA 3 is not correct!");
412  NS_TEST_ASSERT_MSG_EQ (m_countRxFailureSta3, expectedRxFailure, "The number of unsuccessfully received packets by STA 3 is not correct!");
413  NS_TEST_ASSERT_MSG_EQ (m_countRxBytesSta3, expectedRxBytes, "The number of bytes received by STA 3 is not correct!");
414 }
415 
416 void
418 {
419  //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
420  Simulator::ScheduleNow (&TestDlOfdmaPhyTransmission::DoCheckPhyState, this, phy, expectedState);
421 }
422 
423 void
425 {
426  WifiPhyState currentState;
427  PointerValue ptr;
428  phy->GetAttribute ("State", ptr);
429  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
430  currentState = state->GetState ();
431  NS_LOG_FUNCTION (this << currentState);
432  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
433 }
434 
435 void
437 {
438  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
439  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
440  lossModel->SetFrequency (m_frequency * 1e6);
441  spectrumChannel->AddPropagationLossModel (lossModel);
442  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
443  spectrumChannel->SetPropagationDelayModel (delayModel);
444 
445  Ptr<Node> apNode = CreateObject<Node> ();
446  Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
447  m_phyAp = CreateObject<SpectrumWifiPhy> ();
450  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
451  m_phyAp->SetErrorRateModel (error);
452  m_phyAp->SetDevice (apDev);
453  m_phyAp->SetChannel (spectrumChannel);
454  Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
455  m_phyAp->SetMobility (apMobility);
456  apDev->SetPhy (m_phyAp);
457  apNode->AggregateObject (apMobility);
458  apNode->AddDevice (apDev);
459 
460  Ptr<Node> sta1Node = CreateObject<Node> ();
461  Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
462  m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
465  m_phySta1->SetErrorRateModel (error);
466  m_phySta1->SetDevice (sta1Dev);
467  m_phySta1->SetChannel (spectrumChannel);
470  Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
471  m_phySta1->SetMobility (sta1Mobility);
472  sta1Dev->SetPhy (m_phySta1);
473  sta1Node->AggregateObject (sta1Mobility);
474  sta1Node->AddDevice (sta1Dev);
475 
476  Ptr<Node> sta2Node = CreateObject<Node> ();
477  Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
478  m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
481  m_phySta2->SetErrorRateModel (error);
482  m_phySta2->SetDevice (sta2Dev);
483  m_phySta2->SetChannel (spectrumChannel);
486  Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
487  m_phySta2->SetMobility (sta2Mobility);
488  sta2Dev->SetPhy (m_phySta2);
489  sta2Node->AggregateObject (sta2Mobility);
490  sta2Node->AddDevice (sta2Dev);
491 
492  Ptr<Node> sta3Node = CreateObject<Node> ();
493  Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice> ();
494  m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy> (3);
497  m_phySta3->SetErrorRateModel (error);
498  m_phySta3->SetDevice (sta3Dev);
499  m_phySta3->SetChannel (spectrumChannel);
502  Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel> ();
503  m_phySta3->SetMobility (sta3Mobility);
504  sta3Dev->SetPhy (m_phySta3);
505  sta3Node->AggregateObject (sta3Mobility);
506  sta3Node->AddDevice (sta3Dev);
507 
508  Ptr<Node> interfererNode = CreateObject<Node> ();
509  Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
510  m_phyInterferer = CreateObject<WaveformGenerator> ();
511  m_phyInterferer->SetDevice (interfererDev);
512  m_phyInterferer->SetChannel (spectrumChannel);
514  interfererNode->AddDevice (interfererDev);
515 }
516 
517 void
519 {
520  RngSeedManager::SetSeed (1);
521  RngSeedManager::SetRun (1);
522  int64_t streamNumber = 0;
523  m_phyAp->AssignStreams (streamNumber);
524  m_phySta1->AssignStreams (streamNumber);
525  m_phySta2->AssignStreams (streamNumber);
526  m_phySta3->AssignStreams (streamNumber);
527 
530 
533 
536 
539 
540  Simulator::Schedule (Seconds (0.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
541 
542  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
543  //Each STA should receive its PSDU.
544  Simulator::Schedule (Seconds (1.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
545 
546  //Since it takes m_expectedPpduDuration to transmit the PPDU,
547  //all 3 PHYs should be back to IDLE at the same time,
548  //even the PHY that has no PSDU addressed to it.
555 
556  //One PSDU of 1000 bytes should have been successfully received by STA 1
557  Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
558  //One PSDU of 1500 bytes should have been successfully received by STA 2
559  Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 1, 0, 1500);
560  //No PSDU should have been received by STA 3
561  Simulator::Schedule (Seconds (1.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
562 
563  Simulator::Schedule (Seconds (1.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
564 
565  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 3:
566  //STA 1 should receive its PSDU, whereas STA 2 should not receive any PSDU
567  //but should keep its PHY busy during all PPDU duration.
568  Simulator::Schedule (Seconds (2.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 3);
569 
570  //Since it takes m_expectedPpduDuration to transmit the PPDU,
571  //all 3 PHYs should be back to IDLE at the same time,
572  //even the PHY that has no PSDU addressed to it.
579 
580  //One PSDU of 1000 bytes should have been successfully received by STA 1
581  Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
582  //No PSDU should have been received by STA 2
583  Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 0, 0);
584  //One PSDU of 1500 bytes should have been successfully received by STA 3
585  Simulator::Schedule (Seconds (2.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 1, 0, 1500);
586 
587  Simulator::Schedule (Seconds (2.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
588 
589  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
590  Simulator::Schedule (Seconds (3.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
591 
592  //A strong non-wifi interference is generated on RU 1 during PSDU reception
593  BandInfo bandInfo;
594  bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
595  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
596  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
597  Bands bands;
598  bands.push_back (bandInfo);
599 
600  Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
601  Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
602  double interferencePower = 0.1; //watts
603  *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
604 
605  Simulator::Schedule (Seconds (3.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
606 
607  //Since it takes m_expectedPpduDuration to transmit the PPDU,
608  //both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
609  //even the PHY that has no PSDU addressed to it.
616 
617  //One PSDU of 1000 bytes should have been unsuccessfully received by STA 1 (since interference occupies RU 1)
618  Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 0, 1, 0);
619  //One PSDU of 1500 bytes should have been successfully received by STA 2
620  Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 1, 0, 1500);
621  //No PSDU should have been received by STA3
622  Simulator::Schedule (Seconds (3.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
623 
624  Simulator::Schedule (Seconds (3.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
625 
626  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
627  Simulator::Schedule (Seconds (4.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
628 
629  //A strong non-wifi interference is generated on RU 2 during PSDU reception
630  bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
631  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
632  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
633  bands.clear ();
634  bands.push_back (bandInfo);
635 
636  Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel> (bands);
637  Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue> (SpectrumInterferenceRu2);
638  *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
639 
640  Simulator::Schedule (Seconds (4.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
641 
642  //Since it takes m_expectedPpduDuration to transmit the PPDU,
643  //both PHYs should be back to IDLE (or CCA_BUSY if interference on the primary 20 MHz) at the same time,
644  //even the PHY that has no PSDU addressed to it.
651 
652  //One PSDU of 1000 bytes should have been successfully received by STA 1
653  Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 1, 0, 1000);
654  //One PSDU of 1500 bytes should have been unsuccessfully received by STA 2 (since interference occupies RU 2)
655  Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 1, 0);
656  //No PSDU should have been received by STA3
657  Simulator::Schedule (Seconds (4.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
658 
659  Simulator::Schedule (Seconds (4.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
660 
661  //Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
662  Simulator::Schedule (Seconds (5.0), &TestDlOfdmaPhyTransmission::SendMuPpdu, this, 1, 2);
663 
664  //A strong non-wifi interference is generated on the full band during PSDU reception
665  bandInfo.fc = m_frequency * 1e6;
666  bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
667  bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
668  bands.clear ();
669  bands.push_back (bandInfo);
670 
671  Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel> (bands);
672  Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue> (SpectrumInterferenceAll);
673  *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
674 
675  Simulator::Schedule (Seconds (5.0) + MicroSeconds (50), &TestDlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
676 
677  //Since it takes m_expectedPpduDuration to transmit the PPDU,
678  //both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
679  //even the PHY that has no PSDU addressed to it.
686 
687  //One PSDU of 1000 bytes should have been unsuccessfully received by STA 1 (since interference occupies RU 1)
688  Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta1, this, 0, 1, 0);
689  //One PSDU of 1500 bytes should have been unsuccessfully received by STA 2 (since interference occupies RU 2)
690  Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta2, this, 0, 1, 0);
691  //No PSDU should have been received by STA3
692  Simulator::Schedule (Seconds (5.1), &TestDlOfdmaPhyTransmission::CheckResultsSta3, this, 0, 0, 0);
693 
694  Simulator::Schedule (Seconds (5.5), &TestDlOfdmaPhyTransmission::ResetResults, this);
695 
696  Simulator::Run ();
697 }
698 
699 void
701 {
702  m_frequency = 5180;
703  m_channelWidth = 20;
705  RunOne ();
706 
707  m_frequency = 5190;
708  m_channelWidth = 40;
710  RunOne ();
711 
712  m_frequency = 5210;
713  m_channelWidth = 80;
715  RunOne ();
716 
717  m_frequency = 5250;
718  m_channelWidth = 160;
720  RunOne ();
721 
722  Simulator::Destroy ();
723 }
724 
732 {
733 public:
735 };
736 
738  : TestSuite ("wifi-phy-ofdma", UNIT)
739 {
740  AddTestCase (new TestDlOfdmaPhyTransmission, TestCase::QUICK);
741 }
742 
void CheckResultsSta2(uint32_t expectedRxSuccess, uint32_t expectedRxFailure, uint32_t expectedRxBytes)
Check the results for STA 2.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
RuType ruType
RU type.
Definition: he-ru.h:67
void SendMuPpdu(uint16_t rxStaId1, uint16_t rxStaId2)
Send MU-PPDU function.
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
Ptr< T > Get(void) const
Definition: pointer.h:201
void StopInterference(void)
Stop interference function.
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...
uint16_t GetStaId(void) const override
Return the STA ID that has been assigned to the station this PHY belongs to.
uint32_t m_countRxBytesSta2
count RX bytes for STA 2
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Definition: wifi-ppdu.h:33
A suite of tests to run.
Definition: test.h:1343
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
Time m_expectedPpduDuration
expected duration to send MU PPDU
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:589
uint32_t m_countRxSuccessSta3
count RX success for STA 3
#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.
uint16_t m_staId
ID of the STA to which this PHY belongs to.
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:765
Ptr< WaveformGenerator > m_phyInterferer
PHY of interferer.
uint32_t m_countRxBytesSta3
count RX bytes for STA 3
The 5 GHz band.
Definition: wifi-phy-band.h:35
encapsulates test code
Definition: test.h:1153
void AddPropagationLossModel(Ptr< PropagationLossModel > loss)
Add the single-frequency propagation loss model to be used.
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 SetDutyCycle(double value)
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.
void DoCheckPhyState(Ptr< OfdmaSpectrumWifiPhy > phy, WifiPhyState expectedState)
Check the PHY state now.
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:753
uint32_t m_countRxBytesSta1
count RX bytes for STA 1
void RxSuccessSta3(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function for STA 3.
RU Specification.
Definition: he-ru.h:64
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
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
uint32_t m_countRxSuccessSta1
count RX success for STA 1
The PHY layer has sense the medium busy through the CCA mechanism.
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.
virtual void SetFrequency(uint16_t freq)
uint16_t m_channelWidth
channel width in MHz
void SetNss(uint8_t nss)
Sets the number of Nss.
uint32_t m_countRxFailureSta1
count RX failure for STA 1
virtual void ConfigureStandardAndBand(WifiPhyStandard standard, WifiPhyBand band)
Configure the PHY-level parameters for different Wi-Fi standard.
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:784
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double fl
lower limit of subband
Hold objects of type Ptr<T>.
Definition: pointer.h:36
virtual void DoRun(void)
Implementation to actually run this TestCase.
The PHY layer is IDLE.
WifiPhyState
The state of the PHY layer.
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:41
an EUI-48 address
Definition: mac48-address.h:43
void GenerateInterference(Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
wifi PHY OFDMA Test Suite
Ptr< OfdmaSpectrumWifiPhy > m_phySta2
PHY of STA 2.
uint32_t m_countRxFailureSta3
count RX failure for STA 3
virtual void SetChannelWidth(uint16_t channelwidth)
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
#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.
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:583
This objects implements the PHY state machine of the Wifi device.
WifiPhyState GetState(void) const
Return the current state of WifiPhy.
void RxSuccessSta2(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function for STA 2.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
static const uint16_t DEFAULT_CHANNEL_WIDTH
void SetPropagationDelayModel(Ptr< PropagationDelayModel > delay)
Set the propagation delay model to be used.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
The PHY layer is receiving a packet.
std::size_t index
index (starting at 1)
Definition: he-ru.h:68
void Send(Ptr< const WifiPsdu > psdu, WifiTxVector txVector)
Definition: wifi-phy.cc:2707
void RxSuccessSta1(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function for STA 1.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
void ResetResults()
Reset the results.
OfdmaSpectrumWifiPhy(uint16_t staId)
Constructor.
double fh
upper limit of subband
void SetChannel(const Ptr< SpectrumChannel > channel)
Set the SpectrumChannel this SpectrumWifiPhy is to be connected to.
The building block of a SpectrumModel.
void RxFailureSta1(Ptr< WifiPsdu > psdu)
Receive failure function for STA 1.
void SetRu(HeRu::RuSpec ru, uint16_t staId)
Set the RU specification for the STA-ID.
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
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:4758
static WifiPhyOfdmaTestSuite wifiPhyOfdmaTestSuite
the test suite
Implements the IEEE 802.11 MAC header.
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...
static const uint32_t DEFAULT_FREQUENCY