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/test.h"
23 #include "ns3/double.h"
24 #include "ns3/pointer.h"
25 #include "ns3/rng-seed-manager.h"
26 #include "ns3/spectrum-wifi-helper.h"
27 #include "ns3/wifi-spectrum-value-helper.h"
28 #include "ns3/spectrum-wifi-phy.h"
29 #include "ns3/nist-error-rate-model.h"
30 #include "ns3/wifi-mac-header.h"
31 #include "ns3/ampdu-tag.h"
32 #include "ns3/wifi-spectrum-signal-parameters.h"
33 #include "ns3/wifi-utils.h"
34 #include "ns3/threshold-preamble-detection-model.h"
35 #include "ns3/simple-frame-capture-model.h"
36 #include "ns3/wifi-mac-queue-item.h"
37 #include "ns3/mpdu-aggregator.h"
38 #include "ns3/wifi-psdu.h"
39 #include "ns3/wifi-ppdu.h"
40 
41 using namespace ns3;
42 
43 NS_LOG_COMPONENT_DEFINE ("WifiPhyReceptionTest");
44 
45 static const uint8_t CHANNEL_NUMBER = 36;
46 static const uint32_t FREQUENCY = 5180; // MHz
47 static const uint16_t CHANNEL_WIDTH = 20; // MHz
48 static const uint16_t GUARD_WIDTH = CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
49 
57 {
58 public:
61 
62 protected:
63  virtual void DoSetup (void);
65 
69  void SendPacket (double rxPowerDbm);
77  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
82  void RxFailure (Ptr<WifiPsdu> psdu);
83  uint32_t m_countRxSuccess;
84  uint32_t m_countRxFailure;
85 
86 private:
87  virtual void DoRun (void);
88 
93  void CheckPhyState (WifiPhyState expectedState);
98  void DoCheckPhyState (WifiPhyState expectedState);
104  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
105 };
106 
108  : TestCase ("Threshold preamble detection model test when no frame capture model is applied"),
109  m_countRxSuccess (0),
110  m_countRxFailure (0)
111 {
112 }
113 
114 void
116 {
117  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
118 
119  Ptr<Packet> pkt = Create<Packet> (1000);
120  WifiMacHeader hdr;
121 
123  hdr.SetQosTid (0);
124 
125  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
126  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
127 
128  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
129 
130  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
131 
132  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
133  txParams->psd = txPowerSpectrum;
134  txParams->txPhy = 0;
135  txParams->duration = txDuration;
136  txParams->ppdu = ppdu;
137 
138  m_phy->StartRx (txParams);
139 }
140 
141 void
143 {
144  //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
145  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithoutFrameCapture::DoCheckPhyState, this, expectedState);
146 }
147 
148 void
150 {
151  WifiPhyState currentState;
152  PointerValue ptr;
153  m_phy->GetAttribute ("State", ptr);
154  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
155  currentState = state->GetState ();
156  NS_LOG_FUNCTION (this << currentState);
157  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
158 }
159 
160 void
161 TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
162 {
163  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
164  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
165 }
166 
167 void
168 TestThresholdPreambleDetectionWithoutFrameCapture::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
169 {
170  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
172 }
173 
174 void
176 {
177  NS_LOG_FUNCTION (this << *psdu);
179 }
180 
182 {
183  m_phy = 0;
184 }
185 
186 void
188 {
189  m_phy = CreateObject<SpectrumWifiPhy> ();
191  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
192  m_phy->SetErrorRateModel (error);
197 
198  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
199  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
200  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
201  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
202 }
203 
204 void
206 {
207  RngSeedManager::SetSeed (1);
208  RngSeedManager::SetRun (1);
209  int64_t streamNumber = 0;
210  m_phy->AssignStreams (streamNumber);
211 
212  //RX power > CCA-ED > CCA-PD
213  double rxPowerDbm = -50;
214 
215  // CASE 1: send one packet and check PHY state:
216  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
217  // otherwise it should be IDLE.
218 
219  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
220  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
223  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
226  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
229  // Packet should have been successfully received
230  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
231 
232  // CASE 2: send two packets with same power within the 4us window and check PHY state:
233  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
234  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
235  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
236 
237  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
238  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
239  // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
242  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
245  // 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
246  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
247 
248  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
249  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
250  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
251  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
252 
253  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
254  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
255  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
258  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
261  // 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
262  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
263 
264  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
265  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
266  // but payload reception should fail (SNR too low to decode the modulation).
267 
268  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
269  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
270  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
273  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
276  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
277  // 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.
282  // In this case, the first packet should be marked as a failure
283  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
284 
285  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
286  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
287  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
288  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
289 
290  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
291  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
292  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
295  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
298  // 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
299  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
300 
301  // CCA-PD < RX power < CCA-ED
302  rxPowerDbm = -70;
303 
304  // CASE 6: send one packet and check PHY state:
305  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
306  // otherwise it should be IDLE.
307 
308  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
309  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
312  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
315  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
318  // Packet should have been successfully received
319  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
320 
321  // CASE 7: send two packets with same power within the 4us window and check PHY state:
322  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
323  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
324 
325  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
326  Simulator::Schedule (Seconds (7.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
327  // At 4us, STA PHY STATE should stay IDLE
329  // 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
330  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
331 
332  // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
333  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
334  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
335 
336  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
337  Simulator::Schedule (Seconds (8.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
338  // At 4us, STA PHY STATE should stay IDLE
340  // 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
341  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
342 
343  // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
344  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
345  // but payload reception should fail (SNR too low to decode the modulation).
346 
347  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
348  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
349  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
352  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
355  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
358  // In this case, the first packet should be marked as a failure
359  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
360 
361  // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY state:
362  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
363  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
364 
365  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
366  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
367  // At 4us, STA PHY STATE should stay IDLE
369  // 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
370  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
371 
372  // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
373  // preamble detection should succeed and PHY state should move to RX.
374 
375  rxPowerDbm = -81;
376 
377  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
378  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
381  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
384  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
387 
388  // RX power < CCA-PD < CCA-ED
389  rxPowerDbm = -83;
390 
391  //CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
392  //preamble detection should fail and PHY should be kept in IDLE state.
393 
394  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
395  // At 4us, STA PHY state should be IDLE
397 
398  Simulator::Run ();
399  Simulator::Destroy ();
400 }
401 
409 {
410 public:
413 
414 protected:
415  virtual void DoSetup (void);
417 
421  void SendPacket (double rxPowerDbm);
429  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
434  void RxFailure (Ptr<WifiPsdu> psdu);
435  uint32_t m_countRxSuccess;
436  uint32_t m_countRxFailure;
437 
438 private:
439  virtual void DoRun (void);
440 
445  void CheckPhyState (WifiPhyState expectedState);
450  void DoCheckPhyState (WifiPhyState expectedState);
456  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
457 };
458 
460 : TestCase ("Threshold preamble detection model test when simple frame capture model is applied"),
461 m_countRxSuccess (0),
462 m_countRxFailure (0)
463 {
464 }
465 
466 void
468 {
469  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
470 
471  Ptr<Packet> pkt = Create<Packet> (1000);
472  WifiMacHeader hdr;
473 
475  hdr.SetQosTid (0);
476 
477  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
478  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
479 
480  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
481 
482  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
483 
484  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
485  txParams->psd = txPowerSpectrum;
486  txParams->txPhy = 0;
487  txParams->duration = txDuration;
488  txParams->ppdu = ppdu;
489 
490  m_phy->StartRx (txParams);
491 }
492 
493 void
495 {
496  //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
497  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithFrameCapture::DoCheckPhyState, this, expectedState);
498 }
499 
500 void
502 {
503  WifiPhyState currentState;
504  PointerValue ptr;
505  m_phy->GetAttribute ("State", ptr);
506  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
507  currentState = state->GetState ();
508  NS_LOG_FUNCTION (this << currentState);
509  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
510 }
511 
512 void
513 TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
514 {
515  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
516  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
517 }
518 
519 void
520 TestThresholdPreambleDetectionWithFrameCapture::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
521 {
522  NS_LOG_FUNCTION (this << *psdu << txVector);
524 }
525 
526 void
528 {
529  NS_LOG_FUNCTION (this << *psdu);
531 }
532 
534 {
535  m_phy = 0;
536 }
537 
538 void
540 {
541  m_phy = CreateObject<SpectrumWifiPhy> ();
543  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
544  m_phy->SetErrorRateModel (error);
549 
550  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
551  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
552  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
553  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
554 
555  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
556  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
557  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
558  m_phy->SetFrameCaptureModel (frameCaptureModel);
559 }
560 
561 void
563 {
564  RngSeedManager::SetSeed (1);
565  RngSeedManager::SetRun (1);
566  int64_t streamNumber = 1;
567  m_phy->AssignStreams (streamNumber);
568 
569  //RX power > CCA-ED > CCA-PD
570  double rxPowerDbm = -50;
571 
572  // CASE 1: send one packet and check PHY state:
573  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
574  // otherwise it should be IDLE.
575 
576  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
577  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
580  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
583  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
586  // Packet should have been successfully received
587  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
588 
589  // CASE 2: send two packets with same power within the 4us window and check PHY state:
590  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
591  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
592  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
593 
594  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
595  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
596  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
599  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
602  // 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
603  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
604 
605  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
606  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
607  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
608  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
609 
610  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
611  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
612  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
615  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
618  // 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
619  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
620 
621  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
622  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
623  // but payload reception should fail (SNR too low to decode the modulation).
624 
625  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
626  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
627  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
630  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
633  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
634  // 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.
639  // In this case, the first packet should be marked as a failure
640  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
641 
642  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
643  // PHY preamble detection should switch because a higher packet is received within the 4us window,
644  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
645  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
646 
647  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
648  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
649  // At 4us, STA PHY STATE should stay IDLE
651  // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
654  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
657  // 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
658  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
659 
660  // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY state:
661  // PHY preamble detection should switch because a higher packet is received within the 4us window,
662  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
663  // Payload reception should fail (SNR too low to decode the modulation).
664 
665  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
666  Simulator::Schedule (Seconds (6.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
667  // At 4us, STA PHY STATE should stay IDLE
669  // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
672  // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
675  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
678  // In this case, the second packet should be marked as a failure
679  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
680 
681  // CASE 7: send two packets with same power at the exact same time and check PHY state:
682  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
683  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
684  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
685 
686  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
687  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
688  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
691  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
694  // 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
695  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
696 
697  // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY state:
698  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
699  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
700  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
701 
702  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
703  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
704  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
707  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
710  // 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
711  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
712 
713  // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY state:
714  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
715  // but payload reception should fail (SNR too low to decode the modulation).
716 
717  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
718  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
719  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
722  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
725  // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
728  // In this case, the first packet should be marked as a failure
729  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
730 
731  // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY state:
732  // PHY preamble detection should switch because a higher packet is received within the 4us window,
733  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
734  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
735 
736  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
737  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
738  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
741  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
744  // 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
745  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
746 
747  // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY state:
748  // PHY preamble detection should switch because a higher packet is received within the 4us window,
749  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
750  // Payload reception should fail (SNR too low to decode the modulation).
751 
752  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
753  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
754  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
757  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
760  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
763  // In this case, the second packet should be marked as a failure
764  Simulator::Schedule (Seconds (11.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 4);
765 
766  // CCA-PD < RX power < CCA-ED
767  rxPowerDbm = -70;
768 
769  // CASE 12: send one packet and check PHY state:
770  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
771  // otherwise it should be IDLE.
772 
773  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
774  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
777  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
780  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
783  // Packet should have been successfully received
784  Simulator::Schedule (Seconds (12.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
785 
786  // CASE 13: send two packets with same power within the 4us window and check PHY state:
787  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
788  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
789 
790  Simulator::Schedule (Seconds (13.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
791  Simulator::Schedule (Seconds (13.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
792  // At 4us, STA PHY STATE should stay IDLE
794  // 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
795  Simulator::Schedule (Seconds (13.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
796 
797  // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
798  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
799  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
800 
801  Simulator::Schedule (Seconds (14.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
802  Simulator::Schedule (Seconds (14.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
803  // At 4us, STA PHY STATE should stay IDLE
805  // 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
806  Simulator::Schedule (Seconds (14.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
807 
808  // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
809  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
810  // but payload reception should fail (SNR too low to decode the modulation).
811 
812  Simulator::Schedule (Seconds (15.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
813  Simulator::Schedule (Seconds (15.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
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  // In this case, the first packet should be marked as a failure
824  Simulator::Schedule (Seconds (15.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
825 
826  // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY state:
827  // PHY preamble detection should switch because a higher packet is received within the 4us window,
828  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB).
829  // PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
830 
831  Simulator::Schedule (Seconds (16.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
832  Simulator::Schedule (Seconds (16.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
833  // At 4us, STA PHY STATE should stay IDLE
835  // At 6us, STA PHY STATE should stay IDLE
837  // 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
838  Simulator::Schedule (Seconds (16.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
839 
840  // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY state:
841  // PHY preamble detection should switch because a higher packet is received within the 4us window,
842  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
843  // Payload reception should fail (SNR too low to decode the modulation).
844 
845  Simulator::Schedule (Seconds (17.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
846  Simulator::Schedule (Seconds (17.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
847  // At 4us, STA PHY STATE should stay IDLE
849  // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
852  // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
855  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
858  // In this case, the second packet should be marked as a failure
859  Simulator::Schedule (Seconds (17.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 6);
860 
861  rxPowerDbm = -50;
862  // CASE 18: send two packets with second one 50 dB higher within the 4us window
863 
864  Simulator::Schedule (Seconds (18.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
865  Simulator::Schedule (Seconds (18.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
866  // The second packet should be received successfully
867  Simulator::Schedule (Seconds (18.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 6);
868 
869  // CASE 19: send two packets with second one 10 dB higher within the 4us window
870 
871  Simulator::Schedule (Seconds (19.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
872  Simulator::Schedule (Seconds (19.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
873  // The second packet should be captured, but not decoded since SNR to low for used MCS
874  Simulator::Schedule (Seconds (19.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 7);
875 
876  // CASE 20: send two packets with second one 50 dB higher in the same time
877 
878  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
879  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
880  // The second packet should be received successfully, same as in CASE 13
881  Simulator::Schedule (Seconds (20.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 7);
882 
883  // CASE 21: send two packets with second one 10 dB higher in the same time
884 
885  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
886  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
887  // The second packet should be captured, but not decoded since SNR to low for used MCS, same as in CASE 19
888  Simulator::Schedule (Seconds (21.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 8);
889 
890  Simulator::Run ();
891  Simulator::Destroy ();
892 }
893 
901 {
902 public:
904  virtual ~TestSimpleFrameCaptureModel ();
905 
906 protected:
907  virtual void DoSetup (void);
908 
909 private:
910  virtual void DoRun (void);
911 
915  void Reset (void);
921  void SendPacket (double rxPowerDbm, uint32_t packetSize);
929  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
936 
948  void Expect1000BPacketDropped ();
952  void Expect1500BPacketDropped ();
953 
955 
960 };
961 
963 : TestCase ("Simple frame capture model test"),
964  m_rxSuccess1000B (false),
965  m_rxSuccess1500B (false),
966  m_rxDropped1000B (false),
967  m_rxDropped1500B (false)
968 {
969 }
970 
971 void
973 {
974  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
975 
976  Ptr<Packet> pkt = Create<Packet> (packetSize);
977  WifiMacHeader hdr;
978 
980  hdr.SetQosTid (0);
981 
982  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
983  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
984 
985  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
986 
987  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
988 
989  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
990  txParams->psd = txPowerSpectrum;
991  txParams->txPhy = 0;
992  txParams->duration = txDuration;
993  txParams->ppdu = ppdu;
994 
995  m_phy->StartRx (txParams);
996 }
997 
998 void
999 TestSimpleFrameCaptureModel::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1000 {
1001  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
1002  NS_ASSERT (!psdu->IsAggregate () || psdu->IsSingle ());
1003  if (psdu->GetSize () == 1030)
1004  {
1005  m_rxSuccess1000B = true;
1006  }
1007  else if (psdu->GetSize () == 1530)
1008  {
1009  m_rxSuccess1500B = true;
1010  }
1011 }
1012 
1013 void
1015 {
1016  NS_LOG_FUNCTION (this << p << reason);
1017  if (p->GetSize () == 1030)
1018  {
1019  m_rxDropped1000B = true;
1020  }
1021  else if (p->GetSize () == 1530)
1022  {
1023  m_rxDropped1500B = true;
1024  }
1025 }
1026 
1027 void
1029 {
1030  m_rxSuccess1000B = false;
1031  m_rxSuccess1500B = false;
1032  m_rxDropped1000B = false;
1033  m_rxDropped1500B = false;
1034 }
1035 
1036 void
1038 {
1039  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1000B, true, "Didn't receive 1000B packet");
1040 }
1041 
1042 void
1044 {
1045  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1500B, true, "Didn't receive 1500B packet");
1046 }
1047 void
1049 {
1050  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1000B, true, "Didn't drop 1000B packet");
1051 }
1052 
1053 void
1055 {
1056  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1500B, true, "Didn't drop 1500B packet");
1057 }
1058 
1060 {
1061  m_phy = 0;
1062 }
1063 
1064 void
1066 {
1067  m_phy = CreateObject<SpectrumWifiPhy> ();
1069  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1070  m_phy->SetErrorRateModel (error);
1073 
1076 
1077  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1078  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1079  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1080 
1081  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1082  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1083  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1084  m_phy->SetFrameCaptureModel (frameCaptureModel);
1085 }
1086 
1087 void
1089 {
1090  RngSeedManager::SetSeed (1);
1091  RngSeedManager::SetRun (1);
1092  int64_t streamNumber = 2;
1093  double rxPowerDbm = -30;
1094  m_phy->AssignStreams (streamNumber);
1095 
1096  // CASE 1: send two packets with same power within the capture window:
1097  // PHY should not switch reception because they have same power.
1098 
1099  Simulator::Schedule (Seconds (1.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1100  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1500);
1101  Simulator::Schedule (Seconds (1.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1102  Simulator::Schedule (Seconds (1.2), &TestSimpleFrameCaptureModel::Reset, this);
1103 
1104  // CASE 2: send two packets with second one 6 dB weaker within the capture window:
1105  // PHY should not switch reception because first one has higher power.
1106 
1107  Simulator::Schedule (Seconds (2.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1108  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm - 6, 1500);
1109  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1000BPacketReceived, this);
1110  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1111  Simulator::Schedule (Seconds (2.2), &TestSimpleFrameCaptureModel::Reset, this);
1112 
1113  // CASE 3: send two packets with second one 6 dB higher within the capture window:
1114  // PHY should switch reception because the second one has a higher power.
1115 
1116  Simulator::Schedule (Seconds (3.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1117  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1118  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1000BPacketDropped, this);
1119  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1500BPacketReceived, this);
1120  Simulator::Schedule (Seconds (3.2), &TestSimpleFrameCaptureModel::Reset, this);
1121 
1122  // CASE 4: send two packets with second one 6 dB higher after the capture window:
1123  // PHY should not switch reception because capture window duration has elapsed when the second packet arrives.
1124 
1125  Simulator::Schedule (Seconds (4.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1126  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1127  Simulator::Schedule (Seconds (4.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1128  Simulator::Schedule (Seconds (4.2), &TestSimpleFrameCaptureModel::Reset, this);
1129 
1130  Simulator::Run ();
1131  Simulator::Destroy ();
1132 }
1133 
1141 {
1142 public:
1144  virtual ~TestPhyHeadersReception ();
1145 
1146 protected:
1147  virtual void DoSetup (void);
1149 
1153  void SendPacket (double rxPowerDbm);
1154 
1155 private:
1156  virtual void DoRun (void);
1157 
1162  void CheckPhyState (WifiPhyState expectedState);
1167  void DoCheckPhyState (WifiPhyState expectedState);
1168 };
1169 
1171 : TestCase ("PHY headers reception test")
1172 {
1173 }
1174 
1175 void
1177 {
1178  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
1179 
1180  Ptr<Packet> pkt = Create<Packet> (1000);
1181  WifiMacHeader hdr;
1182 
1183  hdr.SetType (WIFI_MAC_QOSDATA);
1184  hdr.SetQosTid (0);
1185 
1186  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1187  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1188 
1189  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
1190 
1191  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1192 
1193  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1194  txParams->psd = txPowerSpectrum;
1195  txParams->txPhy = 0;
1196  txParams->duration = txDuration;
1197  txParams->ppdu = ppdu;
1198 
1199  m_phy->StartRx (txParams);
1200 }
1201 
1202 void
1204 {
1205  //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
1206  Simulator::ScheduleNow (&TestPhyHeadersReception::DoCheckPhyState, this, expectedState);
1207 }
1208 
1209 void
1211 {
1212  WifiPhyState currentState;
1213  PointerValue ptr;
1214  m_phy->GetAttribute ("State", ptr);
1215  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1216  currentState = state->GetState ();
1217  NS_LOG_FUNCTION (this << currentState);
1218  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1219 }
1220 
1221 
1223 {
1224  m_phy = 0;
1225 }
1226 
1227 void
1229 {
1230  m_phy = CreateObject<SpectrumWifiPhy> ();
1232  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1233  m_phy->SetErrorRateModel (error);
1236 }
1237 
1238 void
1240 {
1241  RngSeedManager::SetSeed (1);
1242  RngSeedManager::SetRun (1);
1243  int64_t streamNumber = 0;
1244  m_phy->AssignStreams (streamNumber);
1245 
1246  // RX power > CCA-ED
1247  double rxPowerDbm = -50;
1248 
1249  // CASE 1: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1250  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1251 
1252  Simulator::Schedule (Seconds (1.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1253  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1254  // At 10 us, STA PHY STATE should be CCA_BUSY.
1255  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1256  // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to CCA_BUSY.
1257  Simulator::Schedule (Seconds (1.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1258  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10 = 162.8us.
1259  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1260  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1261 
1262  // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1263  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1264 
1265  Simulator::Schedule (Seconds (2.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1266  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1267  // At 10 us, STA PHY STATE should be CCA_BUSY.
1268  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1269  // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception should have succeeded.
1270  Simulator::Schedule (Seconds (2.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1271  Simulator::Schedule (Seconds (2.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1272  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1273  // 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.
1274  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1275  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1276  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1277  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1278 
1279  // 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:
1280  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1281 
1282  Simulator::Schedule (Seconds (3.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1283  Simulator::Schedule (Seconds (3.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1284  // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be kept to CCA_BUSY.
1285  Simulator::Schedule (Seconds (3.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1286  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1287  // 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.
1288  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1289  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1290  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1291  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1292 
1293  // 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:
1294  // PHY header reception should succeed.
1295 
1296  Simulator::Schedule (Seconds (4.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1297  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1298  // At 10 us, STA PHY STATE should be CCA_BUSY.
1299  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1300  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1301  Simulator::Schedule (Seconds (4.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1302  Simulator::Schedule (Seconds (4.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1303  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1304  // 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.
1305  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1306  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1307  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1308  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1309 
1310  // RX power < CCA-ED
1311  rxPowerDbm = -70;
1312 
1313  // CASE 5: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1314  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1315 
1316  Simulator::Schedule (Seconds (5.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1317  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1318  // At 10 us, STA PHY STATE should be CCA_BUSY.
1319  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1320  // 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.
1321  Simulator::Schedule (Seconds (5.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1322  Simulator::Schedule (Seconds (5.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1323 
1324  // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1325  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1326 
1327  Simulator::Schedule (Seconds (6.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1328  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1329  // At 10 us, STA PHY STATE should be CCA_BUSY.
1330  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1331  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1332  Simulator::Schedule (Seconds (6.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1333  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1334  Simulator::Schedule (Seconds (6.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1335  Simulator::Schedule (Seconds (6.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1336  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1337  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1338  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1339 
1340  // 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:
1341  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1342 
1343  Simulator::Schedule (Seconds (7.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1344  Simulator::Schedule (Seconds (7.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1345  // At 10 us, STA PHY STATE should be CCA_BUSY.
1346  Simulator::Schedule (Seconds (7.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1347  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1348  Simulator::Schedule (Seconds (7.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1349  // 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.
1350  Simulator::Schedule (Seconds (7.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1351  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1352  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1353  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1354 
1355  // 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:
1356  // PHY header reception should succeed.
1357 
1358  Simulator::Schedule (Seconds (8.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1359  Simulator::Schedule (Seconds (8.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1360  // At 10 us, STA PHY STATE should be CCA_BUSY.
1361  Simulator::Schedule (Seconds (8.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1362  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1363  Simulator::Schedule (Seconds (8.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1364  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1365  Simulator::Schedule (Seconds (8.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1366  Simulator::Schedule (Seconds (8.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1367  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1368  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1369  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1370 
1371  Simulator::Run ();
1372  Simulator::Destroy ();
1373 }
1374 
1382 {
1383 public:
1384  TestAmpduReception ();
1385  virtual ~TestAmpduReception ();
1386 
1387 protected:
1388  virtual void DoSetup (void);
1389 
1390 private:
1391  virtual void DoRun (void);
1392 
1400  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1405  void RxFailure (Ptr<WifiPsdu> psdu);
1416  void IncrementSuccessBitmap (uint32_t size);
1421  void IncrementFailureBitmap (uint32_t size);
1422 
1426  void ResetBitmaps();
1427 
1433  void SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize);
1434 
1439  void CheckRxSuccessBitmapAmpdu1 (uint8_t expected);
1444  void CheckRxSuccessBitmapAmpdu2 (uint8_t expected);
1449  void CheckRxFailureBitmapAmpdu1 (uint8_t expected);
1454  void CheckRxFailureBitmapAmpdu2 (uint8_t expected);
1459  void CheckRxDroppedBitmapAmpdu1 (uint8_t expected);
1464  void CheckRxDroppedBitmapAmpdu2 (uint8_t expected);
1465 
1470  void CheckPhyState (WifiPhyState expectedState);
1471 
1473 
1476 
1479 
1482 };
1483 
1485 : TestCase ("A-MPDU reception test"),
1486  m_rxSuccessBitmapAmpdu1 (0),
1487  m_rxSuccessBitmapAmpdu2 (0),
1488  m_rxFailureBitmapAmpdu1 (0),
1489  m_rxFailureBitmapAmpdu2 (0),
1490  m_rxDroppedBitmapAmpdu1 (0),
1491  m_rxDroppedBitmapAmpdu2 (0)
1492 {
1493 }
1494 
1496 {
1497  m_phy = 0;
1498 }
1499 
1500 void
1502 {
1509 }
1510 
1511 void
1512 TestAmpduReception::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1513 {
1514  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
1515  if (statusPerMpdu.empty ()) //wait for the whole A-MPDU
1516  {
1517  return;
1518  }
1519  NS_ABORT_MSG_IF (psdu->GetNMpdus () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1520  auto rxOkForMpdu = statusPerMpdu.begin ();
1521  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1522  {
1523  if (*rxOkForMpdu)
1524  {
1525  IncrementSuccessBitmap ((*mpdu)->GetSize ());
1526  }
1527  else
1528  {
1529  IncrementFailureBitmap ((*mpdu)->GetSize ());
1530  }
1531  ++rxOkForMpdu;
1532  }
1533 }
1534 
1535 void
1537 {
1538  if (size == 1030) //A-MPDU 1 - MPDU #1
1539  {
1541  }
1542  else if (size == 1130) //A-MPDU 1 - MPDU #2
1543  {
1544  m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1545  }
1546  else if (size == 1230) //A-MPDU 1 - MPDU #3
1547  {
1548  m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1549  }
1550  else if (size == 1330) //A-MPDU 2 - MPDU #1
1551  {
1553  }
1554  else if (size == 1430) //A-MPDU 2 - MPDU #2
1555  {
1556  m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1557  }
1558  else if (size == 1530) //A-MPDU 2 - MPDU #3
1559  {
1560  m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1561  }
1562 }
1563 
1564 void
1566 {
1567  NS_LOG_FUNCTION (this << *psdu);
1568  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1569  {
1570  IncrementFailureBitmap ((*mpdu)->GetSize ());
1571  }
1572 }
1573 
1574 void
1576 {
1577  if (size == 1030) //A-MPDU 1 - MPDU #1
1578  {
1580  }
1581  else if (size == 1130) //A-MPDU 1 - MPDU #2
1582  {
1583  m_rxFailureBitmapAmpdu1 |= (1 << 1);
1584  }
1585  else if (size == 1230) //A-MPDU 1 - MPDU #3
1586  {
1587  m_rxFailureBitmapAmpdu1 |= (1 << 2);
1588  }
1589  else if (size == 1330) //A-MPDU 2 - MPDU #1
1590  {
1592  }
1593  else if (size == 1430) //A-MPDU 2 - MPDU #2
1594  {
1595  m_rxFailureBitmapAmpdu2 |= (1 << 1);
1596  }
1597  else if (size == 1530) //A-MPDU 2 - MPDU #3
1598  {
1599  m_rxFailureBitmapAmpdu2 |= (1 << 2);
1600  }
1601 }
1602 
1603 void
1605 {
1606  NS_LOG_FUNCTION (this << p << reason);
1607  if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1608  {
1610  }
1611  else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1612  {
1613  m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1614  }
1615  else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1616  {
1617  m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1618  }
1619  else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1620  {
1622  }
1623  else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1624  {
1625  m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1626  }
1627  else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1628  {
1629  m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1630  }
1631 }
1632 
1633 void
1635 {
1636  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1637 }
1638 
1639 void
1641 {
1642  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1643 }
1644 
1645 void
1647 {
1648  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1649 }
1650 
1651 void
1653 {
1654  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1655 }
1656 
1657 void
1659 {
1660  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1661 }
1662 
1663 void
1665 {
1666  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1667 }
1668 
1669 void
1671 {
1672  WifiPhyState currentState;
1673  PointerValue ptr;
1674  m_phy->GetAttribute ("State", ptr);
1675  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1676  currentState = state->GetState ();
1677  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1678 }
1679 
1680 void
1681 TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1682 {
1683  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true);
1684 
1685  WifiMacHeader hdr;
1686  hdr.SetType (WIFI_MAC_QOSDATA);
1687  hdr.SetQosTid (0);
1688 
1689  std::vector<Ptr<WifiMacQueueItem>> mpduList;
1690  for (size_t i = 0; i < 3; ++i)
1691  {
1692  Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1693  mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1694  }
1695  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1696 
1697  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1698 
1699  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
1700 
1701  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1702 
1703  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1704  txParams->psd = txPowerSpectrum;
1705  txParams->txPhy = 0;
1706  txParams->duration = txDuration;
1707  txParams->ppdu = ppdu;
1708 
1709  m_phy->StartRx (txParams);
1710 }
1711 
1712 void
1714 {
1715  m_phy = CreateObject<SpectrumWifiPhy> ();
1717  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1718  m_phy->SetErrorRateModel (error);
1721 
1725 
1726  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1727  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1728  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1729 
1730  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1731  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1732  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1733  m_phy->SetFrameCaptureModel (frameCaptureModel);
1734 }
1735 
1736 void
1738 {
1739  RngSeedManager::SetSeed (1);
1740  RngSeedManager::SetRun (2);
1741  int64_t streamNumber = 1;
1742  double rxPowerDbm = -30;
1743  m_phy->AssignStreams (streamNumber);
1744 
1746  // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1747  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1749 
1750  // A-MPDU 1
1751  Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1752 
1753  // A-MPDU 2
1754  Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1755 
1756  // All MPDUs of A-MPDU 1 should have been ignored.
1757  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1758  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1759  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1760 
1761  // All MPDUs of A-MPDU 2 should have been successfully received.
1762  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1763  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1764  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1765 
1766  Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1767 
1769  // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1770  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1772 
1773  // A-MPDU 1
1774  Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1775 
1776  // A-MPDU 2
1777  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1778 
1779  // All MPDUs of A-MPDU 1 should have been received.
1780  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1781  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1782  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1783 
1784  // All MPDUs of A-MPDU 2 should have been ignored.
1785  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1786  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1787  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1788 
1789  Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1790 
1792  // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1793  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1795 
1796  // A-MPDU 1
1797  Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1798 
1799  // A-MPDU 2
1800  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1801 
1802  // All MPDUs of A-MPDU 1 should have been ignored.
1803  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1804  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1805  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1806 
1807  // All MPDUs of A-MPDU 2 should have been successfully received.
1808  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1809  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1810  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1811 
1812  Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1813 
1815  // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1816  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1818 
1819  // A-MPDU 1
1820  Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1821 
1822  // A-MPDU 2
1823  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1824 
1825  // All MPDUs of A-MPDU 1 should have been received.
1826  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1827  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1828  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1829 
1830  // All MPDUs of A-MPDU 2 should have been ignored.
1831  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1832  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1833  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1834 
1835  Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1836 
1838  // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1839  // 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).
1841 
1842  // A-MPDU 1
1843  Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1844 
1845  // A-MPDU 2
1846  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1847 
1848  // All MPDUs of A-MPDU 1 should have been ignored.
1849  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1850  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1851  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1852 
1853  // All MPDUs of A-MPDU 2 should have been successfully received.
1854  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1855  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1856  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1857 
1858  Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1859 
1861  // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1862  // 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).
1864 
1865  // A-MPDU 1
1866  Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1867 
1868  // A-MPDU 2
1869  Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1870 
1871  // All MPDUs of A-MPDU 1 should have been received.
1872  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1873  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1874  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1875 
1876  // All MPDUs of A-MPDU 2 should have been ignored.
1877  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1878  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1879  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1880 
1881  Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1882 
1884  // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1885  // The second A-MPDU is received during the payload of MPDU #2.
1887 
1888  // A-MPDU 1
1889  Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1890 
1891  // A-MPDU 2
1892  Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1893 
1894  // All MPDUs of A-MPDU 1 should have been ignored.
1895  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1896  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1897  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1898 
1899  // All MPDUs of A-MPDU 2 should have been successfully received.
1900  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1901  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1902  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1903 
1904  Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1905 
1907  // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1908  // The second A-MPDU is received during the payload of MPDU #2.
1910 
1911  // A-MPDU 1
1912  Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1913 
1914  // A-MPDU 2
1915  Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1916 
1917  // All MPDUs of A-MPDU 1 should have been received.
1918  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1919  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1920  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1921 
1922  // All MPDUs of A-MPDU 2 should have been ignored.
1923  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1924  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1925  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1926 
1927  Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
1928 
1930  // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1931  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1933 
1934  // A-MPDU 1
1935  Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1936 
1937  // A-MPDU 2
1938  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
1939 
1940  // All MPDUs of A-MPDU 1 should have been dropped.
1941  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1942  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1943  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1944 
1945  // All MPDUs of A-MPDU 2 should have been received with errors.
1946  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1947  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
1948  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1949 
1950  Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
1951 
1953  // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
1954  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1956 
1957  // A-MPDU 1
1958  Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1959 
1960  // A-MPDU 2
1961  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1962 
1963  // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
1964  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1965  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1966  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1967 
1968  // All MPDUs of A-MPDU 2 should have been dropped as well.
1969  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1970  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1971  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1972 
1973  Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
1974 
1976  // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
1977  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1979 
1980  // A-MPDU 1
1981  Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
1982 
1983  // A-MPDU 2
1984  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1985 
1986  // All MPDUs of A-MPDU 1 should have been received with errors.
1987  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1988  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
1989  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1990 
1991  // All MPDUs of A-MPDU 2 should have been dropped.
1992  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1993  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1994  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1995 
1996  Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
1997 
1999  // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
2000  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2002 
2003  // A-MPDU 1
2004  Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2005 
2006  // A-MPDU 2
2007  Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2008 
2009  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2010  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2011  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2012  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2013 
2014  // 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)
2015  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2016  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2017  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2018 
2019  Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
2020 
2022  // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2023  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2025 
2026  // A-MPDU 1
2027  Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2028 
2029  // A-MPDU 2
2030  Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2031 
2032  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2033  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2034  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2035  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2036 
2037  // All MPDUs of A-MPDU 2 should have been dropped as well.
2038  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2039  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2040  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2041 
2042  Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
2043 
2045  // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2046  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2048 
2049  // A-MPDU 1
2050  Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2051 
2052  // A-MPDU 2
2053  Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2054 
2055  // All MPDUs of A-MPDU 1 should have been received with errors.
2056  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2057  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2058  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2059 
2060  // All MPDUs of A-MPDU 2 should have been dropped.
2061  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2062  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2063  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2064 
2065  Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
2066 
2068  // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2069  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2071 
2072  // A-MPDU 1
2073  Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2074 
2075  // A-MPDU 2
2076  Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2077 
2078  // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
2079  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2080  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2081  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2082 
2083  // All MPDUs of A-MPDU 2 should have been successfully received
2084  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
2085  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2086  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2087 
2088  Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
2089 
2091  // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2092  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2094 
2095  // A-MPDU 1
2096  Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2097 
2098  // A-MPDU 2
2099  Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2100 
2101  // All MPDUs of A-MPDU 1 should have been successfully received.
2102  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2103  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2104  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2105 
2106  // All MPDUs of A-MPDU 2 should have been dropped.
2107  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2108  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2109  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2110 
2111  Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2112 
2114  // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2115  // 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).
2117 
2118  // A-MPDU 1
2119  Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2120 
2121  // A-MPDU 2
2122  Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2123 
2124  // All MPDUs of A-MPDU 1 should have been received with errors.
2125  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2126  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2127  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2128 
2129  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2130  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2131  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2132  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2133 
2134  Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2135 
2137  // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2138  // 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).
2140 
2141  // A-MPDU 1
2142  Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2143 
2144  // A-MPDU 2
2145  Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2146 
2147  // All MPDUs of A-MPDU 1 should have been successfully received.
2148  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2149  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2150  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2151 
2152  // All MPDUs of A-MPDU 2 should have been dropped.
2153  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2154  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2155  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2156 
2157  Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2158 
2160  // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2161  // 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).
2163 
2164  // A-MPDU 1
2165  Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2166 
2167  // A-MPDU 2
2168  Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2169 
2170  // All MPDUs of A-MPDU 1 should have been received with errors.
2171  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2172  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2173  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2174 
2175  // All MPDUs of A-MPDU 2 should have been dropped.
2176  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2177  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2178  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2179 
2180  Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2181 
2183  // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2184  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2186 
2187  // A-MPDU 1
2188  Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2189 
2190  // A-MPDU 2
2191  Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2192 
2193  // All MPDUs of A-MPDU 1 should have been received with errors.
2194  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2195  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2196  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2197 
2198  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2199  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2200  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2201  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2202 
2203  Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2204 
2206  // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2207  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2209 
2210  // A-MPDU 1
2211  Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2212 
2213  // A-MPDU 2
2214  Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2215 
2216  // All MPDUs of A-MPDU 1 should have been successfully received.
2217  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2218  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2219  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2220 
2221  // All MPDUs of A-MPDU 2 should have been dropped.
2222  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2223  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2224  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2225 
2226  Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2227 
2229  // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2230  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2232 
2233  // A-MPDU 1
2234  Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2235 
2236  // A-MPDU 2
2237  Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2238 
2239  // All MPDUs of A-MPDU 1 should have been received with errors.
2240  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2241  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2242  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2243 
2244  // All MPDUs of A-MPDU 2 should have been dropped.
2245  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2246  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2247  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2248 
2249  Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2250 
2252  // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2253  // The second A-MPDU is received during the payload of MPDU #2.
2255 
2256  // A-MPDU 1
2257  Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2258 
2259  // A-MPDU 2
2260  Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2261 
2262  // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2263  // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2264  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2265  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2266  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2267 
2268  // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2269  // 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.
2270  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2271  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2272  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2273 
2274  Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2275 
2276  Simulator::Run ();
2277  Simulator::Destroy ();
2278 }
2279 
2287 {
2288 public:
2290 };
2291 
2293  : TestSuite ("wifi-phy-reception", UNIT)
2294 {
2297  AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2298  AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2299  AddTestCase (new TestAmpduReception, TestCase::QUICK);
2300 }
2301 
uint8_t m_rxSuccessBitmapAmpdu1
bitmap of successfully received MPDUs in A-MPDU #1
bool IsSingle(void) const
Return true if the PSDU is an S-MPDU.
Definition: wifi-psdu.cc:75
void CheckRxFailureBitmapAmpdu2(uint8_t expected)
Check the RX failure bitmap for A-MPDU 2.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< SpectrumWifiPhy > m_phy
Phy.
Ptr< T > Get(void) const
Definition: pointer.h:201
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
void SendPacket(double rxPowerDbm)
Send packet function.
void Expect1000BPacketDropped()
Verify whether 1000 bytes packet has been dropped.
Ptr< WifiPpdu > ppdu
The PPDU being transmitted.
static const uint32_t packetSize
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
void SendPacket(double rxPowerDbm, uint32_t packetSize)
Send packet function.
void IncrementFailureBitmap(uint32_t size)
Increment reception failure bitmap.
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1426
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:41
A suite of tests to run.
Definition: test.h:1343
void ResetBitmaps()
Reset bitmaps function.
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
RX success function.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void Reset(void)
Reset function.
void CheckRxSuccessBitmapAmpdu1(uint8_t expected)
Check the RX success bitmap for A-MPDU 1.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:589
#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 Expect1500BPacketReceived()
Verify whether 1500 bytes packet has been received.
static WifiPhyReceptionTestSuite wifiPhyReceptionTestSuite
the test suite
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Simple frame capture model test.
The 5 GHz band.
Definition: wifi-phy-band.h:35
encapsulates test code
Definition: test.h:1153
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:798
std::vector< Ptr< WifiMacQueueItem > >::const_iterator end(void) const
Return a const iterator to past-the-last MPDU.
Definition: wifi-psdu.cc:337
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test PHY state upon success or failure of L-SIG and SIG-A.
virtual void SetChannelNumber(uint8_t id)
Set channel number.
static const uint16_t GUARD_WIDTH
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint32_t GetSize(void) const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:260
Ptr< SpectrumWifiPhy > m_phy
Phy.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
Preamble detection test w/o frame capture.
Preamble detection test w/o frame capture.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm)
Send packet function.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
AttributeValue implementation for Time.
Definition: nstime.h:1353
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
void Expect1000BPacketReceived()
Verify whether 1000 bytes packet has been received.
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:804
bool m_rxSuccess1000B
count received packets with 1000B payload
uint8_t m_rxFailureBitmapAmpdu1
bitmap of unsuccessfully received MPDUs in A-MPDU #1
The PHY layer has sense the medium busy through the CCA mechanism.
Ptr< SpectrumPhy > txPhy
The SpectrumPhy instance that is making the transmission.
static const uint32_t FREQUENCY
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void IncrementSuccessBitmap(uint32_t size)
Increment reception success bitmap.
uint8_t m_rxDroppedBitmapAmpdu2
bitmap of dropped MPDUs in A-MPDU #2
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 RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
virtual void SetFrequency(uint16_t freq)
virtual void ConfigureStandardAndBand(WifiPhyStandard standard, WifiPhyBand band)
Configure the PHY-level parameters for different Wi-Fi standard.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:784
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void CheckRxDroppedBitmapAmpdu2(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 2.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
A-MPDU reception test.
std::size_t GetNMpdus(void) const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:319
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void SendPacket(double rxPowerDbm)
Send packet function.
The PHY layer is IDLE.
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
WifiPhyState
The state of the PHY layer.
bool m_rxDropped1500B
count dropped packets with 1500B payload
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
void CheckRxSuccessBitmapAmpdu2(uint8_t expected)
Check the RX success bitmap for A-MPDU 2.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
uint8_t m_rxSuccessBitmapAmpdu2
bitmap of successfully received MPDUs in A-MPDU #2
uint8_t m_rxFailureBitmapAmpdu2
bitmap of unsuccessfully received MPDUs in A-MPDU #2
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:583
This objects implements the PHY state machine of the Wifi device.
WifiPhyState GetState(void) const
Return the current state of WifiPhy.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
Definition: wifi-phy.h:52
The PHY layer is receiving a packet.
bool m_rxSuccess1500B
count received packets with 1500B payload
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
void RxFailure(Ptr< WifiPsdu > psdu)
RX failure function.
Time duration
The duration of the packet transmission.
static const uint16_t CHANNEL_WIDTH
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void Expect1500BPacketDropped()
Verify whether 1500 bytes packet has been dropped.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
static Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:2546
uint8_t m_rxDroppedBitmapAmpdu1
bitmap of dropped MPDUs in A-MPDU #1
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void CheckRxFailureBitmapAmpdu1(uint8_t expected)
Check the RX failure bitmap for A-MPDU 1.
bool m_rxDropped1000B
count dropped packets with 1000B payload
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:223
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
wifi PHY reception Test Suite
static const uint8_t CHANNEL_NUMBER
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Definition: wifi-phy.cc:4758
Implements the IEEE 802.11 MAC header.
void CheckRxDroppedBitmapAmpdu1(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 1.
bool IsAggregate(void) const
Return true if the PSDU is an S-MPDU or A-MPDU.
Definition: wifi-psdu.cc:81