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->GetPhyBand ());
128 
129  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
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->GetPhyBand ());
480 
481  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
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->GetPhyBand ());
985 
986  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
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->GetPhyBand ());
1189 
1190  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
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  if (statusPerMpdu.empty ()) //wait for the whole A-MPDU
1517  {
1518  return;
1519  }
1520  NS_ABORT_MSG_IF (psdu->GetNMpdus () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1521  auto rxOkForMpdu = statusPerMpdu.begin ();
1522  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1523  {
1524  if (*rxOkForMpdu)
1525  {
1526  IncrementSuccessBitmap ((*mpdu)->GetSize ());
1527  }
1528  else
1529  {
1530  IncrementFailureBitmap ((*mpdu)->GetSize ());
1531  }
1532  ++rxOkForMpdu;
1533  }
1534 }
1535 
1536 void
1538 {
1539  if (size == 1030) //A-MPDU 1 - MPDU #1
1540  {
1542  }
1543  else if (size == 1130) //A-MPDU 1 - MPDU #2
1544  {
1545  m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1546  }
1547  else if (size == 1230) //A-MPDU 1 - MPDU #3
1548  {
1549  m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1550  }
1551  else if (size == 1330) //A-MPDU 2 - MPDU #1
1552  {
1554  }
1555  else if (size == 1430) //A-MPDU 2 - MPDU #2
1556  {
1557  m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1558  }
1559  else if (size == 1530) //A-MPDU 2 - MPDU #3
1560  {
1561  m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1562  }
1563 }
1564 
1565 void
1567 {
1568  NS_LOG_FUNCTION (this << *psdu);
1569  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1570  {
1571  IncrementFailureBitmap ((*mpdu)->GetSize ());
1572  }
1573 }
1574 
1575 void
1577 {
1578  if (size == 1030) //A-MPDU 1 - MPDU #1
1579  {
1581  }
1582  else if (size == 1130) //A-MPDU 1 - MPDU #2
1583  {
1584  m_rxFailureBitmapAmpdu1 |= (1 << 1);
1585  }
1586  else if (size == 1230) //A-MPDU 1 - MPDU #3
1587  {
1588  m_rxFailureBitmapAmpdu1 |= (1 << 2);
1589  }
1590  else if (size == 1330) //A-MPDU 2 - MPDU #1
1591  {
1593  }
1594  else if (size == 1430) //A-MPDU 2 - MPDU #2
1595  {
1596  m_rxFailureBitmapAmpdu2 |= (1 << 1);
1597  }
1598  else if (size == 1530) //A-MPDU 2 - MPDU #3
1599  {
1600  m_rxFailureBitmapAmpdu2 |= (1 << 2);
1601  }
1602 }
1603 
1604 void
1606 {
1607  NS_LOG_FUNCTION (this << p << reason);
1608  if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1609  {
1611  }
1612  else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1613  {
1614  m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1615  }
1616  else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1617  {
1618  m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1619  }
1620  else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1621  {
1623  }
1624  else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1625  {
1626  m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1627  }
1628  else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1629  {
1630  m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1631  }
1632 }
1633 
1634 void
1636 {
1637  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1638 }
1639 
1640 void
1642 {
1643  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1644 }
1645 
1646 void
1648 {
1649  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1650 }
1651 
1652 void
1654 {
1655  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1656 }
1657 
1658 void
1660 {
1661  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1662 }
1663 
1664 void
1666 {
1667  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1668 }
1669 
1670 void
1672 {
1673  WifiPhyState currentState;
1674  PointerValue ptr;
1675  m_phy->GetAttribute ("State", ptr);
1676  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1677  currentState = state->GetState ();
1678  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1679 }
1680 
1681 void
1682 TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1683 {
1684  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true, false);
1685 
1686  WifiMacHeader hdr;
1687  hdr.SetType (WIFI_MAC_QOSDATA);
1688  hdr.SetQosTid (0);
1689 
1690  std::vector<Ptr<WifiMacQueueItem>> mpduList;
1691  for (size_t i = 0; i < 3; ++i)
1692  {
1693  Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1694  mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1695  }
1696  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1697 
1698  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1699 
1700  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ);
1701 
1702  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1703 
1704  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1705  txParams->psd = txPowerSpectrum;
1706  txParams->txPhy = 0;
1707  txParams->duration = txDuration;
1708  txParams->ppdu = ppdu;
1709 
1710  m_phy->StartRx (txParams);
1711 }
1712 
1713 void
1715 {
1716  m_phy = CreateObject<SpectrumWifiPhy> ();
1718  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1719  m_phy->SetErrorRateModel (error);
1722 
1726 
1727  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1728  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1729  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1730 
1731  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1732  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1733  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1734  m_phy->SetFrameCaptureModel (frameCaptureModel);
1735 }
1736 
1737 void
1739 {
1740  RngSeedManager::SetSeed (1);
1741  RngSeedManager::SetRun (2);
1742  int64_t streamNumber = 1;
1743  double rxPowerDbm = -30;
1744  m_phy->AssignStreams (streamNumber);
1745 
1747  // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1748  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1750 
1751  // A-MPDU 1
1752  Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1753 
1754  // A-MPDU 2
1755  Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1756 
1757  // All MPDUs of A-MPDU 1 should have been ignored.
1758  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1759  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1760  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1761 
1762  // All MPDUs of A-MPDU 2 should have been successfully received.
1763  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1764  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1765  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1766 
1767  Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1768 
1770  // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1771  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1773 
1774  // A-MPDU 1
1775  Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1776 
1777  // A-MPDU 2
1778  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1779 
1780  // All MPDUs of A-MPDU 1 should have been received.
1781  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1782  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1783  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1784 
1785  // All MPDUs of A-MPDU 2 should have been ignored.
1786  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1787  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1788  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1789 
1790  Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1791 
1793  // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1794  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1796 
1797  // A-MPDU 1
1798  Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1799 
1800  // A-MPDU 2
1801  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1802 
1803  // All MPDUs of A-MPDU 1 should have been ignored.
1804  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1805  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1806  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1807 
1808  // All MPDUs of A-MPDU 2 should have been successfully received.
1809  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1810  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1811  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1812 
1813  Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1814 
1816  // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1817  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1819 
1820  // A-MPDU 1
1821  Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1822 
1823  // A-MPDU 2
1824  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1825 
1826  // All MPDUs of A-MPDU 1 should have been received.
1827  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1828  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1829  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1830 
1831  // All MPDUs of A-MPDU 2 should have been ignored.
1832  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1833  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1834  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1835 
1836  Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1837 
1839  // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1840  // 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).
1842 
1843  // A-MPDU 1
1844  Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1845 
1846  // A-MPDU 2
1847  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1848 
1849  // All MPDUs of A-MPDU 1 should have been ignored.
1850  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1851  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1852  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1853 
1854  // All MPDUs of A-MPDU 2 should have been successfully received.
1855  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1856  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1857  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1858 
1859  Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1860 
1862  // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1863  // 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).
1865 
1866  // A-MPDU 1
1867  Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1868 
1869  // A-MPDU 2
1870  Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1871 
1872  // All MPDUs of A-MPDU 1 should have been received.
1873  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1874  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1875  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1876 
1877  // All MPDUs of A-MPDU 2 should have been ignored.
1878  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1879  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1880  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1881 
1882  Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1883 
1885  // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1886  // The second A-MPDU is received during the payload of MPDU #2.
1888 
1889  // A-MPDU 1
1890  Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1891 
1892  // A-MPDU 2
1893  Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1894 
1895  // All MPDUs of A-MPDU 1 should have been ignored.
1896  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1897  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1898  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1899 
1900  // All MPDUs of A-MPDU 2 should have been successfully received.
1901  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1902  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1903  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1904 
1905  Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1906 
1908  // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1909  // The second A-MPDU is received during the payload of MPDU #2.
1911 
1912  // A-MPDU 1
1913  Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1914 
1915  // A-MPDU 2
1916  Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1917 
1918  // All MPDUs of A-MPDU 1 should have been received.
1919  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1920  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1921  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1922 
1923  // All MPDUs of A-MPDU 2 should have been ignored.
1924  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1925  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1926  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1927 
1928  Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
1929 
1931  // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1932  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1934 
1935  // A-MPDU 1
1936  Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1937 
1938  // A-MPDU 2
1939  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
1940 
1941  // All MPDUs of A-MPDU 1 should have been dropped.
1942  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1943  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1944  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1945 
1946  // All MPDUs of A-MPDU 2 should have been received with errors.
1947  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1948  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
1949  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1950 
1951  Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
1952 
1954  // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
1955  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1957 
1958  // A-MPDU 1
1959  Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1960 
1961  // A-MPDU 2
1962  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1963 
1964  // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
1965  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1966  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1967  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1968 
1969  // All MPDUs of A-MPDU 2 should have been dropped as well.
1970  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1971  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1972  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1973 
1974  Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
1975 
1977  // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
1978  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1980 
1981  // A-MPDU 1
1982  Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
1983 
1984  // A-MPDU 2
1985  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1986 
1987  // All MPDUs of A-MPDU 1 should have been received with errors.
1988  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1989  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
1990  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1991 
1992  // All MPDUs of A-MPDU 2 should have been dropped.
1993  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1994  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1995  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1996 
1997  Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
1998 
2000  // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
2001  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2003 
2004  // A-MPDU 1
2005  Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2006 
2007  // A-MPDU 2
2008  Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2009 
2010  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2011  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2012  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2013  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2014 
2015  // 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)
2016  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2017  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2018  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2019 
2020  Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
2021 
2023  // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2024  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2026 
2027  // A-MPDU 1
2028  Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2029 
2030  // A-MPDU 2
2031  Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2032 
2033  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2034  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2035  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2036  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2037 
2038  // All MPDUs of A-MPDU 2 should have been dropped as well.
2039  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2040  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2041  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2042 
2043  Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
2044 
2046  // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2047  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2049 
2050  // A-MPDU 1
2051  Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2052 
2053  // A-MPDU 2
2054  Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2055 
2056  // All MPDUs of A-MPDU 1 should have been received with errors.
2057  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2058  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2059  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2060 
2061  // All MPDUs of A-MPDU 2 should have been dropped.
2062  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2063  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2064  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2065 
2066  Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
2067 
2069  // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2070  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2072 
2073  // A-MPDU 1
2074  Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2075 
2076  // A-MPDU 2
2077  Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2078 
2079  // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
2080  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2081  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2082  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2083 
2084  // All MPDUs of A-MPDU 2 should have been successfully received
2085  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
2086  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2087  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2088 
2089  Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
2090 
2092  // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2093  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2095 
2096  // A-MPDU 1
2097  Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2098 
2099  // A-MPDU 2
2100  Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2101 
2102  // All MPDUs of A-MPDU 1 should have been successfully received.
2103  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2104  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2105  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2106 
2107  // All MPDUs of A-MPDU 2 should have been dropped.
2108  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2109  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2110  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2111 
2112  Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2113 
2115  // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2116  // 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).
2118 
2119  // A-MPDU 1
2120  Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2121 
2122  // A-MPDU 2
2123  Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2124 
2125  // All MPDUs of A-MPDU 1 should have been received with errors.
2126  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2127  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2128  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2129 
2130  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2131  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2132  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2133  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2134 
2135  Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2136 
2138  // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2139  // 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).
2141 
2142  // A-MPDU 1
2143  Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2144 
2145  // A-MPDU 2
2146  Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2147 
2148  // All MPDUs of A-MPDU 1 should have been successfully received.
2149  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2150  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2151  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2152 
2153  // All MPDUs of A-MPDU 2 should have been dropped.
2154  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2155  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2156  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2157 
2158  Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2159 
2161  // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2162  // 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).
2164 
2165  // A-MPDU 1
2166  Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2167 
2168  // A-MPDU 2
2169  Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2170 
2171  // All MPDUs of A-MPDU 1 should have been received with errors.
2172  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2173  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2174  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2175 
2176  // All MPDUs of A-MPDU 2 should have been dropped.
2177  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2178  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2179  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2180 
2181  Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2182 
2184  // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2185  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2187 
2188  // A-MPDU 1
2189  Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2190 
2191  // A-MPDU 2
2192  Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2193 
2194  // All MPDUs of A-MPDU 1 should have been received with errors.
2195  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2196  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2197  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2198 
2199  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2200  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2201  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2202  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2203 
2204  Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2205 
2207  // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2208  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2210 
2211  // A-MPDU 1
2212  Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2213 
2214  // A-MPDU 2
2215  Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2216 
2217  // All MPDUs of A-MPDU 1 should have been successfully received.
2218  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2219  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2220  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2221 
2222  // All MPDUs of A-MPDU 2 should have been dropped.
2223  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2224  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2225  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2226 
2227  Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2228 
2230  // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2231  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2233 
2234  // A-MPDU 1
2235  Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2236 
2237  // A-MPDU 2
2238  Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2239 
2240  // All MPDUs of A-MPDU 1 should have been received with errors.
2241  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2242  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2243  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2244 
2245  // All MPDUs of A-MPDU 2 should have been dropped.
2246  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2247  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2248  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2249 
2250  Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2251 
2253  // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2254  // The second A-MPDU is received during the payload of MPDU #2.
2256 
2257  // A-MPDU 1
2258  Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2259 
2260  // A-MPDU 2
2261  Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2262 
2263  // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2264  // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2265  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2266  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2267  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2268 
2269  // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2270  // 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.
2271  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2272  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2273  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2274 
2275  Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2276 
2277  Simulator::Run ();
2278  Simulator::Destroy ();
2279 }
2280 
2288 {
2289 public:
2291 };
2292 
2294  : TestSuite ("wifi-phy-reception", UNIT)
2295 {
2298  AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2299  AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2300  AddTestCase (new TestAmpduReception, TestCase::QUICK);
2301 }
2302 
uint8_t m_rxSuccessBitmapAmpdu1
bitmap of successfully received MPDUs in A-MPDU #1
bool IsSingle(void) const
Return true if the PSDU is an S-MPDU.
Definition: wifi-psdu.cc:75
void CheckRxFailureBitmapAmpdu2(uint8_t expected)
Check the RX failure bitmap for A-MPDU 2.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< SpectrumWifiPhy > m_phy
Phy.
Ptr< T > Get(void) const
Definition: pointer.h:201
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
void SendPacket(double rxPowerDbm)
Send packet function.
void Expect1000BPacketDropped()
Verify whether 1000 bytes packet has been dropped.
Ptr< WifiPpdu > ppdu
The PPDU being transmitted.
static const uint32_t packetSize
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
void SendPacket(double rxPowerDbm, uint32_t packetSize)
Send packet function.
void IncrementFailureBitmap(uint32_t size)
Increment reception failure bitmap.
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1425
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:588
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
void Expect1500BPacketReceived()
Verify whether 1500 bytes packet has been received.
static WifiPhyReceptionTestSuite wifiPhyReceptionTestSuite
the test suite
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Simple frame capture model test.
The 5 GHz band.
Definition: wifi-phy-band.h:35
encapsulates test code
Definition: test.h:1153
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:797
std::vector< Ptr< WifiMacQueueItem > >::const_iterator end(void) const
Return a const iterator to past-the-last MPDU.
Definition: wifi-psdu.cc:337
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test PHY state upon success or failure of L-SIG and SIG-A.
virtual void SetChannelNumber(uint8_t id)
Set channel number.
static const uint16_t GUARD_WIDTH
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint32_t GetSize(void) const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:260
Ptr< SpectrumWifiPhy > m_phy
Phy.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
Preamble detection test w/o frame capture.
Preamble detection test w/o frame capture.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm)
Send packet function.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
static Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, WifiPhyBand band)
Definition: wifi-phy.cc:2539
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
AttributeValue implementation for Time.
Definition: nstime.h:1342
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:1302
#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:803
bool m_rxSuccess1000B
count received packets with 1000B payload
uint8_t m_rxFailureBitmapAmpdu1
bitmap of unsuccessfully received MPDUs in A-MPDU #1
The PHY layer has sense the medium busy through the CCA mechanism.
Ptr< SpectrumPhy > txPhy
The SpectrumPhy instance that is making the transmission.
static const uint32_t FREQUENCY
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void IncrementSuccessBitmap(uint32_t size)
Increment reception success bitmap.
uint8_t m_rxDroppedBitmapAmpdu2
bitmap of dropped MPDUs in A-MPDU #2
void SendAmpduWithThreeMpdus(double rxPowerDbm, uint32_t referencePacketSize)
Send A-MPDU with 3 MPDUs of different size (i-th MSDU will have 100 bytes more than (i-1)-th)...
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
virtual void SetFrequency(uint16_t freq)
virtual void ConfigureStandardAndBand(WifiPhyStandard standard, WifiPhyBand band)
Configure the PHY-level parameters for different Wi-Fi standard.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:783
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void CheckRxDroppedBitmapAmpdu2(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 2.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
A-MPDU reception test.
std::size_t GetNMpdus(void) const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:319
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void SendPacket(double rxPowerDbm)
Send packet function.
The PHY layer is IDLE.
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
WifiPhyState
The state of the PHY layer.
bool m_rxDropped1500B
count dropped packets with 1500B payload
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
void CheckRxSuccessBitmapAmpdu2(uint8_t expected)
Check the RX success bitmap for A-MPDU 2.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
uint8_t m_rxSuccessBitmapAmpdu2
bitmap of successfully received MPDUs in A-MPDU #2
uint8_t m_rxFailureBitmapAmpdu2
bitmap of unsuccessfully received MPDUs in A-MPDU #2
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:582
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:1278
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
Definition: wifi-phy.h:52
The PHY layer is receiving a packet.
bool m_rxSuccess1500B
count received packets with 1500B payload
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
void RxFailure(Ptr< WifiPsdu > psdu)
RX failure function.
Time duration
The duration of the packet transmission.
static const uint16_t CHANNEL_WIDTH
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1294
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:4526
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