A Discrete-Event Network Simulator
API
wifi-phy-reception-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2018 University of Washington
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: S├ębastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/test.h"
23 #include "ns3/double.h"
24 #include "ns3/pointer.h"
25 #include "ns3/rng-seed-manager.h"
26 #include "ns3/spectrum-wifi-helper.h"
27 #include "ns3/wifi-spectrum-value-helper.h"
28 #include "ns3/spectrum-wifi-phy.h"
29 #include "ns3/nist-error-rate-model.h"
30 #include "ns3/wifi-mac-header.h"
31 #include "ns3/ampdu-tag.h"
32 #include "ns3/wifi-spectrum-signal-parameters.h"
33 #include "ns3/wifi-utils.h"
34 #include "ns3/threshold-preamble-detection-model.h"
35 #include "ns3/simple-frame-capture-model.h"
36 #include "ns3/wifi-psdu.h"
37 #include "ns3/wifi-mac-queue-item.h"
38 #include "ns3/mpdu-aggregator.h"
39 #include "ns3/wifi-psdu.h"
40 #include "ns3/wifi-ppdu.h"
41 
42 using namespace ns3;
43 
44 NS_LOG_COMPONENT_DEFINE ("WifiPhyReceptionTest");
45 
46 static const uint8_t CHANNEL_NUMBER = 36;
47 static const uint32_t FREQUENCY = 5180; // MHz
48 static const uint16_t CHANNEL_WIDTH = 20; // MHz
49 static const uint16_t GUARD_WIDTH = CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
50 
58 {
59 public:
62 
63 protected:
64  virtual void DoSetup (void);
66 
70  void SendPacket (double rxPowerDbm);
78  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
83  void RxFailure (Ptr<WifiPsdu> psdu);
84  uint32_t m_countRxSuccess;
85  uint32_t m_countRxFailure;
86 
87 private:
88  virtual void DoRun (void);
89 
94  void CheckPhyState (WifiPhyState expectedState);
99  void DoCheckPhyState (WifiPhyState expectedState);
105  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
106 };
107 
109  : TestCase ("Threshold preamble detection model test when no frame capture model is applied"),
110  m_countRxSuccess (0),
111  m_countRxFailure (0)
112 {
113 }
114 
115 void
117 {
118  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
119 
120  Ptr<Packet> pkt = Create<Packet> (1000);
121  WifiMacHeader hdr;
122 
124  hdr.SetQosTid (0);
125 
126  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
127  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
128 
129  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
130 
131  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
132 
133  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
134  txParams->psd = txPowerSpectrum;
135  txParams->txPhy = 0;
136  txParams->duration = txDuration;
137  txParams->ppdu = ppdu;
138 
139  m_phy->StartRx (txParams);
140 }
141 
142 void
144 {
145  //This is needed to make sure PHY state will be checked as the last event if a state change occured at the exact same time as the check
146  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithoutFrameCapture::DoCheckPhyState, this, expectedState);
147 }
148 
149 void
151 {
152  WifiPhyState currentState;
153  PointerValue ptr;
154  m_phy->GetAttribute ("State", ptr);
155  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
156  currentState = state->GetState ();
157  NS_LOG_FUNCTION (this << currentState);
158  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
159 }
160 
161 void
162 TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
163 {
164  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
165  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
166 }
167 
168 void
169 TestThresholdPreambleDetectionWithoutFrameCapture::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
170 {
171  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
173 }
174 
175 void
177 {
178  NS_LOG_FUNCTION (this << *psdu);
180 }
181 
183 {
184  m_phy = 0;
185 }
186 
187 void
189 {
190  m_phy = CreateObject<SpectrumWifiPhy> ();
192  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
193  m_phy->SetErrorRateModel (error);
198 
199  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
200  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
201  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
202  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
203 }
204 
205 void
207 {
208  RngSeedManager::SetSeed (1);
209  RngSeedManager::SetRun (1);
210  int64_t streamNumber = 0;
211  m_phy->AssignStreams (streamNumber);
212 
213  //RX power > CCA-ED > CCA-PD
214  double rxPowerDbm = -50;
215 
216  // CASE 1: send one packet and check PHY state:
217  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
218  // otherwise it should be IDLE.
219 
220  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
221  // At 4us, STA PHY STATE should move from IDLE to RX
224  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
227  // Packet should have been successfully received
228  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
229 
230  // CASE 2: send two packets with same power within the 4us window and check PHY state:
231  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
232  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
233  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
234 
235  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
236  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
237  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
240  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
243  // 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
244  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
245 
246  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
247  // PHY preamble detection should fail because SNR is too low (around 3 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 (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
252  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
253  // At 4us, 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 (3.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
261 
262  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
263  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
264  // but payload reception should fail (SNR too low to decode the modulation).
265 
266  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
267  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
268  // At 4us, STA PHY STATE should move from IDLE to RX
271  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
272  // 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.
277  // In this case, the first packet should be marked as a failure
278  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
279 
280  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
281  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
282  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
283  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
284 
285  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
286  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
287  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
290  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
293  // 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
294  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
295 
296  // CCA-PD < RX power < CCA-ED
297  rxPowerDbm = -70;
298 
299  // CASE 6: send one packet and check PHY state:
300  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
301  // otherwise it should be IDLE.
302 
303  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
304  // At 4us, STA PHY STATE should move from IDLE to RX
307  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
310  // Packet should have been successfully received
311  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
312 
313  // CASE 7: send two packets with same power within the 4us window and check PHY state:
314  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
315  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
316 
317  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
318  Simulator::Schedule (Seconds (7.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
319  // At 4us, STA PHY STATE should stay in IDLE
321  // 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
322  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
323 
324  // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
325  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
326  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
327 
328  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
329  Simulator::Schedule (Seconds (8.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
330  // At 4us, STA PHY STATE should stay in IDLE
332  // 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
333  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
334 
335  // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
336  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
337  // but payload reception should fail (SNR too low to decode the modulation).
338 
339  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
340  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
341  // At 4us, STA PHY STATE should move from IDLE to RX
344  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
347  // In this case, the first packet should be marked as a failure
348  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
349 
350  // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY state:
351  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
352  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
353 
354  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
355  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
356  // At 4us, STA PHY STATE should stay in IDLE
358  // 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
359  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
360 
361  // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
362  // preamble detection should succeed and PHY state should move to RX.
363 
364  rxPowerDbm = -81;
365 
366  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
367  // At 4us, STA PHY STATE should move from IDLE to RX
370  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
373 
374  // RX power < CCA-PD < CCA-ED
375  rxPowerDbm = -83;
376 
377  //CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
378  //preamble detection should fail and PHY should be kept in IDLE state.
379 
380  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
381  // At 4us, STA PHY state should be IDLE
383 
384  Simulator::Run ();
385  Simulator::Destroy ();
386 }
387 
395 {
396 public:
399 
400 protected:
401  virtual void DoSetup (void);
403 
407  void SendPacket (double rxPowerDbm);
415  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
420  void RxFailure (Ptr<WifiPsdu> psdu);
421  uint32_t m_countRxSuccess;
422  uint32_t m_countRxFailure;
423 
424 private:
425  virtual void DoRun (void);
426 
431  void CheckPhyState (WifiPhyState expectedState);
436  void DoCheckPhyState (WifiPhyState expectedState);
442  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
443 };
444 
446 : TestCase ("Threshold preamble detection model test when simple frame capture model is applied"),
447 m_countRxSuccess (0),
448 m_countRxFailure (0)
449 {
450 }
451 
452 void
454 {
455  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
456 
457  Ptr<Packet> pkt = Create<Packet> (1000);
458  WifiMacHeader hdr;
459 
461  hdr.SetQosTid (0);
462 
463  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
464  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
465 
466  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
467 
468  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
469 
470  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
471  txParams->psd = txPowerSpectrum;
472  txParams->txPhy = 0;
473  txParams->duration = txDuration;
474  txParams->ppdu = ppdu;
475 
476  m_phy->StartRx (txParams);
477 }
478 
479 void
481 {
482  //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
483  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithFrameCapture::DoCheckPhyState, this, expectedState);
484 }
485 
486 void
488 {
489  WifiPhyState currentState;
490  PointerValue ptr;
491  m_phy->GetAttribute ("State", ptr);
492  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
493  currentState = state->GetState ();
494  NS_LOG_FUNCTION (this << currentState);
495  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
496 }
497 
498 void
499 TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
500 {
501  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
502  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
503 }
504 
505 void
506 TestThresholdPreambleDetectionWithFrameCapture::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
507 {
508  NS_LOG_FUNCTION (this << *psdu << txVector);
510 }
511 
512 void
514 {
515  NS_LOG_FUNCTION (this << *psdu);
517 }
518 
520 {
521  m_phy = 0;
522 }
523 
524 void
526 {
527  m_phy = CreateObject<SpectrumWifiPhy> ();
529  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
530  m_phy->SetErrorRateModel (error);
535 
536  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
537  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
538  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
539  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
540 
541  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
542  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
543  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
544  m_phy->SetFrameCaptureModel (frameCaptureModel);
545 }
546 
547 void
549 {
550  RngSeedManager::SetSeed (1);
551  RngSeedManager::SetRun (1);
552  int64_t streamNumber = 1;
553  m_phy->AssignStreams (streamNumber);
554 
555  //RX power > CCA-ED > CCA-PD
556  double rxPowerDbm = -50;
557 
558  // CASE 1: send one packet and check PHY state:
559  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
560  // otherwise it should be IDLE.
561 
562  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
563  // At 4us, STA PHY STATE should move from IDLE to RX
566  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
569  // Packet should have been successfully received
570  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
571 
572  // CASE 2: send two packets with same power within the 4us window and check PHY state:
573  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
574  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
575  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
576 
577  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
578  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
579  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
582  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
585  // 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
586  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
587 
588  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
589  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
590  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
591  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
592 
593  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
594  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
595  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
598  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
601  // 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
602  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
603 
604  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
605  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
606  // but payload reception should fail (SNR too low to decode the modulation).
607 
608  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
609  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
610  // At 4us, STA PHY STATE should move from IDLE to RX
613  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
614  // 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.
619  // In this case, the first packet should be marked as a failure
620  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
621 
622  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
623  // PHY preamble detection should switch because a higher packet is received within the 4us window,
624  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
625  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
626 
627  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
628  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
629  // At 4us, STA PHY STATE should stay in IDLE
631  // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
634  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
637  // 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
638  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
639 
640  // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY state:
641  // PHY preamble detection should switch because a higher packet is received within the 4us window,
642  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
643  // Payload reception should fail (SNR too low to decode the modulation).
644 
645  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
646  Simulator::Schedule (Seconds (6.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
647  // At 4us, STA PHY STATE should stay in IDLE
649  // At 6us, STA PHY STATE should move from IDLE to RX
652  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
655  // In this case, the second packet should be marked as a failure
656  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
657 
658  // CASE 7: send two packets with same power at the exact same time and check PHY state:
659  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
660  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
661  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
662 
663  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
664  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
665  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
668  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
671  // 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
672  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
673 
674  // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY state:
675  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
676  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
677  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
678 
679  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
680  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
681  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
684  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
687  // 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
688  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
689 
690  // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY state:
691  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
692  // but payload reception should fail (SNR too low to decode the modulation).
693 
694  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
695  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
696  // At 4us, STA PHY STATE should move from IDLE to RX
699  // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
702  // In this case, the first packet should be marked as a failure
703  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
704 
705  // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY state:
706  // PHY preamble detection should switch because a higher packet is received within the 4us window,
707  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
708  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
709 
710  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
711  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
712  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
715  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
718  // 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
719  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
720 
721  // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY state:
722  // PHY preamble detection should switch because a higher packet is received within the 4us window,
723  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
724  // Payload reception should fail (SNR too low to decode the modulation).
725 
726  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
727  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
728  // At 4us, STA PHY STATE should move from IDLE to RX
731  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
734  // In this case, the second packet should be marked as a failure
735  Simulator::Schedule (Seconds (11.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 4);
736 
737  // CCA-PD < RX power < CCA-ED
738  rxPowerDbm = -70;
739 
740  // CASE 12: send one packet and check PHY state:
741  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
742  // otherwise it should be IDLE.
743 
744  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
745  // At 4us, STA PHY STATE should move from IDLE to RX
748  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
751  // Packet should have been successfully received
752  Simulator::Schedule (Seconds (12.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
753 
754  // CASE 13: send two packets with same power within the 4us window and check PHY state:
755  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
756  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
757 
758  Simulator::Schedule (Seconds (13.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
759  Simulator::Schedule (Seconds (13.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
760  // At 4us, STA PHY STATE should stay in IDLE
762  // 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
763  Simulator::Schedule (Seconds (13.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
764 
765  // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
766  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
767  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
768 
769  Simulator::Schedule (Seconds (14.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
770  Simulator::Schedule (Seconds (14.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
771  // At 4us, STA PHY STATE should stay in IDLE
773  // 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
774  Simulator::Schedule (Seconds (14.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
775 
776  // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
777  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
778  // but payload reception should fail (SNR too low to decode the modulation).
779 
780  Simulator::Schedule (Seconds (15.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
781  Simulator::Schedule (Seconds (15.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
782  // At 4us, STA PHY STATE should move from IDLE to RX
785  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
788  // In this case, the first packet should be marked as a failure
789  Simulator::Schedule (Seconds (15.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
790 
791  // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY state:
792  // PHY preamble detection should switch because a higher packet is received within the 4us window,
793  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB).
794  // PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
795 
796  Simulator::Schedule (Seconds (16.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
797  Simulator::Schedule (Seconds (16.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
798  // At 4us, STA PHY STATE should stay in IDLE
800  // At 6us, STA PHY STATE should stay in IDLE
802  // 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
803  Simulator::Schedule (Seconds (16.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
804 
805  // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY state:
806  // PHY preamble detection should switch because a higher packet is received within the 4us window,
807  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
808  // Payload reception should fail (SNR too low to decode the modulation).
809 
810  Simulator::Schedule (Seconds (17.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
811  Simulator::Schedule (Seconds (17.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
812  // At 4us, STA PHY STATE should stay in IDLE
814  // At 6us, STA PHY STATE should move from IDLE to RX
817  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
820  // In this case, the second packet should be marked as a failure
821  Simulator::Schedule (Seconds (17.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 6);
822 
823  rxPowerDbm = -50;
824  // CASE 18: send two packets with second one 50 dB higher within the 4us window
825 
826  Simulator::Schedule (Seconds (18.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
827  Simulator::Schedule (Seconds (18.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
828  // The second packet should be received successfully
829  Simulator::Schedule (Seconds (18.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 6);
830 
831  // CASE 19: send two packets with second one 10 dB higher within the 4us window
832 
833  Simulator::Schedule (Seconds (19.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
834  Simulator::Schedule (Seconds (19.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
835  // The second packet should be captured, but not decoded since SNR to low for used MCS
836  Simulator::Schedule (Seconds (19.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 7);
837 
838  // CASE 20: send two packets with second one 50 dB higher in the same time
839 
840  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
841  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
842  // The second packet should be received successfully, same as in CASE 13
843  Simulator::Schedule (Seconds (20.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 7);
844 
845  // CASE 21: send two packets with second one 10 dB higher in the same time
846 
847  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
848  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
849  // The second packet should be captured, but not decoded since SNR to low for used MCS, same as in CASE 19
850  Simulator::Schedule (Seconds (21.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 8);
851 
852  Simulator::Run ();
853  Simulator::Destroy ();
854 }
855 
863 {
864 public:
866  virtual ~TestSimpleFrameCaptureModel ();
867 
868 protected:
869  virtual void DoSetup (void);
870 
871 private:
872  virtual void DoRun (void);
873 
877  void Reset (void);
883  void SendPacket (double rxPowerDbm, uint32_t packetSize);
891  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
898 
910  void Expect1000BPacketDropped ();
914  void Expect1500BPacketDropped ();
915 
917 
922 };
923 
925 : TestCase ("Simple frame capture model test"),
926  m_rxSuccess1000B (false),
927  m_rxSuccess1500B (false),
928  m_rxDropped1000B (false),
929  m_rxDropped1500B (false)
930 {
931 }
932 
933 void
935 {
936  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
937 
938  Ptr<Packet> pkt = Create<Packet> (packetSize);
939  WifiMacHeader hdr;
940 
942  hdr.SetQosTid (0);
943 
944  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
945  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
946 
947  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
948 
949  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
950 
951  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
952  txParams->psd = txPowerSpectrum;
953  txParams->txPhy = 0;
954  txParams->duration = txDuration;
955  txParams->ppdu = ppdu;
956 
957  m_phy->StartRx (txParams);
958 }
959 
960 void
961 TestSimpleFrameCaptureModel::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
962 {
963  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
964  NS_ASSERT (!psdu->IsAggregate () || psdu->IsSingle ());
965  if (psdu->GetSize () == 1030)
966  {
967  m_rxSuccess1000B = true;
968  }
969  else if (psdu->GetSize () == 1530)
970  {
971  m_rxSuccess1500B = true;
972  }
973 }
974 
975 void
977 {
978  NS_LOG_FUNCTION (this << p << reason);
979  if (p->GetSize () == 1030)
980  {
981  m_rxDropped1000B = true;
982  }
983  else if (p->GetSize () == 1530)
984  {
985  m_rxDropped1500B = true;
986  }
987 }
988 
989 void
991 {
992  m_rxSuccess1000B = false;
993  m_rxSuccess1500B = false;
994  m_rxDropped1000B = false;
995  m_rxDropped1500B = false;
996 }
997 
998 void
1000 {
1001  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1000B, true, "Didn't receive 1000B packet");
1002 }
1003 
1004 void
1006 {
1007  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1500B, true, "Didn't receive 1500B packet");
1008 }
1009 void
1011 {
1012  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1000B, true, "Didn't drop 1000B packet");
1013 }
1014 
1015 void
1017 {
1018  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1500B, true, "Didn't drop 1500B packet");
1019 }
1020 
1022 {
1023  m_phy = 0;
1024 }
1025 
1026 void
1028 {
1029  m_phy = CreateObject<SpectrumWifiPhy> ();
1031  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1032  m_phy->SetErrorRateModel (error);
1035 
1038 
1039  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1040  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1041  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1042 
1043  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1044  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1045  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1046  m_phy->SetFrameCaptureModel (frameCaptureModel);
1047 }
1048 
1049 void
1051 {
1052  RngSeedManager::SetSeed (1);
1053  RngSeedManager::SetRun (1);
1054  int64_t streamNumber = 2;
1055  double rxPowerDbm = -30;
1056  m_phy->AssignStreams (streamNumber);
1057 
1058  // CASE 1: send two packets with same power within the capture window:
1059  // PHY should not switch reception because they have same power.
1060 
1061  Simulator::Schedule (Seconds (1.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1062  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1500);
1063  Simulator::Schedule (Seconds (1.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1064  Simulator::Schedule (Seconds (1.2), &TestSimpleFrameCaptureModel::Reset, this);
1065 
1066  // CASE 2: send two packets with second one 6 dB weaker within the capture window:
1067  // PHY should not switch reception because first one has higher power.
1068 
1069  Simulator::Schedule (Seconds (2.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1070  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm - 6, 1500);
1071  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1000BPacketReceived, this);
1072  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1073  Simulator::Schedule (Seconds (2.2), &TestSimpleFrameCaptureModel::Reset, this);
1074 
1075  // CASE 3: send two packets with second one 6 dB higher within the capture window:
1076  // PHY should switch reception because the second one has a higher power.
1077 
1078  Simulator::Schedule (Seconds (3.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1079  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1080  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1000BPacketDropped, this);
1081  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1500BPacketReceived, this);
1082  Simulator::Schedule (Seconds (3.2), &TestSimpleFrameCaptureModel::Reset, this);
1083 
1084  // CASE 4: send two packets with second one 6 dB higher after the capture window:
1085  // PHY should not switch reception because capture window duration has elapsed when the second packet arrives.
1086 
1087  Simulator::Schedule (Seconds (4.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1088  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1089  Simulator::Schedule (Seconds (4.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1090  Simulator::Schedule (Seconds (4.2), &TestSimpleFrameCaptureModel::Reset, this);
1091 
1092  Simulator::Run ();
1093  Simulator::Destroy ();
1094 }
1095 
1103 {
1104 public:
1106  virtual ~TestPhyHeadersReception ();
1107 
1108 protected:
1109  virtual void DoSetup (void);
1111 
1115  void SendPacket (double rxPowerDbm);
1116 
1117 private:
1118  virtual void DoRun (void);
1119 
1124  void CheckPhyState (WifiPhyState expectedState);
1129  void DoCheckPhyState (WifiPhyState expectedState);
1130 };
1131 
1133 : TestCase ("PHY headers reception test")
1134 {
1135 }
1136 
1137 void
1139 {
1140  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
1141 
1142  Ptr<Packet> pkt = Create<Packet> (1000);
1143  WifiMacHeader hdr;
1144 
1145  hdr.SetType (WIFI_MAC_QOSDATA);
1146  hdr.SetQosTid (0);
1147 
1148  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
1149  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
1150 
1151  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
1152 
1153  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1154 
1155  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1156  txParams->psd = txPowerSpectrum;
1157  txParams->txPhy = 0;
1158  txParams->duration = txDuration;
1159  txParams->ppdu = ppdu;
1160 
1161  m_phy->StartRx (txParams);
1162 }
1163 
1164 void
1166 {
1167  //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
1168  Simulator::ScheduleNow (&TestPhyHeadersReception::DoCheckPhyState, this, expectedState);
1169 }
1170 
1171 void
1173 {
1174  WifiPhyState currentState;
1175  PointerValue ptr;
1176  m_phy->GetAttribute ("State", ptr);
1177  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1178  currentState = state->GetState ();
1179  NS_LOG_FUNCTION (this << currentState);
1180  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1181 }
1182 
1183 
1185 {
1186  m_phy = 0;
1187 }
1188 
1189 void
1191 {
1192  m_phy = CreateObject<SpectrumWifiPhy> ();
1194  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1195  m_phy->SetErrorRateModel (error);
1198 }
1199 
1200 void
1202 {
1203  RngSeedManager::SetSeed (1);
1204  RngSeedManager::SetRun (1);
1205  int64_t streamNumber = 0;
1206  m_phy->AssignStreams (streamNumber);
1207 
1208  // RX power > CCA-ED
1209  double rxPowerDbm = -50;
1210 
1211  // CASE 1: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1212  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1213 
1214  Simulator::Schedule (Seconds (1.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1215  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1216  // At 10 us, STA PHY STATE should be RX.
1217  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1218  // At 24us (end of L-SIG), STA PHY STATE should go to CCA_BUSY because L-SIG reception failed and the total energy is above CCA-ED.
1219  Simulator::Schedule (Seconds (1.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1220  Simulator::Schedule (Seconds (1.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1221  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10 = 162.8us.
1222  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1223  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1224 
1225  // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1226  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1227 
1228  Simulator::Schedule (Seconds (2.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1229  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1230  // At 10 us, STA PHY STATE should be RX.
1231  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1232  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1233  Simulator::Schedule (Seconds (2.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1234  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1235  // 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.
1236  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1237  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1238  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1239  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1240 
1241  // 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:
1242  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1243 
1244  Simulator::Schedule (Seconds (3.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1245  Simulator::Schedule (Seconds (3.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1246  // At 44 us (end of HE-SIG), STA PHY STATE should be RX (even though reception of HE-SIG failed)
1247  Simulator::Schedule (Seconds (3.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1248  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1249  // 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.
1250  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1251  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1252  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1253  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1254 
1255  // 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:
1256  // PHY header reception should succeed.
1257 
1258  Simulator::Schedule (Seconds (4.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1259  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1260  // At 44 us (end of HE-SIG), STA PHY STATE should be RX.
1261  Simulator::Schedule (Seconds (4.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1262  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1263  // 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.
1264  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1265  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1266  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1267  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1268 
1269  // RX power < CCA-ED
1270  rxPowerDbm = -70;
1271 
1272  // CASE 5: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1273  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1274 
1275  Simulator::Schedule (Seconds (5.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1276  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1277  // At 10 us, STA PHY STATE should be RX.
1278  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1279  // 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.
1280  Simulator::Schedule (Seconds (5.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1281  Simulator::Schedule (Seconds (5.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1282 
1283  // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1284  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1285 
1286  Simulator::Schedule (Seconds (6.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1287  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1288  // At 10 us, STA PHY STATE should be RX.
1289  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1290  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1291  Simulator::Schedule (Seconds (6.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1292  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1293  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1294  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1295 
1296  // 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:
1297  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1298 
1299  Simulator::Schedule (Seconds (7.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1300  Simulator::Schedule (Seconds (7.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1301  // At 44 us (end of HE-SIG), STA PHY STATE should be RX (even though reception of HE-SIG failed).
1302  Simulator::Schedule (Seconds (7.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1303  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1304  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1305  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1306 
1307  // 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:
1308  // PHY header reception should succeed.
1309 
1310  Simulator::Schedule (Seconds (8.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1311  Simulator::Schedule (Seconds (8.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1312  // At 44 us (end of HE-SIG), STA PHY STATE should be RX.
1313  Simulator::Schedule (Seconds (8.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1314  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1315  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1316  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1317 
1318  Simulator::Run ();
1319  Simulator::Destroy ();
1320 }
1321 
1329 {
1330 public:
1331  TestAmpduReception ();
1332  virtual ~TestAmpduReception ();
1333 
1334 protected:
1335  virtual void DoSetup (void);
1336 
1337 private:
1338  virtual void DoRun (void);
1339 
1347  void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1352  void RxFailure (Ptr<WifiPsdu> psdu);
1363  void IncrementSuccessBitmap (uint32_t size);
1368  void IncrementFailureBitmap (uint32_t size);
1369 
1373  void ResetBitmaps();
1374 
1380  void SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize);
1381 
1386  void CheckRxSuccessBitmapAmpdu1 (uint8_t expected);
1391  void CheckRxSuccessBitmapAmpdu2 (uint8_t expected);
1396  void CheckRxFailureBitmapAmpdu1 (uint8_t expected);
1401  void CheckRxFailureBitmapAmpdu2 (uint8_t expected);
1406  void CheckRxDroppedBitmapAmpdu1 (uint8_t expected);
1411  void CheckRxDroppedBitmapAmpdu2 (uint8_t expected);
1412 
1417  void CheckPhyState (WifiPhyState expectedState);
1418 
1420 
1423 
1426 
1429 };
1430 
1432 : TestCase ("A-MPDU reception test"),
1433  m_rxSuccessBitmapAmpdu1 (0),
1434  m_rxSuccessBitmapAmpdu2 (0),
1435  m_rxFailureBitmapAmpdu1 (0),
1436  m_rxFailureBitmapAmpdu2 (0),
1437  m_rxDroppedBitmapAmpdu1 (0),
1438  m_rxDroppedBitmapAmpdu2 (0)
1439 {
1440 }
1441 
1443 {
1444  m_phy = 0;
1445 }
1446 
1447 void
1449 {
1456 }
1457 
1458 void
1459 TestAmpduReception::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1460 {
1461  NS_LOG_FUNCTION (this << *psdu << snr << txVector);
1462  NS_ABORT_MSG_IF (psdu->GetNMpdus () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1463  auto rxOkForMpdu = statusPerMpdu.begin ();
1464  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1465  {
1466  if (*rxOkForMpdu)
1467  {
1468  IncrementSuccessBitmap ((*mpdu)->GetSize ());
1469  }
1470  else
1471  {
1472  IncrementFailureBitmap ((*mpdu)->GetSize ());
1473  }
1474  ++rxOkForMpdu;
1475  }
1476 }
1477 
1478 void
1480 {
1481  if (size == 1030) //A-MPDU 1 - MPDU #1
1482  {
1484  }
1485  else if (size == 1130) //A-MPDU 1 - MPDU #2
1486  {
1487  m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1488  }
1489  else if (size == 1230) //A-MPDU 1 - MPDU #3
1490  {
1491  m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1492  }
1493  else if (size == 1330) //A-MPDU 2 - MPDU #1
1494  {
1496  }
1497  else if (size == 1430) //A-MPDU 2 - MPDU #2
1498  {
1499  m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1500  }
1501  else if (size == 1530) //A-MPDU 2 - MPDU #3
1502  {
1503  m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1504  }
1505 }
1506 
1507 void
1509 {
1510  NS_LOG_FUNCTION (this << *psdu);
1511  for (auto mpdu = psdu->begin (); mpdu != psdu->end (); ++mpdu)
1512  {
1513  IncrementFailureBitmap ((*mpdu)->GetSize ());
1514  }
1515 }
1516 
1517 void
1519 {
1520  if (size == 1030) //A-MPDU 1 - MPDU #1
1521  {
1523  }
1524  else if (size == 1130) //A-MPDU 1 - MPDU #2
1525  {
1526  m_rxFailureBitmapAmpdu1 |= (1 << 1);
1527  }
1528  else if (size == 1230) //A-MPDU 1 - MPDU #3
1529  {
1530  m_rxFailureBitmapAmpdu1 |= (1 << 2);
1531  }
1532  else if (size == 1330) //A-MPDU 2 - MPDU #1
1533  {
1535  }
1536  else if (size == 1430) //A-MPDU 2 - MPDU #2
1537  {
1538  m_rxFailureBitmapAmpdu2 |= (1 << 1);
1539  }
1540  else if (size == 1530) //A-MPDU 2 - MPDU #3
1541  {
1542  m_rxFailureBitmapAmpdu2 |= (1 << 2);
1543  }
1544 }
1545 
1546 void
1548 {
1549  NS_LOG_FUNCTION (this << p << reason);
1550  if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1551  {
1553  }
1554  else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1555  {
1556  m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1557  }
1558  else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1559  {
1560  m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1561  }
1562  else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1563  {
1565  }
1566  else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1567  {
1568  m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1569  }
1570  else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1571  {
1572  m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1573  }
1574 }
1575 
1576 void
1578 {
1579  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1580 }
1581 
1582 void
1584 {
1585  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1586 }
1587 
1588 void
1590 {
1591  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1592 }
1593 
1594 void
1596 {
1597  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1598 }
1599 
1600 void
1602 {
1603  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1604 }
1605 
1606 void
1608 {
1609  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1610 }
1611 
1612 void
1614 {
1615  WifiPhyState currentState;
1616  PointerValue ptr;
1617  m_phy->GetAttribute ("State", ptr);
1618  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1619  currentState = state->GetState ();
1620  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1621 }
1622 
1623 void
1624 TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1625 {
1626  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true, false);
1627 
1628  WifiMacHeader hdr;
1629  hdr.SetType (WIFI_MAC_QOSDATA);
1630  hdr.SetQosTid (0);
1631 
1632  std::vector<Ptr<WifiMacQueueItem>> mpduList;
1633  for (size_t i = 0; i < 3; ++i)
1634  {
1635  Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1636  mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1637  }
1638  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1639 
1640  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
1641 
1642  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, FREQUENCY);
1643 
1644  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1645 
1646  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1647  txParams->psd = txPowerSpectrum;
1648  txParams->txPhy = 0;
1649  txParams->duration = txDuration;
1650  txParams->ppdu = ppdu;
1651 
1652  m_phy->StartRx (txParams);
1653 }
1654 
1655 void
1657 {
1658  m_phy = CreateObject<SpectrumWifiPhy> ();
1660  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1661  m_phy->SetErrorRateModel (error);
1664 
1668 
1669  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1670  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1671  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1672 
1673  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1674  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1675  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1676  m_phy->SetFrameCaptureModel (frameCaptureModel);
1677 }
1678 
1679 void
1681 {
1682  RngSeedManager::SetSeed (1);
1683  RngSeedManager::SetRun (2);
1684  int64_t streamNumber = 1;
1685  double rxPowerDbm = -30;
1686  m_phy->AssignStreams (streamNumber);
1687 
1689  // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1690  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1692 
1693  // A-MPDU 1
1694  Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1695 
1696  // A-MPDU 2
1697  Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1698 
1699  // All MPDUs of A-MPDU 1 should have been ignored.
1700  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1701  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1702  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1703 
1704  // All MPDUs of A-MPDU 2 should have been successfully received.
1705  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1706  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1707  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1708 
1709  Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1710 
1712  // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1713  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1715 
1716  // A-MPDU 1
1717  Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1718 
1719  // A-MPDU 2
1720  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1721 
1722  // All MPDUs of A-MPDU 1 should have been received.
1723  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1724  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1725  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1726 
1727  // All MPDUs of A-MPDU 2 should have been ignored.
1728  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1729  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1730  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1731 
1732  Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1733 
1735  // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1736  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1738 
1739  // A-MPDU 1
1740  Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1741 
1742  // A-MPDU 2
1743  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1744 
1745  // All MPDUs of A-MPDU 1 should have been ignored.
1746  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1747  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1748  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1749 
1750  // All MPDUs of A-MPDU 2 should have been successfully received.
1751  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1752  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1753  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1754 
1755  Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1756 
1758  // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1759  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1761 
1762  // A-MPDU 1
1763  Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1764 
1765  // A-MPDU 2
1766  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1767 
1768  // All MPDUs of A-MPDU 1 should have been received.
1769  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1770  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1771  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1772 
1773  // All MPDUs of A-MPDU 2 should have been ignored.
1774  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1775  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1776  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1777 
1778  Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1779 
1781  // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1782  // 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).
1784 
1785  // A-MPDU 1
1786  Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1787 
1788  // A-MPDU 2
1789  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1790 
1791  // All MPDUs of A-MPDU 1 should have been ignored.
1792  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1793  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1794  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1795 
1796  // All MPDUs of A-MPDU 2 should have been successfully received.
1797  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1798  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1799  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1800 
1801  Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1802 
1804  // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1805  // 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).
1807 
1808  // A-MPDU 1
1809  Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1810 
1811  // A-MPDU 2
1812  Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1813 
1814  // All MPDUs of A-MPDU 1 should have been received.
1815  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1816  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1817  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1818 
1819  // All MPDUs of A-MPDU 2 should have been ignored.
1820  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1821  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1822  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1823 
1824  Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1825 
1827  // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1828  // The second A-MPDU is received during the payload of MPDU #2.
1830 
1831  // A-MPDU 1
1832  Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1833 
1834  // A-MPDU 2
1835  Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1836 
1837  // All MPDUs of A-MPDU 1 should have been ignored.
1838  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1839  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1840  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1841 
1842  // All MPDUs of A-MPDU 2 should have been successfully received.
1843  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1844  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1845  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1846 
1847  Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1848 
1850  // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1851  // The second A-MPDU is received during the payload of MPDU #2.
1853 
1854  // A-MPDU 1
1855  Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1856 
1857  // A-MPDU 2
1858  Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1859 
1860  // All MPDUs of A-MPDU 1 should have been received.
1861  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1862  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1863  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1864 
1865  // All MPDUs of A-MPDU 2 should have been ignored.
1866  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1867  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1868  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1869 
1870  Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
1871 
1873  // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1874  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1876 
1877  // A-MPDU 1
1878  Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1879 
1880  // A-MPDU 2
1881  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
1882 
1883  // All MPDUs of A-MPDU 1 should have been dropped.
1884  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1885  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1886  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1887 
1888  // All MPDUs of A-MPDU 2 should have been received with errors.
1889  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1890  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
1891  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1892 
1893  Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
1894 
1896  // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
1897  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1899 
1900  // A-MPDU 1
1901  Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1902 
1903  // A-MPDU 2
1904  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1905 
1906  // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
1907  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1908  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1909  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1910 
1911  // All MPDUs of A-MPDU 2 should have been dropped as well.
1912  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1913  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1914  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1915 
1916  Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
1917 
1919  // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
1920  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1922 
1923  // A-MPDU 1
1924  Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
1925 
1926  // A-MPDU 2
1927  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1928 
1929  // All MPDUs of A-MPDU 1 should have been received with errors.
1930  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1931  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
1932  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1933 
1934  // All MPDUs of A-MPDU 2 should have been dropped.
1935  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1936  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1937  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1938 
1939  Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
1940 
1942  // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1943  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1945 
1946  // A-MPDU 1
1947  Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1948 
1949  // A-MPDU 2
1950  Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
1951 
1952  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
1953  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1954  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1955  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1956 
1957  // 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)
1958  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1959  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1960  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1961 
1962  Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
1963 
1965  // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
1966  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1968 
1969  // A-MPDU 1
1970  Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1971 
1972  // A-MPDU 2
1973  Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1974 
1975  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
1976  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1977  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1978  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1979 
1980  // All MPDUs of A-MPDU 2 should have been dropped as well.
1981  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1982  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1983  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1984 
1985  Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
1986 
1988  // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
1989  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1991 
1992  // A-MPDU 1
1993  Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
1994 
1995  // A-MPDU 2
1996  Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1997 
1998  // All MPDUs of A-MPDU 1 should have been received with errors.
1999  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2000  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2001  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2002 
2003  // All MPDUs of A-MPDU 2 should have been dropped.
2004  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2005  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2006  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2007 
2008  Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
2009 
2011  // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2012  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2014 
2015  // A-MPDU 1
2016  Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2017 
2018  // A-MPDU 2
2019  Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2020 
2021  // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
2022  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2023  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2024  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2025 
2026  // All MPDUs of A-MPDU 2 should have been successfully received
2027  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
2028  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2029  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2030 
2031  Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
2032 
2034  // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2035  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2037 
2038  // A-MPDU 1
2039  Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2040 
2041  // A-MPDU 2
2042  Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2043 
2044  // All MPDUs of A-MPDU 1 should have been successfully received.
2045  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2046  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2047  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2048 
2049  // All MPDUs of A-MPDU 2 should have been dropped.
2050  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2051  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2052  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2053 
2054  Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2055 
2057  // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2058  // 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).
2060 
2061  // A-MPDU 1
2062  Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2063 
2064  // A-MPDU 2
2065  Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2066 
2067  // All MPDUs of A-MPDU 1 should have been received with errors.
2068  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2069  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2070  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2071 
2072  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2073  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2074  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2075  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2076 
2077  Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2078 
2080  // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2081  // 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).
2083 
2084  // A-MPDU 1
2085  Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2086 
2087  // A-MPDU 2
2088  Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2089 
2090  // All MPDUs of A-MPDU 1 should have been successfully received.
2091  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2092  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2093  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2094 
2095  // All MPDUs of A-MPDU 2 should have been dropped.
2096  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2097  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2098  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2099 
2100  Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2101 
2103  // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2104  // 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).
2106 
2107  // A-MPDU 1
2108  Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2109 
2110  // A-MPDU 2
2111  Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2112 
2113  // All MPDUs of A-MPDU 1 should have been received with errors.
2114  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2115  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2116  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2117 
2118  // All MPDUs of A-MPDU 2 should have been dropped.
2119  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2120  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2121  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2122 
2123  Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2124 
2126  // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2127  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2129 
2130  // A-MPDU 1
2131  Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2132 
2133  // A-MPDU 2
2134  Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2135 
2136  // All MPDUs of A-MPDU 1 should have been received with errors.
2137  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2138  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2139  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2140 
2141  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2142  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2143  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2144  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2145 
2146  Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2147 
2149  // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2150  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2152 
2153  // A-MPDU 1
2154  Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2155 
2156  // A-MPDU 2
2157  Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2158 
2159  // All MPDUs of A-MPDU 1 should have been successfully received.
2160  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2161  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2162  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2163 
2164  // All MPDUs of A-MPDU 2 should have been dropped.
2165  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2166  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2167  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2168 
2169  Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2170 
2172  // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2173  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2175 
2176  // A-MPDU 1
2177  Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2178 
2179  // A-MPDU 2
2180  Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2181 
2182  // All MPDUs of A-MPDU 1 should have been received with errors.
2183  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2184  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2185  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2186 
2187  // All MPDUs of A-MPDU 2 should have been dropped.
2188  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2189  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2190  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2191 
2192  Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2193 
2195  // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2196  // The second A-MPDU is received during the payload of MPDU #2.
2198 
2199  // A-MPDU 1
2200  Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2201 
2202  // A-MPDU 2
2203  Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2204 
2205  // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2206  // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2207  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2208  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2209  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000110);
2210 
2211  // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2212  // 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.
2213  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2214  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2215  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2216 
2217  Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2218 
2219  Simulator::Run ();
2220  Simulator::Destroy ();
2221 }
2222 
2230 {
2231 public:
2233 };
2234 
2236  : TestSuite ("wifi-phy-reception", UNIT)
2237 {
2240  AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2241  AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2242  AddTestCase (new TestAmpduReception, TestCase::QUICK);
2243 }
2244 
uint8_t m_rxSuccessBitmapAmpdu1
bitmap of successfully received MPDUs in A-MPDU #1
bool IsSingle(void) const
Return true if the PSDU is an S-MPDU.
Definition: wifi-psdu.cc:75
void CheckRxFailureBitmapAmpdu2(uint8_t expected)
Check the RX failure bitmap for A-MPDU 2.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< SpectrumWifiPhy > m_phy
Phy.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
void SendPacket(double rxPowerDbm)
Send packet function.
void Expect1000BPacketDropped()
Verify whether 1000 bytes packet has been dropped.
Ptr< WifiPpdu > ppdu
The PPDU being transmitted.
static const uint32_t packetSize
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level Phy interface to this Sp...
void SendPacket(double rxPowerDbm, uint32_t packetSize)
Send packet function.
void IncrementFailureBitmap(uint32_t size)
Increment reception failure bitmap.
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:41
A suite of tests to run.
Definition: test.h:1342
void ResetBitmaps()
Reset bitmaps function.
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
RX success function.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void Reset(void)
Reset function.
void CheckRxSuccessBitmapAmpdu1(uint8_t expected)
Check the RX success bitmap for A-MPDU 1.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:460
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
void Expect1500BPacketReceived()
Verify whether 1500 bytes packet has been received.
static WifiPhyReceptionTestSuite wifiPhyReceptionTestSuite
the test suite
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
Simple frame capture model test.
encapsulates test code
Definition: test.h:1155
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:781
std::vector< Ptr< WifiMacQueueItem > >::const_iterator end(void) const
Return a const iterator to past-the-last MPDU.
Definition: wifi-psdu.cc:337
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test PHY state upon success or failure of L-SIG and SIG-A.
virtual void SetChannelNumber(uint8_t id)
Set channel number.
static const uint16_t GUARD_WIDTH
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint32_t GetSize(void) const
Return the size of the PSDU.
Definition: wifi-psdu.cc:260
static Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2412
Ptr< SpectrumWifiPhy > m_phy
Phy.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
Preamble detection test w/o frame capture.
Preamble detection test w/o frame capture.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm)
Send packet function.
HE PHY for the 5 GHz band (clause 26)
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
AttributeValue implementation for Time.
Definition: nstime.h:1124
virtual void ConfigureStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1086
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:168
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:787
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.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
static const uint32_t FREQUENCY
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void IncrementSuccessBitmap(uint32_t size)
Increment reception success bitmap.
uint8_t m_rxDroppedBitmapAmpdu2
bitmap of dropped MPDUs in A-MPDU #2
void SendAmpduWithThreeMpdus(double rxPowerDbm, uint32_t referencePacketSize)
Send A-MPDU with 3 MPDUs of different size (i-th MSDU will have 100 bytes more than (i-1)-th)...
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
virtual void SetFrequency(uint16_t freq)
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:767
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void CheckRxDroppedBitmapAmpdu2(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 2.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
A-MPDU reception test.
std::size_t GetNMpdus(void) const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:319
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void SendPacket(double rxPowerDbm)
Send packet function.
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1368
The PHY layer is IDLE.
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
WifiPhyState
The state of the PHY layer.
bool m_rxDropped1500B
count dropped packets with 1500B payload
void RxFailure(Ptr< WifiPsdu > psdu)
Spectrum wifi receive failure function.
void CheckRxSuccessBitmapAmpdu2(uint8_t expected)
Check the RX success bitmap for A-MPDU 2.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
uint8_t m_rxSuccessBitmapAmpdu2
bitmap of successfully received MPDUs in A-MPDU #2
uint8_t m_rxFailureBitmapAmpdu2
bitmap of unsuccessfully received MPDUs in A-MPDU #2
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:454
This objects implements the PHY state machine of the Wifi device.
WifiPhyState GetState(void) const
Return the current state of WifiPhy.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
WifiPhyRxfailureReason
Enumeration of the possible reeception failure reasons.
Definition: wifi-phy.h:53
The PHY layer is receiving a packet.
Ptr< T > Get(void) const
Definition: pointer.h:194
bool m_rxSuccess1500B
count received packets with 1500B payload
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
void RxFailure(Ptr< WifiPsdu > psdu)
RX failure function.
Time duration
The duration of the packet transmission.
static const uint16_t CHANNEL_WIDTH
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1078
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:309
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void Expect1500BPacketDropped()
Verify whether 1500 bytes packet has been dropped.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
uint8_t m_rxDroppedBitmapAmpdu1
bitmap of dropped MPDUs in A-MPDU #1
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void CheckRxFailureBitmapAmpdu1(uint8_t expected)
Check the RX failure bitmap for A-MPDU 1.
bool m_rxDropped1000B
count dropped packets with 1000B payload
void RxSuccess(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:223
wifi PHY reception Test Suite
static const uint8_t CHANNEL_NUMBER
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Definition: wifi-phy.cc:4131
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