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-psdu.h"
37 #include "ns3/wifi-mac-queue-item.h"
38 #include "ns3/mpdu-aggregator.h"
39 #include "ns3/wifi-psdu.h"
40 #include "ns3/wifi-ppdu.h"
41 
42 using namespace ns3;
43 
44 NS_LOG_COMPONENT_DEFINE ("WifiPhyReceptionTest");
45 
46 static const uint8_t CHANNEL_NUMBER = 36;
47 static const uint32_t FREQUENCY = 5180; // MHz
48 static const uint16_t CHANNEL_WIDTH = 20; // MHz
49 static const uint16_t GUARD_WIDTH = CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
50 
58 {
59 public:
62 
63 protected:
64  virtual void DoSetup (void);
66 
70  void SendPacket (double rxPowerDbm);
78  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
83  void RxFailure (Ptr<WifiPsdu> psdu);
84  uint32_t m_countRxSuccess;
85  uint32_t m_countRxFailure;
86 
87 private:
88  virtual void DoRun (void);
89 
94  void CheckPhyState (WifiPhyState expectedState);
99  void DoCheckPhyState (WifiPhyState expectedState);
105  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
106 };
107 
109  : TestCase ("Threshold preamble detection model test when no frame capture model is applied"),
110  m_countRxSuccess (0),
111  m_countRxFailure (0)
112 {
113 }
114 
115 void
117 {
118  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
119 
120  Ptr<Packet> pkt = Create<Packet> (1000);
121  WifiMacHeader hdr;
122 
124  hdr.SetQosTid (0);
125 
126  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
127  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
128 
129  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
130 
131  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
132 
133  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
134  txParams->psd = txPowerSpectrum;
135  txParams->txPhy = 0;
136  txParams->duration = txDuration;
137  txParams->ppdu = ppdu;
138 
139  m_phy->StartRx (txParams);
140 }
141 
142 void
144 {
145  //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
146  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithoutFrameCapture::DoCheckPhyState, this, expectedState);
147 }
148 
149 void
151 {
152  WifiPhyState currentState;
153  PointerValue ptr;
154  m_phy->GetAttribute ("State", ptr);
155  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
156  currentState = state->GetState ();
157  NS_LOG_FUNCTION (this << currentState);
158  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
159 }
160 
161 void
162 TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
163 {
164  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
165  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
166 }
167 
168 void
169 TestThresholdPreambleDetectionWithoutFrameCapture::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
170 {
171  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
173 }
174 
175 void
177 {
178  NS_LOG_FUNCTION (this << *psdu);
180 }
181 
183 {
184  m_phy = 0;
185 }
186 
187 void
189 {
190  m_phy = CreateObject<SpectrumWifiPhy> ();
192  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
193  m_phy->SetErrorRateModel (error);
198 
199  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
200  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
201  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
202  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
203 }
204 
205 void
207 {
208  RngSeedManager::SetSeed (1);
209  RngSeedManager::SetRun (1);
210  int64_t streamNumber = 0;
211  m_phy->AssignStreams (streamNumber);
212 
213  //RX power > CCA-ED > CCA-PD
214  double rxPowerDbm = -50;
215 
216  // CASE 1: send one packet and check PHY state:
217  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
218  // otherwise it should be IDLE.
219 
220  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
221  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
224  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
227  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
230  // Packet should have been successfully received
231  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
232 
233  // CASE 2: send two packets with same power within the 4us window and check PHY state:
234  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
235  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
236  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
237 
238  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
239  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
240  // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
243  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
246  // 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
247  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
248 
249  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
250  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
251  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
252  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
253 
254  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
255  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
256  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
259  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
262  // 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
263  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
264 
265  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
266  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
267  // but payload reception should fail (SNR too low to decode the modulation).
268 
269  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
270  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
271  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
274  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
277  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
278  // 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.
283  // In this case, the first packet should be marked as a failure
284  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
285 
286  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
287  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
288  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
289  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
290 
291  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
292  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
293  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
296  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
299  // 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
300  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
301 
302  // CCA-PD < RX power < CCA-ED
303  rxPowerDbm = -70;
304 
305  // CASE 6: send one packet and check PHY state:
306  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
307  // otherwise it should be IDLE.
308 
309  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
310  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
313  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
316  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
319  // Packet should have been successfully received
320  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
321 
322  // CASE 7: send two packets with same power within the 4us window and check PHY state:
323  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
324  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
325 
326  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
327  Simulator::Schedule (Seconds (7.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
328  // At 4us, STA PHY STATE should stay IDLE
330  // 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
331  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
332 
333  // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
334  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
335  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
336 
337  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
338  Simulator::Schedule (Seconds (8.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
339  // At 4us, STA PHY STATE should stay IDLE
341  // 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
342  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
343 
344  // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
345  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
346  // but payload reception should fail (SNR too low to decode the modulation).
347 
348  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
349  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
350  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
353  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
356  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
359  // In this case, the first packet should be marked as a failure
360  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
361 
362  // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY state:
363  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
364  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
365 
366  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
367  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
368  // At 4us, STA PHY STATE should stay IDLE
370  // 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
371  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
372 
373  // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
374  // preamble detection should succeed and PHY state should move to RX.
375 
376  rxPowerDbm = -81;
377 
378  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
379  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
382  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
385  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
388 
389  // RX power < CCA-PD < CCA-ED
390  rxPowerDbm = -83;
391 
392  //CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
393  //preamble detection should fail and PHY should be kept in IDLE state.
394 
395  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
396  // At 4us, STA PHY state should be IDLE
398 
399  Simulator::Run ();
400  Simulator::Destroy ();
401 }
402 
410 {
411 public:
414 
415 protected:
416  virtual void DoSetup (void);
418 
422  void SendPacket (double rxPowerDbm);
430  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
435  void RxFailure (Ptr<WifiPsdu> psdu);
436  uint32_t m_countRxSuccess;
437  uint32_t m_countRxFailure;
438 
439 private:
440  virtual void DoRun (void);
441 
446  void CheckPhyState (WifiPhyState expectedState);
451  void DoCheckPhyState (WifiPhyState expectedState);
457  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
458 };
459 
461 : TestCase ("Threshold preamble detection model test when simple frame capture model is applied"),
462 m_countRxSuccess (0),
463 m_countRxFailure (0)
464 {
465 }
466 
467 void
469 {
470  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
471 
472  Ptr<Packet> pkt = Create<Packet> (1000);
473  WifiMacHeader hdr;
474 
476  hdr.SetQosTid (0);
477 
478  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
479  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
480 
481  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
482 
483  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
484 
485  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
486  txParams->psd = txPowerSpectrum;
487  txParams->txPhy = 0;
488  txParams->duration = txDuration;
489  txParams->ppdu = ppdu;
490 
491  m_phy->StartRx (txParams);
492 }
493 
494 void
496 {
497  //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
498  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithFrameCapture::DoCheckPhyState, this, expectedState);
499 }
500 
501 void
503 {
504  WifiPhyState currentState;
505  PointerValue ptr;
506  m_phy->GetAttribute ("State", ptr);
507  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
508  currentState = state->GetState ();
509  NS_LOG_FUNCTION (this << currentState);
510  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
511 }
512 
513 void
514 TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
515 {
516  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
517  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
518 }
519 
520 void
521 TestThresholdPreambleDetectionWithFrameCapture::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
522 {
523  NS_LOG_FUNCTION (this << *psdu << txVector);
525 }
526 
527 void
529 {
530  NS_LOG_FUNCTION (this << *psdu);
532 }
533 
535 {
536  m_phy = 0;
537 }
538 
539 void
541 {
542  m_phy = CreateObject<SpectrumWifiPhy> ();
544  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
545  m_phy->SetErrorRateModel (error);
550 
551  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
552  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
553  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
554  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
555 
556  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
557  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
558  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
559  m_phy->SetFrameCaptureModel (frameCaptureModel);
560 }
561 
562 void
564 {
565  RngSeedManager::SetSeed (1);
566  RngSeedManager::SetRun (1);
567  int64_t streamNumber = 1;
568  m_phy->AssignStreams (streamNumber);
569 
570  //RX power > CCA-ED > CCA-PD
571  double rxPowerDbm = -50;
572 
573  // CASE 1: send one packet and check PHY state:
574  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
575  // otherwise it should be IDLE.
576 
577  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
578  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
581  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
584  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
587  // Packet should have been successfully received
588  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
589 
590  // CASE 2: send two packets with same power within the 4us window and check PHY state:
591  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
592  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
593  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
594 
595  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
596  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
597  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
600  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
603  // 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
604  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
605 
606  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
607  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
608  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
609  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
610 
611  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
612  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
613  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
616  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
619  // 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
620  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
621 
622  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
623  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
624  // but payload reception should fail (SNR too low to decode the modulation).
625 
626  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
627  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
628  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
631  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
634  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
635  // 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.
640  // In this case, the first packet should be marked as a failure
641  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
642 
643  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
644  // PHY preamble detection should switch because a higher packet is received within the 4us window,
645  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
646  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
647 
648  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
649  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
650  // At 4us, STA PHY STATE should stay IDLE
652  // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
655  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
658  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
659  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
660 
661  // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY state:
662  // PHY preamble detection should switch because a higher packet is received within the 4us window,
663  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
664  // Payload reception should fail (SNR too low to decode the modulation).
665 
666  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
667  Simulator::Schedule (Seconds (6.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
668  // At 4us, STA PHY STATE should stay IDLE
670  // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
673  // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
676  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
679  // In this case, the second packet should be marked as a failure
680  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
681 
682  // CASE 7: send two packets with same power at the exact same time and check PHY state:
683  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
684  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
685  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
686 
687  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
688  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
689  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
692  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
695  // 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
696  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
697 
698  // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY state:
699  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
700  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
701  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
702 
703  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
704  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
705  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
708  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
711  // 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
712  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
713 
714  // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY state:
715  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
716  // but payload reception should fail (SNR too low to decode the modulation).
717 
718  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
719  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
720  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
723  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
726  // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
729  // In this case, the first packet should be marked as a failure
730  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
731 
732  // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY state:
733  // PHY preamble detection should switch because a higher packet is received within the 4us window,
734  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
735  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
736 
737  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
738  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
739  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
742  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
745  // 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
746  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
747 
748  // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY state:
749  // PHY preamble detection should switch because a higher packet is received within the 4us window,
750  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
751  // Payload reception should fail (SNR too low to decode the modulation).
752 
753  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
754  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
755  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
758  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
761  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
764  // In this case, the second packet should be marked as a failure
765  Simulator::Schedule (Seconds (11.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 4);
766 
767  // CCA-PD < RX power < CCA-ED
768  rxPowerDbm = -70;
769 
770  // CASE 12: send one packet and check PHY state:
771  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
772  // otherwise it should be IDLE.
773 
774  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
775  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
778  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
781  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
784  // Packet should have been successfully received
785  Simulator::Schedule (Seconds (12.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
786 
787  // CASE 13: send two packets with same power within the 4us window and check PHY state:
788  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
789  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
790 
791  Simulator::Schedule (Seconds (13.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
792  Simulator::Schedule (Seconds (13.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
793  // At 4us, STA PHY STATE should stay IDLE
795  // 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
796  Simulator::Schedule (Seconds (13.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
797 
798  // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
799  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
800  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
801 
802  Simulator::Schedule (Seconds (14.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
803  Simulator::Schedule (Seconds (14.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
804  // At 4us, STA PHY STATE should stay IDLE
806  // 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
807  Simulator::Schedule (Seconds (14.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
808 
809  // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
810  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
811  // but payload reception should fail (SNR too low to decode the modulation).
812 
813  Simulator::Schedule (Seconds (15.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
814  Simulator::Schedule (Seconds (15.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
815  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
818  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
821  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
824  // In this case, the first packet should be marked as a failure
825  Simulator::Schedule (Seconds (15.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
826 
827  // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY state:
828  // PHY preamble detection should switch because a higher packet is received within the 4us window,
829  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB).
830  // PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
831 
832  Simulator::Schedule (Seconds (16.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
833  Simulator::Schedule (Seconds (16.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
834  // At 4us, STA PHY STATE should stay IDLE
836  // At 6us, STA PHY STATE should stay IDLE
838  // 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
839  Simulator::Schedule (Seconds (16.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
840 
841  // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY state:
842  // PHY preamble detection should switch because a higher packet is received within the 4us window,
843  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
844  // Payload reception should fail (SNR too low to decode the modulation).
845 
846  Simulator::Schedule (Seconds (17.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
847  Simulator::Schedule (Seconds (17.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
848  // At 4us, STA PHY STATE should stay IDLE
850  // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
853  // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
856  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
859  // In this case, the second packet should be marked as a failure
860  Simulator::Schedule (Seconds (17.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 6);
861 
862  rxPowerDbm = -50;
863  // CASE 18: send two packets with second one 50 dB higher within the 4us window
864 
865  Simulator::Schedule (Seconds (18.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
866  Simulator::Schedule (Seconds (18.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
867  // The second packet should be received successfully
868  Simulator::Schedule (Seconds (18.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 6);
869 
870  // CASE 19: send two packets with second one 10 dB higher within the 4us window
871 
872  Simulator::Schedule (Seconds (19.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
873  Simulator::Schedule (Seconds (19.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
874  // The second packet should be captured, but not decoded since SNR to low for used MCS
875  Simulator::Schedule (Seconds (19.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 7);
876 
877  // CASE 20: send two packets with second one 50 dB higher in the same time
878 
879  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
880  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
881  // The second packet should be received successfully, same as in CASE 13
882  Simulator::Schedule (Seconds (20.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 7);
883 
884  // CASE 21: send two packets with second one 10 dB higher in the same time
885 
886  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
887  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
888  // The second packet should be captured, but not decoded since SNR to low for used MCS, same as in CASE 19
889  Simulator::Schedule (Seconds (21.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 8);
890 
891  Simulator::Run ();
892  Simulator::Destroy ();
893 }
894 
902 {
903 public:
905  virtual ~TestSimpleFrameCaptureModel ();
906 
907 protected:
908  virtual void DoSetup (void);
909 
910 private:
911  virtual void DoRun (void);
912 
916  void Reset (void);
922  void SendPacket (double rxPowerDbm, uint32_t packetSize);
930  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
937 
949  void Expect1000BPacketDropped ();
953  void Expect1500BPacketDropped ();
954 
956 
961 };
962 
964 : TestCase ("Simple frame capture model test"),
965  m_rxSuccess1000B (false),
966  m_rxSuccess1500B (false),
967  m_rxDropped1000B (false),
968  m_rxDropped1500B (false)
969 {
970 }
971 
972 void
974 {
975  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
976 
977  Ptr<Packet> pkt = Create<Packet> (packetSize);
978  WifiMacHeader hdr;
979 
981  hdr.SetQosTid (0);
982 
983  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
984  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
985 
986  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
987 
988  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
989 
990  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
991  txParams->psd = txPowerSpectrum;
992  txParams->txPhy = 0;
993  txParams->duration = txDuration;
994  txParams->ppdu = ppdu;
995 
996  m_phy->StartRx (txParams);
997 }
998 
999 void
1000 TestSimpleFrameCaptureModel::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1001 {
1002  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
1003  NS_ASSERT (!psdu->IsAggregate () || psdu->IsSingle ());
1004  if (psdu->GetSize () == 1030)
1005  {
1006  m_rxSuccess1000B = true;
1007  }
1008  else if (psdu->GetSize () == 1530)
1009  {
1010  m_rxSuccess1500B = true;
1011  }
1012 }
1013 
1014 void
1016 {
1017  NS_LOG_FUNCTION (this << p << reason);
1018  if (p->GetSize () == 1030)
1019  {
1020  m_rxDropped1000B = true;
1021  }
1022  else if (p->GetSize () == 1530)
1023  {
1024  m_rxDropped1500B = true;
1025  }
1026 }
1027 
1028 void
1030 {
1031  m_rxSuccess1000B = false;
1032  m_rxSuccess1500B = false;
1033  m_rxDropped1000B = false;
1034  m_rxDropped1500B = false;
1035 }
1036 
1037 void
1039 {
1040  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1000B, true, "Didn't receive 1000B packet");
1041 }
1042 
1043 void
1045 {
1046  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1500B, true, "Didn't receive 1500B packet");
1047 }
1048 void
1050 {
1051  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1000B, true, "Didn't drop 1000B packet");
1052 }
1053 
1054 void
1056 {
1057  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1500B, true, "Didn't drop 1500B packet");
1058 }
1059 
1061 {
1062  m_phy = 0;
1063 }
1064 
1065 void
1067 {
1068  m_phy = CreateObject<SpectrumWifiPhy> ();
1070  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1071  m_phy->SetErrorRateModel (error);
1074 
1077 
1078  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1079  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1080  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1081 
1082  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1083  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1084  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1085  m_phy->SetFrameCaptureModel (frameCaptureModel);
1086 }
1087 
1088 void
1090 {
1091  RngSeedManager::SetSeed (1);
1092  RngSeedManager::SetRun (1);
1093  int64_t streamNumber = 2;
1094  double rxPowerDbm = -30;
1095  m_phy->AssignStreams (streamNumber);
1096 
1097  // CASE 1: send two packets with same power within the capture window:
1098  // PHY should not switch reception because they have same power.
1099 
1100  Simulator::Schedule (Seconds (1.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1101  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1500);
1102  Simulator::Schedule (Seconds (1.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1103  Simulator::Schedule (Seconds (1.2), &TestSimpleFrameCaptureModel::Reset, this);
1104 
1105  // CASE 2: send two packets with second one 6 dB weaker within the capture window:
1106  // PHY should not switch reception because first one has higher power.
1107 
1108  Simulator::Schedule (Seconds (2.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1109  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm - 6, 1500);
1110  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1000BPacketReceived, this);
1111  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1112  Simulator::Schedule (Seconds (2.2), &TestSimpleFrameCaptureModel::Reset, this);
1113 
1114  // CASE 3: send two packets with second one 6 dB higher within the capture window:
1115  // PHY should switch reception because the second one has a higher power.
1116 
1117  Simulator::Schedule (Seconds (3.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1118  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1119  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1000BPacketDropped, this);
1120  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1500BPacketReceived, this);
1121  Simulator::Schedule (Seconds (3.2), &TestSimpleFrameCaptureModel::Reset, this);
1122 
1123  // CASE 4: send two packets with second one 6 dB higher after the capture window:
1124  // PHY should not switch reception because capture window duration has elapsed when the second packet arrives.
1125 
1126  Simulator::Schedule (Seconds (4.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1127  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1128  Simulator::Schedule (Seconds (4.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1129  Simulator::Schedule (Seconds (4.2), &TestSimpleFrameCaptureModel::Reset, this);
1130 
1131  Simulator::Run ();
1132  Simulator::Destroy ();
1133 }
1134 
1142 {
1143 public:
1145  virtual ~TestPhyHeadersReception ();
1146 
1147 protected:
1148  virtual void DoSetup (void);
1150 
1154  void SendPacket (double rxPowerDbm);
1155 
1156 private:
1157  virtual void DoRun (void);
1158 
1163  void CheckPhyState (WifiPhyState expectedState);
1168  void DoCheckPhyState (WifiPhyState expectedState);
1169 };
1170 
1172 : TestCase ("PHY headers reception test")
1173 {
1174 }
1175 
1176 void
1178 {
1179  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
1180 
1181  Ptr<Packet> pkt = Create<Packet> (1000);
1182  WifiMacHeader hdr;
1183 
1184  hdr.SetType (WIFI_MAC_QOSDATA);
1185  hdr.SetQosTid (0);
1186 
1187  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1188  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
1189 
1190  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
1191 
1192  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1193 
1194  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1195  txParams->psd = txPowerSpectrum;
1196  txParams->txPhy = 0;
1197  txParams->duration = txDuration;
1198  txParams->ppdu = ppdu;
1199 
1200  m_phy->StartRx (txParams);
1201 }
1202 
1203 void
1205 {
1206  //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
1207  Simulator::ScheduleNow (&TestPhyHeadersReception::DoCheckPhyState, this, expectedState);
1208 }
1209 
1210 void
1212 {
1213  WifiPhyState currentState;
1214  PointerValue ptr;
1215  m_phy->GetAttribute ("State", ptr);
1216  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1217  currentState = state->GetState ();
1218  NS_LOG_FUNCTION (this << currentState);
1219  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1220 }
1221 
1222 
1224 {
1225  m_phy = 0;
1226 }
1227 
1228 void
1230 {
1231  m_phy = CreateObject<SpectrumWifiPhy> ();
1233  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1234  m_phy->SetErrorRateModel (error);
1237 }
1238 
1239 void
1241 {
1242  RngSeedManager::SetSeed (1);
1243  RngSeedManager::SetRun (1);
1244  int64_t streamNumber = 0;
1245  m_phy->AssignStreams (streamNumber);
1246 
1247  // RX power > CCA-ED
1248  double rxPowerDbm = -50;
1249 
1250  // CASE 1: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1251  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1252 
1253  Simulator::Schedule (Seconds (1.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1254  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1255  // At 10 us, STA PHY STATE should be CCA_BUSY.
1256  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1257  // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to CCA_BUSY.
1258  Simulator::Schedule (Seconds (1.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1259  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10 = 162.8us.
1260  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1261  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1262 
1263  // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1264  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1265 
1266  Simulator::Schedule (Seconds (2.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1267  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1268  // At 10 us, STA PHY STATE should be CCA_BUSY.
1269  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1270  // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception should have succeeded.
1271  Simulator::Schedule (Seconds (2.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1272  Simulator::Schedule (Seconds (2.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1273  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1274  // 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.
1275  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1276  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1277  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1278  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1279 
1280  // 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:
1281  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1282 
1283  Simulator::Schedule (Seconds (3.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1284  Simulator::Schedule (Seconds (3.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1285  // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be kept to CCA_BUSY.
1286  Simulator::Schedule (Seconds (3.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1287  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1288  // 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.
1289  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1290  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1291  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1292  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1293 
1294  // 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:
1295  // PHY header reception should succeed.
1296 
1297  Simulator::Schedule (Seconds (4.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1298  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1299  // At 10 us, STA PHY STATE should be CCA_BUSY.
1300  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1301  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1302  Simulator::Schedule (Seconds (4.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1303  Simulator::Schedule (Seconds (4.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1304  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1305  // 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.
1306  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1307  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1308  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1309  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1310 
1311  // RX power < CCA-ED
1312  rxPowerDbm = -70;
1313 
1314  // CASE 5: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1315  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1316 
1317  Simulator::Schedule (Seconds (5.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1318  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1319  // At 10 us, STA PHY STATE should be CCA_BUSY.
1320  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1321  // 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.
1322  Simulator::Schedule (Seconds (5.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1323  Simulator::Schedule (Seconds (5.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1324 
1325  // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1326  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1327 
1328  Simulator::Schedule (Seconds (6.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1329  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1330  // At 10 us, STA PHY STATE should be CCA_BUSY.
1331  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1332  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1333  Simulator::Schedule (Seconds (6.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1334  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1335  Simulator::Schedule (Seconds (6.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1336  Simulator::Schedule (Seconds (6.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1337  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1338  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1339  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1340 
1341  // 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:
1342  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1343 
1344  Simulator::Schedule (Seconds (7.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1345  Simulator::Schedule (Seconds (7.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1346  // At 10 us, STA PHY STATE should be CCA_BUSY.
1347  Simulator::Schedule (Seconds (7.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1348  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1349  Simulator::Schedule (Seconds (7.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1350  // 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.
1351  Simulator::Schedule (Seconds (7.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1352  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1353  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1354  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1355 
1356  // 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:
1357  // PHY header reception should succeed.
1358 
1359  Simulator::Schedule (Seconds (8.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1360  Simulator::Schedule (Seconds (8.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1361  // At 10 us, STA PHY STATE should be CCA_BUSY.
1362  Simulator::Schedule (Seconds (8.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1363  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1364  Simulator::Schedule (Seconds (8.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1365  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1366  Simulator::Schedule (Seconds (8.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1367  Simulator::Schedule (Seconds (8.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1368  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1369  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1370  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1371 
1372  Simulator::Run ();
1373  Simulator::Destroy ();
1374 }
1375 
1383 {
1384 public:
1385  TestAmpduReception ();
1386  virtual ~TestAmpduReception ();
1387 
1388 protected:
1389  virtual void DoSetup (void);
1390 
1391 private:
1392  virtual void DoRun (void);
1393 
1401  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1406  void RxFailure (Ptr<WifiPsdu> psdu);
1417  void IncrementSuccessBitmap (uint32_t size);
1422  void IncrementFailureBitmap (uint32_t size);
1423 
1427  void ResetBitmaps();
1428 
1434  void SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize);
1435 
1440  void CheckRxSuccessBitmapAmpdu1 (uint8_t expected);
1445  void CheckRxSuccessBitmapAmpdu2 (uint8_t expected);
1450  void CheckRxFailureBitmapAmpdu1 (uint8_t expected);
1455  void CheckRxFailureBitmapAmpdu2 (uint8_t expected);
1460  void CheckRxDroppedBitmapAmpdu1 (uint8_t expected);
1465  void CheckRxDroppedBitmapAmpdu2 (uint8_t expected);
1466 
1471  void CheckPhyState (WifiPhyState expectedState);
1472 
1474 
1477 
1480 
1483 };
1484 
1486 : TestCase ("A-MPDU reception test"),
1487  m_rxSuccessBitmapAmpdu1 (0),
1488  m_rxSuccessBitmapAmpdu2 (0),
1489  m_rxFailureBitmapAmpdu1 (0),
1490  m_rxFailureBitmapAmpdu2 (0),
1491  m_rxDroppedBitmapAmpdu1 (0),
1492  m_rxDroppedBitmapAmpdu2 (0)
1493 {
1494 }
1495 
1497 {
1498  m_phy = 0;
1499 }
1500 
1501 void
1503 {
1510 }
1511 
1512 void
1513 TestAmpduReception::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1514 {
1515  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
1516  NS_ABORT_MSG_IF (psdu->GetNMpdus () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1517  auto rxOkForMpdu = statusPerMpdu.begin ();
1518  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1519  {
1520  if (*rxOkForMpdu)
1521  {
1522  IncrementSuccessBitmap ((*mpdu)->GetSize ());
1523  }
1524  else
1525  {
1526  IncrementFailureBitmap ((*mpdu)->GetSize ());
1527  }
1528  ++rxOkForMpdu;
1529  }
1530 }
1531 
1532 void
1534 {
1535  if (size == 1030) //A-MPDU 1 - MPDU #1
1536  {
1538  }
1539  else if (size == 1130) //A-MPDU 1 - MPDU #2
1540  {
1541  m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1542  }
1543  else if (size == 1230) //A-MPDU 1 - MPDU #3
1544  {
1545  m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1546  }
1547  else if (size == 1330) //A-MPDU 2 - MPDU #1
1548  {
1550  }
1551  else if (size == 1430) //A-MPDU 2 - MPDU #2
1552  {
1553  m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1554  }
1555  else if (size == 1530) //A-MPDU 2 - MPDU #3
1556  {
1557  m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1558  }
1559 }
1560 
1561 void
1563 {
1564  NS_LOG_FUNCTION (this << *psdu);
1565  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1566  {
1567  IncrementFailureBitmap ((*mpdu)->GetSize ());
1568  }
1569 }
1570 
1571 void
1573 {
1574  if (size == 1030) //A-MPDU 1 - MPDU #1
1575  {
1577  }
1578  else if (size == 1130) //A-MPDU 1 - MPDU #2
1579  {
1580  m_rxFailureBitmapAmpdu1 |= (1 << 1);
1581  }
1582  else if (size == 1230) //A-MPDU 1 - MPDU #3
1583  {
1584  m_rxFailureBitmapAmpdu1 |= (1 << 2);
1585  }
1586  else if (size == 1330) //A-MPDU 2 - MPDU #1
1587  {
1589  }
1590  else if (size == 1430) //A-MPDU 2 - MPDU #2
1591  {
1592  m_rxFailureBitmapAmpdu2 |= (1 << 1);
1593  }
1594  else if (size == 1530) //A-MPDU 2 - MPDU #3
1595  {
1596  m_rxFailureBitmapAmpdu2 |= (1 << 2);
1597  }
1598 }
1599 
1600 void
1602 {
1603  NS_LOG_FUNCTION (this << p << reason);
1604  if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1605  {
1607  }
1608  else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1609  {
1610  m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1611  }
1612  else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1613  {
1614  m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1615  }
1616  else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1617  {
1619  }
1620  else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1621  {
1622  m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1623  }
1624  else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1625  {
1626  m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1627  }
1628 }
1629 
1630 void
1632 {
1633  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1634 }
1635 
1636 void
1638 {
1639  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1640 }
1641 
1642 void
1644 {
1645  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1646 }
1647 
1648 void
1650 {
1651  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1652 }
1653 
1654 void
1656 {
1657  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1658 }
1659 
1660 void
1662 {
1663  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1664 }
1665 
1666 void
1668 {
1669  WifiPhyState currentState;
1670  PointerValue ptr;
1671  m_phy->GetAttribute ("State", ptr);
1672  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1673  currentState = state->GetState ();
1674  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1675 }
1676 
1677 void
1678 TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1679 {
1680  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true, false);
1681 
1682  WifiMacHeader hdr;
1683  hdr.SetType (WIFI_MAC_QOSDATA);
1684  hdr.SetQosTid (0);
1685 
1686  std::vector<Ptr<WifiMacQueueItem>> mpduList;
1687  for (size_t i = 0; i < 3; ++i)
1688  {
1689  Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1690  mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1691  }
1692  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1693 
1694  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
1695 
1696  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
1697 
1698  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1699 
1700  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1701  txParams->psd = txPowerSpectrum;
1702  txParams->txPhy = 0;
1703  txParams->duration = txDuration;
1704  txParams->ppdu = ppdu;
1705 
1706  m_phy->StartRx (txParams);
1707 }
1708 
1709 void
1711 {
1712  m_phy = CreateObject<SpectrumWifiPhy> ();
1714  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1715  m_phy->SetErrorRateModel (error);
1718 
1722 
1723  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1724  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1725  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1726 
1727  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1728  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1729  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1730  m_phy->SetFrameCaptureModel (frameCaptureModel);
1731 }
1732 
1733 void
1735 {
1736  RngSeedManager::SetSeed (1);
1737  RngSeedManager::SetRun (2);
1738  int64_t streamNumber = 1;
1739  double rxPowerDbm = -30;
1740  m_phy->AssignStreams (streamNumber);
1741 
1743  // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1744  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1746 
1747  // A-MPDU 1
1748  Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1749 
1750  // A-MPDU 2
1751  Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1752 
1753  // All MPDUs of A-MPDU 1 should have been ignored.
1754  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1755  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1756  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1757 
1758  // All MPDUs of A-MPDU 2 should have been successfully received.
1759  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1760  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1761  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1762 
1763  Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1764 
1766  // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1767  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1769 
1770  // A-MPDU 1
1771  Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1772 
1773  // A-MPDU 2
1774  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1775 
1776  // All MPDUs of A-MPDU 1 should have been received.
1777  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1778  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1779  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1780 
1781  // All MPDUs of A-MPDU 2 should have been ignored.
1782  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1783  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1784  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1785 
1786  Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1787 
1789  // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1790  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1792 
1793  // A-MPDU 1
1794  Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1795 
1796  // A-MPDU 2
1797  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1798 
1799  // All MPDUs of A-MPDU 1 should have been ignored.
1800  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1801  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1802  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1803 
1804  // All MPDUs of A-MPDU 2 should have been successfully received.
1805  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1806  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1807  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1808 
1809  Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1810 
1812  // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1813  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1815 
1816  // A-MPDU 1
1817  Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1818 
1819  // A-MPDU 2
1820  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1821 
1822  // All MPDUs of A-MPDU 1 should have been received.
1823  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1824  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1825  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1826 
1827  // All MPDUs of A-MPDU 2 should have been ignored.
1828  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1829  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1830  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1831 
1832  Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1833 
1835  // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1836  // 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).
1838 
1839  // A-MPDU 1
1840  Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1841 
1842  // A-MPDU 2
1843  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1844 
1845  // All MPDUs of A-MPDU 1 should have been ignored.
1846  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1847  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1848  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1849 
1850  // All MPDUs of A-MPDU 2 should have been successfully received.
1851  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1852  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1853  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1854 
1855  Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1856 
1858  // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1859  // 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).
1861 
1862  // A-MPDU 1
1863  Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1864 
1865  // A-MPDU 2
1866  Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1867 
1868  // All MPDUs of A-MPDU 1 should have been received.
1869  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1870  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1871  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1872 
1873  // All MPDUs of A-MPDU 2 should have been ignored.
1874  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1875  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1876  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1877 
1878  Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1879 
1881  // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1882  // The second A-MPDU is received during the payload of MPDU #2.
1884 
1885  // A-MPDU 1
1886  Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1887 
1888  // A-MPDU 2
1889  Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1890 
1891  // All MPDUs of A-MPDU 1 should have been ignored.
1892  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1893  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1894  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1895 
1896  // All MPDUs of A-MPDU 2 should have been successfully received.
1897  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1898  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1899  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1900 
1901  Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1902 
1904  // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1905  // The second A-MPDU is received during the payload of MPDU #2.
1907 
1908  // A-MPDU 1
1909  Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1910 
1911  // A-MPDU 2
1912  Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1913 
1914  // All MPDUs of A-MPDU 1 should have been received.
1915  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1916  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1917  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1918 
1919  // All MPDUs of A-MPDU 2 should have been ignored.
1920  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1921  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1922  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1923 
1924  Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
1925 
1927  // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1928  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1930 
1931  // A-MPDU 1
1932  Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1933 
1934  // A-MPDU 2
1935  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
1936 
1937  // All MPDUs of A-MPDU 1 should have been dropped.
1938  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1939  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1940  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1941 
1942  // All MPDUs of A-MPDU 2 should have been received with errors.
1943  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1944  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
1945  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1946 
1947  Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
1948 
1950  // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
1951  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1953 
1954  // A-MPDU 1
1955  Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1956 
1957  // A-MPDU 2
1958  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1959 
1960  // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
1961  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1962  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1963  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1964 
1965  // All MPDUs of A-MPDU 2 should have been dropped as well.
1966  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1967  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1968  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1969 
1970  Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
1971 
1973  // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
1974  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1976 
1977  // A-MPDU 1
1978  Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
1979 
1980  // A-MPDU 2
1981  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1982 
1983  // All MPDUs of A-MPDU 1 should have been received with errors.
1984  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1985  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
1986  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1987 
1988  // All MPDUs of A-MPDU 2 should have been dropped.
1989  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1990  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1991  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1992 
1993  Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
1994 
1996  // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1997  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1999 
2000  // A-MPDU 1
2001  Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2002 
2003  // A-MPDU 2
2004  Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2005 
2006  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2007  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2008  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2009  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2010 
2011  // 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)
2012  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2013  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2014  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2015 
2016  Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
2017 
2019  // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2020  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2022 
2023  // A-MPDU 1
2024  Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2025 
2026  // A-MPDU 2
2027  Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2028 
2029  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2030  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2031  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2032  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2033 
2034  // All MPDUs of A-MPDU 2 should have been dropped as well.
2035  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2036  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2037  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2038 
2039  Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
2040 
2042  // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2043  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2045 
2046  // A-MPDU 1
2047  Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2048 
2049  // A-MPDU 2
2050  Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2051 
2052  // All MPDUs of A-MPDU 1 should have been received with errors.
2053  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2054  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2055  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2056 
2057  // All MPDUs of A-MPDU 2 should have been dropped.
2058  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2059  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2060  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2061 
2062  Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
2063 
2065  // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2066  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2068 
2069  // A-MPDU 1
2070  Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2071 
2072  // A-MPDU 2
2073  Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2074 
2075  // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
2076  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2077  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2078  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2079 
2080  // All MPDUs of A-MPDU 2 should have been successfully received
2081  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
2082  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2083  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2084 
2085  Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
2086 
2088  // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2089  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2091 
2092  // A-MPDU 1
2093  Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2094 
2095  // A-MPDU 2
2096  Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2097 
2098  // All MPDUs of A-MPDU 1 should have been successfully received.
2099  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2100  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2101  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2102 
2103  // All MPDUs of A-MPDU 2 should have been dropped.
2104  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2105  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2106  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2107 
2108  Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2109 
2111  // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2112  // 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).
2114 
2115  // A-MPDU 1
2116  Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2117 
2118  // A-MPDU 2
2119  Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2120 
2121  // All MPDUs of A-MPDU 1 should have been received with errors.
2122  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2123  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2124  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2125 
2126  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2127  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2128  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2129  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2130 
2131  Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2132 
2134  // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2135  // 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).
2137 
2138  // A-MPDU 1
2139  Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2140 
2141  // A-MPDU 2
2142  Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2143 
2144  // All MPDUs of A-MPDU 1 should have been successfully received.
2145  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2146  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2147  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2148 
2149  // All MPDUs of A-MPDU 2 should have been dropped.
2150  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2151  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2152  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2153 
2154  Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2155 
2157  // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2158  // 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).
2160 
2161  // A-MPDU 1
2162  Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2163 
2164  // A-MPDU 2
2165  Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2166 
2167  // All MPDUs of A-MPDU 1 should have been received with errors.
2168  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2169  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2170  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2171 
2172  // All MPDUs of A-MPDU 2 should have been dropped.
2173  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2174  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2175  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2176 
2177  Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2178 
2180  // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2181  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2183 
2184  // A-MPDU 1
2185  Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2186 
2187  // A-MPDU 2
2188  Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2189 
2190  // All MPDUs of A-MPDU 1 should have been received with errors.
2191  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2192  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2193  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2194 
2195  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2196  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2197  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2198  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2199 
2200  Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2201 
2203  // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2204  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2206 
2207  // A-MPDU 1
2208  Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2209 
2210  // A-MPDU 2
2211  Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2212 
2213  // All MPDUs of A-MPDU 1 should have been successfully received.
2214  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2215  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2216  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2217 
2218  // All MPDUs of A-MPDU 2 should have been dropped.
2219  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2220  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2221  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2222 
2223  Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2224 
2226  // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2227  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2229 
2230  // A-MPDU 1
2231  Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2232 
2233  // A-MPDU 2
2234  Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2235 
2236  // All MPDUs of A-MPDU 1 should have been received with errors.
2237  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2238  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2239  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2240 
2241  // All MPDUs of A-MPDU 2 should have been dropped.
2242  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2243  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2244  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2245 
2246  Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2247 
2249  // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2250  // The second A-MPDU is received during the payload of MPDU #2.
2252 
2253  // A-MPDU 1
2254  Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2255 
2256  // A-MPDU 2
2257  Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2258 
2259  // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2260  // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2261  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2262  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2263  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2264 
2265  // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2266  // 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.
2267  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2268  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2269  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2270 
2271  Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2272 
2273  Simulator::Run ();
2274  Simulator::Destroy ();
2275 }
2276 
2284 {
2285 public:
2287 };
2288 
2290  : TestSuite ("wifi-phy-reception", UNIT)
2291 {
2294  AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2295  AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2296  AddTestCase (new TestAmpduReception, TestCase::QUICK);
2297 }
2298 
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:102
#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.
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:464
#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.
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:785
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
static Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2417
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.
HE PHY for the 5 GHz band (clause 26)
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:1124
virtual void ConfigureStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
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:1086
#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:791
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)
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:771
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.
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1372
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:458
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:1062
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
Definition: wifi-phy.h:53
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:1078
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.
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:4199
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