A Discrete-Event Network Simulator
API
wifi-phy-reception-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2018 University of Washington
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: S├ębastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/test.h"
23 #include "ns3/double.h"
24 #include "ns3/pointer.h"
25 #include "ns3/rng-seed-manager.h"
26 #include "ns3/spectrum-wifi-helper.h"
27 #include "ns3/wifi-spectrum-value-helper.h"
28 #include "ns3/spectrum-wifi-phy.h"
29 #include "ns3/nist-error-rate-model.h"
30 #include "ns3/wifi-mac-header.h"
31 #include "ns3/ampdu-tag.h"
32 #include "ns3/wifi-spectrum-signal-parameters.h"
33 #include "ns3/wifi-utils.h"
34 #include "ns3/threshold-preamble-detection-model.h"
35 #include "ns3/simple-frame-capture-model.h"
36 #include "ns3/wifi-mac-queue-item.h"
37 #include "ns3/mpdu-aggregator.h"
38 #include "ns3/wifi-psdu.h"
39 #include "ns3/he-ppdu.h"
40 #include "ns3/he-phy.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);
65  virtual void DoTeardown (void);
67 
71  void SendPacket (double rxPowerDbm);
79  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
80  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
85  void RxFailure (Ptr<WifiPsdu> psdu);
86  uint32_t m_countRxSuccess;
87  uint32_t m_countRxFailure;
88 
89 private:
90  virtual void DoRun (void);
91 
96  void CheckPhyState (WifiPhyState expectedState);
101  void DoCheckPhyState (WifiPhyState expectedState);
107  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
108 
109  uint64_t m_uid;
110 };
111 
113  : TestCase ("Threshold preamble detection model test when no frame capture model is applied"),
114  m_countRxSuccess (0),
115  m_countRxFailure (0),
116  m_uid (0)
117 {
118 }
119 
120 void
122 {
123  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
124 
125  Ptr<Packet> pkt = Create<Packet> (1000);
126  WifiMacHeader hdr;
127 
129  hdr.SetQosTid (0);
130 
131  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
132  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
133 
134  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
135 
136  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
137 
138  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
139  txParams->psd = txPowerSpectrum;
140  txParams->txPhy = 0;
141  txParams->duration = txDuration;
142  txParams->ppdu = ppdu;
143 
144  m_phy->StartRx (txParams);
145 }
146 
147 void
149 {
150  //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
151  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithoutFrameCapture::DoCheckPhyState, this, expectedState);
152 }
153 
154 void
156 {
157  WifiPhyState currentState;
158  PointerValue ptr;
159  m_phy->GetAttribute ("State", ptr);
160  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
161  currentState = state->GetState ();
162  NS_LOG_FUNCTION (this << currentState);
163  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
164 }
165 
166 void
167 TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
168 {
169  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
170  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
171 }
172 
173 void
175  WifiTxVector txVector, std::vector<bool> statusPerMpdu)
176 {
177  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
179 }
180 
181 void
183 {
184  NS_LOG_FUNCTION (this << *psdu);
186 }
187 
189 {
190  m_phy = 0;
191 }
192 
193 void
195 {
196  m_phy = CreateObject<SpectrumWifiPhy> ();
198  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
199  m_phy->SetErrorRateModel (error);
204 
205  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
206  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
207  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
208  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
209 }
210 
211 void
213 {
214  m_phy->Dispose ();
215  m_phy = 0;
216 }
217 
218 void
220 {
221  RngSeedManager::SetSeed (1);
222  RngSeedManager::SetRun (1);
223  int64_t streamNumber = 0;
224  m_phy->AssignStreams (streamNumber);
225 
226  //RX power > CCA-ED > CCA-PD
227  double rxPowerDbm = -50;
228 
229  // CASE 1: send one packet and check PHY state:
230  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
231  // otherwise it should be IDLE.
232 
233  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
234  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
237  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
240  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
243  // Packet should have been successfully received
244  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
245 
246  // CASE 2: send two packets with same power within the 4us window and check PHY state:
247  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
248  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
249  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
250 
251  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
252  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
253  // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
256  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
259  // 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
260  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
261 
262  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
263  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
264  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
265  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
266 
267  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
268  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
269  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
272  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
275  // 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
276  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
277 
278  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
279  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
280  // but payload reception should fail (SNR too low to decode the modulation).
281 
282  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
283  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
284  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
287  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
290  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
291  // 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.
296  // In this case, the first packet should be marked as a failure
297  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
298 
299  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
300  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
301  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
302  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
303 
304  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
305  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
306  // At 6us (hence 4us after the last signal is received), no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
309  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
312  // 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
313  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
314 
315  // CCA-PD < RX power < CCA-ED
316  rxPowerDbm = -70;
317 
318  // CASE 6: send one packet and check PHY state:
319  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
320  // otherwise it should be IDLE.
321 
322  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
323  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
326  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
329  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
332  // Packet should have been successfully received
333  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
334 
335  // CASE 7: send two packets with same power within the 4us window and check PHY state:
336  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
337  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
338 
339  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
340  Simulator::Schedule (Seconds (7.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
341  // At 4us, STA PHY STATE should stay IDLE
343  // 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
344  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
345 
346  // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
347  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
348  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
349 
350  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
351  Simulator::Schedule (Seconds (8.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
352  // At 4us, STA PHY STATE should stay IDLE
354  // 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
355  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
356 
357  // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
358  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
359  // but payload reception should fail (SNR too low to decode the modulation).
360 
361  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
362  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
363  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
366  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
369  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
372  // In this case, the first packet should be marked as a failure
373  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
374 
375  // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY state:
376  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
377  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
378 
379  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
380  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
381  // At 4us, STA PHY STATE should stay IDLE
383  // 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
384  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
385 
386  // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
387  // preamble detection should succeed and PHY state should move to RX.
388 
389  rxPowerDbm = -81;
390 
391  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
392  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
395  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
398  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
401 
402  // RX power < CCA-PD < CCA-ED
403  rxPowerDbm = -83;
404 
405  //CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
406  //preamble detection should fail and PHY should be kept in IDLE state.
407 
408  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
409  // At 4us, STA PHY state should be IDLE
411 
412  Simulator::Run ();
413  Simulator::Destroy ();
414 }
415 
423 {
424 public:
427 
428 protected:
429  virtual void DoSetup (void);
430  virtual void DoTeardown (void);
432 
436  void SendPacket (double rxPowerDbm);
444  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
445  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
450  void RxFailure (Ptr<WifiPsdu> psdu);
451  uint32_t m_countRxSuccess;
452  uint32_t m_countRxFailure;
453 
454 private:
455  virtual void DoRun (void);
456 
461  void CheckPhyState (WifiPhyState expectedState);
466  void DoCheckPhyState (WifiPhyState expectedState);
472  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
473 
474  uint64_t m_uid;
475 };
476 
478 : TestCase ("Threshold preamble detection model test when simple frame capture model is applied"),
479  m_countRxSuccess (0),
480  m_countRxFailure (0),
481  m_uid (0)
482 {
483 }
484 
485 void
487 {
488  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
489 
490  Ptr<Packet> pkt = Create<Packet> (1000);
491  WifiMacHeader hdr;
492 
494  hdr.SetQosTid (0);
495 
496  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
497  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
498 
499  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
500 
501  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
502 
503  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
504  txParams->psd = txPowerSpectrum;
505  txParams->txPhy = 0;
506  txParams->duration = txDuration;
507  txParams->ppdu = ppdu;
508 
509  m_phy->StartRx (txParams);
510 }
511 
512 void
514 {
515  //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
516  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithFrameCapture::DoCheckPhyState, this, expectedState);
517 }
518 
519 void
521 {
522  WifiPhyState currentState;
523  PointerValue ptr;
524  m_phy->GetAttribute ("State", ptr);
525  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
526  currentState = state->GetState ();
527  NS_LOG_FUNCTION (this << currentState);
528  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
529 }
530 
531 void
532 TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
533 {
534  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
535  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
536 }
537 
538 void
540  WifiTxVector txVector, std::vector<bool> statusPerMpdu)
541 {
542  NS_LOG_FUNCTION (this << *psdu << txVector);
544 }
545 
546 void
548 {
549  NS_LOG_FUNCTION (this << *psdu);
551 }
552 
554 {
555  m_phy = 0;
556 }
557 
558 void
560 {
561  m_phy = CreateObject<SpectrumWifiPhy> ();
563  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
564  m_phy->SetErrorRateModel (error);
569 
570  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
571  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
572  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
573  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
574 
575  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
576  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
577  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
578  m_phy->SetFrameCaptureModel (frameCaptureModel);
579 }
580 
581 void
583 {
584  m_phy->Dispose ();
585  m_phy = 0;
586 }
587 
588 void
590 {
591  RngSeedManager::SetSeed (1);
592  RngSeedManager::SetRun (1);
593  int64_t streamNumber = 1;
594  m_phy->AssignStreams (streamNumber);
595 
596  //RX power > CCA-ED > CCA-PD
597  double rxPowerDbm = -50;
598 
599  // CASE 1: send one packet and check PHY state:
600  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
601  // otherwise it should be IDLE.
602 
603  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
604  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
607  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
610  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
613  // Packet should have been successfully received
614  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
615 
616  // CASE 2: send two packets with same power within the 4us window and check PHY state:
617  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
618  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
619  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
620 
621  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
622  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
623  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
626  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
629  // 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
630  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
631 
632  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
633  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
634  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
635  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
636 
637  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
638  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
639  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
642  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
645  // 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
646  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
647 
648  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
649  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
650  // but payload reception should fail (SNR too low to decode the modulation).
651 
652  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
653  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
654  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
657  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
660  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
661  // 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.
666  // In this case, the first packet should be marked as a failure
667  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
668 
669  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
670  // PHY preamble detection should switch because a higher packet is received within the 4us window,
671  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
672  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
673 
674  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
675  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
676  // At 4us, STA PHY STATE should stay IDLE
678  // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
681  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
684  // 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
685  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
686 
687  // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY state:
688  // PHY preamble detection should switch because a higher packet is received within the 4us window,
689  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
690  // Payload reception should fail (SNR too low to decode the modulation).
691 
692  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
693  Simulator::Schedule (Seconds (6.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
694  // At 4us, STA PHY STATE should stay IDLE
696  // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
699  // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
702  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
705  // In this case, the second packet should be marked as a failure
706  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
707 
708  // CASE 7: send two packets with same power at the exact same time and check PHY state:
709  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
710  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
711  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
712 
713  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
714  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
715  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
718  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
721  // 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
722  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
723 
724  // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY state:
725  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
726  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
727  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
728 
729  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
730  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
731  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
734  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
737  // 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
738  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
739 
740  // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY state:
741  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
742  // but payload reception should fail (SNR too low to decode the modulation).
743 
744  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
745  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
746  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
749  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
752  // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
755  // In this case, the first packet should be marked as a failure
756  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
757 
758  // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY state:
759  // PHY preamble detection should switch because a higher packet is received within the 4us window,
760  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
761  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
762 
763  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
764  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
765  // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to CCA_BUSY
768  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
771  // 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
772  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
773 
774  // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY state:
775  // PHY preamble detection should switch because a higher packet is received within the 4us window,
776  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
777  // Payload reception should fail (SNR too low to decode the modulation).
778 
779  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
780  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
781  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
784  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
787  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
790  // In this case, the second packet should be marked as a failure
791  Simulator::Schedule (Seconds (11.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 4);
792 
793  // CCA-PD < RX power < CCA-ED
794  rxPowerDbm = -70;
795 
796  // CASE 12: send one packet and check PHY state:
797  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
798  // otherwise it should be IDLE.
799 
800  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
801  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
804  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
807  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
810  // Packet should have been successfully received
811  Simulator::Schedule (Seconds (12.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
812 
813  // CASE 13: send two packets with same power within the 4us window and check PHY state:
814  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
815  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
816 
817  Simulator::Schedule (Seconds (13.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
818  Simulator::Schedule (Seconds (13.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
819  // At 4us, STA PHY STATE should stay IDLE
821  // 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
822  Simulator::Schedule (Seconds (13.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
823 
824  // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
825  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
826  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
827 
828  Simulator::Schedule (Seconds (14.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
829  Simulator::Schedule (Seconds (14.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
830  // At 4us, STA PHY STATE should stay IDLE
832  // 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
833  Simulator::Schedule (Seconds (14.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
834 
835  // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
836  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
837  // but payload reception should fail (SNR too low to decode the modulation).
838 
839  Simulator::Schedule (Seconds (15.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
840  Simulator::Schedule (Seconds (15.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
841  // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
844  // At 44us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
847  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
850  // In this case, the first packet should be marked as a failure
851  Simulator::Schedule (Seconds (15.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
852 
853  // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY state:
854  // PHY preamble detection should switch because a higher packet is received within the 4us window,
855  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB).
856  // PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
857 
858  Simulator::Schedule (Seconds (16.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
859  Simulator::Schedule (Seconds (16.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
860  // At 4us, STA PHY STATE should stay IDLE
862  // At 6us, STA PHY STATE should stay IDLE
864  // 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
865  Simulator::Schedule (Seconds (16.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
866 
867  // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY state:
868  // PHY preamble detection should switch because a higher packet is received within the 4us window,
869  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
870  // Payload reception should fail (SNR too low to decode the modulation).
871 
872  Simulator::Schedule (Seconds (17.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
873  Simulator::Schedule (Seconds (17.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
874  // At 4us, STA PHY STATE should stay IDLE
876  // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to CCA_BUSY
879  // At 46us, PHY header should be successfully received and STA PHY STATE should move from CCA_BUSY to RX
882  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
885  // In this case, the second packet should be marked as a failure
886  Simulator::Schedule (Seconds (17.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 6);
887 
888  rxPowerDbm = -50;
889  // CASE 18: send two packets with second one 50 dB higher within the 4us window
890 
891  Simulator::Schedule (Seconds (18.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
892  Simulator::Schedule (Seconds (18.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
893  // The second packet should be received successfully
894  Simulator::Schedule (Seconds (18.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 6);
895 
896  // CASE 19: send two packets with second one 10 dB higher within the 4us window
897 
898  Simulator::Schedule (Seconds (19.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
899  Simulator::Schedule (Seconds (19.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
900  // The second packet should be captured, but not decoded since SNR to low for used MCS
901  Simulator::Schedule (Seconds (19.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 7);
902 
903  // CASE 20: send two packets with second one 50 dB higher in the same time
904 
905  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
906  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
907  // The second packet should be received successfully, same as in CASE 13
908  Simulator::Schedule (Seconds (20.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 7);
909 
910  // CASE 21: send two packets with second one 10 dB higher in the same time
911 
912  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
913  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
914  // The second packet should be captured, but not decoded since SNR to low for used MCS, same as in CASE 19
915  Simulator::Schedule (Seconds (21.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 8);
916 
917  Simulator::Run ();
918  Simulator::Destroy ();
919 }
920 
928 {
929 public:
931  virtual ~TestSimpleFrameCaptureModel ();
932 
933 protected:
934  virtual void DoSetup (void);
935  virtual void DoTeardown (void);
936 
937 private:
938  virtual void DoRun (void);
939 
943  void Reset (void);
949  void SendPacket (double rxPowerDbm, uint32_t packetSize);
957  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
958  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
965 
977  void Expect1000BPacketDropped ();
981  void Expect1500BPacketDropped ();
982 
984 
989 
990  uint64_t m_uid;
991 };
992 
994 : TestCase ("Simple frame capture model test"),
995  m_rxSuccess1000B (false),
996  m_rxSuccess1500B (false),
997  m_rxDropped1000B (false),
998  m_rxDropped1500B (false),
999  m_uid (0)
1000 {
1001 }
1002 
1003 void
1005 {
1006  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
1007 
1008  Ptr<Packet> pkt = Create<Packet> (packetSize);
1009  WifiMacHeader hdr;
1010 
1011  hdr.SetType (WIFI_MAC_QOSDATA);
1012  hdr.SetQosTid (0);
1013 
1014  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1015  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1016 
1017  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1018 
1019  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1020 
1021  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1022  txParams->psd = txPowerSpectrum;
1023  txParams->txPhy = 0;
1024  txParams->duration = txDuration;
1025  txParams->ppdu = ppdu;
1026 
1027  m_phy->StartRx (txParams);
1028 }
1029 
1030 void
1032  WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1033 {
1034  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
1035  NS_ASSERT (!psdu->IsAggregate () || psdu->IsSingle ());
1036  if (psdu->GetSize () == 1030)
1037  {
1038  m_rxSuccess1000B = true;
1039  }
1040  else if (psdu->GetSize () == 1530)
1041  {
1042  m_rxSuccess1500B = true;
1043  }
1044 }
1045 
1046 void
1048 {
1049  NS_LOG_FUNCTION (this << p << reason);
1050  if (p->GetSize () == 1030)
1051  {
1052  m_rxDropped1000B = true;
1053  }
1054  else if (p->GetSize () == 1530)
1055  {
1056  m_rxDropped1500B = true;
1057  }
1058 }
1059 
1060 void
1062 {
1063  m_rxSuccess1000B = false;
1064  m_rxSuccess1500B = false;
1065  m_rxDropped1000B = false;
1066  m_rxDropped1500B = false;
1067 }
1068 
1069 void
1071 {
1072  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1000B, true, "Didn't receive 1000B packet");
1073 }
1074 
1075 void
1077 {
1078  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1500B, true, "Didn't receive 1500B packet");
1079 }
1080 void
1082 {
1083  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1000B, true, "Didn't drop 1000B packet");
1084 }
1085 
1086 void
1088 {
1089  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1500B, true, "Didn't drop 1500B packet");
1090 }
1091 
1093 {
1094  m_phy = 0;
1095 }
1096 
1097 void
1099 {
1100  m_phy = CreateObject<SpectrumWifiPhy> ();
1102  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1103  m_phy->SetErrorRateModel (error);
1106 
1109 
1110  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1111  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1112  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1113 
1114  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1115  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1116  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1117  m_phy->SetFrameCaptureModel (frameCaptureModel);
1118 }
1119 
1120 void
1122 {
1123  m_phy->Dispose ();
1124  m_phy = 0;
1125 }
1126 
1127 void
1129 {
1130  RngSeedManager::SetSeed (1);
1131  RngSeedManager::SetRun (1);
1132  int64_t streamNumber = 2;
1133  double rxPowerDbm = -30;
1134  m_phy->AssignStreams (streamNumber);
1135 
1136  // CASE 1: send two packets with same power within the capture window:
1137  // PHY should not switch reception because they have same power.
1138 
1139  Simulator::Schedule (Seconds (1.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1140  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1500);
1141  Simulator::Schedule (Seconds (1.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1142  Simulator::Schedule (Seconds (1.2), &TestSimpleFrameCaptureModel::Reset, this);
1143 
1144  // CASE 2: send two packets with second one 6 dB weaker within the capture window:
1145  // PHY should not switch reception because first one has higher power.
1146 
1147  Simulator::Schedule (Seconds (2.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1148  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm - 6, 1500);
1149  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1000BPacketReceived, this);
1150  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1151  Simulator::Schedule (Seconds (2.2), &TestSimpleFrameCaptureModel::Reset, this);
1152 
1153  // CASE 3: send two packets with second one 6 dB higher within the capture window:
1154  // PHY should switch reception because the second one has a higher power.
1155 
1156  Simulator::Schedule (Seconds (3.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1157  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1158  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1000BPacketDropped, this);
1159  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1500BPacketReceived, this);
1160  Simulator::Schedule (Seconds (3.2), &TestSimpleFrameCaptureModel::Reset, this);
1161 
1162  // CASE 4: send two packets with second one 6 dB higher after the capture window:
1163  // PHY should not switch reception because capture window duration has elapsed when the second packet arrives.
1164 
1165  Simulator::Schedule (Seconds (4.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1166  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1167  Simulator::Schedule (Seconds (4.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1168  Simulator::Schedule (Seconds (4.2), &TestSimpleFrameCaptureModel::Reset, this);
1169 
1170  Simulator::Run ();
1171  Simulator::Destroy ();
1172 }
1173 
1181 {
1182 public:
1184  virtual ~TestPhyHeadersReception ();
1185 
1186 protected:
1187  virtual void DoSetup (void);
1188  virtual void DoTeardown (void);
1190 
1194  void SendPacket (double rxPowerDbm);
1195 
1196 private:
1197  virtual void DoRun (void);
1198 
1203  void CheckPhyState (WifiPhyState expectedState);
1208  void DoCheckPhyState (WifiPhyState expectedState);
1209 
1210  uint64_t m_uid;
1211 };
1212 
1214 : TestCase ("PHY headers reception test"),
1215  m_uid (0)
1216 {
1217 }
1218 
1219 void
1221 {
1222  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
1223 
1224  Ptr<Packet> pkt = Create<Packet> (1000);
1225  WifiMacHeader hdr;
1226 
1227  hdr.SetType (WIFI_MAC_QOSDATA);
1228  hdr.SetQosTid (0);
1229 
1230  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1231  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1232 
1233  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1234 
1235  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1236 
1237  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1238  txParams->psd = txPowerSpectrum;
1239  txParams->txPhy = 0;
1240  txParams->duration = txDuration;
1241  txParams->ppdu = ppdu;
1242 
1243  m_phy->StartRx (txParams);
1244 }
1245 
1246 void
1248 {
1249  //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
1250  Simulator::ScheduleNow (&TestPhyHeadersReception::DoCheckPhyState, this, expectedState);
1251 }
1252 
1253 void
1255 {
1256  WifiPhyState currentState;
1257  PointerValue ptr;
1258  m_phy->GetAttribute ("State", ptr);
1259  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1260  currentState = state->GetState ();
1261  NS_LOG_FUNCTION (this << currentState);
1262  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1263 }
1264 
1265 
1267 {
1268  m_phy = 0;
1269 }
1270 
1271 void
1273 {
1274  m_phy = CreateObject<SpectrumWifiPhy> ();
1276  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1277  m_phy->SetErrorRateModel (error);
1280 }
1281 
1282 void
1284 {
1285  m_phy->Dispose ();
1286  m_phy = 0;
1287 }
1288 
1289 void
1291 {
1292  RngSeedManager::SetSeed (1);
1293  RngSeedManager::SetRun (1);
1294  int64_t streamNumber = 0;
1295  m_phy->AssignStreams (streamNumber);
1296 
1297  // RX power > CCA-ED
1298  double rxPowerDbm = -50;
1299 
1300  // CASE 1: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1301  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1302 
1303  Simulator::Schedule (Seconds (1.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1304  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1305  // At 10 us, STA PHY STATE should be CCA_BUSY.
1306  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1307  // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to CCA_BUSY.
1308  Simulator::Schedule (Seconds (1.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1309  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10 = 162.8us.
1310  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1311  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1312 
1313  // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1314  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1315 
1316  Simulator::Schedule (Seconds (2.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1317  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1318  // At 10 us, STA PHY STATE should be CCA_BUSY.
1319  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1320  // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception should have succeeded.
1321  Simulator::Schedule (Seconds (2.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1322  Simulator::Schedule (Seconds (2.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1323  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1324  // 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.
1325  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1326  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1327  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1328  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1329 
1330  // 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:
1331  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1332 
1333  Simulator::Schedule (Seconds (3.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1334  Simulator::Schedule (Seconds (3.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1335  // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be kept to CCA_BUSY.
1336  Simulator::Schedule (Seconds (3.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1337  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1338  // 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.
1339  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1340  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1341  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1342  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1343 
1344  // 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:
1345  // PHY header reception should succeed.
1346 
1347  Simulator::Schedule (Seconds (4.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1348  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1349  // At 10 us, STA PHY STATE should be CCA_BUSY.
1350  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1351  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1352  Simulator::Schedule (Seconds (4.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1353  Simulator::Schedule (Seconds (4.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1354  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1355  // 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.
1356  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1357  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1358  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1359  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1360 
1361  // RX power < CCA-ED
1362  rxPowerDbm = -70;
1363 
1364  // CASE 5: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1365  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1366 
1367  Simulator::Schedule (Seconds (5.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1368  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1369  // At 10 us, STA PHY STATE should be CCA_BUSY.
1370  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1371  // 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.
1372  Simulator::Schedule (Seconds (5.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1373  Simulator::Schedule (Seconds (5.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1374 
1375  // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1376  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1377 
1378  Simulator::Schedule (Seconds (6.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1379  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1380  // At 10 us, STA PHY STATE should be CCA_BUSY.
1381  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1382  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1383  Simulator::Schedule (Seconds (6.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1384  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1385  Simulator::Schedule (Seconds (6.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1386  Simulator::Schedule (Seconds (6.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1387  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1388  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1389  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1390 
1391  // 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:
1392  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1393 
1394  Simulator::Schedule (Seconds (7.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1395  Simulator::Schedule (Seconds (7.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1396  // At 10 us, STA PHY STATE should be CCA_BUSY.
1397  Simulator::Schedule (Seconds (7.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1398  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1399  Simulator::Schedule (Seconds (7.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1400  // 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.
1401  Simulator::Schedule (Seconds (7.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1402  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1403  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1404  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1405 
1406  // 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:
1407  // PHY header reception should succeed.
1408 
1409  Simulator::Schedule (Seconds (8.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1410  Simulator::Schedule (Seconds (8.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1411  // At 10 us, STA PHY STATE should be CCA_BUSY.
1412  Simulator::Schedule (Seconds (8.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1413  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1414  Simulator::Schedule (Seconds (8.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1415  // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception should have succeeded.
1416  Simulator::Schedule (Seconds (8.0) + NanoSeconds (43999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1417  Simulator::Schedule (Seconds (8.0) + NanoSeconds (44000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1418  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1419  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1420  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1421 
1422  Simulator::Run ();
1423  Simulator::Destroy ();
1424 }
1425 
1433 {
1434 public:
1435  TestAmpduReception ();
1436  virtual ~TestAmpduReception ();
1437 
1438 protected:
1439  virtual void DoSetup (void);
1440  virtual void DoTeardown (void);
1441 
1442 private:
1443  virtual void DoRun (void);
1444 
1452  void RxSuccess (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
1453  WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1458  void RxFailure (Ptr<WifiPsdu> psdu);
1469  void IncrementSuccessBitmap (uint32_t size);
1474  void IncrementFailureBitmap (uint32_t size);
1475 
1479  void ResetBitmaps();
1480 
1486  void SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize);
1487 
1492  void CheckRxSuccessBitmapAmpdu1 (uint8_t expected);
1497  void CheckRxSuccessBitmapAmpdu2 (uint8_t expected);
1502  void CheckRxFailureBitmapAmpdu1 (uint8_t expected);
1507  void CheckRxFailureBitmapAmpdu2 (uint8_t expected);
1512  void CheckRxDroppedBitmapAmpdu1 (uint8_t expected);
1517  void CheckRxDroppedBitmapAmpdu2 (uint8_t expected);
1518 
1523  void CheckPhyState (WifiPhyState expectedState);
1524 
1526 
1529 
1532 
1535 
1536  uint64_t m_uid;
1537 };
1538 
1540 : TestCase ("A-MPDU reception test"),
1541  m_rxSuccessBitmapAmpdu1 (0),
1542  m_rxSuccessBitmapAmpdu2 (0),
1543  m_rxFailureBitmapAmpdu1 (0),
1544  m_rxFailureBitmapAmpdu2 (0),
1545  m_rxDroppedBitmapAmpdu1 (0),
1546  m_rxDroppedBitmapAmpdu2 (0),
1547  m_uid (0)
1548 {
1549 }
1550 
1552 {
1553  m_phy = 0;
1554 }
1555 
1556 void
1558 {
1565 }
1566 
1567 void
1569  WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1570 {
1571  NS_LOG_FUNCTION (this << *psdu << rxSignalInfo << txVector);
1572  if (statusPerMpdu.empty ()) //wait for the whole A-MPDU
1573  {
1574  return;
1575  }
1576  NS_ABORT_MSG_IF (psdu->GetNMpdus () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1577  auto rxOkForMpdu = statusPerMpdu.begin ();
1578  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1579  {
1580  if (*rxOkForMpdu)
1581  {
1582  IncrementSuccessBitmap ((*mpdu)->GetSize ());
1583  }
1584  else
1585  {
1586  IncrementFailureBitmap ((*mpdu)->GetSize ());
1587  }
1588  ++rxOkForMpdu;
1589  }
1590 }
1591 
1592 void
1594 {
1595  if (size == 1030) //A-MPDU 1 - MPDU #1
1596  {
1598  }
1599  else if (size == 1130) //A-MPDU 1 - MPDU #2
1600  {
1601  m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1602  }
1603  else if (size == 1230) //A-MPDU 1 - MPDU #3
1604  {
1605  m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1606  }
1607  else if (size == 1330) //A-MPDU 2 - MPDU #1
1608  {
1610  }
1611  else if (size == 1430) //A-MPDU 2 - MPDU #2
1612  {
1613  m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1614  }
1615  else if (size == 1530) //A-MPDU 2 - MPDU #3
1616  {
1617  m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1618  }
1619 }
1620 
1621 void
1623 {
1624  NS_LOG_FUNCTION (this << *psdu);
1625  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1626  {
1627  IncrementFailureBitmap ((*mpdu)->GetSize ());
1628  }
1629 }
1630 
1631 void
1633 {
1634  if (size == 1030) //A-MPDU 1 - MPDU #1
1635  {
1637  }
1638  else if (size == 1130) //A-MPDU 1 - MPDU #2
1639  {
1640  m_rxFailureBitmapAmpdu1 |= (1 << 1);
1641  }
1642  else if (size == 1230) //A-MPDU 1 - MPDU #3
1643  {
1644  m_rxFailureBitmapAmpdu1 |= (1 << 2);
1645  }
1646  else if (size == 1330) //A-MPDU 2 - MPDU #1
1647  {
1649  }
1650  else if (size == 1430) //A-MPDU 2 - MPDU #2
1651  {
1652  m_rxFailureBitmapAmpdu2 |= (1 << 1);
1653  }
1654  else if (size == 1530) //A-MPDU 2 - MPDU #3
1655  {
1656  m_rxFailureBitmapAmpdu2 |= (1 << 2);
1657  }
1658 }
1659 
1660 void
1662 {
1663  NS_LOG_FUNCTION (this << p << reason);
1664  if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1665  {
1667  }
1668  else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1669  {
1670  m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1671  }
1672  else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1673  {
1674  m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1675  }
1676  else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1677  {
1679  }
1680  else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1681  {
1682  m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1683  }
1684  else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1685  {
1686  m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1687  }
1688 }
1689 
1690 void
1692 {
1693  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1694 }
1695 
1696 void
1698 {
1699  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1700 }
1701 
1702 void
1704 {
1705  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1706 }
1707 
1708 void
1710 {
1711  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1712 }
1713 
1714 void
1716 {
1717  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1718 }
1719 
1720 void
1722 {
1723  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1724 }
1725 
1726 void
1728 {
1729  WifiPhyState currentState;
1730  PointerValue ptr;
1731  m_phy->GetAttribute ("State", ptr);
1732  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1733  currentState = state->GetState ();
1734  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1735 }
1736 
1737 void
1738 TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1739 {
1740  WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true);
1741 
1742  WifiMacHeader hdr;
1743  hdr.SetType (WIFI_MAC_QOSDATA);
1744  hdr.SetQosTid (0);
1745 
1746  std::vector<Ptr<WifiMacQueueItem>> mpduList;
1747  for (size_t i = 0; i < 3; ++i)
1748  {
1749  Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1750  mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1751  }
1752  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1753 
1754  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand ());
1755 
1756  Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdu, txVector, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1757 
1758  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1759 
1760  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1761  txParams->psd = txPowerSpectrum;
1762  txParams->txPhy = 0;
1763  txParams->duration = txDuration;
1764  txParams->ppdu = ppdu;
1765 
1766  m_phy->StartRx (txParams);
1767 }
1768 
1769 void
1771 {
1772  m_phy = CreateObject<SpectrumWifiPhy> ();
1774  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1775  m_phy->SetErrorRateModel (error);
1778 
1782 
1783  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1784  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1785  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1786 
1787  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1788  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1789  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1790  m_phy->SetFrameCaptureModel (frameCaptureModel);
1791 }
1792 
1793 void
1795 {
1796  m_phy->Dispose ();
1797  m_phy = 0;
1798 }
1799 
1800 void
1802 {
1803  RngSeedManager::SetSeed (1);
1804  RngSeedManager::SetRun (2);
1805  int64_t streamNumber = 1;
1806  double rxPowerDbm = -30;
1807  m_phy->AssignStreams (streamNumber);
1808 
1810  // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1811  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1813 
1814  // A-MPDU 1
1815  Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1816 
1817  // A-MPDU 2
1818  Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1819 
1820  // All MPDUs of A-MPDU 1 should have been ignored.
1821  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1822  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1823  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1824 
1825  // All MPDUs of A-MPDU 2 should have been successfully received.
1826  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1827  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1828  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1829 
1830  Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1831 
1833  // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1834  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1836 
1837  // A-MPDU 1
1838  Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1839 
1840  // A-MPDU 2
1841  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1842 
1843  // All MPDUs of A-MPDU 1 should have been received.
1844  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1845  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1846  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1847 
1848  // All MPDUs of A-MPDU 2 should have been ignored.
1849  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1850  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1851  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1852 
1853  Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1854 
1856  // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1857  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1859 
1860  // A-MPDU 1
1861  Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1862 
1863  // A-MPDU 2
1864  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1865 
1866  // All MPDUs of A-MPDU 1 should have been ignored.
1867  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1868  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1869  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1870 
1871  // All MPDUs of A-MPDU 2 should have been successfully received.
1872  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1873  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1874  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1875 
1876  Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1877 
1879  // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1880  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1882 
1883  // A-MPDU 1
1884  Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1885 
1886  // A-MPDU 2
1887  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1888 
1889  // All MPDUs of A-MPDU 1 should have been received.
1890  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1891  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1892  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1893 
1894  // All MPDUs of A-MPDU 2 should have been ignored.
1895  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1896  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1897  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1898 
1899  Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1900 
1902  // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1903  // 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).
1905 
1906  // A-MPDU 1
1907  Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1908 
1909  // A-MPDU 2
1910  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1911 
1912  // All MPDUs of A-MPDU 1 should have been ignored.
1913  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1914  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1915  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1916 
1917  // All MPDUs of A-MPDU 2 should have been successfully received.
1918  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1919  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1920  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1921 
1922  Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1923 
1925  // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1926  // 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).
1928 
1929  // A-MPDU 1
1930  Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1931 
1932  // A-MPDU 2
1933  Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1934 
1935  // All MPDUs of A-MPDU 1 should have been received.
1936  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1937  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1938  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1939 
1940  // All MPDUs of A-MPDU 2 should have been ignored.
1941  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1942  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1943  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1944 
1945  Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1946 
1948  // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1949  // The second A-MPDU is received during the payload of MPDU #2.
1951 
1952  // A-MPDU 1
1953  Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1954 
1955  // A-MPDU 2
1956  Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1957 
1958  // All MPDUs of A-MPDU 1 should have been ignored.
1959  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1960  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1961  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1962 
1963  // All MPDUs of A-MPDU 2 should have been successfully received.
1964  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1965  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1966  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1967 
1968  Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1969 
1971  // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1972  // The second A-MPDU is received during the payload of MPDU #2.
1974 
1975  // A-MPDU 1
1976  Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1977 
1978  // A-MPDU 2
1979  Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1980 
1981  // All MPDUs of A-MPDU 1 should have been received.
1982  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1983  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1984  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1985 
1986  // All MPDUs of A-MPDU 2 should have been ignored.
1987  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1988  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1989  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1990 
1991  Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
1992 
1994  // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1995  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1997 
1998  // A-MPDU 1
1999  Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2000 
2001  // A-MPDU 2
2002  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2003 
2004  // All MPDUs of A-MPDU 1 should have been dropped.
2005  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2006  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2007  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2008 
2009  // All MPDUs of A-MPDU 2 should have been received with errors.
2010  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2011  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
2012  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2013 
2014  Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
2015 
2017  // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2018  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
2020 
2021  // A-MPDU 1
2022  Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2023 
2024  // A-MPDU 2
2025  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2026 
2027  // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
2028  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2029  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2030  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2031 
2032  // All MPDUs of A-MPDU 2 should have been dropped as well.
2033  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2034  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2035  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2036 
2037  Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
2038 
2040  // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2041  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
2043 
2044  // A-MPDU 1
2045  Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2046 
2047  // A-MPDU 2
2048  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2049 
2050  // All MPDUs of A-MPDU 1 should have been received with errors.
2051  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2052  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2053  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2054 
2055  // All MPDUs of A-MPDU 2 should have been dropped.
2056  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2057  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2058  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2059 
2060  Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
2061 
2063  // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
2064  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2066 
2067  // A-MPDU 1
2068  Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2069 
2070  // A-MPDU 2
2071  Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2072 
2073  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2074  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2075  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2076  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2077 
2078  // 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)
2079  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2080  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2081  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2082 
2083  Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
2084 
2086  // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2087  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2089 
2090  // A-MPDU 1
2091  Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2092 
2093  // A-MPDU 2
2094  Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2095 
2096  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2097  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2098  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2099  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2100 
2101  // All MPDUs of A-MPDU 2 should have been dropped as well.
2102  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2103  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2104  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2105 
2106  Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
2107 
2109  // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2110  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2112 
2113  // A-MPDU 1
2114  Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2115 
2116  // A-MPDU 2
2117  Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2118 
2119  // All MPDUs of A-MPDU 1 should have been received with errors.
2120  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2121  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2122  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2123 
2124  // All MPDUs of A-MPDU 2 should have been dropped.
2125  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2126  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2127  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2128 
2129  Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
2130 
2132  // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2133  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2135 
2136  // A-MPDU 1
2137  Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2138 
2139  // A-MPDU 2
2140  Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2141 
2142  // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
2143  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2144  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2145  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2146 
2147  // All MPDUs of A-MPDU 2 should have been successfully received
2148  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
2149  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2150  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2151 
2152  Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
2153 
2155  // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2156  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2158 
2159  // A-MPDU 1
2160  Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2161 
2162  // A-MPDU 2
2163  Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2164 
2165  // All MPDUs of A-MPDU 1 should have been successfully received.
2166  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2167  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2168  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2169 
2170  // All MPDUs of A-MPDU 2 should have been dropped.
2171  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2172  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2173  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2174 
2175  Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2176 
2178  // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2179  // 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).
2181 
2182  // A-MPDU 1
2183  Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2184 
2185  // A-MPDU 2
2186  Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2187 
2188  // All MPDUs of A-MPDU 1 should have been received with errors.
2189  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2190  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2191  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2192 
2193  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2194  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2195  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2196  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2197 
2198  Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2199 
2201  // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2202  // 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).
2204 
2205  // A-MPDU 1
2206  Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2207 
2208  // A-MPDU 2
2209  Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2210 
2211  // All MPDUs of A-MPDU 1 should have been successfully received.
2212  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2213  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2214  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2215 
2216  // All MPDUs of A-MPDU 2 should have been dropped.
2217  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2218  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2219  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2220 
2221  Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2222 
2224  // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2225  // 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).
2227 
2228  // A-MPDU 1
2229  Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2230 
2231  // A-MPDU 2
2232  Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2233 
2234  // All MPDUs of A-MPDU 1 should have been received with errors.
2235  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2236  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2237  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2238 
2239  // All MPDUs of A-MPDU 2 should have been dropped.
2240  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2241  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2242  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2243 
2244  Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2245 
2247  // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2248  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2250 
2251  // A-MPDU 1
2252  Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2253 
2254  // A-MPDU 2
2255  Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2256 
2257  // All MPDUs of A-MPDU 1 should have been received with errors.
2258  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2259  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2260  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2261 
2262  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2263  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2264  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2265  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2266 
2267  Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2268 
2270  // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2271  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2273 
2274  // A-MPDU 1
2275  Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2276 
2277  // A-MPDU 2
2278  Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2279 
2280  // All MPDUs of A-MPDU 1 should have been successfully received.
2281  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2282  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2283  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2284 
2285  // All MPDUs of A-MPDU 2 should have been dropped.
2286  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2287  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2288  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2289 
2290  Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2291 
2293  // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2294  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2296 
2297  // A-MPDU 1
2298  Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2299 
2300  // A-MPDU 2
2301  Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2302 
2303  // All MPDUs of A-MPDU 1 should have been received with errors.
2304  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2305  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2306  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2307 
2308  // All MPDUs of A-MPDU 2 should have been dropped.
2309  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2310  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2311  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2312 
2313  Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2314 
2316  // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2317  // The second A-MPDU is received during the payload of MPDU #2.
2319 
2320  // A-MPDU 1
2321  Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2322 
2323  // A-MPDU 2
2324  Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2325 
2326  // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2327  // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2328  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2329  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2330  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2331 
2332  // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2333  // 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.
2334  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2335  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2336  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2337 
2338  Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2339 
2340  Simulator::Run ();
2341  Simulator::Destroy ();
2342 }
2343 
2351 {
2352 public:
2354 };
2355 
2357  : TestSuite ("wifi-phy-reception", UNIT)
2358 {
2361  AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2362  AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2363  AddTestCase (new TestAmpduReception, TestCase::QUICK);
2364 }
2365 
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
uint8_t m_rxSuccessBitmapAmpdu1
bitmap of successfully received MPDUs in A-MPDU #1
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
RX success function.
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.
virtual void DoTeardown(void)
Implementation to do any local setup required for 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.
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
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:1122
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 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 SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:639
#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
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
#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:37
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:820
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.
static const uint16_t GUARD_WIDTH
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
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1614
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.
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:66
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm)
Send packet function.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
AttributeValue implementation for Time.
Definition: nstime.h:1353
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
void Expect1000BPacketReceived()
Verify whether 1000 bytes packet has been received.
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:826
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.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:806
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.
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
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.
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
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:633
This objects implements the PHY state machine of the Wifi device.
WifiPhyState GetState(void) const
Return the current state of WifiPhy.
virtual void SetFrequency(uint16_t freq) override
If the operating channel for this object has not been set yet, the given center frequency is saved an...
#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.
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
The PHY layer is receiving a packet.
virtual void SetChannelNumber(uint8_t id) override
Set channel number.
bool m_rxSuccess1500B
count received packets with 1500B payload
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
void RxFailure(Ptr< WifiPsdu > psdu)
RX failure function.
Time duration
The duration of the packet transmission.
static const uint16_t CHANNEL_WIDTH
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void Expect1500BPacketDropped()
Verify whether 1500 bytes packet has been dropped.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
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 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.
virtual void ConfigureStandardAndBand(WifiPhyStandard standard, WifiPhyBand band) override
Configure the PHY-level parameters for different Wi-Fi standard.
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
void RxSuccess(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
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:2292
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