A Discrete-Event Network Simulator
API
wifi-phy-reception-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2018 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/mobility-helper.h"
23 #include "ns3/multi-model-spectrum-channel.h"
24 #include "ns3/config.h"
25 #include "ns3/ap-wifi-mac.h"
26 #include "ns3/packet-socket-address.h"
27 #include "ns3/packet-socket-client.h"
28 #include "ns3/packet-socket-helper.h"
29 #include "ns3/packet-socket-server.h"
30 #include "ns3/test.h"
31 #include "ns3/double.h"
32 #include "ns3/boolean.h"
33 #include "ns3/pointer.h"
34 #include "ns3/rng-seed-manager.h"
35 #include "ns3/spectrum-wifi-helper.h"
36 #include "ns3/wifi-net-device.h"
37 #include "ns3/wifi-spectrum-value-helper.h"
38 #include "ns3/spectrum-wifi-phy.h"
39 #include "ns3/interference-helper.h"
40 #include "ns3/nist-error-rate-model.h"
41 #include "ns3/wifi-mac-header.h"
42 #include "ns3/ampdu-tag.h"
43 #include "ns3/wifi-spectrum-signal-parameters.h"
44 #include "ns3/wifi-utils.h"
45 #include "ns3/threshold-preamble-detection-model.h"
46 #include "ns3/simple-frame-capture-model.h"
47 #include "ns3/wifi-mac-queue-item.h"
48 #include "ns3/mpdu-aggregator.h"
49 #include "ns3/wifi-psdu.h"
50 #include "ns3/he-ppdu.h"
51 #include "ns3/he-phy.h"
52 
53 using namespace ns3;
54 
55 NS_LOG_COMPONENT_DEFINE ("WifiPhyReceptionTest");
56 
57 static const uint8_t CHANNEL_NUMBER = 36;
58 static const uint32_t FREQUENCY = 5180; // MHz
59 static const uint16_t CHANNEL_WIDTH = 20; // MHz
60 static const uint16_t GUARD_WIDTH = CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
61 
69 {
70 public:
73 
74 protected:
75  void DoSetup (void) override;
76  void DoTeardown (void) override;
82  void SendPacket (double rxPowerDbm);
90  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
91  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
96  void RxFailure (Ptr<WifiPsdu> psdu);
97  uint32_t m_countRxSuccess;
98  uint32_t m_countRxFailure;
99 
100 private:
101  void DoRun (void) override;
102 
107  void CheckPhyState (WifiPhyState expectedState);
112  void DoCheckPhyState (WifiPhyState expectedState);
118  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
119 
120  uint64_t m_uid;
121 };
122 
124  : TestCase ("Threshold preamble detection model test when no frame capture model is applied"),
125  m_countRxSuccess (0),
126  m_countRxFailure (0),
127  m_uid (0)
128 {
129 }
130 
131 void
133 {
134  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
135 
136  Ptr<Packet> pkt = Create<Packet> (1000);
137  WifiMacHeader hdr;
138 
140  hdr.SetQosTid (0);
141 
142  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
143  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
144 
145  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
146 
147  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
148 
149  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
150  txParams->psd = txPowerSpectrum;
151  txParams->txPhy = 0;
152  txParams->duration = txDuration;
153  txParams->ppdu = ppdu;
154 
155  m_phy->StartRx (txParams);
156 }
157 
158 void
160 {
161  //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
162  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithoutFrameCapture::DoCheckPhyState, this, expectedState);
163 }
164 
165 void
167 {
168  WifiPhyState currentState;
169  PointerValue ptr;
170  m_phy->GetAttribute ("State", ptr);
171  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
172  currentState = state->GetState ();
173  NS_LOG_FUNCTION (this << currentState);
174  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
175 }
176 
177 void
178 TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
179 {
180  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
181  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
182 }
183 
184 void
186  WifiTxVector txVector, std::vector<bool> statusPerMpdu)
187 {
188  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
190 }
191 
192 void
194 {
195  NS_LOG_FUNCTION (this << *psdu);
197 }
198 
200 {
201  m_phy = 0;
202 }
203 
204 void
206 {
207  m_phy = CreateObject<SpectrumWifiPhy> ();
209  Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper> ();
210  m_phy->SetInterferenceHelper (interferenceHelper);
211  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
212  m_phy->SetErrorRateModel (error);
216 
217  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
218  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
219  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
220  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
221 }
222 
223 void
225 {
226  m_phy->Dispose ();
227  m_phy = 0;
228 }
229 
230 void
232 {
233  RngSeedManager::SetSeed (1);
234  RngSeedManager::SetRun (1);
235  int64_t streamNumber = 0;
236  m_phy->AssignStreams (streamNumber);
237 
238  //RX power > CCA-ED > CCA-PD
239  double rxPowerDbm = -50;
240 
241  // CASE 1: send one packet and check PHY state:
242  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
243  // otherwise it should be IDLE.
244 
245  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
246  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
249  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
252  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
255  // Packet should have been successfully received
256  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
257 
258  // CASE 2: send two packets with same power within the 4us window and check PHY state:
259  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
260  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
261  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
262 
263  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
264  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
265  // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
268  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
271  // No more packet should have been successfully received, and since preamble detection did not pass, the packet should not have been counted as a failure
272  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
273 
274  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
275  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
276  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
277  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
278 
279  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
280  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
281  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
284  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
287  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
288  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
289 
290  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
291  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
292  // but payload reception should fail (SNR too low to decode the modulation).
293 
294  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
295  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
296  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
299  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
302  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
303  // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 2us.
308  // In this case, the first packet should be marked as a failure
309  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
310 
311  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
312  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
313  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
314  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
315 
316  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
317  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
318  // At 6us (hence 4us after the last signal is received), no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
321  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
324  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
325  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
326 
327  // CCA-PD < RX power < CCA-ED
328  rxPowerDbm = -70;
329 
330  // CASE 6: send one packet and check PHY state:
331  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
332  // otherwise it should be IDLE.
333 
334  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
335  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
338  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
341  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
344  // Packet should have been successfully received
345  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
346 
347  // CASE 7: send two packets with same power within the 4us window and check PHY state:
348  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
349  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
350 
351  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
352  Simulator::Schedule (Seconds (7.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
353  // At 4us, STA PHY STATE should stay IDLE
355  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
356  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
357 
358  // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
359  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
360  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
361 
362  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
363  Simulator::Schedule (Seconds (8.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
364  // At 4us, STA PHY STATE should stay IDLE
366  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
367  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
368 
369  // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
370  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
371  // but payload reception should fail (SNR too low to decode the modulation).
372 
373  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
374  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
375  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
378  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
381  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
384  // In this case, the first packet should be marked as a failure
385  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
386 
387  // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY state:
388  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
389  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
390 
391  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
392  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
393  // At 4us, STA PHY STATE should stay IDLE
395  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
396  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
397 
398  // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
399  // preamble detection should succeed and PHY state should move to RX.
400 
401  rxPowerDbm = -81;
402 
403  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
404  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
407  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
410  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
413 
414  // RX power < CCA-PD < CCA-ED
415  rxPowerDbm = -83;
416 
417  //CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
418  //preamble detection should fail and PHY should be kept in IDLE state.
419 
420  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
421  // At 4us, STA PHY state should be IDLE
423 
424  Simulator::Run ();
425  Simulator::Destroy ();
426 }
427 
435 {
436 public:
439 
440 protected:
441  void DoSetup (void) override;
442  void DoTeardown (void) override;
448  void SendPacket (double rxPowerDbm);
456  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
457  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
462  void RxFailure (Ptr<WifiPsdu> psdu);
463  uint32_t m_countRxSuccess;
464  uint32_t m_countRxFailure;
465 
466 private:
467  void DoRun (void) override;
468 
473  void CheckPhyState (WifiPhyState expectedState);
478  void DoCheckPhyState (WifiPhyState expectedState);
484  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
485 
486  uint64_t m_uid;
487 };
488 
490 : TestCase ("Threshold preamble detection model test when simple frame capture model is applied"),
491  m_countRxSuccess (0),
492  m_countRxFailure (0),
493  m_uid (0)
494 {
495 }
496 
497 void
499 {
500  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
501 
502  Ptr<Packet> pkt = Create<Packet> (1000);
503  WifiMacHeader hdr;
504 
506  hdr.SetQosTid (0);
507 
508  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
509  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
510 
511  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
512 
513  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
514 
515  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
516  txParams->psd = txPowerSpectrum;
517  txParams->txPhy = 0;
518  txParams->duration = txDuration;
519  txParams->ppdu = ppdu;
520 
521  m_phy->StartRx (txParams);
522 }
523 
524 void
526 {
527  //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
528  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithFrameCapture::DoCheckPhyState, this, expectedState);
529 }
530 
531 void
533 {
534  WifiPhyState currentState;
535  PointerValue ptr;
536  m_phy->GetAttribute ("State", ptr);
537  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
538  currentState = state->GetState ();
539  NS_LOG_FUNCTION (this << currentState);
540  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
541 }
542 
543 void
544 TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
545 {
546  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
547  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
548 }
549 
550 void
552  WifiTxVector txVector, std::vector<bool> statusPerMpdu)
553 {
554  NS_LOG_FUNCTION (this << *psdu << txVector);
556 }
557 
558 void
560 {
561  NS_LOG_FUNCTION (this << *psdu);
563 }
564 
566 {
567  m_phy = 0;
568 }
569 
570 void
572 {
573  m_phy = CreateObject<SpectrumWifiPhy> ();
575  Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper> ();
576  m_phy->SetInterferenceHelper (interferenceHelper);
577  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
578  m_phy->SetErrorRateModel (error);
582 
583  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
584  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
585  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
586  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
587 
588  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
589  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
590  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
591  m_phy->SetFrameCaptureModel (frameCaptureModel);
592 }
593 
594 void
596 {
597  m_phy->Dispose ();
598  m_phy = 0;
599 }
600 
601 void
603 {
604  RngSeedManager::SetSeed (1);
605  RngSeedManager::SetRun (1);
606  int64_t streamNumber = 1;
607  m_phy->AssignStreams (streamNumber);
608 
609  //RX power > CCA-ED > CCA-PD
610  double rxPowerDbm = -50;
611 
612  // CASE 1: send one packet and check PHY state:
613  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
614  // otherwise it should be IDLE.
615 
616  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
617  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
620  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
623  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
626  // Packet should have been successfully received
627  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
628 
629  // CASE 2: send two packets with same power within the 4us window and check PHY state:
630  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
631  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
632  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
633 
634  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
635  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
636  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
639  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
642  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
643  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
644 
645  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
646  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
647  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
648  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
649 
650  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
651  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
652  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
655  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
658  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
659  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
660 
661  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
662  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
663  // but payload reception should fail (SNR too low to decode the modulation).
664 
665  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
666  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
667  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
670  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
673  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
674  // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 2us.
679  // In this case, the first packet should be marked as a failure
680  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
681 
682  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
683  // PHY preamble detection should switch because a higher packet is received within the 4us window,
684  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
685  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
686 
687  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
688  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
689  // At 4us, STA PHY STATE should stay IDLE
691  // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
694  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
697  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
698  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
699 
700  // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY state:
701  // PHY preamble detection should switch because a higher packet is received within the 4us window,
702  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
703  // Payload reception should fail (SNR too low to decode the modulation).
704 
705  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
706  Simulator::Schedule (Seconds (6.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
707  // At 4us, STA PHY STATE should stay IDLE
709  // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
712  // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
715  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
718  // In this case, the second packet should be marked as a failure
719  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
720 
721  // CASE 7: send two packets with same power at the exact same time and check PHY state:
722  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
723  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
724  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
725 
726  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
727  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
728  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
731  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
734  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
735  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
736 
737  // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY state:
738  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
739  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
740  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
741 
742  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
743  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
744  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
747  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
750  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
751  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
752 
753  // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY state:
754  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
755  // but payload reception should fail (SNR too low to decode the modulation).
756 
757  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
758  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
759  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
762  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
765  // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
768  // In this case, the first packet should be marked as a failure
769  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
770 
771  // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY state:
772  // PHY preamble detection should switch because a higher packet is received within the 4us window,
773  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
774  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
775 
776  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
777  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
778  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
781  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
784  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
785  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
786 
787  // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY state:
788  // PHY preamble detection should switch because a higher packet is received within the 4us window,
789  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
790  // Payload reception should fail (SNR too low to decode the modulation).
791 
792  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
793  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
794  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
797  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
800  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
803  // In this case, the second packet should be marked as a failure
804  Simulator::Schedule (Seconds (11.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 4);
805 
806  // CCA-PD < RX power < CCA-ED
807  rxPowerDbm = -70;
808 
809  // CASE 12: send one packet and check PHY state:
810  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
811  // otherwise it should be IDLE.
812 
813  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
814  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
817  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
820  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
823  // Packet should have been successfully received
824  Simulator::Schedule (Seconds (12.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
825 
826  // CASE 13: send two packets with same power within the 4us window and check PHY state:
827  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
828  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
829 
830  Simulator::Schedule (Seconds (13.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
831  Simulator::Schedule (Seconds (13.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
832  // At 4us, STA PHY STATE should stay IDLE
834  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
835  Simulator::Schedule (Seconds (13.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
836 
837  // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
838  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
839  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
840 
841  Simulator::Schedule (Seconds (14.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
842  Simulator::Schedule (Seconds (14.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
843  // At 4us, STA PHY STATE should stay IDLE
845  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
846  Simulator::Schedule (Seconds (14.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
847 
848  // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
849  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
850  // but payload reception should fail (SNR too low to decode the modulation).
851 
852  Simulator::Schedule (Seconds (15.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
853  Simulator::Schedule (Seconds (15.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
854  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
857  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
860  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
863  // In this case, the first packet should be marked as a failure
864  Simulator::Schedule (Seconds (15.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
865 
866  // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY state:
867  // PHY preamble detection should switch because a higher packet is received within the 4us window,
868  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB).
869  // PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
870 
871  Simulator::Schedule (Seconds (16.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
872  Simulator::Schedule (Seconds (16.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
873  // At 4us, STA PHY STATE should stay IDLE
875  // At 6us, STA PHY STATE should stay IDLE
877  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
878  Simulator::Schedule (Seconds (16.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
879 
880  // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY state:
881  // PHY preamble detection should switch because a higher packet is received within the 4us window,
882  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
883  // Payload reception should fail (SNR too low to decode the modulation).
884 
885  Simulator::Schedule (Seconds (17.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
886  Simulator::Schedule (Seconds (17.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
887  // At 4us, STA PHY STATE should stay IDLE
889  // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
892  // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
895  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
898  // In this case, the second packet should be marked as a failure
899  Simulator::Schedule (Seconds (17.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 6);
900 
901  rxPowerDbm = -50;
902  // CASE 18: send two packets with second one 50 dB higher within the 4us window
903 
904  Simulator::Schedule (Seconds (18.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
905  Simulator::Schedule (Seconds (18.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
906  // The second packet should be received successfully
907  Simulator::Schedule (Seconds (18.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 6);
908 
909  // CASE 19: send two packets with second one 10 dB higher within the 4us window
910 
911  Simulator::Schedule (Seconds (19.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
912  Simulator::Schedule (Seconds (19.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
913  // The second packet should be captured, but not decoded since SNR to low for used MCS
914  Simulator::Schedule (Seconds (19.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 7);
915 
916  // CASE 20: send two packets with second one 50 dB higher in the same time
917 
918  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
919  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
920  // The second packet should be received successfully, same as in CASE 13
921  Simulator::Schedule (Seconds (20.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 7);
922 
923  // CASE 21: send two packets with second one 10 dB higher in the same time
924 
925  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
926  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
927  // The second packet should be captured, but not decoded since SNR to low for used MCS, same as in CASE 19
928  Simulator::Schedule (Seconds (21.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 8);
929 
930  Simulator::Run ();
931  Simulator::Destroy ();
932 }
933 
941 {
942 public:
944  virtual ~TestSimpleFrameCaptureModel ();
945 
946 protected:
947  void DoSetup (void) override;
948  void DoTeardown (void) override;
949 
950 private:
951  void DoRun (void) override;
952 
956  void Reset (void);
962  void SendPacket (double rxPowerDbm, uint32_t packetSize);
970  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
971  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
978 
990  void Expect1000BPacketDropped ();
994  void Expect1500BPacketDropped ();
995 
997 
1002 
1003  uint64_t m_uid;
1004 };
1005 
1007 : TestCase ("Simple frame capture model test"),
1008  m_rxSuccess1000B (false),
1009  m_rxSuccess1500B (false),
1010  m_rxDropped1000B (false),
1011  m_rxDropped1500B (false),
1012  m_uid (0)
1013 {
1014 }
1015 
1016 void
1018 {
1019  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
1020 
1021  Ptr<Packet> pkt = Create<Packet> (packetSize);
1022  WifiMacHeader hdr;
1023 
1024  hdr.SetType (WIFI_MAC_QOSDATA);
1025  hdr.SetQosTid (0);
1026 
1027  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1028  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1029 
1030  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1031 
1032  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1033 
1034  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1035  txParams->psd = txPowerSpectrum;
1036  txParams->txPhy = 0;
1037  txParams->duration = txDuration;
1038  txParams->ppdu = ppdu;
1039 
1040  m_phy->StartRx (txParams);
1041 }
1042 
1043 void
1045  WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1046 {
1047  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
1048  NS_ASSERT (!psdu->IsAggregate () || psdu->IsSingle ());
1049  if (psdu->GetSize () == 1030)
1050  {
1051  m_rxSuccess1000B = true;
1052  }
1053  else if (psdu->GetSize () == 1530)
1054  {
1055  m_rxSuccess1500B = true;
1056  }
1057 }
1058 
1059 void
1061 {
1062  NS_LOG_FUNCTION (this << p << reason);
1063  if (p->GetSize () == 1030)
1064  {
1065  m_rxDropped1000B = true;
1066  }
1067  else if (p->GetSize () == 1530)
1068  {
1069  m_rxDropped1500B = true;
1070  }
1071 }
1072 
1073 void
1075 {
1076  m_rxSuccess1000B = false;
1077  m_rxSuccess1500B = false;
1078  m_rxDropped1000B = false;
1079  m_rxDropped1500B = false;
1080 }
1081 
1082 void
1084 {
1085  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1000B, true, "Didn't receive 1000B packet");
1086 }
1087 
1088 void
1090 {
1091  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1500B, true, "Didn't receive 1500B packet");
1092 }
1093 void
1095 {
1096  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1000B, true, "Didn't drop 1000B packet");
1097 }
1098 
1099 void
1101 {
1102  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1500B, true, "Didn't drop 1500B packet");
1103 }
1104 
1106 {
1107  m_phy = 0;
1108 }
1109 
1110 void
1112 {
1113  m_phy = CreateObject<SpectrumWifiPhy> ();
1115  Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper> ();
1116  m_phy->SetInterferenceHelper (interferenceHelper);
1117  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1118  m_phy->SetErrorRateModel (error);
1120 
1123 
1124  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1125  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1126  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1127 
1128  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1129  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1130  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1131  m_phy->SetFrameCaptureModel (frameCaptureModel);
1132 }
1133 
1134 void
1136 {
1137  m_phy->Dispose ();
1138  m_phy = 0;
1139 }
1140 
1141 void
1143 {
1144  RngSeedManager::SetSeed (1);
1145  RngSeedManager::SetRun (1);
1146  int64_t streamNumber = 2;
1147  double rxPowerDbm = -30;
1148  m_phy->AssignStreams (streamNumber);
1149 
1150  // CASE 1: send two packets with same power within the capture window:
1151  // PHY should not switch reception because they have same power.
1152 
1153  Simulator::Schedule (Seconds (1.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1154  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1500);
1155  Simulator::Schedule (Seconds (1.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1156  Simulator::Schedule (Seconds (1.2), &TestSimpleFrameCaptureModel::Reset, this);
1157 
1158  // CASE 2: send two packets with second one 6 dB weaker within the capture window:
1159  // PHY should not switch reception because first one has higher power.
1160 
1161  Simulator::Schedule (Seconds (2.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1162  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm - 6, 1500);
1163  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1000BPacketReceived, this);
1164  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1165  Simulator::Schedule (Seconds (2.2), &TestSimpleFrameCaptureModel::Reset, this);
1166 
1167  // CASE 3: send two packets with second one 6 dB higher within the capture window:
1168  // PHY should switch reception because the second one has a higher power.
1169 
1170  Simulator::Schedule (Seconds (3.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1171  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1172  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1000BPacketDropped, this);
1173  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1500BPacketReceived, this);
1174  Simulator::Schedule (Seconds (3.2), &TestSimpleFrameCaptureModel::Reset, this);
1175 
1176  // CASE 4: send two packets with second one 6 dB higher after the capture window:
1177  // PHY should not switch reception because capture window duration has elapsed when the second packet arrives.
1178 
1179  Simulator::Schedule (Seconds (4.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1180  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1181  Simulator::Schedule (Seconds (4.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1182  Simulator::Schedule (Seconds (4.2), &TestSimpleFrameCaptureModel::Reset, this);
1183 
1184  Simulator::Run ();
1185  Simulator::Destroy ();
1186 }
1187 
1195 {
1196 public:
1198  virtual ~TestPhyHeadersReception ();
1199 
1200 protected:
1201  void DoSetup (void) override;
1202  void DoTeardown (void) override;
1208  void SendPacket (double rxPowerDbm);
1209 
1210 private:
1211  void DoRun (void) override;
1212 
1217  void CheckPhyState (WifiPhyState expectedState);
1222  void DoCheckPhyState (WifiPhyState expectedState);
1223 
1224  uint64_t m_uid;
1225 };
1226 
1228 : TestCase ("PHY headers reception test"),
1229  m_uid (0)
1230 {
1231 }
1232 
1233 void
1235 {
1236  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
1237 
1238  Ptr<Packet> pkt = Create<Packet> (1000);
1239  WifiMacHeader hdr;
1240 
1241  hdr.SetType (WIFI_MAC_QOSDATA);
1242  hdr.SetQosTid (0);
1243 
1244  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1245  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1246 
1247  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1248 
1249  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1250 
1251  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1252  txParams->psd = txPowerSpectrum;
1253  txParams->txPhy = 0;
1254  txParams->duration = txDuration;
1255  txParams->ppdu = ppdu;
1256 
1257  m_phy->StartRx (txParams);
1258 }
1259 
1260 void
1262 {
1263  //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
1264  Simulator::ScheduleNow (&TestPhyHeadersReception::DoCheckPhyState, this, expectedState);
1265 }
1266 
1267 void
1269 {
1270  WifiPhyState currentState;
1271  PointerValue ptr;
1272  m_phy->GetAttribute ("State", ptr);
1273  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1274  currentState = state->GetState ();
1275  NS_LOG_FUNCTION (this << currentState);
1276  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1277 }
1278 
1279 
1281 {
1282  m_phy = 0;
1283 }
1284 
1285 void
1287 {
1288  m_phy = CreateObject<SpectrumWifiPhy> ();
1290  Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper> ();
1291  m_phy->SetInterferenceHelper (interferenceHelper);
1292  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1293  m_phy->SetErrorRateModel (error);
1295 }
1296 
1297 void
1299 {
1300  m_phy->Dispose ();
1301  m_phy = 0;
1302 }
1303 
1304 void
1306 {
1307  RngSeedManager::SetSeed (1);
1308  RngSeedManager::SetRun (1);
1309  int64_t streamNumber = 0;
1310  m_phy->AssignStreams (streamNumber);
1311 
1312  // RX power > CCA-ED
1313  double rxPowerDbm = -50;
1314 
1315  // CASE 1: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1316  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1317 
1318  Simulator::Schedule (Seconds (1.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1319  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1320  // At 10 us, STA PHY STATE should be CCA_BUSY.
1321  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1322  // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to CCA_BUSY.
1323  Simulator::Schedule (Seconds (1.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1324  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10 = 162.8us.
1325  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1326  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1327 
1328  // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1329  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1330 
1331  Simulator::Schedule (Seconds (2.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1332  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1333  // At 10 us, STA PHY STATE should be CCA_BUSY.
1334  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1335  // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception should have succeeded.
1336  Simulator::Schedule (Seconds (2.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1337  Simulator::Schedule (Seconds (2.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1338  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1339  // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 10us.
1340  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1341  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1342  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1343  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1344 
1345  // CASE 3: send one packet followed by a second one with same power between the end of L-SIG and the start of HE-SIG of the first packet:
1346  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1347 
1348  Simulator::Schedule (Seconds (3.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1349  Simulator::Schedule (Seconds (3.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1350  // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be kept to CCA_BUSY.
1351  Simulator::Schedule (Seconds (3.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1352  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1353  // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
1354  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1355  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1356  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1357  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1358 
1359  // CASE 4: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the start of HE-SIG of the first packet:
1360  // PHY header reception should succeed.
1361 
1362  Simulator::Schedule (Seconds (4.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1363  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1364  // At 10 us, STA PHY STATE should be CCA_BUSY.
1365  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1366  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1367  Simulator::Schedule (Seconds (4.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1368  Simulator::Schedule (Seconds (4.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1369  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1370  // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
1371  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1372  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1373  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1374  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1375 
1376  // RX power < CCA-ED
1377  rxPowerDbm = -70;
1378 
1379  // CASE 5: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1380  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1381 
1382  Simulator::Schedule (Seconds (5.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1383  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1384  // At 10 us, STA PHY STATE should be CCA_BUSY.
1385  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1386  // At 24us (end of L-SIG), STA PHY STATE should go to IDLE because L-SIG reception failed and the total energy is below CCA-ED.
1387  Simulator::Schedule (Seconds (5.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1388  Simulator::Schedule (Seconds (5.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1389 
1390  // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1391  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1392 
1393  Simulator::Schedule (Seconds (6.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1394  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1395  // At 10 us, STA PHY STATE should be CCA_BUSY.
1396  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1397  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1398  Simulator::Schedule (Seconds (6.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1399  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1400  Simulator::Schedule (Seconds (6.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1401  Simulator::Schedule (Seconds (6.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1402  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1403  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1404  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1405 
1406  // CASE 7: send one packet followed by a second one with same power between the end of L-SIG and the start of HE-SIG of the first packet:
1407  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1408 
1409  Simulator::Schedule (Seconds (7.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1410  Simulator::Schedule (Seconds (7.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1411  // At 10 us, STA PHY STATE should be CCA_BUSY.
1412  Simulator::Schedule (Seconds (7.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1413  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1414  Simulator::Schedule (Seconds (7.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1415  // At 44 us (end of HE-SIG), STA PHY STATE should be not have moved to RX since reception of HE-SIG should have failed.
1416  Simulator::Schedule (Seconds (7.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1417  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1418  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1419  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1420 
1421  // CASE 8: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the start of HE-SIG of the first packet:
1422  // PHY header reception should succeed.
1423 
1424  Simulator::Schedule (Seconds (8.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1425  Simulator::Schedule (Seconds (8.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1426  // At 10 us, STA PHY STATE should be CCA_BUSY.
1427  Simulator::Schedule (Seconds (8.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1428  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1429  Simulator::Schedule (Seconds (8.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1430  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1431  Simulator::Schedule (Seconds (8.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1432  Simulator::Schedule (Seconds (8.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1433  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1434  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1435  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1436 
1437  Simulator::Run ();
1438  Simulator::Destroy ();
1439 }
1440 
1448 {
1449 public:
1450  TestAmpduReception ();
1451  virtual ~TestAmpduReception ();
1452 
1453 protected:
1454  void DoSetup (void) override;
1455  void DoTeardown (void) override;
1456 
1457 private:
1458  void DoRun (void) override;
1459 
1467  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
1468  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1473  void RxFailure (Ptr<WifiPsdu> psdu);
1484  void IncrementSuccessBitmap (uint32_t size);
1489  void IncrementFailureBitmap (uint32_t size);
1490 
1494  void ResetBitmaps();
1495 
1501  void SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize);
1502 
1507  void CheckRxSuccessBitmapAmpdu1 (uint8_t expected);
1512  void CheckRxSuccessBitmapAmpdu2 (uint8_t expected);
1517  void CheckRxFailureBitmapAmpdu1 (uint8_t expected);
1522  void CheckRxFailureBitmapAmpdu2 (uint8_t expected);
1527  void CheckRxDroppedBitmapAmpdu1 (uint8_t expected);
1532  void CheckRxDroppedBitmapAmpdu2 (uint8_t expected);
1533 
1538  void CheckPhyState (WifiPhyState expectedState);
1539 
1541 
1544 
1547 
1550 
1551  uint64_t m_uid;
1552 };
1553 
1555 : TestCase ("A-MPDU reception test"),
1556  m_rxSuccessBitmapAmpdu1 (0),
1557  m_rxSuccessBitmapAmpdu2 (0),
1558  m_rxFailureBitmapAmpdu1 (0),
1559  m_rxFailureBitmapAmpdu2 (0),
1560  m_rxDroppedBitmapAmpdu1 (0),
1561  m_rxDroppedBitmapAmpdu2 (0),
1562  m_uid (0)
1563 {
1564 }
1565 
1567 {
1568  m_phy = 0;
1569 }
1570 
1571 void
1573 {
1580 }
1581 
1582 void
1584  WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1585 {
1586  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
1587  if (statusPerMpdu.empty ()) //wait for the whole A-MPDU
1588  {
1589  return;
1590  }
1591  NS_ABORT_MSG_IF (psdu->GetNMpdus () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1592  auto rxOkForMpdu = statusPerMpdu.begin ();
1593  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1594  {
1595  if (*rxOkForMpdu)
1596  {
1597  IncrementSuccessBitmap ((*mpdu)->GetSize ());
1598  }
1599  else
1600  {
1601  IncrementFailureBitmap ((*mpdu)->GetSize ());
1602  }
1603  ++rxOkForMpdu;
1604  }
1605 }
1606 
1607 void
1609 {
1610  if (size == 1030) //A-MPDU 1 - MPDU #1
1611  {
1613  }
1614  else if (size == 1130) //A-MPDU 1 - MPDU #2
1615  {
1616  m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1617  }
1618  else if (size == 1230) //A-MPDU 1 - MPDU #3
1619  {
1620  m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1621  }
1622  else if (size == 1330) //A-MPDU 2 - MPDU #1
1623  {
1625  }
1626  else if (size == 1430) //A-MPDU 2 - MPDU #2
1627  {
1628  m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1629  }
1630  else if (size == 1530) //A-MPDU 2 - MPDU #3
1631  {
1632  m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1633  }
1634 }
1635 
1636 void
1638 {
1639  NS_LOG_FUNCTION (this << *psdu);
1640  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1641  {
1642  IncrementFailureBitmap ((*mpdu)->GetSize ());
1643  }
1644 }
1645 
1646 void
1648 {
1649  if (size == 1030) //A-MPDU 1 - MPDU #1
1650  {
1652  }
1653  else if (size == 1130) //A-MPDU 1 - MPDU #2
1654  {
1655  m_rxFailureBitmapAmpdu1 |= (1 << 1);
1656  }
1657  else if (size == 1230) //A-MPDU 1 - MPDU #3
1658  {
1659  m_rxFailureBitmapAmpdu1 |= (1 << 2);
1660  }
1661  else if (size == 1330) //A-MPDU 2 - MPDU #1
1662  {
1664  }
1665  else if (size == 1430) //A-MPDU 2 - MPDU #2
1666  {
1667  m_rxFailureBitmapAmpdu2 |= (1 << 1);
1668  }
1669  else if (size == 1530) //A-MPDU 2 - MPDU #3
1670  {
1671  m_rxFailureBitmapAmpdu2 |= (1 << 2);
1672  }
1673 }
1674 
1675 void
1677 {
1678  NS_LOG_FUNCTION (this << p << reason);
1679  if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1680  {
1682  }
1683  else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1684  {
1685  m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1686  }
1687  else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1688  {
1689  m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1690  }
1691  else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1692  {
1694  }
1695  else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1696  {
1697  m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1698  }
1699  else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1700  {
1701  m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1702  }
1703 }
1704 
1705 void
1707 {
1708  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1709 }
1710 
1711 void
1713 {
1714  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1715 }
1716 
1717 void
1719 {
1720  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1721 }
1722 
1723 void
1725 {
1726  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1727 }
1728 
1729 void
1731 {
1732  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1733 }
1734 
1735 void
1737 {
1738  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1739 }
1740 
1741 void
1743 {
1744  WifiPhyState currentState;
1745  PointerValue ptr;
1746  m_phy->GetAttribute ("State", ptr);
1747  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1748  currentState = state->GetState ();
1749  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1750 }
1751 
1752 void
1753 TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1754 {
1755  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true);
1756 
1757  WifiMacHeader hdr;
1758  hdr.SetType (WIFI_MAC_QOSDATA);
1759  hdr.SetQosTid (0);
1760 
1761  std::vector<Ptr<WifiMacQueueItem>> mpduList;
1762  for (size_t i = 0; i < 3; ++i)
1763  {
1764  Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1765  mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1766  }
1767  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1768 
1769  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1770 
1771  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1772 
1773  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1774 
1775  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1776  txParams->psd = txPowerSpectrum;
1777  txParams->txPhy = 0;
1778  txParams->duration = txDuration;
1779  txParams->ppdu = ppdu;
1780 
1781  m_phy->StartRx (txParams);
1782 }
1783 
1784 void
1786 {
1787  m_phy = CreateObject<SpectrumWifiPhy> ();
1789  Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper> ();
1790  m_phy->SetInterferenceHelper (interferenceHelper);
1791  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1792  m_phy->SetErrorRateModel (error);
1794 
1798 
1799  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1800  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1801  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1802 
1803  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1804  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1805  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1806  m_phy->SetFrameCaptureModel (frameCaptureModel);
1807 }
1808 
1809 void
1811 {
1812  m_phy->Dispose ();
1813  m_phy = 0;
1814 }
1815 
1816 void
1818 {
1819  RngSeedManager::SetSeed (1);
1820  RngSeedManager::SetRun (2);
1821  int64_t streamNumber = 1;
1822  double rxPowerDbm = -30;
1823  m_phy->AssignStreams (streamNumber);
1824 
1826  // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1827  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1829 
1830  // A-MPDU 1
1831  Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1832 
1833  // A-MPDU 2
1834  Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1835 
1836  // All MPDUs of A-MPDU 1 should have been ignored.
1837  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1838  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1839  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1840 
1841  // All MPDUs of A-MPDU 2 should have been successfully received.
1842  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1843  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1844  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1845 
1846  Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1847 
1849  // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1850  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1852 
1853  // A-MPDU 1
1854  Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1855 
1856  // A-MPDU 2
1857  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1858 
1859  // All MPDUs of A-MPDU 1 should have been received.
1860  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1861  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1862  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1863 
1864  // All MPDUs of A-MPDU 2 should have been ignored.
1865  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1866  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1867  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1868 
1869  Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1870 
1872  // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1873  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1875 
1876  // A-MPDU 1
1877  Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1878 
1879  // A-MPDU 2
1880  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1881 
1882  // All MPDUs of A-MPDU 1 should have been ignored.
1883  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1884  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1885  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1886 
1887  // All MPDUs of A-MPDU 2 should have been successfully received.
1888  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1889  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1890  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1891 
1892  Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1893 
1895  // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1896  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1898 
1899  // A-MPDU 1
1900  Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1901 
1902  // A-MPDU 2
1903  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1904 
1905  // All MPDUs of A-MPDU 1 should have been received.
1906  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1907  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1908  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1909 
1910  // All MPDUs of A-MPDU 2 should have been ignored.
1911  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1912  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1913  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1914 
1915  Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1916 
1918  // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1919  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
1921 
1922  // A-MPDU 1
1923  Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1924 
1925  // A-MPDU 2
1926  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1927 
1928  // All MPDUs of A-MPDU 1 should have been ignored.
1929  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1930  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1931  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1932 
1933  // All MPDUs of A-MPDU 2 should have been successfully received.
1934  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1935  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1936  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1937 
1938  Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1939 
1941  // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1942  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
1944 
1945  // A-MPDU 1
1946  Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1947 
1948  // A-MPDU 2
1949  Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1950 
1951  // All MPDUs of A-MPDU 1 should have been received.
1952  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1953  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1954  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1955 
1956  // All MPDUs of A-MPDU 2 should have been ignored.
1957  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1958  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1959  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1960 
1961  Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1962 
1964  // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1965  // The second A-MPDU is received during the payload of MPDU #2.
1967 
1968  // A-MPDU 1
1969  Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1970 
1971  // A-MPDU 2
1972  Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1973 
1974  // All MPDUs of A-MPDU 1 should have been ignored.
1975  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1976  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1977  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1978 
1979  // All MPDUs of A-MPDU 2 should have been successfully received.
1980  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1981  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1982  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1983 
1984  Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1985 
1987  // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1988  // The second A-MPDU is received during the payload of MPDU #2.
1990 
1991  // A-MPDU 1
1992  Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1993 
1994  // A-MPDU 2
1995  Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1996 
1997  // All MPDUs of A-MPDU 1 should have been received.
1998  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1999  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2000  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2001 
2002  // All MPDUs of A-MPDU 2 should have been ignored.
2003  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2004  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2005  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2006 
2007  Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
2008 
2010  // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
2011  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
2013 
2014  // A-MPDU 1
2015  Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2016 
2017  // A-MPDU 2
2018  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2019 
2020  // All MPDUs of A-MPDU 1 should have been dropped.
2021  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2022  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2023  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2024 
2025  // All MPDUs of A-MPDU 2 should have been received with errors.
2026  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2027  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
2028  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2029 
2030  Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
2031 
2033  // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2034  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
2036 
2037  // A-MPDU 1
2038  Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2039 
2040  // A-MPDU 2
2041  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2042 
2043  // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
2044  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2045  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2046  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2047 
2048  // All MPDUs of A-MPDU 2 should have been dropped as well.
2049  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2050  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2051  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2052 
2053  Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
2054 
2056  // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2057  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
2059 
2060  // A-MPDU 1
2061  Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2062 
2063  // A-MPDU 2
2064  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2065 
2066  // All MPDUs of A-MPDU 1 should have been received with errors.
2067  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2068  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2069  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2070 
2071  // All MPDUs of A-MPDU 2 should have been dropped.
2072  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2073  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2074  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2075 
2076  Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
2077 
2079  // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
2080  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2082 
2083  // A-MPDU 1
2084  Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2085 
2086  // A-MPDU 2
2087  Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2088 
2089  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2090  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2091  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2092  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2093 
2094  // All MPDUs of A-MPDU 2 should have been dropped (even though TX power is higher, it is not high enough to get the PHY reception switched)
2095  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2096  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2097  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2098 
2099  Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
2100 
2102  // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2103  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2105 
2106  // A-MPDU 1
2107  Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2108 
2109  // A-MPDU 2
2110  Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2111 
2112  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2113  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2114  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2115  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2116 
2117  // All MPDUs of A-MPDU 2 should have been dropped as well.
2118  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2119  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2120  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2121 
2122  Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
2123 
2125  // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2126  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2128 
2129  // A-MPDU 1
2130  Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2131 
2132  // A-MPDU 2
2133  Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2134 
2135  // All MPDUs of A-MPDU 1 should have been received with errors.
2136  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2137  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2138  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2139 
2140  // All MPDUs of A-MPDU 2 should have been dropped.
2141  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2142  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2143  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2144 
2145  Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
2146 
2148  // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2149  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2151 
2152  // A-MPDU 1
2153  Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2154 
2155  // A-MPDU 2
2156  Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2157 
2158  // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
2159  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2160  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2161  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2162 
2163  // All MPDUs of A-MPDU 2 should have been successfully received
2164  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
2165  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2166  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2167 
2168  Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
2169 
2171  // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2172  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2174 
2175  // A-MPDU 1
2176  Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2177 
2178  // A-MPDU 2
2179  Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2180 
2181  // All MPDUs of A-MPDU 1 should have been successfully received.
2182  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2183  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2184  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2185 
2186  // All MPDUs of A-MPDU 2 should have been dropped.
2187  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2188  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2189  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2190 
2191  Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2192 
2194  // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2195  // The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after the frame capture window, but still during PHY header).
2197 
2198  // A-MPDU 1
2199  Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2200 
2201  // A-MPDU 2
2202  Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2203 
2204  // All MPDUs of A-MPDU 1 should have been received with errors.
2205  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2206  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2207  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2208 
2209  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2210  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2211  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2212  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2213 
2214  Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2215 
2217  // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2218  // The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after the frame capture window, but still during PHY header).
2220 
2221  // A-MPDU 1
2222  Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2223 
2224  // A-MPDU 2
2225  Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2226 
2227  // All MPDUs of A-MPDU 1 should have been successfully received.
2228  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2229  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2230  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2231 
2232  // All MPDUs of A-MPDU 2 should have been dropped.
2233  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2234  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2235  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2236 
2237  Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2238 
2240  // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2241  // The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after the frame capture window, but still during PHY header).
2243 
2244  // A-MPDU 1
2245  Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2246 
2247  // A-MPDU 2
2248  Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2249 
2250  // All MPDUs of A-MPDU 1 should have been received with errors.
2251  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2252  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2253  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2254 
2255  // All MPDUs of A-MPDU 2 should have been dropped.
2256  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2257  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2258  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2259 
2260  Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2261 
2263  // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2264  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2266 
2267  // A-MPDU 1
2268  Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2269 
2270  // A-MPDU 2
2271  Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2272 
2273  // All MPDUs of A-MPDU 1 should have been received with errors.
2274  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2275  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2276  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2277 
2278  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2279  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2280  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2281  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2282 
2283  Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2284 
2286  // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2287  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2289 
2290  // A-MPDU 1
2291  Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2292 
2293  // A-MPDU 2
2294  Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2295 
2296  // All MPDUs of A-MPDU 1 should have been successfully received.
2297  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2298  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2299  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2300 
2301  // All MPDUs of A-MPDU 2 should have been dropped.
2302  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2303  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2304  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2305 
2306  Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2307 
2309  // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2310  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2312 
2313  // A-MPDU 1
2314  Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2315 
2316  // A-MPDU 2
2317  Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2318 
2319  // All MPDUs of A-MPDU 1 should have been received with errors.
2320  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2321  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2322  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2323 
2324  // All MPDUs of A-MPDU 2 should have been dropped.
2325  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2326  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2327  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2328 
2329  Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2330 
2332  // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2333  // The second A-MPDU is received during the payload of MPDU #2.
2335 
2336  // A-MPDU 1
2337  Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2338 
2339  // A-MPDU 2
2340  Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2341 
2342  // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2343  // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2344  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2345  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2346  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2347 
2348  // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2349  // The last MPDU of A-MPDU 2 is interference free (A-MPDU 1 transmission is finished) but is dropped because its PHY preamble and header were not received.
2350  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2351  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2352  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2353 
2354  Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2355 
2356  Simulator::Run ();
2357  Simulator::Destroy ();
2358 }
2359 
2381 {
2382 public:
2388 
2395  void Dropped (std::string context, Ptr<const Packet> packet, WifiPhyRxfailureReason reason);
2399  void CheckResults (void);
2400 
2401 private:
2402  void DoRun (void) override;
2403  uint16_t m_dropped;
2404 };
2405 
2407  : TestCase ("Check correct behavior when a STA is receiving a transmission using an unsupported modulation"),
2408  m_dropped (0)
2409 {
2410 }
2411 
2413 {
2414 }
2415 
2416 void
2418  WifiPhyRxfailureReason reason)
2419 {
2420  // Print if the test is executed through test-runner
2421  if (reason == RXING)
2422  {
2423  std::cout << "Dropped a packet because already receiving" << std::endl;
2424  m_dropped++;
2425  }
2426 }
2427 
2428 void
2430 {
2431  uint16_t m_nStations = 2;
2432  NetDeviceContainer m_staDevices;
2433  NetDeviceContainer m_apDevices;
2434 
2435  // RngSeedManager::SetSeed (1);
2436  // RngSeedManager::SetRun (40);
2437  int64_t streamNumber = 100;
2438 
2440  wifiApNode.Create (1);
2441 
2443  wifiStaNodes.Create (m_nStations);
2444 
2445  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
2446  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
2447  spectrumChannel->AddPropagationLossModel (lossModel);
2449  CreateObject<ConstantSpeedPropagationDelayModel> ();
2450  spectrumChannel->SetPropagationDelayModel (delayModel);
2451 
2453  phy.SetChannel (spectrumChannel);
2454 
2455  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (65535));
2456 
2457  WifiHelper wifi;
2458  wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
2459 
2461  mac.SetType ("ns3::StaWifiMac", "QosSupported", BooleanValue (true), "Ssid",
2462  SsidValue (Ssid ("non-existent-ssid")));
2463 
2464  wifi.SetStandard (WIFI_STANDARD_80211ax);
2465  m_staDevices.Add (wifi.Install (phy, mac, wifiStaNodes.Get (0)));
2466  wifi.SetStandard (WIFI_STANDARD_80211ac);
2467  m_staDevices.Add (wifi.Install (phy, mac, wifiStaNodes.Get (1)));
2468 
2469  wifi.SetStandard (WIFI_STANDARD_80211ax);
2470  mac.SetType ("ns3::ApWifiMac", "QosSupported", BooleanValue (true), "Ssid",
2471  SsidValue (Ssid ("wifi-backoff-ssid")), "BeaconInterval",
2472  TimeValue (MicroSeconds (102400)), "EnableBeaconJitter", BooleanValue (false));
2473 
2474  m_apDevices = wifi.Install (phy, mac, wifiApNode);
2475 
2476  // schedule association requests at different times
2477  Time init = MilliSeconds (100);
2478  Ptr<WifiNetDevice> dev;
2479 
2480  for (uint16_t i = 0; i < m_nStations; i++)
2481  {
2482  dev = DynamicCast<WifiNetDevice> (m_staDevices.Get (i));
2483  Simulator::Schedule (init + i * MicroSeconds (102400), &WifiMac::SetSsid, dev->GetMac (),
2484  Ssid ("wifi-backoff-ssid"));
2485  }
2486 
2487  // Assign fixed streams to random variables in use
2488  wifi.AssignStreams (m_apDevices, streamNumber);
2489 
2491  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
2492 
2493  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
2494  positionAlloc->Add (Vector (1.0, 0.0, 0.0));
2495  positionAlloc->Add (Vector (0.0, 1.0, 0.0));
2496  positionAlloc->Add (Vector (-1.0, 0.0, 0.0));
2497  mobility.SetPositionAllocator (positionAlloc);
2498 
2499  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
2500  mobility.Install (wifiApNode);
2501  mobility.Install (wifiStaNodes);
2502 
2503  // set the TXOP limit on BE AC
2504  dev = DynamicCast<WifiNetDevice> (m_apDevices.Get (0));
2505  PointerValue ptr;
2506  dev->GetMac ()->GetAttribute ("BE_Txop", ptr);
2507 
2508  PacketSocketHelper packetSocket;
2509  packetSocket.Install (wifiApNode);
2510  packetSocket.Install (wifiStaNodes);
2511 
2512  // UL Traffic
2513  for (uint16_t i = 0; i < m_nStations; i++)
2514  {
2515  PacketSocketAddress socket;
2516  socket.SetSingleDevice (m_staDevices.Get (0)->GetIfIndex ());
2517  socket.SetPhysicalAddress (m_apDevices.Get (0)->GetAddress ());
2518  socket.SetProtocol (1);
2519  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
2520  client->SetAttribute ("PacketSize", UintegerValue (1500));
2521  client->SetAttribute ("MaxPackets", UintegerValue (200));
2522  client->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
2523  client->SetRemote (socket);
2524  wifiStaNodes.Get (i)->AddApplication (client);
2525  client->SetStartTime (MicroSeconds (400000));
2526  client->SetStopTime (Seconds (1.0));
2527  Ptr<PacketSocketClient> legacyStaClient = CreateObject<PacketSocketClient> ();
2528  legacyStaClient->SetAttribute ("PacketSize", UintegerValue (1500));
2529  legacyStaClient->SetAttribute ("MaxPackets", UintegerValue (200));
2530  legacyStaClient->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
2531  legacyStaClient->SetRemote (socket);
2532  wifiStaNodes.Get (i)->AddApplication (legacyStaClient);
2533  legacyStaClient->SetStartTime (MicroSeconds (400000));
2534  legacyStaClient->SetStopTime (Seconds (1.0));
2535  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
2536  server->SetLocal (socket);
2537  wifiApNode.Get (0)->AddApplication (server);
2538  server->SetStartTime (Seconds (0.0));
2539  server->SetStopTime (Seconds (1.0));
2540  }
2541 
2542  // Trace dropped packets
2543  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
2545 
2546  Simulator::Stop (Seconds (1));
2547  Simulator::Run ();
2548 
2549  CheckResults ();
2550 
2551  Simulator::Destroy ();
2552 }
2553 
2554 void
2556 {
2557  NS_TEST_EXPECT_MSG_EQ (m_dropped, 0, "Dropped some packets unexpectedly");
2558 }
2559 
2567 {
2568 public:
2570 };
2571 
2573  : TestSuite ("wifi-phy-reception", UNIT)
2574 {
2577  AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2578  AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2579  AddTestCase (new TestAmpduReception, TestCase::QUICK);
2580  AddTestCase (new TestUnsupportedModulationReception (), TestCase::QUICK);
2581 }
2582 
A-MPDU reception test.
void IncrementSuccessBitmap(uint32_t size)
Increment reception success bitmap.
uint8_t m_rxDroppedBitmapAmpdu2
bitmap of dropped MPDUs in A-MPDU #2
void CheckRxSuccessBitmapAmpdu2(uint8_t expected)
Check the RX success bitmap for A-MPDU 2.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void CheckRxDroppedBitmapAmpdu1(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 1.
uint8_t m_rxSuccessBitmapAmpdu1
bitmap of successfully received MPDUs in A-MPDU #1
uint8_t m_rxFailureBitmapAmpdu1
bitmap of unsuccessfully received MPDUs in A-MPDU #1
void RxFailure(Ptr< WifiPsdu > psdu)
RX failure function.
uint8_t m_rxFailureBitmapAmpdu2
bitmap of unsuccessfully received MPDUs in A-MPDU #2
void DoRun(void) override
Implementation to actually run this TestCase.
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void SendAmpduWithThreeMpdus(double rxPowerDbm, uint32_t referencePacketSize)
Send A-MPDU with 3 MPDUs of different size (i-th MSDU will have 100 bytes more than (i-1)-th).
void CheckRxFailureBitmapAmpdu2(uint8_t expected)
Check the RX failure bitmap for A-MPDU 2.
uint8_t m_rxDroppedBitmapAmpdu1
bitmap of dropped MPDUs in A-MPDU #1
void IncrementFailureBitmap(uint32_t size)
Increment reception failure bitmap.
void ResetBitmaps()
Reset bitmaps function.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
RX success function.
void CheckRxSuccessBitmapAmpdu1(uint8_t expected)
Check the RX success bitmap for A-MPDU 1.
void CheckRxFailureBitmapAmpdu1(uint8_t expected)
Check the RX failure bitmap for A-MPDU 1.
uint8_t m_rxSuccessBitmapAmpdu2
bitmap of successfully received MPDUs in A-MPDU #2
Ptr< SpectrumWifiPhy > m_phy
Phy.
void CheckRxDroppedBitmapAmpdu2(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 2.
Test PHY state upon success or failure of L-SIG and SIG-A.
void SendPacket(double rxPowerDbm)
Send packet function.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
uint64_t m_uid
the UID to use for the PPDU
void DoRun(void) override
Implementation to actually run this TestCase.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
Simple frame capture model test.
void Expect1000BPacketReceived()
Verify whether 1000 bytes packet has been received.
bool m_rxDropped1500B
count dropped packets with 1500B payload
void Expect1500BPacketDropped()
Verify whether 1500 bytes packet has been dropped.
void Expect1000BPacketDropped()
Verify whether 1000 bytes packet has been dropped.
void DoRun(void) override
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm, uint32_t packetSize)
Send packet function.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
bool m_rxSuccess1000B
count received packets with 1000B payload
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
bool m_rxSuccess1500B
count received packets with 1500B payload
void Expect1500BPacketReceived()
Verify whether 1500 bytes packet has been received.
uint64_t m_uid
the UID to use for the PPDU
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
bool m_rxDropped1000B
count dropped packets with 1000B payload
Preamble detection test w/o frame capture.
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void SendPacket(double rxPowerDbm)
Send packet function.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void DoRun(void) override
Implementation to actually run this TestCase.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
Preamble detection test w/o frame capture.
void DoTeardown(void) override
Implementation to do any local setup required for this TestCase.
void DoSetup(void) override
Implementation to do any local setup required for this TestCase.
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void DoRun(void) override
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm)
Send packet function.
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
Unsupported Modulation Reception Test This test creates a mixed network, in which an HE STA and a VHT...
void DoRun(void) override
Implementation to actually run this TestCase.
void Dropped(std::string context, Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Callback invoked when PHY drops an incoming packet.
void CheckResults(void)
Check correctness of transmitted frames.
uint16_t m_dropped
number of packets dropped by the AP because it was already receiving
wifi PHY reception Test Suite
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
virtual Address GetAddress(void) const =0
virtual uint32_t GetIfIndex(void) const =0
keep track of a set of node pointers.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:364
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:294
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get(void) const
Definition: pointer.h:201
Make it easy to create and manage PHY objects for the spectrum model.
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:105
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:274
Implements the IEEE 802.11 MAC header.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
create MAC layers for a ns3::WifiNetDevice.
Ptr< WifiMac > GetMac(void) const
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition: wifi-phy.cc:566
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:574
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:887
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:396
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:835
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1327
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:930
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:594
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:390
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:588
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:833
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:2012
This objects implements the PHY state machine of the Wifi device.
uint32_t GetSize(void) const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:260
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
std::size_t GetNMpdus(void) const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:319
std::vector< Ptr< WifiMacQueueItem > >::const_iterator end(void) const
Return a const iterator to past-the-last MPDU.
Definition: wifi-psdu.cc:337
bool IsAggregate(void) const
Return true if the PSDU is an S-MPDU or A-MPDU.
Definition: wifi-psdu.cc:81
bool IsSingle(void) const
Return true if the PSDU is an S-MPDU.
Definition: wifi-psdu.cc:75
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#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
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#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:141
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:240
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:37
@ WIFI_MAC_QOSDATA
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:1648
mac
Definition: third.py:99
wifi
Definition: third.py:96
wifiApNode
Definition: third.py:90
mobility
Definition: third.py:108
wifiStaNodes
Definition: third.py:88
phy
Definition: third.py:93
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:67
static const uint8_t CHANNEL_NUMBER
static const uint16_t GUARD_WIDTH
static const uint16_t CHANNEL_WIDTH
static WifiPhyReceptionTestSuite wifiPhyReceptionTestSuite
the test suite
static const uint32_t FREQUENCY
WifiPhyState
The state of the PHY layer.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ RX
The PHY layer is receiving a packet.
@ IDLE
The PHY layer is IDLE.
static const uint32_t packetSize
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...