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/wifi-mac-trailer.h"
32 #include "ns3/ampdu-tag.h"
33 #include "ns3/wifi-phy-tag.h"
34 #include "ns3/wifi-spectrum-signal-parameters.h"
35 #include "ns3/wifi-utils.h"
36 #include "ns3/threshold-preamble-detection-model.h"
37 #include "ns3/simple-frame-capture-model.h"
38 #include "ns3/wifi-psdu.h"
39 #include "ns3/wifi-mac-queue-item.h"
40 #include "ns3/mpdu-aggregator.h"
41 #include "ns3/wifi-phy-header.h"
42 
43 using namespace ns3;
44 
45 NS_LOG_COMPONENT_DEFINE ("WifiPhyReceptionTest");
46 
47 static const uint8_t CHANNEL_NUMBER = 36;
48 static const uint32_t FREQUENCY = 5180; // MHz
49 static const uint16_t CHANNEL_WIDTH = 20; // MHz
50 static const uint16_t GUARD_WIDTH = CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
51 
59 {
60 public:
63 
64 protected:
65  virtual void DoSetup (void);
67 
71  void SendPacket (double rxPowerDbm);
79  void RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
84  void RxFailure (Ptr<Packet> p);
85  uint32_t m_countRxSuccess;
86  uint32_t m_countRxFailure;
87 
88 private:
89  virtual void DoRun (void);
90 
95  void CheckPhyState (WifiPhyState expectedState);
96  void DoCheckPhyState (WifiPhyState expectedState);
102  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
103 };
104 
106  : TestCase ("Threshold preamble detection model test when no frame capture model is applied"),
107  m_countRxSuccess (0),
108  m_countRxFailure (0)
109 {
110 }
111 
112 void
114 {
115  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
116 
117  Ptr<Packet> pkt = Create<Packet> (1000);
118  WifiMacHeader hdr;
119  WifiMacTrailer trailer;
120 
121  hdr.SetType (WIFI_MAC_QOSDATA);
122  hdr.SetQosTid (0);
123  uint32_t size = pkt->GetSize () + hdr.GetSize () + trailer.GetSerializedSize ();
124  Time txDuration = m_phy->CalculateTxDuration (size, txVector, m_phy->GetFrequency ());
125  hdr.SetDuration (txDuration);
126 
127  pkt->AddHeader (hdr);
128  pkt->AddTrailer (trailer);
129 
130  HeSigHeader heSig;
131  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
132  heSig.SetBssColor (txVector.GetBssColor ());
133  heSig.SetChannelWidth (txVector.GetChannelWidth ());
134  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2);
135  pkt->AddHeader (heSig);
136 
137  LSigHeader sig;
138  pkt->AddHeader (sig);
139 
140  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), 1);
141  pkt->AddPacketTag (tag);
142 
143  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
144  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
145  txParams->psd = txPowerSpectrum;
146  txParams->txPhy = 0;
147  txParams->duration = txDuration;
148  txParams->packet = pkt;
149 
150  m_phy->StartRx (txParams);
151 }
152 
153 void
155 {
156  //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
157  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithoutFrameCapture::DoCheckPhyState, this, expectedState);
158 }
159 
160 void
162 {
163  WifiPhyState currentState;
164  PointerValue ptr;
165  m_phy->GetAttribute ("State", ptr);
166  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
167  currentState = state->GetState ();
168  NS_LOG_FUNCTION (this << currentState);
169  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
170 }
171 
172 void
173 TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
174 {
175  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
176  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
177 }
178 
179 void
180 TestThresholdPreambleDetectionWithoutFrameCapture::RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
181 {
182  NS_LOG_FUNCTION (this << p << snr << txVector);
184 }
185 
186 void
188 {
189  NS_LOG_FUNCTION (this << p);
191 }
192 
194 {
195  m_phy = 0;
196 }
197 
198 void
200 {
201  m_phy = CreateObject<SpectrumWifiPhy> ();
203  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
204  m_phy->SetErrorRateModel (error);
209 
210  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
211  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
212  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
213  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
214 }
215 
216 void
218 {
219  RngSeedManager::SetSeed (1);
220  RngSeedManager::SetRun (1);
221  int64_t streamNumber = 0;
222  m_phy->AssignStreams (streamNumber);
223 
224  //RX power > CCA-ED > CCA-PD
225  double rxPowerDbm = -50;
226 
227  // CASE 1: send one packet and check PHY state:
228  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
229  // otherwise it should be IDLE.
230 
231  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
232  // At 4us, STA PHY STATE should move from IDLE to RX
235  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
238  // Packet should have been successfully received
239  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
240 
241  // CASE 2: send two packets with same power within the 4us window and check PHY state:
242  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
243  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
244  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
245 
246  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
247  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
248  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
251  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
254  // 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
255  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
256 
257  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
258  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
259  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
260  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
261 
262  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
263  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
264  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
267  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
270  // 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
271  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0);
272 
273  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
274  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
275  // but payload reception should fail (SNR too low to decode the modulation).
276 
277  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
278  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
279  // At 4us, STA PHY STATE should move from IDLE to RX
282  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
283  // 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.
288  // In this case, the first packet should be marked as a failure
289  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
290 
291  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
292  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
293  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
294  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
295 
296  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
297  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
298  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
301  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
304  // 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
305  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1);
306 
307  // CCA-PD < RX power < CCA-ED
308  rxPowerDbm = -70;
309 
310  // CASE 6: send one packet and check PHY state:
311  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
312  // otherwise it should be IDLE.
313 
314  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
315  // At 4us, STA PHY STATE should move from IDLE to RX
318  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
321  // Packet should have been successfully received
322  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
323 
324  // CASE 7: send two packets with same power within the 4us window and check PHY state:
325  // PHY preamble detection should fail because SNR is too low (around 0 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 (7.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
329  Simulator::Schedule (Seconds (7.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
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 (7.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
334 
335  // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
336  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
337  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
338 
339  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
340  Simulator::Schedule (Seconds (8.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 3);
341  // At 4us, STA PHY STATE should stay in IDLE
343  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
344  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 1);
345 
346  // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
347  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
348  // but payload reception should fail (SNR too low to decode the modulation).
349 
350  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
351  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm - 6);
352  // At 4us, STA PHY STATE should move from IDLE to RX
355  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
358  // In this case, the first packet should be marked as a failure
359  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
360 
361  // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY state:
362  // PHY preamble detection should fail because SNR is too low (around -3 dB, which is lower than the threshold of 4 dB),
363  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
364 
365  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
366  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm + 3);
367  // At 4us, STA PHY STATE should stay in IDLE
369  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
370  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 2, 2);
371 
372  // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
373  // preamble detection should succeed and PHY state should move to RX.
374 
375  rxPowerDbm = -81;
376 
377  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
378  // At 4us, STA PHY STATE should move from IDLE to RX
381  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
384 
385  // RX power < CCA-PD < CCA-ED
386  rxPowerDbm = -83;
387 
388  //CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble detection (-82 dBm) and check PHY state:
389  //preamble detection should fail and PHY should be kept in IDLE state.
390 
391  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, rxPowerDbm);
392  // At 4us, STA PHY state should be IDLE
394 
395  Simulator::Run ();
396  Simulator::Destroy ();
397 }
398 
406 {
407 public:
410 
411 protected:
412  virtual void DoSetup (void);
414 
418  void SendPacket (double rxPowerDbm);
426  void RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
431  void RxFailure (Ptr<Packet> p);
432  uint32_t m_countRxSuccess;
433  uint32_t m_countRxFailure;
434 
435 private:
436  virtual void DoRun (void);
437 
442  void CheckPhyState (WifiPhyState expectedState);
443  void DoCheckPhyState (WifiPhyState expectedState);
449  void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
450 };
451 
453 : TestCase ("Threshold preamble detection model test when simple frame capture model is applied"),
454 m_countRxSuccess (0),
455 m_countRxFailure (0)
456 {
457 }
458 
459 void
461 {
462  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
463 
464  Ptr<Packet> pkt = Create<Packet> (1000);
465  WifiMacHeader hdr;
466  WifiMacTrailer trailer;
467 
468  hdr.SetType (WIFI_MAC_QOSDATA);
469  hdr.SetQosTid (0);
470  uint32_t size = pkt->GetSize () + hdr.GetSize () + trailer.GetSerializedSize ();
471  Time txDuration = m_phy->CalculateTxDuration (size, txVector, m_phy->GetFrequency ());
472  hdr.SetDuration (txDuration);
473 
474  pkt->AddHeader (hdr);
475  pkt->AddTrailer (trailer);
476 
477  HeSigHeader heSig;
478  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
479  heSig.SetBssColor (txVector.GetBssColor ());
480  heSig.SetChannelWidth (txVector.GetChannelWidth ());
481  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2);
482  pkt->AddHeader (heSig);
483 
484  LSigHeader sig;
485  pkt->AddHeader (sig);
486 
487  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), 1);
488  pkt->AddPacketTag (tag);
489 
490  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
491  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
492  txParams->psd = txPowerSpectrum;
493  txParams->txPhy = 0;
494  txParams->duration = txDuration;
495  txParams->packet = pkt;
496 
497  m_phy->StartRx (txParams);
498 }
499 
500 void
502 {
503  //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
504  Simulator::ScheduleNow (&TestThresholdPreambleDetectionWithFrameCapture::DoCheckPhyState, this, expectedState);
505 }
506 
507 void
509 {
510  WifiPhyState currentState;
511  PointerValue ptr;
512  m_phy->GetAttribute ("State", ptr);
513  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
514  currentState = state->GetState ();
515  NS_LOG_FUNCTION (this << currentState);
516  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
517 }
518 
519 void
520 TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
521 {
522  NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets");
523  NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets");
524 }
525 
526 void
527 TestThresholdPreambleDetectionWithFrameCapture::RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
528 {
529  NS_LOG_FUNCTION (this << p << txVector);
531 }
532 
533 void
535 {
536  NS_LOG_FUNCTION (this << p);
538 }
539 
541 {
542  m_phy = 0;
543 }
544 
545 void
547 {
548  m_phy = CreateObject<SpectrumWifiPhy> ();
550  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
551  m_phy->SetErrorRateModel (error);
556 
557  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
558  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (4));
559  preambleDetectionModel->SetAttribute ("MinimumRssi", DoubleValue (-82));
560  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
561 
562  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
563  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
564  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
565  m_phy->SetFrameCaptureModel (frameCaptureModel);
566 }
567 
568 void
570 {
571  RngSeedManager::SetSeed (1);
572  RngSeedManager::SetRun (1);
573  int64_t streamNumber = 1;
574  m_phy->AssignStreams (streamNumber);
575 
576  //RX power > CCA-ED > CCA-PD
577  double rxPowerDbm = -50;
578 
579  // CASE 1: send one packet and check PHY state:
580  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
581  // otherwise it should be IDLE.
582 
583  Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
584  // At 4us, STA PHY STATE should move from IDLE to RX
587  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
590  // Packet should have been successfully received
591  Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
592 
593  // CASE 2: send two packets with same power within the 4us window and check PHY state:
594  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
595  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
596  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
597 
598  Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
599  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
600  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
603  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
606  // 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
607  Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
608 
609  // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state:
610  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
611  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
612  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
613 
614  Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
615  Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
616  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
619  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
622  // 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
623  Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 0);
624 
625  // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
626  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
627  // but payload reception should fail (SNR too low to decode the modulation).
628 
629  Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
630  Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
631  // At 4us, STA PHY STATE should move from IDLE to RX
634  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
635  // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 2us.
640  // In this case, the first packet should be marked as a failure
641  Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
642 
643  // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY state:
644  // PHY preamble detection should switch because a higher packet is received within the 4us window,
645  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
646  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
647 
648  Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
649  Simulator::Schedule (Seconds (5.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
650  // At 4us, STA PHY STATE should stay in IDLE
652  // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
655  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
658  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
659  Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 1);
660 
661  // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY state:
662  // PHY preamble detection should switch because a higher packet is received within the 4us window,
663  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
664  // Payload reception should fail (SNR too low to decode the modulation).
665 
666  Simulator::Schedule (Seconds (6.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
667  Simulator::Schedule (Seconds (6.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
668  // At 4us, STA PHY STATE should stay in IDLE
670  // At 6us, STA PHY STATE should move from IDLE to RX
673  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
676  // In this case, the second packet should be marked as a failure
677  Simulator::Schedule (Seconds (6.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
678 
679  // CASE 7: send two packets with same power at the exact same time and check PHY state:
680  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
681  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
682  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
683 
684  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
685  Simulator::Schedule (Seconds (7.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
686  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
689  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
692  // 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
693  Simulator::Schedule (Seconds (7.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
694 
695  // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY state:
696  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
697  // and PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
698  // CCA_BUSY state should last for the duration of the two packets minus the time to detect the preamble.
699 
700  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
701  Simulator::Schedule (Seconds (8.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
702  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
705  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
708  // 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
709  Simulator::Schedule (Seconds (8.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 2);
710 
711  // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY state:
712  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
713  // but payload reception should fail (SNR too low to decode the modulation).
714 
715  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
716  Simulator::Schedule (Seconds (9.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
717  // At 4us, STA PHY STATE should move from IDLE to RX
720  // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
723  // In this case, the first packet should be marked as a failure
724  Simulator::Schedule (Seconds (9.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
725 
726  // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY state:
727  // PHY preamble detection should switch because a higher packet is received within the 4us window,
728  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
729  // PHY state should be CCA_BUSY since the total energy is above CCA-ED (-62 dBm).
730 
731  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
732  Simulator::Schedule (Seconds (10.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
733  // At 4us, STA PHY STATE should move from IDLE to CCA_BUSY
736  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
739  // 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
740  Simulator::Schedule (Seconds (10.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 3);
741 
742  // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY state:
743  // PHY preamble detection should switch because a higher packet is received within the 4us window,
744  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
745  // Payload reception should fail (SNR too low to decode the modulation).
746 
747  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
748  Simulator::Schedule (Seconds (11.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
749  // At 4us, STA PHY STATE should move from IDLE to RX
752  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
755  // In this case, the second packet should be marked as a failure
756  Simulator::Schedule (Seconds (11.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 1, 4);
757 
758  // CCA-PD < RX power < CCA-ED
759  rxPowerDbm = -70;
760 
761  // CASE 12: send one packet and check PHY state:
762  // All reception stages should succeed and PHY state should be RX for the duration of the packet minus the time to detect the preamble,
763  // otherwise it should be IDLE.
764 
765  Simulator::Schedule (Seconds (12.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
766  // At 4us, STA PHY STATE should move from IDLE to RX
769  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
772  // Packet should have been successfully received
773  Simulator::Schedule (Seconds (12.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
774 
775  // CASE 13: send two packets with same power within the 4us window and check PHY state:
776  // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than the threshold of 4 dB),
777  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
778 
779  Simulator::Schedule (Seconds (13.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
780  Simulator::Schedule (Seconds (13.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
781  // At 4us, STA PHY STATE should stay in IDLE
783  // 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
784  Simulator::Schedule (Seconds (13.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
785 
786  // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should fail
787  // PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB),
788  // and PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
789 
790  Simulator::Schedule (Seconds (14.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
791  Simulator::Schedule (Seconds (14.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 3);
792  // At 4us, STA PHY STATE should stay in IDLE
794  // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure
795  Simulator::Schedule (Seconds (14.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 4);
796 
797  // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY state:
798  // PHY preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
799  // but payload reception should fail (SNR too low to decode the modulation).
800 
801  Simulator::Schedule (Seconds (15.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
802  Simulator::Schedule (Seconds (15.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm - 6);
803  // At 4us, STA PHY STATE should move from IDLE to RX
806  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
809  // In this case, the first packet should be marked as a failure
810  Simulator::Schedule (Seconds (15.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
811 
812  // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY state:
813  // PHY preamble detection should switch because a higher packet is received within the 4us window,
814  // but preamble detection should fail because SNR is too low (around 3 dB, which is lower than the threshold of 4 dB).
815  // PHY state should stay IDLE since the total energy is below CCA-ED (-62 dBm).
816 
817  Simulator::Schedule (Seconds (16.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
818  Simulator::Schedule (Seconds (16.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 3);
819  // At 4us, STA PHY STATE should stay in IDLE
821  // At 6us, STA PHY STATE should stay in IDLE
823  // 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
824  Simulator::Schedule (Seconds (16.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 5);
825 
826  // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY state:
827  // PHY preamble detection should switch because a higher packet is received within the 4us window,
828  // and preamble detection should succeed because SNR is high enough (around 6 dB, which is higher than the threshold of 4 dB),
829  // Payload reception should fail (SNR too low to decode the modulation).
830 
831  Simulator::Schedule (Seconds (17.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
832  Simulator::Schedule (Seconds (17.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm + 6);
833  // At 4us, STA PHY STATE should stay in IDLE
835  // At 6us, STA PHY STATE should move from IDLE to RX
838  // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2 = 154.8us
841  // In this case, the second packet should be marked as a failure
842  Simulator::Schedule (Seconds (17.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 2, 6);
843 
844  rxPowerDbm = -50;
845  // CASE 18: send two packets with second one 50 dB higher within the 4us window
846 
847  Simulator::Schedule (Seconds (18.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
848  Simulator::Schedule (Seconds (18.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
849  // The second packet should be received successfully
850  Simulator::Schedule (Seconds (18.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 6);
851 
852  // CASE 19: send two packets with second one 10 dB higher within the 4us window
853 
854  Simulator::Schedule (Seconds (19.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
855  Simulator::Schedule (Seconds (19.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
856  // The second packet should be captured, but not decoded since SNR to low for used MCS
857  Simulator::Schedule (Seconds (19.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 3, 7);
858 
859  // CASE 20: send two packets with second one 50 dB higher in the same time
860 
861  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
862  Simulator::Schedule (Seconds (20.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+50);
863  // The second packet should be received successfully, same as in CASE 13
864  Simulator::Schedule (Seconds (20.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 7);
865 
866  // CASE 21: send two packets with second one 10 dB higher in the same time
867 
868  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm);
869  Simulator::Schedule (Seconds (21.0), &TestThresholdPreambleDetectionWithFrameCapture::SendPacket, this, rxPowerDbm+10);
870  // The second packet should be captured, but not decoded since SNR to low for used MCS, same as in CASE 19
871  Simulator::Schedule (Seconds (21.1), &TestThresholdPreambleDetectionWithFrameCapture::CheckRxPacketCount, this, 4, 8);
872 
873  Simulator::Run ();
874  Simulator::Destroy ();
875 }
876 
884 {
885 public:
887  virtual ~TestSimpleFrameCaptureModel ();
888 
889 protected:
890  virtual void DoSetup (void);
891 
892 private:
893  virtual void DoRun (void);
894 
898  void Reset (void);
904  void SendPacket (double rxPowerDbm, uint32_t packetSize);
912  void RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
919 
922  void Expect1000BPacketDropped ();
923  void Expect1500BPacketDropped ();
924 
926 
931 };
932 
934 : TestCase ("Simple frame capture model test"),
935  m_rxSuccess1000B (false),
936  m_rxSuccess1500B (false),
937  m_rxDropped1000B (false),
938  m_rxDropped1500B (false)
939 {
940 }
941 
942 void
944 {
945  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
946 
947  Ptr<Packet> pkt = Create<Packet> (packetSize);
948  WifiMacHeader hdr;
949  WifiMacTrailer trailer;
950 
951  hdr.SetType (WIFI_MAC_QOSDATA);
952  hdr.SetQosTid (0);
953  uint32_t size = pkt->GetSize () + hdr.GetSize () + trailer.GetSerializedSize ();
954  Time txDuration = m_phy->CalculateTxDuration (size, txVector, m_phy->GetFrequency ());
955  hdr.SetDuration (txDuration);
956 
957  pkt->AddHeader (hdr);
958  pkt->AddTrailer (trailer);
959 
960  HeSigHeader heSig;
961  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
962  heSig.SetBssColor (txVector.GetBssColor ());
963  heSig.SetChannelWidth (txVector.GetChannelWidth ());
964  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2);
965  pkt->AddHeader (heSig);
966 
967  LSigHeader sig;
968  pkt->AddHeader (sig);
969 
970  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), 1);
971  pkt->AddPacketTag (tag);
972 
973  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
974  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
975  txParams->psd = txPowerSpectrum;
976  txParams->txPhy = 0;
977  txParams->duration = txDuration;
978  txParams->packet = pkt;
979 
980  m_phy->StartRx (txParams);
981 }
982 
983 void
984 TestSimpleFrameCaptureModel::RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
985 {
986  NS_LOG_FUNCTION (this << p << snr << txVector);
987  if (p->GetSize () == 1030)
988  {
989  m_rxSuccess1000B = true;
990  }
991  else if (p->GetSize () == 1530)
992  {
993  m_rxSuccess1500B = true;
994  }
995 }
996 
997 void
999 {
1000  NS_LOG_FUNCTION (this << p << reason);
1001  if (p->GetSize () == 1030)
1002  {
1003  m_rxDropped1000B = true;
1004  }
1005  else if (p->GetSize () == 1530)
1006  {
1007  m_rxDropped1500B = true;
1008  }
1009 }
1010 
1011 void
1013 {
1014  m_rxSuccess1000B = false;
1015  m_rxSuccess1500B = false;
1016  m_rxDropped1000B = false;
1017  m_rxDropped1500B = false;
1018 }
1019 
1020 void
1022 {
1023  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1000B, true, "Didn't receive 1000B packet");
1024 }
1025 
1026 void
1028 {
1029  NS_TEST_ASSERT_MSG_EQ (m_rxSuccess1500B, true, "Didn't receive 1500B packet");
1030 }
1031 void
1033 {
1034  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1000B, true, "Didn't drop 1000B packet");
1035 }
1036 
1037 void
1039 {
1040  NS_TEST_ASSERT_MSG_EQ (m_rxDropped1500B, true, "Didn't drop 1500B packet");
1041 }
1042 
1044 {
1045  m_phy = 0;
1046 }
1047 
1048 void
1050 {
1051  m_phy = CreateObject<SpectrumWifiPhy> ();
1053  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1054  m_phy->SetErrorRateModel (error);
1057 
1060 
1061  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1062  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1063  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1064 
1065  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1066  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1067  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1068  m_phy->SetFrameCaptureModel (frameCaptureModel);
1069 }
1070 
1071 void
1073 {
1074  RngSeedManager::SetSeed (1);
1075  RngSeedManager::SetRun (1);
1076  int64_t streamNumber = 2;
1077  double rxPowerDbm = -30;
1078  m_phy->AssignStreams (streamNumber);
1079 
1080  // CASE 1: send two packets with same power within the capture window:
1081  // PHY should not switch reception because they have same power.
1082 
1083  Simulator::Schedule (Seconds (1.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1084  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1500);
1085  Simulator::Schedule (Seconds (1.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1086  Simulator::Schedule (Seconds (1.2), &TestSimpleFrameCaptureModel::Reset, this);
1087 
1088  // CASE 2: send two packets with second one 6 dB weaker within the capture window:
1089  // PHY should not switch reception because first one has higher power.
1090 
1091  Simulator::Schedule (Seconds (2.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1092  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm - 6, 1500);
1093  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1000BPacketReceived, this);
1094  Simulator::Schedule (Seconds (2.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1095  Simulator::Schedule (Seconds (2.2), &TestSimpleFrameCaptureModel::Reset, this);
1096 
1097  // CASE 3: send two packets with second one 6 dB higher within the capture window:
1098  // PHY should switch reception because the second one has a higher power.
1099 
1100  Simulator::Schedule (Seconds (3.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1101  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1102  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1000BPacketDropped, this);
1103  Simulator::Schedule (Seconds (3.1), &TestSimpleFrameCaptureModel::Expect1500BPacketReceived, this);
1104  Simulator::Schedule (Seconds (3.2), &TestSimpleFrameCaptureModel::Reset, this);
1105 
1106  // CASE 4: send two packets with second one 6 dB higher after the capture window:
1107  // PHY should not switch reception because capture window duration has elapsed when the second packet arrives.
1108 
1109  Simulator::Schedule (Seconds (4.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm, 1000);
1110  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25.0), &TestSimpleFrameCaptureModel::SendPacket, this, rxPowerDbm + 6, 1500);
1111  Simulator::Schedule (Seconds (4.1), &TestSimpleFrameCaptureModel::Expect1500BPacketDropped, this);
1112  Simulator::Schedule (Seconds (4.2), &TestSimpleFrameCaptureModel::Reset, this);
1113 
1114  Simulator::Run ();
1115  Simulator::Destroy ();
1116 }
1117 
1125 {
1126 public:
1128  virtual ~TestPhyHeadersReception ();
1129 
1130 protected:
1131  virtual void DoSetup (void);
1133 
1137  void SendPacket (double rxPowerDbm);
1138 
1139 private:
1140  virtual void DoRun (void);
1141 
1146  void CheckPhyState (WifiPhyState expectedState);
1147  void DoCheckPhyState (WifiPhyState expectedState);
1148 };
1149 
1151 : TestCase ("PHY headers reception test")
1152 {
1153 }
1154 
1155 void
1157 {
1158  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
1159  MpduType mpdutype = NORMAL_MPDU;
1160 
1161  Ptr<Packet> pkt = Create<Packet> (1000);
1162  WifiMacHeader hdr;
1163  WifiMacTrailer trailer;
1164 
1165  hdr.SetType (WIFI_MAC_QOSDATA);
1166  hdr.SetQosTid (0);
1167  uint32_t size = pkt->GetSize () + hdr.GetSize () + trailer.GetSerializedSize ();
1168  Time txDuration = m_phy->CalculateTxDuration (size, txVector, m_phy->GetFrequency (), mpdutype, 0);
1169  hdr.SetDuration (txDuration);
1170 
1171  pkt->AddHeader (hdr);
1172  pkt->AddTrailer (trailer);
1173 
1174  HeSigHeader heSig;
1175  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
1176  heSig.SetBssColor (txVector.GetBssColor ());
1177  heSig.SetChannelWidth (txVector.GetChannelWidth ());
1178  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2);
1179  pkt->AddHeader (heSig);
1180 
1181  LSigHeader sig;
1182  pkt->AddHeader (sig);
1183 
1184  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), 1);
1185  pkt->AddPacketTag (tag);
1186 
1187  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1188  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1189  txParams->psd = txPowerSpectrum;
1190  txParams->txPhy = 0;
1191  txParams->duration = txDuration;
1192  txParams->packet = pkt;
1193 
1194  m_phy->StartRx (txParams);
1195 }
1196 
1197 void
1199 {
1200  //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
1201  Simulator::ScheduleNow (&TestPhyHeadersReception::DoCheckPhyState, this, expectedState);
1202 }
1203 
1204 void
1206 {
1207  WifiPhyState currentState;
1208  PointerValue ptr;
1209  m_phy->GetAttribute ("State", ptr);
1210  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1211  currentState = state->GetState ();
1212  NS_LOG_FUNCTION (this << currentState);
1213  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1214 }
1215 
1216 
1218 {
1219  m_phy = 0;
1220 }
1221 
1222 void
1224 {
1225  m_phy = CreateObject<SpectrumWifiPhy> ();
1227  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1228  m_phy->SetErrorRateModel (error);
1231 }
1232 
1233 void
1235 {
1236  RngSeedManager::SetSeed (1);
1237  RngSeedManager::SetRun (1);
1238  int64_t streamNumber = 0;
1239  m_phy->AssignStreams (streamNumber);
1240 
1241  // RX power > CCA-ED
1242  double rxPowerDbm = -50;
1243 
1244  // CASE 1: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1245  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1246 
1247  Simulator::Schedule (Seconds (1.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1248  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1249  // At 10 us, STA PHY STATE should be RX.
1250  Simulator::Schedule (Seconds (1.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1251  // 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.
1252  Simulator::Schedule (Seconds (1.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1253  Simulator::Schedule (Seconds (1.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1254  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10 = 162.8us.
1255  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1256  Simulator::Schedule (Seconds (1.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1257 
1258  // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1259  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1260 
1261  Simulator::Schedule (Seconds (2.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1262  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1263  // At 10 us, STA PHY STATE should be RX.
1264  Simulator::Schedule (Seconds (2.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1265  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1266  Simulator::Schedule (Seconds (2.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1267  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1268  // 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.
1269  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1270  Simulator::Schedule (Seconds (2.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1271  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1272  Simulator::Schedule (Seconds (2.0) + NanoSeconds (162800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1273 
1274  // 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:
1275  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1276 
1277  Simulator::Schedule (Seconds (3.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1278  Simulator::Schedule (Seconds (3.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1279  // At 44 us (end of HE-SIG), STA PHY STATE should be RX (even though reception of HE-SIG failed)
1280  Simulator::Schedule (Seconds (3.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1281  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1282  // 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.
1283  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1284  Simulator::Schedule (Seconds (3.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1285  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1286  Simulator::Schedule (Seconds (3.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1287 
1288  // 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:
1289  // PHY header reception should succeed.
1290 
1291  Simulator::Schedule (Seconds (4.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1292  Simulator::Schedule (Seconds (4.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1293  // At 44 us (end of HE-SIG), STA PHY STATE should be RX.
1294  Simulator::Schedule (Seconds (4.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1295  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1296  // 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.
1297  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1298  Simulator::Schedule (Seconds (4.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1299  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::CCA_BUSY);
1300  Simulator::Schedule (Seconds (4.0) + NanoSeconds (177800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1301 
1302  // RX power < CCA-ED
1303  rxPowerDbm = -70;
1304 
1305  // CASE 5: send one packet followed by a second one with same power between the end of the 4us preamble detection window
1306  // and the start of L-SIG of the first packet: reception should be aborted since L-SIG cannot be decoded (SNR too low).
1307 
1308  Simulator::Schedule (Seconds (5.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1309  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1310  // At 10 us, STA PHY STATE should be RX.
1311  Simulator::Schedule (Seconds (5.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1312  // 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.
1313  Simulator::Schedule (Seconds (5.0) + NanoSeconds (23999), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1314  Simulator::Schedule (Seconds (5.0) + NanoSeconds (24000), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1315 
1316  // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us preamble detection window
1317  // and the start of L-SIG of the first packet: reception should not be aborted since L-SIG can be decoded (SNR high enough).
1318 
1319  Simulator::Schedule (Seconds (6.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1320  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1321  // At 10 us, STA PHY STATE should be RX.
1322  Simulator::Schedule (Seconds (6.0) + MicroSeconds (10.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1323  // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have succeeded.
1324  Simulator::Schedule (Seconds (6.0) + MicroSeconds (24.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1325  // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1326  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1327  Simulator::Schedule (Seconds (6.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1328 
1329  // 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:
1330  // PHY header reception should not succeed but PHY should stay in RX state for the duration estimated from L-SIG.
1331 
1332  Simulator::Schedule (Seconds (7.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1333  Simulator::Schedule (Seconds (7.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1334  // At 44 us (end of HE-SIG), STA PHY STATE should be RX (even though reception of HE-SIG failed).
1335  Simulator::Schedule (Seconds (7.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1336  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1337  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1338  Simulator::Schedule (Seconds (7.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1339 
1340  // 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:
1341  // PHY header reception should succeed.
1342 
1343  Simulator::Schedule (Seconds (8.0), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm);
1344  Simulator::Schedule (Seconds (8.0) + MicroSeconds (25), &TestPhyHeadersReception::SendPacket, this, rxPowerDbm - 3);
1345  // At 44 us (end of HE-SIG), STA PHY STATE should be RX.
1346  Simulator::Schedule (Seconds (8.0) + MicroSeconds (44.0), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1347  // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed, i.e. at 152.8us.
1348  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152799), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::RX);
1349  Simulator::Schedule (Seconds (8.0) + NanoSeconds (152800), &TestPhyHeadersReception::CheckPhyState, this, WifiPhyState::IDLE);
1350 
1351  Simulator::Run ();
1352  Simulator::Destroy ();
1353 }
1354 
1362 {
1363 public:
1364  TestAmpduReception ();
1365  virtual ~TestAmpduReception ();
1366 
1367 protected:
1368  virtual void DoSetup (void);
1369 
1370 private:
1371  virtual void DoRun (void);
1372 
1380  void RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
1385  void RxFailure (Ptr<Packet> p);
1396  void IncrementSuccessBitmap (uint32_t size);
1401  void IncrementFailureBitmap (uint32_t size);
1402 
1406  void ResetBitmaps();
1407 
1413  void SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize);
1414 
1419  void CheckRxSuccessBitmapAmpdu1 (uint8_t expected);
1424  void CheckRxSuccessBitmapAmpdu2 (uint8_t expected);
1429  void CheckRxFailureBitmapAmpdu1 (uint8_t expected);
1434  void CheckRxFailureBitmapAmpdu2 (uint8_t expected);
1439  void CheckRxDroppedBitmapAmpdu1 (uint8_t expected);
1444  void CheckRxDroppedBitmapAmpdu2 (uint8_t expected);
1445 
1450  void CheckPhyState (WifiPhyState expectedState);
1451 
1453 
1456 
1459 
1462 };
1463 
1465 : TestCase ("A-MPDU reception test"),
1466  m_rxSuccessBitmapAmpdu1 (0),
1467  m_rxSuccessBitmapAmpdu2 (0),
1468  m_rxFailureBitmapAmpdu1 (0),
1469  m_rxFailureBitmapAmpdu2 (0),
1470  m_rxDroppedBitmapAmpdu1 (0),
1471  m_rxDroppedBitmapAmpdu2 (0)
1472 {
1473 }
1474 
1476 {
1477  m_phy = 0;
1478 }
1479 
1480 void
1482 {
1489 }
1490 
1491 void
1492 TestAmpduReception::RxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
1493 {
1494  NS_LOG_FUNCTION (this << p << snr << txVector);
1495  if (IsAmpdu (p))
1496  {
1497  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (p);
1498  NS_ABORT_MSG_IF (mpdus.size () != statusPerMpdu.size (), "Should have one receive status per MPDU");
1499  auto rxOkForMpdu = statusPerMpdu.begin ();
1500  for (const auto & mpdu : mpdus)
1501  {
1502  if (*rxOkForMpdu)
1503  {
1504  IncrementSuccessBitmap (mpdu->GetSize ());
1505  }
1506  else
1507  {
1508  IncrementFailureBitmap (mpdu->GetSize ());
1509  }
1510  ++rxOkForMpdu;
1511  }
1512  }
1513  else
1514  {
1516  }
1517 }
1518 
1519 void
1521 {
1522  if (size == 1030) //A-MPDU 1 - MPDU #1
1523  {
1525  }
1526  else if (size == 1130) //A-MPDU 1 - MPDU #2
1527  {
1528  m_rxSuccessBitmapAmpdu1 |= (1 << 1);
1529  }
1530  else if (size == 1230) //A-MPDU 1 - MPDU #3
1531  {
1532  m_rxSuccessBitmapAmpdu1 |= (1 << 2);
1533  }
1534  else if (size == 1330) //A-MPDU 2 - MPDU #1
1535  {
1537  }
1538  else if (size == 1430) //A-MPDU 2 - MPDU #2
1539  {
1540  m_rxSuccessBitmapAmpdu2 |= (1 << 1);
1541  }
1542  else if (size == 1530) //A-MPDU 2 - MPDU #3
1543  {
1544  m_rxSuccessBitmapAmpdu2 |= (1 << 2);
1545  }
1546 }
1547 
1548 void
1550 {
1551  NS_LOG_FUNCTION (this << p);
1552  if (IsAmpdu (p))
1553  {
1554  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (p);
1555  for (const auto & mpdu : mpdus)
1556  {
1557  IncrementFailureBitmap (mpdu->GetSize ());
1558  }
1559  }
1560  else
1561  {
1563  }
1564 }
1565 
1566 void
1568 {
1569  if (size == 1030) //A-MPDU 1 - MPDU #1
1570  {
1572  }
1573  else if (size == 1130) //A-MPDU 1 - MPDU #2
1574  {
1575  m_rxFailureBitmapAmpdu1 |= (1 << 1);
1576  }
1577  else if (size == 1230) //A-MPDU 1 - MPDU #3
1578  {
1579  m_rxFailureBitmapAmpdu1 |= (1 << 2);
1580  }
1581  else if (size == 1330) //A-MPDU 2 - MPDU #1
1582  {
1584  }
1585  else if (size == 1430) //A-MPDU 2 - MPDU #2
1586  {
1587  m_rxFailureBitmapAmpdu2 |= (1 << 1);
1588  }
1589  else if (size == 1530) //A-MPDU 2 - MPDU #3
1590  {
1591  m_rxFailureBitmapAmpdu2 |= (1 << 2);
1592  }
1593 }
1594 
1595 void
1597 {
1598  NS_LOG_FUNCTION (this << p << reason);
1599  if (p->GetSize () == 1030) //A-MPDU 1 - MPDU #1
1600  {
1602  }
1603  else if (p->GetSize () == 1130) //A-MPDU 1 - MPDU #2
1604  {
1605  m_rxDroppedBitmapAmpdu1 |= (1 << 1);
1606  }
1607  else if (p->GetSize () == 1230) //A-MPDU 1 - MPDU #3
1608  {
1609  m_rxDroppedBitmapAmpdu1 |= (1 << 2);
1610  }
1611  else if (p->GetSize () == 1330) //A-MPDU 2 - MPDU #1
1612  {
1614  }
1615  else if (p->GetSize () == 1430) //A-MPDU 2 - MPDU #2
1616  {
1617  m_rxDroppedBitmapAmpdu2 |= (1 << 1);
1618  }
1619  else if (p->GetSize () == 1530) //A-MPDU 2 - MPDU #3
1620  {
1621  m_rxDroppedBitmapAmpdu2 |= (1 << 2);
1622  }
1623 }
1624 
1625 void
1627 {
1628  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu1, expected, "RX success bitmap for A-MPDU 1 is not as expected");
1629 }
1630 
1631 void
1633 {
1634  NS_TEST_ASSERT_MSG_EQ (m_rxSuccessBitmapAmpdu2, expected, "RX success bitmap for A-MPDU 2 is not as expected");
1635 }
1636 
1637 void
1639 {
1640  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu1, expected, "RX failure bitmap for A-MPDU 1 is not as expected");
1641 }
1642 
1643 void
1645 {
1646  NS_TEST_ASSERT_MSG_EQ (m_rxFailureBitmapAmpdu2, expected, "RX failure bitmap for A-MPDU 2 is not as expected");
1647 }
1648 
1649 void
1651 {
1652  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu1, expected, "RX dropped bitmap for A-MPDU 1 is not as expected");
1653 }
1654 
1655 void
1657 {
1658  NS_TEST_ASSERT_MSG_EQ (m_rxDroppedBitmapAmpdu2, expected, "RX dropped bitmap for A-MPDU 2 is not as expected");
1659 }
1660 
1661 void
1663 {
1664  WifiPhyState currentState;
1665  PointerValue ptr;
1666  m_phy->GetAttribute ("State", ptr);
1667  Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
1668  currentState = state->GetState ();
1669  NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
1670 }
1671 
1672 void
1673 TestAmpduReception::SendAmpduWithThreeMpdus (double rxPowerDbm, uint32_t referencePacketSize)
1674 {
1675  WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs0 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true, false);
1676 
1677  WifiMacHeader hdr;
1678  hdr.SetType (WIFI_MAC_QOSDATA);
1679  hdr.SetQosTid (0);
1680 
1681  std::vector<Ptr<WifiMacQueueItem>> mpduList;
1682  for (size_t i = 0; i < 3; ++i)
1683  {
1684  Ptr<Packet> p = Create<Packet> (referencePacketSize + i * 100);
1685  mpduList.push_back (Create<WifiMacQueueItem> (p, hdr));
1686  }
1687  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (mpduList);
1688 
1689  Time txDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetFrequency ());
1690  psdu->SetDuration (txDuration);
1691  Ptr<Packet> pkt = psdu->GetPacket ()->Copy ();
1692 
1693  HeSigHeader heSig;
1694  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
1695  heSig.SetBssColor (txVector.GetBssColor ());
1696  heSig.SetChannelWidth (txVector.GetChannelWidth ());
1697  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2);
1698  pkt->AddHeader (heSig);
1699 
1700  LSigHeader sig;
1701  uint16_t length = ((ceil ((static_cast<double> (txDuration.GetNanoSeconds () - (20 * 1000)) / 1000) / 4.0) * 3) - 3 - 2);
1702  sig.SetLength (length);
1703  pkt->AddHeader (sig);
1704 
1705  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), 1);
1706  pkt->AddPacketTag (tag);
1707 
1708  Ptr<SpectrumValue> txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (rxPowerDbm), GUARD_WIDTH);
1709  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
1710  txParams->psd = txPowerSpectrum;
1711  txParams->txPhy = 0;
1712  txParams->duration = txDuration;
1713  txParams->packet = pkt;
1714 
1715  m_phy->StartRx (txParams);
1716 }
1717 
1718 void
1720 {
1721  m_phy = CreateObject<SpectrumWifiPhy> ();
1723  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
1724  m_phy->SetErrorRateModel (error);
1727 
1731 
1732  Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel = CreateObject<ThresholdPreambleDetectionModel> ();
1733  preambleDetectionModel->SetAttribute ("Threshold", DoubleValue (2));
1734  m_phy->SetPreambleDetectionModel (preambleDetectionModel);
1735 
1736  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
1737  frameCaptureModel->SetAttribute ("Margin", DoubleValue (5));
1738  frameCaptureModel->SetAttribute ("CaptureWindow", TimeValue (MicroSeconds (16)));
1739  m_phy->SetFrameCaptureModel (frameCaptureModel);
1740 }
1741 
1742 void
1744 {
1745  RngSeedManager::SetSeed (1);
1746  RngSeedManager::SetRun (2);
1747  int64_t streamNumber = 1;
1748  double rxPowerDbm = -30;
1749  m_phy->AssignStreams (streamNumber);
1750 
1752  // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1753  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1755 
1756  // A-MPDU 1
1757  Simulator::Schedule (Seconds (1.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1758 
1759  // A-MPDU 2
1760  Simulator::Schedule (Seconds (1.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1761 
1762  // All MPDUs of A-MPDU 1 should have been ignored.
1763  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1764  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1765  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1766 
1767  // All MPDUs of A-MPDU 2 should have been successfully received.
1768  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1769  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1770  Simulator::Schedule (Seconds (1.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1771 
1772  Simulator::Schedule (Seconds (1.2), &TestAmpduReception::ResetBitmaps, this);
1773 
1775  // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1776  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1778 
1779  // A-MPDU 1
1780  Simulator::Schedule (Seconds (2.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1781 
1782  // A-MPDU 2
1783  Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1784 
1785  // All MPDUs of A-MPDU 1 should have been received.
1786  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1787  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1788  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1789 
1790  // All MPDUs of A-MPDU 2 should have been ignored.
1791  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1792  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1793  Simulator::Schedule (Seconds (2.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1794 
1795  Simulator::Schedule (Seconds (2.2), &TestAmpduReception::ResetBitmaps, this);
1796 
1798  // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1799  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1801 
1802  // A-MPDU 1
1803  Simulator::Schedule (Seconds (3.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1804 
1805  // A-MPDU 2
1806  Simulator::Schedule (Seconds (3.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1807 
1808  // All MPDUs of A-MPDU 1 should have been ignored.
1809  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1810  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1811  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1812 
1813  // All MPDUs of A-MPDU 2 should have been successfully received.
1814  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1815  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1816  Simulator::Schedule (Seconds (3.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1817 
1818  Simulator::Schedule (Seconds (3.2), &TestAmpduReception::ResetBitmaps, this);
1819 
1821  // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1822  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
1824 
1825  // A-MPDU 1
1826  Simulator::Schedule (Seconds (4.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1827 
1828  // A-MPDU 2
1829  Simulator::Schedule (Seconds (4.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1830 
1831  // All MPDUs of A-MPDU 1 should have been received.
1832  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1833  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1834  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1835 
1836  // All MPDUs of A-MPDU 2 should have been ignored.
1837  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1838  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1839  Simulator::Schedule (Seconds (4.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1840 
1841  Simulator::Schedule (Seconds (4.2), &TestAmpduReception::ResetBitmaps, this);
1842 
1844  // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1845  // 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).
1847 
1848  // A-MPDU 1
1849  Simulator::Schedule (Seconds (5.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1850 
1851  // A-MPDU 2
1852  Simulator::Schedule (Seconds (5.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1853 
1854  // All MPDUs of A-MPDU 1 should have been ignored.
1855  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1856  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1857  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1858 
1859  // All MPDUs of A-MPDU 2 should have been successfully received.
1860  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1861  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1862  Simulator::Schedule (Seconds (5.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1863 
1864  Simulator::Schedule (Seconds (5.2), &TestAmpduReception::ResetBitmaps, this);
1865 
1867  // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1868  // 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).
1870 
1871  // A-MPDU 1
1872  Simulator::Schedule (Seconds (6.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1873 
1874  // A-MPDU 2
1875  Simulator::Schedule (Seconds (6.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1876 
1877  // All MPDUs of A-MPDU 1 should have been received.
1878  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1879  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1880  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1881 
1882  // All MPDUs of A-MPDU 2 should have been ignored.
1883  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1884  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1885  Simulator::Schedule (Seconds (6.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1886 
1887  Simulator::Schedule (Seconds (6.2), &TestAmpduReception::ResetBitmaps, this);
1888 
1890  // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with power under RX sensitivity.
1891  // The second A-MPDU is received during the payload of MPDU #2.
1893 
1894  // A-MPDU 1
1895  Simulator::Schedule (Seconds (7.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1000);
1896 
1897  // A-MPDU 2
1898  Simulator::Schedule (Seconds (7.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1899 
1900  // All MPDUs of A-MPDU 1 should have been ignored.
1901  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1902  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1903  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1904 
1905  // All MPDUs of A-MPDU 2 should have been successfully received.
1906  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
1907  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1908  Simulator::Schedule (Seconds (7.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1909 
1910  Simulator::Schedule (Seconds (7.2), &TestAmpduReception::ResetBitmaps, this);
1911 
1913  // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received with power under RX sensitivity.
1914  // The second A-MPDU is received during the payload of MPDU #2.
1916 
1917  // A-MPDU 1
1918  Simulator::Schedule (Seconds (8.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1919 
1920  // A-MPDU 2
1921  Simulator::Schedule (Seconds (8.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm - 100, 1300);
1922 
1923  // All MPDUs of A-MPDU 1 should have been received.
1924  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
1925  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1926  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
1927 
1928  // All MPDUs of A-MPDU 2 should have been ignored.
1929  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1930  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1931  Simulator::Schedule (Seconds (8.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
1932 
1933  Simulator::Schedule (Seconds (8.2), &TestAmpduReception::ResetBitmaps, this);
1934 
1936  // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
1937  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1939 
1940  // A-MPDU 1
1941  Simulator::Schedule (Seconds (9.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1942 
1943  // A-MPDU 2
1944  Simulator::Schedule (Seconds (9.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
1945 
1946  // All MPDUs of A-MPDU 1 should have been dropped.
1947  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1948  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1949  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1950 
1951  // All MPDUs of A-MPDU 2 should have been received with errors.
1952  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1953  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000111);
1954  Simulator::Schedule (Seconds (9.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1955 
1956  Simulator::Schedule (Seconds (9.2), &TestAmpduReception::ResetBitmaps, this);
1957 
1959  // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
1960  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1962 
1963  // A-MPDU 1
1964  Simulator::Schedule (Seconds (10.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
1965 
1966  // A-MPDU 2
1967  Simulator::Schedule (Seconds (10.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1968 
1969  // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
1970  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1971  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
1972  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1973 
1974  // All MPDUs of A-MPDU 2 should have been dropped as well.
1975  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1976  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
1977  Simulator::Schedule (Seconds (10.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
1978 
1979  Simulator::Schedule (Seconds (10.2), &TestAmpduReception::ResetBitmaps, this);
1980 
1982  // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
1983  // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble detection).
1985 
1986  // A-MPDU 1
1987  Simulator::Schedule (Seconds (11.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
1988 
1989  // A-MPDU 2
1990  Simulator::Schedule (Seconds (11.0) + MicroSeconds (2), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
1991 
1992  // All MPDUs of A-MPDU 1 should have been received with errors.
1993  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
1994  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
1995  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
1996 
1997  // All MPDUs of A-MPDU 2 should have been dropped.
1998  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
1999  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2000  Simulator::Schedule (Seconds (11.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2001 
2002  Simulator::Schedule (Seconds (11.2), &TestAmpduReception::ResetBitmaps, this);
2003 
2005  // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3 dB higher.
2006  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2008 
2009  // A-MPDU 1
2010  Simulator::Schedule (Seconds (12.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2011 
2012  // A-MPDU 2
2013  Simulator::Schedule (Seconds (12.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1300);
2014 
2015  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2016  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2017  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2018  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2019 
2020  // 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)
2021  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2022  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2023  Simulator::Schedule (Seconds (12.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2024 
2025  Simulator::Schedule (Seconds (12.2), &TestAmpduReception::ResetBitmaps, this);
2026 
2028  // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2029  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2031 
2032  // A-MPDU 1
2033  Simulator::Schedule (Seconds (13.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2034 
2035  // A-MPDU 2
2036  Simulator::Schedule (Seconds (13.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2037 
2038  // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and thus incorrect decoding of payload).
2039  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2040  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2041  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2042 
2043  // All MPDUs of A-MPDU 2 should have been dropped as well.
2044  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2045  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2046  Simulator::Schedule (Seconds (13.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2047 
2048  Simulator::Schedule (Seconds (13.2), &TestAmpduReception::ResetBitmaps, this);
2049 
2051  // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3 dB higher.
2052  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2054 
2055  // A-MPDU 1
2056  Simulator::Schedule (Seconds (14.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 3, 1000);
2057 
2058  // A-MPDU 2
2059  Simulator::Schedule (Seconds (14.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2060 
2061  // All MPDUs of A-MPDU 1 should have been received with errors.
2062  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2063  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2064  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2065 
2066  // All MPDUs of A-MPDU 2 should have been dropped.
2067  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2068  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2069  Simulator::Schedule (Seconds (14.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2070 
2071  Simulator::Schedule (Seconds (14.2), &TestAmpduReception::ResetBitmaps, this);
2072 
2074  // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2075  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2077 
2078  // A-MPDU 1
2079  Simulator::Schedule (Seconds (15.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2080 
2081  // A-MPDU 2
2082  Simulator::Schedule (Seconds (15.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2083 
2084  // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
2085  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2086  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2087  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2088 
2089  // All MPDUs of A-MPDU 2 should have been successfully received
2090  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000111);
2091  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2092  Simulator::Schedule (Seconds (15.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000000);
2093 
2094  Simulator::Schedule (Seconds (15.2), &TestAmpduReception::ResetBitmaps, this);
2095 
2097  // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2098  // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame capture window).
2100 
2101  // A-MPDU 1
2102  Simulator::Schedule (Seconds (16.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2103 
2104  // A-MPDU 2
2105  Simulator::Schedule (Seconds (16.0) + MicroSeconds (10), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2106 
2107  // All MPDUs of A-MPDU 1 should have been successfully received.
2108  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2109  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2110  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2111 
2112  // All MPDUs of A-MPDU 2 should have been dropped.
2113  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2114  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2115  Simulator::Schedule (Seconds (16.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2116 
2117  Simulator::Schedule (Seconds (16.2), &TestAmpduReception::ResetBitmaps, this);
2118 
2120  // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2121  // 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).
2123 
2124  // A-MPDU 1
2125  Simulator::Schedule (Seconds (17.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2126 
2127  // A-MPDU 2
2128  Simulator::Schedule (Seconds (17.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2129 
2130  // All MPDUs of A-MPDU 1 should have been received with errors.
2131  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2132  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2133  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2134 
2135  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2136  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2137  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2138  Simulator::Schedule (Seconds (17.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2139 
2140  Simulator::Schedule (Seconds (17.2), &TestAmpduReception::ResetBitmaps, this);
2141 
2143  // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2144  // 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).
2146 
2147  // A-MPDU 1
2148  Simulator::Schedule (Seconds (18.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2149 
2150  // A-MPDU 2
2151  Simulator::Schedule (Seconds (18.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2152 
2153  // All MPDUs of A-MPDU 1 should have been successfully received.
2154  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2155  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2156  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2157 
2158  // All MPDUs of A-MPDU 2 should have been dropped.
2159  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2160  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2161  Simulator::Schedule (Seconds (18.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2162 
2163  Simulator::Schedule (Seconds (18.2), &TestAmpduReception::ResetBitmaps, this);
2164 
2166  // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2167  // 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).
2169 
2170  // A-MPDU 1
2171  Simulator::Schedule (Seconds (19.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2172 
2173  // A-MPDU 2
2174  Simulator::Schedule (Seconds (19.0) + MicroSeconds (25), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2175 
2176  // All MPDUs of A-MPDU 1 should have been received with errors.
2177  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2178  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2179  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2180 
2181  // All MPDUs of A-MPDU 2 should have been dropped.
2182  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2183  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2184  Simulator::Schedule (Seconds (19.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2185 
2186  Simulator::Schedule (Seconds (19.2), &TestAmpduReception::ResetBitmaps, this);
2187 
2189  // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 6 dB higher.
2190  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2192 
2193  // A-MPDU 1
2194  Simulator::Schedule (Seconds (20.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2195 
2196  // A-MPDU 2
2197  Simulator::Schedule (Seconds (20.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1300);
2198 
2199  // All MPDUs of A-MPDU 1 should have been received with errors.
2200  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2201  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2202  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2203 
2204  // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because PHY is already in RX state).
2205  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2206  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2207  Simulator::Schedule (Seconds (20.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2208 
2209  Simulator::Schedule (Seconds (20.2), &TestAmpduReception::ResetBitmaps, this);
2210 
2212  // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6 dB higher.
2213  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2215 
2216  // A-MPDU 1
2217  Simulator::Schedule (Seconds (21.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm + 6, 1000);
2218 
2219  // A-MPDU 2
2220  Simulator::Schedule (Seconds (21.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2221 
2222  // All MPDUs of A-MPDU 1 should have been successfully received.
2223  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000111);
2224  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000000);
2225  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000000);
2226 
2227  // All MPDUs of A-MPDU 2 should have been dropped.
2228  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2229  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2230  Simulator::Schedule (Seconds (21.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2231 
2232  Simulator::Schedule (Seconds (21.2), &TestAmpduReception::ResetBitmaps, this);
2233 
2235  // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2236  // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the payload of MPDU #1).
2238 
2239  // A-MPDU 1
2240  Simulator::Schedule (Seconds (22.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2241 
2242  // A-MPDU 2
2243  Simulator::Schedule (Seconds (22.0) + MicroSeconds (100), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2244 
2245  // All MPDUs of A-MPDU 1 should have been received with errors.
2246  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000000);
2247  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000111);
2248  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000111);
2249 
2250  // All MPDUs of A-MPDU 2 should have been dropped.
2251  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2252  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2253  Simulator::Schedule (Seconds (22.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2254 
2255  Simulator::Schedule (Seconds (22.2), &TestAmpduReception::ResetBitmaps, this);
2256 
2258  // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
2259  // The second A-MPDU is received during the payload of MPDU #2.
2261 
2262  // A-MPDU 1
2263  Simulator::Schedule (Seconds (23.0), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1000);
2264 
2265  // A-MPDU 2
2266  Simulator::Schedule (Seconds (23.0) + NanoSeconds (1100000), &TestAmpduReception::SendAmpduWithThreeMpdus, this, rxPowerDbm, 1300);
2267 
2268  // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
2269  // The two other MPDUs failed due to interference and are marked as failure (and dropped).
2270  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu1, this, 0b00000001);
2271  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu1, this, 0b00000110);
2272  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu1, this, 0b00000110);
2273 
2274  // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving A-MPDU 1).
2275  // 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.
2276  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxSuccessBitmapAmpdu2, this, 0b00000000);
2277  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxFailureBitmapAmpdu2, this, 0b00000000);
2278  Simulator::Schedule (Seconds (23.1), &TestAmpduReception::CheckRxDroppedBitmapAmpdu2, this, 0b00000111);
2279 
2280  Simulator::Schedule (Seconds (23.2), &TestAmpduReception::ResetBitmaps, this);
2281 
2282  Simulator::Run ();
2283  Simulator::Destroy ();
2284 }
2285 
2293 {
2294 public:
2296 };
2297 
2299  : TestSuite ("wifi-phy-reception", UNIT)
2300 {
2303  AddTestCase (new TestSimpleFrameCaptureModel, TestCase::QUICK);
2304  AddTestCase (new TestPhyHeadersReception, TestCase::QUICK);
2305  AddTestCase (new TestAmpduReception, TestCase::QUICK);
2306 }
2307 
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...
void SetDuration(Time duration)
Set the Duration/ID field on all the MPDUs.
Definition: wifi-psdu.cc:166
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.
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 Reset(void)
Reset function.
void CheckRxSuccessBitmapAmpdu1(uint8_t expected)
Check the RX success bitmap for A-MPDU 1.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:455
void RxSuccess(Ptr< Packet > p, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
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.
uint16_t GetGuardInterval(void) const
encapsulates test code
Definition: test.h:1155
void SetBssColor(uint8_t bssColor)
Fill the BSS Color field of HE-SIG-A1.
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:776
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
virtual void DoRun(void)
Implementation to actually run this TestCase.
MpduType
The type of an MPDU.
void RxFailure(Ptr< Packet > p)
Spectrum wifi receive failure function.
uint32_t GetSize(void) const
Return the size of the PSDU.
Definition: wifi-psdu.cc:241
void RxSuccess(Ptr< Packet > p, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
WifiPreamble GetPreambleType(void) const
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2344
Ptr< SpectrumWifiPhy > m_phy
Phy.
The MPDU is not part of an A-MPDU.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
Preamble detection test w/o frame capture.
Preamble detection test w/o frame capture.
Ptr< const Packet > GetPacket(void) const
Get the PSDU as a single packet.
Definition: wifi-psdu.cc:89
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)
void SetMcs(uint8_t mcs)
Fill the MCS field of HE-SIG-A1.
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
uint32_t GetSerializedSize(void) const
#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 SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:782
bool m_rxSuccess1000B
count received packets with 1000B payload
void RxFailure(Ptr< Packet > p)
Spectrum wifi receive failure function.
WifiMode GetMode(void) const
The PHY layer has sense the medium busy through the CCA mechanism.
Implements the IEEE 802.11 OFDM and ERP OFDM L-SIG PHY header.
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.
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 SetLength(uint16_t length)
Fill the LENGTH field of L-SIG (in bytes).
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:494
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:762
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
void SetChannelWidth(uint16_t channelWidth)
Fill the channel width field of HE-SIG-A1 (in MHz).
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.
bool IsAmpdu(Ptr< const Packet > packet)
Definition: wifi-utils.cc:270
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:1337
The PHY layer is IDLE.
WifiPhyState
The state of the PHY layer.
bool m_rxDropped1500B
count dropped packets with 1500B payload
void CheckRxSuccessBitmapAmpdu2(uint8_t expected)
Check the RX success bitmap for A-MPDU 2.
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:307
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
Ptr< Packet > packet
The packet being transmitted with this signal.
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:449
This objects implements the PHY state machine of the Wifi device.
Implements the IEEE 802.11ax HE-SIG PHY header (HE-SIG-A1/A2/B)
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
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:863
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
void SetGuardIntervalAndLtfSize(uint16_t gi, uint8_t ltf)
Fill the GI + LTF size field of HE-SIG-A1.
uint8_t GetBssColor(void) const
Get the BSS color.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
WifiPhyRxfailureReason
Definition: wifi-phy.h:48
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
Tag for WifiTxVector and WifiPreamble information to be embedded in outgoing transmissions as a Packe...
Definition: wifi-phy-tag.h:36
Time duration
The duration of the packet transmission.
static const uint16_t CHANNEL_WIDTH
void RxFailure(Ptr< Packet > p)
RX failure function.
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)
Check the PHY state.
uint16_t GetChannelWidth(void) const
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void RxSuccess(Ptr< Packet > p, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void CheckRxFailureBitmapAmpdu1(uint8_t expected)
Check the RX failure bitmap for A-MPDU 1.
bool m_rxDropped1000B
count dropped packets with 1000B payload
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:472
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:4259
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Implements the IEEE 802.11 MAC header.
void CheckRxDroppedBitmapAmpdu1(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 1.
Implements the IEEE 802.11 MAC trailer.
void RxSuccess(Ptr< Packet > p, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
RX success function.